From 9575fa54bfb771f3ab1c0f9ff136cde92a8758db Mon Sep 17 00:00:00 2001 From: joaop Date: Mon, 20 Jan 2025 21:43:03 -0300 Subject: [PATCH] Docker and Docker Compose add --- src/COPYRIGHT => COPYRIGHT | 0 Dockerfile | 12 + src/LICENSE => LICENSE | 0 README.md | 10 +- src/api.php => api.php | 1 - buildtar.php | 122 - composer.json | 24 - composer.lock | 763 ---- composer.sh | 11 - src/config-sample.php => config-sample.php | 0 {src/content => content}/index.html | 0 {src/content => content}/js/index.html | 0 {src/content => content}/js/jquery-ui.min.js | 0 {src/content => content}/js/jquery.min.js | 0 .../js/jquery.ui.touch-punch.js | 0 {src/content => content}/mytinytodo.js | 0 {src/content => content}/mytinytodo_api.js | 0 {src/content => content}/theme/dark.css | 0 .../theme/images/COPYRIGHT | 0 {src/content => content}/theme/images/add.svg | 0 .../theme/images/arr-left.svg | 0 .../theme/images/arr-right.svg | 0 .../theme/images/arrdown2.svg | 0 .../content => content}/theme/images/back.svg | 0 .../theme/images/calendar.svg | 0 .../theme/images/checkmark.svg | 0 .../theme/images/closetag.svg | 0 .../theme/images/index.html | 0 .../theme/images/loading48.gif | Bin .../theme/images/logo-loading.gif | Bin .../content => content}/theme/images/logo.gif | Bin .../theme/images/newtask-ext.svg | 0 .../theme/images/note-toggle.svg | 0 .../content => content}/theme/images/plus.svg | 0 .../theme/images/rss-disabled.svg | 0 {src/content => content}/theme/images/rss.svg | 0 .../theme/images/search-cancel.svg | 0 .../theme/images/search.svg | 0 .../theme/images/select-dark.svg | 0 .../theme/images/select.svg | 0 .../theme/images/selectlist.svg | 0 .../theme/images/selectlist2.svg | 0 .../theme/images/task-menu.svg | 0 .../theme/images/task-menu2.svg | 0 {src/content => content}/theme/index.html | 0 {src/content => content}/theme/markdown.css | 0 {src/content => content}/theme/print.css | 0 {src/content => content}/theme/style.css | 0 {src/content => content}/theme/style_rtl.css | 0 {src/db => db}/.htaccess | 0 docker-compose.yml | 16 + docker/dev/.gitignore | 1 - docker/dev/_mariadb100/my.cnf | 4 - docker/dev/_mariadb105/my.cnf | 4 - docker/dev/_mariadb108/my.cnf | 4 - docker/dev/_nginx/Dockerfile-angie-alpine | 23 - docker/dev/_nginx/Dockerfile-nginx | 5 - docker/dev/_nginx/Dockerfile-nginx-alpine | 5 - docker/dev/_nginx/default.conf | 59 - docker/dev/mtt-php72-angie-postgres10/.env | 1 - .../mtt-php72-angie-postgres10/Dockerfile-fpm | 17 - .../mtt-php72-angie-postgres10/compose.yml | 58 - .../php-fpm-www.conf | 13 - .../mtt-php72-angie-postgres10/php-mtt.ini | 10 - .../php-opcache.ini | 42 - docker/dev/mtt-php72-apache-mariadb100/.env | 1 - .../mtt-php72-apache-mariadb100/compose.yml | 47 - docker/dev/mtt-php72-apache-mariadb105/.env | 1 - .../mtt-php72-apache-mariadb105/compose.yml | 47 - docker/dev/mtt-php72-apache-postgres10/.env | 1 - .../mtt-php72-apache-postgres10/compose.yml | 45 - docker/dev/mtt-php72-apache/.env | 1 - docker/dev/mtt-php72-apache/Dockerfile-web | 18 - docker/dev/mtt-php72-apache/compose.yml | 17 - docker/dev/mtt-php72-apache/php-mtt.ini | 11 - docker/dev/mtt-php72-apache/php-opcache.ini | 34 - docker/dev/mtt-php74-apache/.env | 1 - docker/dev/mtt-php74-apache/Dockerfile-web | 15 - docker/dev/mtt-php74-apache/compose.yml | 17 - docker/dev/mtt-php74-apache/php-mtt.ini | 9 - docker/dev/mtt-php74-apache/php-opcache.ini | 34 - docker/dev/mtt-php74-nginx/.env | 1 - docker/dev/mtt-php74-nginx/Dockerfile-fpm | 11 - docker/dev/mtt-php74-nginx/compose.yml | 37 - docker/dev/mtt-php74-nginx/php-mtt.ini | 10 - docker/dev/mtt-php74-nginx/php-opcache.ini | 42 - docker/dev/mtt-php80-apache-mariadb105/.env | 1 - .../mtt-php80-apache-mariadb105/compose.yml | 45 - docker/dev/mtt-php80-apache/.env | 1 - docker/dev/mtt-php80-apache/Dockerfile-web | 15 - docker/dev/mtt-php80-apache/compose.yml | 16 - docker/dev/mtt-php80-apache/php-mtt.ini | 9 - docker/dev/mtt-php80-apache/php-opcache.ini | 42 - docker/dev/mtt-php81-apache-mariadb108/.env | 1 - .../mtt-php81-apache-mariadb108/compose.yml | 56 - docker/dev/mtt-php81-apache/.env | 1 - docker/dev/mtt-php81-apache/Dockerfile-web | 16 - docker/dev/mtt-php81-apache/compose.yml | 16 - docker/dev/mtt-php81-apache/php-mtt.ini | 9 - docker/dev/mtt-php81-apache/php-opcache.ini | 42 - docker/dev/mtt-php82-angie-postgres10/.env | 1 - .../mtt-php82-angie-postgres10/compose.yml | 58 - docker/dev/mtt-php82-angie/.env | 1 - docker/dev/mtt-php82-angie/Dockerfile-fpm | 17 - docker/dev/mtt-php82-angie/compose.yml | 40 - docker/dev/mtt-php82-angie/php-fpm-www.conf | 13 - docker/dev/mtt-php82-angie/php-mtt.ini | 12 - docker/dev/mtt-php82-angie/php-opcache.ini | 42 - docker/dev/mtt-php82-apache/.env | 1 - docker/dev/mtt-php82-apache/Dockerfile-web | 17 - docker/dev/mtt-php82-apache/compose.yml | 19 - docker/dev/mtt-php82-apache/php-mtt.ini | 9 - docker/dev/mtt-php82-apache/php-opcache.ini | 42 - docker/dev/mtt-php83-apache/.env | 1 - docker/dev/mtt-php83-apache/Dockerfile-web | 15 - docker/dev/mtt-php83-apache/compose.yml | 20 - docker/dev/mtt-php83-apache/php-mtt.ini | 11 - docker/dev/mtt-php83-apache/php-opcache.ini | 42 - docker/dev/readme.md | 8 - src/export.php => export.php | 0 ext/extensions.tar.gz | Bin 0 -> 18837 bytes src/feed.php => feed.php | 0 {src/ext/CustomCSS => includes}/.htaccess | 0 .../api/AuthController.php | 0 .../api/ExtSettingsController.php | 0 .../api/ListsController.php | 0 .../api/TagsController.php | 0 .../api/TasksController.php | 0 {src/includes => includes}/class.config.php | 0 {src/includes => includes}/class.db.mysql.php | 2 +- .../includes => includes}/class.db.mysqli.php | 2 +- .../class.db.postgres.php | 2 +- .../class.db.sqlite3.php | 4 +- .../class.dbconnection.php | 19 - {src/includes => includes}/class.dbcore.php | 0 {src/includes => includes}/class.lang.php | 0 .../class.sessionhandler.php | 0 {src/includes => includes}/classes.php | 21 +- {src/includes => includes}/common.php | 0 {src/includes => includes}/filters.php | 0 {src/includes => includes}/index.html | 0 {src/includes => includes}/lang/ar.json | 0 {src/includes => includes}/lang/bg.json | 0 {src/includes => includes}/lang/ca.json | 0 {src/includes => includes}/lang/cz.json | 0 {src/includes => includes}/lang/da.json | 0 {src/includes => includes}/lang/de.json | 19 +- {src/includes => includes}/lang/el.json | 0 {src/includes => includes}/lang/en.json | 0 {src/includes => includes}/lang/es-mx.json | 0 {src/includes => includes}/lang/es.json | 0 {src/includes => includes}/lang/fa.json | 0 {src/includes => includes}/lang/fr.json | 0 {src/includes => includes}/lang/he.json | 0 {src/includes => includes}/lang/hu.json | 0 {src/includes => includes}/lang/it.json | 0 {src/includes => includes}/lang/ja.json | 0 {src/includes => includes}/lang/lt.json | 0 {src/includes => includes}/lang/mk.json | 0 {src/includes => includes}/lang/nl.json | 0 {src/includes => includes}/lang/no.json | 0 {src/includes => includes}/lang/pl.json | 0 {src/includes => includes}/lang/pt-br.json | 0 {src/includes => includes}/lang/pt-pt.json | 0 {src/includes => includes}/lang/ro.json | 0 {src/includes => includes}/lang/ru.json | 0 {src/includes => includes}/lang/sk.json | 0 {src/includes => includes}/lang/sl.json | 0 {src/includes => includes}/lang/sr.json | 0 {src/includes => includes}/lang/sv.json | 0 {src/includes => includes}/lang/th.json | 0 {src/includes => includes}/lang/tr.json | 0 {src/includes => includes}/lang/uk.json | 0 {src/includes => includes}/lang/vi.json | 0 {src/includes => includes}/lang/zh-cn.json | 0 {src/includes => includes}/lang/zh-tw.json | 0 .../markup.commonmark.php | 0 .../markup.parsedown.php | 0 {src/includes => includes}/markup.php | 0 {src/includes => includes}/notifications.php | 0 {src/includes => includes}/smartsyntax.php | 0 {src/includes => includes}/theme.php | 0 includes/vendor/autoload.php | 25 + includes/vendor/composer/ClassLoader.php | 579 +++ .../vendor/composer/InstalledVersions.php | 359 ++ includes/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 13 + includes/vendor/composer/autoload_files.php | 10 + .../vendor/composer/autoload_namespaces.php | 10 + includes/vendor/composer/autoload_psr4.php | 10 + includes/vendor/composer/autoload_real.php | 50 + includes/vendor/composer/autoload_static.php | 54 + includes/vendor/composer/installed.json | 146 + includes/vendor/composer/installed.php | 41 + includes/vendor/composer/platform_check.php | 26 + includes/vendor/erusev/._parsedown | Bin 0 -> 194 bytes includes/vendor/erusev/parsedown/LICENSE.txt | 20 + .../vendor/erusev/parsedown/Parsedown.php | 1712 ++++++++ includes/vendor/erusev/parsedown/README.md | 86 + .../vendor/erusev/parsedown/composer.json | 33 + .../vendor/symfony/._polyfill-intl-normalizer | Bin 0 -> 194 bytes .../polyfill-intl-normalizer/._Resources | Bin 0 -> 194 bytes .../symfony/polyfill-intl-normalizer/LICENSE | 19 + .../polyfill-intl-normalizer/Normalizer.php | 310 ++ .../polyfill-intl-normalizer/README.md | 14 + .../Resources/._stubs | Bin 0 -> 194 bytes .../Resources/._unidata | Bin 0 -> 194 bytes .../Resources/stubs/Normalizer.php | 17 + .../unidata/canonicalComposition.php | 945 +++++ .../unidata/canonicalDecomposition.php | 2065 +++++++++ .../Resources/unidata/combiningClass.php | 876 ++++ .../unidata/compatibilityDecomposition.php | 3695 +++++++++++++++++ .../polyfill-intl-normalizer/bootstrap.php | 23 + .../polyfill-intl-normalizer/bootstrap80.php | 19 + .../polyfill-intl-normalizer/composer.json | 39 + {src/includes => includes}/version.php | 0 src/index.php => index.php | 0 src/init.php => init.php | 6 +- src/settings.php => settings.php | 0 src/setup.php => setup.php | 4 - src/.htaccess | 16 - src/content/theme/images/svg2base64.php | 62 - src/docker-config.php | 23 - src/ext/CustomCSS/extension.json | 6 - src/ext/CustomCSS/lang/en.json | 7 - src/ext/CustomCSS/lang/pl.json | 7 - src/ext/CustomCSS/lang/ru.json | 7 - src/ext/CustomCSS/loader.php | 93 - src/ext/_examples/CustomSmartSyntax/.htaccess | 1 - .../CustomSmartSyntax/extension.json | 6 - .../_examples/CustomSmartSyntax/loader.php | 41 - src/ext/backup/.htaccess | 1 - src/ext/backup/class.backup.php | 190 - src/ext/backup/class.check.php | 126 - src/ext/backup/class.controller.php | 156 - src/ext/backup/class.download.php | 74 - src/ext/backup/class.restore.php | 251 -- src/ext/backup/extension.json | 6 - src/ext/backup/lang/en.json | 17 - src/ext/backup/lang/ru.json | 17 - src/ext/backup/loader.php | 140 - src/ext/notifications/.htaccess | 1 - src/ext/notifications/class.controller.php | 117 - src/ext/notifications/class.observer.php | 65 - src/ext/notifications/class.sender.php | 202 - src/ext/notifications/class.telegramapi.php | 128 - src/ext/notifications/cli-notify.php | 63 - src/ext/notifications/extension.json | 6 - src/ext/notifications/lang/de.json | 30 - src/ext/notifications/lang/en.json | 30 - src/ext/notifications/lang/ru.json | 30 - src/ext/notifications/loader.php | 244 -- src/ext/updater/.htaccess | 1 - src/ext/updater/class.controller.php | 82 - src/ext/updater/class.updater.php | 142 - src/ext/updater/extension.json | 6 - src/ext/updater/lang/de.json | 16 - src/ext/updater/lang/en.json | 16 - src/ext/updater/lang/ru.json | 16 - src/ext/updater/loader.php | 129 - src/includes/.htaccess | 1 - src/includes/lang/en-rtl.json | 11 - src/mtt-edit-settings.php | 47 - 263 files changed, 11274 insertions(+), 4896 deletions(-) rename src/COPYRIGHT => COPYRIGHT (100%) create mode 100644 Dockerfile rename src/LICENSE => LICENSE (100%) rename src/api.php => api.php (99%) delete mode 100755 buildtar.php delete mode 100644 composer.json delete mode 100644 composer.lock delete mode 100755 composer.sh rename src/config-sample.php => config-sample.php (100%) rename {src/content => content}/index.html (100%) rename {src/content => content}/js/index.html (100%) rename {src/content => content}/js/jquery-ui.min.js (100%) rename {src/content => content}/js/jquery.min.js (100%) rename {src/content => content}/js/jquery.ui.touch-punch.js (100%) rename {src/content => content}/mytinytodo.js (100%) rename {src/content => content}/mytinytodo_api.js (100%) rename {src/content => content}/theme/dark.css (100%) rename {src/content => content}/theme/images/COPYRIGHT (100%) rename {src/content => content}/theme/images/add.svg (100%) rename {src/content => content}/theme/images/arr-left.svg (100%) rename {src/content => content}/theme/images/arr-right.svg (100%) rename {src/content => content}/theme/images/arrdown2.svg (100%) rename {src/content => content}/theme/images/back.svg (100%) rename {src/content => content}/theme/images/calendar.svg (100%) rename {src/content => content}/theme/images/checkmark.svg (100%) rename {src/content => content}/theme/images/closetag.svg (100%) rename {src/content => content}/theme/images/index.html (100%) rename {src/content => content}/theme/images/loading48.gif (100%) rename {src/content => content}/theme/images/logo-loading.gif (100%) rename {src/content => content}/theme/images/logo.gif (100%) rename {src/content => content}/theme/images/newtask-ext.svg (100%) rename {src/content => content}/theme/images/note-toggle.svg (100%) rename {src/content => content}/theme/images/plus.svg (100%) rename {src/content => content}/theme/images/rss-disabled.svg (100%) rename {src/content => content}/theme/images/rss.svg (100%) rename {src/content => content}/theme/images/search-cancel.svg (100%) rename {src/content => content}/theme/images/search.svg (100%) rename {src/content => content}/theme/images/select-dark.svg (100%) rename {src/content => content}/theme/images/select.svg (100%) rename {src/content => content}/theme/images/selectlist.svg (100%) rename {src/content => content}/theme/images/selectlist2.svg (100%) rename {src/content => content}/theme/images/task-menu.svg (100%) rename {src/content => content}/theme/images/task-menu2.svg (100%) rename {src/content => content}/theme/index.html (100%) rename {src/content => content}/theme/markdown.css (100%) rename {src/content => content}/theme/print.css (100%) rename {src/content => content}/theme/style.css (100%) rename {src/content => content}/theme/style_rtl.css (100%) rename {src/db => db}/.htaccess (100%) create mode 100644 docker-compose.yml delete mode 100644 docker/dev/.gitignore delete mode 100644 docker/dev/_mariadb100/my.cnf delete mode 100644 docker/dev/_mariadb105/my.cnf delete mode 100644 docker/dev/_mariadb108/my.cnf delete mode 100644 docker/dev/_nginx/Dockerfile-angie-alpine delete mode 100644 docker/dev/_nginx/Dockerfile-nginx delete mode 100644 docker/dev/_nginx/Dockerfile-nginx-alpine delete mode 100644 docker/dev/_nginx/default.conf delete mode 100644 docker/dev/mtt-php72-angie-postgres10/.env delete mode 100644 docker/dev/mtt-php72-angie-postgres10/Dockerfile-fpm delete mode 100644 docker/dev/mtt-php72-angie-postgres10/compose.yml delete mode 100644 docker/dev/mtt-php72-angie-postgres10/php-fpm-www.conf delete mode 100644 docker/dev/mtt-php72-angie-postgres10/php-mtt.ini delete mode 100644 docker/dev/mtt-php72-angie-postgres10/php-opcache.ini delete mode 100644 docker/dev/mtt-php72-apache-mariadb100/.env delete mode 100644 docker/dev/mtt-php72-apache-mariadb100/compose.yml delete mode 100644 docker/dev/mtt-php72-apache-mariadb105/.env delete mode 100644 docker/dev/mtt-php72-apache-mariadb105/compose.yml delete mode 100644 docker/dev/mtt-php72-apache-postgres10/.env delete mode 100644 docker/dev/mtt-php72-apache-postgres10/compose.yml delete mode 100644 docker/dev/mtt-php72-apache/.env delete mode 100644 docker/dev/mtt-php72-apache/Dockerfile-web delete mode 100644 docker/dev/mtt-php72-apache/compose.yml delete mode 100644 docker/dev/mtt-php72-apache/php-mtt.ini delete mode 100644 docker/dev/mtt-php72-apache/php-opcache.ini delete mode 100644 docker/dev/mtt-php74-apache/.env delete mode 100644 docker/dev/mtt-php74-apache/Dockerfile-web delete mode 100644 docker/dev/mtt-php74-apache/compose.yml delete mode 100644 docker/dev/mtt-php74-apache/php-mtt.ini delete mode 100644 docker/dev/mtt-php74-apache/php-opcache.ini delete mode 100644 docker/dev/mtt-php74-nginx/.env delete mode 100644 docker/dev/mtt-php74-nginx/Dockerfile-fpm delete mode 100644 docker/dev/mtt-php74-nginx/compose.yml delete mode 100644 docker/dev/mtt-php74-nginx/php-mtt.ini delete mode 100644 docker/dev/mtt-php74-nginx/php-opcache.ini delete mode 100644 docker/dev/mtt-php80-apache-mariadb105/.env delete mode 100644 docker/dev/mtt-php80-apache-mariadb105/compose.yml delete mode 100644 docker/dev/mtt-php80-apache/.env delete mode 100644 docker/dev/mtt-php80-apache/Dockerfile-web delete mode 100644 docker/dev/mtt-php80-apache/compose.yml delete mode 100644 docker/dev/mtt-php80-apache/php-mtt.ini delete mode 100644 docker/dev/mtt-php80-apache/php-opcache.ini delete mode 100644 docker/dev/mtt-php81-apache-mariadb108/.env delete mode 100644 docker/dev/mtt-php81-apache-mariadb108/compose.yml delete mode 100644 docker/dev/mtt-php81-apache/.env delete mode 100644 docker/dev/mtt-php81-apache/Dockerfile-web delete mode 100644 docker/dev/mtt-php81-apache/compose.yml delete mode 100644 docker/dev/mtt-php81-apache/php-mtt.ini delete mode 100644 docker/dev/mtt-php81-apache/php-opcache.ini delete mode 100644 docker/dev/mtt-php82-angie-postgres10/.env delete mode 100644 docker/dev/mtt-php82-angie-postgres10/compose.yml delete mode 100644 docker/dev/mtt-php82-angie/.env delete mode 100644 docker/dev/mtt-php82-angie/Dockerfile-fpm delete mode 100644 docker/dev/mtt-php82-angie/compose.yml delete mode 100644 docker/dev/mtt-php82-angie/php-fpm-www.conf delete mode 100644 docker/dev/mtt-php82-angie/php-mtt.ini delete mode 100644 docker/dev/mtt-php82-angie/php-opcache.ini delete mode 100644 docker/dev/mtt-php82-apache/.env delete mode 100644 docker/dev/mtt-php82-apache/Dockerfile-web delete mode 100644 docker/dev/mtt-php82-apache/compose.yml delete mode 100644 docker/dev/mtt-php82-apache/php-mtt.ini delete mode 100644 docker/dev/mtt-php82-apache/php-opcache.ini delete mode 100644 docker/dev/mtt-php83-apache/.env delete mode 100644 docker/dev/mtt-php83-apache/Dockerfile-web delete mode 100644 docker/dev/mtt-php83-apache/compose.yml delete mode 100644 docker/dev/mtt-php83-apache/php-mtt.ini delete mode 100644 docker/dev/mtt-php83-apache/php-opcache.ini delete mode 100644 docker/dev/readme.md rename src/export.php => export.php (100%) create mode 100644 ext/extensions.tar.gz rename src/feed.php => feed.php (100%) rename {src/ext/CustomCSS => includes}/.htaccess (100%) rename {src/includes => includes}/api/AuthController.php (100%) rename {src/includes => includes}/api/ExtSettingsController.php (100%) rename {src/includes => includes}/api/ListsController.php (100%) rename {src/includes => includes}/api/TagsController.php (100%) rename {src/includes => includes}/api/TasksController.php (100%) rename {src/includes => includes}/class.config.php (100%) rename {src/includes => includes}/class.db.mysql.php (99%) rename {src/includes => includes}/class.db.mysqli.php (99%) rename {src/includes => includes}/class.db.postgres.php (99%) rename {src/includes => includes}/class.db.sqlite3.php (99%) rename {src/includes => includes}/class.dbconnection.php (83%) rename {src/includes => includes}/class.dbcore.php (100%) rename {src/includes => includes}/class.lang.php (100%) rename {src/includes => includes}/class.sessionhandler.php (100%) rename {src/includes => includes}/classes.php (93%) rename {src/includes => includes}/common.php (100%) rename {src/includes => includes}/filters.php (100%) rename {src/includes => includes}/index.html (100%) rename {src/includes => includes}/lang/ar.json (100%) rename {src/includes => includes}/lang/bg.json (100%) rename {src/includes => includes}/lang/ca.json (100%) rename {src/includes => includes}/lang/cz.json (100%) rename {src/includes => includes}/lang/da.json (100%) rename {src/includes => includes}/lang/de.json (91%) rename {src/includes => includes}/lang/el.json (100%) rename {src/includes => includes}/lang/en.json (100%) rename {src/includes => includes}/lang/es-mx.json (100%) rename {src/includes => includes}/lang/es.json (100%) rename {src/includes => includes}/lang/fa.json (100%) rename {src/includes => includes}/lang/fr.json (100%) rename {src/includes => includes}/lang/he.json (100%) rename {src/includes => includes}/lang/hu.json (100%) rename {src/includes => includes}/lang/it.json (100%) rename {src/includes => includes}/lang/ja.json (100%) rename {src/includes => includes}/lang/lt.json (100%) rename {src/includes => includes}/lang/mk.json (100%) rename {src/includes => includes}/lang/nl.json (100%) rename {src/includes => includes}/lang/no.json (100%) rename {src/includes => includes}/lang/pl.json (100%) rename {src/includes => includes}/lang/pt-br.json (100%) rename {src/includes => includes}/lang/pt-pt.json (100%) rename {src/includes => includes}/lang/ro.json (100%) rename {src/includes => includes}/lang/ru.json (100%) rename {src/includes => includes}/lang/sk.json (100%) rename {src/includes => includes}/lang/sl.json (100%) rename {src/includes => includes}/lang/sr.json (100%) rename {src/includes => includes}/lang/sv.json (100%) rename {src/includes => includes}/lang/th.json (100%) rename {src/includes => includes}/lang/tr.json (100%) rename {src/includes => includes}/lang/uk.json (100%) rename {src/includes => includes}/lang/vi.json (100%) rename {src/includes => includes}/lang/zh-cn.json (100%) rename {src/includes => includes}/lang/zh-tw.json (100%) rename {src/includes => includes}/markup.commonmark.php (100%) rename {src/includes => includes}/markup.parsedown.php (100%) rename {src/includes => includes}/markup.php (100%) rename {src/includes => includes}/notifications.php (100%) rename {src/includes => includes}/smartsyntax.php (100%) rename {src/includes => includes}/theme.php (100%) create mode 100644 includes/vendor/autoload.php create mode 100644 includes/vendor/composer/ClassLoader.php create mode 100644 includes/vendor/composer/InstalledVersions.php create mode 100644 includes/vendor/composer/LICENSE create mode 100644 includes/vendor/composer/autoload_classmap.php create mode 100644 includes/vendor/composer/autoload_files.php create mode 100644 includes/vendor/composer/autoload_namespaces.php create mode 100644 includes/vendor/composer/autoload_psr4.php create mode 100644 includes/vendor/composer/autoload_real.php create mode 100644 includes/vendor/composer/autoload_static.php create mode 100644 includes/vendor/composer/installed.json create mode 100644 includes/vendor/composer/installed.php create mode 100644 includes/vendor/composer/platform_check.php create mode 100755 includes/vendor/erusev/._parsedown create mode 100644 includes/vendor/erusev/parsedown/LICENSE.txt create mode 100644 includes/vendor/erusev/parsedown/Parsedown.php create mode 100644 includes/vendor/erusev/parsedown/README.md create mode 100644 includes/vendor/erusev/parsedown/composer.json create mode 100755 includes/vendor/symfony/._polyfill-intl-normalizer create mode 100755 includes/vendor/symfony/polyfill-intl-normalizer/._Resources create mode 100644 includes/vendor/symfony/polyfill-intl-normalizer/LICENSE create mode 100644 includes/vendor/symfony/polyfill-intl-normalizer/Normalizer.php create mode 100644 includes/vendor/symfony/polyfill-intl-normalizer/README.md create mode 100755 includes/vendor/symfony/polyfill-intl-normalizer/Resources/._stubs create mode 100755 includes/vendor/symfony/polyfill-intl-normalizer/Resources/._unidata create mode 100644 includes/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php create mode 100644 includes/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalComposition.php create mode 100644 includes/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php create mode 100644 includes/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php create mode 100644 includes/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php create mode 100644 includes/vendor/symfony/polyfill-intl-normalizer/bootstrap.php create mode 100644 includes/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php create mode 100644 includes/vendor/symfony/polyfill-intl-normalizer/composer.json rename {src/includes => includes}/version.php (100%) rename src/index.php => index.php (100%) rename src/init.php => init.php (98%) rename src/settings.php => settings.php (100%) rename src/setup.php => setup.php (99%) delete mode 100644 src/.htaccess delete mode 100644 src/content/theme/images/svg2base64.php delete mode 100644 src/docker-config.php delete mode 100644 src/ext/CustomCSS/extension.json delete mode 100644 src/ext/CustomCSS/lang/en.json delete mode 100644 src/ext/CustomCSS/lang/pl.json delete mode 100644 src/ext/CustomCSS/lang/ru.json delete mode 100644 src/ext/CustomCSS/loader.php delete mode 100644 src/ext/_examples/CustomSmartSyntax/.htaccess delete mode 100644 src/ext/_examples/CustomSmartSyntax/extension.json delete mode 100644 src/ext/_examples/CustomSmartSyntax/loader.php delete mode 100644 src/ext/backup/.htaccess delete mode 100644 src/ext/backup/class.backup.php delete mode 100644 src/ext/backup/class.check.php delete mode 100644 src/ext/backup/class.controller.php delete mode 100644 src/ext/backup/class.download.php delete mode 100644 src/ext/backup/class.restore.php delete mode 100644 src/ext/backup/extension.json delete mode 100644 src/ext/backup/lang/en.json delete mode 100644 src/ext/backup/lang/ru.json delete mode 100644 src/ext/backup/loader.php delete mode 100644 src/ext/notifications/.htaccess delete mode 100644 src/ext/notifications/class.controller.php delete mode 100644 src/ext/notifications/class.observer.php delete mode 100644 src/ext/notifications/class.sender.php delete mode 100644 src/ext/notifications/class.telegramapi.php delete mode 100644 src/ext/notifications/cli-notify.php delete mode 100644 src/ext/notifications/extension.json delete mode 100644 src/ext/notifications/lang/de.json delete mode 100644 src/ext/notifications/lang/en.json delete mode 100644 src/ext/notifications/lang/ru.json delete mode 100644 src/ext/notifications/loader.php delete mode 100644 src/ext/updater/.htaccess delete mode 100644 src/ext/updater/class.controller.php delete mode 100644 src/ext/updater/class.updater.php delete mode 100644 src/ext/updater/extension.json delete mode 100644 src/ext/updater/lang/de.json delete mode 100644 src/ext/updater/lang/en.json delete mode 100644 src/ext/updater/lang/ru.json delete mode 100644 src/ext/updater/loader.php delete mode 100644 src/includes/.htaccess delete mode 100644 src/includes/lang/en-rtl.json delete mode 100644 src/mtt-edit-settings.php diff --git a/src/COPYRIGHT b/COPYRIGHT similarity index 100% rename from src/COPYRIGHT rename to COPYRIGHT diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a97b6f8 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM php:8.1-apache + +RUN docker-php-ext-install mysqli + +COPY . /var/www/html/ + +RUN chown -R www-data:www-data /var/www/html \ + && chmod -R 755 /var/www/html + +RUN a2enmod rewrite + +EXPOSE 80 diff --git a/src/LICENSE b/LICENSE similarity index 100% rename from src/LICENSE rename to LICENSE diff --git a/README.md b/README.md index 9a3b527..8979082 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,11 @@ -myTinyTodo +# My Tiny Todo + +An easy way to organize and manage your to-do lists. + +- **Languages Used:** PHP and jQuery. +- **Supported Databases:** PostgreSQL, MySQL, or SQLite. +- **License:** Released under the GNU GPL License. + +Start managing your tasks effectively today! Original website - http://www.mytinytodo.net/ diff --git a/src/api.php b/api.php similarity index 99% rename from src/api.php rename to api.php index c540fac..cb6a8aa 100644 --- a/src/api.php +++ b/api.php @@ -200,7 +200,6 @@ function checkReadAccess(?int $listId = null) $id = $db->sq("SELECT id FROM {$db->prefix}lists WHERE id=? AND published=1", array($listId)); if ($id) return; } - http_response_code(403); jsonExit( array('total'=>0, 'list'=>array(), 'denied'=>1) ); } diff --git a/buildtar.php b/buildtar.php deleted file mode 100755 index 159d97e..0000000 --- a/buildtar.php +++ /dev/null @@ -1,122 +0,0 @@ -#!/usr/bin/env php - [-o source.tar.gz] [-v VERSION]\n"); -} - -$repo = $argv[1]; -$dir = sys_get_temp_dir(). DIRECTORY_SEPARATOR. "mytinytodo.build"; -$curdir = getcwd(); -$archive = $curdir. DIRECTORY_SEPARATOR. 'mytinytodo-v@VERSION-@REV.tar.gz'; -$ver = 0; - -while ($arg = next($argv)) -{ - if ($arg == '-o') { - $archive = next($argv); - } - elseif ($arg == '-v') { - $ver = next($argv); - } -} - -deleteTreeIfDir($dir); -$out = `git clone $repo $dir 2>&1`; -if (!is_dir($dir)) { - die("Error while clone: $out\n"); -} -print "> Repository was cloned to temp dir: $dir\n"; - -#get current version number if not specified -if (!$ver) { - require_once(__DIR__ . '/src/includes/version.php'); - $ver = mytinytodo\Version::VERSION; -} -chdir($dir. DIRECTORY_SEPARATOR. 'src'); -$rev = trim(`git show --format=format:%H --summary`); -$rev = substr($rev, 0, 8); -##$ver = str_replace('@REV', $rev, $ver); -print "> Version is $ver\n"; - -unlink('./docker-config.php'); -unlink('./includes/lang/en-rtl.json'); -unlink('./mtt-edit-settings.php'); -unlink('./content/theme/images/svg2base64.php'); - -chdir('..'); # to the root of repo - -assert( strpos(getcwd(), ':') === false ); # FIXME: if path contains a colon ':' -echo("> Run Composer\n"); -$retval = 0; -if (false === system( "./composer.sh install --no-dev --no-interaction --optimize-autoloader", $retval) || $retval != 0) { - die("Failed to install composer libs via docker\n"); -} - -# ext -if (is_dir('src/ext')) { - mkdir('src/ext2'); - chdir('src/ext'); - deleteTreeIfDir('_examples'); - $extCount = 0; - $exts = array_diff(scandir('.') ?? [], ['.', '..']); - foreach ($exts as $ext) { - if (is_dir($ext)) { - rename($ext, "../ext2/$ext"); - $extCount++; - } - } - chdir('../ext2'); - if ($extCount > 0) { - `tar --no-xattrs -czf ../ext/extensions.tar.gz *`; #OS dep.!!! - } - chdir('../..'); - deleteTreeIfDir('src/ext2'); - echo("> Extensions were packed\n"); -} - - -rename('src', 'mytinytodo') or die("Cant rename 'src'\n"); - -`tar --no-xattrs -czf mytinytodo.tar.gz mytinytodo`; #OS dep.!!! -if (!file_exists('mytinytodo.tar.gz')) { - die("Failed to pack files (no output tar.gz file)\n"); -} - -$archive = str_replace('@VERSION', $ver, $archive); -$archive = str_replace('@REV', $rev, $archive); - -chdir($curdir); -if ( ! rename("$dir/mytinytodo.tar.gz", $archive) ) { - die("Failed to move mytinytodo.tar.gz to $archive"); -} - -deleteTreeIfDir($dir); -echo("> Temp dir was cleaned\n"); - -echo("> Build is stored in $archive\n"); - - - - - - -function deleteTreeIfDir($dir) -{ - if ( !is_dir($dir) ) { - return; - } - switch (PHP_OS) { - case 'Darwin': - case 'Linux': - system("rm -rf ". escapeshellarg($dir)); - break; - case 'Windows': - system("rmdir /s /q ". escapeshellarg($dir)); - break; - default: - die("Unknown system ". PHP_OS. "\n"); - } -} diff --git a/composer.json b/composer.json deleted file mode 100644 index 9849935..0000000 --- a/composer.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "maxpozdeev/mytinytodo", - "type": "project", - "license": "GPL-2.0-or-later", - "homepage": "https://mytinytodo.net", - "authors": [ - { - "name": "Max Pozdeev", - "role": "Developer" - } - ], - "config": { - "vendor-dir": "src/includes/vendor" - }, - "require": { - "php": ">=7.2", - "ext-mbstring": "*", - "erusev/parsedown": "^1.7", - "symfony/polyfill-intl-normalizer": "^1.31" - }, - "require-dev": { - "league/commonmark": "^2.6" - } -} diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 60f4a8a..0000000 --- a/composer.lock +++ /dev/null @@ -1,763 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "282581dc840171ff5aaaf39ad242a12a", - "packages": [ - { - "name": "erusev/parsedown", - "version": "1.7.4", - "source": { - "type": "git", - "url": "https://github.com/erusev/parsedown.git", - "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/erusev/parsedown/zipball/cb17b6477dfff935958ba01325f2e8a2bfa6dab3", - "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35" - }, - "type": "library", - "autoload": { - "psr-0": { - "Parsedown": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Emanuil Rusev", - "email": "hello@erusev.com", - "homepage": "http://erusev.com" - } - ], - "description": "Parser for Markdown.", - "homepage": "http://parsedown.org", - "keywords": [ - "markdown", - "parser" - ], - "support": { - "issues": "https://github.com/erusev/parsedown/issues", - "source": "https://github.com/erusev/parsedown/tree/1.7.x" - }, - "time": "2019-12-30T22:54:17+00:00" - }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.31.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "3833d7255cc303546435cb650316bff708a1c75c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", - "reference": "3833d7255cc303546435cb650316bff708a1c75c", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's Normalizer class and related functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "intl", - "normalizer", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-09T11:45:10+00:00" - } - ], - "packages-dev": [ - { - "name": "dflydev/dot-access-data", - "version": "v3.0.3", - "source": { - "type": "git", - "url": "https://github.com/dflydev/dflydev-dot-access-data.git", - "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/a23a2bf4f31d3518f3ecb38660c95715dfead60f", - "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^0.12.42", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", - "scrutinizer/ocular": "1.6.0", - "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "^4.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Dflydev\\DotAccessData\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Dragonfly Development Inc.", - "email": "info@dflydev.com", - "homepage": "http://dflydev.com" - }, - { - "name": "Beau Simensen", - "email": "beau@dflydev.com", - "homepage": "http://beausimensen.com" - }, - { - "name": "Carlos Frutos", - "email": "carlos@kiwing.it", - "homepage": "https://github.com/cfrutos" - }, - { - "name": "Colin O'Dell", - "email": "colinodell@gmail.com", - "homepage": "https://www.colinodell.com" - } - ], - "description": "Given a deep data structure, access data by dot notation.", - "homepage": "https://github.com/dflydev/dflydev-dot-access-data", - "keywords": [ - "access", - "data", - "dot", - "notation" - ], - "support": { - "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", - "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.3" - }, - "time": "2024-07-08T12:26:09+00:00" - }, - { - "name": "league/commonmark", - "version": "2.6.1", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/commonmark.git", - "reference": "d990688c91cedfb69753ffc2512727ec646df2ad" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/d990688c91cedfb69753ffc2512727ec646df2ad", - "reference": "d990688c91cedfb69753ffc2512727ec646df2ad", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "league/config": "^1.1.1", - "php": "^7.4 || ^8.0", - "psr/event-dispatcher": "^1.0", - "symfony/deprecation-contracts": "^2.1 || ^3.0", - "symfony/polyfill-php80": "^1.16" - }, - "require-dev": { - "cebe/markdown": "^1.0", - "commonmark/cmark": "0.31.1", - "commonmark/commonmark.js": "0.31.1", - "composer/package-versions-deprecated": "^1.8", - "embed/embed": "^4.4", - "erusev/parsedown": "^1.0", - "ext-json": "*", - "github/gfm": "0.29.0", - "michelf/php-markdown": "^1.4 || ^2.0", - "nyholm/psr7": "^1.5", - "phpstan/phpstan": "^1.8.2", - "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0", - "scrutinizer/ocular": "^1.8.1", - "symfony/finder": "^5.3 | ^6.0 | ^7.0", - "symfony/process": "^5.4 | ^6.0 | ^7.0", - "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0", - "unleashedtech/php-coding-standard": "^3.1.1", - "vimeo/psalm": "^4.24.0 || ^5.0.0" - }, - "suggest": { - "symfony/yaml": "v2.3+ required if using the Front Matter extension" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "League\\CommonMark\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Colin O'Dell", - "email": "colinodell@gmail.com", - "homepage": "https://www.colinodell.com", - "role": "Lead Developer" - } - ], - "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", - "homepage": "https://commonmark.thephpleague.com", - "keywords": [ - "commonmark", - "flavored", - "gfm", - "github", - "github-flavored", - "markdown", - "md", - "parser" - ], - "support": { - "docs": "https://commonmark.thephpleague.com/", - "forum": "https://github.com/thephpleague/commonmark/discussions", - "issues": "https://github.com/thephpleague/commonmark/issues", - "rss": "https://github.com/thephpleague/commonmark/releases.atom", - "source": "https://github.com/thephpleague/commonmark" - }, - "funding": [ - { - "url": "https://www.colinodell.com/sponsor", - "type": "custom" - }, - { - "url": "https://www.paypal.me/colinpodell/10.00", - "type": "custom" - }, - { - "url": "https://github.com/colinodell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/league/commonmark", - "type": "tidelift" - } - ], - "time": "2024-12-29T14:10:59+00:00" - }, - { - "name": "league/config", - "version": "v1.2.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/config.git", - "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", - "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", - "shasum": "" - }, - "require": { - "dflydev/dot-access-data": "^3.0.1", - "nette/schema": "^1.2", - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.8.2", - "phpunit/phpunit": "^9.5.5", - "scrutinizer/ocular": "^1.8.1", - "unleashedtech/php-coding-standard": "^3.1", - "vimeo/psalm": "^4.7.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.2-dev" - } - }, - "autoload": { - "psr-4": { - "League\\Config\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Colin O'Dell", - "email": "colinodell@gmail.com", - "homepage": "https://www.colinodell.com", - "role": "Lead Developer" - } - ], - "description": "Define configuration arrays with strict schemas and access values with dot notation", - "homepage": "https://config.thephpleague.com", - "keywords": [ - "array", - "config", - "configuration", - "dot", - "dot-access", - "nested", - "schema" - ], - "support": { - "docs": "https://config.thephpleague.com/", - "issues": "https://github.com/thephpleague/config/issues", - "rss": "https://github.com/thephpleague/config/releases.atom", - "source": "https://github.com/thephpleague/config" - }, - "funding": [ - { - "url": "https://www.colinodell.com/sponsor", - "type": "custom" - }, - { - "url": "https://www.paypal.me/colinpodell/10.00", - "type": "custom" - }, - { - "url": "https://github.com/colinodell", - "type": "github" - } - ], - "time": "2022-12-11T20:36:23+00:00" - }, - { - "name": "nette/schema", - "version": "v1.3.2", - "source": { - "type": "git", - "url": "https://github.com/nette/schema.git", - "reference": "da801d52f0354f70a638673c4a0f04e16529431d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/schema/zipball/da801d52f0354f70a638673c4a0f04e16529431d", - "reference": "da801d52f0354f70a638673c4a0f04e16529431d", - "shasum": "" - }, - "require": { - "nette/utils": "^4.0", - "php": "8.1 - 8.4" - }, - "require-dev": { - "nette/tester": "^2.5.2", - "phpstan/phpstan-nette": "^1.0", - "tracy/tracy": "^2.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0-only", - "GPL-3.0-only" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "📐 Nette Schema: validating data structures against a given Schema.", - "homepage": "https://nette.org", - "keywords": [ - "config", - "nette" - ], - "support": { - "issues": "https://github.com/nette/schema/issues", - "source": "https://github.com/nette/schema/tree/v1.3.2" - }, - "time": "2024-10-06T23:10:23+00:00" - }, - { - "name": "nette/utils", - "version": "v4.0.5", - "source": { - "type": "git", - "url": "https://github.com/nette/utils.git", - "reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/736c567e257dbe0fcf6ce81b4d6dbe05c6899f96", - "reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96", - "shasum": "" - }, - "require": { - "php": "8.0 - 8.4" - }, - "conflict": { - "nette/finder": "<3", - "nette/schema": "<1.2.2" - }, - "require-dev": { - "jetbrains/phpstorm-attributes": "dev-master", - "nette/tester": "^2.5", - "phpstan/phpstan": "^1.0", - "tracy/tracy": "^2.9" - }, - "suggest": { - "ext-gd": "to use Image", - "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", - "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", - "ext-json": "to use Nette\\Utils\\Json", - "ext-mbstring": "to use Strings::lower() etc...", - "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0-only", - "GPL-3.0-only" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", - "homepage": "https://nette.org", - "keywords": [ - "array", - "core", - "datetime", - "images", - "json", - "nette", - "paginator", - "password", - "slugify", - "string", - "unicode", - "utf-8", - "utility", - "validation" - ], - "support": { - "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v4.0.5" - }, - "time": "2024-08-07T15:39:19+00:00" - }, - { - "name": "psr/event-dispatcher", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/event-dispatcher.git", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", - "shasum": "" - }, - "require": { - "php": ">=7.2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\EventDispatcher\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Standard interfaces for event handling.", - "keywords": [ - "events", - "psr", - "psr-14" - ], - "support": { - "issues": "https://github.com/php-fig/event-dispatcher/issues", - "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" - }, - "time": "2019-01-08T18:20:26+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v3.5.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/contracts", - "name": "symfony/contracts" - }, - "branch-alias": { - "dev-main": "3.5-dev" - } - }, - "autoload": { - "files": [ - "function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-25T14:20:29+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.31.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", - "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-09T11:45:10+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": {}, - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=7.2", - "ext-mbstring": "*" - }, - "platform-dev": {}, - "plugin-api-version": "2.6.0" -} diff --git a/composer.sh b/composer.sh deleted file mode 100755 index 00eac74..0000000 --- a/composer.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -#dir="$( dirname -- "$( readlink -f -- "$0"; )"; )" -dir="$PWD" - -app=$(which podman) -if [ -z $app ]; then - app="docker" -fi - -$app run -it --rm -v "$dir:/app" composer $@ diff --git a/src/config-sample.php b/config-sample.php similarity index 100% rename from src/config-sample.php rename to config-sample.php diff --git a/src/content/index.html b/content/index.html similarity index 100% rename from src/content/index.html rename to content/index.html diff --git a/src/content/js/index.html b/content/js/index.html similarity index 100% rename from src/content/js/index.html rename to content/js/index.html diff --git a/src/content/js/jquery-ui.min.js b/content/js/jquery-ui.min.js similarity index 100% rename from src/content/js/jquery-ui.min.js rename to content/js/jquery-ui.min.js diff --git a/src/content/js/jquery.min.js b/content/js/jquery.min.js similarity index 100% rename from src/content/js/jquery.min.js rename to content/js/jquery.min.js diff --git a/src/content/js/jquery.ui.touch-punch.js b/content/js/jquery.ui.touch-punch.js similarity index 100% rename from src/content/js/jquery.ui.touch-punch.js rename to content/js/jquery.ui.touch-punch.js diff --git a/src/content/mytinytodo.js b/content/mytinytodo.js similarity index 100% rename from src/content/mytinytodo.js rename to content/mytinytodo.js diff --git a/src/content/mytinytodo_api.js b/content/mytinytodo_api.js similarity index 100% rename from src/content/mytinytodo_api.js rename to content/mytinytodo_api.js diff --git a/src/content/theme/dark.css b/content/theme/dark.css similarity index 100% rename from src/content/theme/dark.css rename to content/theme/dark.css diff --git a/src/content/theme/images/COPYRIGHT b/content/theme/images/COPYRIGHT similarity index 100% rename from src/content/theme/images/COPYRIGHT rename to content/theme/images/COPYRIGHT diff --git a/src/content/theme/images/add.svg b/content/theme/images/add.svg similarity index 100% rename from src/content/theme/images/add.svg rename to content/theme/images/add.svg diff --git a/src/content/theme/images/arr-left.svg b/content/theme/images/arr-left.svg similarity index 100% rename from src/content/theme/images/arr-left.svg rename to content/theme/images/arr-left.svg diff --git a/src/content/theme/images/arr-right.svg b/content/theme/images/arr-right.svg similarity index 100% rename from src/content/theme/images/arr-right.svg rename to content/theme/images/arr-right.svg diff --git a/src/content/theme/images/arrdown2.svg b/content/theme/images/arrdown2.svg similarity index 100% rename from src/content/theme/images/arrdown2.svg rename to content/theme/images/arrdown2.svg diff --git a/src/content/theme/images/back.svg b/content/theme/images/back.svg similarity index 100% rename from src/content/theme/images/back.svg rename to content/theme/images/back.svg diff --git a/src/content/theme/images/calendar.svg b/content/theme/images/calendar.svg similarity index 100% rename from src/content/theme/images/calendar.svg rename to content/theme/images/calendar.svg diff --git a/src/content/theme/images/checkmark.svg b/content/theme/images/checkmark.svg similarity index 100% rename from src/content/theme/images/checkmark.svg rename to content/theme/images/checkmark.svg diff --git a/src/content/theme/images/closetag.svg b/content/theme/images/closetag.svg similarity index 100% rename from src/content/theme/images/closetag.svg rename to content/theme/images/closetag.svg diff --git a/src/content/theme/images/index.html b/content/theme/images/index.html similarity index 100% rename from src/content/theme/images/index.html rename to content/theme/images/index.html diff --git a/src/content/theme/images/loading48.gif b/content/theme/images/loading48.gif similarity index 100% rename from src/content/theme/images/loading48.gif rename to content/theme/images/loading48.gif diff --git a/src/content/theme/images/logo-loading.gif b/content/theme/images/logo-loading.gif similarity index 100% rename from src/content/theme/images/logo-loading.gif rename to content/theme/images/logo-loading.gif diff --git a/src/content/theme/images/logo.gif b/content/theme/images/logo.gif similarity index 100% rename from src/content/theme/images/logo.gif rename to content/theme/images/logo.gif diff --git a/src/content/theme/images/newtask-ext.svg b/content/theme/images/newtask-ext.svg similarity index 100% rename from src/content/theme/images/newtask-ext.svg rename to content/theme/images/newtask-ext.svg diff --git a/src/content/theme/images/note-toggle.svg b/content/theme/images/note-toggle.svg similarity index 100% rename from src/content/theme/images/note-toggle.svg rename to content/theme/images/note-toggle.svg diff --git a/src/content/theme/images/plus.svg b/content/theme/images/plus.svg similarity index 100% rename from src/content/theme/images/plus.svg rename to content/theme/images/plus.svg diff --git a/src/content/theme/images/rss-disabled.svg b/content/theme/images/rss-disabled.svg similarity index 100% rename from src/content/theme/images/rss-disabled.svg rename to content/theme/images/rss-disabled.svg diff --git a/src/content/theme/images/rss.svg b/content/theme/images/rss.svg similarity index 100% rename from src/content/theme/images/rss.svg rename to content/theme/images/rss.svg diff --git a/src/content/theme/images/search-cancel.svg b/content/theme/images/search-cancel.svg similarity index 100% rename from src/content/theme/images/search-cancel.svg rename to content/theme/images/search-cancel.svg diff --git a/src/content/theme/images/search.svg b/content/theme/images/search.svg similarity index 100% rename from src/content/theme/images/search.svg rename to content/theme/images/search.svg diff --git a/src/content/theme/images/select-dark.svg b/content/theme/images/select-dark.svg similarity index 100% rename from src/content/theme/images/select-dark.svg rename to content/theme/images/select-dark.svg diff --git a/src/content/theme/images/select.svg b/content/theme/images/select.svg similarity index 100% rename from src/content/theme/images/select.svg rename to content/theme/images/select.svg diff --git a/src/content/theme/images/selectlist.svg b/content/theme/images/selectlist.svg similarity index 100% rename from src/content/theme/images/selectlist.svg rename to content/theme/images/selectlist.svg diff --git a/src/content/theme/images/selectlist2.svg b/content/theme/images/selectlist2.svg similarity index 100% rename from src/content/theme/images/selectlist2.svg rename to content/theme/images/selectlist2.svg diff --git a/src/content/theme/images/task-menu.svg b/content/theme/images/task-menu.svg similarity index 100% rename from src/content/theme/images/task-menu.svg rename to content/theme/images/task-menu.svg diff --git a/src/content/theme/images/task-menu2.svg b/content/theme/images/task-menu2.svg similarity index 100% rename from src/content/theme/images/task-menu2.svg rename to content/theme/images/task-menu2.svg diff --git a/src/content/theme/index.html b/content/theme/index.html similarity index 100% rename from src/content/theme/index.html rename to content/theme/index.html diff --git a/src/content/theme/markdown.css b/content/theme/markdown.css similarity index 100% rename from src/content/theme/markdown.css rename to content/theme/markdown.css diff --git a/src/content/theme/print.css b/content/theme/print.css similarity index 100% rename from src/content/theme/print.css rename to content/theme/print.css diff --git a/src/content/theme/style.css b/content/theme/style.css similarity index 100% rename from src/content/theme/style.css rename to content/theme/style.css diff --git a/src/content/theme/style_rtl.css b/content/theme/style_rtl.css similarity index 100% rename from src/content/theme/style_rtl.css rename to content/theme/style_rtl.css diff --git a/src/db/.htaccess b/db/.htaccess similarity index 100% rename from src/db/.htaccess rename to db/.htaccess diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..365bb40 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,16 @@ +version: '3.8' + +services: + app: + build: + context: . + dockerfile: Dockerfile + container_name: mytinytodo_app + ports: + - "8080:80" + volumes: + - ./db:/var/www/html/db + +volumes: + db_data: + diff --git a/docker/dev/.gitignore b/docker/dev/.gitignore deleted file mode 100644 index 369ea15..0000000 --- a/docker/dev/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*/db_data diff --git a/docker/dev/_mariadb100/my.cnf b/docker/dev/_mariadb100/my.cnf deleted file mode 100644 index fa9302b..0000000 --- a/docker/dev/_mariadb100/my.cnf +++ /dev/null @@ -1,4 +0,0 @@ -[mysqld] -collation-server = utf8mb4_unicode_ci -character-set-server = utf8mb4 -innodb_log_file_size=10M diff --git a/docker/dev/_mariadb105/my.cnf b/docker/dev/_mariadb105/my.cnf deleted file mode 100644 index fa9302b..0000000 --- a/docker/dev/_mariadb105/my.cnf +++ /dev/null @@ -1,4 +0,0 @@ -[mysqld] -collation-server = utf8mb4_unicode_ci -character-set-server = utf8mb4 -innodb_log_file_size=10M diff --git a/docker/dev/_mariadb108/my.cnf b/docker/dev/_mariadb108/my.cnf deleted file mode 100644 index fa9302b..0000000 --- a/docker/dev/_mariadb108/my.cnf +++ /dev/null @@ -1,4 +0,0 @@ -[mysqld] -collation-server = utf8mb4_unicode_ci -character-set-server = utf8mb4 -innodb_log_file_size=10M diff --git a/docker/dev/_nginx/Dockerfile-angie-alpine b/docker/dev/_nginx/Dockerfile-angie-alpine deleted file mode 100644 index 12250a6..0000000 --- a/docker/dev/_nginx/Dockerfile-angie-alpine +++ /dev/null @@ -1,23 +0,0 @@ -FROM alpine:latest - -RUN set -x \ - && apk add --no-cache ca-certificates curl \ - && curl -o /etc/apk/keys/angie-signing.rsa https://angie.software/keys/angie-signing.rsa \ - && echo "https://download.angie.software/angie/alpine/v$(egrep -o '[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ - && apk add --no-cache angie \ - && rm /etc/apk/keys/angie-signing.rsa \ - && ln -sf /dev/stdout /var/log/angie/access.log \ - && ln -sf /dev/stderr /var/log/angie/error.log - -EXPOSE 80 -CMD ["angie", "-g", "daemon off;"] - - -RUN mv /etc/angie/http.d/default.conf /etc/angie/http.d/default.conf.bak \ - && mkdir /var/log/nginx \ - && ln -sf /var/log/angie/access.log /var/log/nginx/access.log - -# config from nginx -COPY default.conf /etc/angie/http.d/default.conf - -VOLUME /var/www/html diff --git a/docker/dev/_nginx/Dockerfile-nginx b/docker/dev/_nginx/Dockerfile-nginx deleted file mode 100644 index 84b70a0..0000000 --- a/docker/dev/_nginx/Dockerfile-nginx +++ /dev/null @@ -1,5 +0,0 @@ -FROM nginx:latest - -COPY default.conf /etc/nginx/conf.d/ - -VOLUME /var/www/html diff --git a/docker/dev/_nginx/Dockerfile-nginx-alpine b/docker/dev/_nginx/Dockerfile-nginx-alpine deleted file mode 100644 index 1312e5b..0000000 --- a/docker/dev/_nginx/Dockerfile-nginx-alpine +++ /dev/null @@ -1,5 +0,0 @@ -FROM nginx:alpine - -COPY default.conf /etc/nginx/conf.d/ - -VOLUME /var/www/html diff --git a/docker/dev/_nginx/default.conf b/docker/dev/_nginx/default.conf deleted file mode 100644 index 403e02c..0000000 --- a/docker/dev/_nginx/default.conf +++ /dev/null @@ -1,59 +0,0 @@ -# format like 'main' excluding user agent -log_format mtt '$time_local "$request" $status $body_bytes_sent "$http_referer"'; -log_format mtt2 '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer"'; -access_log off; - -upstream fpm { - server fpm:9000; -} - -server { - listen 80; - server_name localhost; - root /var/www/html; # same as php-fpm - - access_log /var/log/nginx/access.log mtt; - - index index.php index.html; - autoindex off; - - location = /phpinfo { - include fastcgi_params; - fastcgi_param SCRIPT_FILENAME /var/www/phpinfo/phpinfo.php; - fastcgi_pass fpm; - } - - location /api/ { - rewrite ^/api/(.*) /api.php/$1 last; - } - - location / { - try_files $uri $uri/ =404; - } - - location ~ [^/]\.php(/|$) { - - fastcgi_split_path_info ^(.+?\.php)(/.*)$; - if (!-f $document_root$fastcgi_script_name) { - return 404; - } - include fastcgi_params; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_param PATH_INFO $fastcgi_path_info; - fastcgi_index index.php; - fastcgi_pass fpm; - } - - location /db/ { - return 404; #deny all - } - - location /includes/ { - return 404; #deny all - } - - location ~ /\.ht { - return 404; #deny all - } - -} diff --git a/docker/dev/mtt-php72-angie-postgres10/.env b/docker/dev/mtt-php72-angie-postgres10/.env deleted file mode 100644 index b32391f..0000000 --- a/docker/dev/mtt-php72-angie-postgres10/.env +++ /dev/null @@ -1 +0,0 @@ -PLATFORM_NAME=mtt-dev-php72-angie-postgres10 diff --git a/docker/dev/mtt-php72-angie-postgres10/Dockerfile-fpm b/docker/dev/mtt-php72-angie-postgres10/Dockerfile-fpm deleted file mode 100644 index 49c5b6d..0000000 --- a/docker/dev/mtt-php72-angie-postgres10/Dockerfile-fpm +++ /dev/null @@ -1,17 +0,0 @@ -FROM php:7.2-fpm-alpine - -RUN apk add --update-cache libpq postgresql-dev && \ - docker-php-ext-install pdo_mysql pdo_pgsql && \ - apk del postgresql-dev && rm -rf /var/cache/apk/* && \ - mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" && \ - mkdir /var/www/phpinfo && \ - echo " /var/www/phpinfo/phpinfo.php && \ - curl -o /usr/local/bin/phpunit -fL "https://phar.phpunit.de/phpunit-8.phar" && \ - chmod +x /usr/local/bin/phpunit && \ - ln -s html /var/www/src - -COPY php-mtt.ini /usr/local/etc/php/conf.d/ -COPY php-opcache.ini /usr/local/etc/php/conf.d/ -COPY php-fpm-www.conf /usr/local/etc/php-fpm.d/www.conf - -VOLUME /var/www/html diff --git a/docker/dev/mtt-php72-angie-postgres10/compose.yml b/docker/dev/mtt-php72-angie-postgres10/compose.yml deleted file mode 100644 index 88f91df..0000000 --- a/docker/dev/mtt-php72-angie-postgres10/compose.yml +++ /dev/null @@ -1,58 +0,0 @@ -version: "3.9" - -networks: - network: - name: "${PLATFORM_NAME}-network" - -services: - web: - build: - context: ../_nginx - dockerfile: Dockerfile-angie-alpine - image: mtt-dev/angie:alpine - container_name: ${PLATFORM_NAME}-web - ports: - - "8080:80" - volumes: - - ../../../src:/var/www/html - depends_on: - - fpm - networks: - - network - - fpm: - build: - context: . - dockerfile: Dockerfile-fpm - image: mtt-dev/php:7.2-fpm-alpine - container_name: ${PLATFORM_NAME}-fpm - environment: - - MTT_ENABLE_DEBUG=YES - - MTT_DB_TYPE=postgres - - MTT_API_USE_PATH_INFO=YES - - MTT_DB_HOST=db - - MTT_DB_NAME=mtt - - MTT_DB_USER=mtt - - MTT_DB_PASSWORD=mtt - - MTT_DB_PREFIX=mtt_ - volumes: - - ../../../src:/var/www/html - - ../../../tests:/var/www/tests - - ./php-mtt.ini:/usr/local/etc/php/conf.d/php-mtt.ini - - ./php-opcache.ini:/usr/local/etc/php/conf.d/php-opcache.ini - networks: - - network - - db: - # do not use alpine image due to missing locales - image: postgres:10.0 - container_name: ${PLATFORM_NAME}-db - userns_mode: keep-id - environment: - POSTGRES_PASSWORD: mtt - POSTGRES_USER: mtt - POSTGRES_DB: mtt - volumes: - - ../_postgres10/db_data:/var/lib/postgresql/data - networks: - - network diff --git a/docker/dev/mtt-php72-angie-postgres10/php-fpm-www.conf b/docker/dev/mtt-php72-angie-postgres10/php-fpm-www.conf deleted file mode 100644 index c8c06bd..0000000 --- a/docker/dev/mtt-php72-angie-postgres10/php-fpm-www.conf +++ /dev/null @@ -1,13 +0,0 @@ -[www] -user = www-data -group = www-data -listen = 127.0.0.1:9000 -pm = dynamic -pm.max_children = 5 -pm.start_servers = 2 -pm.min_spare_servers = 1 -pm.max_spare_servers = 3 -pm.max_requests = 500 - -access.format = "%R - %u [%t] \"%m %r\" %s %f" -access.log = /dev/null diff --git a/docker/dev/mtt-php72-angie-postgres10/php-mtt.ini b/docker/dev/mtt-php72-angie-postgres10/php-mtt.ini deleted file mode 100644 index f9b6186..0000000 --- a/docker/dev/mtt-php72-angie-postgres10/php-mtt.ini +++ /dev/null @@ -1,10 +0,0 @@ - -; Since PHP 5.4 E_STRICT is included in E_ALL -error_reporting = E_ALL - -log_errors = On -display_errors = On -display_startup_errors = On - -cgi.fix_pathinfo=0 -session.gc_divisor = 100 diff --git a/docker/dev/mtt-php72-angie-postgres10/php-opcache.ini b/docker/dev/mtt-php72-angie-postgres10/php-opcache.ini deleted file mode 100644 index 2866d5c..0000000 --- a/docker/dev/mtt-php72-angie-postgres10/php-opcache.ini +++ /dev/null @@ -1,42 +0,0 @@ -;; opcache.ini - -;; check /usr/local/etc/php/conf.d if exists docker-php-ext-opcache.ini - -; To disable opcache just comment this line -zend_extension=opcache.so - -[opcache] -opcache.enable=1 -opcache.enable_cli=1 - -; JIT will work only if opcache is enabled and jit_buffer_size is not zero. -; To disable JIT set the buffer size to 0. -opcache.jit_buffer_size=64M - -; JIT mode. Read more at https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.jit -; Default is tracing. -opcache.jit=tracing - -; The size of the shared memory storage used by OPcache, in megabytes. The minimum permissible value is "8", which is enforced if a smaller value is set. -; Default is 128. -opcache.memory_consumption=128 - -; The maximum number of keys (and therefore scripts) in the OPcache hash table. -; The actual value used will be the first number in the set of prime numbers -; { 223, 463, 983, 1979, 3907, 7963, 16229, 32531, 65407, 130987, 262237, 524521, 1048793 } -; that is greater than or equal to the configured value. -; The minimum value is 200. The maximum value is 1000000. Values outside of this range are clamped to the permissible range. -; Default is 10000. -opcache.max_accelerated_files=1000 - -; How often to check script timestamps for updates, in seconds. 0 will result in OPcache checking for updates on every request. -; This configuration directive is ignored if opcache.validate_timestamps is disabled. -; Default is 2. -opcache.revalidate_freq=2 - -; If enabled, OPcache will check for updated scripts every opcache.revalidate_freq seconds. -; When this directive is disabled, you must reset OPcache manually via opcache_reset(), opcache_invalidate() -; or by restarting the Web server for changes to the filesystem to take effect. -; Default is 1. -;; Override in docker-compose -opcache.validate_timestamps=1 diff --git a/docker/dev/mtt-php72-apache-mariadb100/.env b/docker/dev/mtt-php72-apache-mariadb100/.env deleted file mode 100644 index ebb4320..0000000 --- a/docker/dev/mtt-php72-apache-mariadb100/.env +++ /dev/null @@ -1 +0,0 @@ -PLATFORM_NAME=mtt-dev-php72-apache-mariadb100 diff --git a/docker/dev/mtt-php72-apache-mariadb100/compose.yml b/docker/dev/mtt-php72-apache-mariadb100/compose.yml deleted file mode 100644 index 84e0c7b..0000000 --- a/docker/dev/mtt-php72-apache-mariadb100/compose.yml +++ /dev/null @@ -1,47 +0,0 @@ -version: "3.9" - -networks: - network: - name: "${PLATFORM_NAME}-network" - -services: - web: - build: - context: ../mtt-php72-apache/ - dockerfile: Dockerfile-web - image: mtt-dev/php:7.2-apache - container_name: ${PLATFORM_NAME}-web - ports: - - "8080:80" - environment: - - MTT_ENABLE_DEBUG=YES - - MTT_DB_TYPE=mysql - - MTT_DB_HOST=db - - MTT_DB_NAME=mytinytodo - - MTT_DB_USER=mtt - - MTT_DB_PASSWORD=mtt - - MTT_DB_PREFIX=mtt_ - - MTT_DB_DRIVER=mysqli - volumes: - - ../../../src:/var/www/html - - ../mtt-php72-apache/php-mtt.ini:/usr/local/etc/php/conf.d/php-mtt.ini - - ../mtt-php72-apache/php-opcache.ini:/usr/local/etc/php/conf.d/php-opcache.ini - depends_on: - - db - networks: - - network - - db: - image: mariadb:10.0.15 - container_name: ${PLATFORM_NAME}-db - #restart: always - environment: - MYSQL_ROOT_PASSWORD: JustForDev - MYSQL_USER: mtt - MYSQL_PASSWORD: mtt - MYSQL_DATABASE: mytinytodo - volumes: - - ../_mariadb100/my.cnf:/etc/mysql/conf.d/my.cnf - - ../_mariadb100/db_data:/var/lib/mysql - networks: - - network diff --git a/docker/dev/mtt-php72-apache-mariadb105/.env b/docker/dev/mtt-php72-apache-mariadb105/.env deleted file mode 100644 index 32d82cd..0000000 --- a/docker/dev/mtt-php72-apache-mariadb105/.env +++ /dev/null @@ -1 +0,0 @@ -PLATFORM_NAME=mtt-dev-php72-apache-mariadb105 diff --git a/docker/dev/mtt-php72-apache-mariadb105/compose.yml b/docker/dev/mtt-php72-apache-mariadb105/compose.yml deleted file mode 100644 index fd8c7dc..0000000 --- a/docker/dev/mtt-php72-apache-mariadb105/compose.yml +++ /dev/null @@ -1,47 +0,0 @@ -version: "3.9" - -networks: - network: - name: "${PLATFORM_NAME}-network" - -services: - web: - build: - context: ../mtt-php72-apache/ - dockerfile: Dockerfile-web - image: mtt-dev/php:7.2-apache - container_name: ${PLATFORM_NAME}-web - ports: - - "8080:80" - environment: - - MTT_ENABLE_DEBUG=YES - - MTT_DB_TYPE=mysql - - MTT_DB_HOST=db - - MTT_DB_NAME=mytinytodo - - MTT_DB_USER=mtt - - MTT_DB_PASSWORD=mtt - - MTT_DB_PREFIX=mtt_ - - MTT_DB_DRIVER=mysqli - volumes: - - ../../../src:/var/www/html - - ../mtt-php72-apache/php-mtt.ini:/usr/local/etc/php/conf.d/php-mtt.ini - - ../mtt-php72-apache/php-opcache.ini:/usr/local/etc/php/conf.d/php-opcache.ini - depends_on: - - db - networks: - - network - - db: - image: mariadb:10.5 - container_name: ${PLATFORM_NAME}-db - #restart: always - environment: - MARIADB_ROOT_PASSWORD: JustForDev - MARIADB_USER: mtt - MARIADB_PASSWORD: mtt - MARIADB_DATABASE: mytinytodo - volumes: - - ../_mariadb105/my.cnf:/etc/mysql/conf.d/my.cnf - - ../_mariadb105/db_data:/var/lib/mysql - networks: - - network diff --git a/docker/dev/mtt-php72-apache-postgres10/.env b/docker/dev/mtt-php72-apache-postgres10/.env deleted file mode 100644 index 927f4f3..0000000 --- a/docker/dev/mtt-php72-apache-postgres10/.env +++ /dev/null @@ -1 +0,0 @@ -PLATFORM_NAME=mtt-dev-php72-apache-postgres10 diff --git a/docker/dev/mtt-php72-apache-postgres10/compose.yml b/docker/dev/mtt-php72-apache-postgres10/compose.yml deleted file mode 100644 index e1b0e71..0000000 --- a/docker/dev/mtt-php72-apache-postgres10/compose.yml +++ /dev/null @@ -1,45 +0,0 @@ -version: "3.9" - -networks: - network: - name: "${PLATFORM_NAME}-network" - -services: - web: - build: - context: ../mtt-php72-apache/ - dockerfile: Dockerfile-web - image: mtt-dev/php:7.2-apache - container_name: ${PLATFORM_NAME}-web - ports: - - "8080:80" - environment: - - MTT_ENABLE_DEBUG=YES - - MTT_DB_TYPE=postgres - - MTT_DB_HOST=db - - MTT_DB_NAME=mtt - - MTT_DB_USER=mtt - - MTT_DB_PASSWORD=mtt - - MTT_DB_PREFIX=mtt_ - volumes: - - ../../../src:/var/www/html - - ../mtt-php72-apache/php-mtt.ini:/usr/local/etc/php/conf.d/php-mtt.ini - - ../mtt-php72-apache/php-opcache.ini:/usr/local/etc/php/conf.d/php-opcache.ini - depends_on: - - db - networks: - - network - - db: - # do not use alpine image due to missing locales - image: postgres:10.0 - container_name: ${PLATFORM_NAME}-db - userns_mode: keep-id - environment: - POSTGRES_PASSWORD: mtt - POSTGRES_USER: mtt - POSTGRES_DB: mtt - volumes: - - ../_postgres10/db_data:/var/lib/postgresql/data - networks: - - network diff --git a/docker/dev/mtt-php72-apache/.env b/docker/dev/mtt-php72-apache/.env deleted file mode 100644 index 456326f..0000000 --- a/docker/dev/mtt-php72-apache/.env +++ /dev/null @@ -1 +0,0 @@ -PLATFORM_NAME=mtt-dev-php72-apache diff --git a/docker/dev/mtt-php72-apache/Dockerfile-web b/docker/dev/mtt-php72-apache/Dockerfile-web deleted file mode 100644 index ee64439..0000000 --- a/docker/dev/mtt-php72-apache/Dockerfile-web +++ /dev/null @@ -1,18 +0,0 @@ -FROM php:7.2-apache-buster - -RUN apt-get update && apt-get install -y libpq5 libpq-dev && \ - docker-php-ext-install mysqli pdo_pgsql && \ - apt-get remove -y libpq-dev && apt-get -y autoremove && \ - mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" && \ - mkdir /var/www/phpinfo && \ - echo " /var/www/phpinfo/phpinfo.php && \ - echo 'Alias "/phpinfo" "/var/www/phpinfo/phpinfo.php"' > /etc/apache2/conf-enabled/phpinfo.conf && \ - echo 'LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\"" combined' > /etc/apache2/conf-enabled/logformat.conf && \ - a2enmod rewrite && \ - curl -o /usr/local/bin/phpunit -fL "https://phar.phpunit.de/phpunit-8.phar" && \ - chmod +x /usr/local/bin/phpunit && \ - ln -s html /var/www/src - - -COPY php-mtt.ini /usr/local/etc/php/conf.d/ -COPY php-opcache.ini /usr/local/etc/php/conf.d/ diff --git a/docker/dev/mtt-php72-apache/compose.yml b/docker/dev/mtt-php72-apache/compose.yml deleted file mode 100644 index 5244805..0000000 --- a/docker/dev/mtt-php72-apache/compose.yml +++ /dev/null @@ -1,17 +0,0 @@ -services: - web: - build: - context: . - dockerfile: Dockerfile-web - image: mtt-dev/php:7.2-apache - container_name: ${PLATFORM_NAME}-web - ports: - - "8080:80" - environment: - - MTT_ENABLE_DEBUG=YES - - MTT_DB_TYPE=sqlite - volumes: - - ../../../src:/var/www/html - - ../../../tests:/var/www/tests - - ./php-mtt.ini:/usr/local/etc/php/conf.d/php-mtt.ini - - ./php-opcache.ini:/usr/local/etc/php/conf.d/php-opcache.ini diff --git a/docker/dev/mtt-php72-apache/php-mtt.ini b/docker/dev/mtt-php72-apache/php-mtt.ini deleted file mode 100644 index c6b0ee0..0000000 --- a/docker/dev/mtt-php72-apache/php-mtt.ini +++ /dev/null @@ -1,11 +0,0 @@ - -; Since PHP 5.4 E_STRICT is included in E_ALL -error_reporting = E_ALL - -log_errors = On -display_errors = On -display_startup_errors = On - -session.gc_divisor = 100 - -allow_url_fopen=1 diff --git a/docker/dev/mtt-php72-apache/php-opcache.ini b/docker/dev/mtt-php72-apache/php-opcache.ini deleted file mode 100644 index 9e1abaa..0000000 --- a/docker/dev/mtt-php72-apache/php-opcache.ini +++ /dev/null @@ -1,34 +0,0 @@ -;; opcache.ini - -;; check /usr/local/etc/php/conf.d if exists docker-php-ext-opcache.ini - -; To disable opcache just comment this line -zend_extension=opcache.so - -[opcache] -opcache.enable=0 -opcache.enable_cli=0 - -; The size of the shared memory storage used by OPcache, in megabytes. The minimum permissible value is "8", which is enforced if a smaller value is set. -; Default is 128. -opcache.memory_consumption=128 - -; The maximum number of keys (and therefore scripts) in the OPcache hash table. -; The actual value used will be the first number in the set of prime numbers -; { 223, 463, 983, 1979, 3907, 7963, 16229, 32531, 65407, 130987, 262237, 524521, 1048793 } -; that is greater than or equal to the configured value. -; The minimum value is 200. The maximum value is 1000000. Values outside of this range are clamped to the permissible range. -; Default is 10000. -opcache.max_accelerated_files=1000 - -; How often to check script timestamps for updates, in seconds. 0 will result in OPcache checking for updates on every request. -; This configuration directive is ignored if opcache.validate_timestamps is disabled. -; Default is 2. -opcache.revalidate_freq=2 - -; If enabled, OPcache will check for updated scripts every opcache.revalidate_freq seconds. -; When this directive is disabled, you must reset OPcache manually via opcache_reset(), opcache_invalidate() -; or by restarting the Web server for changes to the filesystem to take effect. -; Default is 1. -;; Override in docker-compose -opcache.validate_timestamps=1 diff --git a/docker/dev/mtt-php74-apache/.env b/docker/dev/mtt-php74-apache/.env deleted file mode 100644 index 9129463..0000000 --- a/docker/dev/mtt-php74-apache/.env +++ /dev/null @@ -1 +0,0 @@ -PLATFORM_NAME=mtt-dev-php74-apache diff --git a/docker/dev/mtt-php74-apache/Dockerfile-web b/docker/dev/mtt-php74-apache/Dockerfile-web deleted file mode 100644 index ae0093d..0000000 --- a/docker/dev/mtt-php74-apache/Dockerfile-web +++ /dev/null @@ -1,15 +0,0 @@ -FROM php:7.4-apache - -RUN docker-php-ext-install mysqli && \ - mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" && \ - mkdir /var/www/phpinfo && \ - echo " /var/www/phpinfo/phpinfo.php && \ - echo 'Alias "/phpinfo" "/var/www/phpinfo/phpinfo.php"' > /etc/apache2/conf-enabled/phpinfo.conf && \ - echo 'LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\"" combined' > /etc/apache2/conf-enabled/logformat.conf && \ - a2enmod rewrite && \ - curl -o /usr/local/bin/phpunit -fL "https://phar.phpunit.de/phpunit-9.phar" && \ - chmod +x /usr/local/bin/phpunit && \ - ln -s html /var/www/src - -#COPY php-mtt.ini /usr/local/etc/php/conf.d/ -#COPY php-opcache.ini /usr/local/etc/php/conf.d/ diff --git a/docker/dev/mtt-php74-apache/compose.yml b/docker/dev/mtt-php74-apache/compose.yml deleted file mode 100644 index 48dca4f..0000000 --- a/docker/dev/mtt-php74-apache/compose.yml +++ /dev/null @@ -1,17 +0,0 @@ -services: - web: - build: - context: . - dockerfile: Dockerfile-web - image: mtt-dev/php:7.4-apache - container_name: ${PLATFORM_NAME}-web - ports: - - "8080:80" - environment: - - MTT_ENABLE_DEBUG=YES - - MTT_DB_TYPE=sqlite - volumes: - - ../../../src:/var/www/html - - ../../../tests:/var/www/tests - - ./php-mtt.ini:/usr/local/etc/php/conf.d/php-mtt.ini - - ./php-opcache.ini:/usr/local/etc/php/conf.d/php-opcache.ini diff --git a/docker/dev/mtt-php74-apache/php-mtt.ini b/docker/dev/mtt-php74-apache/php-mtt.ini deleted file mode 100644 index 5503e6a..0000000 --- a/docker/dev/mtt-php74-apache/php-mtt.ini +++ /dev/null @@ -1,9 +0,0 @@ - -; Since PHP 5.4 E_STRICT is included in E_ALL -error_reporting = E_ALL - -log_errors = On -display_errors = On -display_startup_errors = On - -session.gc_divisor = 100 diff --git a/docker/dev/mtt-php74-apache/php-opcache.ini b/docker/dev/mtt-php74-apache/php-opcache.ini deleted file mode 100644 index 9e1abaa..0000000 --- a/docker/dev/mtt-php74-apache/php-opcache.ini +++ /dev/null @@ -1,34 +0,0 @@ -;; opcache.ini - -;; check /usr/local/etc/php/conf.d if exists docker-php-ext-opcache.ini - -; To disable opcache just comment this line -zend_extension=opcache.so - -[opcache] -opcache.enable=0 -opcache.enable_cli=0 - -; The size of the shared memory storage used by OPcache, in megabytes. The minimum permissible value is "8", which is enforced if a smaller value is set. -; Default is 128. -opcache.memory_consumption=128 - -; The maximum number of keys (and therefore scripts) in the OPcache hash table. -; The actual value used will be the first number in the set of prime numbers -; { 223, 463, 983, 1979, 3907, 7963, 16229, 32531, 65407, 130987, 262237, 524521, 1048793 } -; that is greater than or equal to the configured value. -; The minimum value is 200. The maximum value is 1000000. Values outside of this range are clamped to the permissible range. -; Default is 10000. -opcache.max_accelerated_files=1000 - -; How often to check script timestamps for updates, in seconds. 0 will result in OPcache checking for updates on every request. -; This configuration directive is ignored if opcache.validate_timestamps is disabled. -; Default is 2. -opcache.revalidate_freq=2 - -; If enabled, OPcache will check for updated scripts every opcache.revalidate_freq seconds. -; When this directive is disabled, you must reset OPcache manually via opcache_reset(), opcache_invalidate() -; or by restarting the Web server for changes to the filesystem to take effect. -; Default is 1. -;; Override in docker-compose -opcache.validate_timestamps=1 diff --git a/docker/dev/mtt-php74-nginx/.env b/docker/dev/mtt-php74-nginx/.env deleted file mode 100644 index 138fba2..0000000 --- a/docker/dev/mtt-php74-nginx/.env +++ /dev/null @@ -1 +0,0 @@ -PLATFORM_NAME=mtt-dev-php74-nginx diff --git a/docker/dev/mtt-php74-nginx/Dockerfile-fpm b/docker/dev/mtt-php74-nginx/Dockerfile-fpm deleted file mode 100644 index df1bf3d..0000000 --- a/docker/dev/mtt-php74-nginx/Dockerfile-fpm +++ /dev/null @@ -1,11 +0,0 @@ -FROM php:7.4-fpm - -RUN docker-php-ext-install mysqli && \ - mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" && \ - mkdir /var/www/phpinfo && \ - echo " /var/www/phpinfo/phpinfo.php - -#COPY php-mtt.ini /usr/local/etc/php/conf.d/ -#COPY php-opcache.ini /usr/local/etc/php/conf.d/ - -VOLUME /var/www/html diff --git a/docker/dev/mtt-php74-nginx/compose.yml b/docker/dev/mtt-php74-nginx/compose.yml deleted file mode 100644 index 2186d16..0000000 --- a/docker/dev/mtt-php74-nginx/compose.yml +++ /dev/null @@ -1,37 +0,0 @@ -version: "3.9" - -networks: - network: - name: "${PLATFORM_NAME}-network" - -services: - web: - build: - context: ../_nginx - dockerfile: Dockerfile-nginx - image: mtt-dev/nginx - container_name: ${PLATFORM_NAME}-web - ports: - - "8080:80" - volumes: - - ../../../src:/var/www/html - depends_on: - - fpm - networks: - - network - - fpm: - build: - context: . - dockerfile: Dockerfile-fpm - image: mtt-dev/php:7.4-fpm - container_name: ${PLATFORM_NAME}-fpm - environment: - - MTT_ENABLE_DEBUG=YES - - MTT_DB_TYPE=sqlite - volumes: - - ../../../src:/var/www/html - - ./php-mtt.ini:/usr/local/etc/php/conf.d/php-mtt.ini - - ./php-opcache.ini:/usr/local/etc/php/conf.d/php-opcache.ini - networks: - - network diff --git a/docker/dev/mtt-php74-nginx/php-mtt.ini b/docker/dev/mtt-php74-nginx/php-mtt.ini deleted file mode 100644 index 03afd85..0000000 --- a/docker/dev/mtt-php74-nginx/php-mtt.ini +++ /dev/null @@ -1,10 +0,0 @@ - -; Since PHP 5.4 E_STRICT is included in E_ALL -error_reporting = E_ALL - -log_errors = On -display_errors = On -display_startup_errors = On - -session.gc_divisor = 100 -cgi.fix_pathinfo=0 \ No newline at end of file diff --git a/docker/dev/mtt-php74-nginx/php-opcache.ini b/docker/dev/mtt-php74-nginx/php-opcache.ini deleted file mode 100644 index 2866d5c..0000000 --- a/docker/dev/mtt-php74-nginx/php-opcache.ini +++ /dev/null @@ -1,42 +0,0 @@ -;; opcache.ini - -;; check /usr/local/etc/php/conf.d if exists docker-php-ext-opcache.ini - -; To disable opcache just comment this line -zend_extension=opcache.so - -[opcache] -opcache.enable=1 -opcache.enable_cli=1 - -; JIT will work only if opcache is enabled and jit_buffer_size is not zero. -; To disable JIT set the buffer size to 0. -opcache.jit_buffer_size=64M - -; JIT mode. Read more at https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.jit -; Default is tracing. -opcache.jit=tracing - -; The size of the shared memory storage used by OPcache, in megabytes. The minimum permissible value is "8", which is enforced if a smaller value is set. -; Default is 128. -opcache.memory_consumption=128 - -; The maximum number of keys (and therefore scripts) in the OPcache hash table. -; The actual value used will be the first number in the set of prime numbers -; { 223, 463, 983, 1979, 3907, 7963, 16229, 32531, 65407, 130987, 262237, 524521, 1048793 } -; that is greater than or equal to the configured value. -; The minimum value is 200. The maximum value is 1000000. Values outside of this range are clamped to the permissible range. -; Default is 10000. -opcache.max_accelerated_files=1000 - -; How often to check script timestamps for updates, in seconds. 0 will result in OPcache checking for updates on every request. -; This configuration directive is ignored if opcache.validate_timestamps is disabled. -; Default is 2. -opcache.revalidate_freq=2 - -; If enabled, OPcache will check for updated scripts every opcache.revalidate_freq seconds. -; When this directive is disabled, you must reset OPcache manually via opcache_reset(), opcache_invalidate() -; or by restarting the Web server for changes to the filesystem to take effect. -; Default is 1. -;; Override in docker-compose -opcache.validate_timestamps=1 diff --git a/docker/dev/mtt-php80-apache-mariadb105/.env b/docker/dev/mtt-php80-apache-mariadb105/.env deleted file mode 100644 index a3961ac..0000000 --- a/docker/dev/mtt-php80-apache-mariadb105/.env +++ /dev/null @@ -1 +0,0 @@ -PLATFORM_NAME=mtt-dev-php80-apache-mariadb105 diff --git a/docker/dev/mtt-php80-apache-mariadb105/compose.yml b/docker/dev/mtt-php80-apache-mariadb105/compose.yml deleted file mode 100644 index 8230c5c..0000000 --- a/docker/dev/mtt-php80-apache-mariadb105/compose.yml +++ /dev/null @@ -1,45 +0,0 @@ -version: "3.9" - -networks: - network: - name: "${PLATFORM_NAME}-network" - -services: - web: - build: - context: ../mtt-php80-apache/ - dockerfile: Dockerfile-web - image: mtt-dev/php:8.0-apache - container_name: ${PLATFORM_NAME}-web - ports: - - "8080:80" - environment: - - MTT_ENABLE_DEBUG=YES - - MTT_DB_TYPE=mysql - - MTT_DB_HOST=db - - MTT_DB_NAME=mytinytodo - - MTT_DB_USER=mtt - - MTT_DB_PASSWORD=mtt - - MTT_DB_PREFIX=mtt_ - - MTT_DB_DRIVER=mysqli - volumes: - - ../../../src:/var/www/html - depends_on: - - db - networks: - - network - - db: - image: mariadb:10.5 - container_name: ${PLATFORM_NAME}-db - #restart: always - environment: - MARIADB_ROOT_PASSWORD: JustForDev - MARIADB_USER: mtt - MARIADB_PASSWORD: mtt - MARIADB_DATABASE: mytinytodo - volumes: - - ../_mariadb105/my.cnf:/etc/mysql/conf.d/my.cnf - - ../_mariadb105/db_data:/var/lib/mysql - networks: - - network diff --git a/docker/dev/mtt-php80-apache/.env b/docker/dev/mtt-php80-apache/.env deleted file mode 100644 index d2988cc..0000000 --- a/docker/dev/mtt-php80-apache/.env +++ /dev/null @@ -1 +0,0 @@ -PLATFORM_NAME=mtt-dev-php80-apache diff --git a/docker/dev/mtt-php80-apache/Dockerfile-web b/docker/dev/mtt-php80-apache/Dockerfile-web deleted file mode 100644 index 4c7faf8..0000000 --- a/docker/dev/mtt-php80-apache/Dockerfile-web +++ /dev/null @@ -1,15 +0,0 @@ -FROM php:8.0-apache - -RUN docker-php-ext-install mysqli && \ - mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" && \ - mkdir /var/www/phpinfo && \ - echo " /var/www/phpinfo/phpinfo.php && \ - echo 'Alias "/phpinfo" "/var/www/phpinfo/phpinfo.php"' > /etc/apache2/conf-enabled/phpinfo.conf && \ - echo 'LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\"" combined' > /etc/apache2/conf-enabled/logformat.conf && \ - a2enmod rewrite && \ - curl -o /usr/local/bin/phpunit -fL "https://phar.phpunit.de/phpunit-9.phar" && \ - chmod +x /usr/local/bin/phpunit && \ - ln -s html /var/www/src - -COPY php-mtt.ini /usr/local/etc/php/conf.d/ -COPY php-opcache.ini /usr/local/etc/php/conf.d/ diff --git a/docker/dev/mtt-php80-apache/compose.yml b/docker/dev/mtt-php80-apache/compose.yml deleted file mode 100644 index b0a0664..0000000 --- a/docker/dev/mtt-php80-apache/compose.yml +++ /dev/null @@ -1,16 +0,0 @@ -version: "3.9" - -services: - web: - build: - context: . - dockerfile: Dockerfile-web - image: mtt-dev/php:8.0-apache - container_name: ${PLATFORM_NAME}-web - ports: - - "8080:80" - environment: - - MTT_ENABLE_DEBUG=YES - - MTT_DB_TYPE=sqlite - volumes: - - ../../../src:/var/www/html diff --git a/docker/dev/mtt-php80-apache/php-mtt.ini b/docker/dev/mtt-php80-apache/php-mtt.ini deleted file mode 100644 index 5503e6a..0000000 --- a/docker/dev/mtt-php80-apache/php-mtt.ini +++ /dev/null @@ -1,9 +0,0 @@ - -; Since PHP 5.4 E_STRICT is included in E_ALL -error_reporting = E_ALL - -log_errors = On -display_errors = On -display_startup_errors = On - -session.gc_divisor = 100 diff --git a/docker/dev/mtt-php80-apache/php-opcache.ini b/docker/dev/mtt-php80-apache/php-opcache.ini deleted file mode 100644 index 70c3516..0000000 --- a/docker/dev/mtt-php80-apache/php-opcache.ini +++ /dev/null @@ -1,42 +0,0 @@ -;; opcache.ini - -;; check /usr/local/etc/php/conf.d if exists docker-php-ext-opcache.ini - -; To disable opcache just comment this line -zend_extension=opcache.so - -[opcache] -opcache.enable=0 -opcache.enable_cli=0 - -; JIT will work only if opcache is enabled and jit_buffer_size is not zero. -; To disable JIT set the buffer size to 0. -opcache.jit_buffer_size=64M - -; JIT mode. Read more at https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.jit -; Default is tracing. -opcache.jit=tracing - -; The size of the shared memory storage used by OPcache, in megabytes. The minimum permissible value is "8", which is enforced if a smaller value is set. -; Default is 128. -opcache.memory_consumption=128 - -; The maximum number of keys (and therefore scripts) in the OPcache hash table. -; The actual value used will be the first number in the set of prime numbers -; { 223, 463, 983, 1979, 3907, 7963, 16229, 32531, 65407, 130987, 262237, 524521, 1048793 } -; that is greater than or equal to the configured value. -; The minimum value is 200. The maximum value is 1000000. Values outside of this range are clamped to the permissible range. -; Default is 10000. -opcache.max_accelerated_files=1000 - -; How often to check script timestamps for updates, in seconds. 0 will result in OPcache checking for updates on every request. -; This configuration directive is ignored if opcache.validate_timestamps is disabled. -; Default is 2. -opcache.revalidate_freq=2 - -; If enabled, OPcache will check for updated scripts every opcache.revalidate_freq seconds. -; When this directive is disabled, you must reset OPcache manually via opcache_reset(), opcache_invalidate() -; or by restarting the Web server for changes to the filesystem to take effect. -; Default is 1. -;; Override in docker-compose -opcache.validate_timestamps=1 diff --git a/docker/dev/mtt-php81-apache-mariadb108/.env b/docker/dev/mtt-php81-apache-mariadb108/.env deleted file mode 100644 index cf81ec9..0000000 --- a/docker/dev/mtt-php81-apache-mariadb108/.env +++ /dev/null @@ -1 +0,0 @@ -PLATFORM_NAME=mtt-dev-php81-apache-mariadb108 diff --git a/docker/dev/mtt-php81-apache-mariadb108/compose.yml b/docker/dev/mtt-php81-apache-mariadb108/compose.yml deleted file mode 100644 index 788e3cc..0000000 --- a/docker/dev/mtt-php81-apache-mariadb108/compose.yml +++ /dev/null @@ -1,56 +0,0 @@ -version: "3.9" - -networks: - network: - name: "${PLATFORM_NAME}-network" - -services: - web: - build: - context: ../mtt-php81-apache/ - dockerfile: Dockerfile-web - image: mtt-dev/php:8.1-apache - container_name: ${PLATFORM_NAME}-web - ports: - - "8080:80" - environment: - - MTT_ENABLE_DEBUG=YES - - MTT_DB_TYPE=mysql - - MTT_DB_HOST=db - - MTT_DB_NAME=mytinytodo - - MTT_DB_USER=mtt - - MTT_DB_PASSWORD=mtt - - MTT_DB_PREFIX=mtt_ - - MTT_DB_DRIVER=mysqli - volumes: - - ../../../src:/var/www/html - - ../../../tests:/var/www/tests - depends_on: - - db - networks: - - network - - db: - image: mariadb:10.8 - container_name: ${PLATFORM_NAME}-db - #restart: always - environment: - MARIADB_ROOT_PASSWORD: JustForDev - MARIADB_USER: mtt - MARIADB_PASSWORD: mtt - MARIADB_DATABASE: mytinytodo - volumes: - - ../_mariadb108/my.cnf:/etc/mysql/conf.d/my.cnf - - ../_mariadb108/db_data:/var/lib/mysql - networks: - - network - - adminer: - image: adminer:latest - container_name: ${PLATFORM_NAME}-adminer - environment: - ADMINER_DEFAULT_SERVER: db - ports: - - 8079:8080 - networks: - - network diff --git a/docker/dev/mtt-php81-apache/.env b/docker/dev/mtt-php81-apache/.env deleted file mode 100644 index 48f80ed..0000000 --- a/docker/dev/mtt-php81-apache/.env +++ /dev/null @@ -1 +0,0 @@ -PLATFORM_NAME=mtt-dev-php81-apache diff --git a/docker/dev/mtt-php81-apache/Dockerfile-web b/docker/dev/mtt-php81-apache/Dockerfile-web deleted file mode 100644 index b399e55..0000000 --- a/docker/dev/mtt-php81-apache/Dockerfile-web +++ /dev/null @@ -1,16 +0,0 @@ -FROM php:8.1-apache - -RUN docker-php-ext-install mysqli && \ - mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" && \ - mkdir /var/www/phpinfo && \ - echo " /var/www/phpinfo/phpinfo.php && \ - echo 'Alias "/phpinfo" "/var/www/phpinfo/phpinfo.php"' > /etc/apache2/conf-enabled/phpinfo.conf && \ - a2enmod rewrite && \ - echo 'LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\"" combined' > /etc/apache2/conf-enabled/logformat.conf && \ - curl -o /usr/local/bin/phpunit -fL "https://phar.phpunit.de/phpunit-9.phar" && \ - chmod +x /usr/local/bin/phpunit && \ - ln -s html /var/www/src - - -COPY php-mtt.ini /usr/local/etc/php/conf.d/ -COPY php-opcache.ini /usr/local/etc/php/conf.d/ diff --git a/docker/dev/mtt-php81-apache/compose.yml b/docker/dev/mtt-php81-apache/compose.yml deleted file mode 100644 index 38011d2..0000000 --- a/docker/dev/mtt-php81-apache/compose.yml +++ /dev/null @@ -1,16 +0,0 @@ -version: "3.9" - -services: - web: - build: - context: . - dockerfile: Dockerfile-web - image: mtt-dev/php:8.1-apache - container_name: ${PLATFORM_NAME}-web - ports: - - "8080:80" - environment: - - MTT_ENABLE_DEBUG=YES - - MTT_DB_TYPE=sqlite - volumes: - - ../../../src:/var/www/html diff --git a/docker/dev/mtt-php81-apache/php-mtt.ini b/docker/dev/mtt-php81-apache/php-mtt.ini deleted file mode 100644 index 60882d1..0000000 --- a/docker/dev/mtt-php81-apache/php-mtt.ini +++ /dev/null @@ -1,9 +0,0 @@ - -; Since PHP 5.4 E_STRICT is included in E_ALL -error_reporting = E_ALL - -log_errors = On -display_errors = On -display_startup_errors = On - -session.gc_divisor = 100 \ No newline at end of file diff --git a/docker/dev/mtt-php81-apache/php-opcache.ini b/docker/dev/mtt-php81-apache/php-opcache.ini deleted file mode 100644 index 70c3516..0000000 --- a/docker/dev/mtt-php81-apache/php-opcache.ini +++ /dev/null @@ -1,42 +0,0 @@ -;; opcache.ini - -;; check /usr/local/etc/php/conf.d if exists docker-php-ext-opcache.ini - -; To disable opcache just comment this line -zend_extension=opcache.so - -[opcache] -opcache.enable=0 -opcache.enable_cli=0 - -; JIT will work only if opcache is enabled and jit_buffer_size is not zero. -; To disable JIT set the buffer size to 0. -opcache.jit_buffer_size=64M - -; JIT mode. Read more at https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.jit -; Default is tracing. -opcache.jit=tracing - -; The size of the shared memory storage used by OPcache, in megabytes. The minimum permissible value is "8", which is enforced if a smaller value is set. -; Default is 128. -opcache.memory_consumption=128 - -; The maximum number of keys (and therefore scripts) in the OPcache hash table. -; The actual value used will be the first number in the set of prime numbers -; { 223, 463, 983, 1979, 3907, 7963, 16229, 32531, 65407, 130987, 262237, 524521, 1048793 } -; that is greater than or equal to the configured value. -; The minimum value is 200. The maximum value is 1000000. Values outside of this range are clamped to the permissible range. -; Default is 10000. -opcache.max_accelerated_files=1000 - -; How often to check script timestamps for updates, in seconds. 0 will result in OPcache checking for updates on every request. -; This configuration directive is ignored if opcache.validate_timestamps is disabled. -; Default is 2. -opcache.revalidate_freq=2 - -; If enabled, OPcache will check for updated scripts every opcache.revalidate_freq seconds. -; When this directive is disabled, you must reset OPcache manually via opcache_reset(), opcache_invalidate() -; or by restarting the Web server for changes to the filesystem to take effect. -; Default is 1. -;; Override in docker-compose -opcache.validate_timestamps=1 diff --git a/docker/dev/mtt-php82-angie-postgres10/.env b/docker/dev/mtt-php82-angie-postgres10/.env deleted file mode 100644 index ca7b6fa..0000000 --- a/docker/dev/mtt-php82-angie-postgres10/.env +++ /dev/null @@ -1 +0,0 @@ -PLATFORM_NAME=mtt-dev-php82-angie-postgres10 diff --git a/docker/dev/mtt-php82-angie-postgres10/compose.yml b/docker/dev/mtt-php82-angie-postgres10/compose.yml deleted file mode 100644 index 15c0695..0000000 --- a/docker/dev/mtt-php82-angie-postgres10/compose.yml +++ /dev/null @@ -1,58 +0,0 @@ -version: "3.9" - -networks: - network: - name: "${PLATFORM_NAME}-network" - -services: - web: - build: - context: ../_nginx - dockerfile: Dockerfile-angie-alpine - image: mtt-dev/angie:alpine - container_name: ${PLATFORM_NAME}-web - ports: - - "8080:80" - volumes: - - ../../../src:/var/www/html - depends_on: - - fpm - networks: - - network - - fpm: - build: - context: ../mtt-php82-angie - dockerfile: Dockerfile-fpm - image: mtt-dev/php:8.2-fpm-alpine - container_name: ${PLATFORM_NAME}-fpm - environment: - - MTT_ENABLE_DEBUG=YES - - MTT_DB_TYPE=postgres - - MTT_API_USE_PATH_INFO=YES - - MTT_DB_HOST=db - - MTT_DB_NAME=mtt - - MTT_DB_USER=mtt - - MTT_DB_PASSWORD=mtt - - MTT_DB_PREFIX=mtt_ - volumes: - - ../../../src:/var/www/html - - ../../../tests:/var/www/tests - - ../mtt-php82-angie/php-mtt.ini:/usr/local/etc/php/conf.d/php-mtt.ini - - ../mtt-php82-angie/php-opcache.ini:/usr/local/etc/php/conf.d/php-opcache.ini - networks: - - network - - db: - # do not use alpine image due to missing locales - image: postgres:10.0 - container_name: ${PLATFORM_NAME}-db - userns_mode: keep-id - environment: - POSTGRES_PASSWORD: mtt - POSTGRES_USER: mtt - POSTGRES_DB: mtt - volumes: - - ../_postgres10/db_data:/var/lib/postgresql/data - networks: - - network diff --git a/docker/dev/mtt-php82-angie/.env b/docker/dev/mtt-php82-angie/.env deleted file mode 100644 index 0993892..0000000 --- a/docker/dev/mtt-php82-angie/.env +++ /dev/null @@ -1 +0,0 @@ -PLATFORM_NAME=mtt-dev-php82-angie-alpine diff --git a/docker/dev/mtt-php82-angie/Dockerfile-fpm b/docker/dev/mtt-php82-angie/Dockerfile-fpm deleted file mode 100644 index b8e178c..0000000 --- a/docker/dev/mtt-php82-angie/Dockerfile-fpm +++ /dev/null @@ -1,17 +0,0 @@ -FROM php:8.2-fpm-alpine - -RUN apk add --update-cache libpq postgresql-dev icu icu-dev && \ - docker-php-ext-install pdo_mysql pdo_pgsql intl && \ - apk del postgresql-dev icu-dev && rm -rf /var/cache/apk/* && \ - mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" && \ - mkdir /var/www/phpinfo && \ - echo " /var/www/phpinfo/phpinfo.php && \ - curl -o /usr/local/bin/phpunit -fL "https://phar.phpunit.de/phpunit-10.phar" && \ - chmod +x /usr/local/bin/phpunit && \ - ln -s html /var/www/src - -COPY php-mtt.ini /usr/local/etc/php/conf.d/ -COPY php-opcache.ini /usr/local/etc/php/conf.d/ -COPY php-fpm-www.conf /usr/local/etc/php-fpm.d/www.conf - -VOLUME /var/www/html diff --git a/docker/dev/mtt-php82-angie/compose.yml b/docker/dev/mtt-php82-angie/compose.yml deleted file mode 100644 index 81a135f..0000000 --- a/docker/dev/mtt-php82-angie/compose.yml +++ /dev/null @@ -1,40 +0,0 @@ -version: "3.9" - -networks: - network: - name: "${PLATFORM_NAME}-network" - -services: - web: - build: - context: ../_nginx - dockerfile: Dockerfile-angie-alpine - image: mtt-dev/angie:alpine - container_name: ${PLATFORM_NAME}-web - ports: - - "8080:80" - volumes: - - ../../../src:/var/www/html - depends_on: - - fpm - networks: - - network - - fpm: - build: - context: . - dockerfile: Dockerfile-fpm - image: mtt-dev/php:8.2-fpm-alpine - container_name: ${PLATFORM_NAME}-fpm - environment: - - MTT_ENABLE_DEBUG=YES - - MTT_DB_TYPE=sqlite - - MTT_API_USE_PATH_INFO=YES - volumes: - - ../../../src:/var/www/html - - ../../../tests:/var/www/tests - - ./php-mtt.ini:/usr/local/etc/php/conf.d/php-mtt.ini - - ./php-opcache.ini:/usr/local/etc/php/conf.d/php-opcache.ini - - networks: - - network diff --git a/docker/dev/mtt-php82-angie/php-fpm-www.conf b/docker/dev/mtt-php82-angie/php-fpm-www.conf deleted file mode 100644 index c8c06bd..0000000 --- a/docker/dev/mtt-php82-angie/php-fpm-www.conf +++ /dev/null @@ -1,13 +0,0 @@ -[www] -user = www-data -group = www-data -listen = 127.0.0.1:9000 -pm = dynamic -pm.max_children = 5 -pm.start_servers = 2 -pm.min_spare_servers = 1 -pm.max_spare_servers = 3 -pm.max_requests = 500 - -access.format = "%R - %u [%t] \"%m %r\" %s %f" -access.log = /dev/null diff --git a/docker/dev/mtt-php82-angie/php-mtt.ini b/docker/dev/mtt-php82-angie/php-mtt.ini deleted file mode 100644 index 4ab4103..0000000 --- a/docker/dev/mtt-php82-angie/php-mtt.ini +++ /dev/null @@ -1,12 +0,0 @@ - -; Since PHP 5.4 E_STRICT is included in E_ALL -error_reporting = E_ALL - -log_errors = On -display_errors = On -display_startup_errors = On - -cgi.fix_pathinfo=0 -session.gc_divisor = 100 - -allow_url_fopen=1 diff --git a/docker/dev/mtt-php82-angie/php-opcache.ini b/docker/dev/mtt-php82-angie/php-opcache.ini deleted file mode 100644 index 2866d5c..0000000 --- a/docker/dev/mtt-php82-angie/php-opcache.ini +++ /dev/null @@ -1,42 +0,0 @@ -;; opcache.ini - -;; check /usr/local/etc/php/conf.d if exists docker-php-ext-opcache.ini - -; To disable opcache just comment this line -zend_extension=opcache.so - -[opcache] -opcache.enable=1 -opcache.enable_cli=1 - -; JIT will work only if opcache is enabled and jit_buffer_size is not zero. -; To disable JIT set the buffer size to 0. -opcache.jit_buffer_size=64M - -; JIT mode. Read more at https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.jit -; Default is tracing. -opcache.jit=tracing - -; The size of the shared memory storage used by OPcache, in megabytes. The minimum permissible value is "8", which is enforced if a smaller value is set. -; Default is 128. -opcache.memory_consumption=128 - -; The maximum number of keys (and therefore scripts) in the OPcache hash table. -; The actual value used will be the first number in the set of prime numbers -; { 223, 463, 983, 1979, 3907, 7963, 16229, 32531, 65407, 130987, 262237, 524521, 1048793 } -; that is greater than or equal to the configured value. -; The minimum value is 200. The maximum value is 1000000. Values outside of this range are clamped to the permissible range. -; Default is 10000. -opcache.max_accelerated_files=1000 - -; How often to check script timestamps for updates, in seconds. 0 will result in OPcache checking for updates on every request. -; This configuration directive is ignored if opcache.validate_timestamps is disabled. -; Default is 2. -opcache.revalidate_freq=2 - -; If enabled, OPcache will check for updated scripts every opcache.revalidate_freq seconds. -; When this directive is disabled, you must reset OPcache manually via opcache_reset(), opcache_invalidate() -; or by restarting the Web server for changes to the filesystem to take effect. -; Default is 1. -;; Override in docker-compose -opcache.validate_timestamps=1 diff --git a/docker/dev/mtt-php82-apache/.env b/docker/dev/mtt-php82-apache/.env deleted file mode 100644 index 3e2ed7e..0000000 --- a/docker/dev/mtt-php82-apache/.env +++ /dev/null @@ -1 +0,0 @@ -PLATFORM_NAME=mtt-dev-php82-apache diff --git a/docker/dev/mtt-php82-apache/Dockerfile-web b/docker/dev/mtt-php82-apache/Dockerfile-web deleted file mode 100644 index be632ba..0000000 --- a/docker/dev/mtt-php82-apache/Dockerfile-web +++ /dev/null @@ -1,17 +0,0 @@ -FROM php:8.2-apache-buster - -RUN apt-get update && apt-get install -y libicu-dev && \ - docker-php-ext-install mysqli intl && \ - apt-get -y autoremove && \ - mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" && \ - mkdir /var/www/phpinfo && \ - a2enmod rewrite && \ - echo " /var/www/phpinfo/phpinfo.php && \ - echo 'Alias "/phpinfo" "/var/www/phpinfo/phpinfo.php"' > /etc/apache2/conf-enabled/phpinfo.conf && \ - echo 'LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\"" combined' > /etc/apache2/conf-enabled/logformat.conf && \ - curl -o /usr/local/bin/phpunit -fL "https://phar.phpunit.de/phpunit-9.phar" && \ - chmod +x /usr/local/bin/phpunit && \ - ln -s html /var/www/src - -COPY php-mtt.ini /usr/local/etc/php/conf.d/ -COPY php-opcache.ini /usr/local/etc/php/conf.d/ diff --git a/docker/dev/mtt-php82-apache/compose.yml b/docker/dev/mtt-php82-apache/compose.yml deleted file mode 100644 index 15f51f9..0000000 --- a/docker/dev/mtt-php82-apache/compose.yml +++ /dev/null @@ -1,19 +0,0 @@ -version: "3.9" - -services: - web: - build: - context: . - dockerfile: Dockerfile-web - image: mtt-dev/php:8.2-apache - container_name: ${PLATFORM_NAME}-web - ports: - - "8080:80" - environment: - - MTT_ENABLE_DEBUG=YES - - MTT_DB_TYPE=sqlite - volumes: - - ../../../src:/var/www/html - - ../../../tests:/var/www/tests - - ./php-mtt.ini:/usr/local/etc/php/conf.d/php-mtt.ini - - ./php-opcache.ini:/usr/local/etc/php/conf.d/php-opcache.ini diff --git a/docker/dev/mtt-php82-apache/php-mtt.ini b/docker/dev/mtt-php82-apache/php-mtt.ini deleted file mode 100644 index 5503e6a..0000000 --- a/docker/dev/mtt-php82-apache/php-mtt.ini +++ /dev/null @@ -1,9 +0,0 @@ - -; Since PHP 5.4 E_STRICT is included in E_ALL -error_reporting = E_ALL - -log_errors = On -display_errors = On -display_startup_errors = On - -session.gc_divisor = 100 diff --git a/docker/dev/mtt-php82-apache/php-opcache.ini b/docker/dev/mtt-php82-apache/php-opcache.ini deleted file mode 100644 index 70c3516..0000000 --- a/docker/dev/mtt-php82-apache/php-opcache.ini +++ /dev/null @@ -1,42 +0,0 @@ -;; opcache.ini - -;; check /usr/local/etc/php/conf.d if exists docker-php-ext-opcache.ini - -; To disable opcache just comment this line -zend_extension=opcache.so - -[opcache] -opcache.enable=0 -opcache.enable_cli=0 - -; JIT will work only if opcache is enabled and jit_buffer_size is not zero. -; To disable JIT set the buffer size to 0. -opcache.jit_buffer_size=64M - -; JIT mode. Read more at https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.jit -; Default is tracing. -opcache.jit=tracing - -; The size of the shared memory storage used by OPcache, in megabytes. The minimum permissible value is "8", which is enforced if a smaller value is set. -; Default is 128. -opcache.memory_consumption=128 - -; The maximum number of keys (and therefore scripts) in the OPcache hash table. -; The actual value used will be the first number in the set of prime numbers -; { 223, 463, 983, 1979, 3907, 7963, 16229, 32531, 65407, 130987, 262237, 524521, 1048793 } -; that is greater than or equal to the configured value. -; The minimum value is 200. The maximum value is 1000000. Values outside of this range are clamped to the permissible range. -; Default is 10000. -opcache.max_accelerated_files=1000 - -; How often to check script timestamps for updates, in seconds. 0 will result in OPcache checking for updates on every request. -; This configuration directive is ignored if opcache.validate_timestamps is disabled. -; Default is 2. -opcache.revalidate_freq=2 - -; If enabled, OPcache will check for updated scripts every opcache.revalidate_freq seconds. -; When this directive is disabled, you must reset OPcache manually via opcache_reset(), opcache_invalidate() -; or by restarting the Web server for changes to the filesystem to take effect. -; Default is 1. -;; Override in docker-compose -opcache.validate_timestamps=1 diff --git a/docker/dev/mtt-php83-apache/.env b/docker/dev/mtt-php83-apache/.env deleted file mode 100644 index b4f9b86..0000000 --- a/docker/dev/mtt-php83-apache/.env +++ /dev/null @@ -1 +0,0 @@ -PLATFORM_NAME=mtt-dev-php83-apache diff --git a/docker/dev/mtt-php83-apache/Dockerfile-web b/docker/dev/mtt-php83-apache/Dockerfile-web deleted file mode 100644 index 3a6f2ce..0000000 --- a/docker/dev/mtt-php83-apache/Dockerfile-web +++ /dev/null @@ -1,15 +0,0 @@ -FROM php:8.3-apache - -RUN docker-php-ext-install mysqli && \ - mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" && \ - mkdir /var/www/phpinfo && \ - a2enmod rewrite && \ - echo " /var/www/phpinfo/phpinfo.php && \ - echo 'Alias "/phpinfo" "/var/www/phpinfo/phpinfo.php"' > /etc/apache2/conf-enabled/phpinfo.conf && \ - echo 'LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\"" combined' > /etc/apache2/conf-enabled/logformat.conf && \ - curl -o /usr/local/bin/phpunit -fL "https://phar.phpunit.de/phpunit-9.phar" && \ - chmod +x /usr/local/bin/phpunit && \ - ln -s html /var/www/src - -COPY php-mtt.ini /usr/local/etc/php/conf.d/ -COPY php-opcache.ini /usr/local/etc/php/conf.d/ diff --git a/docker/dev/mtt-php83-apache/compose.yml b/docker/dev/mtt-php83-apache/compose.yml deleted file mode 100644 index b1cc401..0000000 --- a/docker/dev/mtt-php83-apache/compose.yml +++ /dev/null @@ -1,20 +0,0 @@ -version: "3.9" - -services: - web: - build: - context: . - dockerfile: Dockerfile-web - image: mtt-dev/php:8.3-apache - container_name: ${PLATFORM_NAME}-web - hostname: web.local - ports: - - "8080:80" - environment: - - MTT_ENABLE_DEBUG=YES - - MTT_DB_TYPE=sqlite - volumes: - - ../../../src:/var/www/html - - ../../../tests:/var/www/tests - - ./php-mtt.ini:/usr/local/etc/php/conf.d/php-mtt.ini - - ./php-opcache.ini:/usr/local/etc/php/conf.d/php-opcache.ini diff --git a/docker/dev/mtt-php83-apache/php-mtt.ini b/docker/dev/mtt-php83-apache/php-mtt.ini deleted file mode 100644 index c6b0ee0..0000000 --- a/docker/dev/mtt-php83-apache/php-mtt.ini +++ /dev/null @@ -1,11 +0,0 @@ - -; Since PHP 5.4 E_STRICT is included in E_ALL -error_reporting = E_ALL - -log_errors = On -display_errors = On -display_startup_errors = On - -session.gc_divisor = 100 - -allow_url_fopen=1 diff --git a/docker/dev/mtt-php83-apache/php-opcache.ini b/docker/dev/mtt-php83-apache/php-opcache.ini deleted file mode 100644 index 70c3516..0000000 --- a/docker/dev/mtt-php83-apache/php-opcache.ini +++ /dev/null @@ -1,42 +0,0 @@ -;; opcache.ini - -;; check /usr/local/etc/php/conf.d if exists docker-php-ext-opcache.ini - -; To disable opcache just comment this line -zend_extension=opcache.so - -[opcache] -opcache.enable=0 -opcache.enable_cli=0 - -; JIT will work only if opcache is enabled and jit_buffer_size is not zero. -; To disable JIT set the buffer size to 0. -opcache.jit_buffer_size=64M - -; JIT mode. Read more at https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.jit -; Default is tracing. -opcache.jit=tracing - -; The size of the shared memory storage used by OPcache, in megabytes. The minimum permissible value is "8", which is enforced if a smaller value is set. -; Default is 128. -opcache.memory_consumption=128 - -; The maximum number of keys (and therefore scripts) in the OPcache hash table. -; The actual value used will be the first number in the set of prime numbers -; { 223, 463, 983, 1979, 3907, 7963, 16229, 32531, 65407, 130987, 262237, 524521, 1048793 } -; that is greater than or equal to the configured value. -; The minimum value is 200. The maximum value is 1000000. Values outside of this range are clamped to the permissible range. -; Default is 10000. -opcache.max_accelerated_files=1000 - -; How often to check script timestamps for updates, in seconds. 0 will result in OPcache checking for updates on every request. -; This configuration directive is ignored if opcache.validate_timestamps is disabled. -; Default is 2. -opcache.revalidate_freq=2 - -; If enabled, OPcache will check for updated scripts every opcache.revalidate_freq seconds. -; When this directive is disabled, you must reset OPcache manually via opcache_reset(), opcache_invalidate() -; or by restarting the Web server for changes to the filesystem to take effect. -; Default is 1. -;; Override in docker-compose -opcache.validate_timestamps=1 diff --git a/docker/dev/readme.md b/docker/dev/readme.md deleted file mode 100644 index 30229f7..0000000 --- a/docker/dev/readme.md +++ /dev/null @@ -1,8 +0,0 @@ -Docker containers for development and testing purposes. -Not recommended for production usage! - -To run docker container: - - cd mtt-php74-apache - docker-compose build --pull - docker-compose up diff --git a/src/export.php b/export.php similarity index 100% rename from src/export.php rename to export.php diff --git a/ext/extensions.tar.gz b/ext/extensions.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..048108c2dd620f6584f51f1bb449103fbfc6e757 GIT binary patch literal 18837 zcmV)PK()UgiwFQ;S+->W1MPila~nx=pg-$Z)bw%(z$^&xtu;ha!y!2%+L9=X)Q{S2Y!ag%IGuIav8U0=2e`n?v z_+Rm1vkQxhiwp3-`9(G}yD+z~_y=t9;!sLI(0?}sR66dHUhvbV=N;S2L9teA2prLm z#| z8f`c9icuW;jkq44^t@vus4 zS$yQN5AHr-AKbgmj=eDQgD#t6LCDOzE^9%FrWXU` zsB-O{>a}ZrixuB$dM&@}HH(EiySw++c5f9*CH673+Vs7m^PuZJ>3NM98;{&Wui`+* zpI*Dx>USG4Hr$Ehy7wfmH)yOhqNwh7K^(dbuUM)v0J`}k2IQgWH4ZlP;(pj=UGFgy z<131iGDQv@2p&b2*UZCj%}9gG{7$d!b-Zq@Ki~1<*zX=jTV0??%WZf9foc^A7`Yvf zxe@d-WL@}9uNnd1&JKXgZEvf|R#+iX0R`YUugxL>m^B07Q&*|UA3!|^5UnI6sr)1g zx{d(AOTyFlfj!tVHp7cn;HhjUA+X=|<6?=Pas2T!)eF5=1T`bC-Ky2_mlt|K^av>^ zOCf{(2+%F^@_Pkr;9a>J;|4!yYE??!IRt9P)|t)N%{ z>UF$&KWrCD716%Zn+hx3JYFeOSkk7~^g(o8)Jr(rhJ6?q96k0q8g0|5lj$2hP*EcrrY!|Y_ zHid&KXT$3RhJ*{;QKC%YRU}4Ws7Z(-AXB=oLVR{_ZQj|eqq(qX0A2sQg;oeGgdfEq zib}CecixSIe&a|lW5b%D`ceIH=*R9s+Zzs5ClU-XMH;(7oIoj*tfXtX?Z`^Icd1{! zK3Kj03{2PPU75(Hj?N)?pwu)~1TuURat4Mq_8Y0VX_}zMNZ_oNf_N)&10JuuB3Cu0 z+FHo+!L$Y|G(YLYe#hV-*@+w0%3MHK1o6>0S&3hgGMr_bpezTN(Dvyy>-<-aEdFB$y5KD#t?wf?(|57%IhTn{)k z<|HEFl=(~4H|Yzeyb((?d^ua0sm#jfG&Ayhv3R%EY_gM}&w|HYTotge57SvEPbFP_ zF7cC&|H@J9Ho(e8=ibJs@jo+bj{l{Zg{$#@DW9g-Jz=d7hPB&nUya8%?qkgV!v48i z|Iy=rG3)@ZXn%uLmzrKN-9je0ln-!Plq1 z9K2wsKZge|;nhoN^$mv!O&QX;g5e=a;QxB?Z15c5em3|mwg7PPAwho*4St?cH%m&|{{tViKmQH_m`YS?! z9wAOp@AJVo*zoD6P#b=J!BQ_~76n@4QrrIw)qX)xzNRjG^V&{!jPc)Ve+T1#VPVc3 z{|na_uEzgme1?wy5C8oWH-h;A`k(EiZp?wc5j5SOu*U?>W1)B0|MyQ$#v8}?+WsR# zpwGI#$A02PG5e|8^P`i;Zo7L@W>GJ6A2h&|3etcUb6Uy zvSRT+a@=E4x#0}&n0!}ejU%t|i1oa%<45Ryh-lk)tZ}|WUw-cg^#q>-xACaoyTIU| zKRAp3cYbN<`j!9pGCqR;7Z?2V2cz`=Ed0-0|1B;pTk8)b~TL z9$=tPfi~tVxEB`&?KU4P6l9PI6XHW^f*7IqsDc?Fgh3+4oBj2q`5Q8V$SCq^;X`G7 zeJhT8YdxPz0WZ!HQp8DchIk@gQ41zAqJ#wJo+h9z7;DuyK}3p_fA75jy|}3Em96s9T7|Jk0IKM=TB=dEMb%3Sr?Egx)Ll=)Qz8 zihhLJRu?7AkAVG+li}?SZ+6`RZ4?Hf*K_^w+)%i01DC}i`CS?v4wN6h_1F!&7{#-q z1sIr7U1c`qhKDQNe!FcC@ZtrGFfSO5wg4_3iy>8r8oMVw#e7_u zZ(3UH2M_uvG!Lpm$vo+_3qwLaTDjpi7|)@{cC@m=JXzebp@$KL`n8G}KqipF8p47U zN@X-?9XH;^MnE=N{$Z^K z%e!2aUCBlYGL{o8DA;#YM{B`D1^Fj0U{F+O@(N`XOeJU#D=J@&(7_b=K|hXx)D#pd zzGIiBp+D1duut=d&lLw1NiDTzPEvHm!EtGHMRWx4;DA@5wNPz3T-5~p?e0O;yYVWh zNmmhFxISj@x0BNy%9X73ObWtosAaLHv$b_BS+X? zorQAhF`Rk2L@AZnq>O932VPsgf>l9Er+yE`bei{3sY2EKZm%D6LOZDH91$1Hzr!ko zbm)pB6tG3T#;{5&IivYQJ61M{P2|@-H$I{%U*5bVsrXPL1FKmZGCIu6A&P2MpkfKD-!l<eA^T=`Oew?D%FXY+2HTN|VNe>2(m&!y}0SN^}t`23#x|ImWc2^!N+cEjpmyJ7XZ z@!$4$(nVr_OP+(oRhO>r6EEHVTF*}(3s+leX*9P{M!DM@ltM=f=cFvDE`<#oVbyJz z5T)9IT)U=jN^P;Lt)AZ!#iv(03eMTpGl#$%;b#4 zfz^o)>0P~Ebi6POLZ@UYC8U8$Civm1WfQCH@aX{^r7)Z+*0t|=$Sa7?8h)YR5j`gN zi2g?HPO_}&dS<5zF33r|3-Ytwy)8Y2L+U)VPsLRK;8=1cmssZ|SrVR*tpt}L(j}`* zuhOyw!LCuj^6MpJDVmds8K*o>yR7HfURCl!uL(SD#3qvR+k>zz1VO>e6dT1S{Q67H zR1l-DvB=i|r8+sz;(~E_c$i!vgf~I9Qn2KZL<*>6_nzR!OTHozZuzk!LM$aS0wJCY z#wHLmN4#Z9B-DwQ3T@*!vY@p1&4 zdxozh+w95(t}Di0QCzwHe)m7R|4$Cr^KE04|8HqNbN+J?<3F$be;5CG!~K67@2v;j zu1A(G_0!=n5Wcux|Df$R_(r#??ZJBW+wB`#895b5bIT+~R7}vUTTfF>Ob?}EQmduG zgNoe*RgN~{p<*nnRkrI!kJw{BJ_`CVYlC%G3~kWwB0kW<^lJ1`(b?I&y}7;%1bc9I zxA;zpy?=lE4*Qs143wsn^k1ps)Gt%_x%l2bD0 zNr*(oenVgOXu^W%M;iV$fw*H`4^WQ}lL|5RzK90|Ty_u!2W_uYdNl&Lhmq)fw%_ow zZtXj~m_t;~(EY&(dB%cfX2I0tr1V3);i6Z?s}3*XPPw}PAFbQY!JmHGo4Z4{s z&?zho1G26b&;)>r~iQ|e8!w>FnKe)%<`!S-weSc%~KL4)r;PDZfyW&)cSbj9U+VbMY z(OMJ*4a*AY7z%X`>R{62fT&QEp3tdqufS7Sm097z?)%d}G&6&V{9}|>QP68|>NuP6 zN@W=qKpr4;zlpHZc8rD4Q|*^!nVX8o4}NeX`zB?2(pu8A?AX+CSwn4a=ArRmR-o7z zg5Oh%{IgZe@t8LT?grgyY^Cp^q(+t@fFGEscy8keKq><4Mr?}9?v!h#bkYdh+NgaD zWuKxggl{hN?kOYLgckAl!o#PfBwC+JyL)pF)AI8VpPH#6^Zbs4e-Rrmp_^k!-wi)T zc6lr2M|d0|XnI9wzl$-e2ssmal1U7g%%!AH;7pS#wczxs_oV2&xB0==U8gkhq^jtH zD*WzeRyJwGQxU;22w*@y77c&u13uZ>fKKcqr9!V(6KNldrRmiMh-U2Fh9VyV0q%kf z6&>M_Z<5lC97A0sw0v-HV{Lacr{6o9yRz3SH_uLmGK_PM|HD#_CB;cqmeCsk8<4xu zDc@L)ovU3wLyMEodKB6k`VB{88`oDjSYSC80;Bos9Gjj#mNkvXLrn0M#nlKZEUq+x zXR)z@2bvjG!H>3!sU?&ARLmG?pRHzwPD8bY< z8}9$xeA4iGn)8pBJA?O6hM+f&cc04Mf{;mP;DZR&5NyL zl$#pcC}vab+3eUOV2?_4J#xv>$q&Nh+m##vlO{R4mRV`ST-k#9XGz$dVfzstPYilq z*CY*0KOUPAP)a3O-VyK&;vVis(*7u=q{bc;%|$?7=b-Xlp~DYf@Z9Up`!GUrF%d9C zl8<5>yV!B4WKZ!vq}#OU+aF`q*TNQ3fjKHOXZa=wyi_tP`cpGFAb{J@3n&beredKJ$IXL6+1$Go4On+?-Cj?9y`P?J-2V}OUaS3R z^Zw4(_Fbc9^I&AfjrZz#by3fYz_J4@xclRKn?@nN802B5c<8i!2W~pCsuXB_hbJMmFNGYETL8%Q5mu#js{Aqu444%1YRTWpYSZLT)J(oZ z>COaT?B3&p$nnXqDAnzI2#(ffhH&|mQ`UFrU|HJQUzlUf8%|=_EyL& z?WRa2C4U}ec~qbh9rddT2u|LDX1J0|3iiUF7in`8iM%q-(UoTa<1gxWe!TN1 zw=;Zq`*GlR8^}e@Uf}+nljx&15q1sUZgoLfV3LudAVhYBn?QLBH%YB)TZ#N$0n6ec zS`L)!DN%onb!m=zmaOLOs8qB09p2#!z${xP@(U=KY=LAI6Zt~_vz^!WVa<`xiNsCe zOECtj`SA%gl9?X5hih>h+NDIeA%si7(x0?472(mJ!hxW3rr*^-jq0n)s04f2oT|-I zrvtegTE5rj9*1MM-Oo;6>?0!Wub3M1%K2gmy@;?Rh1wNPyr_^Thr>EX$XX=OtOJGD z`PCn(ABkg_Uq=-dYG)$x;v~) zeXt{ZHaLKUFNoTGnDwTp?zc5vn>Qa;sP(be5@%q4+tjZ>|u#`H^*GjnQ#z z-aqKaiIse0Zb0aiNP2aw9RHX)&Q?K`HH-n_aDTu1@CStO@v9?D;}tMI9us4iZ=_8< zf^~;AiuV{Jcj4VI#iMN6xh32F5H&^OQo+qcXeil{W7u)Gln34vH>|IQ5UZM{m@F+* z*9Oe^99H9V&kE{^dg%3Fg;6Xpyn#+xJd{{Pw2`;E_`wRB&Ad{*DB59u%lKAQpEAB* zgORNEa$4)9vR>z}myx^KMOOl<=Qf+!Tuus@gkV{tnN%Ihr%?u`m_nkUbL=-Rr7e8T zy1;UIrx?e?873~uvN2G;%h!M!#+K-LUcbyX@9x(B^v>+{4EGspuoTf`MY6-vKs;q{3qG(yd^}CO{ znA{hv1*YvQ*)Ea13Kf4%Kid9}ayaii+ZeI`bA5Kn%>R0Q_WD))_oaN^@ckdq<}e;LE4T=^__RvyT@*rBEdwGpQJ)4aMK>rY6lnk!*+S%WN^%AQ5yPFezGIBd;anA{c1OPVfPOX0($tm1;T6ywg- zq^Ry|HOnVnR9-&gRDC$|c&B>aIQK?d8NpG1f9v+<&K}QQ_^`zO{Lh*Fl?)3RS|slD z>Umd==DAv(yFtwQ0^^DIQ!=}ULvYe(l|%RZL?`Pg)?;nl<#%u0#T2y3?$LR>jFSV_ z_8>zU&q#xIMUGQ(q%j%Jx>JK5O|RN^<&5CNFaX|pJYjPdK-YT`TO9l}%T3B4*U-l* zij7THJmMMRDQJ;-6lSz|$pX9-pemEflDa?I368zHfc_@$+XNe=7Q{$5@w*{fu-I)* zjG1Wcz&rH2wuA#yqJVl-H{+3k0{5Y;rVoV;rWMpt!y!P*-$;vvrx z@u}4|Z*Sg#^@eTv&gb>*;84q7E`){^KGsCxX#tHjT6GK#HXD6v^GzH;sYk<{4ArWF z!u!YoVO%n8Yr9NDSQuS+#dxkiwp-_kxHUj>eIDZ2p zgL_?p*={;WlKlQP)GnNhhi?x>WJDV$yC#CrQ}W+|} zyHOv~S9yU!W(eE7g_*)5c$|uuh1mv|<$dQyr_f9i{U>89&QWsA6>=}ZNZ zrvFJNjA@6cmm57ahE=Ea2MvvnE#u`WXfLTe!M;d5z_wUzK8YEbV{FbMj>$+!qvEg& zd4Xdy1nh1=SVnxhVVhB8jJ*8}6GcZ4XS5!LE(x8g7C(!tCI#@f$bXc@K^4C_)Ph0( z6np+Xfq9MhH5FeT=I`T^X4bA_sXy(svz^1g+t9HP-e#gjo=}a5?kIupbzHO5`M4=c zkmO?Bp&~G3H;uWmqz?y`Cx-Y@`e+(RoFXOtv`vW;Yd*qUC((f22vceVau&iB0^&H# zg6GICZ)$Q2osL;^ks%Up@ktwwO{QxXR_x$*Z%G^KsRRm*m7T(;stkpY3!iva76Ll< z?F5QiuO>U6QPD6G!nYx7h=359AL-BR zu|Wba+8)JXh7RHQ(c5IhR|jid0;XHsgna|XR5OJ2d5Irl!S$UL59}|#CACc_YT z2&vfk_+l5v=AI3Rcq(Q=1uaDk>Lwuk38hXQhaW$*?ntmJ#7Hcu`EX zYAG?jTCc|epBN}ITU;rQGv}&PTkZg%c;-EP{86NvF z46aJ0k^+eO2e#_mlhE=(gU*zh*rXRA%dBv-P~wnpmf?Ro#4)pk#NkQad8@6vJDd0M zl+*6Eex~VTt`VNHV%qT%`_bC%2b(+aO!TEhF%d*RtLkW=6tiL?lQ3mBrB`(s@Lk4_ z`d)Za6X>87`V)MRaY^J)A=BMTx7nmC4e)#7icosVJ6WhOylCdY1#81s#Kp+-I3A$F z#WO&$L>rz{9*=b7JD%ofIIEvAV>@)qWY`WLt%WpF=E`AAv4~*eMv5+t05zG@aE%=h zJtDN09hFkB)^6`^-WM@i7Lv2I2fN$#t-I^@`3h@=c9PYJ!FUd+d<5|dtq<;R?z{?) z^nQK&_Jccjae@obcGqCEe7LoH>x}q{Gu2t7jIvLMiiYl=JR|$Fr`_e7)C8JaK4=0n zc?blxM1Y?p0+gd#V-aa_lzx{mxB^#8o87>-CZM|KjEE z7uCk(_dhQz&CXoi|9lxAE&fMM*M5#|43GbrnO~Y;Fynvb=dSL5zLd`!9{-bl%7c95 z%>qW0k8#F(lGq=*BG;N5@-;iyZC-+qphP{mb=@n$X(fU&W~2C&H&tqiAedxXk9v zb#ur!bZ~yIo_I;#A8~#{fmv$-LJJGky^s2Ue38B%b=*d=5FNR5i%W-94SLjf@8h>QgZ~9R$h^t)2 zb*IKe-hYQj#5y?c@acQnQ!yvQ7qgWa`IK(b^~w3GRJmI6zs4Ui{wqf@pBY_58>7ZQ zjCW)FFD@)y<^Q^rPt$`1RVxfS%x$-?#_1dPQT=~m|01ma$nifnKeK4s|JnH~|Iej- zg#Cy4pUnO!4gTPt1}_G`8N4|C+2Hx$>%ljJ7i{na{P}k95*~d651+x~mxCA5`iuHU zbvy)15dL}aIl%aG@a*)H(_f{v|Hi1%RBL>5`U?P0pie(xr+)!oe>?b+4W2Wo`wag3 z0uU*DKPprVC@KuV`*Yr^*_2#A@q%AKp})*2*yYgv=jkt@(Qlv^UqfGj4n{#WUmI2U zhtt0Ts{9&ZGr;2+b@}Imm)Hf_oicPr5E1Bm`m57VkhO%-XVydv^L+O8U=g?E6uMVZM5?7lHW46g%FLUjt^pIsGMKhP?Uu^p~f< z$gnXB=YK)Zzr?Lv7(USWG*5{+Nt%a?=SFlb$u!QUob;RGFg zPVoNq^wZP7kw|{3Az5Ys{u?&<5{mpKum&LmQj*p$xoAEonfVI-{Wq+JrM^k{Na(*H zTs}8Yf}&sL42!{6ri7AbEkoXy7U|} zB@M~JbHL~YgGN3*{c8Y*jXg*D!!Kf-F7rtH=hX67D2TZ%KmE)k*BJf!kDvYDtL4Qj zeN_AJUC8Qxr2PlepIQIU&dy)i|I7H~+kbt*pE2%uFFiZ3l}XL{hkm=wcm_#PRO}&j z$%3<1&~AERo*~B;hM4b-#1(2a+#C3JxT#k67kqw_P`)nnZ4lP;LOK8mW{qzyjcSmzBbK~Go?6* zTGMNLAZoCZ1tK(puo+QAAMQgT#!1&jM|gF3GsN-;G=6Ul4M>IG5+45Of+9dBkN;Sl zyFPyv|8W@~o&S_BAiV7SFN;ei|F6$2UD^Lj`CM@P$K3R55ClSd*iEnHcfDq@AR;3Q z$;Kb;B`T-0`xxn6!L7unqORONl_3p<&H-3qXus>W>oQY#3eb8!<37J0yUFg|y2m;} zv!6~nD6XN#ItM(`g13wf(@iq{9!x@twifXaGai4lPrH7nFDNX6t)0o;ChV3NV|04ECo(lwq-c{=* z<%*nj7|uimPWIJu+k$&H)B@`XyR^r>aBa&*ILbOHYHQu4?>N; zMJ--n&xBB`fsC)ydI~S7D-U^(*S9ev3z8{95)0+Pl^!h){p^LHsv2IzqE39o+CD7$ z=%3}ads}tXqpKJ@P}QdqP0t1DVceTeOfED+E>PU*IFvzLA@4i`h=zYb0n8IQWr8sZ zc$}cXc!sM~%4;<)%w<;S1yQ__fLUv|3nrP&+)-6p)4WoH>l}jFP!8D>dPzCHM@NtH z@+xBxpsZ4yitvn`pkciZzsnT%RJy^QD)C0Z38#9BcMiO8yS0Ag#@Ih`a!;Vrz^9bnTnRfA0f({- z{Vrr;?9j}sQZgNa25aK z9euld5cO^_$@P8bd;1RgaHc_fO-tQ4?ULey*QjV~q^p&3@En!hzO(xA6zCq^;&a7b zdMe~2i>WOqL5g@5Aan#LcNowO6zaotzo3Qsr9o>SMQEgsBH6?kyJF zb~|`n?}zO=MMc6wBQvm4aG((UV@B2o`W}bSb9xfRCv6X&JocOMQEhf+=KD8dq@&yR z54*Jn%}s7V;s5yifBMgtpD_!y00G`F(HId9K(F$D?N|R+t7oxKP^+QUdgPrb^)kvs zN+gnt%5reVoZ{N@^77{P#x+T;Yu6N70jU^WuQAOdSshrCYOjx+RU1_f>tw=!7>v{5 zn*5_wCcw_B(cZXC93@RahtvubZ)cV4W>Q69!;-&hgH32~+3)sXkwhW64mZaR&s)FZ zOv&G(g5RBAoN?qy$R2uISDc{LLNK|VpQNLSQJ<)R_ zttpkNV$zYN2_GzPO;1<3piQrylLX3T@Wl!tpTSJT7+Ga9u28L%CF190i6AWvygHxL zP1IYX=EzPPvr5C>Io}&%?YOZ^mqUudBYS7ZFezRKlOpWiIZ+L)B6WN+iYc|mpq4Pa zqem4e`Oyn1OaX_Bs%$nkHS3o+!_Rt9!wwQALDHE~6c@wvT=YqmnLIl6_EgZ9DJ1ew zO<9%!89SfCK~uj0Q-Aw8BRv(MWl11#%w3nHOSz<^T&iV?Dyy}mu(>)j<~V+oWccDs z5t$lTKIM&N9!s#}r9ay0f)4SU!b|7mOvU8VR!$;9?mo24Y%}M@!~$)F6|Kv>EdMe~ ztCj4LEPYXFxtK?mpw8`z23PX4keIlw2r)31_sUX3Ujvzobu&9uc151t8G;tFxaaJL z4!>~_{;knh2mdYLKQ|q`6}^D-K)<81SWj3+y~RiZj)l$%A+7dRr*>kFlK2Se(#fja zcSN}_sE~DGMsMhj5=5An%dWeO+l30%Kim7W{b>K){Xc*BgLl)fQ`H2c-1~-12Jrkv z^efwLHa}=i>I;IbX%xJNR@c!!A3}0EnQaX}ljJMa&gWVAOR{MnXuw_cjJ#zV0a>>9 ze36k`@oT5953}s_YCAYYe>EOSjIlRZr*WEs!r}(8ATF=q`4vT4#P$< z)M%(@MHMHn-B*8h+bQolFg&Qz-i!R-#@jq|YB!ac3&Yh0Q@^vd#pHEflR2g^n>don zOFF-P5k&gNjcqgc)!P^m|9O3B&dC2UH#15h6$M_7#!(xsymjJ?K zqX%`teu@i9_ZS%Y*lp8}D&C{li4N&I*e*x6U2eP0-6{3dchPi8d3W?ATdfyL?YD~7 znGme_c-rZlq#?uUFf)`6*?onS2)e-;)BIhmy&ZRN?F{>BqxMxNlfL0phsmULP(_^H z>Ust54PfFX#E3;c%#(N;ZQ4~*y(2s&yF?hvJfL)+Tg`0u#$2?Fv0$0vIYlFNk-^)I zih3MFA!xNgIQTu@NuF&Z3W7GFyk=cM6&GnGH$f(aA7&?dQo2M{5<0Pgo;+Gv$zD^N zm1vdzJ3yaC%t{{#>Ix1I}3(qK>EL<>Rj(C!zbVWQtCkrFE* zDN;-Jay5aNp>Khl zj4<#}E(5diK=>gb*gjE2v|uku9n7nIO8C@ z{J!yq-6+NXQ?D0mk4@AmYQ_cN49kF8!)()Bod7)030)JOeZ;|Hsm-k^f^3DlA_4 ze=g(mCis8A9@o*1*4uu^kBjp-Bc$^+(Dix*YKd;LE%L)OFa(kbl5$2^ zo(0|ZiQG-5tbNn7$(fz(VWD258)N8R_$b{FRv?c)7(@W{_U4AQ7exLOoP%vXz~#HKly&sRHMy1miT2zM#!;g41T#~nP2*9Y4}JC+ zj}9YyK(OfsAUyrt4B%HAECG8AZ>~-C=+3s3l|_jvlgt=yGc~=Hpxk6NB~bl z!s8b(D!Va9kPKHXQwAr&G5l0c(#Ku~L)dI2mw@$8P>_UP5f700<#gSx zU~Uv@QAbq7sj0-PmS^LPa{?AelyKkJ#FUc3avuoa6V?g0z?nb7AH*+Na-#^?*sOyV z0o!IaZsw}haG-0^j)Kttsb_F*k)OMo;-}h#*G4;5P)uyQD8%PK(z6qN=*LIgy#vAu zrM?6GZ`=P-5B!}+8zb!h{Pjh1|7Yg<;>?x(zl_gC+yCFatsmn|o%JC<%Ew=+7o^~6 z)$FlJdCpEfAGvQplx58GkV*b{scJ2$<>`E@*VHX=XNno=KvLJSUm z0$nnJLg}Xc5O*<}&2DfIG*8g*^3{yh zzd7m6St^CBcW2p7V`?XoE!R`Y{sowPb%Qg~76_Dg9oFy@qP0mX;E~ZRhCs~^yqLA| zJZW+iSL*`35*I>6AGt;5>}=lNT;Ju#sIylSVfl!Ccx&_iCi9ysHyv>;UQr0$UI9xa znuZseux!%TIuI$pK_bNxz2 z{+A2625R#BKTC773s?DnF5_dH{~Jj-Ub&4C`G01X=1l+J?83~_)%^c5K5v5m&$0;M zlXNA-!klia*ENyKedita?y(!Po8pX5a(fMfCa9`;8-ACERZTfIC$$;r84xp&O2nhrL~jj1GPG4(J?}p9V1_8B6~zM8l_uK)SjM2-)DBCf zcS?=fx$+7w_ZwFHMq@ff+8HPUS;4UaP-pukHp7;*KcK{&~~ju#&V%{)A&f}UL8 z*)pVHW(1mCT3%8C|F8>Fp*p#^cn}Xp4Qb^v*$C^LrL0Vrm`Zo~P`& zB3h;4NtQ7C6211^6L;idK9aDQP_Bp-x1Oto)3agwghzTpOsOv+ z%D*Z+WvVy)rft!mcj^8!&F7rttU#kG4QwR{532`3T&U=Svr?$yBQ6PLKJ3d03x-|3 zy+7=jg&=b#zW^?qq(qeH_BeAPRR;rsr>D$Q5GA}$F879PH5i_9x6oG6VO8GWSy*emdJKYFOz zFzuwOI9)x7CHp9?IfXg30CD`o^Ui?`$T2GWuDNMVlXsj? z$DXvd6eJFdr|Qx71JVF*rF!=4fDU`~K|PHS!6Qpdu9Y>8U4|G5gJWeH2~MWDY&=5J zm8_b~x`+#0#^~q+DR`{`$M{=dbUr8#r| zfByQ_`Oi!FyrKTTiGu*7%aHFlSvTj6UHJy>agB7@$#oRpy27cRvO~tr&+xq?wedt< z3J7n%&4z{}+6!3Y2aVQw?`&y?Ojn!OG!y-#tuwPjsuIE;VWB;Je>IzRi0_`J#l_C5 z<(T2C?cgiB>9X^@OZbStY|5?c(v350)YHDZ4jLbg1g()d_0@?sx9OoB>h5 zHUCNoWnmt&jI>AbXOKr#Vs^u5{`JxidDF+EcxY&;xx zp)4UG^Fm`Ps4}C3Nl~xu$3>@F-jCj?!oyLNqh?EGHa%Nr_wH|gP~W+Cduz9Tce}oM z=ics*OQZ4UhzW6`AEoKpF?-?+gRU0D9Je(-223dtuJwc#+^-~Rm(0|~T;6e-wn@TX zwk zZZaEyHOK~VOukbafGC_rpQ}V1U!8vkngS8c$%=R(s(}b<(G5;Tmpq{yGAY|97VV6T zDwIg}%84HGSJbx#zD{9A!nI~IWZ8t>!e6D4Bu#}VQu*6o<|Hgs8dK9KvN7{0=AvSA ze%Vr-tL;+?FU#!+R_~|C0?M3pVaS#faB7P1DH!^@sMWE!rIXl4(H&G2{chy8yi{Ls zgP>m;Ay|jPwwHi^m^^oMuD#Vcs8gnn^g1P35}IAxS>M{SEPm29pgP~ss(1X3$G41B z2>ene`0`!>*@UCiPBUIL$~X}VNaq?uU5Ers-aXX&Vd(~!=-fVt21(Nt> z8igsnrLXa=kVf_PEt}#r&x6TNes-hWlsPuAH?(S_GUyz%gT^DTDKC9d=L{4h*uF>CLDAQIQJ2?p}p-hynXy~g3;xh9l7k@tca=f)B^EMc%x!UX<{j%*%yOiNrg zdS9Sg{gB^p7kZuG*h?BA!Qz+U$|UBtd70XuocWkdTt%Qnz3I1Fc8MM^1-=~GPs4%0UBgm7{W6o1<_1T4AMc6L78zQ0l5*nEHO!R=jDXW)Hwm}8YrIjg?N zeoRhinjEt4p^v(-%BoH8xJocdK1DEG= zMp~%;S@H4X$NQBMX6mL1HWt&*V~C1}xStrsJfDC*QOohOLyg|!K6={88Bc)}Jfl2j zXGWxnEo#wX@)LjHZ9sNw$r2Fh!m98tPACyad)NongXuev>m-Kh`@2-uNm%vzWw5>a zyvj%4|4r^VrOPnStBn!ozv26mx&J$NmH+p0K3s1&^2$f_x@saJf*T#wANcaF?WNe9 z#rLz7xyr13t^`FSbx)XkfS2-ig{wGXZnw$!nNYkUbeir~00S!BPtKLjxxkM;{wqhZ z+rVR<=i0`o@jo-WWZwTivvhU->ry^VuY1Cm6>htIHO}6+kLCPt*gse6KXUvpEG*5M z<9~5s?rQvB#z)xy>}}}M;1B*~@OMX;oH}Pm#3d4(}JNlgi` ejEE z8G}kcAAAcyzC8Wa;5YF1`QRA`l?HvEescOVXyDhUpAKHY_n%|6=Yubx%HN#+B^3SS z^j8cJc}b2en{R|)=#BT<_1t8B(e?j@qDt6S#hfetZBUOPu z!(VFCUcr)*9c%xO!8fO$VCye*6o77aIO6_Lth_mmi(GrLBefWQtJ%vn({h7<0uuiQ z2=)T_20h^@y#PLZA@~4)8I<`P2?~#)*Q~*aOJ6}Z{`&M+r+>o$!n47*r=LN6AY=~p z(u+H(;r}i{GNcC7{u#h{&T&9#$i-cQ^8c_&B<8ae9LmP$C>;#Gd_nyKF=F)f3$3KJ zVUmn*Q5K>1Uy)2eSpa1barpi+r@QHmn~12C-#pUr+-2CK{{t<2f$&j`37uaPp3ia# zGNdl=6a4qD)XT4?C9pCR1MO27HQ1T2Pk%Z1Em4HM`(6;g@5V=7n9E7^7E8fRG1dss z3kFc1fmHu87wHUyzejX{rhkd70a(vL?l=^bIl%V|V(T+O4@QhbCjAnsJ(KLV@F=Gf z`bC$7!aqP;h9-FqBL58X4E_z}k_zrybk)9-LlU|LiqQIJfcgt+@oOUEH}(qJ z#c!fNFA$g0pC$TN2v$1k`0C9LP`R2*aOAH*sD6z@R}4$&X2K(4F!osp^$j!y-@tGO z%>*<6w9AZ$D8|IscI51+*sm1GNZkD2&D1S0_ zLR1Mz4m(sqP?Vm^g5N(^gk}Ekov-(AbpFS=nYqmT|0@5><$OlY|E&(c(bN9TF76J~ zj5|9&Z^FnYrH5xe@wi2@1keGGn5xrNPm|2f#l|fr(p6qu^0a)%!vpZK$2$FX?1TPh zZnGJBQRGGJu^%4+YMqWd)<-d>6@0KSob) z69K?Fcr=fnt0u?P8Ro2OT)OD@*wfUzbQ?P!YvNOY$Cy1C!v=^<(O9yXoq49Wz@dk2 zoarV;O5*piW|@?Wo1Ez&(ddWghiFKUMASo>@aL?jD^p<5;VTMLK<9g-?Kd95bdtu? zzC&4~M@=Jl=*xIBM|ll5zcyKj+E|msb(g}5aa)xbfzPo!UMCU~0(}zgUEWmhZommn zzsH=~t%*Qt@noF2+&%iqndc^)lemsIL0iXKLgnG3vF2k`3BzaPvoWSzAL186a*Wy4 zTJq!fZ$kAu_Tkrth3B92QTa@s|8ar#f3EUBUi?S$za6;edgfdGjF|slzrM6!=Kq{o zn!lR=U&iN6IR8z-rcJNqcfDq@aA$Y--rDZ1G%&vDdqw9#7mOV&O0aQ^xUD$+b_a2@ zNj<hm2DlbWQjFXQW5aoof3Y66s;ny*%o zu@NQ*hdBm@R3>@F=~z6I!6+CUDTpL*cCA*E@K?qINtJs10R}?ia#qqGeHo5<0zZ?K zISp{P;H_2VWD!M*Ihk|>(`@O-s+lEj`-=uhdT~=@o|JktKBj zXUtA)o+g`W^ur$|fHGZ5qcZnJsaowvoA-CNw(qK#+j6s^3glNwvT3z%tL%qM3o|qC zT+hUbi{T?qRwT+oE90gY;f6d^U*NTcv9`AKT(0%J>?m5Vh-)yjQTYnpvt-AE6hqjc z3&dUlk3!%yD5dp$aS#=9<&vr#86orKt-u{8Q9!IW^vS&l3wWV4<> z#1hir*1GVd%Ogsbf1DX^7NOXC7tHt8ON?MC-uq4d<6 zryxPbA`#zX6tQHD3#fs zgTU~#C4zDuW<#$n9j=HT3n*mD+wDy)NbJ`_+2(M8A*EkrZ zAfB6rKl{$AMnIwLOHb)oy^|%((=1Ow!ycPgJSQ)Me%$NF8BHQT{VpBe;-xHnc-MR4 zHHrn8T(jwEIR?uTY*{vLsYwDVP(?4cpxqv)z2*jZ$QGC+&;K^gZ z86VYVXJ)>C1CJw2yKVolTWj!Je4y}u{QW=u=gZG@i3H3=14L8+x61z=N!#(pcV*%!(>_srY#M#{wpeEGkO+CaGhXw03&C z!3NYI?VJ`6X#!=AMosg)l}To4?hcf)Csrk+D;L9QbN?cr-!RQFrg+zumzOuUH?Bz> zuPOKedJZgXv?oW7q4X?*`QE$1%Xb#o&tgo~x|5uHrj0siq=DW#}nB`$Y5#Z4X(0Xp zg-6db@z62OHT`aEpN-FoyP9FJ!RWgK`=>?_#$F{OPFCW9G_|K)8?ESyj zulzrk@_7^dKWY9y)5jq)0q$p?(_=o^5)VnbN=|$u`)fTveJmUt>A;q2_3Zsmay*+Y z=PyV{EXc-RjM*1r@O+l?+>}_@n)hZLR>49{qn&-u>Xgj%$3qfGj2cqB+ ztMw|CiuzMzrl|VeM!VniMATrT8RI*|R#wHipmt zXJ;1|&HexD^NX`r^Z(2ET=4w=wVwKG`<^nTw|R@7Q1#LcsuoHnQ<=&31zp}Y;l)Il z25EZj5DL{)r#EEw1Hvo3v$xe#3*d zo>xumm9+N?Fo_Ys__E7-a}7xiNR;1I^W5p3B%F_FIV5+%sDao$tSc9(9~a7O*0#k< zRXMNhO>zGNW;@F4F}iz&Iy$o{-x&PO%yhL5P&CLRzsK6aV`$WzxmvnK9T6?yg7w(G zr47aMRx*^O3#HTILCG6x7%(h&LkAw@&ZIMz@Tt;gW-S(c%E?IUs!Yo+uyh`4g^9I5 zUNO~g`C$|z%X5fAplB-@xtg}_;SV=@Q3`WQErO$bl~-wQ92EW0|wnU!3-%0RTI|6Oe~l$iQ|JDk{%4Zu5HJd^P$A?A(Qfv|3m%|3FNGMCgYl7k%G*?KNomZ_F9k3i5TW%FrhP;!mptqAoNCeB zfpYF~8WqBVX%AaNE+X?#U2%!Q$p>Pc@z&;b2rBOt#9WH&bj5@sN@ChKX`c>GVlt3? zPSoowb0WzmoT`=C?d|nHu5bRS7P>UNKS}Pu%teH}&2cYm8$yHh%nAAqXnipu0c_iT z_{SV1Sx1;0AlN91^?8gC;k5kS7#GSy$sT-?Mywdm>C9XgBSsyJIC=8Z7RC+nTMMEi zuMMl)!(vL<3Uk=>G}5~_jgya{OA)QJYN|=9hCi*K>00uG8_jc?`i64N?a|%bQq;~WBiwCHIz#+CzvbeGZAKI$!a^Y$R&*Z zUBkg$cG57yN18I%7S1+Wz=v}o?a0_do=+oAC#~VL$nPYgik}I@ zRg!H~7}huht3mfKON8+=p%_oXCe>$8e6Y&B#Q?m%r`(eBKj_21pf)By|FsAuug-s6 z#z*r1Vluz-&xrURboZO*zph`u%KvaFAFk82{I5bJ%*?OcPj1WkI#c<>%6v}FS7mmH zL2A8oq{}+?_m48N!|7`x(#igaI{l823T;+d#vp?GW@7y!L^3RCzKR2^* z-L(Jn^H=e|m+}$zUp+9JWPbgJ!LQY1Zff4wyrUCp##cQFCFOAY#)OC|6)!dGYxZ=H z%s|KS9ejQI8D(IkY>$62cm`m;WO$6JkY;s-XPBPu>$0s!Jj<$?tuTXtaqc6NdX~~6 zTIglM86$CR_DqqQuyBkv)Z<2Jc06F%GoD)y$V^OwmVu7I=^FcfltENKt0Iz`B1=C# z{p$<_D+=PwicE9}CBLMcpujT{IGuc%?%R$S3W5EGq~=qQfv+(qu7#@^$)~@@II)sl z283CM6pG7lC{H1F{jcU-fKcC6}GC#9;W&bbZGsONI3;tmyfBbBZ2OguM@KtIx5fBlLu+bbH>2&V} zQRE-sRwB2}{n&5&apIG2;hk{f*j#?1wQujLJ=3J!oZb!cpqSS4HvDFZ0g_=WW17r$ z{z%puWhSXD`FmV@csC6Lr*O~YU9Jh_ycuHn1oJSd9PYQZy*P_c*2-;23E?{kqYRp8 cg#W%WT34T|&(-JZGxYQS0j2_4KLD%&0ORnLqW}N^ literal 0 HcmV?d00001 diff --git a/src/feed.php b/feed.php similarity index 100% rename from src/feed.php rename to feed.php diff --git a/src/ext/CustomCSS/.htaccess b/includes/.htaccess similarity index 100% rename from src/ext/CustomCSS/.htaccess rename to includes/.htaccess diff --git a/src/includes/api/AuthController.php b/includes/api/AuthController.php similarity index 100% rename from src/includes/api/AuthController.php rename to includes/api/AuthController.php diff --git a/src/includes/api/ExtSettingsController.php b/includes/api/ExtSettingsController.php similarity index 100% rename from src/includes/api/ExtSettingsController.php rename to includes/api/ExtSettingsController.php diff --git a/src/includes/api/ListsController.php b/includes/api/ListsController.php similarity index 100% rename from src/includes/api/ListsController.php rename to includes/api/ListsController.php diff --git a/src/includes/api/TagsController.php b/includes/api/TagsController.php similarity index 100% rename from src/includes/api/TagsController.php rename to includes/api/TagsController.php diff --git a/src/includes/api/TasksController.php b/includes/api/TasksController.php similarity index 100% rename from src/includes/api/TasksController.php rename to includes/api/TasksController.php diff --git a/src/includes/class.config.php b/includes/class.config.php similarity index 100% rename from src/includes/class.config.php rename to includes/class.config.php diff --git a/src/includes/class.db.mysql.php b/includes/class.db.mysql.php similarity index 99% rename from src/includes/class.db.mysql.php rename to includes/class.db.mysql.php index 20385df..63731e7 100644 --- a/src/includes/class.db.mysql.php +++ b/includes/class.db.mysql.php @@ -147,7 +147,7 @@ class Database_Mysql extends Database_Abstract } $query .= $m[$i]; } - $this->setLastQuery($query); + $this->lastQuery = $query; $dbr = new DatabaseResult_Mysql($this->dbh, $query, $resultless); $this->affected = $dbr->rowsAffected(); return $dbr; diff --git a/src/includes/class.db.mysqli.php b/includes/class.db.mysqli.php similarity index 99% rename from src/includes/class.db.mysqli.php rename to includes/class.db.mysqli.php index 4f6e0f2..679e9bc 100644 --- a/src/includes/class.db.mysqli.php +++ b/includes/class.db.mysqli.php @@ -122,7 +122,7 @@ class Database_Mysqli extends Database_Abstract } $query .= $m[$i]; } - $this->setLastQuery($query); + $this->lastQuery = $query; return new DatabaseResult_Mysqli($this->dbh, $query, $resultless); } diff --git a/src/includes/class.db.postgres.php b/includes/class.db.postgres.php similarity index 99% rename from src/includes/class.db.postgres.php rename to includes/class.db.postgres.php index ea251f2..dfc22ae 100644 --- a/src/includes/class.db.postgres.php +++ b/includes/class.db.postgres.php @@ -150,7 +150,7 @@ class Database_Postgres extends Database_Abstract } $query .= $m[$i]; } - $this->setLastQuery($query); + $this->lastQuery = $query; $dbr = new DatabaseResult_Postgres($this->dbh, $query, $resultless); $this->affected = $dbr->rowsAffected(); return $dbr; diff --git a/src/includes/class.db.sqlite3.php b/includes/class.db.sqlite3.php similarity index 99% rename from src/includes/class.db.sqlite3.php rename to includes/class.db.sqlite3.php index 9f38d8b..546c105 100644 --- a/src/includes/class.db.sqlite3.php +++ b/includes/class.db.sqlite3.php @@ -67,7 +67,7 @@ class Database_Sqlite3 extends Database_Abstract /** @var bool */ protected $useNormalizedUtf8 = true; - function __construct(?array $params = null) + function __construct(array $params = null) { if (is_array($params)) { if (isset($params['useNormalizedUtf8'])) { @@ -151,7 +151,7 @@ class Database_Sqlite3 extends Database_Abstract } $query .= $m[$i]; } - $this->setLastQuery($query); + $this->lastQuery = $query; $dbr = new DatabaseResult_Sqlite3($this->dbh, $query, $resultless); $this->affected = $dbr->rowsAffected(); return $dbr; diff --git a/src/includes/class.dbconnection.php b/includes/class.dbconnection.php similarity index 83% rename from src/includes/class.dbconnection.php rename to includes/class.dbconnection.php index 8f33262..aa8e44a 100644 --- a/src/includes/class.dbconnection.php +++ b/includes/class.dbconnection.php @@ -46,9 +46,6 @@ abstract class Database_Abstract /** @var string */ protected $lastQuery = ''; - /** @var null|string */ - protected $logQueryToFile = null; - abstract function connect(array $params): void; abstract function sq(string $query, ?array $values = null); abstract function sqa(string $query, ?array $values = null): ?array; @@ -76,22 +73,6 @@ abstract class Database_Abstract } $this->prefix = $prefix; } - - function setLogQueryToFile(?string $path) { - //any checks? - $this->logQueryToFile = $path; - } - - function setLastQuery(string $lastQuery) { - $this->lastQuery = $lastQuery; - if (MTT_DEBUG && $this->logQueryToFile !== null) { - $f = fopen($this->logQueryToFile, "a"); - if ($f) { - fwrite($f, $this->lastQuery . "\n"); - fclose($f); - } - } - } } abstract class DatabaseResult_Abstract diff --git a/src/includes/class.dbcore.php b/includes/class.dbcore.php similarity index 100% rename from src/includes/class.dbcore.php rename to includes/class.dbcore.php diff --git a/src/includes/class.lang.php b/includes/class.lang.php similarity index 100% rename from src/includes/class.lang.php rename to includes/class.lang.php diff --git a/src/includes/class.sessionhandler.php b/includes/class.sessionhandler.php similarity index 100% rename from src/includes/class.sessionhandler.php rename to includes/class.sessionhandler.php diff --git a/src/includes/classes.php b/includes/classes.php similarity index 93% rename from src/includes/classes.php rename to includes/classes.php index 53ca97e..f6cbdd1 100644 --- a/src/includes/classes.php +++ b/includes/classes.php @@ -148,32 +148,27 @@ class MTTExtensionLoader { private static $exts = []; - /** - * - * @throws Exception - */ - public static function loadExtension(string $ext): bool + public static function loadExtension(string $ext) { if (isset(self::$exts[$ext])) { error_log("Extension '$ext' is already registered"); - return false; + return; } $loader = MTT_EXT. $ext. '/loader.php'; if (!file_exists($loader)) { error_log("Failed to init extension '$ext': no loader.php"); - return false; + return; } require_once(MTT_EXT. $ext. '/loader.php'); - $extNormalized = str_replace('-', '_', $ext); - $instanceFunc = 'mtt_ext_'. $extNormalized. '_instance'; + $getInstance = 'mtt_ext_'. $ext. '_instance'; - if (!function_exists($instanceFunc)) { - throw new Exception("Failed to init extension '$ext': no '$instanceFunc' function"); + if (!function_exists($getInstance)) { + throw new Exception("Failed to init extension '$ext': no '$getInstance' function"); } - $instance = $instanceFunc(); + $instance = $getInstance(); if ( ! ($instance instanceof MTTExtension) ) { throw new Exception("Failed to init extension '$ext': incompatible instance"); } @@ -190,8 +185,6 @@ class MTTExtensionLoader $instance->init(); self::$exts[$ext] = $instance; - - return true; } /** diff --git a/src/includes/common.php b/includes/common.php similarity index 100% rename from src/includes/common.php rename to includes/common.php diff --git a/src/includes/filters.php b/includes/filters.php similarity index 100% rename from src/includes/filters.php rename to includes/filters.php diff --git a/src/includes/index.html b/includes/index.html similarity index 100% rename from src/includes/index.html rename to includes/index.html diff --git a/src/includes/lang/ar.json b/includes/lang/ar.json similarity index 100% rename from src/includes/lang/ar.json rename to includes/lang/ar.json diff --git a/src/includes/lang/bg.json b/includes/lang/bg.json similarity index 100% rename from src/includes/lang/bg.json rename to includes/lang/bg.json diff --git a/src/includes/lang/ca.json b/includes/lang/ca.json similarity index 100% rename from src/includes/lang/ca.json rename to includes/lang/ca.json diff --git a/src/includes/lang/cz.json b/includes/lang/cz.json similarity index 100% rename from src/includes/lang/cz.json rename to includes/lang/cz.json diff --git a/src/includes/lang/da.json b/includes/lang/da.json similarity index 100% rename from src/includes/lang/da.json rename to includes/lang/da.json diff --git a/src/includes/lang/de.json b/includes/lang/de.json similarity index 91% rename from src/includes/lang/de.json rename to includes/lang/de.json index 0061beb..4e2a966 100644 --- a/src/includes/lang/de.json +++ b/includes/lang/de.json @@ -2,9 +2,9 @@ "_header": { "language": "German", "original_name": "Deutsch", - "author": "Franky, Tobias Quathamer, Denny Korsukéwitz", - "date": "2024-04-03", - "ver": "v1.8.1" + "author": "Franky, Tobias Quathamer", + "date": "2023-12-17", + "ver": "v1.7" }, "My Tiny Todolist": "Meine winzige Todoliste", "powered_by": "Powered by", @@ -28,11 +28,8 @@ "task": "Aufgabe", "note": "Notiz", "tags": "Schlagwörter", - "list": "Liste", - "no_note": "Keine Notizen", "save": "Speichern", "cancel": "Abbrechen", - "close": "Schließen", "password": "Passwort", "btn_login": "Anmelden", "a_login": "Anmelden", @@ -164,7 +161,7 @@ "set_newpass": "Neues Passwort", "set_newpass_descr": "(leer lassen, um aktuelles Passwort nicht zu ändern)", "set_smartsyntax": "Smartsyntax", - "set_smartsyntax3_descr": "Beispiel: +1 Titel der Aufgabe #schlagwort1 #schlagwort2 @duedate", + "set_smartsyntax2_descr": "Beispiel: +1 Titel der Aufgabe #schlagwort1 #schlagwort2", "set_timezone": "Zeitzone", "set_autotag": "Automatische Schlagwörter", "set_autotag_descr": "(fügt Schlagwort des aktuellen Filters automatisch der neu erstellten Aufgabe hinzu)", @@ -182,14 +179,9 @@ "set_cancel": "Abbrechen", "set_showdate": "Aufgabendatum in Liste anzeigen", "set_showtime": "Zeit anzeigen", - "set_showdate_inline": "Datum inline anzeigen", - "set_exactduedate": "Fälligkeitsdatum immer als Datum anzeigen", "set_appearance": "Erscheinungsbild", "set_appearance_system": "Vom System übernehmen", "set_appearance_light": "Helles Thema", - "set_appearance_dark": "Dunkles Thema", - "set_newtaskcounter_h": "Zähler für neue Aufgaben", - "set_newtaskcounter": "Überprüfe auf neue Aufgaben", "set_extensions": "Erweiterungen", "set_activate": "Aktivieren", "set_deactivate": "Deaktivieren", @@ -201,7 +193,6 @@ "denied": "Zugriff verweigert", "listNotFound": "Liste nicht gefunden", "noPublicLists": "Keine öffentlichen Aufgaben", - "noTags": "keine Tags", "invalidpass": "Falsches Passwort", "addList": "Neue Liste anlegen", "addListDefault": "Todo", @@ -209,4 +200,4 @@ "deleteList": "Die Liste wird mit allen Aufgaben gelöscht.\nBist Du sicher?", "clearCompleted": "Alle abgeschlossenen Aufgaben dieser Liste werden gelöscht.\nBist Du sicher?", "settingsSaved": "Einstellungen gespeichert. Aktualisierung …" -} \ No newline at end of file +} diff --git a/src/includes/lang/el.json b/includes/lang/el.json similarity index 100% rename from src/includes/lang/el.json rename to includes/lang/el.json diff --git a/src/includes/lang/en.json b/includes/lang/en.json similarity index 100% rename from src/includes/lang/en.json rename to includes/lang/en.json diff --git a/src/includes/lang/es-mx.json b/includes/lang/es-mx.json similarity index 100% rename from src/includes/lang/es-mx.json rename to includes/lang/es-mx.json diff --git a/src/includes/lang/es.json b/includes/lang/es.json similarity index 100% rename from src/includes/lang/es.json rename to includes/lang/es.json diff --git a/src/includes/lang/fa.json b/includes/lang/fa.json similarity index 100% rename from src/includes/lang/fa.json rename to includes/lang/fa.json diff --git a/src/includes/lang/fr.json b/includes/lang/fr.json similarity index 100% rename from src/includes/lang/fr.json rename to includes/lang/fr.json diff --git a/src/includes/lang/he.json b/includes/lang/he.json similarity index 100% rename from src/includes/lang/he.json rename to includes/lang/he.json diff --git a/src/includes/lang/hu.json b/includes/lang/hu.json similarity index 100% rename from src/includes/lang/hu.json rename to includes/lang/hu.json diff --git a/src/includes/lang/it.json b/includes/lang/it.json similarity index 100% rename from src/includes/lang/it.json rename to includes/lang/it.json diff --git a/src/includes/lang/ja.json b/includes/lang/ja.json similarity index 100% rename from src/includes/lang/ja.json rename to includes/lang/ja.json diff --git a/src/includes/lang/lt.json b/includes/lang/lt.json similarity index 100% rename from src/includes/lang/lt.json rename to includes/lang/lt.json diff --git a/src/includes/lang/mk.json b/includes/lang/mk.json similarity index 100% rename from src/includes/lang/mk.json rename to includes/lang/mk.json diff --git a/src/includes/lang/nl.json b/includes/lang/nl.json similarity index 100% rename from src/includes/lang/nl.json rename to includes/lang/nl.json diff --git a/src/includes/lang/no.json b/includes/lang/no.json similarity index 100% rename from src/includes/lang/no.json rename to includes/lang/no.json diff --git a/src/includes/lang/pl.json b/includes/lang/pl.json similarity index 100% rename from src/includes/lang/pl.json rename to includes/lang/pl.json diff --git a/src/includes/lang/pt-br.json b/includes/lang/pt-br.json similarity index 100% rename from src/includes/lang/pt-br.json rename to includes/lang/pt-br.json diff --git a/src/includes/lang/pt-pt.json b/includes/lang/pt-pt.json similarity index 100% rename from src/includes/lang/pt-pt.json rename to includes/lang/pt-pt.json diff --git a/src/includes/lang/ro.json b/includes/lang/ro.json similarity index 100% rename from src/includes/lang/ro.json rename to includes/lang/ro.json diff --git a/src/includes/lang/ru.json b/includes/lang/ru.json similarity index 100% rename from src/includes/lang/ru.json rename to includes/lang/ru.json diff --git a/src/includes/lang/sk.json b/includes/lang/sk.json similarity index 100% rename from src/includes/lang/sk.json rename to includes/lang/sk.json diff --git a/src/includes/lang/sl.json b/includes/lang/sl.json similarity index 100% rename from src/includes/lang/sl.json rename to includes/lang/sl.json diff --git a/src/includes/lang/sr.json b/includes/lang/sr.json similarity index 100% rename from src/includes/lang/sr.json rename to includes/lang/sr.json diff --git a/src/includes/lang/sv.json b/includes/lang/sv.json similarity index 100% rename from src/includes/lang/sv.json rename to includes/lang/sv.json diff --git a/src/includes/lang/th.json b/includes/lang/th.json similarity index 100% rename from src/includes/lang/th.json rename to includes/lang/th.json diff --git a/src/includes/lang/tr.json b/includes/lang/tr.json similarity index 100% rename from src/includes/lang/tr.json rename to includes/lang/tr.json diff --git a/src/includes/lang/uk.json b/includes/lang/uk.json similarity index 100% rename from src/includes/lang/uk.json rename to includes/lang/uk.json diff --git a/src/includes/lang/vi.json b/includes/lang/vi.json similarity index 100% rename from src/includes/lang/vi.json rename to includes/lang/vi.json diff --git a/src/includes/lang/zh-cn.json b/includes/lang/zh-cn.json similarity index 100% rename from src/includes/lang/zh-cn.json rename to includes/lang/zh-cn.json diff --git a/src/includes/lang/zh-tw.json b/includes/lang/zh-tw.json similarity index 100% rename from src/includes/lang/zh-tw.json rename to includes/lang/zh-tw.json diff --git a/src/includes/markup.commonmark.php b/includes/markup.commonmark.php similarity index 100% rename from src/includes/markup.commonmark.php rename to includes/markup.commonmark.php diff --git a/src/includes/markup.parsedown.php b/includes/markup.parsedown.php similarity index 100% rename from src/includes/markup.parsedown.php rename to includes/markup.parsedown.php diff --git a/src/includes/markup.php b/includes/markup.php similarity index 100% rename from src/includes/markup.php rename to includes/markup.php diff --git a/src/includes/notifications.php b/includes/notifications.php similarity index 100% rename from src/includes/notifications.php rename to includes/notifications.php diff --git a/src/includes/smartsyntax.php b/includes/smartsyntax.php similarity index 100% rename from src/includes/smartsyntax.php rename to includes/smartsyntax.php diff --git a/src/includes/theme.php b/includes/theme.php similarity index 100% rename from src/includes/theme.php rename to includes/theme.php diff --git a/includes/vendor/autoload.php b/includes/vendor/autoload.php new file mode 100644 index 0000000..b160650 --- /dev/null +++ b/includes/vendor/autoload.php @@ -0,0 +1,25 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + /** @var \Closure(string):void */ + private static $includeFile; + + /** @var string|null */ + private $vendorDir; + + // PSR-4 + /** + * @var array> + */ + private $prefixLengthsPsr4 = array(); + /** + * @var array> + */ + private $prefixDirsPsr4 = array(); + /** + * @var list + */ + private $fallbackDirsPsr4 = array(); + + // PSR-0 + /** + * List of PSR-0 prefixes + * + * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) + * + * @var array>> + */ + private $prefixesPsr0 = array(); + /** + * @var list + */ + private $fallbackDirsPsr0 = array(); + + /** @var bool */ + private $useIncludePath = false; + + /** + * @var array + */ + private $classMap = array(); + + /** @var bool */ + private $classMapAuthoritative = false; + + /** + * @var array + */ + private $missingClasses = array(); + + /** @var string|null */ + private $apcuPrefix; + + /** + * @var array + */ + private static $registeredLoaders = array(); + + /** + * @param string|null $vendorDir + */ + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + self::initializeIncludeClosure(); + } + + /** + * @return array> + */ + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); + } + + return array(); + } + + /** + * @return array> + */ + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + /** + * @return list + */ + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + /** + * @return list + */ + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + /** + * @return array Array of classname => path + */ + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + * + * @return void + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + * + * @return void + */ + public function add($prefix, $paths, $prepend = false) + { + $paths = (array) $paths; + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + $paths = (array) $paths; + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 base directories + * + * @return void + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + * + * @return void + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + * + * @return void + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + * + * @return void + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + * + * @return void + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + return; + } + + if ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } + } + + /** + * Unregisters this instance as an autoloader. + * + * @return void + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return true|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + $includeFile = self::$includeFile; + $includeFile($file); + + return true; + } + + return null; + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + /** + * Returns the currently registered loaders keyed by their corresponding vendor directories. + * + * @return array + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + + /** + * @param string $class + * @param string $ext + * @return string|false + */ + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } + + /** + * @return void + */ + private static function initializeIncludeClosure() + { + if (self::$includeFile !== null) { + return; + } + + /** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + */ + self::$includeFile = \Closure::bind(static function($file) { + include $file; + }, null, null); + } +} diff --git a/includes/vendor/composer/InstalledVersions.php b/includes/vendor/composer/InstalledVersions.php new file mode 100644 index 0000000..51e734a --- /dev/null +++ b/includes/vendor/composer/InstalledVersions.php @@ -0,0 +1,359 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer; + +use Composer\Autoload\ClassLoader; +use Composer\Semver\VersionParser; + +/** + * This class is copied in every Composer installed project and available to all + * + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + * + * @final + */ +class InstalledVersions +{ + /** + * @var mixed[]|null + * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null + */ + private static $installed; + + /** + * @var bool|null + */ + private static $canGetVendors; + + /** + * @var array[] + * @psalm-var array}> + */ + private static $installedByVendor = array(); + + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackages() + { + $packages = array(); + foreach (self::getInstalled() as $installed) { + $packages[] = array_keys($installed['versions']); + } + + if (1 === \count($packages)) { + return $packages[0]; + } + + return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); + } + + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + + return $packagesByType; + } + + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @param bool $includeDevRequirements + * @return bool + */ + public static function isInstalled($packageName, $includeDevRequirements = true) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; + } + } + + return false; + } + + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints((string) $constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + + return $provided->matches($constraint); + } + + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + public static function getVersionRanges($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + $ranges = array(); + if (isset($installed['versions'][$packageName]['pretty_version'])) { + $ranges[] = $installed['versions'][$packageName]['pretty_version']; + } + if (array_key_exists('aliases', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); + } + if (array_key_exists('replaced', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); + } + if (array_key_exists('provided', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); + } + + return implode(' || ', $ranges); + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['version'])) { + return null; + } + + return $installed['versions'][$packageName]['version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getPrettyVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['pretty_version'])) { + return null; + } + + return $installed['versions'][$packageName]['pretty_version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference + */ + public static function getReference($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['reference'])) { + return null; + } + + return $installed['versions'][$packageName]['reference']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. + */ + public static function getInstallPath($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @return array + * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} + */ + public static function getRootPackage() + { + $installed = self::getInstalled(); + + return $installed[0]['root']; + } + + /** + * Returns the raw installed.php data for custom implementations + * + * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. + * @return array[] + * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} + */ + public static function getRawData() + { + @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = include __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + + return self::$installed; + } + + /** + * Returns the raw data of all installed.php which are currently loaded for custom implementations + * + * @return array[] + * @psalm-return list}> + */ + public static function getAllRawData() + { + return self::getInstalled(); + } + + /** + * Lets you reload the static array from another file + * + * This is only useful for complex integrations in which a project needs to use + * this class but then also needs to execute another project's autoloader in process, + * and wants to ensure both projects have access to their version of installed.php. + * + * A typical case would be PHPUnit, where it would need to make sure it reads all + * the data it needs from this class, then call reload() with + * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure + * the project in which it runs can then also use this class safely, without + * interference between PHPUnit's dependencies and the project's dependencies. + * + * @param array[] $data A vendor/composer/installed.php data set + * @return void + * + * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data + */ + public static function reload($data) + { + self::$installed = $data; + self::$installedByVendor = array(); + } + + /** + * @return array[] + * @psalm-return list}> + */ + private static function getInstalled() + { + if (null === self::$canGetVendors) { + self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); + } + + $installed = array(); + + if (self::$canGetVendors) { + foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + if (isset(self::$installedByVendor[$vendorDir])) { + $installed[] = self::$installedByVendor[$vendorDir]; + } elseif (is_file($vendorDir.'/composer/installed.php')) { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require $vendorDir.'/composer/installed.php'; + $installed[] = self::$installedByVendor[$vendorDir] = $required; + if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { + self::$installed = $installed[count($installed) - 1]; + } + } + } + } + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require __DIR__ . '/installed.php'; + self::$installed = $required; + } else { + self::$installed = array(); + } + } + + if (self::$installed !== array()) { + $installed[] = self::$installed; + } + + return $installed; + } +} diff --git a/includes/vendor/composer/LICENSE b/includes/vendor/composer/LICENSE new file mode 100644 index 0000000..f27399a --- /dev/null +++ b/includes/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/includes/vendor/composer/autoload_classmap.php b/includes/vendor/composer/autoload_classmap.php new file mode 100644 index 0000000..52fd184 --- /dev/null +++ b/includes/vendor/composer/autoload_classmap.php @@ -0,0 +1,13 @@ + $vendorDir . '/composer/InstalledVersions.php', + 'Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php', + 'Parsedown' => $vendorDir . '/erusev/parsedown/Parsedown.php', + 'Symfony\\Polyfill\\Intl\\Normalizer\\Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Normalizer.php', +); diff --git a/includes/vendor/composer/autoload_files.php b/includes/vendor/composer/autoload_files.php new file mode 100644 index 0000000..23ab925 --- /dev/null +++ b/includes/vendor/composer/autoload_files.php @@ -0,0 +1,10 @@ + $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php', +); diff --git a/includes/vendor/composer/autoload_namespaces.php b/includes/vendor/composer/autoload_namespaces.php new file mode 100644 index 0000000..922da64 --- /dev/null +++ b/includes/vendor/composer/autoload_namespaces.php @@ -0,0 +1,10 @@ + array($vendorDir . '/erusev/parsedown'), +); diff --git a/includes/vendor/composer/autoload_psr4.php b/includes/vendor/composer/autoload_psr4.php new file mode 100644 index 0000000..dedb8cc --- /dev/null +++ b/includes/vendor/composer/autoload_psr4.php @@ -0,0 +1,10 @@ + array($vendorDir . '/symfony/polyfill-intl-normalizer'), +); diff --git a/includes/vendor/composer/autoload_real.php b/includes/vendor/composer/autoload_real.php new file mode 100644 index 0000000..ff40f7d --- /dev/null +++ b/includes/vendor/composer/autoload_real.php @@ -0,0 +1,50 @@ +register(true); + + $filesToLoad = \Composer\Autoload\ComposerStaticInitee0f5e5f2fe7aba230dbdcace19801b2::$files; + $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + + require $file; + } + }, null, null); + foreach ($filesToLoad as $fileIdentifier => $file) { + $requireFile($fileIdentifier, $file); + } + + return $loader; + } +} diff --git a/includes/vendor/composer/autoload_static.php b/includes/vendor/composer/autoload_static.php new file mode 100644 index 0000000..c39147a --- /dev/null +++ b/includes/vendor/composer/autoload_static.php @@ -0,0 +1,54 @@ + __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php', + ); + + public static $prefixLengthsPsr4 = array ( + 'S' => + array ( + 'Symfony\\Polyfill\\Intl\\Normalizer\\' => 33, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'Symfony\\Polyfill\\Intl\\Normalizer\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer', + ), + ); + + public static $prefixesPsr0 = array ( + 'P' => + array ( + 'Parsedown' => + array ( + 0 => __DIR__ . '/..' . '/erusev/parsedown', + ), + ), + ); + + public static $classMap = array ( + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', + 'Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php', + 'Parsedown' => __DIR__ . '/..' . '/erusev/parsedown/Parsedown.php', + 'Symfony\\Polyfill\\Intl\\Normalizer\\Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Normalizer.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInitee0f5e5f2fe7aba230dbdcace19801b2::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitee0f5e5f2fe7aba230dbdcace19801b2::$prefixDirsPsr4; + $loader->prefixesPsr0 = ComposerStaticInitee0f5e5f2fe7aba230dbdcace19801b2::$prefixesPsr0; + $loader->classMap = ComposerStaticInitee0f5e5f2fe7aba230dbdcace19801b2::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/includes/vendor/composer/installed.json b/includes/vendor/composer/installed.json new file mode 100644 index 0000000..efae776 --- /dev/null +++ b/includes/vendor/composer/installed.json @@ -0,0 +1,146 @@ +{ + "packages": [ + { + "name": "erusev/parsedown", + "version": "1.7.4", + "version_normalized": "1.7.4.0", + "source": { + "type": "git", + "url": "https://github.com/erusev/parsedown.git", + "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/erusev/parsedown/zipball/cb17b6477dfff935958ba01325f2e8a2bfa6dab3", + "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35" + }, + "time": "2019-12-30T22:54:17+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "Parsedown": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Emanuil Rusev", + "email": "hello@erusev.com", + "homepage": "http://erusev.com" + } + ], + "description": "Parser for Markdown.", + "homepage": "http://parsedown.org", + "keywords": [ + "markdown", + "parser" + ], + "support": { + "issues": "https://github.com/erusev/parsedown/issues", + "source": "https://github.com/erusev/parsedown/tree/1.7.x" + }, + "install-path": "../erusev/parsedown" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.28.0", + "version_normalized": "1.28.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "time": "2023-01-26T09:26:14+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/polyfill-intl-normalizer" + } + ], + "dev": false, + "dev-package-names": [] +} diff --git a/includes/vendor/composer/installed.php b/includes/vendor/composer/installed.php new file mode 100644 index 0000000..0d10047 --- /dev/null +++ b/includes/vendor/composer/installed.php @@ -0,0 +1,41 @@ + array( + 'name' => '__root__', + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'reference' => '80de4b7a9b19ef5ca1b91b9587f46beef5befef7', + 'type' => 'library', + 'install_path' => __DIR__ . '/../../../../', + 'aliases' => array(), + 'dev' => false, + ), + 'versions' => array( + '__root__' => array( + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'reference' => '80de4b7a9b19ef5ca1b91b9587f46beef5befef7', + 'type' => 'library', + 'install_path' => __DIR__ . '/../../../../', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'erusev/parsedown' => array( + 'pretty_version' => '1.7.4', + 'version' => '1.7.4.0', + 'reference' => 'cb17b6477dfff935958ba01325f2e8a2bfa6dab3', + 'type' => 'library', + 'install_path' => __DIR__ . '/../erusev/parsedown', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-intl-normalizer' => array( + 'pretty_version' => 'v1.28.0', + 'version' => '1.28.0.0', + 'reference' => '8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer', + 'aliases' => array(), + 'dev_requirement' => false, + ), + ), +); diff --git a/includes/vendor/composer/platform_check.php b/includes/vendor/composer/platform_check.php new file mode 100644 index 0000000..6d3407d --- /dev/null +++ b/includes/vendor/composer/platform_check.php @@ -0,0 +1,26 @@ += 70100)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 7.1.0". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR + ); +} diff --git a/includes/vendor/erusev/._parsedown b/includes/vendor/erusev/._parsedown new file mode 100755 index 0000000000000000000000000000000000000000..f751aa387184aa6c03a6e78f287b7dbe6164af5b GIT binary patch literal 194 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@dO|S@ectp5x_AdBnYYuq+->g?hRuS?L<;D7nKJx%nxn KN>=8krnLZ5%NwEq literal 0 HcmV?d00001 diff --git a/includes/vendor/erusev/parsedown/LICENSE.txt b/includes/vendor/erusev/parsedown/LICENSE.txt new file mode 100644 index 0000000..8e7c764 --- /dev/null +++ b/includes/vendor/erusev/parsedown/LICENSE.txt @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013-2018 Emanuil Rusev, erusev.com + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/includes/vendor/erusev/parsedown/Parsedown.php b/includes/vendor/erusev/parsedown/Parsedown.php new file mode 100644 index 0000000..1b9d6d5 --- /dev/null +++ b/includes/vendor/erusev/parsedown/Parsedown.php @@ -0,0 +1,1712 @@ +DefinitionData = array(); + + # standardize line breaks + $text = str_replace(array("\r\n", "\r"), "\n", $text); + + # remove surrounding line breaks + $text = trim($text, "\n"); + + # split text into lines + $lines = explode("\n", $text); + + # iterate through lines to identify blocks + $markup = $this->lines($lines); + + # trim line breaks + $markup = trim($markup, "\n"); + + return $markup; + } + + # + # Setters + # + + function setBreaksEnabled($breaksEnabled) + { + $this->breaksEnabled = $breaksEnabled; + + return $this; + } + + protected $breaksEnabled; + + function setMarkupEscaped($markupEscaped) + { + $this->markupEscaped = $markupEscaped; + + return $this; + } + + protected $markupEscaped; + + function setUrlsLinked($urlsLinked) + { + $this->urlsLinked = $urlsLinked; + + return $this; + } + + protected $urlsLinked = true; + + function setSafeMode($safeMode) + { + $this->safeMode = (bool) $safeMode; + + return $this; + } + + protected $safeMode; + + protected $safeLinksWhitelist = array( + 'http://', + 'https://', + 'ftp://', + 'ftps://', + 'mailto:', + 'data:image/png;base64,', + 'data:image/gif;base64,', + 'data:image/jpeg;base64,', + 'irc:', + 'ircs:', + 'git:', + 'ssh:', + 'news:', + 'steam:', + ); + + # + # Lines + # + + protected $BlockTypes = array( + '#' => array('Header'), + '*' => array('Rule', 'List'), + '+' => array('List'), + '-' => array('SetextHeader', 'Table', 'Rule', 'List'), + '0' => array('List'), + '1' => array('List'), + '2' => array('List'), + '3' => array('List'), + '4' => array('List'), + '5' => array('List'), + '6' => array('List'), + '7' => array('List'), + '8' => array('List'), + '9' => array('List'), + ':' => array('Table'), + '<' => array('Comment', 'Markup'), + '=' => array('SetextHeader'), + '>' => array('Quote'), + '[' => array('Reference'), + '_' => array('Rule'), + '`' => array('FencedCode'), + '|' => array('Table'), + '~' => array('FencedCode'), + ); + + # ~ + + protected $unmarkedBlockTypes = array( + 'Code', + ); + + # + # Blocks + # + + protected function lines(array $lines) + { + $CurrentBlock = null; + + foreach ($lines as $line) + { + if (chop($line) === '') + { + if (isset($CurrentBlock)) + { + $CurrentBlock['interrupted'] = true; + } + + continue; + } + + if (strpos($line, "\t") !== false) + { + $parts = explode("\t", $line); + + $line = $parts[0]; + + unset($parts[0]); + + foreach ($parts as $part) + { + $shortage = 4 - mb_strlen($line, 'utf-8') % 4; + + $line .= str_repeat(' ', $shortage); + $line .= $part; + } + } + + $indent = 0; + + while (isset($line[$indent]) and $line[$indent] === ' ') + { + $indent ++; + } + + $text = $indent > 0 ? substr($line, $indent) : $line; + + # ~ + + $Line = array('body' => $line, 'indent' => $indent, 'text' => $text); + + # ~ + + if (isset($CurrentBlock['continuable'])) + { + $Block = $this->{'block'.$CurrentBlock['type'].'Continue'}($Line, $CurrentBlock); + + if (isset($Block)) + { + $CurrentBlock = $Block; + + continue; + } + else + { + if ($this->isBlockCompletable($CurrentBlock['type'])) + { + $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock); + } + } + } + + # ~ + + $marker = $text[0]; + + # ~ + + $blockTypes = $this->unmarkedBlockTypes; + + if (isset($this->BlockTypes[$marker])) + { + foreach ($this->BlockTypes[$marker] as $blockType) + { + $blockTypes []= $blockType; + } + } + + # + # ~ + + foreach ($blockTypes as $blockType) + { + $Block = $this->{'block'.$blockType}($Line, $CurrentBlock); + + if (isset($Block)) + { + $Block['type'] = $blockType; + + if ( ! isset($Block['identified'])) + { + $Blocks []= $CurrentBlock; + + $Block['identified'] = true; + } + + if ($this->isBlockContinuable($blockType)) + { + $Block['continuable'] = true; + } + + $CurrentBlock = $Block; + + continue 2; + } + } + + # ~ + + if (isset($CurrentBlock) and ! isset($CurrentBlock['type']) and ! isset($CurrentBlock['interrupted'])) + { + $CurrentBlock['element']['text'] .= "\n".$text; + } + else + { + $Blocks []= $CurrentBlock; + + $CurrentBlock = $this->paragraph($Line); + + $CurrentBlock['identified'] = true; + } + } + + # ~ + + if (isset($CurrentBlock['continuable']) and $this->isBlockCompletable($CurrentBlock['type'])) + { + $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock); + } + + # ~ + + $Blocks []= $CurrentBlock; + + unset($Blocks[0]); + + # ~ + + $markup = ''; + + foreach ($Blocks as $Block) + { + if (isset($Block['hidden'])) + { + continue; + } + + $markup .= "\n"; + $markup .= isset($Block['markup']) ? $Block['markup'] : $this->element($Block['element']); + } + + $markup .= "\n"; + + # ~ + + return $markup; + } + + protected function isBlockContinuable($Type) + { + return method_exists($this, 'block'.$Type.'Continue'); + } + + protected function isBlockCompletable($Type) + { + return method_exists($this, 'block'.$Type.'Complete'); + } + + # + # Code + + protected function blockCode($Line, $Block = null) + { + if (isset($Block) and ! isset($Block['type']) and ! isset($Block['interrupted'])) + { + return; + } + + if ($Line['indent'] >= 4) + { + $text = substr($Line['body'], 4); + + $Block = array( + 'element' => array( + 'name' => 'pre', + 'handler' => 'element', + 'text' => array( + 'name' => 'code', + 'text' => $text, + ), + ), + ); + + return $Block; + } + } + + protected function blockCodeContinue($Line, $Block) + { + if ($Line['indent'] >= 4) + { + if (isset($Block['interrupted'])) + { + $Block['element']['text']['text'] .= "\n"; + + unset($Block['interrupted']); + } + + $Block['element']['text']['text'] .= "\n"; + + $text = substr($Line['body'], 4); + + $Block['element']['text']['text'] .= $text; + + return $Block; + } + } + + protected function blockCodeComplete($Block) + { + $text = $Block['element']['text']['text']; + + $Block['element']['text']['text'] = $text; + + return $Block; + } + + # + # Comment + + protected function blockComment($Line) + { + if ($this->markupEscaped or $this->safeMode) + { + return; + } + + if (isset($Line['text'][3]) and $Line['text'][3] === '-' and $Line['text'][2] === '-' and $Line['text'][1] === '!') + { + $Block = array( + 'markup' => $Line['body'], + ); + + if (preg_match('/-->$/', $Line['text'])) + { + $Block['closed'] = true; + } + + return $Block; + } + } + + protected function blockCommentContinue($Line, array $Block) + { + if (isset($Block['closed'])) + { + return; + } + + $Block['markup'] .= "\n" . $Line['body']; + + if (preg_match('/-->$/', $Line['text'])) + { + $Block['closed'] = true; + } + + return $Block; + } + + # + # Fenced Code + + protected function blockFencedCode($Line) + { + if (preg_match('/^['.$Line['text'][0].']{3,}[ ]*([^`]+)?[ ]*$/', $Line['text'], $matches)) + { + $Element = array( + 'name' => 'code', + 'text' => '', + ); + + if (isset($matches[1])) + { + /** + * https://www.w3.org/TR/2011/WD-html5-20110525/elements.html#classes + * Every HTML element may have a class attribute specified. + * The attribute, if specified, must have a value that is a set + * of space-separated tokens representing the various classes + * that the element belongs to. + * [...] + * The space characters, for the purposes of this specification, + * are U+0020 SPACE, U+0009 CHARACTER TABULATION (tab), + * U+000A LINE FEED (LF), U+000C FORM FEED (FF), and + * U+000D CARRIAGE RETURN (CR). + */ + $language = substr($matches[1], 0, strcspn($matches[1], " \t\n\f\r")); + + $class = 'language-'.$language; + + $Element['attributes'] = array( + 'class' => $class, + ); + } + + $Block = array( + 'char' => $Line['text'][0], + 'element' => array( + 'name' => 'pre', + 'handler' => 'element', + 'text' => $Element, + ), + ); + + return $Block; + } + } + + protected function blockFencedCodeContinue($Line, $Block) + { + if (isset($Block['complete'])) + { + return; + } + + if (isset($Block['interrupted'])) + { + $Block['element']['text']['text'] .= "\n"; + + unset($Block['interrupted']); + } + + if (preg_match('/^'.$Block['char'].'{3,}[ ]*$/', $Line['text'])) + { + $Block['element']['text']['text'] = substr($Block['element']['text']['text'], 1); + + $Block['complete'] = true; + + return $Block; + } + + $Block['element']['text']['text'] .= "\n".$Line['body']; + + return $Block; + } + + protected function blockFencedCodeComplete($Block) + { + $text = $Block['element']['text']['text']; + + $Block['element']['text']['text'] = $text; + + return $Block; + } + + # + # Header + + protected function blockHeader($Line) + { + if (isset($Line['text'][1])) + { + $level = 1; + + while (isset($Line['text'][$level]) and $Line['text'][$level] === '#') + { + $level ++; + } + + if ($level > 6) + { + return; + } + + $text = trim($Line['text'], '# '); + + $Block = array( + 'element' => array( + 'name' => 'h' . min(6, $level), + 'text' => $text, + 'handler' => 'line', + ), + ); + + return $Block; + } + } + + # + # List + + protected function blockList($Line) + { + list($name, $pattern) = $Line['text'][0] <= '-' ? array('ul', '[*+-]') : array('ol', '[0-9]+[.]'); + + if (preg_match('/^('.$pattern.'[ ]+)(.*)/', $Line['text'], $matches)) + { + $Block = array( + 'indent' => $Line['indent'], + 'pattern' => $pattern, + 'element' => array( + 'name' => $name, + 'handler' => 'elements', + ), + ); + + if($name === 'ol') + { + $listStart = stristr($matches[0], '.', true); + + if($listStart !== '1') + { + $Block['element']['attributes'] = array('start' => $listStart); + } + } + + $Block['li'] = array( + 'name' => 'li', + 'handler' => 'li', + 'text' => array( + $matches[2], + ), + ); + + $Block['element']['text'] []= & $Block['li']; + + return $Block; + } + } + + protected function blockListContinue($Line, array $Block) + { + if ($Block['indent'] === $Line['indent'] and preg_match('/^'.$Block['pattern'].'(?:[ ]+(.*)|$)/', $Line['text'], $matches)) + { + if (isset($Block['interrupted'])) + { + $Block['li']['text'] []= ''; + + $Block['loose'] = true; + + unset($Block['interrupted']); + } + + unset($Block['li']); + + $text = isset($matches[1]) ? $matches[1] : ''; + + $Block['li'] = array( + 'name' => 'li', + 'handler' => 'li', + 'text' => array( + $text, + ), + ); + + $Block['element']['text'] []= & $Block['li']; + + return $Block; + } + + if ($Line['text'][0] === '[' and $this->blockReference($Line)) + { + return $Block; + } + + if ( ! isset($Block['interrupted'])) + { + $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']); + + $Block['li']['text'] []= $text; + + return $Block; + } + + if ($Line['indent'] > 0) + { + $Block['li']['text'] []= ''; + + $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']); + + $Block['li']['text'] []= $text; + + unset($Block['interrupted']); + + return $Block; + } + } + + protected function blockListComplete(array $Block) + { + if (isset($Block['loose'])) + { + foreach ($Block['element']['text'] as &$li) + { + if (end($li['text']) !== '') + { + $li['text'] []= ''; + } + } + } + + return $Block; + } + + # + # Quote + + protected function blockQuote($Line) + { + if (preg_match('/^>[ ]?(.*)/', $Line['text'], $matches)) + { + $Block = array( + 'element' => array( + 'name' => 'blockquote', + 'handler' => 'lines', + 'text' => (array) $matches[1], + ), + ); + + return $Block; + } + } + + protected function blockQuoteContinue($Line, array $Block) + { + if ($Line['text'][0] === '>' and preg_match('/^>[ ]?(.*)/', $Line['text'], $matches)) + { + if (isset($Block['interrupted'])) + { + $Block['element']['text'] []= ''; + + unset($Block['interrupted']); + } + + $Block['element']['text'] []= $matches[1]; + + return $Block; + } + + if ( ! isset($Block['interrupted'])) + { + $Block['element']['text'] []= $Line['text']; + + return $Block; + } + } + + # + # Rule + + protected function blockRule($Line) + { + if (preg_match('/^(['.$Line['text'][0].'])([ ]*\1){2,}[ ]*$/', $Line['text'])) + { + $Block = array( + 'element' => array( + 'name' => 'hr' + ), + ); + + return $Block; + } + } + + # + # Setext + + protected function blockSetextHeader($Line, array $Block = null) + { + if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted'])) + { + return; + } + + if (chop($Line['text'], $Line['text'][0]) === '') + { + $Block['element']['name'] = $Line['text'][0] === '=' ? 'h1' : 'h2'; + + return $Block; + } + } + + # + # Markup + + protected function blockMarkup($Line) + { + if ($this->markupEscaped or $this->safeMode) + { + return; + } + + if (preg_match('/^<(\w[\w-]*)(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*(\/)?>/', $Line['text'], $matches)) + { + $element = strtolower($matches[1]); + + if (in_array($element, $this->textLevelElements)) + { + return; + } + + $Block = array( + 'name' => $matches[1], + 'depth' => 0, + 'markup' => $Line['text'], + ); + + $length = strlen($matches[0]); + + $remainder = substr($Line['text'], $length); + + if (trim($remainder) === '') + { + if (isset($matches[2]) or in_array($matches[1], $this->voidElements)) + { + $Block['closed'] = true; + + $Block['void'] = true; + } + } + else + { + if (isset($matches[2]) or in_array($matches[1], $this->voidElements)) + { + return; + } + + if (preg_match('/<\/'.$matches[1].'>[ ]*$/i', $remainder)) + { + $Block['closed'] = true; + } + } + + return $Block; + } + } + + protected function blockMarkupContinue($Line, array $Block) + { + if (isset($Block['closed'])) + { + return; + } + + if (preg_match('/^<'.$Block['name'].'(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*>/i', $Line['text'])) # open + { + $Block['depth'] ++; + } + + if (preg_match('/(.*?)<\/'.$Block['name'].'>[ ]*$/i', $Line['text'], $matches)) # close + { + if ($Block['depth'] > 0) + { + $Block['depth'] --; + } + else + { + $Block['closed'] = true; + } + } + + if (isset($Block['interrupted'])) + { + $Block['markup'] .= "\n"; + + unset($Block['interrupted']); + } + + $Block['markup'] .= "\n".$Line['body']; + + return $Block; + } + + # + # Reference + + protected function blockReference($Line) + { + if (preg_match('/^\[(.+?)\]:[ ]*?(?:[ ]+["\'(](.+)["\')])?[ ]*$/', $Line['text'], $matches)) + { + $id = strtolower($matches[1]); + + $Data = array( + 'url' => $matches[2], + 'title' => null, + ); + + if (isset($matches[3])) + { + $Data['title'] = $matches[3]; + } + + $this->DefinitionData['Reference'][$id] = $Data; + + $Block = array( + 'hidden' => true, + ); + + return $Block; + } + } + + # + # Table + + protected function blockTable($Line, array $Block = null) + { + if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted'])) + { + return; + } + + if (strpos($Block['element']['text'], '|') !== false and chop($Line['text'], ' -:|') === '') + { + $alignments = array(); + + $divider = $Line['text']; + + $divider = trim($divider); + $divider = trim($divider, '|'); + + $dividerCells = explode('|', $divider); + + foreach ($dividerCells as $dividerCell) + { + $dividerCell = trim($dividerCell); + + if ($dividerCell === '') + { + continue; + } + + $alignment = null; + + if ($dividerCell[0] === ':') + { + $alignment = 'left'; + } + + if (substr($dividerCell, - 1) === ':') + { + $alignment = $alignment === 'left' ? 'center' : 'right'; + } + + $alignments []= $alignment; + } + + # ~ + + $HeaderElements = array(); + + $header = $Block['element']['text']; + + $header = trim($header); + $header = trim($header, '|'); + + $headerCells = explode('|', $header); + + foreach ($headerCells as $index => $headerCell) + { + $headerCell = trim($headerCell); + + $HeaderElement = array( + 'name' => 'th', + 'text' => $headerCell, + 'handler' => 'line', + ); + + if (isset($alignments[$index])) + { + $alignment = $alignments[$index]; + + $HeaderElement['attributes'] = array( + 'style' => 'text-align: '.$alignment.';', + ); + } + + $HeaderElements []= $HeaderElement; + } + + # ~ + + $Block = array( + 'alignments' => $alignments, + 'identified' => true, + 'element' => array( + 'name' => 'table', + 'handler' => 'elements', + ), + ); + + $Block['element']['text'] []= array( + 'name' => 'thead', + 'handler' => 'elements', + ); + + $Block['element']['text'] []= array( + 'name' => 'tbody', + 'handler' => 'elements', + 'text' => array(), + ); + + $Block['element']['text'][0]['text'] []= array( + 'name' => 'tr', + 'handler' => 'elements', + 'text' => $HeaderElements, + ); + + return $Block; + } + } + + protected function blockTableContinue($Line, array $Block) + { + if (isset($Block['interrupted'])) + { + return; + } + + if ($Line['text'][0] === '|' or strpos($Line['text'], '|')) + { + $Elements = array(); + + $row = $Line['text']; + + $row = trim($row); + $row = trim($row, '|'); + + preg_match_all('/(?:(\\\\[|])|[^|`]|`[^`]+`|`)+/', $row, $matches); + + foreach ($matches[0] as $index => $cell) + { + $cell = trim($cell); + + $Element = array( + 'name' => 'td', + 'handler' => 'line', + 'text' => $cell, + ); + + if (isset($Block['alignments'][$index])) + { + $Element['attributes'] = array( + 'style' => 'text-align: '.$Block['alignments'][$index].';', + ); + } + + $Elements []= $Element; + } + + $Element = array( + 'name' => 'tr', + 'handler' => 'elements', + 'text' => $Elements, + ); + + $Block['element']['text'][1]['text'] []= $Element; + + return $Block; + } + } + + # + # ~ + # + + protected function paragraph($Line) + { + $Block = array( + 'element' => array( + 'name' => 'p', + 'text' => $Line['text'], + 'handler' => 'line', + ), + ); + + return $Block; + } + + # + # Inline Elements + # + + protected $InlineTypes = array( + '"' => array('SpecialCharacter'), + '!' => array('Image'), + '&' => array('SpecialCharacter'), + '*' => array('Emphasis'), + ':' => array('Url'), + '<' => array('UrlTag', 'EmailTag', 'Markup', 'SpecialCharacter'), + '>' => array('SpecialCharacter'), + '[' => array('Link'), + '_' => array('Emphasis'), + '`' => array('Code'), + '~' => array('Strikethrough'), + '\\' => array('EscapeSequence'), + ); + + # ~ + + protected $inlineMarkerList = '!"*_&[:<>`~\\'; + + # + # ~ + # + + public function line($text, $nonNestables=array()) + { + $markup = ''; + + # $excerpt is based on the first occurrence of a marker + + while ($excerpt = strpbrk($text, $this->inlineMarkerList)) + { + $marker = $excerpt[0]; + + $markerPosition = strpos($text, $marker); + + $Excerpt = array('text' => $excerpt, 'context' => $text); + + foreach ($this->InlineTypes[$marker] as $inlineType) + { + # check to see if the current inline type is nestable in the current context + + if ( ! empty($nonNestables) and in_array($inlineType, $nonNestables)) + { + continue; + } + + $Inline = $this->{'inline'.$inlineType}($Excerpt); + + if ( ! isset($Inline)) + { + continue; + } + + # makes sure that the inline belongs to "our" marker + + if (isset($Inline['position']) and $Inline['position'] > $markerPosition) + { + continue; + } + + # sets a default inline position + + if ( ! isset($Inline['position'])) + { + $Inline['position'] = $markerPosition; + } + + # cause the new element to 'inherit' our non nestables + + foreach ($nonNestables as $non_nestable) + { + $Inline['element']['nonNestables'][] = $non_nestable; + } + + # the text that comes before the inline + $unmarkedText = substr($text, 0, $Inline['position']); + + # compile the unmarked text + $markup .= $this->unmarkedText($unmarkedText); + + # compile the inline + $markup .= isset($Inline['markup']) ? $Inline['markup'] : $this->element($Inline['element']); + + # remove the examined text + $text = substr($text, $Inline['position'] + $Inline['extent']); + + continue 2; + } + + # the marker does not belong to an inline + + $unmarkedText = substr($text, 0, $markerPosition + 1); + + $markup .= $this->unmarkedText($unmarkedText); + + $text = substr($text, $markerPosition + 1); + } + + $markup .= $this->unmarkedText($text); + + return $markup; + } + + # + # ~ + # + + protected function inlineCode($Excerpt) + { + $marker = $Excerpt['text'][0]; + + if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(? strlen($matches[0]), + 'element' => array( + 'name' => 'code', + 'text' => $text, + ), + ); + } + } + + protected function inlineEmailTag($Excerpt) + { + if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<((mailto:)?\S+?@\S+?)>/i', $Excerpt['text'], $matches)) + { + $url = $matches[1]; + + if ( ! isset($matches[2])) + { + $url = 'mailto:' . $url; + } + + return array( + 'extent' => strlen($matches[0]), + 'element' => array( + 'name' => 'a', + 'text' => $matches[1], + 'attributes' => array( + 'href' => $url, + ), + ), + ); + } + } + + protected function inlineEmphasis($Excerpt) + { + if ( ! isset($Excerpt['text'][1])) + { + return; + } + + $marker = $Excerpt['text'][0]; + + if ($Excerpt['text'][1] === $marker and preg_match($this->StrongRegex[$marker], $Excerpt['text'], $matches)) + { + $emphasis = 'strong'; + } + elseif (preg_match($this->EmRegex[$marker], $Excerpt['text'], $matches)) + { + $emphasis = 'em'; + } + else + { + return; + } + + return array( + 'extent' => strlen($matches[0]), + 'element' => array( + 'name' => $emphasis, + 'handler' => 'line', + 'text' => $matches[1], + ), + ); + } + + protected function inlineEscapeSequence($Excerpt) + { + if (isset($Excerpt['text'][1]) and in_array($Excerpt['text'][1], $this->specialCharacters)) + { + return array( + 'markup' => $Excerpt['text'][1], + 'extent' => 2, + ); + } + } + + protected function inlineImage($Excerpt) + { + if ( ! isset($Excerpt['text'][1]) or $Excerpt['text'][1] !== '[') + { + return; + } + + $Excerpt['text']= substr($Excerpt['text'], 1); + + $Link = $this->inlineLink($Excerpt); + + if ($Link === null) + { + return; + } + + $Inline = array( + 'extent' => $Link['extent'] + 1, + 'element' => array( + 'name' => 'img', + 'attributes' => array( + 'src' => $Link['element']['attributes']['href'], + 'alt' => $Link['element']['text'], + ), + ), + ); + + $Inline['element']['attributes'] += $Link['element']['attributes']; + + unset($Inline['element']['attributes']['href']); + + return $Inline; + } + + protected function inlineLink($Excerpt) + { + $Element = array( + 'name' => 'a', + 'handler' => 'line', + 'nonNestables' => array('Url', 'Link'), + 'text' => null, + 'attributes' => array( + 'href' => null, + 'title' => null, + ), + ); + + $extent = 0; + + $remainder = $Excerpt['text']; + + if (preg_match('/\[((?:[^][]++|(?R))*+)\]/', $remainder, $matches)) + { + $Element['text'] = $matches[1]; + + $extent += strlen($matches[0]); + + $remainder = substr($remainder, $extent); + } + else + { + return; + } + + if (preg_match('/^[(]\s*+((?:[^ ()]++|[(][^ )]+[)])++)(?:[ ]+("[^"]*"|\'[^\']*\'))?\s*[)]/', $remainder, $matches)) + { + $Element['attributes']['href'] = $matches[1]; + + if (isset($matches[2])) + { + $Element['attributes']['title'] = substr($matches[2], 1, - 1); + } + + $extent += strlen($matches[0]); + } + else + { + if (preg_match('/^\s*\[(.*?)\]/', $remainder, $matches)) + { + $definition = strlen($matches[1]) ? $matches[1] : $Element['text']; + $definition = strtolower($definition); + + $extent += strlen($matches[0]); + } + else + { + $definition = strtolower($Element['text']); + } + + if ( ! isset($this->DefinitionData['Reference'][$definition])) + { + return; + } + + $Definition = $this->DefinitionData['Reference'][$definition]; + + $Element['attributes']['href'] = $Definition['url']; + $Element['attributes']['title'] = $Definition['title']; + } + + return array( + 'extent' => $extent, + 'element' => $Element, + ); + } + + protected function inlineMarkup($Excerpt) + { + if ($this->markupEscaped or $this->safeMode or strpos($Excerpt['text'], '>') === false) + { + return; + } + + if ($Excerpt['text'][1] === '/' and preg_match('/^<\/\w[\w-]*[ ]*>/s', $Excerpt['text'], $matches)) + { + return array( + 'markup' => $matches[0], + 'extent' => strlen($matches[0]), + ); + } + + if ($Excerpt['text'][1] === '!' and preg_match('/^/s', $Excerpt['text'], $matches)) + { + return array( + 'markup' => $matches[0], + 'extent' => strlen($matches[0]), + ); + } + + if ($Excerpt['text'][1] !== ' ' and preg_match('/^<\w[\w-]*(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*\/?>/s', $Excerpt['text'], $matches)) + { + return array( + 'markup' => $matches[0], + 'extent' => strlen($matches[0]), + ); + } + } + + protected function inlineSpecialCharacter($Excerpt) + { + if ($Excerpt['text'][0] === '&' and ! preg_match('/^&#?\w+;/', $Excerpt['text'])) + { + return array( + 'markup' => '&', + 'extent' => 1, + ); + } + + $SpecialCharacter = array('>' => 'gt', '<' => 'lt', '"' => 'quot'); + + if (isset($SpecialCharacter[$Excerpt['text'][0]])) + { + return array( + 'markup' => '&'.$SpecialCharacter[$Excerpt['text'][0]].';', + 'extent' => 1, + ); + } + } + + protected function inlineStrikethrough($Excerpt) + { + if ( ! isset($Excerpt['text'][1])) + { + return; + } + + if ($Excerpt['text'][1] === '~' and preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $Excerpt['text'], $matches)) + { + return array( + 'extent' => strlen($matches[0]), + 'element' => array( + 'name' => 'del', + 'text' => $matches[1], + 'handler' => 'line', + ), + ); + } + } + + protected function inlineUrl($Excerpt) + { + if ($this->urlsLinked !== true or ! isset($Excerpt['text'][2]) or $Excerpt['text'][2] !== '/') + { + return; + } + + if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE)) + { + $url = $matches[0][0]; + + $Inline = array( + 'extent' => strlen($matches[0][0]), + 'position' => $matches[0][1], + 'element' => array( + 'name' => 'a', + 'text' => $url, + 'attributes' => array( + 'href' => $url, + ), + ), + ); + + return $Inline; + } + } + + protected function inlineUrlTag($Excerpt) + { + if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w+:\/{2}[^ >]+)>/i', $Excerpt['text'], $matches)) + { + $url = $matches[1]; + + return array( + 'extent' => strlen($matches[0]), + 'element' => array( + 'name' => 'a', + 'text' => $url, + 'attributes' => array( + 'href' => $url, + ), + ), + ); + } + } + + # ~ + + protected function unmarkedText($text) + { + if ($this->breaksEnabled) + { + $text = preg_replace('/[ ]*\n/', "
\n", $text); + } + else + { + $text = preg_replace('/(?:[ ][ ]+|[ ]*\\\\)\n/', "
\n", $text); + $text = str_replace(" \n", "\n", $text); + } + + return $text; + } + + # + # Handlers + # + + protected function element(array $Element) + { + if ($this->safeMode) + { + $Element = $this->sanitiseElement($Element); + } + + $markup = '<'.$Element['name']; + + if (isset($Element['attributes'])) + { + foreach ($Element['attributes'] as $name => $value) + { + if ($value === null) + { + continue; + } + + $markup .= ' '.$name.'="'.self::escape($value).'"'; + } + } + + $permitRawHtml = false; + + if (isset($Element['text'])) + { + $text = $Element['text']; + } + // very strongly consider an alternative if you're writing an + // extension + elseif (isset($Element['rawHtml'])) + { + $text = $Element['rawHtml']; + $allowRawHtmlInSafeMode = isset($Element['allowRawHtmlInSafeMode']) && $Element['allowRawHtmlInSafeMode']; + $permitRawHtml = !$this->safeMode || $allowRawHtmlInSafeMode; + } + + if (isset($text)) + { + $markup .= '>'; + + if (!isset($Element['nonNestables'])) + { + $Element['nonNestables'] = array(); + } + + if (isset($Element['handler'])) + { + $markup .= $this->{$Element['handler']}($text, $Element['nonNestables']); + } + elseif (!$permitRawHtml) + { + $markup .= self::escape($text, true); + } + else + { + $markup .= $text; + } + + $markup .= ''; + } + else + { + $markup .= ' />'; + } + + return $markup; + } + + protected function elements(array $Elements) + { + $markup = ''; + + foreach ($Elements as $Element) + { + $markup .= "\n" . $this->element($Element); + } + + $markup .= "\n"; + + return $markup; + } + + # ~ + + protected function li($lines) + { + $markup = $this->lines($lines); + + $trimmedMarkup = trim($markup); + + if ( ! in_array('', $lines) and substr($trimmedMarkup, 0, 3) === '

') + { + $markup = $trimmedMarkup; + $markup = substr($markup, 3); + + $position = strpos($markup, "

"); + + $markup = substr_replace($markup, '', $position, 4); + } + + return $markup; + } + + # + # Deprecated Methods + # + + function parse($text) + { + $markup = $this->text($text); + + return $markup; + } + + protected function sanitiseElement(array $Element) + { + static $goodAttribute = '/^[a-zA-Z0-9][a-zA-Z0-9-_]*+$/'; + static $safeUrlNameToAtt = array( + 'a' => 'href', + 'img' => 'src', + ); + + if (isset($safeUrlNameToAtt[$Element['name']])) + { + $Element = $this->filterUnsafeUrlInAttribute($Element, $safeUrlNameToAtt[$Element['name']]); + } + + if ( ! empty($Element['attributes'])) + { + foreach ($Element['attributes'] as $att => $val) + { + # filter out badly parsed attribute + if ( ! preg_match($goodAttribute, $att)) + { + unset($Element['attributes'][$att]); + } + # dump onevent attribute + elseif (self::striAtStart($att, 'on')) + { + unset($Element['attributes'][$att]); + } + } + } + + return $Element; + } + + protected function filterUnsafeUrlInAttribute(array $Element, $attribute) + { + foreach ($this->safeLinksWhitelist as $scheme) + { + if (self::striAtStart($Element['attributes'][$attribute], $scheme)) + { + return $Element; + } + } + + $Element['attributes'][$attribute] = str_replace(':', '%3A', $Element['attributes'][$attribute]); + + return $Element; + } + + # + # Static Methods + # + + protected static function escape($text, $allowQuotes = false) + { + return htmlspecialchars($text, $allowQuotes ? ENT_NOQUOTES : ENT_QUOTES, 'UTF-8'); + } + + protected static function striAtStart($string, $needle) + { + $len = strlen($needle); + + if ($len > strlen($string)) + { + return false; + } + else + { + return strtolower(substr($string, 0, $len)) === strtolower($needle); + } + } + + static function instance($name = 'default') + { + if (isset(self::$instances[$name])) + { + return self::$instances[$name]; + } + + $instance = new static(); + + self::$instances[$name] = $instance; + + return $instance; + } + + private static $instances = array(); + + # + # Fields + # + + protected $DefinitionData; + + # + # Read-Only + + protected $specialCharacters = array( + '\\', '`', '*', '_', '{', '}', '[', ']', '(', ')', '>', '#', '+', '-', '.', '!', '|', + ); + + protected $StrongRegex = array( + '*' => '/^[*]{2}((?:\\\\\*|[^*]|[*][^*]*[*])+?)[*]{2}(?![*])/s', + '_' => '/^__((?:\\\\_|[^_]|_[^_]*_)+?)__(?!_)/us', + ); + + protected $EmRegex = array( + '*' => '/^[*]((?:\\\\\*|[^*]|[*][*][^*]+?[*][*])+?)[*](?![*])/s', + '_' => '/^_((?:\\\\_|[^_]|__[^_]*__)+?)_(?!_)\b/us', + ); + + protected $regexHtmlAttribute = '[a-zA-Z_:][\w:.-]*(?:\s*=\s*(?:[^"\'=<>`\s]+|"[^"]*"|\'[^\']*\'))?'; + + protected $voidElements = array( + 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', + ); + + protected $textLevelElements = array( + 'a', 'br', 'bdo', 'abbr', 'blink', 'nextid', 'acronym', 'basefont', + 'b', 'em', 'big', 'cite', 'small', 'spacer', 'listing', + 'i', 'rp', 'del', 'code', 'strike', 'marquee', + 'q', 'rt', 'ins', 'font', 'strong', + 's', 'tt', 'kbd', 'mark', + 'u', 'xm', 'sub', 'nobr', + 'sup', 'ruby', + 'var', 'span', + 'wbr', 'time', + ); +} diff --git a/includes/vendor/erusev/parsedown/README.md b/includes/vendor/erusev/parsedown/README.md new file mode 100644 index 0000000..b5d9ed2 --- /dev/null +++ b/includes/vendor/erusev/parsedown/README.md @@ -0,0 +1,86 @@ +> I also make [Caret](https://caret.io?ref=parsedown) - a Markdown editor for Mac and PC. + +## Parsedown + +[![Build Status](https://img.shields.io/travis/erusev/parsedown/master.svg?style=flat-square)](https://travis-ci.org/erusev/parsedown) + + +Better Markdown Parser in PHP + +[Demo](http://parsedown.org/demo) | +[Benchmarks](http://parsedown.org/speed) | +[Tests](http://parsedown.org/tests/) | +[Documentation](https://github.com/erusev/parsedown/wiki/) + +### Features + +* One File +* No Dependencies +* Super Fast +* Extensible +* [GitHub flavored](https://help.github.com/articles/github-flavored-markdown) +* Tested in 5.3 to 7.1 and in HHVM +* [Markdown Extra extension](https://github.com/erusev/parsedown-extra) + +### Installation + +Include `Parsedown.php` or install [the composer package](https://packagist.org/packages/erusev/parsedown). + +### Example + +``` php +$Parsedown = new Parsedown(); + +echo $Parsedown->text('Hello _Parsedown_!'); # prints:

Hello Parsedown!

+``` + +More examples in [the wiki](https://github.com/erusev/parsedown/wiki/) and in [this video tutorial](http://youtu.be/wYZBY8DEikI). + +### Security + +Parsedown is capable of escaping user-input within the HTML that it generates. Additionally Parsedown will apply sanitisation to additional scripting vectors (such as scripting link destinations) that are introduced by the markdown syntax itself. + +To tell Parsedown that it is processing untrusted user-input, use the following: +```php +$parsedown = new Parsedown; +$parsedown->setSafeMode(true); +``` + +If instead, you wish to allow HTML within untrusted user-input, but still want output to be free from XSS it is recommended that you make use of a HTML sanitiser that allows HTML tags to be whitelisted, like [HTML Purifier](http://htmlpurifier.org/). + +In both cases you should strongly consider employing defence-in-depth measures, like [deploying a Content-Security-Policy](https://scotthelme.co.uk/content-security-policy-an-introduction/) (a browser security feature) so that your page is likely to be safe even if an attacker finds a vulnerability in one of the first lines of defence above. + +#### Security of Parsedown Extensions + +Safe mode does not necessarily yield safe results when using extensions to Parsedown. Extensions should be evaluated on their own to determine their specific safety against XSS. + +### Escaping HTML +> ⚠️  **WARNING:** This method isn't safe from XSS! + +If you wish to escape HTML **in trusted input**, you can use the following: +```php +$parsedown = new Parsedown; +$parsedown->setMarkupEscaped(true); +``` + +Beware that this still allows users to insert unsafe scripting vectors, such as links like `[xss](javascript:alert%281%29)`. + +### Questions + +**How does Parsedown work?** + +It tries to read Markdown like a human. First, it looks at the lines. It’s interested in how the lines start. This helps it recognise blocks. It knows, for example, that if a line starts with a `-` then perhaps it belongs to a list. Once it recognises the blocks, it continues to the content. As it reads, it watches out for special characters. This helps it recognise inline elements (or inlines). + +We call this approach "line based". We believe that Parsedown is the first Markdown parser to use it. Since the release of Parsedown, other developers have used the same approach to develop other Markdown parsers in PHP and in other languages. + +**Is it compliant with CommonMark?** + +It passes most of the CommonMark tests. Most of the tests that don't pass deal with cases that are quite uncommon. Still, as CommonMark matures, compliance should improve. + +**Who uses it?** + +[Laravel Framework](https://laravel.com/), [Bolt CMS](http://bolt.cm/), [Grav CMS](http://getgrav.org/), [Herbie CMS](http://www.getherbie.org/), [Kirby CMS](http://getkirby.com/), [October CMS](http://octobercms.com/), [Pico CMS](http://picocms.org), [Statamic CMS](http://www.statamic.com/), [phpDocumentor](http://www.phpdoc.org/), [RaspberryPi.org](http://www.raspberrypi.org/), [Symfony demo](https://github.com/symfony/symfony-demo) and [more](https://packagist.org/packages/erusev/parsedown/dependents). + +**How can I help?** + +Use it, star it, share it and if you feel generous, [donate](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=528P3NZQMP8N2). diff --git a/includes/vendor/erusev/parsedown/composer.json b/includes/vendor/erusev/parsedown/composer.json new file mode 100644 index 0000000..f8b40f8 --- /dev/null +++ b/includes/vendor/erusev/parsedown/composer.json @@ -0,0 +1,33 @@ +{ + "name": "erusev/parsedown", + "description": "Parser for Markdown.", + "keywords": ["markdown", "parser"], + "homepage": "http://parsedown.org", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Emanuil Rusev", + "email": "hello@erusev.com", + "homepage": "http://erusev.com" + } + ], + "require": { + "php": ">=5.3.0", + "ext-mbstring": "*" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35" + }, + "autoload": { + "psr-0": {"Parsedown": ""} + }, + "autoload-dev": { + "psr-0": { + "TestParsedown": "test/", + "ParsedownTest": "test/", + "CommonMarkTest": "test/", + "CommonMarkTestWeak": "test/" + } + } +} diff --git a/includes/vendor/symfony/._polyfill-intl-normalizer b/includes/vendor/symfony/._polyfill-intl-normalizer new file mode 100755 index 0000000000000000000000000000000000000000..f751aa387184aa6c03a6e78f287b7dbe6164af5b GIT binary patch literal 194 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@dO|S@ectp5x_AdBnYYuq+->g?hRuS?L<;D7nKJx%nxn KN>=8krnLZ5%NwEq literal 0 HcmV?d00001 diff --git a/includes/vendor/symfony/polyfill-intl-normalizer/._Resources b/includes/vendor/symfony/polyfill-intl-normalizer/._Resources new file mode 100755 index 0000000000000000000000000000000000000000..f751aa387184aa6c03a6e78f287b7dbe6164af5b GIT binary patch literal 194 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@dO|S@ectp5x_AdBnYYuq+->g?hRuS?L<;D7nKJx%nxn KN>=8krnLZ5%NwEq literal 0 HcmV?d00001 diff --git a/includes/vendor/symfony/polyfill-intl-normalizer/LICENSE b/includes/vendor/symfony/polyfill-intl-normalizer/LICENSE new file mode 100644 index 0000000..6e3afce --- /dev/null +++ b/includes/vendor/symfony/polyfill-intl-normalizer/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/includes/vendor/symfony/polyfill-intl-normalizer/Normalizer.php b/includes/vendor/symfony/polyfill-intl-normalizer/Normalizer.php new file mode 100644 index 0000000..81704ab --- /dev/null +++ b/includes/vendor/symfony/polyfill-intl-normalizer/Normalizer.php @@ -0,0 +1,310 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Intl\Normalizer; + +/** + * Normalizer is a PHP fallback implementation of the Normalizer class provided by the intl extension. + * + * It has been validated with Unicode 6.3 Normalization Conformance Test. + * See http://www.unicode.org/reports/tr15/ for detailed info about Unicode normalizations. + * + * @author Nicolas Grekas + * + * @internal + */ +class Normalizer +{ + public const FORM_D = \Normalizer::FORM_D; + public const FORM_KD = \Normalizer::FORM_KD; + public const FORM_C = \Normalizer::FORM_C; + public const FORM_KC = \Normalizer::FORM_KC; + public const NFD = \Normalizer::NFD; + public const NFKD = \Normalizer::NFKD; + public const NFC = \Normalizer::NFC; + public const NFKC = \Normalizer::NFKC; + + private static $C; + private static $D; + private static $KD; + private static $cC; + private static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4]; + private static $ASCII = "\x20\x65\x69\x61\x73\x6E\x74\x72\x6F\x6C\x75\x64\x5D\x5B\x63\x6D\x70\x27\x0A\x67\x7C\x68\x76\x2E\x66\x62\x2C\x3A\x3D\x2D\x71\x31\x30\x43\x32\x2A\x79\x78\x29\x28\x4C\x39\x41\x53\x2F\x50\x22\x45\x6A\x4D\x49\x6B\x33\x3E\x35\x54\x3C\x44\x34\x7D\x42\x7B\x38\x46\x77\x52\x36\x37\x55\x47\x4E\x3B\x4A\x7A\x56\x23\x48\x4F\x57\x5F\x26\x21\x4B\x3F\x58\x51\x25\x59\x5C\x09\x5A\x2B\x7E\x5E\x24\x40\x60\x7F\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"; + + public static function isNormalized(string $s, int $form = self::FORM_C) + { + if (!\in_array($form, [self::NFD, self::NFKD, self::NFC, self::NFKC])) { + return false; + } + if (!isset($s[strspn($s, self::$ASCII)])) { + return true; + } + if (self::NFC == $form && preg_match('//u', $s) && !preg_match('/[^\x00-\x{2FF}]/u', $s)) { + return true; + } + + return self::normalize($s, $form) === $s; + } + + public static function normalize(string $s, int $form = self::FORM_C) + { + if (!preg_match('//u', $s)) { + return false; + } + + switch ($form) { + case self::NFC: $C = true; $K = false; break; + case self::NFD: $C = false; $K = false; break; + case self::NFKC: $C = true; $K = true; break; + case self::NFKD: $C = false; $K = true; break; + default: + if (\defined('Normalizer::NONE') && \Normalizer::NONE == $form) { + return $s; + } + + if (80000 > \PHP_VERSION_ID) { + return false; + } + + throw new \ValueError('normalizer_normalize(): Argument #2 ($form) must be a a valid normalization form'); + } + + if ('' === $s) { + return ''; + } + + if ($K && null === self::$KD) { + self::$KD = self::getData('compatibilityDecomposition'); + } + + if (null === self::$D) { + self::$D = self::getData('canonicalDecomposition'); + self::$cC = self::getData('combiningClass'); + } + + if (null !== $mbEncoding = (2 /* MB_OVERLOAD_STRING */ & (int) \ini_get('mbstring.func_overload')) ? mb_internal_encoding() : null) { + mb_internal_encoding('8bit'); + } + + $r = self::decompose($s, $K); + + if ($C) { + if (null === self::$C) { + self::$C = self::getData('canonicalComposition'); + } + + $r = self::recompose($r); + } + if (null !== $mbEncoding) { + mb_internal_encoding($mbEncoding); + } + + return $r; + } + + private static function recompose($s) + { + $ASCII = self::$ASCII; + $compMap = self::$C; + $combClass = self::$cC; + $ulenMask = self::$ulenMask; + + $result = $tail = ''; + + $i = $s[0] < "\x80" ? 1 : $ulenMask[$s[0] & "\xF0"]; + $len = \strlen($s); + + $lastUchr = substr($s, 0, $i); + $lastUcls = isset($combClass[$lastUchr]) ? 256 : 0; + + while ($i < $len) { + if ($s[$i] < "\x80") { + // ASCII chars + + if ($tail) { + $lastUchr .= $tail; + $tail = ''; + } + + if ($j = strspn($s, $ASCII, $i + 1)) { + $lastUchr .= substr($s, $i, $j); + $i += $j; + } + + $result .= $lastUchr; + $lastUchr = $s[$i]; + $lastUcls = 0; + ++$i; + continue; + } + + $ulen = $ulenMask[$s[$i] & "\xF0"]; + $uchr = substr($s, $i, $ulen); + + if ($lastUchr < "\xE1\x84\x80" || "\xE1\x84\x92" < $lastUchr + || $uchr < "\xE1\x85\xA1" || "\xE1\x85\xB5" < $uchr + || $lastUcls) { + // Table lookup and combining chars composition + + $ucls = $combClass[$uchr] ?? 0; + + if (isset($compMap[$lastUchr.$uchr]) && (!$lastUcls || $lastUcls < $ucls)) { + $lastUchr = $compMap[$lastUchr.$uchr]; + } elseif ($lastUcls = $ucls) { + $tail .= $uchr; + } else { + if ($tail) { + $lastUchr .= $tail; + $tail = ''; + } + + $result .= $lastUchr; + $lastUchr = $uchr; + } + } else { + // Hangul chars + + $L = \ord($lastUchr[2]) - 0x80; + $V = \ord($uchr[2]) - 0xA1; + $T = 0; + + $uchr = substr($s, $i + $ulen, 3); + + if ("\xE1\x86\xA7" <= $uchr && $uchr <= "\xE1\x87\x82") { + $T = \ord($uchr[2]) - 0xA7; + 0 > $T && $T += 0x40; + $ulen += 3; + } + + $L = 0xAC00 + ($L * 21 + $V) * 28 + $T; + $lastUchr = \chr(0xE0 | $L >> 12).\chr(0x80 | $L >> 6 & 0x3F).\chr(0x80 | $L & 0x3F); + } + + $i += $ulen; + } + + return $result.$lastUchr.$tail; + } + + private static function decompose($s, $c) + { + $result = ''; + + $ASCII = self::$ASCII; + $decompMap = self::$D; + $combClass = self::$cC; + $ulenMask = self::$ulenMask; + if ($c) { + $compatMap = self::$KD; + } + + $c = []; + $i = 0; + $len = \strlen($s); + + while ($i < $len) { + if ($s[$i] < "\x80") { + // ASCII chars + + if ($c) { + ksort($c); + $result .= implode('', $c); + $c = []; + } + + $j = 1 + strspn($s, $ASCII, $i + 1); + $result .= substr($s, $i, $j); + $i += $j; + continue; + } + + $ulen = $ulenMask[$s[$i] & "\xF0"]; + $uchr = substr($s, $i, $ulen); + $i += $ulen; + + if ($uchr < "\xEA\xB0\x80" || "\xED\x9E\xA3" < $uchr) { + // Table lookup + + if ($uchr !== $j = $compatMap[$uchr] ?? ($decompMap[$uchr] ?? $uchr)) { + $uchr = $j; + + $j = \strlen($uchr); + $ulen = $uchr[0] < "\x80" ? 1 : $ulenMask[$uchr[0] & "\xF0"]; + + if ($ulen != $j) { + // Put trailing chars in $s + + $j -= $ulen; + $i -= $j; + + if (0 > $i) { + $s = str_repeat(' ', -$i).$s; + $len -= $i; + $i = 0; + } + + while ($j--) { + $s[$i + $j] = $uchr[$ulen + $j]; + } + + $uchr = substr($uchr, 0, $ulen); + } + } + if (isset($combClass[$uchr])) { + // Combining chars, for sorting + + if (!isset($c[$combClass[$uchr]])) { + $c[$combClass[$uchr]] = ''; + } + $c[$combClass[$uchr]] .= $uchr; + continue; + } + } else { + // Hangul chars + + $uchr = unpack('C*', $uchr); + $j = (($uchr[1] - 224) << 12) + (($uchr[2] - 128) << 6) + $uchr[3] - 0xAC80; + + $uchr = "\xE1\x84".\chr(0x80 + (int) ($j / 588)) + ."\xE1\x85".\chr(0xA1 + (int) (($j % 588) / 28)); + + if ($j %= 28) { + $uchr .= $j < 25 + ? ("\xE1\x86".\chr(0xA7 + $j)) + : ("\xE1\x87".\chr(0x67 + $j)); + } + } + if ($c) { + ksort($c); + $result .= implode('', $c); + $c = []; + } + + $result .= $uchr; + } + + if ($c) { + ksort($c); + $result .= implode('', $c); + } + + return $result; + } + + private static function getData($file) + { + if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) { + return require $file; + } + + return false; + } +} diff --git a/includes/vendor/symfony/polyfill-intl-normalizer/README.md b/includes/vendor/symfony/polyfill-intl-normalizer/README.md new file mode 100644 index 0000000..b9b762e --- /dev/null +++ b/includes/vendor/symfony/polyfill-intl-normalizer/README.md @@ -0,0 +1,14 @@ +Symfony Polyfill / Intl: Normalizer +=================================== + +This component provides a fallback implementation for the +[`Normalizer`](https://php.net/Normalizer) class provided +by the [Intl](https://php.net/intl) extension. + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/includes/vendor/symfony/polyfill-intl-normalizer/Resources/._stubs b/includes/vendor/symfony/polyfill-intl-normalizer/Resources/._stubs new file mode 100755 index 0000000000000000000000000000000000000000..f751aa387184aa6c03a6e78f287b7dbe6164af5b GIT binary patch literal 194 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@dO|S@ectp5x_AdBnYYuq+->g?hRuS?L<;D7nKJx%nxn KN>=8krnLZ5%NwEq literal 0 HcmV?d00001 diff --git a/includes/vendor/symfony/polyfill-intl-normalizer/Resources/._unidata b/includes/vendor/symfony/polyfill-intl-normalizer/Resources/._unidata new file mode 100755 index 0000000000000000000000000000000000000000..f751aa387184aa6c03a6e78f287b7dbe6164af5b GIT binary patch literal 194 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@dO|S@ectp5x_AdBnYYuq+->g?hRuS?L<;D7nKJx%nxn KN>=8krnLZ5%NwEq literal 0 HcmV?d00001 diff --git a/includes/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php b/includes/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php new file mode 100644 index 0000000..0fdfc89 --- /dev/null +++ b/includes/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php @@ -0,0 +1,17 @@ + 'À', + 'Á' => 'Á', + 'Â' => 'Â', + 'Ã' => 'Ã', + 'Ä' => 'Ä', + 'Å' => 'Å', + 'Ç' => 'Ç', + 'È' => 'È', + 'É' => 'É', + 'Ê' => 'Ê', + 'Ë' => 'Ë', + 'Ì' => 'Ì', + 'Í' => 'Í', + 'Î' => 'Î', + 'Ï' => 'Ï', + 'Ñ' => 'Ñ', + 'Ò' => 'Ò', + 'Ó' => 'Ó', + 'Ô' => 'Ô', + 'Õ' => 'Õ', + 'Ö' => 'Ö', + 'Ù' => 'Ù', + 'Ú' => 'Ú', + 'Û' => 'Û', + 'Ü' => 'Ü', + 'Ý' => 'Ý', + 'à' => 'à', + 'á' => 'á', + 'â' => 'â', + 'ã' => 'ã', + 'ä' => 'ä', + 'å' => 'å', + 'ç' => 'ç', + 'è' => 'è', + 'é' => 'é', + 'ê' => 'ê', + 'ë' => 'ë', + 'ì' => 'ì', + 'í' => 'í', + 'î' => 'î', + 'ï' => 'ï', + 'ñ' => 'ñ', + 'ò' => 'ò', + 'ó' => 'ó', + 'ô' => 'ô', + 'õ' => 'õ', + 'ö' => 'ö', + 'ù' => 'ù', + 'ú' => 'ú', + 'û' => 'û', + 'ü' => 'ü', + 'ý' => 'ý', + 'ÿ' => 'ÿ', + 'Ā' => 'Ā', + 'ā' => 'ā', + 'Ă' => 'Ă', + 'ă' => 'ă', + 'Ą' => 'Ą', + 'ą' => 'ą', + 'Ć' => 'Ć', + 'ć' => 'ć', + 'Ĉ' => 'Ĉ', + 'ĉ' => 'ĉ', + 'Ċ' => 'Ċ', + 'ċ' => 'ċ', + 'Č' => 'Č', + 'č' => 'č', + 'Ď' => 'Ď', + 'ď' => 'ď', + 'Ē' => 'Ē', + 'ē' => 'ē', + 'Ĕ' => 'Ĕ', + 'ĕ' => 'ĕ', + 'Ė' => 'Ė', + 'ė' => 'ė', + 'Ę' => 'Ę', + 'ę' => 'ę', + 'Ě' => 'Ě', + 'ě' => 'ě', + 'Ĝ' => 'Ĝ', + 'ĝ' => 'ĝ', + 'Ğ' => 'Ğ', + 'ğ' => 'ğ', + 'Ġ' => 'Ġ', + 'ġ' => 'ġ', + 'Ģ' => 'Ģ', + 'ģ' => 'ģ', + 'Ĥ' => 'Ĥ', + 'ĥ' => 'ĥ', + 'Ĩ' => 'Ĩ', + 'ĩ' => 'ĩ', + 'Ī' => 'Ī', + 'ī' => 'ī', + 'Ĭ' => 'Ĭ', + 'ĭ' => 'ĭ', + 'Į' => 'Į', + 'į' => 'į', + 'İ' => 'İ', + 'Ĵ' => 'Ĵ', + 'ĵ' => 'ĵ', + 'Ķ' => 'Ķ', + 'ķ' => 'ķ', + 'Ĺ' => 'Ĺ', + 'ĺ' => 'ĺ', + 'Ļ' => 'Ļ', + 'ļ' => 'ļ', + 'Ľ' => 'Ľ', + 'ľ' => 'ľ', + 'Ń' => 'Ń', + 'ń' => 'ń', + 'Ņ' => 'Ņ', + 'ņ' => 'ņ', + 'Ň' => 'Ň', + 'ň' => 'ň', + 'Ō' => 'Ō', + 'ō' => 'ō', + 'Ŏ' => 'Ŏ', + 'ŏ' => 'ŏ', + 'Ő' => 'Ő', + 'ő' => 'ő', + 'Ŕ' => 'Ŕ', + 'ŕ' => 'ŕ', + 'Ŗ' => 'Ŗ', + 'ŗ' => 'ŗ', + 'Ř' => 'Ř', + 'ř' => 'ř', + 'Ś' => 'Ś', + 'ś' => 'ś', + 'Ŝ' => 'Ŝ', + 'ŝ' => 'ŝ', + 'Ş' => 'Ş', + 'ş' => 'ş', + 'Š' => 'Š', + 'š' => 'š', + 'Ţ' => 'Ţ', + 'ţ' => 'ţ', + 'Ť' => 'Ť', + 'ť' => 'ť', + 'Ũ' => 'Ũ', + 'ũ' => 'ũ', + 'Ū' => 'Ū', + 'ū' => 'ū', + 'Ŭ' => 'Ŭ', + 'ŭ' => 'ŭ', + 'Ů' => 'Ů', + 'ů' => 'ů', + 'Ű' => 'Ű', + 'ű' => 'ű', + 'Ų' => 'Ų', + 'ų' => 'ų', + 'Ŵ' => 'Ŵ', + 'ŵ' => 'ŵ', + 'Ŷ' => 'Ŷ', + 'ŷ' => 'ŷ', + 'Ÿ' => 'Ÿ', + 'Ź' => 'Ź', + 'ź' => 'ź', + 'Ż' => 'Ż', + 'ż' => 'ż', + 'Ž' => 'Ž', + 'ž' => 'ž', + 'Ơ' => 'Ơ', + 'ơ' => 'ơ', + 'Ư' => 'Ư', + 'ư' => 'ư', + 'Ǎ' => 'Ǎ', + 'ǎ' => 'ǎ', + 'Ǐ' => 'Ǐ', + 'ǐ' => 'ǐ', + 'Ǒ' => 'Ǒ', + 'ǒ' => 'ǒ', + 'Ǔ' => 'Ǔ', + 'ǔ' => 'ǔ', + 'Ǖ' => 'Ǖ', + 'ǖ' => 'ǖ', + 'Ǘ' => 'Ǘ', + 'ǘ' => 'ǘ', + 'Ǚ' => 'Ǚ', + 'ǚ' => 'ǚ', + 'Ǜ' => 'Ǜ', + 'ǜ' => 'ǜ', + 'Ǟ' => 'Ǟ', + 'ǟ' => 'ǟ', + 'Ǡ' => 'Ǡ', + 'ǡ' => 'ǡ', + 'Ǣ' => 'Ǣ', + 'ǣ' => 'ǣ', + 'Ǧ' => 'Ǧ', + 'ǧ' => 'ǧ', + 'Ǩ' => 'Ǩ', + 'ǩ' => 'ǩ', + 'Ǫ' => 'Ǫ', + 'ǫ' => 'ǫ', + 'Ǭ' => 'Ǭ', + 'ǭ' => 'ǭ', + 'Ǯ' => 'Ǯ', + 'ǯ' => 'ǯ', + 'ǰ' => 'ǰ', + 'Ǵ' => 'Ǵ', + 'ǵ' => 'ǵ', + 'Ǹ' => 'Ǹ', + 'ǹ' => 'ǹ', + 'Ǻ' => 'Ǻ', + 'ǻ' => 'ǻ', + 'Ǽ' => 'Ǽ', + 'ǽ' => 'ǽ', + 'Ǿ' => 'Ǿ', + 'ǿ' => 'ǿ', + 'Ȁ' => 'Ȁ', + 'ȁ' => 'ȁ', + 'Ȃ' => 'Ȃ', + 'ȃ' => 'ȃ', + 'Ȅ' => 'Ȅ', + 'ȅ' => 'ȅ', + 'Ȇ' => 'Ȇ', + 'ȇ' => 'ȇ', + 'Ȉ' => 'Ȉ', + 'ȉ' => 'ȉ', + 'Ȋ' => 'Ȋ', + 'ȋ' => 'ȋ', + 'Ȍ' => 'Ȍ', + 'ȍ' => 'ȍ', + 'Ȏ' => 'Ȏ', + 'ȏ' => 'ȏ', + 'Ȑ' => 'Ȑ', + 'ȑ' => 'ȑ', + 'Ȓ' => 'Ȓ', + 'ȓ' => 'ȓ', + 'Ȕ' => 'Ȕ', + 'ȕ' => 'ȕ', + 'Ȗ' => 'Ȗ', + 'ȗ' => 'ȗ', + 'Ș' => 'Ș', + 'ș' => 'ș', + 'Ț' => 'Ț', + 'ț' => 'ț', + 'Ȟ' => 'Ȟ', + 'ȟ' => 'ȟ', + 'Ȧ' => 'Ȧ', + 'ȧ' => 'ȧ', + 'Ȩ' => 'Ȩ', + 'ȩ' => 'ȩ', + 'Ȫ' => 'Ȫ', + 'ȫ' => 'ȫ', + 'Ȭ' => 'Ȭ', + 'ȭ' => 'ȭ', + 'Ȯ' => 'Ȯ', + 'ȯ' => 'ȯ', + 'Ȱ' => 'Ȱ', + 'ȱ' => 'ȱ', + 'Ȳ' => 'Ȳ', + 'ȳ' => 'ȳ', + '΅' => '΅', + 'Ά' => 'Ά', + 'Έ' => 'Έ', + 'Ή' => 'Ή', + 'Ί' => 'Ί', + 'Ό' => 'Ό', + 'Ύ' => 'Ύ', + 'Ώ' => 'Ώ', + 'ΐ' => 'ΐ', + 'Ϊ' => 'Ϊ', + 'Ϋ' => 'Ϋ', + 'ά' => 'ά', + 'έ' => 'έ', + 'ή' => 'ή', + 'ί' => 'ί', + 'ΰ' => 'ΰ', + 'ϊ' => 'ϊ', + 'ϋ' => 'ϋ', + 'ό' => 'ό', + 'ύ' => 'ύ', + 'ώ' => 'ώ', + 'ϓ' => 'ϓ', + 'ϔ' => 'ϔ', + 'Ѐ' => 'Ѐ', + 'Ё' => 'Ё', + 'Ѓ' => 'Ѓ', + 'Ї' => 'Ї', + 'Ќ' => 'Ќ', + 'Ѝ' => 'Ѝ', + 'Ў' => 'Ў', + 'Й' => 'Й', + 'й' => 'й', + 'ѐ' => 'ѐ', + 'ё' => 'ё', + 'ѓ' => 'ѓ', + 'ї' => 'ї', + 'ќ' => 'ќ', + 'ѝ' => 'ѝ', + 'ў' => 'ў', + 'Ѷ' => 'Ѷ', + 'ѷ' => 'ѷ', + 'Ӂ' => 'Ӂ', + 'ӂ' => 'ӂ', + 'Ӑ' => 'Ӑ', + 'ӑ' => 'ӑ', + 'Ӓ' => 'Ӓ', + 'ӓ' => 'ӓ', + 'Ӗ' => 'Ӗ', + 'ӗ' => 'ӗ', + 'Ӛ' => 'Ӛ', + 'ӛ' => 'ӛ', + 'Ӝ' => 'Ӝ', + 'ӝ' => 'ӝ', + 'Ӟ' => 'Ӟ', + 'ӟ' => 'ӟ', + 'Ӣ' => 'Ӣ', + 'ӣ' => 'ӣ', + 'Ӥ' => 'Ӥ', + 'ӥ' => 'ӥ', + 'Ӧ' => 'Ӧ', + 'ӧ' => 'ӧ', + 'Ӫ' => 'Ӫ', + 'ӫ' => 'ӫ', + 'Ӭ' => 'Ӭ', + 'ӭ' => 'ӭ', + 'Ӯ' => 'Ӯ', + 'ӯ' => 'ӯ', + 'Ӱ' => 'Ӱ', + 'ӱ' => 'ӱ', + 'Ӳ' => 'Ӳ', + 'ӳ' => 'ӳ', + 'Ӵ' => 'Ӵ', + 'ӵ' => 'ӵ', + 'Ӹ' => 'Ӹ', + 'ӹ' => 'ӹ', + 'آ' => 'آ', + 'أ' => 'أ', + 'ؤ' => 'ؤ', + 'إ' => 'إ', + 'ئ' => 'ئ', + 'ۀ' => 'ۀ', + 'ۂ' => 'ۂ', + 'ۓ' => 'ۓ', + 'ऩ' => 'ऩ', + 'ऱ' => 'ऱ', + 'ऴ' => 'ऴ', + 'ো' => 'ো', + 'ৌ' => 'ৌ', + 'ୈ' => 'ୈ', + 'ୋ' => 'ୋ', + 'ୌ' => 'ୌ', + 'ஔ' => 'ஔ', + 'ொ' => 'ொ', + 'ோ' => 'ோ', + 'ௌ' => 'ௌ', + 'ై' => 'ై', + 'ೀ' => 'ೀ', + 'ೇ' => 'ೇ', + 'ೈ' => 'ೈ', + 'ೊ' => 'ೊ', + 'ೋ' => 'ೋ', + 'ൊ' => 'ൊ', + 'ോ' => 'ോ', + 'ൌ' => 'ൌ', + 'ේ' => 'ේ', + 'ො' => 'ො', + 'ෝ' => 'ෝ', + 'ෞ' => 'ෞ', + 'ဦ' => 'ဦ', + 'ᬆ' => 'ᬆ', + 'ᬈ' => 'ᬈ', + 'ᬊ' => 'ᬊ', + 'ᬌ' => 'ᬌ', + 'ᬎ' => 'ᬎ', + 'ᬒ' => 'ᬒ', + 'ᬻ' => 'ᬻ', + 'ᬽ' => 'ᬽ', + 'ᭀ' => 'ᭀ', + 'ᭁ' => 'ᭁ', + 'ᭃ' => 'ᭃ', + 'Ḁ' => 'Ḁ', + 'ḁ' => 'ḁ', + 'Ḃ' => 'Ḃ', + 'ḃ' => 'ḃ', + 'Ḅ' => 'Ḅ', + 'ḅ' => 'ḅ', + 'Ḇ' => 'Ḇ', + 'ḇ' => 'ḇ', + 'Ḉ' => 'Ḉ', + 'ḉ' => 'ḉ', + 'Ḋ' => 'Ḋ', + 'ḋ' => 'ḋ', + 'Ḍ' => 'Ḍ', + 'ḍ' => 'ḍ', + 'Ḏ' => 'Ḏ', + 'ḏ' => 'ḏ', + 'Ḑ' => 'Ḑ', + 'ḑ' => 'ḑ', + 'Ḓ' => 'Ḓ', + 'ḓ' => 'ḓ', + 'Ḕ' => 'Ḕ', + 'ḕ' => 'ḕ', + 'Ḗ' => 'Ḗ', + 'ḗ' => 'ḗ', + 'Ḙ' => 'Ḙ', + 'ḙ' => 'ḙ', + 'Ḛ' => 'Ḛ', + 'ḛ' => 'ḛ', + 'Ḝ' => 'Ḝ', + 'ḝ' => 'ḝ', + 'Ḟ' => 'Ḟ', + 'ḟ' => 'ḟ', + 'Ḡ' => 'Ḡ', + 'ḡ' => 'ḡ', + 'Ḣ' => 'Ḣ', + 'ḣ' => 'ḣ', + 'Ḥ' => 'Ḥ', + 'ḥ' => 'ḥ', + 'Ḧ' => 'Ḧ', + 'ḧ' => 'ḧ', + 'Ḩ' => 'Ḩ', + 'ḩ' => 'ḩ', + 'Ḫ' => 'Ḫ', + 'ḫ' => 'ḫ', + 'Ḭ' => 'Ḭ', + 'ḭ' => 'ḭ', + 'Ḯ' => 'Ḯ', + 'ḯ' => 'ḯ', + 'Ḱ' => 'Ḱ', + 'ḱ' => 'ḱ', + 'Ḳ' => 'Ḳ', + 'ḳ' => 'ḳ', + 'Ḵ' => 'Ḵ', + 'ḵ' => 'ḵ', + 'Ḷ' => 'Ḷ', + 'ḷ' => 'ḷ', + 'Ḹ' => 'Ḹ', + 'ḹ' => 'ḹ', + 'Ḻ' => 'Ḻ', + 'ḻ' => 'ḻ', + 'Ḽ' => 'Ḽ', + 'ḽ' => 'ḽ', + 'Ḿ' => 'Ḿ', + 'ḿ' => 'ḿ', + 'Ṁ' => 'Ṁ', + 'ṁ' => 'ṁ', + 'Ṃ' => 'Ṃ', + 'ṃ' => 'ṃ', + 'Ṅ' => 'Ṅ', + 'ṅ' => 'ṅ', + 'Ṇ' => 'Ṇ', + 'ṇ' => 'ṇ', + 'Ṉ' => 'Ṉ', + 'ṉ' => 'ṉ', + 'Ṋ' => 'Ṋ', + 'ṋ' => 'ṋ', + 'Ṍ' => 'Ṍ', + 'ṍ' => 'ṍ', + 'Ṏ' => 'Ṏ', + 'ṏ' => 'ṏ', + 'Ṑ' => 'Ṑ', + 'ṑ' => 'ṑ', + 'Ṓ' => 'Ṓ', + 'ṓ' => 'ṓ', + 'Ṕ' => 'Ṕ', + 'ṕ' => 'ṕ', + 'Ṗ' => 'Ṗ', + 'ṗ' => 'ṗ', + 'Ṙ' => 'Ṙ', + 'ṙ' => 'ṙ', + 'Ṛ' => 'Ṛ', + 'ṛ' => 'ṛ', + 'Ṝ' => 'Ṝ', + 'ṝ' => 'ṝ', + 'Ṟ' => 'Ṟ', + 'ṟ' => 'ṟ', + 'Ṡ' => 'Ṡ', + 'ṡ' => 'ṡ', + 'Ṣ' => 'Ṣ', + 'ṣ' => 'ṣ', + 'Ṥ' => 'Ṥ', + 'ṥ' => 'ṥ', + 'Ṧ' => 'Ṧ', + 'ṧ' => 'ṧ', + 'Ṩ' => 'Ṩ', + 'ṩ' => 'ṩ', + 'Ṫ' => 'Ṫ', + 'ṫ' => 'ṫ', + 'Ṭ' => 'Ṭ', + 'ṭ' => 'ṭ', + 'Ṯ' => 'Ṯ', + 'ṯ' => 'ṯ', + 'Ṱ' => 'Ṱ', + 'ṱ' => 'ṱ', + 'Ṳ' => 'Ṳ', + 'ṳ' => 'ṳ', + 'Ṵ' => 'Ṵ', + 'ṵ' => 'ṵ', + 'Ṷ' => 'Ṷ', + 'ṷ' => 'ṷ', + 'Ṹ' => 'Ṹ', + 'ṹ' => 'ṹ', + 'Ṻ' => 'Ṻ', + 'ṻ' => 'ṻ', + 'Ṽ' => 'Ṽ', + 'ṽ' => 'ṽ', + 'Ṿ' => 'Ṿ', + 'ṿ' => 'ṿ', + 'Ẁ' => 'Ẁ', + 'ẁ' => 'ẁ', + 'Ẃ' => 'Ẃ', + 'ẃ' => 'ẃ', + 'Ẅ' => 'Ẅ', + 'ẅ' => 'ẅ', + 'Ẇ' => 'Ẇ', + 'ẇ' => 'ẇ', + 'Ẉ' => 'Ẉ', + 'ẉ' => 'ẉ', + 'Ẋ' => 'Ẋ', + 'ẋ' => 'ẋ', + 'Ẍ' => 'Ẍ', + 'ẍ' => 'ẍ', + 'Ẏ' => 'Ẏ', + 'ẏ' => 'ẏ', + 'Ẑ' => 'Ẑ', + 'ẑ' => 'ẑ', + 'Ẓ' => 'Ẓ', + 'ẓ' => 'ẓ', + 'Ẕ' => 'Ẕ', + 'ẕ' => 'ẕ', + 'ẖ' => 'ẖ', + 'ẗ' => 'ẗ', + 'ẘ' => 'ẘ', + 'ẙ' => 'ẙ', + 'ẛ' => 'ẛ', + 'Ạ' => 'Ạ', + 'ạ' => 'ạ', + 'Ả' => 'Ả', + 'ả' => 'ả', + 'Ấ' => 'Ấ', + 'ấ' => 'ấ', + 'Ầ' => 'Ầ', + 'ầ' => 'ầ', + 'Ẩ' => 'Ẩ', + 'ẩ' => 'ẩ', + 'Ẫ' => 'Ẫ', + 'ẫ' => 'ẫ', + 'Ậ' => 'Ậ', + 'ậ' => 'ậ', + 'Ắ' => 'Ắ', + 'ắ' => 'ắ', + 'Ằ' => 'Ằ', + 'ằ' => 'ằ', + 'Ẳ' => 'Ẳ', + 'ẳ' => 'ẳ', + 'Ẵ' => 'Ẵ', + 'ẵ' => 'ẵ', + 'Ặ' => 'Ặ', + 'ặ' => 'ặ', + 'Ẹ' => 'Ẹ', + 'ẹ' => 'ẹ', + 'Ẻ' => 'Ẻ', + 'ẻ' => 'ẻ', + 'Ẽ' => 'Ẽ', + 'ẽ' => 'ẽ', + 'Ế' => 'Ế', + 'ế' => 'ế', + 'Ề' => 'Ề', + 'ề' => 'ề', + 'Ể' => 'Ể', + 'ể' => 'ể', + 'Ễ' => 'Ễ', + 'ễ' => 'ễ', + 'Ệ' => 'Ệ', + 'ệ' => 'ệ', + 'Ỉ' => 'Ỉ', + 'ỉ' => 'ỉ', + 'Ị' => 'Ị', + 'ị' => 'ị', + 'Ọ' => 'Ọ', + 'ọ' => 'ọ', + 'Ỏ' => 'Ỏ', + 'ỏ' => 'ỏ', + 'Ố' => 'Ố', + 'ố' => 'ố', + 'Ồ' => 'Ồ', + 'ồ' => 'ồ', + 'Ổ' => 'Ổ', + 'ổ' => 'ổ', + 'Ỗ' => 'Ỗ', + 'ỗ' => 'ỗ', + 'Ộ' => 'Ộ', + 'ộ' => 'ộ', + 'Ớ' => 'Ớ', + 'ớ' => 'ớ', + 'Ờ' => 'Ờ', + 'ờ' => 'ờ', + 'Ở' => 'Ở', + 'ở' => 'ở', + 'Ỡ' => 'Ỡ', + 'ỡ' => 'ỡ', + 'Ợ' => 'Ợ', + 'ợ' => 'ợ', + 'Ụ' => 'Ụ', + 'ụ' => 'ụ', + 'Ủ' => 'Ủ', + 'ủ' => 'ủ', + 'Ứ' => 'Ứ', + 'ứ' => 'ứ', + 'Ừ' => 'Ừ', + 'ừ' => 'ừ', + 'Ử' => 'Ử', + 'ử' => 'ử', + 'Ữ' => 'Ữ', + 'ữ' => 'ữ', + 'Ự' => 'Ự', + 'ự' => 'ự', + 'Ỳ' => 'Ỳ', + 'ỳ' => 'ỳ', + 'Ỵ' => 'Ỵ', + 'ỵ' => 'ỵ', + 'Ỷ' => 'Ỷ', + 'ỷ' => 'ỷ', + 'Ỹ' => 'Ỹ', + 'ỹ' => 'ỹ', + 'ἀ' => 'ἀ', + 'ἁ' => 'ἁ', + 'ἂ' => 'ἂ', + 'ἃ' => 'ἃ', + 'ἄ' => 'ἄ', + 'ἅ' => 'ἅ', + 'ἆ' => 'ἆ', + 'ἇ' => 'ἇ', + 'Ἀ' => 'Ἀ', + 'Ἁ' => 'Ἁ', + 'Ἂ' => 'Ἂ', + 'Ἃ' => 'Ἃ', + 'Ἄ' => 'Ἄ', + 'Ἅ' => 'Ἅ', + 'Ἆ' => 'Ἆ', + 'Ἇ' => 'Ἇ', + 'ἐ' => 'ἐ', + 'ἑ' => 'ἑ', + 'ἒ' => 'ἒ', + 'ἓ' => 'ἓ', + 'ἔ' => 'ἔ', + 'ἕ' => 'ἕ', + 'Ἐ' => 'Ἐ', + 'Ἑ' => 'Ἑ', + 'Ἒ' => 'Ἒ', + 'Ἓ' => 'Ἓ', + 'Ἔ' => 'Ἔ', + 'Ἕ' => 'Ἕ', + 'ἠ' => 'ἠ', + 'ἡ' => 'ἡ', + 'ἢ' => 'ἢ', + 'ἣ' => 'ἣ', + 'ἤ' => 'ἤ', + 'ἥ' => 'ἥ', + 'ἦ' => 'ἦ', + 'ἧ' => 'ἧ', + 'Ἠ' => 'Ἠ', + 'Ἡ' => 'Ἡ', + 'Ἢ' => 'Ἢ', + 'Ἣ' => 'Ἣ', + 'Ἤ' => 'Ἤ', + 'Ἥ' => 'Ἥ', + 'Ἦ' => 'Ἦ', + 'Ἧ' => 'Ἧ', + 'ἰ' => 'ἰ', + 'ἱ' => 'ἱ', + 'ἲ' => 'ἲ', + 'ἳ' => 'ἳ', + 'ἴ' => 'ἴ', + 'ἵ' => 'ἵ', + 'ἶ' => 'ἶ', + 'ἷ' => 'ἷ', + 'Ἰ' => 'Ἰ', + 'Ἱ' => 'Ἱ', + 'Ἲ' => 'Ἲ', + 'Ἳ' => 'Ἳ', + 'Ἴ' => 'Ἴ', + 'Ἵ' => 'Ἵ', + 'Ἶ' => 'Ἶ', + 'Ἷ' => 'Ἷ', + 'ὀ' => 'ὀ', + 'ὁ' => 'ὁ', + 'ὂ' => 'ὂ', + 'ὃ' => 'ὃ', + 'ὄ' => 'ὄ', + 'ὅ' => 'ὅ', + 'Ὀ' => 'Ὀ', + 'Ὁ' => 'Ὁ', + 'Ὂ' => 'Ὂ', + 'Ὃ' => 'Ὃ', + 'Ὄ' => 'Ὄ', + 'Ὅ' => 'Ὅ', + 'ὐ' => 'ὐ', + 'ὑ' => 'ὑ', + 'ὒ' => 'ὒ', + 'ὓ' => 'ὓ', + 'ὔ' => 'ὔ', + 'ὕ' => 'ὕ', + 'ὖ' => 'ὖ', + 'ὗ' => 'ὗ', + 'Ὑ' => 'Ὑ', + 'Ὓ' => 'Ὓ', + 'Ὕ' => 'Ὕ', + 'Ὗ' => 'Ὗ', + 'ὠ' => 'ὠ', + 'ὡ' => 'ὡ', + 'ὢ' => 'ὢ', + 'ὣ' => 'ὣ', + 'ὤ' => 'ὤ', + 'ὥ' => 'ὥ', + 'ὦ' => 'ὦ', + 'ὧ' => 'ὧ', + 'Ὠ' => 'Ὠ', + 'Ὡ' => 'Ὡ', + 'Ὢ' => 'Ὢ', + 'Ὣ' => 'Ὣ', + 'Ὤ' => 'Ὤ', + 'Ὥ' => 'Ὥ', + 'Ὦ' => 'Ὦ', + 'Ὧ' => 'Ὧ', + 'ὰ' => 'ὰ', + 'ὲ' => 'ὲ', + 'ὴ' => 'ὴ', + 'ὶ' => 'ὶ', + 'ὸ' => 'ὸ', + 'ὺ' => 'ὺ', + 'ὼ' => 'ὼ', + 'ᾀ' => 'ᾀ', + 'ᾁ' => 'ᾁ', + 'ᾂ' => 'ᾂ', + 'ᾃ' => 'ᾃ', + 'ᾄ' => 'ᾄ', + 'ᾅ' => 'ᾅ', + 'ᾆ' => 'ᾆ', + 'ᾇ' => 'ᾇ', + 'ᾈ' => 'ᾈ', + 'ᾉ' => 'ᾉ', + 'ᾊ' => 'ᾊ', + 'ᾋ' => 'ᾋ', + 'ᾌ' => 'ᾌ', + 'ᾍ' => 'ᾍ', + 'ᾎ' => 'ᾎ', + 'ᾏ' => 'ᾏ', + 'ᾐ' => 'ᾐ', + 'ᾑ' => 'ᾑ', + 'ᾒ' => 'ᾒ', + 'ᾓ' => 'ᾓ', + 'ᾔ' => 'ᾔ', + 'ᾕ' => 'ᾕ', + 'ᾖ' => 'ᾖ', + 'ᾗ' => 'ᾗ', + 'ᾘ' => 'ᾘ', + 'ᾙ' => 'ᾙ', + 'ᾚ' => 'ᾚ', + 'ᾛ' => 'ᾛ', + 'ᾜ' => 'ᾜ', + 'ᾝ' => 'ᾝ', + 'ᾞ' => 'ᾞ', + 'ᾟ' => 'ᾟ', + 'ᾠ' => 'ᾠ', + 'ᾡ' => 'ᾡ', + 'ᾢ' => 'ᾢ', + 'ᾣ' => 'ᾣ', + 'ᾤ' => 'ᾤ', + 'ᾥ' => 'ᾥ', + 'ᾦ' => 'ᾦ', + 'ᾧ' => 'ᾧ', + 'ᾨ' => 'ᾨ', + 'ᾩ' => 'ᾩ', + 'ᾪ' => 'ᾪ', + 'ᾫ' => 'ᾫ', + 'ᾬ' => 'ᾬ', + 'ᾭ' => 'ᾭ', + 'ᾮ' => 'ᾮ', + 'ᾯ' => 'ᾯ', + 'ᾰ' => 'ᾰ', + 'ᾱ' => 'ᾱ', + 'ᾲ' => 'ᾲ', + 'ᾳ' => 'ᾳ', + 'ᾴ' => 'ᾴ', + 'ᾶ' => 'ᾶ', + 'ᾷ' => 'ᾷ', + 'Ᾰ' => 'Ᾰ', + 'Ᾱ' => 'Ᾱ', + 'Ὰ' => 'Ὰ', + 'ᾼ' => 'ᾼ', + '῁' => '῁', + 'ῂ' => 'ῂ', + 'ῃ' => 'ῃ', + 'ῄ' => 'ῄ', + 'ῆ' => 'ῆ', + 'ῇ' => 'ῇ', + 'Ὲ' => 'Ὲ', + 'Ὴ' => 'Ὴ', + 'ῌ' => 'ῌ', + '῍' => '῍', + '῎' => '῎', + '῏' => '῏', + 'ῐ' => 'ῐ', + 'ῑ' => 'ῑ', + 'ῒ' => 'ῒ', + 'ῖ' => 'ῖ', + 'ῗ' => 'ῗ', + 'Ῐ' => 'Ῐ', + 'Ῑ' => 'Ῑ', + 'Ὶ' => 'Ὶ', + '῝' => '῝', + '῞' => '῞', + '῟' => '῟', + 'ῠ' => 'ῠ', + 'ῡ' => 'ῡ', + 'ῢ' => 'ῢ', + 'ῤ' => 'ῤ', + 'ῥ' => 'ῥ', + 'ῦ' => 'ῦ', + 'ῧ' => 'ῧ', + 'Ῠ' => 'Ῠ', + 'Ῡ' => 'Ῡ', + 'Ὺ' => 'Ὺ', + 'Ῥ' => 'Ῥ', + '῭' => '῭', + 'ῲ' => 'ῲ', + 'ῳ' => 'ῳ', + 'ῴ' => 'ῴ', + 'ῶ' => 'ῶ', + 'ῷ' => 'ῷ', + 'Ὸ' => 'Ὸ', + 'Ὼ' => 'Ὼ', + 'ῼ' => 'ῼ', + '↚' => '↚', + '↛' => '↛', + '↮' => '↮', + '⇍' => '⇍', + '⇎' => '⇎', + '⇏' => '⇏', + '∄' => '∄', + '∉' => '∉', + '∌' => '∌', + '∤' => '∤', + '∦' => '∦', + '≁' => '≁', + '≄' => '≄', + '≇' => '≇', + '≉' => '≉', + '≠' => '≠', + '≢' => '≢', + '≭' => '≭', + '≮' => '≮', + '≯' => '≯', + '≰' => '≰', + '≱' => '≱', + '≴' => '≴', + '≵' => '≵', + '≸' => '≸', + '≹' => '≹', + '⊀' => '⊀', + '⊁' => '⊁', + '⊄' => '⊄', + '⊅' => '⊅', + '⊈' => '⊈', + '⊉' => '⊉', + '⊬' => '⊬', + '⊭' => '⊭', + '⊮' => '⊮', + '⊯' => '⊯', + '⋠' => '⋠', + '⋡' => '⋡', + '⋢' => '⋢', + '⋣' => '⋣', + '⋪' => '⋪', + '⋫' => '⋫', + '⋬' => '⋬', + '⋭' => '⋭', + 'が' => 'が', + 'ぎ' => 'ぎ', + 'ぐ' => 'ぐ', + 'げ' => 'げ', + 'ご' => 'ご', + 'ざ' => 'ざ', + 'じ' => 'じ', + 'ず' => 'ず', + 'ぜ' => 'ぜ', + 'ぞ' => 'ぞ', + 'だ' => 'だ', + 'ぢ' => 'ぢ', + 'づ' => 'づ', + 'で' => 'で', + 'ど' => 'ど', + 'ば' => 'ば', + 'ぱ' => 'ぱ', + 'び' => 'び', + 'ぴ' => 'ぴ', + 'ぶ' => 'ぶ', + 'ぷ' => 'ぷ', + 'べ' => 'べ', + 'ぺ' => 'ぺ', + 'ぼ' => 'ぼ', + 'ぽ' => 'ぽ', + 'ゔ' => 'ゔ', + 'ゞ' => 'ゞ', + 'ガ' => 'ガ', + 'ギ' => 'ギ', + 'グ' => 'グ', + 'ゲ' => 'ゲ', + 'ゴ' => 'ゴ', + 'ザ' => 'ザ', + 'ジ' => 'ジ', + 'ズ' => 'ズ', + 'ゼ' => 'ゼ', + 'ゾ' => 'ゾ', + 'ダ' => 'ダ', + 'ヂ' => 'ヂ', + 'ヅ' => 'ヅ', + 'デ' => 'デ', + 'ド' => 'ド', + 'バ' => 'バ', + 'パ' => 'パ', + 'ビ' => 'ビ', + 'ピ' => 'ピ', + 'ブ' => 'ブ', + 'プ' => 'プ', + 'ベ' => 'ベ', + 'ペ' => 'ペ', + 'ボ' => 'ボ', + 'ポ' => 'ポ', + 'ヴ' => 'ヴ', + 'ヷ' => 'ヷ', + 'ヸ' => 'ヸ', + 'ヹ' => 'ヹ', + 'ヺ' => 'ヺ', + 'ヾ' => 'ヾ', + '𑂚' => '𑂚', + '𑂜' => '𑂜', + '𑂫' => '𑂫', + '𑄮' => '𑄮', + '𑄯' => '𑄯', + '𑍋' => '𑍋', + '𑍌' => '𑍌', + '𑒻' => '𑒻', + '𑒼' => '𑒼', + '𑒾' => '𑒾', + '𑖺' => '𑖺', + '𑖻' => '𑖻', + '𑤸' => '𑤸', +); diff --git a/includes/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php b/includes/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php new file mode 100644 index 0000000..5a3e8e0 --- /dev/null +++ b/includes/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php @@ -0,0 +1,2065 @@ + 'À', + 'Á' => 'Á', + 'Â' => 'Â', + 'Ã' => 'Ã', + 'Ä' => 'Ä', + 'Å' => 'Å', + 'Ç' => 'Ç', + 'È' => 'È', + 'É' => 'É', + 'Ê' => 'Ê', + 'Ë' => 'Ë', + 'Ì' => 'Ì', + 'Í' => 'Í', + 'Î' => 'Î', + 'Ï' => 'Ï', + 'Ñ' => 'Ñ', + 'Ò' => 'Ò', + 'Ó' => 'Ó', + 'Ô' => 'Ô', + 'Õ' => 'Õ', + 'Ö' => 'Ö', + 'Ù' => 'Ù', + 'Ú' => 'Ú', + 'Û' => 'Û', + 'Ü' => 'Ü', + 'Ý' => 'Ý', + 'à' => 'à', + 'á' => 'á', + 'â' => 'â', + 'ã' => 'ã', + 'ä' => 'ä', + 'å' => 'å', + 'ç' => 'ç', + 'è' => 'è', + 'é' => 'é', + 'ê' => 'ê', + 'ë' => 'ë', + 'ì' => 'ì', + 'í' => 'í', + 'î' => 'î', + 'ï' => 'ï', + 'ñ' => 'ñ', + 'ò' => 'ò', + 'ó' => 'ó', + 'ô' => 'ô', + 'õ' => 'õ', + 'ö' => 'ö', + 'ù' => 'ù', + 'ú' => 'ú', + 'û' => 'û', + 'ü' => 'ü', + 'ý' => 'ý', + 'ÿ' => 'ÿ', + 'Ā' => 'Ā', + 'ā' => 'ā', + 'Ă' => 'Ă', + 'ă' => 'ă', + 'Ą' => 'Ą', + 'ą' => 'ą', + 'Ć' => 'Ć', + 'ć' => 'ć', + 'Ĉ' => 'Ĉ', + 'ĉ' => 'ĉ', + 'Ċ' => 'Ċ', + 'ċ' => 'ċ', + 'Č' => 'Č', + 'č' => 'č', + 'Ď' => 'Ď', + 'ď' => 'ď', + 'Ē' => 'Ē', + 'ē' => 'ē', + 'Ĕ' => 'Ĕ', + 'ĕ' => 'ĕ', + 'Ė' => 'Ė', + 'ė' => 'ė', + 'Ę' => 'Ę', + 'ę' => 'ę', + 'Ě' => 'Ě', + 'ě' => 'ě', + 'Ĝ' => 'Ĝ', + 'ĝ' => 'ĝ', + 'Ğ' => 'Ğ', + 'ğ' => 'ğ', + 'Ġ' => 'Ġ', + 'ġ' => 'ġ', + 'Ģ' => 'Ģ', + 'ģ' => 'ģ', + 'Ĥ' => 'Ĥ', + 'ĥ' => 'ĥ', + 'Ĩ' => 'Ĩ', + 'ĩ' => 'ĩ', + 'Ī' => 'Ī', + 'ī' => 'ī', + 'Ĭ' => 'Ĭ', + 'ĭ' => 'ĭ', + 'Į' => 'Į', + 'į' => 'į', + 'İ' => 'İ', + 'Ĵ' => 'Ĵ', + 'ĵ' => 'ĵ', + 'Ķ' => 'Ķ', + 'ķ' => 'ķ', + 'Ĺ' => 'Ĺ', + 'ĺ' => 'ĺ', + 'Ļ' => 'Ļ', + 'ļ' => 'ļ', + 'Ľ' => 'Ľ', + 'ľ' => 'ľ', + 'Ń' => 'Ń', + 'ń' => 'ń', + 'Ņ' => 'Ņ', + 'ņ' => 'ņ', + 'Ň' => 'Ň', + 'ň' => 'ň', + 'Ō' => 'Ō', + 'ō' => 'ō', + 'Ŏ' => 'Ŏ', + 'ŏ' => 'ŏ', + 'Ő' => 'Ő', + 'ő' => 'ő', + 'Ŕ' => 'Ŕ', + 'ŕ' => 'ŕ', + 'Ŗ' => 'Ŗ', + 'ŗ' => 'ŗ', + 'Ř' => 'Ř', + 'ř' => 'ř', + 'Ś' => 'Ś', + 'ś' => 'ś', + 'Ŝ' => 'Ŝ', + 'ŝ' => 'ŝ', + 'Ş' => 'Ş', + 'ş' => 'ş', + 'Š' => 'Š', + 'š' => 'š', + 'Ţ' => 'Ţ', + 'ţ' => 'ţ', + 'Ť' => 'Ť', + 'ť' => 'ť', + 'Ũ' => 'Ũ', + 'ũ' => 'ũ', + 'Ū' => 'Ū', + 'ū' => 'ū', + 'Ŭ' => 'Ŭ', + 'ŭ' => 'ŭ', + 'Ů' => 'Ů', + 'ů' => 'ů', + 'Ű' => 'Ű', + 'ű' => 'ű', + 'Ų' => 'Ų', + 'ų' => 'ų', + 'Ŵ' => 'Ŵ', + 'ŵ' => 'ŵ', + 'Ŷ' => 'Ŷ', + 'ŷ' => 'ŷ', + 'Ÿ' => 'Ÿ', + 'Ź' => 'Ź', + 'ź' => 'ź', + 'Ż' => 'Ż', + 'ż' => 'ż', + 'Ž' => 'Ž', + 'ž' => 'ž', + 'Ơ' => 'Ơ', + 'ơ' => 'ơ', + 'Ư' => 'Ư', + 'ư' => 'ư', + 'Ǎ' => 'Ǎ', + 'ǎ' => 'ǎ', + 'Ǐ' => 'Ǐ', + 'ǐ' => 'ǐ', + 'Ǒ' => 'Ǒ', + 'ǒ' => 'ǒ', + 'Ǔ' => 'Ǔ', + 'ǔ' => 'ǔ', + 'Ǖ' => 'Ǖ', + 'ǖ' => 'ǖ', + 'Ǘ' => 'Ǘ', + 'ǘ' => 'ǘ', + 'Ǚ' => 'Ǚ', + 'ǚ' => 'ǚ', + 'Ǜ' => 'Ǜ', + 'ǜ' => 'ǜ', + 'Ǟ' => 'Ǟ', + 'ǟ' => 'ǟ', + 'Ǡ' => 'Ǡ', + 'ǡ' => 'ǡ', + 'Ǣ' => 'Ǣ', + 'ǣ' => 'ǣ', + 'Ǧ' => 'Ǧ', + 'ǧ' => 'ǧ', + 'Ǩ' => 'Ǩ', + 'ǩ' => 'ǩ', + 'Ǫ' => 'Ǫ', + 'ǫ' => 'ǫ', + 'Ǭ' => 'Ǭ', + 'ǭ' => 'ǭ', + 'Ǯ' => 'Ǯ', + 'ǯ' => 'ǯ', + 'ǰ' => 'ǰ', + 'Ǵ' => 'Ǵ', + 'ǵ' => 'ǵ', + 'Ǹ' => 'Ǹ', + 'ǹ' => 'ǹ', + 'Ǻ' => 'Ǻ', + 'ǻ' => 'ǻ', + 'Ǽ' => 'Ǽ', + 'ǽ' => 'ǽ', + 'Ǿ' => 'Ǿ', + 'ǿ' => 'ǿ', + 'Ȁ' => 'Ȁ', + 'ȁ' => 'ȁ', + 'Ȃ' => 'Ȃ', + 'ȃ' => 'ȃ', + 'Ȅ' => 'Ȅ', + 'ȅ' => 'ȅ', + 'Ȇ' => 'Ȇ', + 'ȇ' => 'ȇ', + 'Ȉ' => 'Ȉ', + 'ȉ' => 'ȉ', + 'Ȋ' => 'Ȋ', + 'ȋ' => 'ȋ', + 'Ȍ' => 'Ȍ', + 'ȍ' => 'ȍ', + 'Ȏ' => 'Ȏ', + 'ȏ' => 'ȏ', + 'Ȑ' => 'Ȑ', + 'ȑ' => 'ȑ', + 'Ȓ' => 'Ȓ', + 'ȓ' => 'ȓ', + 'Ȕ' => 'Ȕ', + 'ȕ' => 'ȕ', + 'Ȗ' => 'Ȗ', + 'ȗ' => 'ȗ', + 'Ș' => 'Ș', + 'ș' => 'ș', + 'Ț' => 'Ț', + 'ț' => 'ț', + 'Ȟ' => 'Ȟ', + 'ȟ' => 'ȟ', + 'Ȧ' => 'Ȧ', + 'ȧ' => 'ȧ', + 'Ȩ' => 'Ȩ', + 'ȩ' => 'ȩ', + 'Ȫ' => 'Ȫ', + 'ȫ' => 'ȫ', + 'Ȭ' => 'Ȭ', + 'ȭ' => 'ȭ', + 'Ȯ' => 'Ȯ', + 'ȯ' => 'ȯ', + 'Ȱ' => 'Ȱ', + 'ȱ' => 'ȱ', + 'Ȳ' => 'Ȳ', + 'ȳ' => 'ȳ', + '̀' => '̀', + '́' => '́', + '̓' => '̓', + '̈́' => '̈́', + 'ʹ' => 'ʹ', + ';' => ';', + '΅' => '΅', + 'Ά' => 'Ά', + '·' => '·', + 'Έ' => 'Έ', + 'Ή' => 'Ή', + 'Ί' => 'Ί', + 'Ό' => 'Ό', + 'Ύ' => 'Ύ', + 'Ώ' => 'Ώ', + 'ΐ' => 'ΐ', + 'Ϊ' => 'Ϊ', + 'Ϋ' => 'Ϋ', + 'ά' => 'ά', + 'έ' => 'έ', + 'ή' => 'ή', + 'ί' => 'ί', + 'ΰ' => 'ΰ', + 'ϊ' => 'ϊ', + 'ϋ' => 'ϋ', + 'ό' => 'ό', + 'ύ' => 'ύ', + 'ώ' => 'ώ', + 'ϓ' => 'ϓ', + 'ϔ' => 'ϔ', + 'Ѐ' => 'Ѐ', + 'Ё' => 'Ё', + 'Ѓ' => 'Ѓ', + 'Ї' => 'Ї', + 'Ќ' => 'Ќ', + 'Ѝ' => 'Ѝ', + 'Ў' => 'Ў', + 'Й' => 'Й', + 'й' => 'й', + 'ѐ' => 'ѐ', + 'ё' => 'ё', + 'ѓ' => 'ѓ', + 'ї' => 'ї', + 'ќ' => 'ќ', + 'ѝ' => 'ѝ', + 'ў' => 'ў', + 'Ѷ' => 'Ѷ', + 'ѷ' => 'ѷ', + 'Ӂ' => 'Ӂ', + 'ӂ' => 'ӂ', + 'Ӑ' => 'Ӑ', + 'ӑ' => 'ӑ', + 'Ӓ' => 'Ӓ', + 'ӓ' => 'ӓ', + 'Ӗ' => 'Ӗ', + 'ӗ' => 'ӗ', + 'Ӛ' => 'Ӛ', + 'ӛ' => 'ӛ', + 'Ӝ' => 'Ӝ', + 'ӝ' => 'ӝ', + 'Ӟ' => 'Ӟ', + 'ӟ' => 'ӟ', + 'Ӣ' => 'Ӣ', + 'ӣ' => 'ӣ', + 'Ӥ' => 'Ӥ', + 'ӥ' => 'ӥ', + 'Ӧ' => 'Ӧ', + 'ӧ' => 'ӧ', + 'Ӫ' => 'Ӫ', + 'ӫ' => 'ӫ', + 'Ӭ' => 'Ӭ', + 'ӭ' => 'ӭ', + 'Ӯ' => 'Ӯ', + 'ӯ' => 'ӯ', + 'Ӱ' => 'Ӱ', + 'ӱ' => 'ӱ', + 'Ӳ' => 'Ӳ', + 'ӳ' => 'ӳ', + 'Ӵ' => 'Ӵ', + 'ӵ' => 'ӵ', + 'Ӹ' => 'Ӹ', + 'ӹ' => 'ӹ', + 'آ' => 'آ', + 'أ' => 'أ', + 'ؤ' => 'ؤ', + 'إ' => 'إ', + 'ئ' => 'ئ', + 'ۀ' => 'ۀ', + 'ۂ' => 'ۂ', + 'ۓ' => 'ۓ', + 'ऩ' => 'ऩ', + 'ऱ' => 'ऱ', + 'ऴ' => 'ऴ', + 'क़' => 'क़', + 'ख़' => 'ख़', + 'ग़' => 'ग़', + 'ज़' => 'ज़', + 'ड़' => 'ड़', + 'ढ़' => 'ढ़', + 'फ़' => 'फ़', + 'य़' => 'य़', + 'ো' => 'ো', + 'ৌ' => 'ৌ', + 'ড়' => 'ড়', + 'ঢ়' => 'ঢ়', + 'য়' => 'য়', + 'ਲ਼' => 'ਲ਼', + 'ਸ਼' => 'ਸ਼', + 'ਖ਼' => 'ਖ਼', + 'ਗ਼' => 'ਗ਼', + 'ਜ਼' => 'ਜ਼', + 'ਫ਼' => 'ਫ਼', + 'ୈ' => 'ୈ', + 'ୋ' => 'ୋ', + 'ୌ' => 'ୌ', + 'ଡ଼' => 'ଡ଼', + 'ଢ଼' => 'ଢ଼', + 'ஔ' => 'ஔ', + 'ொ' => 'ொ', + 'ோ' => 'ோ', + 'ௌ' => 'ௌ', + 'ై' => 'ై', + 'ೀ' => 'ೀ', + 'ೇ' => 'ೇ', + 'ೈ' => 'ೈ', + 'ೊ' => 'ೊ', + 'ೋ' => 'ೋ', + 'ൊ' => 'ൊ', + 'ോ' => 'ോ', + 'ൌ' => 'ൌ', + 'ේ' => 'ේ', + 'ො' => 'ො', + 'ෝ' => 'ෝ', + 'ෞ' => 'ෞ', + 'གྷ' => 'གྷ', + 'ཌྷ' => 'ཌྷ', + 'དྷ' => 'དྷ', + 'བྷ' => 'བྷ', + 'ཛྷ' => 'ཛྷ', + 'ཀྵ' => 'ཀྵ', + 'ཱི' => 'ཱི', + 'ཱུ' => 'ཱུ', + 'ྲྀ' => 'ྲྀ', + 'ླྀ' => 'ླྀ', + 'ཱྀ' => 'ཱྀ', + 'ྒྷ' => 'ྒྷ', + 'ྜྷ' => 'ྜྷ', + 'ྡྷ' => 'ྡྷ', + 'ྦྷ' => 'ྦྷ', + 'ྫྷ' => 'ྫྷ', + 'ྐྵ' => 'ྐྵ', + 'ဦ' => 'ဦ', + 'ᬆ' => 'ᬆ', + 'ᬈ' => 'ᬈ', + 'ᬊ' => 'ᬊ', + 'ᬌ' => 'ᬌ', + 'ᬎ' => 'ᬎ', + 'ᬒ' => 'ᬒ', + 'ᬻ' => 'ᬻ', + 'ᬽ' => 'ᬽ', + 'ᭀ' => 'ᭀ', + 'ᭁ' => 'ᭁ', + 'ᭃ' => 'ᭃ', + 'Ḁ' => 'Ḁ', + 'ḁ' => 'ḁ', + 'Ḃ' => 'Ḃ', + 'ḃ' => 'ḃ', + 'Ḅ' => 'Ḅ', + 'ḅ' => 'ḅ', + 'Ḇ' => 'Ḇ', + 'ḇ' => 'ḇ', + 'Ḉ' => 'Ḉ', + 'ḉ' => 'ḉ', + 'Ḋ' => 'Ḋ', + 'ḋ' => 'ḋ', + 'Ḍ' => 'Ḍ', + 'ḍ' => 'ḍ', + 'Ḏ' => 'Ḏ', + 'ḏ' => 'ḏ', + 'Ḑ' => 'Ḑ', + 'ḑ' => 'ḑ', + 'Ḓ' => 'Ḓ', + 'ḓ' => 'ḓ', + 'Ḕ' => 'Ḕ', + 'ḕ' => 'ḕ', + 'Ḗ' => 'Ḗ', + 'ḗ' => 'ḗ', + 'Ḙ' => 'Ḙ', + 'ḙ' => 'ḙ', + 'Ḛ' => 'Ḛ', + 'ḛ' => 'ḛ', + 'Ḝ' => 'Ḝ', + 'ḝ' => 'ḝ', + 'Ḟ' => 'Ḟ', + 'ḟ' => 'ḟ', + 'Ḡ' => 'Ḡ', + 'ḡ' => 'ḡ', + 'Ḣ' => 'Ḣ', + 'ḣ' => 'ḣ', + 'Ḥ' => 'Ḥ', + 'ḥ' => 'ḥ', + 'Ḧ' => 'Ḧ', + 'ḧ' => 'ḧ', + 'Ḩ' => 'Ḩ', + 'ḩ' => 'ḩ', + 'Ḫ' => 'Ḫ', + 'ḫ' => 'ḫ', + 'Ḭ' => 'Ḭ', + 'ḭ' => 'ḭ', + 'Ḯ' => 'Ḯ', + 'ḯ' => 'ḯ', + 'Ḱ' => 'Ḱ', + 'ḱ' => 'ḱ', + 'Ḳ' => 'Ḳ', + 'ḳ' => 'ḳ', + 'Ḵ' => 'Ḵ', + 'ḵ' => 'ḵ', + 'Ḷ' => 'Ḷ', + 'ḷ' => 'ḷ', + 'Ḹ' => 'Ḹ', + 'ḹ' => 'ḹ', + 'Ḻ' => 'Ḻ', + 'ḻ' => 'ḻ', + 'Ḽ' => 'Ḽ', + 'ḽ' => 'ḽ', + 'Ḿ' => 'Ḿ', + 'ḿ' => 'ḿ', + 'Ṁ' => 'Ṁ', + 'ṁ' => 'ṁ', + 'Ṃ' => 'Ṃ', + 'ṃ' => 'ṃ', + 'Ṅ' => 'Ṅ', + 'ṅ' => 'ṅ', + 'Ṇ' => 'Ṇ', + 'ṇ' => 'ṇ', + 'Ṉ' => 'Ṉ', + 'ṉ' => 'ṉ', + 'Ṋ' => 'Ṋ', + 'ṋ' => 'ṋ', + 'Ṍ' => 'Ṍ', + 'ṍ' => 'ṍ', + 'Ṏ' => 'Ṏ', + 'ṏ' => 'ṏ', + 'Ṑ' => 'Ṑ', + 'ṑ' => 'ṑ', + 'Ṓ' => 'Ṓ', + 'ṓ' => 'ṓ', + 'Ṕ' => 'Ṕ', + 'ṕ' => 'ṕ', + 'Ṗ' => 'Ṗ', + 'ṗ' => 'ṗ', + 'Ṙ' => 'Ṙ', + 'ṙ' => 'ṙ', + 'Ṛ' => 'Ṛ', + 'ṛ' => 'ṛ', + 'Ṝ' => 'Ṝ', + 'ṝ' => 'ṝ', + 'Ṟ' => 'Ṟ', + 'ṟ' => 'ṟ', + 'Ṡ' => 'Ṡ', + 'ṡ' => 'ṡ', + 'Ṣ' => 'Ṣ', + 'ṣ' => 'ṣ', + 'Ṥ' => 'Ṥ', + 'ṥ' => 'ṥ', + 'Ṧ' => 'Ṧ', + 'ṧ' => 'ṧ', + 'Ṩ' => 'Ṩ', + 'ṩ' => 'ṩ', + 'Ṫ' => 'Ṫ', + 'ṫ' => 'ṫ', + 'Ṭ' => 'Ṭ', + 'ṭ' => 'ṭ', + 'Ṯ' => 'Ṯ', + 'ṯ' => 'ṯ', + 'Ṱ' => 'Ṱ', + 'ṱ' => 'ṱ', + 'Ṳ' => 'Ṳ', + 'ṳ' => 'ṳ', + 'Ṵ' => 'Ṵ', + 'ṵ' => 'ṵ', + 'Ṷ' => 'Ṷ', + 'ṷ' => 'ṷ', + 'Ṹ' => 'Ṹ', + 'ṹ' => 'ṹ', + 'Ṻ' => 'Ṻ', + 'ṻ' => 'ṻ', + 'Ṽ' => 'Ṽ', + 'ṽ' => 'ṽ', + 'Ṿ' => 'Ṿ', + 'ṿ' => 'ṿ', + 'Ẁ' => 'Ẁ', + 'ẁ' => 'ẁ', + 'Ẃ' => 'Ẃ', + 'ẃ' => 'ẃ', + 'Ẅ' => 'Ẅ', + 'ẅ' => 'ẅ', + 'Ẇ' => 'Ẇ', + 'ẇ' => 'ẇ', + 'Ẉ' => 'Ẉ', + 'ẉ' => 'ẉ', + 'Ẋ' => 'Ẋ', + 'ẋ' => 'ẋ', + 'Ẍ' => 'Ẍ', + 'ẍ' => 'ẍ', + 'Ẏ' => 'Ẏ', + 'ẏ' => 'ẏ', + 'Ẑ' => 'Ẑ', + 'ẑ' => 'ẑ', + 'Ẓ' => 'Ẓ', + 'ẓ' => 'ẓ', + 'Ẕ' => 'Ẕ', + 'ẕ' => 'ẕ', + 'ẖ' => 'ẖ', + 'ẗ' => 'ẗ', + 'ẘ' => 'ẘ', + 'ẙ' => 'ẙ', + 'ẛ' => 'ẛ', + 'Ạ' => 'Ạ', + 'ạ' => 'ạ', + 'Ả' => 'Ả', + 'ả' => 'ả', + 'Ấ' => 'Ấ', + 'ấ' => 'ấ', + 'Ầ' => 'Ầ', + 'ầ' => 'ầ', + 'Ẩ' => 'Ẩ', + 'ẩ' => 'ẩ', + 'Ẫ' => 'Ẫ', + 'ẫ' => 'ẫ', + 'Ậ' => 'Ậ', + 'ậ' => 'ậ', + 'Ắ' => 'Ắ', + 'ắ' => 'ắ', + 'Ằ' => 'Ằ', + 'ằ' => 'ằ', + 'Ẳ' => 'Ẳ', + 'ẳ' => 'ẳ', + 'Ẵ' => 'Ẵ', + 'ẵ' => 'ẵ', + 'Ặ' => 'Ặ', + 'ặ' => 'ặ', + 'Ẹ' => 'Ẹ', + 'ẹ' => 'ẹ', + 'Ẻ' => 'Ẻ', + 'ẻ' => 'ẻ', + 'Ẽ' => 'Ẽ', + 'ẽ' => 'ẽ', + 'Ế' => 'Ế', + 'ế' => 'ế', + 'Ề' => 'Ề', + 'ề' => 'ề', + 'Ể' => 'Ể', + 'ể' => 'ể', + 'Ễ' => 'Ễ', + 'ễ' => 'ễ', + 'Ệ' => 'Ệ', + 'ệ' => 'ệ', + 'Ỉ' => 'Ỉ', + 'ỉ' => 'ỉ', + 'Ị' => 'Ị', + 'ị' => 'ị', + 'Ọ' => 'Ọ', + 'ọ' => 'ọ', + 'Ỏ' => 'Ỏ', + 'ỏ' => 'ỏ', + 'Ố' => 'Ố', + 'ố' => 'ố', + 'Ồ' => 'Ồ', + 'ồ' => 'ồ', + 'Ổ' => 'Ổ', + 'ổ' => 'ổ', + 'Ỗ' => 'Ỗ', + 'ỗ' => 'ỗ', + 'Ộ' => 'Ộ', + 'ộ' => 'ộ', + 'Ớ' => 'Ớ', + 'ớ' => 'ớ', + 'Ờ' => 'Ờ', + 'ờ' => 'ờ', + 'Ở' => 'Ở', + 'ở' => 'ở', + 'Ỡ' => 'Ỡ', + 'ỡ' => 'ỡ', + 'Ợ' => 'Ợ', + 'ợ' => 'ợ', + 'Ụ' => 'Ụ', + 'ụ' => 'ụ', + 'Ủ' => 'Ủ', + 'ủ' => 'ủ', + 'Ứ' => 'Ứ', + 'ứ' => 'ứ', + 'Ừ' => 'Ừ', + 'ừ' => 'ừ', + 'Ử' => 'Ử', + 'ử' => 'ử', + 'Ữ' => 'Ữ', + 'ữ' => 'ữ', + 'Ự' => 'Ự', + 'ự' => 'ự', + 'Ỳ' => 'Ỳ', + 'ỳ' => 'ỳ', + 'Ỵ' => 'Ỵ', + 'ỵ' => 'ỵ', + 'Ỷ' => 'Ỷ', + 'ỷ' => 'ỷ', + 'Ỹ' => 'Ỹ', + 'ỹ' => 'ỹ', + 'ἀ' => 'ἀ', + 'ἁ' => 'ἁ', + 'ἂ' => 'ἂ', + 'ἃ' => 'ἃ', + 'ἄ' => 'ἄ', + 'ἅ' => 'ἅ', + 'ἆ' => 'ἆ', + 'ἇ' => 'ἇ', + 'Ἀ' => 'Ἀ', + 'Ἁ' => 'Ἁ', + 'Ἂ' => 'Ἂ', + 'Ἃ' => 'Ἃ', + 'Ἄ' => 'Ἄ', + 'Ἅ' => 'Ἅ', + 'Ἆ' => 'Ἆ', + 'Ἇ' => 'Ἇ', + 'ἐ' => 'ἐ', + 'ἑ' => 'ἑ', + 'ἒ' => 'ἒ', + 'ἓ' => 'ἓ', + 'ἔ' => 'ἔ', + 'ἕ' => 'ἕ', + 'Ἐ' => 'Ἐ', + 'Ἑ' => 'Ἑ', + 'Ἒ' => 'Ἒ', + 'Ἓ' => 'Ἓ', + 'Ἔ' => 'Ἔ', + 'Ἕ' => 'Ἕ', + 'ἠ' => 'ἠ', + 'ἡ' => 'ἡ', + 'ἢ' => 'ἢ', + 'ἣ' => 'ἣ', + 'ἤ' => 'ἤ', + 'ἥ' => 'ἥ', + 'ἦ' => 'ἦ', + 'ἧ' => 'ἧ', + 'Ἠ' => 'Ἠ', + 'Ἡ' => 'Ἡ', + 'Ἢ' => 'Ἢ', + 'Ἣ' => 'Ἣ', + 'Ἤ' => 'Ἤ', + 'Ἥ' => 'Ἥ', + 'Ἦ' => 'Ἦ', + 'Ἧ' => 'Ἧ', + 'ἰ' => 'ἰ', + 'ἱ' => 'ἱ', + 'ἲ' => 'ἲ', + 'ἳ' => 'ἳ', + 'ἴ' => 'ἴ', + 'ἵ' => 'ἵ', + 'ἶ' => 'ἶ', + 'ἷ' => 'ἷ', + 'Ἰ' => 'Ἰ', + 'Ἱ' => 'Ἱ', + 'Ἲ' => 'Ἲ', + 'Ἳ' => 'Ἳ', + 'Ἴ' => 'Ἴ', + 'Ἵ' => 'Ἵ', + 'Ἶ' => 'Ἶ', + 'Ἷ' => 'Ἷ', + 'ὀ' => 'ὀ', + 'ὁ' => 'ὁ', + 'ὂ' => 'ὂ', + 'ὃ' => 'ὃ', + 'ὄ' => 'ὄ', + 'ὅ' => 'ὅ', + 'Ὀ' => 'Ὀ', + 'Ὁ' => 'Ὁ', + 'Ὂ' => 'Ὂ', + 'Ὃ' => 'Ὃ', + 'Ὄ' => 'Ὄ', + 'Ὅ' => 'Ὅ', + 'ὐ' => 'ὐ', + 'ὑ' => 'ὑ', + 'ὒ' => 'ὒ', + 'ὓ' => 'ὓ', + 'ὔ' => 'ὔ', + 'ὕ' => 'ὕ', + 'ὖ' => 'ὖ', + 'ὗ' => 'ὗ', + 'Ὑ' => 'Ὑ', + 'Ὓ' => 'Ὓ', + 'Ὕ' => 'Ὕ', + 'Ὗ' => 'Ὗ', + 'ὠ' => 'ὠ', + 'ὡ' => 'ὡ', + 'ὢ' => 'ὢ', + 'ὣ' => 'ὣ', + 'ὤ' => 'ὤ', + 'ὥ' => 'ὥ', + 'ὦ' => 'ὦ', + 'ὧ' => 'ὧ', + 'Ὠ' => 'Ὠ', + 'Ὡ' => 'Ὡ', + 'Ὢ' => 'Ὢ', + 'Ὣ' => 'Ὣ', + 'Ὤ' => 'Ὤ', + 'Ὥ' => 'Ὥ', + 'Ὦ' => 'Ὦ', + 'Ὧ' => 'Ὧ', + 'ὰ' => 'ὰ', + 'ά' => 'ά', + 'ὲ' => 'ὲ', + 'έ' => 'έ', + 'ὴ' => 'ὴ', + 'ή' => 'ή', + 'ὶ' => 'ὶ', + 'ί' => 'ί', + 'ὸ' => 'ὸ', + 'ό' => 'ό', + 'ὺ' => 'ὺ', + 'ύ' => 'ύ', + 'ὼ' => 'ὼ', + 'ώ' => 'ώ', + 'ᾀ' => 'ᾀ', + 'ᾁ' => 'ᾁ', + 'ᾂ' => 'ᾂ', + 'ᾃ' => 'ᾃ', + 'ᾄ' => 'ᾄ', + 'ᾅ' => 'ᾅ', + 'ᾆ' => 'ᾆ', + 'ᾇ' => 'ᾇ', + 'ᾈ' => 'ᾈ', + 'ᾉ' => 'ᾉ', + 'ᾊ' => 'ᾊ', + 'ᾋ' => 'ᾋ', + 'ᾌ' => 'ᾌ', + 'ᾍ' => 'ᾍ', + 'ᾎ' => 'ᾎ', + 'ᾏ' => 'ᾏ', + 'ᾐ' => 'ᾐ', + 'ᾑ' => 'ᾑ', + 'ᾒ' => 'ᾒ', + 'ᾓ' => 'ᾓ', + 'ᾔ' => 'ᾔ', + 'ᾕ' => 'ᾕ', + 'ᾖ' => 'ᾖ', + 'ᾗ' => 'ᾗ', + 'ᾘ' => 'ᾘ', + 'ᾙ' => 'ᾙ', + 'ᾚ' => 'ᾚ', + 'ᾛ' => 'ᾛ', + 'ᾜ' => 'ᾜ', + 'ᾝ' => 'ᾝ', + 'ᾞ' => 'ᾞ', + 'ᾟ' => 'ᾟ', + 'ᾠ' => 'ᾠ', + 'ᾡ' => 'ᾡ', + 'ᾢ' => 'ᾢ', + 'ᾣ' => 'ᾣ', + 'ᾤ' => 'ᾤ', + 'ᾥ' => 'ᾥ', + 'ᾦ' => 'ᾦ', + 'ᾧ' => 'ᾧ', + 'ᾨ' => 'ᾨ', + 'ᾩ' => 'ᾩ', + 'ᾪ' => 'ᾪ', + 'ᾫ' => 'ᾫ', + 'ᾬ' => 'ᾬ', + 'ᾭ' => 'ᾭ', + 'ᾮ' => 'ᾮ', + 'ᾯ' => 'ᾯ', + 'ᾰ' => 'ᾰ', + 'ᾱ' => 'ᾱ', + 'ᾲ' => 'ᾲ', + 'ᾳ' => 'ᾳ', + 'ᾴ' => 'ᾴ', + 'ᾶ' => 'ᾶ', + 'ᾷ' => 'ᾷ', + 'Ᾰ' => 'Ᾰ', + 'Ᾱ' => 'Ᾱ', + 'Ὰ' => 'Ὰ', + 'Ά' => 'Ά', + 'ᾼ' => 'ᾼ', + 'ι' => 'ι', + '῁' => '῁', + 'ῂ' => 'ῂ', + 'ῃ' => 'ῃ', + 'ῄ' => 'ῄ', + 'ῆ' => 'ῆ', + 'ῇ' => 'ῇ', + 'Ὲ' => 'Ὲ', + 'Έ' => 'Έ', + 'Ὴ' => 'Ὴ', + 'Ή' => 'Ή', + 'ῌ' => 'ῌ', + '῍' => '῍', + '῎' => '῎', + '῏' => '῏', + 'ῐ' => 'ῐ', + 'ῑ' => 'ῑ', + 'ῒ' => 'ῒ', + 'ΐ' => 'ΐ', + 'ῖ' => 'ῖ', + 'ῗ' => 'ῗ', + 'Ῐ' => 'Ῐ', + 'Ῑ' => 'Ῑ', + 'Ὶ' => 'Ὶ', + 'Ί' => 'Ί', + '῝' => '῝', + '῞' => '῞', + '῟' => '῟', + 'ῠ' => 'ῠ', + 'ῡ' => 'ῡ', + 'ῢ' => 'ῢ', + 'ΰ' => 'ΰ', + 'ῤ' => 'ῤ', + 'ῥ' => 'ῥ', + 'ῦ' => 'ῦ', + 'ῧ' => 'ῧ', + 'Ῠ' => 'Ῠ', + 'Ῡ' => 'Ῡ', + 'Ὺ' => 'Ὺ', + 'Ύ' => 'Ύ', + 'Ῥ' => 'Ῥ', + '῭' => '῭', + '΅' => '΅', + '`' => '`', + 'ῲ' => 'ῲ', + 'ῳ' => 'ῳ', + 'ῴ' => 'ῴ', + 'ῶ' => 'ῶ', + 'ῷ' => 'ῷ', + 'Ὸ' => 'Ὸ', + 'Ό' => 'Ό', + 'Ὼ' => 'Ὼ', + 'Ώ' => 'Ώ', + 'ῼ' => 'ῼ', + '´' => '´', + ' ' => ' ', + ' ' => ' ', + 'Ω' => 'Ω', + 'K' => 'K', + 'Å' => 'Å', + '↚' => '↚', + '↛' => '↛', + '↮' => '↮', + '⇍' => '⇍', + '⇎' => '⇎', + '⇏' => '⇏', + '∄' => '∄', + '∉' => '∉', + '∌' => '∌', + '∤' => '∤', + '∦' => '∦', + '≁' => '≁', + '≄' => '≄', + '≇' => '≇', + '≉' => '≉', + '≠' => '≠', + '≢' => '≢', + '≭' => '≭', + '≮' => '≮', + '≯' => '≯', + '≰' => '≰', + '≱' => '≱', + '≴' => '≴', + '≵' => '≵', + '≸' => '≸', + '≹' => '≹', + '⊀' => '⊀', + '⊁' => '⊁', + '⊄' => '⊄', + '⊅' => '⊅', + '⊈' => '⊈', + '⊉' => '⊉', + '⊬' => '⊬', + '⊭' => '⊭', + '⊮' => '⊮', + '⊯' => '⊯', + '⋠' => '⋠', + '⋡' => '⋡', + '⋢' => '⋢', + '⋣' => '⋣', + '⋪' => '⋪', + '⋫' => '⋫', + '⋬' => '⋬', + '⋭' => '⋭', + '〈' => '〈', + '〉' => '〉', + '⫝̸' => '⫝̸', + 'が' => 'が', + 'ぎ' => 'ぎ', + 'ぐ' => 'ぐ', + 'げ' => 'げ', + 'ご' => 'ご', + 'ざ' => 'ざ', + 'じ' => 'じ', + 'ず' => 'ず', + 'ぜ' => 'ぜ', + 'ぞ' => 'ぞ', + 'だ' => 'だ', + 'ぢ' => 'ぢ', + 'づ' => 'づ', + 'で' => 'で', + 'ど' => 'ど', + 'ば' => 'ば', + 'ぱ' => 'ぱ', + 'び' => 'び', + 'ぴ' => 'ぴ', + 'ぶ' => 'ぶ', + 'ぷ' => 'ぷ', + 'べ' => 'べ', + 'ぺ' => 'ぺ', + 'ぼ' => 'ぼ', + 'ぽ' => 'ぽ', + 'ゔ' => 'ゔ', + 'ゞ' => 'ゞ', + 'ガ' => 'ガ', + 'ギ' => 'ギ', + 'グ' => 'グ', + 'ゲ' => 'ゲ', + 'ゴ' => 'ゴ', + 'ザ' => 'ザ', + 'ジ' => 'ジ', + 'ズ' => 'ズ', + 'ゼ' => 'ゼ', + 'ゾ' => 'ゾ', + 'ダ' => 'ダ', + 'ヂ' => 'ヂ', + 'ヅ' => 'ヅ', + 'デ' => 'デ', + 'ド' => 'ド', + 'バ' => 'バ', + 'パ' => 'パ', + 'ビ' => 'ビ', + 'ピ' => 'ピ', + 'ブ' => 'ブ', + 'プ' => 'プ', + 'ベ' => 'ベ', + 'ペ' => 'ペ', + 'ボ' => 'ボ', + 'ポ' => 'ポ', + 'ヴ' => 'ヴ', + 'ヷ' => 'ヷ', + 'ヸ' => 'ヸ', + 'ヹ' => 'ヹ', + 'ヺ' => 'ヺ', + 'ヾ' => 'ヾ', + '豈' => '豈', + '更' => '更', + '車' => '車', + '賈' => '賈', + '滑' => '滑', + '串' => '串', + '句' => '句', + '龜' => '龜', + '龜' => '龜', + '契' => '契', + '金' => '金', + '喇' => '喇', + '奈' => '奈', + '懶' => '懶', + '癩' => '癩', + '羅' => '羅', + '蘿' => '蘿', + '螺' => '螺', + '裸' => '裸', + '邏' => '邏', + '樂' => '樂', + '洛' => '洛', + '烙' => '烙', + '珞' => '珞', + '落' => '落', + '酪' => '酪', + '駱' => '駱', + '亂' => '亂', + '卵' => '卵', + '欄' => '欄', + '爛' => '爛', + '蘭' => '蘭', + '鸞' => '鸞', + '嵐' => '嵐', + '濫' => '濫', + '藍' => '藍', + '襤' => '襤', + '拉' => '拉', + '臘' => '臘', + '蠟' => '蠟', + '廊' => '廊', + '朗' => '朗', + '浪' => '浪', + '狼' => '狼', + '郎' => '郎', + '來' => '來', + '冷' => '冷', + '勞' => '勞', + '擄' => '擄', + '櫓' => '櫓', + '爐' => '爐', + '盧' => '盧', + '老' => '老', + '蘆' => '蘆', + '虜' => '虜', + '路' => '路', + '露' => '露', + '魯' => '魯', + '鷺' => '鷺', + '碌' => '碌', + '祿' => '祿', + '綠' => '綠', + '菉' => '菉', + '錄' => '錄', + '鹿' => '鹿', + '論' => '論', + '壟' => '壟', + '弄' => '弄', + '籠' => '籠', + '聾' => '聾', + '牢' => '牢', + '磊' => '磊', + '賂' => '賂', + '雷' => '雷', + '壘' => '壘', + '屢' => '屢', + '樓' => '樓', + '淚' => '淚', + '漏' => '漏', + '累' => '累', + '縷' => '縷', + '陋' => '陋', + '勒' => '勒', + '肋' => '肋', + '凜' => '凜', + '凌' => '凌', + '稜' => '稜', + '綾' => '綾', + '菱' => '菱', + '陵' => '陵', + '讀' => '讀', + '拏' => '拏', + '樂' => '樂', + '諾' => '諾', + '丹' => '丹', + '寧' => '寧', + '怒' => '怒', + '率' => '率', + '異' => '異', + '北' => '北', + '磻' => '磻', + '便' => '便', + '復' => '復', + '不' => '不', + '泌' => '泌', + '數' => '數', + '索' => '索', + '參' => '參', + '塞' => '塞', + '省' => '省', + '葉' => '葉', + '說' => '說', + '殺' => '殺', + '辰' => '辰', + '沈' => '沈', + '拾' => '拾', + '若' => '若', + '掠' => '掠', + '略' => '略', + '亮' => '亮', + '兩' => '兩', + '凉' => '凉', + '梁' => '梁', + '糧' => '糧', + '良' => '良', + '諒' => '諒', + '量' => '量', + '勵' => '勵', + '呂' => '呂', + '女' => '女', + '廬' => '廬', + '旅' => '旅', + '濾' => '濾', + '礪' => '礪', + '閭' => '閭', + '驪' => '驪', + '麗' => '麗', + '黎' => '黎', + '力' => '力', + '曆' => '曆', + '歷' => '歷', + '轢' => '轢', + '年' => '年', + '憐' => '憐', + '戀' => '戀', + '撚' => '撚', + '漣' => '漣', + '煉' => '煉', + '璉' => '璉', + '秊' => '秊', + '練' => '練', + '聯' => '聯', + '輦' => '輦', + '蓮' => '蓮', + '連' => '連', + '鍊' => '鍊', + '列' => '列', + '劣' => '劣', + '咽' => '咽', + '烈' => '烈', + '裂' => '裂', + '說' => '說', + '廉' => '廉', + '念' => '念', + '捻' => '捻', + '殮' => '殮', + '簾' => '簾', + '獵' => '獵', + '令' => '令', + '囹' => '囹', + '寧' => '寧', + '嶺' => '嶺', + '怜' => '怜', + '玲' => '玲', + '瑩' => '瑩', + '羚' => '羚', + '聆' => '聆', + '鈴' => '鈴', + '零' => '零', + '靈' => '靈', + '領' => '領', + '例' => '例', + '禮' => '禮', + '醴' => '醴', + '隸' => '隸', + '惡' => '惡', + '了' => '了', + '僚' => '僚', + '寮' => '寮', + '尿' => '尿', + '料' => '料', + '樂' => '樂', + '燎' => '燎', + '療' => '療', + '蓼' => '蓼', + '遼' => '遼', + '龍' => '龍', + '暈' => '暈', + '阮' => '阮', + '劉' => '劉', + '杻' => '杻', + '柳' => '柳', + '流' => '流', + '溜' => '溜', + '琉' => '琉', + '留' => '留', + '硫' => '硫', + '紐' => '紐', + '類' => '類', + '六' => '六', + '戮' => '戮', + '陸' => '陸', + '倫' => '倫', + '崙' => '崙', + '淪' => '淪', + '輪' => '輪', + '律' => '律', + '慄' => '慄', + '栗' => '栗', + '率' => '率', + '隆' => '隆', + '利' => '利', + '吏' => '吏', + '履' => '履', + '易' => '易', + '李' => '李', + '梨' => '梨', + '泥' => '泥', + '理' => '理', + '痢' => '痢', + '罹' => '罹', + '裏' => '裏', + '裡' => '裡', + '里' => '里', + '離' => '離', + '匿' => '匿', + '溺' => '溺', + '吝' => '吝', + '燐' => '燐', + '璘' => '璘', + '藺' => '藺', + '隣' => '隣', + '鱗' => '鱗', + '麟' => '麟', + '林' => '林', + '淋' => '淋', + '臨' => '臨', + '立' => '立', + '笠' => '笠', + '粒' => '粒', + '狀' => '狀', + '炙' => '炙', + '識' => '識', + '什' => '什', + '茶' => '茶', + '刺' => '刺', + '切' => '切', + '度' => '度', + '拓' => '拓', + '糖' => '糖', + '宅' => '宅', + '洞' => '洞', + '暴' => '暴', + '輻' => '輻', + '行' => '行', + '降' => '降', + '見' => '見', + '廓' => '廓', + '兀' => '兀', + '嗀' => '嗀', + '塚' => '塚', + '晴' => '晴', + '凞' => '凞', + '猪' => '猪', + '益' => '益', + '礼' => '礼', + '神' => '神', + '祥' => '祥', + '福' => '福', + '靖' => '靖', + '精' => '精', + '羽' => '羽', + '蘒' => '蘒', + '諸' => '諸', + '逸' => '逸', + '都' => '都', + '飯' => '飯', + '飼' => '飼', + '館' => '館', + '鶴' => '鶴', + '郞' => '郞', + '隷' => '隷', + '侮' => '侮', + '僧' => '僧', + '免' => '免', + '勉' => '勉', + '勤' => '勤', + '卑' => '卑', + '喝' => '喝', + '嘆' => '嘆', + '器' => '器', + '塀' => '塀', + '墨' => '墨', + '層' => '層', + '屮' => '屮', + '悔' => '悔', + '慨' => '慨', + '憎' => '憎', + '懲' => '懲', + '敏' => '敏', + '既' => '既', + '暑' => '暑', + '梅' => '梅', + '海' => '海', + '渚' => '渚', + '漢' => '漢', + '煮' => '煮', + '爫' => '爫', + '琢' => '琢', + '碑' => '碑', + '社' => '社', + '祉' => '祉', + '祈' => '祈', + '祐' => '祐', + '祖' => '祖', + '祝' => '祝', + '禍' => '禍', + '禎' => '禎', + '穀' => '穀', + '突' => '突', + '節' => '節', + '練' => '練', + '縉' => '縉', + '繁' => '繁', + '署' => '署', + '者' => '者', + '臭' => '臭', + '艹' => '艹', + '艹' => '艹', + '著' => '著', + '褐' => '褐', + '視' => '視', + '謁' => '謁', + '謹' => '謹', + '賓' => '賓', + '贈' => '贈', + '辶' => '辶', + '逸' => '逸', + '難' => '難', + '響' => '響', + '頻' => '頻', + '恵' => '恵', + '𤋮' => '𤋮', + '舘' => '舘', + '並' => '並', + '况' => '况', + '全' => '全', + '侀' => '侀', + '充' => '充', + '冀' => '冀', + '勇' => '勇', + '勺' => '勺', + '喝' => '喝', + '啕' => '啕', + '喙' => '喙', + '嗢' => '嗢', + '塚' => '塚', + '墳' => '墳', + '奄' => '奄', + '奔' => '奔', + '婢' => '婢', + '嬨' => '嬨', + '廒' => '廒', + '廙' => '廙', + '彩' => '彩', + '徭' => '徭', + '惘' => '惘', + '慎' => '慎', + '愈' => '愈', + '憎' => '憎', + '慠' => '慠', + '懲' => '懲', + '戴' => '戴', + '揄' => '揄', + '搜' => '搜', + '摒' => '摒', + '敖' => '敖', + '晴' => '晴', + '朗' => '朗', + '望' => '望', + '杖' => '杖', + '歹' => '歹', + '殺' => '殺', + '流' => '流', + '滛' => '滛', + '滋' => '滋', + '漢' => '漢', + '瀞' => '瀞', + '煮' => '煮', + '瞧' => '瞧', + '爵' => '爵', + '犯' => '犯', + '猪' => '猪', + '瑱' => '瑱', + '甆' => '甆', + '画' => '画', + '瘝' => '瘝', + '瘟' => '瘟', + '益' => '益', + '盛' => '盛', + '直' => '直', + '睊' => '睊', + '着' => '着', + '磌' => '磌', + '窱' => '窱', + '節' => '節', + '类' => '类', + '絛' => '絛', + '練' => '練', + '缾' => '缾', + '者' => '者', + '荒' => '荒', + '華' => '華', + '蝹' => '蝹', + '襁' => '襁', + '覆' => '覆', + '視' => '視', + '調' => '調', + '諸' => '諸', + '請' => '請', + '謁' => '謁', + '諾' => '諾', + '諭' => '諭', + '謹' => '謹', + '變' => '變', + '贈' => '贈', + '輸' => '輸', + '遲' => '遲', + '醙' => '醙', + '鉶' => '鉶', + '陼' => '陼', + '難' => '難', + '靖' => '靖', + '韛' => '韛', + '響' => '響', + '頋' => '頋', + '頻' => '頻', + '鬒' => '鬒', + '龜' => '龜', + '𢡊' => '𢡊', + '𢡄' => '𢡄', + '𣏕' => '𣏕', + '㮝' => '㮝', + '䀘' => '䀘', + '䀹' => '䀹', + '𥉉' => '𥉉', + '𥳐' => '𥳐', + '𧻓' => '𧻓', + '齃' => '齃', + '龎' => '龎', + 'יִ' => 'יִ', + 'ײַ' => 'ײַ', + 'שׁ' => 'שׁ', + 'שׂ' => 'שׂ', + 'שּׁ' => 'שּׁ', + 'שּׂ' => 'שּׂ', + 'אַ' => 'אַ', + 'אָ' => 'אָ', + 'אּ' => 'אּ', + 'בּ' => 'בּ', + 'גּ' => 'גּ', + 'דּ' => 'דּ', + 'הּ' => 'הּ', + 'וּ' => 'וּ', + 'זּ' => 'זּ', + 'טּ' => 'טּ', + 'יּ' => 'יּ', + 'ךּ' => 'ךּ', + 'כּ' => 'כּ', + 'לּ' => 'לּ', + 'מּ' => 'מּ', + 'נּ' => 'נּ', + 'סּ' => 'סּ', + 'ףּ' => 'ףּ', + 'פּ' => 'פּ', + 'צּ' => 'צּ', + 'קּ' => 'קּ', + 'רּ' => 'רּ', + 'שּ' => 'שּ', + 'תּ' => 'תּ', + 'וֹ' => 'וֹ', + 'בֿ' => 'בֿ', + 'כֿ' => 'כֿ', + 'פֿ' => 'פֿ', + '𑂚' => '𑂚', + '𑂜' => '𑂜', + '𑂫' => '𑂫', + '𑄮' => '𑄮', + '𑄯' => '𑄯', + '𑍋' => '𑍋', + '𑍌' => '𑍌', + '𑒻' => '𑒻', + '𑒼' => '𑒼', + '𑒾' => '𑒾', + '𑖺' => '𑖺', + '𑖻' => '𑖻', + '𑤸' => '𑤸', + '𝅗𝅥' => '𝅗𝅥', + '𝅘𝅥' => '𝅘𝅥', + '𝅘𝅥𝅮' => '𝅘𝅥𝅮', + '𝅘𝅥𝅯' => '𝅘𝅥𝅯', + '𝅘𝅥𝅰' => '𝅘𝅥𝅰', + '𝅘𝅥𝅱' => '𝅘𝅥𝅱', + '𝅘𝅥𝅲' => '𝅘𝅥𝅲', + '𝆹𝅥' => '𝆹𝅥', + '𝆺𝅥' => '𝆺𝅥', + '𝆹𝅥𝅮' => '𝆹𝅥𝅮', + '𝆺𝅥𝅮' => '𝆺𝅥𝅮', + '𝆹𝅥𝅯' => '𝆹𝅥𝅯', + '𝆺𝅥𝅯' => '𝆺𝅥𝅯', + '丽' => '丽', + '丸' => '丸', + '乁' => '乁', + '𠄢' => '𠄢', + '你' => '你', + '侮' => '侮', + '侻' => '侻', + '倂' => '倂', + '偺' => '偺', + '備' => '備', + '僧' => '僧', + '像' => '像', + '㒞' => '㒞', + '𠘺' => '𠘺', + '免' => '免', + '兔' => '兔', + '兤' => '兤', + '具' => '具', + '𠔜' => '𠔜', + '㒹' => '㒹', + '內' => '內', + '再' => '再', + '𠕋' => '𠕋', + '冗' => '冗', + '冤' => '冤', + '仌' => '仌', + '冬' => '冬', + '况' => '况', + '𩇟' => '𩇟', + '凵' => '凵', + '刃' => '刃', + '㓟' => '㓟', + '刻' => '刻', + '剆' => '剆', + '割' => '割', + '剷' => '剷', + '㔕' => '㔕', + '勇' => '勇', + '勉' => '勉', + '勤' => '勤', + '勺' => '勺', + '包' => '包', + '匆' => '匆', + '北' => '北', + '卉' => '卉', + '卑' => '卑', + '博' => '博', + '即' => '即', + '卽' => '卽', + '卿' => '卿', + '卿' => '卿', + '卿' => '卿', + '𠨬' => '𠨬', + '灰' => '灰', + '及' => '及', + '叟' => '叟', + '𠭣' => '𠭣', + '叫' => '叫', + '叱' => '叱', + '吆' => '吆', + '咞' => '咞', + '吸' => '吸', + '呈' => '呈', + '周' => '周', + '咢' => '咢', + '哶' => '哶', + '唐' => '唐', + '啓' => '啓', + '啣' => '啣', + '善' => '善', + '善' => '善', + '喙' => '喙', + '喫' => '喫', + '喳' => '喳', + '嗂' => '嗂', + '圖' => '圖', + '嘆' => '嘆', + '圗' => '圗', + '噑' => '噑', + '噴' => '噴', + '切' => '切', + '壮' => '壮', + '城' => '城', + '埴' => '埴', + '堍' => '堍', + '型' => '型', + '堲' => '堲', + '報' => '報', + '墬' => '墬', + '𡓤' => '𡓤', + '売' => '売', + '壷' => '壷', + '夆' => '夆', + '多' => '多', + '夢' => '夢', + '奢' => '奢', + '𡚨' => '𡚨', + '𡛪' => '𡛪', + '姬' => '姬', + '娛' => '娛', + '娧' => '娧', + '姘' => '姘', + '婦' => '婦', + '㛮' => '㛮', + '㛼' => '㛼', + '嬈' => '嬈', + '嬾' => '嬾', + '嬾' => '嬾', + '𡧈' => '𡧈', + '寃' => '寃', + '寘' => '寘', + '寧' => '寧', + '寳' => '寳', + '𡬘' => '𡬘', + '寿' => '寿', + '将' => '将', + '当' => '当', + '尢' => '尢', + '㞁' => '㞁', + '屠' => '屠', + '屮' => '屮', + '峀' => '峀', + '岍' => '岍', + '𡷤' => '𡷤', + '嵃' => '嵃', + '𡷦' => '𡷦', + '嵮' => '嵮', + '嵫' => '嵫', + '嵼' => '嵼', + '巡' => '巡', + '巢' => '巢', + '㠯' => '㠯', + '巽' => '巽', + '帨' => '帨', + '帽' => '帽', + '幩' => '幩', + '㡢' => '㡢', + '𢆃' => '𢆃', + '㡼' => '㡼', + '庰' => '庰', + '庳' => '庳', + '庶' => '庶', + '廊' => '廊', + '𪎒' => '𪎒', + '廾' => '廾', + '𢌱' => '𢌱', + '𢌱' => '𢌱', + '舁' => '舁', + '弢' => '弢', + '弢' => '弢', + '㣇' => '㣇', + '𣊸' => '𣊸', + '𦇚' => '𦇚', + '形' => '形', + '彫' => '彫', + '㣣' => '㣣', + '徚' => '徚', + '忍' => '忍', + '志' => '志', + '忹' => '忹', + '悁' => '悁', + '㤺' => '㤺', + '㤜' => '㤜', + '悔' => '悔', + '𢛔' => '𢛔', + '惇' => '惇', + '慈' => '慈', + '慌' => '慌', + '慎' => '慎', + '慌' => '慌', + '慺' => '慺', + '憎' => '憎', + '憲' => '憲', + '憤' => '憤', + '憯' => '憯', + '懞' => '懞', + '懲' => '懲', + '懶' => '懶', + '成' => '成', + '戛' => '戛', + '扝' => '扝', + '抱' => '抱', + '拔' => '拔', + '捐' => '捐', + '𢬌' => '𢬌', + '挽' => '挽', + '拼' => '拼', + '捨' => '捨', + '掃' => '掃', + '揤' => '揤', + '𢯱' => '𢯱', + '搢' => '搢', + '揅' => '揅', + '掩' => '掩', + '㨮' => '㨮', + '摩' => '摩', + '摾' => '摾', + '撝' => '撝', + '摷' => '摷', + '㩬' => '㩬', + '敏' => '敏', + '敬' => '敬', + '𣀊' => '𣀊', + '旣' => '旣', + '書' => '書', + '晉' => '晉', + '㬙' => '㬙', + '暑' => '暑', + '㬈' => '㬈', + '㫤' => '㫤', + '冒' => '冒', + '冕' => '冕', + '最' => '最', + '暜' => '暜', + '肭' => '肭', + '䏙' => '䏙', + '朗' => '朗', + '望' => '望', + '朡' => '朡', + '杞' => '杞', + '杓' => '杓', + '𣏃' => '𣏃', + '㭉' => '㭉', + '柺' => '柺', + '枅' => '枅', + '桒' => '桒', + '梅' => '梅', + '𣑭' => '𣑭', + '梎' => '梎', + '栟' => '栟', + '椔' => '椔', + '㮝' => '㮝', + '楂' => '楂', + '榣' => '榣', + '槪' => '槪', + '檨' => '檨', + '𣚣' => '𣚣', + '櫛' => '櫛', + '㰘' => '㰘', + '次' => '次', + '𣢧' => '𣢧', + '歔' => '歔', + '㱎' => '㱎', + '歲' => '歲', + '殟' => '殟', + '殺' => '殺', + '殻' => '殻', + '𣪍' => '𣪍', + '𡴋' => '𡴋', + '𣫺' => '𣫺', + '汎' => '汎', + '𣲼' => '𣲼', + '沿' => '沿', + '泍' => '泍', + '汧' => '汧', + '洖' => '洖', + '派' => '派', + '海' => '海', + '流' => '流', + '浩' => '浩', + '浸' => '浸', + '涅' => '涅', + '𣴞' => '𣴞', + '洴' => '洴', + '港' => '港', + '湮' => '湮', + '㴳' => '㴳', + '滋' => '滋', + '滇' => '滇', + '𣻑' => '𣻑', + '淹' => '淹', + '潮' => '潮', + '𣽞' => '𣽞', + '𣾎' => '𣾎', + '濆' => '濆', + '瀹' => '瀹', + '瀞' => '瀞', + '瀛' => '瀛', + '㶖' => '㶖', + '灊' => '灊', + '災' => '災', + '灷' => '灷', + '炭' => '炭', + '𠔥' => '𠔥', + '煅' => '煅', + '𤉣' => '𤉣', + '熜' => '熜', + '𤎫' => '𤎫', + '爨' => '爨', + '爵' => '爵', + '牐' => '牐', + '𤘈' => '𤘈', + '犀' => '犀', + '犕' => '犕', + '𤜵' => '𤜵', + '𤠔' => '𤠔', + '獺' => '獺', + '王' => '王', + '㺬' => '㺬', + '玥' => '玥', + '㺸' => '㺸', + '㺸' => '㺸', + '瑇' => '瑇', + '瑜' => '瑜', + '瑱' => '瑱', + '璅' => '璅', + '瓊' => '瓊', + '㼛' => '㼛', + '甤' => '甤', + '𤰶' => '𤰶', + '甾' => '甾', + '𤲒' => '𤲒', + '異' => '異', + '𢆟' => '𢆟', + '瘐' => '瘐', + '𤾡' => '𤾡', + '𤾸' => '𤾸', + '𥁄' => '𥁄', + '㿼' => '㿼', + '䀈' => '䀈', + '直' => '直', + '𥃳' => '𥃳', + '𥃲' => '𥃲', + '𥄙' => '𥄙', + '𥄳' => '𥄳', + '眞' => '眞', + '真' => '真', + '真' => '真', + '睊' => '睊', + '䀹' => '䀹', + '瞋' => '瞋', + '䁆' => '䁆', + '䂖' => '䂖', + '𥐝' => '𥐝', + '硎' => '硎', + '碌' => '碌', + '磌' => '磌', + '䃣' => '䃣', + '𥘦' => '𥘦', + '祖' => '祖', + '𥚚' => '𥚚', + '𥛅' => '𥛅', + '福' => '福', + '秫' => '秫', + '䄯' => '䄯', + '穀' => '穀', + '穊' => '穊', + '穏' => '穏', + '𥥼' => '𥥼', + '𥪧' => '𥪧', + '𥪧' => '𥪧', + '竮' => '竮', + '䈂' => '䈂', + '𥮫' => '𥮫', + '篆' => '篆', + '築' => '築', + '䈧' => '䈧', + '𥲀' => '𥲀', + '糒' => '糒', + '䊠' => '䊠', + '糨' => '糨', + '糣' => '糣', + '紀' => '紀', + '𥾆' => '𥾆', + '絣' => '絣', + '䌁' => '䌁', + '緇' => '緇', + '縂' => '縂', + '繅' => '繅', + '䌴' => '䌴', + '𦈨' => '𦈨', + '𦉇' => '𦉇', + '䍙' => '䍙', + '𦋙' => '𦋙', + '罺' => '罺', + '𦌾' => '𦌾', + '羕' => '羕', + '翺' => '翺', + '者' => '者', + '𦓚' => '𦓚', + '𦔣' => '𦔣', + '聠' => '聠', + '𦖨' => '𦖨', + '聰' => '聰', + '𣍟' => '𣍟', + '䏕' => '䏕', + '育' => '育', + '脃' => '脃', + '䐋' => '䐋', + '脾' => '脾', + '媵' => '媵', + '𦞧' => '𦞧', + '𦞵' => '𦞵', + '𣎓' => '𣎓', + '𣎜' => '𣎜', + '舁' => '舁', + '舄' => '舄', + '辞' => '辞', + '䑫' => '䑫', + '芑' => '芑', + '芋' => '芋', + '芝' => '芝', + '劳' => '劳', + '花' => '花', + '芳' => '芳', + '芽' => '芽', + '苦' => '苦', + '𦬼' => '𦬼', + '若' => '若', + '茝' => '茝', + '荣' => '荣', + '莭' => '莭', + '茣' => '茣', + '莽' => '莽', + '菧' => '菧', + '著' => '著', + '荓' => '荓', + '菊' => '菊', + '菌' => '菌', + '菜' => '菜', + '𦰶' => '𦰶', + '𦵫' => '𦵫', + '𦳕' => '𦳕', + '䔫' => '䔫', + '蓱' => '蓱', + '蓳' => '蓳', + '蔖' => '蔖', + '𧏊' => '𧏊', + '蕤' => '蕤', + '𦼬' => '𦼬', + '䕝' => '䕝', + '䕡' => '䕡', + '𦾱' => '𦾱', + '𧃒' => '𧃒', + '䕫' => '䕫', + '虐' => '虐', + '虜' => '虜', + '虧' => '虧', + '虩' => '虩', + '蚩' => '蚩', + '蚈' => '蚈', + '蜎' => '蜎', + '蛢' => '蛢', + '蝹' => '蝹', + '蜨' => '蜨', + '蝫' => '蝫', + '螆' => '螆', + '䗗' => '䗗', + '蟡' => '蟡', + '蠁' => '蠁', + '䗹' => '䗹', + '衠' => '衠', + '衣' => '衣', + '𧙧' => '𧙧', + '裗' => '裗', + '裞' => '裞', + '䘵' => '䘵', + '裺' => '裺', + '㒻' => '㒻', + '𧢮' => '𧢮', + '𧥦' => '𧥦', + '䚾' => '䚾', + '䛇' => '䛇', + '誠' => '誠', + '諭' => '諭', + '變' => '變', + '豕' => '豕', + '𧲨' => '𧲨', + '貫' => '貫', + '賁' => '賁', + '贛' => '贛', + '起' => '起', + '𧼯' => '𧼯', + '𠠄' => '𠠄', + '跋' => '跋', + '趼' => '趼', + '跰' => '跰', + '𠣞' => '𠣞', + '軔' => '軔', + '輸' => '輸', + '𨗒' => '𨗒', + '𨗭' => '𨗭', + '邔' => '邔', + '郱' => '郱', + '鄑' => '鄑', + '𨜮' => '𨜮', + '鄛' => '鄛', + '鈸' => '鈸', + '鋗' => '鋗', + '鋘' => '鋘', + '鉼' => '鉼', + '鏹' => '鏹', + '鐕' => '鐕', + '𨯺' => '𨯺', + '開' => '開', + '䦕' => '䦕', + '閷' => '閷', + '𨵷' => '𨵷', + '䧦' => '䧦', + '雃' => '雃', + '嶲' => '嶲', + '霣' => '霣', + '𩅅' => '𩅅', + '𩈚' => '𩈚', + '䩮' => '䩮', + '䩶' => '䩶', + '韠' => '韠', + '𩐊' => '𩐊', + '䪲' => '䪲', + '𩒖' => '𩒖', + '頋' => '頋', + '頋' => '頋', + '頩' => '頩', + '𩖶' => '𩖶', + '飢' => '飢', + '䬳' => '䬳', + '餩' => '餩', + '馧' => '馧', + '駂' => '駂', + '駾' => '駾', + '䯎' => '䯎', + '𩬰' => '𩬰', + '鬒' => '鬒', + '鱀' => '鱀', + '鳽' => '鳽', + '䳎' => '䳎', + '䳭' => '䳭', + '鵧' => '鵧', + '𪃎' => '𪃎', + '䳸' => '䳸', + '𪄅' => '𪄅', + '𪈎' => '𪈎', + '𪊑' => '𪊑', + '麻' => '麻', + '䵖' => '䵖', + '黹' => '黹', + '黾' => '黾', + '鼅' => '鼅', + '鼏' => '鼏', + '鼖' => '鼖', + '鼻' => '鼻', + '𪘀' => '𪘀', +); diff --git a/includes/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php b/includes/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php new file mode 100644 index 0000000..ec90f36 --- /dev/null +++ b/includes/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php @@ -0,0 +1,876 @@ + 230, + '́' => 230, + '̂' => 230, + '̃' => 230, + '̄' => 230, + '̅' => 230, + '̆' => 230, + '̇' => 230, + '̈' => 230, + '̉' => 230, + '̊' => 230, + '̋' => 230, + '̌' => 230, + '̍' => 230, + '̎' => 230, + '̏' => 230, + '̐' => 230, + '̑' => 230, + '̒' => 230, + '̓' => 230, + '̔' => 230, + '̕' => 232, + '̖' => 220, + '̗' => 220, + '̘' => 220, + '̙' => 220, + '̚' => 232, + '̛' => 216, + '̜' => 220, + '̝' => 220, + '̞' => 220, + '̟' => 220, + '̠' => 220, + '̡' => 202, + '̢' => 202, + '̣' => 220, + '̤' => 220, + '̥' => 220, + '̦' => 220, + '̧' => 202, + '̨' => 202, + '̩' => 220, + '̪' => 220, + '̫' => 220, + '̬' => 220, + '̭' => 220, + '̮' => 220, + '̯' => 220, + '̰' => 220, + '̱' => 220, + '̲' => 220, + '̳' => 220, + '̴' => 1, + '̵' => 1, + '̶' => 1, + '̷' => 1, + '̸' => 1, + '̹' => 220, + '̺' => 220, + '̻' => 220, + '̼' => 220, + '̽' => 230, + '̾' => 230, + '̿' => 230, + '̀' => 230, + '́' => 230, + '͂' => 230, + '̓' => 230, + '̈́' => 230, + 'ͅ' => 240, + '͆' => 230, + '͇' => 220, + '͈' => 220, + '͉' => 220, + '͊' => 230, + '͋' => 230, + '͌' => 230, + '͍' => 220, + '͎' => 220, + '͐' => 230, + '͑' => 230, + '͒' => 230, + '͓' => 220, + '͔' => 220, + '͕' => 220, + '͖' => 220, + '͗' => 230, + '͘' => 232, + '͙' => 220, + '͚' => 220, + '͛' => 230, + '͜' => 233, + '͝' => 234, + '͞' => 234, + '͟' => 233, + '͠' => 234, + '͡' => 234, + '͢' => 233, + 'ͣ' => 230, + 'ͤ' => 230, + 'ͥ' => 230, + 'ͦ' => 230, + 'ͧ' => 230, + 'ͨ' => 230, + 'ͩ' => 230, + 'ͪ' => 230, + 'ͫ' => 230, + 'ͬ' => 230, + 'ͭ' => 230, + 'ͮ' => 230, + 'ͯ' => 230, + '҃' => 230, + '҄' => 230, + '҅' => 230, + '҆' => 230, + '҇' => 230, + '֑' => 220, + '֒' => 230, + '֓' => 230, + '֔' => 230, + '֕' => 230, + '֖' => 220, + '֗' => 230, + '֘' => 230, + '֙' => 230, + '֚' => 222, + '֛' => 220, + '֜' => 230, + '֝' => 230, + '֞' => 230, + '֟' => 230, + '֠' => 230, + '֡' => 230, + '֢' => 220, + '֣' => 220, + '֤' => 220, + '֥' => 220, + '֦' => 220, + '֧' => 220, + '֨' => 230, + '֩' => 230, + '֪' => 220, + '֫' => 230, + '֬' => 230, + '֭' => 222, + '֮' => 228, + '֯' => 230, + 'ְ' => 10, + 'ֱ' => 11, + 'ֲ' => 12, + 'ֳ' => 13, + 'ִ' => 14, + 'ֵ' => 15, + 'ֶ' => 16, + 'ַ' => 17, + 'ָ' => 18, + 'ֹ' => 19, + 'ֺ' => 19, + 'ֻ' => 20, + 'ּ' => 21, + 'ֽ' => 22, + 'ֿ' => 23, + 'ׁ' => 24, + 'ׂ' => 25, + 'ׄ' => 230, + 'ׅ' => 220, + 'ׇ' => 18, + 'ؐ' => 230, + 'ؑ' => 230, + 'ؒ' => 230, + 'ؓ' => 230, + 'ؔ' => 230, + 'ؕ' => 230, + 'ؖ' => 230, + 'ؗ' => 230, + 'ؘ' => 30, + 'ؙ' => 31, + 'ؚ' => 32, + 'ً' => 27, + 'ٌ' => 28, + 'ٍ' => 29, + 'َ' => 30, + 'ُ' => 31, + 'ِ' => 32, + 'ّ' => 33, + 'ْ' => 34, + 'ٓ' => 230, + 'ٔ' => 230, + 'ٕ' => 220, + 'ٖ' => 220, + 'ٗ' => 230, + '٘' => 230, + 'ٙ' => 230, + 'ٚ' => 230, + 'ٛ' => 230, + 'ٜ' => 220, + 'ٝ' => 230, + 'ٞ' => 230, + 'ٟ' => 220, + 'ٰ' => 35, + 'ۖ' => 230, + 'ۗ' => 230, + 'ۘ' => 230, + 'ۙ' => 230, + 'ۚ' => 230, + 'ۛ' => 230, + 'ۜ' => 230, + '۟' => 230, + '۠' => 230, + 'ۡ' => 230, + 'ۢ' => 230, + 'ۣ' => 220, + 'ۤ' => 230, + 'ۧ' => 230, + 'ۨ' => 230, + '۪' => 220, + '۫' => 230, + '۬' => 230, + 'ۭ' => 220, + 'ܑ' => 36, + 'ܰ' => 230, + 'ܱ' => 220, + 'ܲ' => 230, + 'ܳ' => 230, + 'ܴ' => 220, + 'ܵ' => 230, + 'ܶ' => 230, + 'ܷ' => 220, + 'ܸ' => 220, + 'ܹ' => 220, + 'ܺ' => 230, + 'ܻ' => 220, + 'ܼ' => 220, + 'ܽ' => 230, + 'ܾ' => 220, + 'ܿ' => 230, + '݀' => 230, + '݁' => 230, + '݂' => 220, + '݃' => 230, + '݄' => 220, + '݅' => 230, + '݆' => 220, + '݇' => 230, + '݈' => 220, + '݉' => 230, + '݊' => 230, + '߫' => 230, + '߬' => 230, + '߭' => 230, + '߮' => 230, + '߯' => 230, + '߰' => 230, + '߱' => 230, + '߲' => 220, + '߳' => 230, + '߽' => 220, + 'ࠖ' => 230, + 'ࠗ' => 230, + '࠘' => 230, + '࠙' => 230, + 'ࠛ' => 230, + 'ࠜ' => 230, + 'ࠝ' => 230, + 'ࠞ' => 230, + 'ࠟ' => 230, + 'ࠠ' => 230, + 'ࠡ' => 230, + 'ࠢ' => 230, + 'ࠣ' => 230, + 'ࠥ' => 230, + 'ࠦ' => 230, + 'ࠧ' => 230, + 'ࠩ' => 230, + 'ࠪ' => 230, + 'ࠫ' => 230, + 'ࠬ' => 230, + '࠭' => 230, + '࡙' => 220, + '࡚' => 220, + '࡛' => 220, + '࣓' => 220, + 'ࣔ' => 230, + 'ࣕ' => 230, + 'ࣖ' => 230, + 'ࣗ' => 230, + 'ࣘ' => 230, + 'ࣙ' => 230, + 'ࣚ' => 230, + 'ࣛ' => 230, + 'ࣜ' => 230, + 'ࣝ' => 230, + 'ࣞ' => 230, + 'ࣟ' => 230, + '࣠' => 230, + '࣡' => 230, + 'ࣣ' => 220, + 'ࣤ' => 230, + 'ࣥ' => 230, + 'ࣦ' => 220, + 'ࣧ' => 230, + 'ࣨ' => 230, + 'ࣩ' => 220, + '࣪' => 230, + '࣫' => 230, + '࣬' => 230, + '࣭' => 220, + '࣮' => 220, + '࣯' => 220, + 'ࣰ' => 27, + 'ࣱ' => 28, + 'ࣲ' => 29, + 'ࣳ' => 230, + 'ࣴ' => 230, + 'ࣵ' => 230, + 'ࣶ' => 220, + 'ࣷ' => 230, + 'ࣸ' => 230, + 'ࣹ' => 220, + 'ࣺ' => 220, + 'ࣻ' => 230, + 'ࣼ' => 230, + 'ࣽ' => 230, + 'ࣾ' => 230, + 'ࣿ' => 230, + '़' => 7, + '्' => 9, + '॑' => 230, + '॒' => 220, + '॓' => 230, + '॔' => 230, + '়' => 7, + '্' => 9, + '৾' => 230, + '਼' => 7, + '੍' => 9, + '઼' => 7, + '્' => 9, + '଼' => 7, + '୍' => 9, + '்' => 9, + '్' => 9, + 'ౕ' => 84, + 'ౖ' => 91, + '಼' => 7, + '್' => 9, + '഻' => 9, + '഼' => 9, + '്' => 9, + '්' => 9, + 'ุ' => 103, + 'ู' => 103, + 'ฺ' => 9, + '่' => 107, + '้' => 107, + '๊' => 107, + '๋' => 107, + 'ຸ' => 118, + 'ູ' => 118, + '຺' => 9, + '່' => 122, + '້' => 122, + '໊' => 122, + '໋' => 122, + '༘' => 220, + '༙' => 220, + '༵' => 220, + '༷' => 220, + '༹' => 216, + 'ཱ' => 129, + 'ི' => 130, + 'ུ' => 132, + 'ེ' => 130, + 'ཻ' => 130, + 'ོ' => 130, + 'ཽ' => 130, + 'ྀ' => 130, + 'ྂ' => 230, + 'ྃ' => 230, + '྄' => 9, + '྆' => 230, + '྇' => 230, + '࿆' => 220, + '့' => 7, + '္' => 9, + '်' => 9, + 'ႍ' => 220, + '፝' => 230, + '፞' => 230, + '፟' => 230, + '᜔' => 9, + '᜴' => 9, + '្' => 9, + '៝' => 230, + 'ᢩ' => 228, + '᤹' => 222, + '᤺' => 230, + '᤻' => 220, + 'ᨗ' => 230, + 'ᨘ' => 220, + '᩠' => 9, + '᩵' => 230, + '᩶' => 230, + '᩷' => 230, + '᩸' => 230, + '᩹' => 230, + '᩺' => 230, + '᩻' => 230, + '᩼' => 230, + '᩿' => 220, + '᪰' => 230, + '᪱' => 230, + '᪲' => 230, + '᪳' => 230, + '᪴' => 230, + '᪵' => 220, + '᪶' => 220, + '᪷' => 220, + '᪸' => 220, + '᪹' => 220, + '᪺' => 220, + '᪻' => 230, + '᪼' => 230, + '᪽' => 220, + 'ᪿ' => 220, + 'ᫀ' => 220, + '᬴' => 7, + '᭄' => 9, + '᭫' => 230, + '᭬' => 220, + '᭭' => 230, + '᭮' => 230, + '᭯' => 230, + '᭰' => 230, + '᭱' => 230, + '᭲' => 230, + '᭳' => 230, + '᮪' => 9, + '᮫' => 9, + '᯦' => 7, + '᯲' => 9, + '᯳' => 9, + '᰷' => 7, + '᳐' => 230, + '᳑' => 230, + '᳒' => 230, + '᳔' => 1, + '᳕' => 220, + '᳖' => 220, + '᳗' => 220, + '᳘' => 220, + '᳙' => 220, + '᳚' => 230, + '᳛' => 230, + '᳜' => 220, + '᳝' => 220, + '᳞' => 220, + '᳟' => 220, + '᳠' => 230, + '᳢' => 1, + '᳣' => 1, + '᳤' => 1, + '᳥' => 1, + '᳦' => 1, + '᳧' => 1, + '᳨' => 1, + '᳭' => 220, + '᳴' => 230, + '᳸' => 230, + '᳹' => 230, + '᷀' => 230, + '᷁' => 230, + '᷂' => 220, + '᷃' => 230, + '᷄' => 230, + '᷅' => 230, + '᷆' => 230, + '᷇' => 230, + '᷈' => 230, + '᷉' => 230, + '᷊' => 220, + '᷋' => 230, + '᷌' => 230, + '᷍' => 234, + '᷎' => 214, + '᷏' => 220, + '᷐' => 202, + '᷑' => 230, + '᷒' => 230, + 'ᷓ' => 230, + 'ᷔ' => 230, + 'ᷕ' => 230, + 'ᷖ' => 230, + 'ᷗ' => 230, + 'ᷘ' => 230, + 'ᷙ' => 230, + 'ᷚ' => 230, + 'ᷛ' => 230, + 'ᷜ' => 230, + 'ᷝ' => 230, + 'ᷞ' => 230, + 'ᷟ' => 230, + 'ᷠ' => 230, + 'ᷡ' => 230, + 'ᷢ' => 230, + 'ᷣ' => 230, + 'ᷤ' => 230, + 'ᷥ' => 230, + 'ᷦ' => 230, + 'ᷧ' => 230, + 'ᷨ' => 230, + 'ᷩ' => 230, + 'ᷪ' => 230, + 'ᷫ' => 230, + 'ᷬ' => 230, + 'ᷭ' => 230, + 'ᷮ' => 230, + 'ᷯ' => 230, + 'ᷰ' => 230, + 'ᷱ' => 230, + 'ᷲ' => 230, + 'ᷳ' => 230, + 'ᷴ' => 230, + '᷵' => 230, + '᷶' => 232, + '᷷' => 228, + '᷸' => 228, + '᷹' => 220, + '᷻' => 230, + '᷼' => 233, + '᷽' => 220, + '᷾' => 230, + '᷿' => 220, + '⃐' => 230, + '⃑' => 230, + '⃒' => 1, + '⃓' => 1, + '⃔' => 230, + '⃕' => 230, + '⃖' => 230, + '⃗' => 230, + '⃘' => 1, + '⃙' => 1, + '⃚' => 1, + '⃛' => 230, + '⃜' => 230, + '⃡' => 230, + '⃥' => 1, + '⃦' => 1, + '⃧' => 230, + '⃨' => 220, + '⃩' => 230, + '⃪' => 1, + '⃫' => 1, + '⃬' => 220, + '⃭' => 220, + '⃮' => 220, + '⃯' => 220, + '⃰' => 230, + '⳯' => 230, + '⳰' => 230, + '⳱' => 230, + '⵿' => 9, + 'ⷠ' => 230, + 'ⷡ' => 230, + 'ⷢ' => 230, + 'ⷣ' => 230, + 'ⷤ' => 230, + 'ⷥ' => 230, + 'ⷦ' => 230, + 'ⷧ' => 230, + 'ⷨ' => 230, + 'ⷩ' => 230, + 'ⷪ' => 230, + 'ⷫ' => 230, + 'ⷬ' => 230, + 'ⷭ' => 230, + 'ⷮ' => 230, + 'ⷯ' => 230, + 'ⷰ' => 230, + 'ⷱ' => 230, + 'ⷲ' => 230, + 'ⷳ' => 230, + 'ⷴ' => 230, + 'ⷵ' => 230, + 'ⷶ' => 230, + 'ⷷ' => 230, + 'ⷸ' => 230, + 'ⷹ' => 230, + 'ⷺ' => 230, + 'ⷻ' => 230, + 'ⷼ' => 230, + 'ⷽ' => 230, + 'ⷾ' => 230, + 'ⷿ' => 230, + '〪' => 218, + '〫' => 228, + '〬' => 232, + '〭' => 222, + '〮' => 224, + '〯' => 224, + '゙' => 8, + '゚' => 8, + '꙯' => 230, + 'ꙴ' => 230, + 'ꙵ' => 230, + 'ꙶ' => 230, + 'ꙷ' => 230, + 'ꙸ' => 230, + 'ꙹ' => 230, + 'ꙺ' => 230, + 'ꙻ' => 230, + '꙼' => 230, + '꙽' => 230, + 'ꚞ' => 230, + 'ꚟ' => 230, + '꛰' => 230, + '꛱' => 230, + '꠆' => 9, + '꠬' => 9, + '꣄' => 9, + '꣠' => 230, + '꣡' => 230, + '꣢' => 230, + '꣣' => 230, + '꣤' => 230, + '꣥' => 230, + '꣦' => 230, + '꣧' => 230, + '꣨' => 230, + '꣩' => 230, + '꣪' => 230, + '꣫' => 230, + '꣬' => 230, + '꣭' => 230, + '꣮' => 230, + '꣯' => 230, + '꣰' => 230, + '꣱' => 230, + '꤫' => 220, + '꤬' => 220, + '꤭' => 220, + '꥓' => 9, + '꦳' => 7, + '꧀' => 9, + 'ꪰ' => 230, + 'ꪲ' => 230, + 'ꪳ' => 230, + 'ꪴ' => 220, + 'ꪷ' => 230, + 'ꪸ' => 230, + 'ꪾ' => 230, + '꪿' => 230, + '꫁' => 230, + '꫶' => 9, + '꯭' => 9, + 'ﬞ' => 26, + '︠' => 230, + '︡' => 230, + '︢' => 230, + '︣' => 230, + '︤' => 230, + '︥' => 230, + '︦' => 230, + '︧' => 220, + '︨' => 220, + '︩' => 220, + '︪' => 220, + '︫' => 220, + '︬' => 220, + '︭' => 220, + '︮' => 230, + '︯' => 230, + '𐇽' => 220, + '𐋠' => 220, + '𐍶' => 230, + '𐍷' => 230, + '𐍸' => 230, + '𐍹' => 230, + '𐍺' => 230, + '𐨍' => 220, + '𐨏' => 230, + '𐨸' => 230, + '𐨹' => 1, + '𐨺' => 220, + '𐨿' => 9, + '𐫥' => 230, + '𐫦' => 220, + '𐴤' => 230, + '𐴥' => 230, + '𐴦' => 230, + '𐴧' => 230, + '𐺫' => 230, + '𐺬' => 230, + '𐽆' => 220, + '𐽇' => 220, + '𐽈' => 230, + '𐽉' => 230, + '𐽊' => 230, + '𐽋' => 220, + '𐽌' => 230, + '𐽍' => 220, + '𐽎' => 220, + '𐽏' => 220, + '𐽐' => 220, + '𑁆' => 9, + '𑁿' => 9, + '𑂹' => 9, + '𑂺' => 7, + '𑄀' => 230, + '𑄁' => 230, + '𑄂' => 230, + '𑄳' => 9, + '𑄴' => 9, + '𑅳' => 7, + '𑇀' => 9, + '𑇊' => 7, + '𑈵' => 9, + '𑈶' => 7, + '𑋩' => 7, + '𑋪' => 9, + '𑌻' => 7, + '𑌼' => 7, + '𑍍' => 9, + '𑍦' => 230, + '𑍧' => 230, + '𑍨' => 230, + '𑍩' => 230, + '𑍪' => 230, + '𑍫' => 230, + '𑍬' => 230, + '𑍰' => 230, + '𑍱' => 230, + '𑍲' => 230, + '𑍳' => 230, + '𑍴' => 230, + '𑑂' => 9, + '𑑆' => 7, + '𑑞' => 230, + '𑓂' => 9, + '𑓃' => 7, + '𑖿' => 9, + '𑗀' => 7, + '𑘿' => 9, + '𑚶' => 9, + '𑚷' => 7, + '𑜫' => 9, + '𑠹' => 9, + '𑠺' => 7, + '𑤽' => 9, + '𑤾' => 9, + '𑥃' => 7, + '𑧠' => 9, + '𑨴' => 9, + '𑩇' => 9, + '𑪙' => 9, + '𑰿' => 9, + '𑵂' => 7, + '𑵄' => 9, + '𑵅' => 9, + '𑶗' => 9, + '𖫰' => 1, + '𖫱' => 1, + '𖫲' => 1, + '𖫳' => 1, + '𖫴' => 1, + '𖬰' => 230, + '𖬱' => 230, + '𖬲' => 230, + '𖬳' => 230, + '𖬴' => 230, + '𖬵' => 230, + '𖬶' => 230, + '𖿰' => 6, + '𖿱' => 6, + '𛲞' => 1, + '𝅥' => 216, + '𝅦' => 216, + '𝅧' => 1, + '𝅨' => 1, + '𝅩' => 1, + '𝅭' => 226, + '𝅮' => 216, + '𝅯' => 216, + '𝅰' => 216, + '𝅱' => 216, + '𝅲' => 216, + '𝅻' => 220, + '𝅼' => 220, + '𝅽' => 220, + '𝅾' => 220, + '𝅿' => 220, + '𝆀' => 220, + '𝆁' => 220, + '𝆂' => 220, + '𝆅' => 230, + '𝆆' => 230, + '𝆇' => 230, + '𝆈' => 230, + '𝆉' => 230, + '𝆊' => 220, + '𝆋' => 220, + '𝆪' => 230, + '𝆫' => 230, + '𝆬' => 230, + '𝆭' => 230, + '𝉂' => 230, + '𝉃' => 230, + '𝉄' => 230, + '𞀀' => 230, + '𞀁' => 230, + '𞀂' => 230, + '𞀃' => 230, + '𞀄' => 230, + '𞀅' => 230, + '𞀆' => 230, + '𞀈' => 230, + '𞀉' => 230, + '𞀊' => 230, + '𞀋' => 230, + '𞀌' => 230, + '𞀍' => 230, + '𞀎' => 230, + '𞀏' => 230, + '𞀐' => 230, + '𞀑' => 230, + '𞀒' => 230, + '𞀓' => 230, + '𞀔' => 230, + '𞀕' => 230, + '𞀖' => 230, + '𞀗' => 230, + '𞀘' => 230, + '𞀛' => 230, + '𞀜' => 230, + '𞀝' => 230, + '𞀞' => 230, + '𞀟' => 230, + '𞀠' => 230, + '𞀡' => 230, + '𞀣' => 230, + '𞀤' => 230, + '𞀦' => 230, + '𞀧' => 230, + '𞀨' => 230, + '𞀩' => 230, + '𞀪' => 230, + '𞄰' => 230, + '𞄱' => 230, + '𞄲' => 230, + '𞄳' => 230, + '𞄴' => 230, + '𞄵' => 230, + '𞄶' => 230, + '𞋬' => 230, + '𞋭' => 230, + '𞋮' => 230, + '𞋯' => 230, + '𞣐' => 220, + '𞣑' => 220, + '𞣒' => 220, + '𞣓' => 220, + '𞣔' => 220, + '𞣕' => 220, + '𞣖' => 220, + '𞥄' => 230, + '𞥅' => 230, + '𞥆' => 230, + '𞥇' => 230, + '𞥈' => 230, + '𞥉' => 230, + '𞥊' => 7, +); diff --git a/includes/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php b/includes/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php new file mode 100644 index 0000000..1574902 --- /dev/null +++ b/includes/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php @@ -0,0 +1,3695 @@ + ' ', + '¨' => ' ̈', + 'ª' => 'a', + '¯' => ' ̄', + '²' => '2', + '³' => '3', + '´' => ' ́', + 'µ' => 'μ', + '¸' => ' ̧', + '¹' => '1', + 'º' => 'o', + '¼' => '1⁄4', + '½' => '1⁄2', + '¾' => '3⁄4', + 'IJ' => 'IJ', + 'ij' => 'ij', + 'Ŀ' => 'L·', + 'ŀ' => 'l·', + 'ʼn' => 'ʼn', + 'ſ' => 's', + 'DŽ' => 'DŽ', + 'Dž' => 'Dž', + 'dž' => 'dž', + 'LJ' => 'LJ', + 'Lj' => 'Lj', + 'lj' => 'lj', + 'NJ' => 'NJ', + 'Nj' => 'Nj', + 'nj' => 'nj', + 'DZ' => 'DZ', + 'Dz' => 'Dz', + 'dz' => 'dz', + 'ʰ' => 'h', + 'ʱ' => 'ɦ', + 'ʲ' => 'j', + 'ʳ' => 'r', + 'ʴ' => 'ɹ', + 'ʵ' => 'ɻ', + 'ʶ' => 'ʁ', + 'ʷ' => 'w', + 'ʸ' => 'y', + '˘' => ' ̆', + '˙' => ' ̇', + '˚' => ' ̊', + '˛' => ' ̨', + '˜' => ' ̃', + '˝' => ' ̋', + 'ˠ' => 'ɣ', + 'ˡ' => 'l', + 'ˢ' => 's', + 'ˣ' => 'x', + 'ˤ' => 'ʕ', + 'ͺ' => ' ͅ', + '΄' => ' ́', + '΅' => ' ̈́', + 'ϐ' => 'β', + 'ϑ' => 'θ', + 'ϒ' => 'Υ', + 'ϓ' => 'Ύ', + 'ϔ' => 'Ϋ', + 'ϕ' => 'φ', + 'ϖ' => 'π', + 'ϰ' => 'κ', + 'ϱ' => 'ρ', + 'ϲ' => 'ς', + 'ϴ' => 'Θ', + 'ϵ' => 'ε', + 'Ϲ' => 'Σ', + 'և' => 'եւ', + 'ٵ' => 'اٴ', + 'ٶ' => 'وٴ', + 'ٷ' => 'ۇٴ', + 'ٸ' => 'يٴ', + 'ำ' => 'ํา', + 'ຳ' => 'ໍາ', + 'ໜ' => 'ຫນ', + 'ໝ' => 'ຫມ', + '༌' => '་', + 'ཷ' => 'ྲཱྀ', + 'ཹ' => 'ླཱྀ', + 'ჼ' => 'ნ', + 'ᴬ' => 'A', + 'ᴭ' => 'Æ', + 'ᴮ' => 'B', + 'ᴰ' => 'D', + 'ᴱ' => 'E', + 'ᴲ' => 'Ǝ', + 'ᴳ' => 'G', + 'ᴴ' => 'H', + 'ᴵ' => 'I', + 'ᴶ' => 'J', + 'ᴷ' => 'K', + 'ᴸ' => 'L', + 'ᴹ' => 'M', + 'ᴺ' => 'N', + 'ᴼ' => 'O', + 'ᴽ' => 'Ȣ', + 'ᴾ' => 'P', + 'ᴿ' => 'R', + 'ᵀ' => 'T', + 'ᵁ' => 'U', + 'ᵂ' => 'W', + 'ᵃ' => 'a', + 'ᵄ' => 'ɐ', + 'ᵅ' => 'ɑ', + 'ᵆ' => 'ᴂ', + 'ᵇ' => 'b', + 'ᵈ' => 'd', + 'ᵉ' => 'e', + 'ᵊ' => 'ə', + 'ᵋ' => 'ɛ', + 'ᵌ' => 'ɜ', + 'ᵍ' => 'g', + 'ᵏ' => 'k', + 'ᵐ' => 'm', + 'ᵑ' => 'ŋ', + 'ᵒ' => 'o', + 'ᵓ' => 'ɔ', + 'ᵔ' => 'ᴖ', + 'ᵕ' => 'ᴗ', + 'ᵖ' => 'p', + 'ᵗ' => 't', + 'ᵘ' => 'u', + 'ᵙ' => 'ᴝ', + 'ᵚ' => 'ɯ', + 'ᵛ' => 'v', + 'ᵜ' => 'ᴥ', + 'ᵝ' => 'β', + 'ᵞ' => 'γ', + 'ᵟ' => 'δ', + 'ᵠ' => 'φ', + 'ᵡ' => 'χ', + 'ᵢ' => 'i', + 'ᵣ' => 'r', + 'ᵤ' => 'u', + 'ᵥ' => 'v', + 'ᵦ' => 'β', + 'ᵧ' => 'γ', + 'ᵨ' => 'ρ', + 'ᵩ' => 'φ', + 'ᵪ' => 'χ', + 'ᵸ' => 'н', + 'ᶛ' => 'ɒ', + 'ᶜ' => 'c', + 'ᶝ' => 'ɕ', + 'ᶞ' => 'ð', + 'ᶟ' => 'ɜ', + 'ᶠ' => 'f', + 'ᶡ' => 'ɟ', + 'ᶢ' => 'ɡ', + 'ᶣ' => 'ɥ', + 'ᶤ' => 'ɨ', + 'ᶥ' => 'ɩ', + 'ᶦ' => 'ɪ', + 'ᶧ' => 'ᵻ', + 'ᶨ' => 'ʝ', + 'ᶩ' => 'ɭ', + 'ᶪ' => 'ᶅ', + 'ᶫ' => 'ʟ', + 'ᶬ' => 'ɱ', + 'ᶭ' => 'ɰ', + 'ᶮ' => 'ɲ', + 'ᶯ' => 'ɳ', + 'ᶰ' => 'ɴ', + 'ᶱ' => 'ɵ', + 'ᶲ' => 'ɸ', + 'ᶳ' => 'ʂ', + 'ᶴ' => 'ʃ', + 'ᶵ' => 'ƫ', + 'ᶶ' => 'ʉ', + 'ᶷ' => 'ʊ', + 'ᶸ' => 'ᴜ', + 'ᶹ' => 'ʋ', + 'ᶺ' => 'ʌ', + 'ᶻ' => 'z', + 'ᶼ' => 'ʐ', + 'ᶽ' => 'ʑ', + 'ᶾ' => 'ʒ', + 'ᶿ' => 'θ', + 'ẚ' => 'aʾ', + 'ẛ' => 'ṡ', + '᾽' => ' ̓', + '᾿' => ' ̓', + '῀' => ' ͂', + '῁' => ' ̈͂', + '῍' => ' ̓̀', + '῎' => ' ̓́', + '῏' => ' ̓͂', + '῝' => ' ̔̀', + '῞' => ' ̔́', + '῟' => ' ̔͂', + '῭' => ' ̈̀', + '΅' => ' ̈́', + '´' => ' ́', + '῾' => ' ̔', + ' ' => ' ', + ' ' => ' ', + ' ' => ' ', + ' ' => ' ', + ' ' => ' ', + ' ' => ' ', + ' ' => ' ', + ' ' => ' ', + ' ' => ' ', + ' ' => ' ', + ' ' => ' ', + '‑' => '‐', + '‗' => ' ̳', + '․' => '.', + '‥' => '..', + '…' => '...', + ' ' => ' ', + '″' => '′′', + '‴' => '′′′', + '‶' => '‵‵', + '‷' => '‵‵‵', + '‼' => '!!', + '‾' => ' ̅', + '⁇' => '??', + '⁈' => '?!', + '⁉' => '!?', + '⁗' => '′′′′', + ' ' => ' ', + '⁰' => '0', + 'ⁱ' => 'i', + '⁴' => '4', + '⁵' => '5', + '⁶' => '6', + '⁷' => '7', + '⁸' => '8', + '⁹' => '9', + '⁺' => '+', + '⁻' => '−', + '⁼' => '=', + '⁽' => '(', + '⁾' => ')', + 'ⁿ' => 'n', + '₀' => '0', + '₁' => '1', + '₂' => '2', + '₃' => '3', + '₄' => '4', + '₅' => '5', + '₆' => '6', + '₇' => '7', + '₈' => '8', + '₉' => '9', + '₊' => '+', + '₋' => '−', + '₌' => '=', + '₍' => '(', + '₎' => ')', + 'ₐ' => 'a', + 'ₑ' => 'e', + 'ₒ' => 'o', + 'ₓ' => 'x', + 'ₔ' => 'ə', + 'ₕ' => 'h', + 'ₖ' => 'k', + 'ₗ' => 'l', + 'ₘ' => 'm', + 'ₙ' => 'n', + 'ₚ' => 'p', + 'ₛ' => 's', + 'ₜ' => 't', + '₨' => 'Rs', + '℀' => 'a/c', + '℁' => 'a/s', + 'ℂ' => 'C', + '℃' => '°C', + '℅' => 'c/o', + '℆' => 'c/u', + 'ℇ' => 'Ɛ', + '℉' => '°F', + 'ℊ' => 'g', + 'ℋ' => 'H', + 'ℌ' => 'H', + 'ℍ' => 'H', + 'ℎ' => 'h', + 'ℏ' => 'ħ', + 'ℐ' => 'I', + 'ℑ' => 'I', + 'ℒ' => 'L', + 'ℓ' => 'l', + 'ℕ' => 'N', + '№' => 'No', + 'ℙ' => 'P', + 'ℚ' => 'Q', + 'ℛ' => 'R', + 'ℜ' => 'R', + 'ℝ' => 'R', + '℠' => 'SM', + '℡' => 'TEL', + '™' => 'TM', + 'ℤ' => 'Z', + 'ℨ' => 'Z', + 'ℬ' => 'B', + 'ℭ' => 'C', + 'ℯ' => 'e', + 'ℰ' => 'E', + 'ℱ' => 'F', + 'ℳ' => 'M', + 'ℴ' => 'o', + 'ℵ' => 'א', + 'ℶ' => 'ב', + 'ℷ' => 'ג', + 'ℸ' => 'ד', + 'ℹ' => 'i', + '℻' => 'FAX', + 'ℼ' => 'π', + 'ℽ' => 'γ', + 'ℾ' => 'Γ', + 'ℿ' => 'Π', + '⅀' => '∑', + 'ⅅ' => 'D', + 'ⅆ' => 'd', + 'ⅇ' => 'e', + 'ⅈ' => 'i', + 'ⅉ' => 'j', + '⅐' => '1⁄7', + '⅑' => '1⁄9', + '⅒' => '1⁄10', + '⅓' => '1⁄3', + '⅔' => '2⁄3', + '⅕' => '1⁄5', + '⅖' => '2⁄5', + '⅗' => '3⁄5', + '⅘' => '4⁄5', + '⅙' => '1⁄6', + '⅚' => '5⁄6', + '⅛' => '1⁄8', + '⅜' => '3⁄8', + '⅝' => '5⁄8', + '⅞' => '7⁄8', + '⅟' => '1⁄', + 'Ⅰ' => 'I', + 'Ⅱ' => 'II', + 'Ⅲ' => 'III', + 'Ⅳ' => 'IV', + 'Ⅴ' => 'V', + 'Ⅵ' => 'VI', + 'Ⅶ' => 'VII', + 'Ⅷ' => 'VIII', + 'Ⅸ' => 'IX', + 'Ⅹ' => 'X', + 'Ⅺ' => 'XI', + 'Ⅻ' => 'XII', + 'Ⅼ' => 'L', + 'Ⅽ' => 'C', + 'Ⅾ' => 'D', + 'Ⅿ' => 'M', + 'ⅰ' => 'i', + 'ⅱ' => 'ii', + 'ⅲ' => 'iii', + 'ⅳ' => 'iv', + 'ⅴ' => 'v', + 'ⅵ' => 'vi', + 'ⅶ' => 'vii', + 'ⅷ' => 'viii', + 'ⅸ' => 'ix', + 'ⅹ' => 'x', + 'ⅺ' => 'xi', + 'ⅻ' => 'xii', + 'ⅼ' => 'l', + 'ⅽ' => 'c', + 'ⅾ' => 'd', + 'ⅿ' => 'm', + '↉' => '0⁄3', + '∬' => '∫∫', + '∭' => '∫∫∫', + '∯' => '∮∮', + '∰' => '∮∮∮', + '①' => '1', + '②' => '2', + '③' => '3', + '④' => '4', + '⑤' => '5', + '⑥' => '6', + '⑦' => '7', + '⑧' => '8', + '⑨' => '9', + '⑩' => '10', + '⑪' => '11', + '⑫' => '12', + '⑬' => '13', + '⑭' => '14', + '⑮' => '15', + '⑯' => '16', + '⑰' => '17', + '⑱' => '18', + '⑲' => '19', + '⑳' => '20', + '⑴' => '(1)', + '⑵' => '(2)', + '⑶' => '(3)', + '⑷' => '(4)', + '⑸' => '(5)', + '⑹' => '(6)', + '⑺' => '(7)', + '⑻' => '(8)', + '⑼' => '(9)', + '⑽' => '(10)', + '⑾' => '(11)', + '⑿' => '(12)', + '⒀' => '(13)', + '⒁' => '(14)', + '⒂' => '(15)', + '⒃' => '(16)', + '⒄' => '(17)', + '⒅' => '(18)', + '⒆' => '(19)', + '⒇' => '(20)', + '⒈' => '1.', + '⒉' => '2.', + '⒊' => '3.', + '⒋' => '4.', + '⒌' => '5.', + '⒍' => '6.', + '⒎' => '7.', + '⒏' => '8.', + '⒐' => '9.', + '⒑' => '10.', + '⒒' => '11.', + '⒓' => '12.', + '⒔' => '13.', + '⒕' => '14.', + '⒖' => '15.', + '⒗' => '16.', + '⒘' => '17.', + '⒙' => '18.', + '⒚' => '19.', + '⒛' => '20.', + '⒜' => '(a)', + '⒝' => '(b)', + '⒞' => '(c)', + '⒟' => '(d)', + '⒠' => '(e)', + '⒡' => '(f)', + '⒢' => '(g)', + '⒣' => '(h)', + '⒤' => '(i)', + '⒥' => '(j)', + '⒦' => '(k)', + '⒧' => '(l)', + '⒨' => '(m)', + '⒩' => '(n)', + '⒪' => '(o)', + '⒫' => '(p)', + '⒬' => '(q)', + '⒭' => '(r)', + '⒮' => '(s)', + '⒯' => '(t)', + '⒰' => '(u)', + '⒱' => '(v)', + '⒲' => '(w)', + '⒳' => '(x)', + '⒴' => '(y)', + '⒵' => '(z)', + 'Ⓐ' => 'A', + 'Ⓑ' => 'B', + 'Ⓒ' => 'C', + 'Ⓓ' => 'D', + 'Ⓔ' => 'E', + 'Ⓕ' => 'F', + 'Ⓖ' => 'G', + 'Ⓗ' => 'H', + 'Ⓘ' => 'I', + 'Ⓙ' => 'J', + 'Ⓚ' => 'K', + 'Ⓛ' => 'L', + 'Ⓜ' => 'M', + 'Ⓝ' => 'N', + 'Ⓞ' => 'O', + 'Ⓟ' => 'P', + 'Ⓠ' => 'Q', + 'Ⓡ' => 'R', + 'Ⓢ' => 'S', + 'Ⓣ' => 'T', + 'Ⓤ' => 'U', + 'Ⓥ' => 'V', + 'Ⓦ' => 'W', + 'Ⓧ' => 'X', + 'Ⓨ' => 'Y', + 'Ⓩ' => 'Z', + 'ⓐ' => 'a', + 'ⓑ' => 'b', + 'ⓒ' => 'c', + 'ⓓ' => 'd', + 'ⓔ' => 'e', + 'ⓕ' => 'f', + 'ⓖ' => 'g', + 'ⓗ' => 'h', + 'ⓘ' => 'i', + 'ⓙ' => 'j', + 'ⓚ' => 'k', + 'ⓛ' => 'l', + 'ⓜ' => 'm', + 'ⓝ' => 'n', + 'ⓞ' => 'o', + 'ⓟ' => 'p', + 'ⓠ' => 'q', + 'ⓡ' => 'r', + 'ⓢ' => 's', + 'ⓣ' => 't', + 'ⓤ' => 'u', + 'ⓥ' => 'v', + 'ⓦ' => 'w', + 'ⓧ' => 'x', + 'ⓨ' => 'y', + 'ⓩ' => 'z', + '⓪' => '0', + '⨌' => '∫∫∫∫', + '⩴' => '::=', + '⩵' => '==', + '⩶' => '===', + 'ⱼ' => 'j', + 'ⱽ' => 'V', + 'ⵯ' => 'ⵡ', + '⺟' => '母', + '⻳' => '龟', + '⼀' => '一', + '⼁' => '丨', + '⼂' => '丶', + '⼃' => '丿', + '⼄' => '乙', + '⼅' => '亅', + '⼆' => '二', + '⼇' => '亠', + '⼈' => '人', + '⼉' => '儿', + '⼊' => '入', + '⼋' => '八', + '⼌' => '冂', + '⼍' => '冖', + '⼎' => '冫', + '⼏' => '几', + '⼐' => '凵', + '⼑' => '刀', + '⼒' => '力', + '⼓' => '勹', + '⼔' => '匕', + '⼕' => '匚', + '⼖' => '匸', + '⼗' => '十', + '⼘' => '卜', + '⼙' => '卩', + '⼚' => '厂', + '⼛' => '厶', + '⼜' => '又', + '⼝' => '口', + '⼞' => '囗', + '⼟' => '土', + '⼠' => '士', + '⼡' => '夂', + '⼢' => '夊', + '⼣' => '夕', + '⼤' => '大', + '⼥' => '女', + '⼦' => '子', + '⼧' => '宀', + '⼨' => '寸', + '⼩' => '小', + '⼪' => '尢', + '⼫' => '尸', + '⼬' => '屮', + '⼭' => '山', + '⼮' => '巛', + '⼯' => '工', + '⼰' => '己', + '⼱' => '巾', + '⼲' => '干', + '⼳' => '幺', + '⼴' => '广', + '⼵' => '廴', + '⼶' => '廾', + '⼷' => '弋', + '⼸' => '弓', + '⼹' => '彐', + '⼺' => '彡', + '⼻' => '彳', + '⼼' => '心', + '⼽' => '戈', + '⼾' => '戶', + '⼿' => '手', + '⽀' => '支', + '⽁' => '攴', + '⽂' => '文', + '⽃' => '斗', + '⽄' => '斤', + '⽅' => '方', + '⽆' => '无', + '⽇' => '日', + '⽈' => '曰', + '⽉' => '月', + '⽊' => '木', + '⽋' => '欠', + '⽌' => '止', + '⽍' => '歹', + '⽎' => '殳', + '⽏' => '毋', + '⽐' => '比', + '⽑' => '毛', + '⽒' => '氏', + '⽓' => '气', + '⽔' => '水', + '⽕' => '火', + '⽖' => '爪', + '⽗' => '父', + '⽘' => '爻', + '⽙' => '爿', + '⽚' => '片', + '⽛' => '牙', + '⽜' => '牛', + '⽝' => '犬', + '⽞' => '玄', + '⽟' => '玉', + '⽠' => '瓜', + '⽡' => '瓦', + '⽢' => '甘', + '⽣' => '生', + '⽤' => '用', + '⽥' => '田', + '⽦' => '疋', + '⽧' => '疒', + '⽨' => '癶', + '⽩' => '白', + '⽪' => '皮', + '⽫' => '皿', + '⽬' => '目', + '⽭' => '矛', + '⽮' => '矢', + '⽯' => '石', + '⽰' => '示', + '⽱' => '禸', + '⽲' => '禾', + '⽳' => '穴', + '⽴' => '立', + '⽵' => '竹', + '⽶' => '米', + '⽷' => '糸', + '⽸' => '缶', + '⽹' => '网', + '⽺' => '羊', + '⽻' => '羽', + '⽼' => '老', + '⽽' => '而', + '⽾' => '耒', + '⽿' => '耳', + '⾀' => '聿', + '⾁' => '肉', + '⾂' => '臣', + '⾃' => '自', + '⾄' => '至', + '⾅' => '臼', + '⾆' => '舌', + '⾇' => '舛', + '⾈' => '舟', + '⾉' => '艮', + '⾊' => '色', + '⾋' => '艸', + '⾌' => '虍', + '⾍' => '虫', + '⾎' => '血', + '⾏' => '行', + '⾐' => '衣', + '⾑' => '襾', + '⾒' => '見', + '⾓' => '角', + '⾔' => '言', + '⾕' => '谷', + '⾖' => '豆', + '⾗' => '豕', + '⾘' => '豸', + '⾙' => '貝', + '⾚' => '赤', + '⾛' => '走', + '⾜' => '足', + '⾝' => '身', + '⾞' => '車', + '⾟' => '辛', + '⾠' => '辰', + '⾡' => '辵', + '⾢' => '邑', + '⾣' => '酉', + '⾤' => '釆', + '⾥' => '里', + '⾦' => '金', + '⾧' => '長', + '⾨' => '門', + '⾩' => '阜', + '⾪' => '隶', + '⾫' => '隹', + '⾬' => '雨', + '⾭' => '靑', + '⾮' => '非', + '⾯' => '面', + '⾰' => '革', + '⾱' => '韋', + '⾲' => '韭', + '⾳' => '音', + '⾴' => '頁', + '⾵' => '風', + '⾶' => '飛', + '⾷' => '食', + '⾸' => '首', + '⾹' => '香', + '⾺' => '馬', + '⾻' => '骨', + '⾼' => '高', + '⾽' => '髟', + '⾾' => '鬥', + '⾿' => '鬯', + '⿀' => '鬲', + '⿁' => '鬼', + '⿂' => '魚', + '⿃' => '鳥', + '⿄' => '鹵', + '⿅' => '鹿', + '⿆' => '麥', + '⿇' => '麻', + '⿈' => '黃', + '⿉' => '黍', + '⿊' => '黑', + '⿋' => '黹', + '⿌' => '黽', + '⿍' => '鼎', + '⿎' => '鼓', + '⿏' => '鼠', + '⿐' => '鼻', + '⿑' => '齊', + '⿒' => '齒', + '⿓' => '龍', + '⿔' => '龜', + '⿕' => '龠', + ' ' => ' ', + '〶' => '〒', + '〸' => '十', + '〹' => '卄', + '〺' => '卅', + '゛' => ' ゙', + '゜' => ' ゚', + 'ゟ' => 'より', + 'ヿ' => 'コト', + 'ㄱ' => 'ᄀ', + 'ㄲ' => 'ᄁ', + 'ㄳ' => 'ᆪ', + 'ㄴ' => 'ᄂ', + 'ㄵ' => 'ᆬ', + 'ㄶ' => 'ᆭ', + 'ㄷ' => 'ᄃ', + 'ㄸ' => 'ᄄ', + 'ㄹ' => 'ᄅ', + 'ㄺ' => 'ᆰ', + 'ㄻ' => 'ᆱ', + 'ㄼ' => 'ᆲ', + 'ㄽ' => 'ᆳ', + 'ㄾ' => 'ᆴ', + 'ㄿ' => 'ᆵ', + 'ㅀ' => 'ᄚ', + 'ㅁ' => 'ᄆ', + 'ㅂ' => 'ᄇ', + 'ㅃ' => 'ᄈ', + 'ㅄ' => 'ᄡ', + 'ㅅ' => 'ᄉ', + 'ㅆ' => 'ᄊ', + 'ㅇ' => 'ᄋ', + 'ㅈ' => 'ᄌ', + 'ㅉ' => 'ᄍ', + 'ㅊ' => 'ᄎ', + 'ㅋ' => 'ᄏ', + 'ㅌ' => 'ᄐ', + 'ㅍ' => 'ᄑ', + 'ㅎ' => 'ᄒ', + 'ㅏ' => 'ᅡ', + 'ㅐ' => 'ᅢ', + 'ㅑ' => 'ᅣ', + 'ㅒ' => 'ᅤ', + 'ㅓ' => 'ᅥ', + 'ㅔ' => 'ᅦ', + 'ㅕ' => 'ᅧ', + 'ㅖ' => 'ᅨ', + 'ㅗ' => 'ᅩ', + 'ㅘ' => 'ᅪ', + 'ㅙ' => 'ᅫ', + 'ㅚ' => 'ᅬ', + 'ㅛ' => 'ᅭ', + 'ㅜ' => 'ᅮ', + 'ㅝ' => 'ᅯ', + 'ㅞ' => 'ᅰ', + 'ㅟ' => 'ᅱ', + 'ㅠ' => 'ᅲ', + 'ㅡ' => 'ᅳ', + 'ㅢ' => 'ᅴ', + 'ㅣ' => 'ᅵ', + 'ㅤ' => 'ᅠ', + 'ㅥ' => 'ᄔ', + 'ㅦ' => 'ᄕ', + 'ㅧ' => 'ᇇ', + 'ㅨ' => 'ᇈ', + 'ㅩ' => 'ᇌ', + 'ㅪ' => 'ᇎ', + 'ㅫ' => 'ᇓ', + 'ㅬ' => 'ᇗ', + 'ㅭ' => 'ᇙ', + 'ㅮ' => 'ᄜ', + 'ㅯ' => 'ᇝ', + 'ㅰ' => 'ᇟ', + 'ㅱ' => 'ᄝ', + 'ㅲ' => 'ᄞ', + 'ㅳ' => 'ᄠ', + 'ㅴ' => 'ᄢ', + 'ㅵ' => 'ᄣ', + 'ㅶ' => 'ᄧ', + 'ㅷ' => 'ᄩ', + 'ㅸ' => 'ᄫ', + 'ㅹ' => 'ᄬ', + 'ㅺ' => 'ᄭ', + 'ㅻ' => 'ᄮ', + 'ㅼ' => 'ᄯ', + 'ㅽ' => 'ᄲ', + 'ㅾ' => 'ᄶ', + 'ㅿ' => 'ᅀ', + 'ㆀ' => 'ᅇ', + 'ㆁ' => 'ᅌ', + 'ㆂ' => 'ᇱ', + 'ㆃ' => 'ᇲ', + 'ㆄ' => 'ᅗ', + 'ㆅ' => 'ᅘ', + 'ㆆ' => 'ᅙ', + 'ㆇ' => 'ᆄ', + 'ㆈ' => 'ᆅ', + 'ㆉ' => 'ᆈ', + 'ㆊ' => 'ᆑ', + 'ㆋ' => 'ᆒ', + 'ㆌ' => 'ᆔ', + 'ㆍ' => 'ᆞ', + 'ㆎ' => 'ᆡ', + '㆒' => '一', + '㆓' => '二', + '㆔' => '三', + '㆕' => '四', + '㆖' => '上', + '㆗' => '中', + '㆘' => '下', + '㆙' => '甲', + '㆚' => '乙', + '㆛' => '丙', + '㆜' => '丁', + '㆝' => '天', + '㆞' => '地', + '㆟' => '人', + '㈀' => '(ᄀ)', + '㈁' => '(ᄂ)', + '㈂' => '(ᄃ)', + '㈃' => '(ᄅ)', + '㈄' => '(ᄆ)', + '㈅' => '(ᄇ)', + '㈆' => '(ᄉ)', + '㈇' => '(ᄋ)', + '㈈' => '(ᄌ)', + '㈉' => '(ᄎ)', + '㈊' => '(ᄏ)', + '㈋' => '(ᄐ)', + '㈌' => '(ᄑ)', + '㈍' => '(ᄒ)', + '㈎' => '(가)', + '㈏' => '(나)', + '㈐' => '(다)', + '㈑' => '(라)', + '㈒' => '(마)', + '㈓' => '(바)', + '㈔' => '(사)', + '㈕' => '(아)', + '㈖' => '(자)', + '㈗' => '(차)', + '㈘' => '(카)', + '㈙' => '(타)', + '㈚' => '(파)', + '㈛' => '(하)', + '㈜' => '(주)', + '㈝' => '(오전)', + '㈞' => '(오후)', + '㈠' => '(一)', + '㈡' => '(二)', + '㈢' => '(三)', + '㈣' => '(四)', + '㈤' => '(五)', + '㈥' => '(六)', + '㈦' => '(七)', + '㈧' => '(八)', + '㈨' => '(九)', + '㈩' => '(十)', + '㈪' => '(月)', + '㈫' => '(火)', + '㈬' => '(水)', + '㈭' => '(木)', + '㈮' => '(金)', + '㈯' => '(土)', + '㈰' => '(日)', + '㈱' => '(株)', + '㈲' => '(有)', + '㈳' => '(社)', + '㈴' => '(名)', + '㈵' => '(特)', + '㈶' => '(財)', + '㈷' => '(祝)', + '㈸' => '(労)', + '㈹' => '(代)', + '㈺' => '(呼)', + '㈻' => '(学)', + '㈼' => '(監)', + '㈽' => '(企)', + '㈾' => '(資)', + '㈿' => '(協)', + '㉀' => '(祭)', + '㉁' => '(休)', + '㉂' => '(自)', + '㉃' => '(至)', + '㉄' => '問', + '㉅' => '幼', + '㉆' => '文', + '㉇' => '箏', + '㉐' => 'PTE', + '㉑' => '21', + '㉒' => '22', + '㉓' => '23', + '㉔' => '24', + '㉕' => '25', + '㉖' => '26', + '㉗' => '27', + '㉘' => '28', + '㉙' => '29', + '㉚' => '30', + '㉛' => '31', + '㉜' => '32', + '㉝' => '33', + '㉞' => '34', + '㉟' => '35', + '㉠' => 'ᄀ', + '㉡' => 'ᄂ', + '㉢' => 'ᄃ', + '㉣' => 'ᄅ', + '㉤' => 'ᄆ', + '㉥' => 'ᄇ', + '㉦' => 'ᄉ', + '㉧' => 'ᄋ', + '㉨' => 'ᄌ', + '㉩' => 'ᄎ', + '㉪' => 'ᄏ', + '㉫' => 'ᄐ', + '㉬' => 'ᄑ', + '㉭' => 'ᄒ', + '㉮' => '가', + '㉯' => '나', + '㉰' => '다', + '㉱' => '라', + '㉲' => '마', + '㉳' => '바', + '㉴' => '사', + '㉵' => '아', + '㉶' => '자', + '㉷' => '차', + '㉸' => '카', + '㉹' => '타', + '㉺' => '파', + '㉻' => '하', + '㉼' => '참고', + '㉽' => '주의', + '㉾' => '우', + '㊀' => '一', + '㊁' => '二', + '㊂' => '三', + '㊃' => '四', + '㊄' => '五', + '㊅' => '六', + '㊆' => '七', + '㊇' => '八', + '㊈' => '九', + '㊉' => '十', + '㊊' => '月', + '㊋' => '火', + '㊌' => '水', + '㊍' => '木', + '㊎' => '金', + '㊏' => '土', + '㊐' => '日', + '㊑' => '株', + '㊒' => '有', + '㊓' => '社', + '㊔' => '名', + '㊕' => '特', + '㊖' => '財', + '㊗' => '祝', + '㊘' => '労', + '㊙' => '秘', + '㊚' => '男', + '㊛' => '女', + '㊜' => '適', + '㊝' => '優', + '㊞' => '印', + '㊟' => '注', + '㊠' => '項', + '㊡' => '休', + '㊢' => '写', + '㊣' => '正', + '㊤' => '上', + '㊥' => '中', + '㊦' => '下', + '㊧' => '左', + '㊨' => '右', + '㊩' => '医', + '㊪' => '宗', + '㊫' => '学', + '㊬' => '監', + '㊭' => '企', + '㊮' => '資', + '㊯' => '協', + '㊰' => '夜', + '㊱' => '36', + '㊲' => '37', + '㊳' => '38', + '㊴' => '39', + '㊵' => '40', + '㊶' => '41', + '㊷' => '42', + '㊸' => '43', + '㊹' => '44', + '㊺' => '45', + '㊻' => '46', + '㊼' => '47', + '㊽' => '48', + '㊾' => '49', + '㊿' => '50', + '㋀' => '1月', + '㋁' => '2月', + '㋂' => '3月', + '㋃' => '4月', + '㋄' => '5月', + '㋅' => '6月', + '㋆' => '7月', + '㋇' => '8月', + '㋈' => '9月', + '㋉' => '10月', + '㋊' => '11月', + '㋋' => '12月', + '㋌' => 'Hg', + '㋍' => 'erg', + '㋎' => 'eV', + '㋏' => 'LTD', + '㋐' => 'ア', + '㋑' => 'イ', + '㋒' => 'ウ', + '㋓' => 'エ', + '㋔' => 'オ', + '㋕' => 'カ', + '㋖' => 'キ', + '㋗' => 'ク', + '㋘' => 'ケ', + '㋙' => 'コ', + '㋚' => 'サ', + '㋛' => 'シ', + '㋜' => 'ス', + '㋝' => 'セ', + '㋞' => 'ソ', + '㋟' => 'タ', + '㋠' => 'チ', + '㋡' => 'ツ', + '㋢' => 'テ', + '㋣' => 'ト', + '㋤' => 'ナ', + '㋥' => 'ニ', + '㋦' => 'ヌ', + '㋧' => 'ネ', + '㋨' => 'ノ', + '㋩' => 'ハ', + '㋪' => 'ヒ', + '㋫' => 'フ', + '㋬' => 'ヘ', + '㋭' => 'ホ', + '㋮' => 'マ', + '㋯' => 'ミ', + '㋰' => 'ム', + '㋱' => 'メ', + '㋲' => 'モ', + '㋳' => 'ヤ', + '㋴' => 'ユ', + '㋵' => 'ヨ', + '㋶' => 'ラ', + '㋷' => 'リ', + '㋸' => 'ル', + '㋹' => 'レ', + '㋺' => 'ロ', + '㋻' => 'ワ', + '㋼' => 'ヰ', + '㋽' => 'ヱ', + '㋾' => 'ヲ', + '㋿' => '令和', + '㌀' => 'アパート', + '㌁' => 'アルファ', + '㌂' => 'アンペア', + '㌃' => 'アール', + '㌄' => 'イニング', + '㌅' => 'インチ', + '㌆' => 'ウォン', + '㌇' => 'エスクード', + '㌈' => 'エーカー', + '㌉' => 'オンス', + '㌊' => 'オーム', + '㌋' => 'カイリ', + '㌌' => 'カラット', + '㌍' => 'カロリー', + '㌎' => 'ガロン', + '㌏' => 'ガンマ', + '㌐' => 'ギガ', + '㌑' => 'ギニー', + '㌒' => 'キュリー', + '㌓' => 'ギルダー', + '㌔' => 'キロ', + '㌕' => 'キログラム', + '㌖' => 'キロメートル', + '㌗' => 'キロワット', + '㌘' => 'グラム', + '㌙' => 'グラムトン', + '㌚' => 'クルゼイロ', + '㌛' => 'クローネ', + '㌜' => 'ケース', + '㌝' => 'コルナ', + '㌞' => 'コーポ', + '㌟' => 'サイクル', + '㌠' => 'サンチーム', + '㌡' => 'シリング', + '㌢' => 'センチ', + '㌣' => 'セント', + '㌤' => 'ダース', + '㌥' => 'デシ', + '㌦' => 'ドル', + '㌧' => 'トン', + '㌨' => 'ナノ', + '㌩' => 'ノット', + '㌪' => 'ハイツ', + '㌫' => 'パーセント', + '㌬' => 'パーツ', + '㌭' => 'バーレル', + '㌮' => 'ピアストル', + '㌯' => 'ピクル', + '㌰' => 'ピコ', + '㌱' => 'ビル', + '㌲' => 'ファラッド', + '㌳' => 'フィート', + '㌴' => 'ブッシェル', + '㌵' => 'フラン', + '㌶' => 'ヘクタール', + '㌷' => 'ペソ', + '㌸' => 'ペニヒ', + '㌹' => 'ヘルツ', + '㌺' => 'ペンス', + '㌻' => 'ページ', + '㌼' => 'ベータ', + '㌽' => 'ポイント', + '㌾' => 'ボルト', + '㌿' => 'ホン', + '㍀' => 'ポンド', + '㍁' => 'ホール', + '㍂' => 'ホーン', + '㍃' => 'マイクロ', + '㍄' => 'マイル', + '㍅' => 'マッハ', + '㍆' => 'マルク', + '㍇' => 'マンション', + '㍈' => 'ミクロン', + '㍉' => 'ミリ', + '㍊' => 'ミリバール', + '㍋' => 'メガ', + '㍌' => 'メガトン', + '㍍' => 'メートル', + '㍎' => 'ヤード', + '㍏' => 'ヤール', + '㍐' => 'ユアン', + '㍑' => 'リットル', + '㍒' => 'リラ', + '㍓' => 'ルピー', + '㍔' => 'ルーブル', + '㍕' => 'レム', + '㍖' => 'レントゲン', + '㍗' => 'ワット', + '㍘' => '0点', + '㍙' => '1点', + '㍚' => '2点', + '㍛' => '3点', + '㍜' => '4点', + '㍝' => '5点', + '㍞' => '6点', + '㍟' => '7点', + '㍠' => '8点', + '㍡' => '9点', + '㍢' => '10点', + '㍣' => '11点', + '㍤' => '12点', + '㍥' => '13点', + '㍦' => '14点', + '㍧' => '15点', + '㍨' => '16点', + '㍩' => '17点', + '㍪' => '18点', + '㍫' => '19点', + '㍬' => '20点', + '㍭' => '21点', + '㍮' => '22点', + '㍯' => '23点', + '㍰' => '24点', + '㍱' => 'hPa', + '㍲' => 'da', + '㍳' => 'AU', + '㍴' => 'bar', + '㍵' => 'oV', + '㍶' => 'pc', + '㍷' => 'dm', + '㍸' => 'dm2', + '㍹' => 'dm3', + '㍺' => 'IU', + '㍻' => '平成', + '㍼' => '昭和', + '㍽' => '大正', + '㍾' => '明治', + '㍿' => '株式会社', + '㎀' => 'pA', + '㎁' => 'nA', + '㎂' => 'μA', + '㎃' => 'mA', + '㎄' => 'kA', + '㎅' => 'KB', + '㎆' => 'MB', + '㎇' => 'GB', + '㎈' => 'cal', + '㎉' => 'kcal', + '㎊' => 'pF', + '㎋' => 'nF', + '㎌' => 'μF', + '㎍' => 'μg', + '㎎' => 'mg', + '㎏' => 'kg', + '㎐' => 'Hz', + '㎑' => 'kHz', + '㎒' => 'MHz', + '㎓' => 'GHz', + '㎔' => 'THz', + '㎕' => 'μl', + '㎖' => 'ml', + '㎗' => 'dl', + '㎘' => 'kl', + '㎙' => 'fm', + '㎚' => 'nm', + '㎛' => 'μm', + '㎜' => 'mm', + '㎝' => 'cm', + '㎞' => 'km', + '㎟' => 'mm2', + '㎠' => 'cm2', + '㎡' => 'm2', + '㎢' => 'km2', + '㎣' => 'mm3', + '㎤' => 'cm3', + '㎥' => 'm3', + '㎦' => 'km3', + '㎧' => 'm∕s', + '㎨' => 'm∕s2', + '㎩' => 'Pa', + '㎪' => 'kPa', + '㎫' => 'MPa', + '㎬' => 'GPa', + '㎭' => 'rad', + '㎮' => 'rad∕s', + '㎯' => 'rad∕s2', + '㎰' => 'ps', + '㎱' => 'ns', + '㎲' => 'μs', + '㎳' => 'ms', + '㎴' => 'pV', + '㎵' => 'nV', + '㎶' => 'μV', + '㎷' => 'mV', + '㎸' => 'kV', + '㎹' => 'MV', + '㎺' => 'pW', + '㎻' => 'nW', + '㎼' => 'μW', + '㎽' => 'mW', + '㎾' => 'kW', + '㎿' => 'MW', + '㏀' => 'kΩ', + '㏁' => 'MΩ', + '㏂' => 'a.m.', + '㏃' => 'Bq', + '㏄' => 'cc', + '㏅' => 'cd', + '㏆' => 'C∕kg', + '㏇' => 'Co.', + '㏈' => 'dB', + '㏉' => 'Gy', + '㏊' => 'ha', + '㏋' => 'HP', + '㏌' => 'in', + '㏍' => 'KK', + '㏎' => 'KM', + '㏏' => 'kt', + '㏐' => 'lm', + '㏑' => 'ln', + '㏒' => 'log', + '㏓' => 'lx', + '㏔' => 'mb', + '㏕' => 'mil', + '㏖' => 'mol', + '㏗' => 'PH', + '㏘' => 'p.m.', + '㏙' => 'PPM', + '㏚' => 'PR', + '㏛' => 'sr', + '㏜' => 'Sv', + '㏝' => 'Wb', + '㏞' => 'V∕m', + '㏟' => 'A∕m', + '㏠' => '1日', + '㏡' => '2日', + '㏢' => '3日', + '㏣' => '4日', + '㏤' => '5日', + '㏥' => '6日', + '㏦' => '7日', + '㏧' => '8日', + '㏨' => '9日', + '㏩' => '10日', + '㏪' => '11日', + '㏫' => '12日', + '㏬' => '13日', + '㏭' => '14日', + '㏮' => '15日', + '㏯' => '16日', + '㏰' => '17日', + '㏱' => '18日', + '㏲' => '19日', + '㏳' => '20日', + '㏴' => '21日', + '㏵' => '22日', + '㏶' => '23日', + '㏷' => '24日', + '㏸' => '25日', + '㏹' => '26日', + '㏺' => '27日', + '㏻' => '28日', + '㏼' => '29日', + '㏽' => '30日', + '㏾' => '31日', + '㏿' => 'gal', + 'ꚜ' => 'ъ', + 'ꚝ' => 'ь', + 'ꝰ' => 'ꝯ', + 'ꟸ' => 'Ħ', + 'ꟹ' => 'œ', + 'ꭜ' => 'ꜧ', + 'ꭝ' => 'ꬷ', + 'ꭞ' => 'ɫ', + 'ꭟ' => 'ꭒ', + 'ꭩ' => 'ʍ', + 'ff' => 'ff', + 'fi' => 'fi', + 'fl' => 'fl', + 'ffi' => 'ffi', + 'ffl' => 'ffl', + 'ſt' => 'st', + 'st' => 'st', + 'ﬓ' => 'մն', + 'ﬔ' => 'մե', + 'ﬕ' => 'մի', + 'ﬖ' => 'վն', + 'ﬗ' => 'մխ', + 'ﬠ' => 'ע', + 'ﬡ' => 'א', + 'ﬢ' => 'ד', + 'ﬣ' => 'ה', + 'ﬤ' => 'כ', + 'ﬥ' => 'ל', + 'ﬦ' => 'ם', + 'ﬧ' => 'ר', + 'ﬨ' => 'ת', + '﬩' => '+', + 'ﭏ' => 'אל', + 'ﭐ' => 'ٱ', + 'ﭑ' => 'ٱ', + 'ﭒ' => 'ٻ', + 'ﭓ' => 'ٻ', + 'ﭔ' => 'ٻ', + 'ﭕ' => 'ٻ', + 'ﭖ' => 'پ', + 'ﭗ' => 'پ', + 'ﭘ' => 'پ', + 'ﭙ' => 'پ', + 'ﭚ' => 'ڀ', + 'ﭛ' => 'ڀ', + 'ﭜ' => 'ڀ', + 'ﭝ' => 'ڀ', + 'ﭞ' => 'ٺ', + 'ﭟ' => 'ٺ', + 'ﭠ' => 'ٺ', + 'ﭡ' => 'ٺ', + 'ﭢ' => 'ٿ', + 'ﭣ' => 'ٿ', + 'ﭤ' => 'ٿ', + 'ﭥ' => 'ٿ', + 'ﭦ' => 'ٹ', + 'ﭧ' => 'ٹ', + 'ﭨ' => 'ٹ', + 'ﭩ' => 'ٹ', + 'ﭪ' => 'ڤ', + 'ﭫ' => 'ڤ', + 'ﭬ' => 'ڤ', + 'ﭭ' => 'ڤ', + 'ﭮ' => 'ڦ', + 'ﭯ' => 'ڦ', + 'ﭰ' => 'ڦ', + 'ﭱ' => 'ڦ', + 'ﭲ' => 'ڄ', + 'ﭳ' => 'ڄ', + 'ﭴ' => 'ڄ', + 'ﭵ' => 'ڄ', + 'ﭶ' => 'ڃ', + 'ﭷ' => 'ڃ', + 'ﭸ' => 'ڃ', + 'ﭹ' => 'ڃ', + 'ﭺ' => 'چ', + 'ﭻ' => 'چ', + 'ﭼ' => 'چ', + 'ﭽ' => 'چ', + 'ﭾ' => 'ڇ', + 'ﭿ' => 'ڇ', + 'ﮀ' => 'ڇ', + 'ﮁ' => 'ڇ', + 'ﮂ' => 'ڍ', + 'ﮃ' => 'ڍ', + 'ﮄ' => 'ڌ', + 'ﮅ' => 'ڌ', + 'ﮆ' => 'ڎ', + 'ﮇ' => 'ڎ', + 'ﮈ' => 'ڈ', + 'ﮉ' => 'ڈ', + 'ﮊ' => 'ژ', + 'ﮋ' => 'ژ', + 'ﮌ' => 'ڑ', + 'ﮍ' => 'ڑ', + 'ﮎ' => 'ک', + 'ﮏ' => 'ک', + 'ﮐ' => 'ک', + 'ﮑ' => 'ک', + 'ﮒ' => 'گ', + 'ﮓ' => 'گ', + 'ﮔ' => 'گ', + 'ﮕ' => 'گ', + 'ﮖ' => 'ڳ', + 'ﮗ' => 'ڳ', + 'ﮘ' => 'ڳ', + 'ﮙ' => 'ڳ', + 'ﮚ' => 'ڱ', + 'ﮛ' => 'ڱ', + 'ﮜ' => 'ڱ', + 'ﮝ' => 'ڱ', + 'ﮞ' => 'ں', + 'ﮟ' => 'ں', + 'ﮠ' => 'ڻ', + 'ﮡ' => 'ڻ', + 'ﮢ' => 'ڻ', + 'ﮣ' => 'ڻ', + 'ﮤ' => 'ۀ', + 'ﮥ' => 'ۀ', + 'ﮦ' => 'ہ', + 'ﮧ' => 'ہ', + 'ﮨ' => 'ہ', + 'ﮩ' => 'ہ', + 'ﮪ' => 'ھ', + 'ﮫ' => 'ھ', + 'ﮬ' => 'ھ', + 'ﮭ' => 'ھ', + 'ﮮ' => 'ے', + 'ﮯ' => 'ے', + 'ﮰ' => 'ۓ', + 'ﮱ' => 'ۓ', + 'ﯓ' => 'ڭ', + 'ﯔ' => 'ڭ', + 'ﯕ' => 'ڭ', + 'ﯖ' => 'ڭ', + 'ﯗ' => 'ۇ', + 'ﯘ' => 'ۇ', + 'ﯙ' => 'ۆ', + 'ﯚ' => 'ۆ', + 'ﯛ' => 'ۈ', + 'ﯜ' => 'ۈ', + 'ﯝ' => 'ۇٴ', + 'ﯞ' => 'ۋ', + 'ﯟ' => 'ۋ', + 'ﯠ' => 'ۅ', + 'ﯡ' => 'ۅ', + 'ﯢ' => 'ۉ', + 'ﯣ' => 'ۉ', + 'ﯤ' => 'ې', + 'ﯥ' => 'ې', + 'ﯦ' => 'ې', + 'ﯧ' => 'ې', + 'ﯨ' => 'ى', + 'ﯩ' => 'ى', + 'ﯪ' => 'ئا', + 'ﯫ' => 'ئا', + 'ﯬ' => 'ئە', + 'ﯭ' => 'ئە', + 'ﯮ' => 'ئو', + 'ﯯ' => 'ئو', + 'ﯰ' => 'ئۇ', + 'ﯱ' => 'ئۇ', + 'ﯲ' => 'ئۆ', + 'ﯳ' => 'ئۆ', + 'ﯴ' => 'ئۈ', + 'ﯵ' => 'ئۈ', + 'ﯶ' => 'ئې', + 'ﯷ' => 'ئې', + 'ﯸ' => 'ئې', + 'ﯹ' => 'ئى', + 'ﯺ' => 'ئى', + 'ﯻ' => 'ئى', + 'ﯼ' => 'ی', + 'ﯽ' => 'ی', + 'ﯾ' => 'ی', + 'ﯿ' => 'ی', + 'ﰀ' => 'ئج', + 'ﰁ' => 'ئح', + 'ﰂ' => 'ئم', + 'ﰃ' => 'ئى', + 'ﰄ' => 'ئي', + 'ﰅ' => 'بج', + 'ﰆ' => 'بح', + 'ﰇ' => 'بخ', + 'ﰈ' => 'بم', + 'ﰉ' => 'بى', + 'ﰊ' => 'بي', + 'ﰋ' => 'تج', + 'ﰌ' => 'تح', + 'ﰍ' => 'تخ', + 'ﰎ' => 'تم', + 'ﰏ' => 'تى', + 'ﰐ' => 'تي', + 'ﰑ' => 'ثج', + 'ﰒ' => 'ثم', + 'ﰓ' => 'ثى', + 'ﰔ' => 'ثي', + 'ﰕ' => 'جح', + 'ﰖ' => 'جم', + 'ﰗ' => 'حج', + 'ﰘ' => 'حم', + 'ﰙ' => 'خج', + 'ﰚ' => 'خح', + 'ﰛ' => 'خم', + 'ﰜ' => 'سج', + 'ﰝ' => 'سح', + 'ﰞ' => 'سخ', + 'ﰟ' => 'سم', + 'ﰠ' => 'صح', + 'ﰡ' => 'صم', + 'ﰢ' => 'ضج', + 'ﰣ' => 'ضح', + 'ﰤ' => 'ضخ', + 'ﰥ' => 'ضم', + 'ﰦ' => 'طح', + 'ﰧ' => 'طم', + 'ﰨ' => 'ظم', + 'ﰩ' => 'عج', + 'ﰪ' => 'عم', + 'ﰫ' => 'غج', + 'ﰬ' => 'غم', + 'ﰭ' => 'فج', + 'ﰮ' => 'فح', + 'ﰯ' => 'فخ', + 'ﰰ' => 'فم', + 'ﰱ' => 'فى', + 'ﰲ' => 'في', + 'ﰳ' => 'قح', + 'ﰴ' => 'قم', + 'ﰵ' => 'قى', + 'ﰶ' => 'قي', + 'ﰷ' => 'كا', + 'ﰸ' => 'كج', + 'ﰹ' => 'كح', + 'ﰺ' => 'كخ', + 'ﰻ' => 'كل', + 'ﰼ' => 'كم', + 'ﰽ' => 'كى', + 'ﰾ' => 'كي', + 'ﰿ' => 'لج', + 'ﱀ' => 'لح', + 'ﱁ' => 'لخ', + 'ﱂ' => 'لم', + 'ﱃ' => 'لى', + 'ﱄ' => 'لي', + 'ﱅ' => 'مج', + 'ﱆ' => 'مح', + 'ﱇ' => 'مخ', + 'ﱈ' => 'مم', + 'ﱉ' => 'مى', + 'ﱊ' => 'مي', + 'ﱋ' => 'نج', + 'ﱌ' => 'نح', + 'ﱍ' => 'نخ', + 'ﱎ' => 'نم', + 'ﱏ' => 'نى', + 'ﱐ' => 'ني', + 'ﱑ' => 'هج', + 'ﱒ' => 'هم', + 'ﱓ' => 'هى', + 'ﱔ' => 'هي', + 'ﱕ' => 'يج', + 'ﱖ' => 'يح', + 'ﱗ' => 'يخ', + 'ﱘ' => 'يم', + 'ﱙ' => 'يى', + 'ﱚ' => 'يي', + 'ﱛ' => 'ذٰ', + 'ﱜ' => 'رٰ', + 'ﱝ' => 'ىٰ', + 'ﱞ' => ' ٌّ', + 'ﱟ' => ' ٍّ', + 'ﱠ' => ' َّ', + 'ﱡ' => ' ُّ', + 'ﱢ' => ' ِّ', + 'ﱣ' => ' ّٰ', + 'ﱤ' => 'ئر', + 'ﱥ' => 'ئز', + 'ﱦ' => 'ئم', + 'ﱧ' => 'ئن', + 'ﱨ' => 'ئى', + 'ﱩ' => 'ئي', + 'ﱪ' => 'بر', + 'ﱫ' => 'بز', + 'ﱬ' => 'بم', + 'ﱭ' => 'بن', + 'ﱮ' => 'بى', + 'ﱯ' => 'بي', + 'ﱰ' => 'تر', + 'ﱱ' => 'تز', + 'ﱲ' => 'تم', + 'ﱳ' => 'تن', + 'ﱴ' => 'تى', + 'ﱵ' => 'تي', + 'ﱶ' => 'ثر', + 'ﱷ' => 'ثز', + 'ﱸ' => 'ثم', + 'ﱹ' => 'ثن', + 'ﱺ' => 'ثى', + 'ﱻ' => 'ثي', + 'ﱼ' => 'فى', + 'ﱽ' => 'في', + 'ﱾ' => 'قى', + 'ﱿ' => 'قي', + 'ﲀ' => 'كا', + 'ﲁ' => 'كل', + 'ﲂ' => 'كم', + 'ﲃ' => 'كى', + 'ﲄ' => 'كي', + 'ﲅ' => 'لم', + 'ﲆ' => 'لى', + 'ﲇ' => 'لي', + 'ﲈ' => 'ما', + 'ﲉ' => 'مم', + 'ﲊ' => 'نر', + 'ﲋ' => 'نز', + 'ﲌ' => 'نم', + 'ﲍ' => 'نن', + 'ﲎ' => 'نى', + 'ﲏ' => 'ني', + 'ﲐ' => 'ىٰ', + 'ﲑ' => 'ير', + 'ﲒ' => 'يز', + 'ﲓ' => 'يم', + 'ﲔ' => 'ين', + 'ﲕ' => 'يى', + 'ﲖ' => 'يي', + 'ﲗ' => 'ئج', + 'ﲘ' => 'ئح', + 'ﲙ' => 'ئخ', + 'ﲚ' => 'ئم', + 'ﲛ' => 'ئه', + 'ﲜ' => 'بج', + 'ﲝ' => 'بح', + 'ﲞ' => 'بخ', + 'ﲟ' => 'بم', + 'ﲠ' => 'به', + 'ﲡ' => 'تج', + 'ﲢ' => 'تح', + 'ﲣ' => 'تخ', + 'ﲤ' => 'تم', + 'ﲥ' => 'ته', + 'ﲦ' => 'ثم', + 'ﲧ' => 'جح', + 'ﲨ' => 'جم', + 'ﲩ' => 'حج', + 'ﲪ' => 'حم', + 'ﲫ' => 'خج', + 'ﲬ' => 'خم', + 'ﲭ' => 'سج', + 'ﲮ' => 'سح', + 'ﲯ' => 'سخ', + 'ﲰ' => 'سم', + 'ﲱ' => 'صح', + 'ﲲ' => 'صخ', + 'ﲳ' => 'صم', + 'ﲴ' => 'ضج', + 'ﲵ' => 'ضح', + 'ﲶ' => 'ضخ', + 'ﲷ' => 'ضم', + 'ﲸ' => 'طح', + 'ﲹ' => 'ظم', + 'ﲺ' => 'عج', + 'ﲻ' => 'عم', + 'ﲼ' => 'غج', + 'ﲽ' => 'غم', + 'ﲾ' => 'فج', + 'ﲿ' => 'فح', + 'ﳀ' => 'فخ', + 'ﳁ' => 'فم', + 'ﳂ' => 'قح', + 'ﳃ' => 'قم', + 'ﳄ' => 'كج', + 'ﳅ' => 'كح', + 'ﳆ' => 'كخ', + 'ﳇ' => 'كل', + 'ﳈ' => 'كم', + 'ﳉ' => 'لج', + 'ﳊ' => 'لح', + 'ﳋ' => 'لخ', + 'ﳌ' => 'لم', + 'ﳍ' => 'له', + 'ﳎ' => 'مج', + 'ﳏ' => 'مح', + 'ﳐ' => 'مخ', + 'ﳑ' => 'مم', + 'ﳒ' => 'نج', + 'ﳓ' => 'نح', + 'ﳔ' => 'نخ', + 'ﳕ' => 'نم', + 'ﳖ' => 'نه', + 'ﳗ' => 'هج', + 'ﳘ' => 'هم', + 'ﳙ' => 'هٰ', + 'ﳚ' => 'يج', + 'ﳛ' => 'يح', + 'ﳜ' => 'يخ', + 'ﳝ' => 'يم', + 'ﳞ' => 'يه', + 'ﳟ' => 'ئم', + 'ﳠ' => 'ئه', + 'ﳡ' => 'بم', + 'ﳢ' => 'به', + 'ﳣ' => 'تم', + 'ﳤ' => 'ته', + 'ﳥ' => 'ثم', + 'ﳦ' => 'ثه', + 'ﳧ' => 'سم', + 'ﳨ' => 'سه', + 'ﳩ' => 'شم', + 'ﳪ' => 'شه', + 'ﳫ' => 'كل', + 'ﳬ' => 'كم', + 'ﳭ' => 'لم', + 'ﳮ' => 'نم', + 'ﳯ' => 'نه', + 'ﳰ' => 'يم', + 'ﳱ' => 'يه', + 'ﳲ' => 'ـَّ', + 'ﳳ' => 'ـُّ', + 'ﳴ' => 'ـِّ', + 'ﳵ' => 'طى', + 'ﳶ' => 'طي', + 'ﳷ' => 'عى', + 'ﳸ' => 'عي', + 'ﳹ' => 'غى', + 'ﳺ' => 'غي', + 'ﳻ' => 'سى', + 'ﳼ' => 'سي', + 'ﳽ' => 'شى', + 'ﳾ' => 'شي', + 'ﳿ' => 'حى', + 'ﴀ' => 'حي', + 'ﴁ' => 'جى', + 'ﴂ' => 'جي', + 'ﴃ' => 'خى', + 'ﴄ' => 'خي', + 'ﴅ' => 'صى', + 'ﴆ' => 'صي', + 'ﴇ' => 'ضى', + 'ﴈ' => 'ضي', + 'ﴉ' => 'شج', + 'ﴊ' => 'شح', + 'ﴋ' => 'شخ', + 'ﴌ' => 'شم', + 'ﴍ' => 'شر', + 'ﴎ' => 'سر', + 'ﴏ' => 'صر', + 'ﴐ' => 'ضر', + 'ﴑ' => 'طى', + 'ﴒ' => 'طي', + 'ﴓ' => 'عى', + 'ﴔ' => 'عي', + 'ﴕ' => 'غى', + 'ﴖ' => 'غي', + 'ﴗ' => 'سى', + 'ﴘ' => 'سي', + 'ﴙ' => 'شى', + 'ﴚ' => 'شي', + 'ﴛ' => 'حى', + 'ﴜ' => 'حي', + 'ﴝ' => 'جى', + 'ﴞ' => 'جي', + 'ﴟ' => 'خى', + 'ﴠ' => 'خي', + 'ﴡ' => 'صى', + 'ﴢ' => 'صي', + 'ﴣ' => 'ضى', + 'ﴤ' => 'ضي', + 'ﴥ' => 'شج', + 'ﴦ' => 'شح', + 'ﴧ' => 'شخ', + 'ﴨ' => 'شم', + 'ﴩ' => 'شر', + 'ﴪ' => 'سر', + 'ﴫ' => 'صر', + 'ﴬ' => 'ضر', + 'ﴭ' => 'شج', + 'ﴮ' => 'شح', + 'ﴯ' => 'شخ', + 'ﴰ' => 'شم', + 'ﴱ' => 'سه', + 'ﴲ' => 'شه', + 'ﴳ' => 'طم', + 'ﴴ' => 'سج', + 'ﴵ' => 'سح', + 'ﴶ' => 'سخ', + 'ﴷ' => 'شج', + 'ﴸ' => 'شح', + 'ﴹ' => 'شخ', + 'ﴺ' => 'طم', + 'ﴻ' => 'ظم', + 'ﴼ' => 'اً', + 'ﴽ' => 'اً', + 'ﵐ' => 'تجم', + 'ﵑ' => 'تحج', + 'ﵒ' => 'تحج', + 'ﵓ' => 'تحم', + 'ﵔ' => 'تخم', + 'ﵕ' => 'تمج', + 'ﵖ' => 'تمح', + 'ﵗ' => 'تمخ', + 'ﵘ' => 'جمح', + 'ﵙ' => 'جمح', + 'ﵚ' => 'حمي', + 'ﵛ' => 'حمى', + 'ﵜ' => 'سحج', + 'ﵝ' => 'سجح', + 'ﵞ' => 'سجى', + 'ﵟ' => 'سمح', + 'ﵠ' => 'سمح', + 'ﵡ' => 'سمج', + 'ﵢ' => 'سمم', + 'ﵣ' => 'سمم', + 'ﵤ' => 'صحح', + 'ﵥ' => 'صحح', + 'ﵦ' => 'صمم', + 'ﵧ' => 'شحم', + 'ﵨ' => 'شحم', + 'ﵩ' => 'شجي', + 'ﵪ' => 'شمخ', + 'ﵫ' => 'شمخ', + 'ﵬ' => 'شمم', + 'ﵭ' => 'شمم', + 'ﵮ' => 'ضحى', + 'ﵯ' => 'ضخم', + 'ﵰ' => 'ضخم', + 'ﵱ' => 'طمح', + 'ﵲ' => 'طمح', + 'ﵳ' => 'طمم', + 'ﵴ' => 'طمي', + 'ﵵ' => 'عجم', + 'ﵶ' => 'عمم', + 'ﵷ' => 'عمم', + 'ﵸ' => 'عمى', + 'ﵹ' => 'غمم', + 'ﵺ' => 'غمي', + 'ﵻ' => 'غمى', + 'ﵼ' => 'فخم', + 'ﵽ' => 'فخم', + 'ﵾ' => 'قمح', + 'ﵿ' => 'قمم', + 'ﶀ' => 'لحم', + 'ﶁ' => 'لحي', + 'ﶂ' => 'لحى', + 'ﶃ' => 'لجج', + 'ﶄ' => 'لجج', + 'ﶅ' => 'لخم', + 'ﶆ' => 'لخم', + 'ﶇ' => 'لمح', + 'ﶈ' => 'لمح', + 'ﶉ' => 'محج', + 'ﶊ' => 'محم', + 'ﶋ' => 'محي', + 'ﶌ' => 'مجح', + 'ﶍ' => 'مجم', + 'ﶎ' => 'مخج', + 'ﶏ' => 'مخم', + 'ﶒ' => 'مجخ', + 'ﶓ' => 'همج', + 'ﶔ' => 'همم', + 'ﶕ' => 'نحم', + 'ﶖ' => 'نحى', + 'ﶗ' => 'نجم', + 'ﶘ' => 'نجم', + 'ﶙ' => 'نجى', + 'ﶚ' => 'نمي', + 'ﶛ' => 'نمى', + 'ﶜ' => 'يمم', + 'ﶝ' => 'يمم', + 'ﶞ' => 'بخي', + 'ﶟ' => 'تجي', + 'ﶠ' => 'تجى', + 'ﶡ' => 'تخي', + 'ﶢ' => 'تخى', + 'ﶣ' => 'تمي', + 'ﶤ' => 'تمى', + 'ﶥ' => 'جمي', + 'ﶦ' => 'جحى', + 'ﶧ' => 'جمى', + 'ﶨ' => 'سخى', + 'ﶩ' => 'صحي', + 'ﶪ' => 'شحي', + 'ﶫ' => 'ضحي', + 'ﶬ' => 'لجي', + 'ﶭ' => 'لمي', + 'ﶮ' => 'يحي', + 'ﶯ' => 'يجي', + 'ﶰ' => 'يمي', + 'ﶱ' => 'ممي', + 'ﶲ' => 'قمي', + 'ﶳ' => 'نحي', + 'ﶴ' => 'قمح', + 'ﶵ' => 'لحم', + 'ﶶ' => 'عمي', + 'ﶷ' => 'كمي', + 'ﶸ' => 'نجح', + 'ﶹ' => 'مخي', + 'ﶺ' => 'لجم', + 'ﶻ' => 'كمم', + 'ﶼ' => 'لجم', + 'ﶽ' => 'نجح', + 'ﶾ' => 'جحي', + 'ﶿ' => 'حجي', + 'ﷀ' => 'مجي', + 'ﷁ' => 'فمي', + 'ﷂ' => 'بحي', + 'ﷃ' => 'كمم', + 'ﷄ' => 'عجم', + 'ﷅ' => 'صمم', + 'ﷆ' => 'سخي', + 'ﷇ' => 'نجي', + 'ﷰ' => 'صلے', + 'ﷱ' => 'قلے', + 'ﷲ' => 'الله', + 'ﷳ' => 'اكبر', + 'ﷴ' => 'محمد', + 'ﷵ' => 'صلعم', + 'ﷶ' => 'رسول', + 'ﷷ' => 'عليه', + 'ﷸ' => 'وسلم', + 'ﷹ' => 'صلى', + 'ﷺ' => 'صلى الله عليه وسلم', + 'ﷻ' => 'جل جلاله', + '﷼' => 'ریال', + '︐' => ',', + '︑' => '、', + '︒' => '。', + '︓' => ':', + '︔' => ';', + '︕' => '!', + '︖' => '?', + '︗' => '〖', + '︘' => '〗', + '︙' => '...', + '︰' => '..', + '︱' => '—', + '︲' => '–', + '︳' => '_', + '︴' => '_', + '︵' => '(', + '︶' => ')', + '︷' => '{', + '︸' => '}', + '︹' => '〔', + '︺' => '〕', + '︻' => '【', + '︼' => '】', + '︽' => '《', + '︾' => '》', + '︿' => '〈', + '﹀' => '〉', + '﹁' => '「', + '﹂' => '」', + '﹃' => '『', + '﹄' => '』', + '﹇' => '[', + '﹈' => ']', + '﹉' => ' ̅', + '﹊' => ' ̅', + '﹋' => ' ̅', + '﹌' => ' ̅', + '﹍' => '_', + '﹎' => '_', + '﹏' => '_', + '﹐' => ',', + '﹑' => '、', + '﹒' => '.', + '﹔' => ';', + '﹕' => ':', + '﹖' => '?', + '﹗' => '!', + '﹘' => '—', + '﹙' => '(', + '﹚' => ')', + '﹛' => '{', + '﹜' => '}', + '﹝' => '〔', + '﹞' => '〕', + '﹟' => '#', + '﹠' => '&', + '﹡' => '*', + '﹢' => '+', + '﹣' => '-', + '﹤' => '<', + '﹥' => '>', + '﹦' => '=', + '﹨' => '\\', + '﹩' => '$', + '﹪' => '%', + '﹫' => '@', + 'ﹰ' => ' ً', + 'ﹱ' => 'ـً', + 'ﹲ' => ' ٌ', + 'ﹴ' => ' ٍ', + 'ﹶ' => ' َ', + 'ﹷ' => 'ـَ', + 'ﹸ' => ' ُ', + 'ﹹ' => 'ـُ', + 'ﹺ' => ' ِ', + 'ﹻ' => 'ـِ', + 'ﹼ' => ' ّ', + 'ﹽ' => 'ـّ', + 'ﹾ' => ' ْ', + 'ﹿ' => 'ـْ', + 'ﺀ' => 'ء', + 'ﺁ' => 'آ', + 'ﺂ' => 'آ', + 'ﺃ' => 'أ', + 'ﺄ' => 'أ', + 'ﺅ' => 'ؤ', + 'ﺆ' => 'ؤ', + 'ﺇ' => 'إ', + 'ﺈ' => 'إ', + 'ﺉ' => 'ئ', + 'ﺊ' => 'ئ', + 'ﺋ' => 'ئ', + 'ﺌ' => 'ئ', + 'ﺍ' => 'ا', + 'ﺎ' => 'ا', + 'ﺏ' => 'ب', + 'ﺐ' => 'ب', + 'ﺑ' => 'ب', + 'ﺒ' => 'ب', + 'ﺓ' => 'ة', + 'ﺔ' => 'ة', + 'ﺕ' => 'ت', + 'ﺖ' => 'ت', + 'ﺗ' => 'ت', + 'ﺘ' => 'ت', + 'ﺙ' => 'ث', + 'ﺚ' => 'ث', + 'ﺛ' => 'ث', + 'ﺜ' => 'ث', + 'ﺝ' => 'ج', + 'ﺞ' => 'ج', + 'ﺟ' => 'ج', + 'ﺠ' => 'ج', + 'ﺡ' => 'ح', + 'ﺢ' => 'ح', + 'ﺣ' => 'ح', + 'ﺤ' => 'ح', + 'ﺥ' => 'خ', + 'ﺦ' => 'خ', + 'ﺧ' => 'خ', + 'ﺨ' => 'خ', + 'ﺩ' => 'د', + 'ﺪ' => 'د', + 'ﺫ' => 'ذ', + 'ﺬ' => 'ذ', + 'ﺭ' => 'ر', + 'ﺮ' => 'ر', + 'ﺯ' => 'ز', + 'ﺰ' => 'ز', + 'ﺱ' => 'س', + 'ﺲ' => 'س', + 'ﺳ' => 'س', + 'ﺴ' => 'س', + 'ﺵ' => 'ش', + 'ﺶ' => 'ش', + 'ﺷ' => 'ش', + 'ﺸ' => 'ش', + 'ﺹ' => 'ص', + 'ﺺ' => 'ص', + 'ﺻ' => 'ص', + 'ﺼ' => 'ص', + 'ﺽ' => 'ض', + 'ﺾ' => 'ض', + 'ﺿ' => 'ض', + 'ﻀ' => 'ض', + 'ﻁ' => 'ط', + 'ﻂ' => 'ط', + 'ﻃ' => 'ط', + 'ﻄ' => 'ط', + 'ﻅ' => 'ظ', + 'ﻆ' => 'ظ', + 'ﻇ' => 'ظ', + 'ﻈ' => 'ظ', + 'ﻉ' => 'ع', + 'ﻊ' => 'ع', + 'ﻋ' => 'ع', + 'ﻌ' => 'ع', + 'ﻍ' => 'غ', + 'ﻎ' => 'غ', + 'ﻏ' => 'غ', + 'ﻐ' => 'غ', + 'ﻑ' => 'ف', + 'ﻒ' => 'ف', + 'ﻓ' => 'ف', + 'ﻔ' => 'ف', + 'ﻕ' => 'ق', + 'ﻖ' => 'ق', + 'ﻗ' => 'ق', + 'ﻘ' => 'ق', + 'ﻙ' => 'ك', + 'ﻚ' => 'ك', + 'ﻛ' => 'ك', + 'ﻜ' => 'ك', + 'ﻝ' => 'ل', + 'ﻞ' => 'ل', + 'ﻟ' => 'ل', + 'ﻠ' => 'ل', + 'ﻡ' => 'م', + 'ﻢ' => 'م', + 'ﻣ' => 'م', + 'ﻤ' => 'م', + 'ﻥ' => 'ن', + 'ﻦ' => 'ن', + 'ﻧ' => 'ن', + 'ﻨ' => 'ن', + 'ﻩ' => 'ه', + 'ﻪ' => 'ه', + 'ﻫ' => 'ه', + 'ﻬ' => 'ه', + 'ﻭ' => 'و', + 'ﻮ' => 'و', + 'ﻯ' => 'ى', + 'ﻰ' => 'ى', + 'ﻱ' => 'ي', + 'ﻲ' => 'ي', + 'ﻳ' => 'ي', + 'ﻴ' => 'ي', + 'ﻵ' => 'لآ', + 'ﻶ' => 'لآ', + 'ﻷ' => 'لأ', + 'ﻸ' => 'لأ', + 'ﻹ' => 'لإ', + 'ﻺ' => 'لإ', + 'ﻻ' => 'لا', + 'ﻼ' => 'لا', + '!' => '!', + '"' => '"', + '#' => '#', + '$' => '$', + '%' => '%', + '&' => '&', + ''' => '\'', + '(' => '(', + ')' => ')', + '*' => '*', + '+' => '+', + ',' => ',', + '-' => '-', + '.' => '.', + '/' => '/', + '0' => '0', + '1' => '1', + '2' => '2', + '3' => '3', + '4' => '4', + '5' => '5', + '6' => '6', + '7' => '7', + '8' => '8', + '9' => '9', + ':' => ':', + ';' => ';', + '<' => '<', + '=' => '=', + '>' => '>', + '?' => '?', + '@' => '@', + 'A' => 'A', + 'B' => 'B', + 'C' => 'C', + 'D' => 'D', + 'E' => 'E', + 'F' => 'F', + 'G' => 'G', + 'H' => 'H', + 'I' => 'I', + 'J' => 'J', + 'K' => 'K', + 'L' => 'L', + 'M' => 'M', + 'N' => 'N', + 'O' => 'O', + 'P' => 'P', + 'Q' => 'Q', + 'R' => 'R', + 'S' => 'S', + 'T' => 'T', + 'U' => 'U', + 'V' => 'V', + 'W' => 'W', + 'X' => 'X', + 'Y' => 'Y', + 'Z' => 'Z', + '[' => '[', + '\' => '\\', + ']' => ']', + '^' => '^', + '_' => '_', + '`' => '`', + 'a' => 'a', + 'b' => 'b', + 'c' => 'c', + 'd' => 'd', + 'e' => 'e', + 'f' => 'f', + 'g' => 'g', + 'h' => 'h', + 'i' => 'i', + 'j' => 'j', + 'k' => 'k', + 'l' => 'l', + 'm' => 'm', + 'n' => 'n', + 'o' => 'o', + 'p' => 'p', + 'q' => 'q', + 'r' => 'r', + 's' => 's', + 't' => 't', + 'u' => 'u', + 'v' => 'v', + 'w' => 'w', + 'x' => 'x', + 'y' => 'y', + 'z' => 'z', + '{' => '{', + '|' => '|', + '}' => '}', + '~' => '~', + '⦅' => '⦅', + '⦆' => '⦆', + '。' => '。', + '「' => '「', + '」' => '」', + '、' => '、', + '・' => '・', + 'ヲ' => 'ヲ', + 'ァ' => 'ァ', + 'ィ' => 'ィ', + 'ゥ' => 'ゥ', + 'ェ' => 'ェ', + 'ォ' => 'ォ', + 'ャ' => 'ャ', + 'ュ' => 'ュ', + 'ョ' => 'ョ', + 'ッ' => 'ッ', + 'ー' => 'ー', + 'ア' => 'ア', + 'イ' => 'イ', + 'ウ' => 'ウ', + 'エ' => 'エ', + 'オ' => 'オ', + 'カ' => 'カ', + 'キ' => 'キ', + 'ク' => 'ク', + 'ケ' => 'ケ', + 'コ' => 'コ', + 'サ' => 'サ', + 'シ' => 'シ', + 'ス' => 'ス', + 'セ' => 'セ', + 'ソ' => 'ソ', + 'タ' => 'タ', + 'チ' => 'チ', + 'ツ' => 'ツ', + 'テ' => 'テ', + 'ト' => 'ト', + 'ナ' => 'ナ', + 'ニ' => 'ニ', + 'ヌ' => 'ヌ', + 'ネ' => 'ネ', + 'ノ' => 'ノ', + 'ハ' => 'ハ', + 'ヒ' => 'ヒ', + 'フ' => 'フ', + 'ヘ' => 'ヘ', + 'ホ' => 'ホ', + 'マ' => 'マ', + 'ミ' => 'ミ', + 'ム' => 'ム', + 'メ' => 'メ', + 'モ' => 'モ', + 'ヤ' => 'ヤ', + 'ユ' => 'ユ', + 'ヨ' => 'ヨ', + 'ラ' => 'ラ', + 'リ' => 'リ', + 'ル' => 'ル', + 'レ' => 'レ', + 'ロ' => 'ロ', + 'ワ' => 'ワ', + 'ン' => 'ン', + '゙' => '゙', + '゚' => '゚', + 'ᅠ' => 'ᅠ', + 'ᄀ' => 'ᄀ', + 'ᄁ' => 'ᄁ', + 'ᆪ' => 'ᆪ', + 'ᄂ' => 'ᄂ', + 'ᆬ' => 'ᆬ', + 'ᆭ' => 'ᆭ', + 'ᄃ' => 'ᄃ', + 'ᄄ' => 'ᄄ', + 'ᄅ' => 'ᄅ', + 'ᆰ' => 'ᆰ', + 'ᆱ' => 'ᆱ', + 'ᆲ' => 'ᆲ', + 'ᆳ' => 'ᆳ', + 'ᆴ' => 'ᆴ', + 'ᆵ' => 'ᆵ', + 'ᄚ' => 'ᄚ', + 'ᄆ' => 'ᄆ', + 'ᄇ' => 'ᄇ', + 'ᄈ' => 'ᄈ', + 'ᄡ' => 'ᄡ', + 'ᄉ' => 'ᄉ', + 'ᄊ' => 'ᄊ', + 'ᄋ' => 'ᄋ', + 'ᄌ' => 'ᄌ', + 'ᄍ' => 'ᄍ', + 'ᄎ' => 'ᄎ', + 'ᄏ' => 'ᄏ', + 'ᄐ' => 'ᄐ', + 'ᄑ' => 'ᄑ', + 'ᄒ' => 'ᄒ', + 'ᅡ' => 'ᅡ', + 'ᅢ' => 'ᅢ', + 'ᅣ' => 'ᅣ', + 'ᅤ' => 'ᅤ', + 'ᅥ' => 'ᅥ', + 'ᅦ' => 'ᅦ', + 'ᅧ' => 'ᅧ', + 'ᅨ' => 'ᅨ', + 'ᅩ' => 'ᅩ', + 'ᅪ' => 'ᅪ', + 'ᅫ' => 'ᅫ', + 'ᅬ' => 'ᅬ', + 'ᅭ' => 'ᅭ', + 'ᅮ' => 'ᅮ', + 'ᅯ' => 'ᅯ', + 'ᅰ' => 'ᅰ', + 'ᅱ' => 'ᅱ', + 'ᅲ' => 'ᅲ', + 'ᅳ' => 'ᅳ', + 'ᅴ' => 'ᅴ', + 'ᅵ' => 'ᅵ', + '¢' => '¢', + '£' => '£', + '¬' => '¬', + ' ̄' => ' ̄', + '¦' => '¦', + '¥' => '¥', + '₩' => '₩', + '│' => '│', + '←' => '←', + '↑' => '↑', + '→' => '→', + '↓' => '↓', + '■' => '■', + '○' => '○', + '𝐀' => 'A', + '𝐁' => 'B', + '𝐂' => 'C', + '𝐃' => 'D', + '𝐄' => 'E', + '𝐅' => 'F', + '𝐆' => 'G', + '𝐇' => 'H', + '𝐈' => 'I', + '𝐉' => 'J', + '𝐊' => 'K', + '𝐋' => 'L', + '𝐌' => 'M', + '𝐍' => 'N', + '𝐎' => 'O', + '𝐏' => 'P', + '𝐐' => 'Q', + '𝐑' => 'R', + '𝐒' => 'S', + '𝐓' => 'T', + '𝐔' => 'U', + '𝐕' => 'V', + '𝐖' => 'W', + '𝐗' => 'X', + '𝐘' => 'Y', + '𝐙' => 'Z', + '𝐚' => 'a', + '𝐛' => 'b', + '𝐜' => 'c', + '𝐝' => 'd', + '𝐞' => 'e', + '𝐟' => 'f', + '𝐠' => 'g', + '𝐡' => 'h', + '𝐢' => 'i', + '𝐣' => 'j', + '𝐤' => 'k', + '𝐥' => 'l', + '𝐦' => 'm', + '𝐧' => 'n', + '𝐨' => 'o', + '𝐩' => 'p', + '𝐪' => 'q', + '𝐫' => 'r', + '𝐬' => 's', + '𝐭' => 't', + '𝐮' => 'u', + '𝐯' => 'v', + '𝐰' => 'w', + '𝐱' => 'x', + '𝐲' => 'y', + '𝐳' => 'z', + '𝐴' => 'A', + '𝐵' => 'B', + '𝐶' => 'C', + '𝐷' => 'D', + '𝐸' => 'E', + '𝐹' => 'F', + '𝐺' => 'G', + '𝐻' => 'H', + '𝐼' => 'I', + '𝐽' => 'J', + '𝐾' => 'K', + '𝐿' => 'L', + '𝑀' => 'M', + '𝑁' => 'N', + '𝑂' => 'O', + '𝑃' => 'P', + '𝑄' => 'Q', + '𝑅' => 'R', + '𝑆' => 'S', + '𝑇' => 'T', + '𝑈' => 'U', + '𝑉' => 'V', + '𝑊' => 'W', + '𝑋' => 'X', + '𝑌' => 'Y', + '𝑍' => 'Z', + '𝑎' => 'a', + '𝑏' => 'b', + '𝑐' => 'c', + '𝑑' => 'd', + '𝑒' => 'e', + '𝑓' => 'f', + '𝑔' => 'g', + '𝑖' => 'i', + '𝑗' => 'j', + '𝑘' => 'k', + '𝑙' => 'l', + '𝑚' => 'm', + '𝑛' => 'n', + '𝑜' => 'o', + '𝑝' => 'p', + '𝑞' => 'q', + '𝑟' => 'r', + '𝑠' => 's', + '𝑡' => 't', + '𝑢' => 'u', + '𝑣' => 'v', + '𝑤' => 'w', + '𝑥' => 'x', + '𝑦' => 'y', + '𝑧' => 'z', + '𝑨' => 'A', + '𝑩' => 'B', + '𝑪' => 'C', + '𝑫' => 'D', + '𝑬' => 'E', + '𝑭' => 'F', + '𝑮' => 'G', + '𝑯' => 'H', + '𝑰' => 'I', + '𝑱' => 'J', + '𝑲' => 'K', + '𝑳' => 'L', + '𝑴' => 'M', + '𝑵' => 'N', + '𝑶' => 'O', + '𝑷' => 'P', + '𝑸' => 'Q', + '𝑹' => 'R', + '𝑺' => 'S', + '𝑻' => 'T', + '𝑼' => 'U', + '𝑽' => 'V', + '𝑾' => 'W', + '𝑿' => 'X', + '𝒀' => 'Y', + '𝒁' => 'Z', + '𝒂' => 'a', + '𝒃' => 'b', + '𝒄' => 'c', + '𝒅' => 'd', + '𝒆' => 'e', + '𝒇' => 'f', + '𝒈' => 'g', + '𝒉' => 'h', + '𝒊' => 'i', + '𝒋' => 'j', + '𝒌' => 'k', + '𝒍' => 'l', + '𝒎' => 'm', + '𝒏' => 'n', + '𝒐' => 'o', + '𝒑' => 'p', + '𝒒' => 'q', + '𝒓' => 'r', + '𝒔' => 's', + '𝒕' => 't', + '𝒖' => 'u', + '𝒗' => 'v', + '𝒘' => 'w', + '𝒙' => 'x', + '𝒚' => 'y', + '𝒛' => 'z', + '𝒜' => 'A', + '𝒞' => 'C', + '𝒟' => 'D', + '𝒢' => 'G', + '𝒥' => 'J', + '𝒦' => 'K', + '𝒩' => 'N', + '𝒪' => 'O', + '𝒫' => 'P', + '𝒬' => 'Q', + '𝒮' => 'S', + '𝒯' => 'T', + '𝒰' => 'U', + '𝒱' => 'V', + '𝒲' => 'W', + '𝒳' => 'X', + '𝒴' => 'Y', + '𝒵' => 'Z', + '𝒶' => 'a', + '𝒷' => 'b', + '𝒸' => 'c', + '𝒹' => 'd', + '𝒻' => 'f', + '𝒽' => 'h', + '𝒾' => 'i', + '𝒿' => 'j', + '𝓀' => 'k', + '𝓁' => 'l', + '𝓂' => 'm', + '𝓃' => 'n', + '𝓅' => 'p', + '𝓆' => 'q', + '𝓇' => 'r', + '𝓈' => 's', + '𝓉' => 't', + '𝓊' => 'u', + '𝓋' => 'v', + '𝓌' => 'w', + '𝓍' => 'x', + '𝓎' => 'y', + '𝓏' => 'z', + '𝓐' => 'A', + '𝓑' => 'B', + '𝓒' => 'C', + '𝓓' => 'D', + '𝓔' => 'E', + '𝓕' => 'F', + '𝓖' => 'G', + '𝓗' => 'H', + '𝓘' => 'I', + '𝓙' => 'J', + '𝓚' => 'K', + '𝓛' => 'L', + '𝓜' => 'M', + '𝓝' => 'N', + '𝓞' => 'O', + '𝓟' => 'P', + '𝓠' => 'Q', + '𝓡' => 'R', + '𝓢' => 'S', + '𝓣' => 'T', + '𝓤' => 'U', + '𝓥' => 'V', + '𝓦' => 'W', + '𝓧' => 'X', + '𝓨' => 'Y', + '𝓩' => 'Z', + '𝓪' => 'a', + '𝓫' => 'b', + '𝓬' => 'c', + '𝓭' => 'd', + '𝓮' => 'e', + '𝓯' => 'f', + '𝓰' => 'g', + '𝓱' => 'h', + '𝓲' => 'i', + '𝓳' => 'j', + '𝓴' => 'k', + '𝓵' => 'l', + '𝓶' => 'm', + '𝓷' => 'n', + '𝓸' => 'o', + '𝓹' => 'p', + '𝓺' => 'q', + '𝓻' => 'r', + '𝓼' => 's', + '𝓽' => 't', + '𝓾' => 'u', + '𝓿' => 'v', + '𝔀' => 'w', + '𝔁' => 'x', + '𝔂' => 'y', + '𝔃' => 'z', + '𝔄' => 'A', + '𝔅' => 'B', + '𝔇' => 'D', + '𝔈' => 'E', + '𝔉' => 'F', + '𝔊' => 'G', + '𝔍' => 'J', + '𝔎' => 'K', + '𝔏' => 'L', + '𝔐' => 'M', + '𝔑' => 'N', + '𝔒' => 'O', + '𝔓' => 'P', + '𝔔' => 'Q', + '𝔖' => 'S', + '𝔗' => 'T', + '𝔘' => 'U', + '𝔙' => 'V', + '𝔚' => 'W', + '𝔛' => 'X', + '𝔜' => 'Y', + '𝔞' => 'a', + '𝔟' => 'b', + '𝔠' => 'c', + '𝔡' => 'd', + '𝔢' => 'e', + '𝔣' => 'f', + '𝔤' => 'g', + '𝔥' => 'h', + '𝔦' => 'i', + '𝔧' => 'j', + '𝔨' => 'k', + '𝔩' => 'l', + '𝔪' => 'm', + '𝔫' => 'n', + '𝔬' => 'o', + '𝔭' => 'p', + '𝔮' => 'q', + '𝔯' => 'r', + '𝔰' => 's', + '𝔱' => 't', + '𝔲' => 'u', + '𝔳' => 'v', + '𝔴' => 'w', + '𝔵' => 'x', + '𝔶' => 'y', + '𝔷' => 'z', + '𝔸' => 'A', + '𝔹' => 'B', + '𝔻' => 'D', + '𝔼' => 'E', + '𝔽' => 'F', + '𝔾' => 'G', + '𝕀' => 'I', + '𝕁' => 'J', + '𝕂' => 'K', + '𝕃' => 'L', + '𝕄' => 'M', + '𝕆' => 'O', + '𝕊' => 'S', + '𝕋' => 'T', + '𝕌' => 'U', + '𝕍' => 'V', + '𝕎' => 'W', + '𝕏' => 'X', + '𝕐' => 'Y', + '𝕒' => 'a', + '𝕓' => 'b', + '𝕔' => 'c', + '𝕕' => 'd', + '𝕖' => 'e', + '𝕗' => 'f', + '𝕘' => 'g', + '𝕙' => 'h', + '𝕚' => 'i', + '𝕛' => 'j', + '𝕜' => 'k', + '𝕝' => 'l', + '𝕞' => 'm', + '𝕟' => 'n', + '𝕠' => 'o', + '𝕡' => 'p', + '𝕢' => 'q', + '𝕣' => 'r', + '𝕤' => 's', + '𝕥' => 't', + '𝕦' => 'u', + '𝕧' => 'v', + '𝕨' => 'w', + '𝕩' => 'x', + '𝕪' => 'y', + '𝕫' => 'z', + '𝕬' => 'A', + '𝕭' => 'B', + '𝕮' => 'C', + '𝕯' => 'D', + '𝕰' => 'E', + '𝕱' => 'F', + '𝕲' => 'G', + '𝕳' => 'H', + '𝕴' => 'I', + '𝕵' => 'J', + '𝕶' => 'K', + '𝕷' => 'L', + '𝕸' => 'M', + '𝕹' => 'N', + '𝕺' => 'O', + '𝕻' => 'P', + '𝕼' => 'Q', + '𝕽' => 'R', + '𝕾' => 'S', + '𝕿' => 'T', + '𝖀' => 'U', + '𝖁' => 'V', + '𝖂' => 'W', + '𝖃' => 'X', + '𝖄' => 'Y', + '𝖅' => 'Z', + '𝖆' => 'a', + '𝖇' => 'b', + '𝖈' => 'c', + '𝖉' => 'd', + '𝖊' => 'e', + '𝖋' => 'f', + '𝖌' => 'g', + '𝖍' => 'h', + '𝖎' => 'i', + '𝖏' => 'j', + '𝖐' => 'k', + '𝖑' => 'l', + '𝖒' => 'm', + '𝖓' => 'n', + '𝖔' => 'o', + '𝖕' => 'p', + '𝖖' => 'q', + '𝖗' => 'r', + '𝖘' => 's', + '𝖙' => 't', + '𝖚' => 'u', + '𝖛' => 'v', + '𝖜' => 'w', + '𝖝' => 'x', + '𝖞' => 'y', + '𝖟' => 'z', + '𝖠' => 'A', + '𝖡' => 'B', + '𝖢' => 'C', + '𝖣' => 'D', + '𝖤' => 'E', + '𝖥' => 'F', + '𝖦' => 'G', + '𝖧' => 'H', + '𝖨' => 'I', + '𝖩' => 'J', + '𝖪' => 'K', + '𝖫' => 'L', + '𝖬' => 'M', + '𝖭' => 'N', + '𝖮' => 'O', + '𝖯' => 'P', + '𝖰' => 'Q', + '𝖱' => 'R', + '𝖲' => 'S', + '𝖳' => 'T', + '𝖴' => 'U', + '𝖵' => 'V', + '𝖶' => 'W', + '𝖷' => 'X', + '𝖸' => 'Y', + '𝖹' => 'Z', + '𝖺' => 'a', + '𝖻' => 'b', + '𝖼' => 'c', + '𝖽' => 'd', + '𝖾' => 'e', + '𝖿' => 'f', + '𝗀' => 'g', + '𝗁' => 'h', + '𝗂' => 'i', + '𝗃' => 'j', + '𝗄' => 'k', + '𝗅' => 'l', + '𝗆' => 'm', + '𝗇' => 'n', + '𝗈' => 'o', + '𝗉' => 'p', + '𝗊' => 'q', + '𝗋' => 'r', + '𝗌' => 's', + '𝗍' => 't', + '𝗎' => 'u', + '𝗏' => 'v', + '𝗐' => 'w', + '𝗑' => 'x', + '𝗒' => 'y', + '𝗓' => 'z', + '𝗔' => 'A', + '𝗕' => 'B', + '𝗖' => 'C', + '𝗗' => 'D', + '𝗘' => 'E', + '𝗙' => 'F', + '𝗚' => 'G', + '𝗛' => 'H', + '𝗜' => 'I', + '𝗝' => 'J', + '𝗞' => 'K', + '𝗟' => 'L', + '𝗠' => 'M', + '𝗡' => 'N', + '𝗢' => 'O', + '𝗣' => 'P', + '𝗤' => 'Q', + '𝗥' => 'R', + '𝗦' => 'S', + '𝗧' => 'T', + '𝗨' => 'U', + '𝗩' => 'V', + '𝗪' => 'W', + '𝗫' => 'X', + '𝗬' => 'Y', + '𝗭' => 'Z', + '𝗮' => 'a', + '𝗯' => 'b', + '𝗰' => 'c', + '𝗱' => 'd', + '𝗲' => 'e', + '𝗳' => 'f', + '𝗴' => 'g', + '𝗵' => 'h', + '𝗶' => 'i', + '𝗷' => 'j', + '𝗸' => 'k', + '𝗹' => 'l', + '𝗺' => 'm', + '𝗻' => 'n', + '𝗼' => 'o', + '𝗽' => 'p', + '𝗾' => 'q', + '𝗿' => 'r', + '𝘀' => 's', + '𝘁' => 't', + '𝘂' => 'u', + '𝘃' => 'v', + '𝘄' => 'w', + '𝘅' => 'x', + '𝘆' => 'y', + '𝘇' => 'z', + '𝘈' => 'A', + '𝘉' => 'B', + '𝘊' => 'C', + '𝘋' => 'D', + '𝘌' => 'E', + '𝘍' => 'F', + '𝘎' => 'G', + '𝘏' => 'H', + '𝘐' => 'I', + '𝘑' => 'J', + '𝘒' => 'K', + '𝘓' => 'L', + '𝘔' => 'M', + '𝘕' => 'N', + '𝘖' => 'O', + '𝘗' => 'P', + '𝘘' => 'Q', + '𝘙' => 'R', + '𝘚' => 'S', + '𝘛' => 'T', + '𝘜' => 'U', + '𝘝' => 'V', + '𝘞' => 'W', + '𝘟' => 'X', + '𝘠' => 'Y', + '𝘡' => 'Z', + '𝘢' => 'a', + '𝘣' => 'b', + '𝘤' => 'c', + '𝘥' => 'd', + '𝘦' => 'e', + '𝘧' => 'f', + '𝘨' => 'g', + '𝘩' => 'h', + '𝘪' => 'i', + '𝘫' => 'j', + '𝘬' => 'k', + '𝘭' => 'l', + '𝘮' => 'm', + '𝘯' => 'n', + '𝘰' => 'o', + '𝘱' => 'p', + '𝘲' => 'q', + '𝘳' => 'r', + '𝘴' => 's', + '𝘵' => 't', + '𝘶' => 'u', + '𝘷' => 'v', + '𝘸' => 'w', + '𝘹' => 'x', + '𝘺' => 'y', + '𝘻' => 'z', + '𝘼' => 'A', + '𝘽' => 'B', + '𝘾' => 'C', + '𝘿' => 'D', + '𝙀' => 'E', + '𝙁' => 'F', + '𝙂' => 'G', + '𝙃' => 'H', + '𝙄' => 'I', + '𝙅' => 'J', + '𝙆' => 'K', + '𝙇' => 'L', + '𝙈' => 'M', + '𝙉' => 'N', + '𝙊' => 'O', + '𝙋' => 'P', + '𝙌' => 'Q', + '𝙍' => 'R', + '𝙎' => 'S', + '𝙏' => 'T', + '𝙐' => 'U', + '𝙑' => 'V', + '𝙒' => 'W', + '𝙓' => 'X', + '𝙔' => 'Y', + '𝙕' => 'Z', + '𝙖' => 'a', + '𝙗' => 'b', + '𝙘' => 'c', + '𝙙' => 'd', + '𝙚' => 'e', + '𝙛' => 'f', + '𝙜' => 'g', + '𝙝' => 'h', + '𝙞' => 'i', + '𝙟' => 'j', + '𝙠' => 'k', + '𝙡' => 'l', + '𝙢' => 'm', + '𝙣' => 'n', + '𝙤' => 'o', + '𝙥' => 'p', + '𝙦' => 'q', + '𝙧' => 'r', + '𝙨' => 's', + '𝙩' => 't', + '𝙪' => 'u', + '𝙫' => 'v', + '𝙬' => 'w', + '𝙭' => 'x', + '𝙮' => 'y', + '𝙯' => 'z', + '𝙰' => 'A', + '𝙱' => 'B', + '𝙲' => 'C', + '𝙳' => 'D', + '𝙴' => 'E', + '𝙵' => 'F', + '𝙶' => 'G', + '𝙷' => 'H', + '𝙸' => 'I', + '𝙹' => 'J', + '𝙺' => 'K', + '𝙻' => 'L', + '𝙼' => 'M', + '𝙽' => 'N', + '𝙾' => 'O', + '𝙿' => 'P', + '𝚀' => 'Q', + '𝚁' => 'R', + '𝚂' => 'S', + '𝚃' => 'T', + '𝚄' => 'U', + '𝚅' => 'V', + '𝚆' => 'W', + '𝚇' => 'X', + '𝚈' => 'Y', + '𝚉' => 'Z', + '𝚊' => 'a', + '𝚋' => 'b', + '𝚌' => 'c', + '𝚍' => 'd', + '𝚎' => 'e', + '𝚏' => 'f', + '𝚐' => 'g', + '𝚑' => 'h', + '𝚒' => 'i', + '𝚓' => 'j', + '𝚔' => 'k', + '𝚕' => 'l', + '𝚖' => 'm', + '𝚗' => 'n', + '𝚘' => 'o', + '𝚙' => 'p', + '𝚚' => 'q', + '𝚛' => 'r', + '𝚜' => 's', + '𝚝' => 't', + '𝚞' => 'u', + '𝚟' => 'v', + '𝚠' => 'w', + '𝚡' => 'x', + '𝚢' => 'y', + '𝚣' => 'z', + '𝚤' => 'ı', + '𝚥' => 'ȷ', + '𝚨' => 'Α', + '𝚩' => 'Β', + '𝚪' => 'Γ', + '𝚫' => 'Δ', + '𝚬' => 'Ε', + '𝚭' => 'Ζ', + '𝚮' => 'Η', + '𝚯' => 'Θ', + '𝚰' => 'Ι', + '𝚱' => 'Κ', + '𝚲' => 'Λ', + '𝚳' => 'Μ', + '𝚴' => 'Ν', + '𝚵' => 'Ξ', + '𝚶' => 'Ο', + '𝚷' => 'Π', + '𝚸' => 'Ρ', + '𝚹' => 'Θ', + '𝚺' => 'Σ', + '𝚻' => 'Τ', + '𝚼' => 'Υ', + '𝚽' => 'Φ', + '𝚾' => 'Χ', + '𝚿' => 'Ψ', + '𝛀' => 'Ω', + '𝛁' => '∇', + '𝛂' => 'α', + '𝛃' => 'β', + '𝛄' => 'γ', + '𝛅' => 'δ', + '𝛆' => 'ε', + '𝛇' => 'ζ', + '𝛈' => 'η', + '𝛉' => 'θ', + '𝛊' => 'ι', + '𝛋' => 'κ', + '𝛌' => 'λ', + '𝛍' => 'μ', + '𝛎' => 'ν', + '𝛏' => 'ξ', + '𝛐' => 'ο', + '𝛑' => 'π', + '𝛒' => 'ρ', + '𝛓' => 'ς', + '𝛔' => 'σ', + '𝛕' => 'τ', + '𝛖' => 'υ', + '𝛗' => 'φ', + '𝛘' => 'χ', + '𝛙' => 'ψ', + '𝛚' => 'ω', + '𝛛' => '∂', + '𝛜' => 'ε', + '𝛝' => 'θ', + '𝛞' => 'κ', + '𝛟' => 'φ', + '𝛠' => 'ρ', + '𝛡' => 'π', + '𝛢' => 'Α', + '𝛣' => 'Β', + '𝛤' => 'Γ', + '𝛥' => 'Δ', + '𝛦' => 'Ε', + '𝛧' => 'Ζ', + '𝛨' => 'Η', + '𝛩' => 'Θ', + '𝛪' => 'Ι', + '𝛫' => 'Κ', + '𝛬' => 'Λ', + '𝛭' => 'Μ', + '𝛮' => 'Ν', + '𝛯' => 'Ξ', + '𝛰' => 'Ο', + '𝛱' => 'Π', + '𝛲' => 'Ρ', + '𝛳' => 'Θ', + '𝛴' => 'Σ', + '𝛵' => 'Τ', + '𝛶' => 'Υ', + '𝛷' => 'Φ', + '𝛸' => 'Χ', + '𝛹' => 'Ψ', + '𝛺' => 'Ω', + '𝛻' => '∇', + '𝛼' => 'α', + '𝛽' => 'β', + '𝛾' => 'γ', + '𝛿' => 'δ', + '𝜀' => 'ε', + '𝜁' => 'ζ', + '𝜂' => 'η', + '𝜃' => 'θ', + '𝜄' => 'ι', + '𝜅' => 'κ', + '𝜆' => 'λ', + '𝜇' => 'μ', + '𝜈' => 'ν', + '𝜉' => 'ξ', + '𝜊' => 'ο', + '𝜋' => 'π', + '𝜌' => 'ρ', + '𝜍' => 'ς', + '𝜎' => 'σ', + '𝜏' => 'τ', + '𝜐' => 'υ', + '𝜑' => 'φ', + '𝜒' => 'χ', + '𝜓' => 'ψ', + '𝜔' => 'ω', + '𝜕' => '∂', + '𝜖' => 'ε', + '𝜗' => 'θ', + '𝜘' => 'κ', + '𝜙' => 'φ', + '𝜚' => 'ρ', + '𝜛' => 'π', + '𝜜' => 'Α', + '𝜝' => 'Β', + '𝜞' => 'Γ', + '𝜟' => 'Δ', + '𝜠' => 'Ε', + '𝜡' => 'Ζ', + '𝜢' => 'Η', + '𝜣' => 'Θ', + '𝜤' => 'Ι', + '𝜥' => 'Κ', + '𝜦' => 'Λ', + '𝜧' => 'Μ', + '𝜨' => 'Ν', + '𝜩' => 'Ξ', + '𝜪' => 'Ο', + '𝜫' => 'Π', + '𝜬' => 'Ρ', + '𝜭' => 'Θ', + '𝜮' => 'Σ', + '𝜯' => 'Τ', + '𝜰' => 'Υ', + '𝜱' => 'Φ', + '𝜲' => 'Χ', + '𝜳' => 'Ψ', + '𝜴' => 'Ω', + '𝜵' => '∇', + '𝜶' => 'α', + '𝜷' => 'β', + '𝜸' => 'γ', + '𝜹' => 'δ', + '𝜺' => 'ε', + '𝜻' => 'ζ', + '𝜼' => 'η', + '𝜽' => 'θ', + '𝜾' => 'ι', + '𝜿' => 'κ', + '𝝀' => 'λ', + '𝝁' => 'μ', + '𝝂' => 'ν', + '𝝃' => 'ξ', + '𝝄' => 'ο', + '𝝅' => 'π', + '𝝆' => 'ρ', + '𝝇' => 'ς', + '𝝈' => 'σ', + '𝝉' => 'τ', + '𝝊' => 'υ', + '𝝋' => 'φ', + '𝝌' => 'χ', + '𝝍' => 'ψ', + '𝝎' => 'ω', + '𝝏' => '∂', + '𝝐' => 'ε', + '𝝑' => 'θ', + '𝝒' => 'κ', + '𝝓' => 'φ', + '𝝔' => 'ρ', + '𝝕' => 'π', + '𝝖' => 'Α', + '𝝗' => 'Β', + '𝝘' => 'Γ', + '𝝙' => 'Δ', + '𝝚' => 'Ε', + '𝝛' => 'Ζ', + '𝝜' => 'Η', + '𝝝' => 'Θ', + '𝝞' => 'Ι', + '𝝟' => 'Κ', + '𝝠' => 'Λ', + '𝝡' => 'Μ', + '𝝢' => 'Ν', + '𝝣' => 'Ξ', + '𝝤' => 'Ο', + '𝝥' => 'Π', + '𝝦' => 'Ρ', + '𝝧' => 'Θ', + '𝝨' => 'Σ', + '𝝩' => 'Τ', + '𝝪' => 'Υ', + '𝝫' => 'Φ', + '𝝬' => 'Χ', + '𝝭' => 'Ψ', + '𝝮' => 'Ω', + '𝝯' => '∇', + '𝝰' => 'α', + '𝝱' => 'β', + '𝝲' => 'γ', + '𝝳' => 'δ', + '𝝴' => 'ε', + '𝝵' => 'ζ', + '𝝶' => 'η', + '𝝷' => 'θ', + '𝝸' => 'ι', + '𝝹' => 'κ', + '𝝺' => 'λ', + '𝝻' => 'μ', + '𝝼' => 'ν', + '𝝽' => 'ξ', + '𝝾' => 'ο', + '𝝿' => 'π', + '𝞀' => 'ρ', + '𝞁' => 'ς', + '𝞂' => 'σ', + '𝞃' => 'τ', + '𝞄' => 'υ', + '𝞅' => 'φ', + '𝞆' => 'χ', + '𝞇' => 'ψ', + '𝞈' => 'ω', + '𝞉' => '∂', + '𝞊' => 'ε', + '𝞋' => 'θ', + '𝞌' => 'κ', + '𝞍' => 'φ', + '𝞎' => 'ρ', + '𝞏' => 'π', + '𝞐' => 'Α', + '𝞑' => 'Β', + '𝞒' => 'Γ', + '𝞓' => 'Δ', + '𝞔' => 'Ε', + '𝞕' => 'Ζ', + '𝞖' => 'Η', + '𝞗' => 'Θ', + '𝞘' => 'Ι', + '𝞙' => 'Κ', + '𝞚' => 'Λ', + '𝞛' => 'Μ', + '𝞜' => 'Ν', + '𝞝' => 'Ξ', + '𝞞' => 'Ο', + '𝞟' => 'Π', + '𝞠' => 'Ρ', + '𝞡' => 'Θ', + '𝞢' => 'Σ', + '𝞣' => 'Τ', + '𝞤' => 'Υ', + '𝞥' => 'Φ', + '𝞦' => 'Χ', + '𝞧' => 'Ψ', + '𝞨' => 'Ω', + '𝞩' => '∇', + '𝞪' => 'α', + '𝞫' => 'β', + '𝞬' => 'γ', + '𝞭' => 'δ', + '𝞮' => 'ε', + '𝞯' => 'ζ', + '𝞰' => 'η', + '𝞱' => 'θ', + '𝞲' => 'ι', + '𝞳' => 'κ', + '𝞴' => 'λ', + '𝞵' => 'μ', + '𝞶' => 'ν', + '𝞷' => 'ξ', + '𝞸' => 'ο', + '𝞹' => 'π', + '𝞺' => 'ρ', + '𝞻' => 'ς', + '𝞼' => 'σ', + '𝞽' => 'τ', + '𝞾' => 'υ', + '𝞿' => 'φ', + '𝟀' => 'χ', + '𝟁' => 'ψ', + '𝟂' => 'ω', + '𝟃' => '∂', + '𝟄' => 'ε', + '𝟅' => 'θ', + '𝟆' => 'κ', + '𝟇' => 'φ', + '𝟈' => 'ρ', + '𝟉' => 'π', + '𝟊' => 'Ϝ', + '𝟋' => 'ϝ', + '𝟎' => '0', + '𝟏' => '1', + '𝟐' => '2', + '𝟑' => '3', + '𝟒' => '4', + '𝟓' => '5', + '𝟔' => '6', + '𝟕' => '7', + '𝟖' => '8', + '𝟗' => '9', + '𝟘' => '0', + '𝟙' => '1', + '𝟚' => '2', + '𝟛' => '3', + '𝟜' => '4', + '𝟝' => '5', + '𝟞' => '6', + '𝟟' => '7', + '𝟠' => '8', + '𝟡' => '9', + '𝟢' => '0', + '𝟣' => '1', + '𝟤' => '2', + '𝟥' => '3', + '𝟦' => '4', + '𝟧' => '5', + '𝟨' => '6', + '𝟩' => '7', + '𝟪' => '8', + '𝟫' => '9', + '𝟬' => '0', + '𝟭' => '1', + '𝟮' => '2', + '𝟯' => '3', + '𝟰' => '4', + '𝟱' => '5', + '𝟲' => '6', + '𝟳' => '7', + '𝟴' => '8', + '𝟵' => '9', + '𝟶' => '0', + '𝟷' => '1', + '𝟸' => '2', + '𝟹' => '3', + '𝟺' => '4', + '𝟻' => '5', + '𝟼' => '6', + '𝟽' => '7', + '𝟾' => '8', + '𝟿' => '9', + '𞸀' => 'ا', + '𞸁' => 'ب', + '𞸂' => 'ج', + '𞸃' => 'د', + '𞸅' => 'و', + '𞸆' => 'ز', + '𞸇' => 'ح', + '𞸈' => 'ط', + '𞸉' => 'ي', + '𞸊' => 'ك', + '𞸋' => 'ل', + '𞸌' => 'م', + '𞸍' => 'ن', + '𞸎' => 'س', + '𞸏' => 'ع', + '𞸐' => 'ف', + '𞸑' => 'ص', + '𞸒' => 'ق', + '𞸓' => 'ر', + '𞸔' => 'ش', + '𞸕' => 'ت', + '𞸖' => 'ث', + '𞸗' => 'خ', + '𞸘' => 'ذ', + '𞸙' => 'ض', + '𞸚' => 'ظ', + '𞸛' => 'غ', + '𞸜' => 'ٮ', + '𞸝' => 'ں', + '𞸞' => 'ڡ', + '𞸟' => 'ٯ', + '𞸡' => 'ب', + '𞸢' => 'ج', + '𞸤' => 'ه', + '𞸧' => 'ح', + '𞸩' => 'ي', + '𞸪' => 'ك', + '𞸫' => 'ل', + '𞸬' => 'م', + '𞸭' => 'ن', + '𞸮' => 'س', + '𞸯' => 'ع', + '𞸰' => 'ف', + '𞸱' => 'ص', + '𞸲' => 'ق', + '𞸴' => 'ش', + '𞸵' => 'ت', + '𞸶' => 'ث', + '𞸷' => 'خ', + '𞸹' => 'ض', + '𞸻' => 'غ', + '𞹂' => 'ج', + '𞹇' => 'ح', + '𞹉' => 'ي', + '𞹋' => 'ل', + '𞹍' => 'ن', + '𞹎' => 'س', + '𞹏' => 'ع', + '𞹑' => 'ص', + '𞹒' => 'ق', + '𞹔' => 'ش', + '𞹗' => 'خ', + '𞹙' => 'ض', + '𞹛' => 'غ', + '𞹝' => 'ں', + '𞹟' => 'ٯ', + '𞹡' => 'ب', + '𞹢' => 'ج', + '𞹤' => 'ه', + '𞹧' => 'ح', + '𞹨' => 'ط', + '𞹩' => 'ي', + '𞹪' => 'ك', + '𞹬' => 'م', + '𞹭' => 'ن', + '𞹮' => 'س', + '𞹯' => 'ع', + '𞹰' => 'ف', + '𞹱' => 'ص', + '𞹲' => 'ق', + '𞹴' => 'ش', + '𞹵' => 'ت', + '𞹶' => 'ث', + '𞹷' => 'خ', + '𞹹' => 'ض', + '𞹺' => 'ظ', + '𞹻' => 'غ', + '𞹼' => 'ٮ', + '𞹾' => 'ڡ', + '𞺀' => 'ا', + '𞺁' => 'ب', + '𞺂' => 'ج', + '𞺃' => 'د', + '𞺄' => 'ه', + '𞺅' => 'و', + '𞺆' => 'ز', + '𞺇' => 'ح', + '𞺈' => 'ط', + '𞺉' => 'ي', + '𞺋' => 'ل', + '𞺌' => 'م', + '𞺍' => 'ن', + '𞺎' => 'س', + '𞺏' => 'ع', + '𞺐' => 'ف', + '𞺑' => 'ص', + '𞺒' => 'ق', + '𞺓' => 'ر', + '𞺔' => 'ش', + '𞺕' => 'ت', + '𞺖' => 'ث', + '𞺗' => 'خ', + '𞺘' => 'ذ', + '𞺙' => 'ض', + '𞺚' => 'ظ', + '𞺛' => 'غ', + '𞺡' => 'ب', + '𞺢' => 'ج', + '𞺣' => 'د', + '𞺥' => 'و', + '𞺦' => 'ز', + '𞺧' => 'ح', + '𞺨' => 'ط', + '𞺩' => 'ي', + '𞺫' => 'ل', + '𞺬' => 'م', + '𞺭' => 'ن', + '𞺮' => 'س', + '𞺯' => 'ع', + '𞺰' => 'ف', + '𞺱' => 'ص', + '𞺲' => 'ق', + '𞺳' => 'ر', + '𞺴' => 'ش', + '𞺵' => 'ت', + '𞺶' => 'ث', + '𞺷' => 'خ', + '𞺸' => 'ذ', + '𞺹' => 'ض', + '𞺺' => 'ظ', + '𞺻' => 'غ', + '🄀' => '0.', + '🄁' => '0,', + '🄂' => '1,', + '🄃' => '2,', + '🄄' => '3,', + '🄅' => '4,', + '🄆' => '5,', + '🄇' => '6,', + '🄈' => '7,', + '🄉' => '8,', + '🄊' => '9,', + '🄐' => '(A)', + '🄑' => '(B)', + '🄒' => '(C)', + '🄓' => '(D)', + '🄔' => '(E)', + '🄕' => '(F)', + '🄖' => '(G)', + '🄗' => '(H)', + '🄘' => '(I)', + '🄙' => '(J)', + '🄚' => '(K)', + '🄛' => '(L)', + '🄜' => '(M)', + '🄝' => '(N)', + '🄞' => '(O)', + '🄟' => '(P)', + '🄠' => '(Q)', + '🄡' => '(R)', + '🄢' => '(S)', + '🄣' => '(T)', + '🄤' => '(U)', + '🄥' => '(V)', + '🄦' => '(W)', + '🄧' => '(X)', + '🄨' => '(Y)', + '🄩' => '(Z)', + '🄪' => '〔S〕', + '🄫' => 'C', + '🄬' => 'R', + '🄭' => 'CD', + '🄮' => 'WZ', + '🄰' => 'A', + '🄱' => 'B', + '🄲' => 'C', + '🄳' => 'D', + '🄴' => 'E', + '🄵' => 'F', + '🄶' => 'G', + '🄷' => 'H', + '🄸' => 'I', + '🄹' => 'J', + '🄺' => 'K', + '🄻' => 'L', + '🄼' => 'M', + '🄽' => 'N', + '🄾' => 'O', + '🄿' => 'P', + '🅀' => 'Q', + '🅁' => 'R', + '🅂' => 'S', + '🅃' => 'T', + '🅄' => 'U', + '🅅' => 'V', + '🅆' => 'W', + '🅇' => 'X', + '🅈' => 'Y', + '🅉' => 'Z', + '🅊' => 'HV', + '🅋' => 'MV', + '🅌' => 'SD', + '🅍' => 'SS', + '🅎' => 'PPV', + '🅏' => 'WC', + '🅪' => 'MC', + '🅫' => 'MD', + '🅬' => 'MR', + '🆐' => 'DJ', + '🈀' => 'ほか', + '🈁' => 'ココ', + '🈂' => 'サ', + '🈐' => '手', + '🈑' => '字', + '🈒' => '双', + '🈓' => 'デ', + '🈔' => '二', + '🈕' => '多', + '🈖' => '解', + '🈗' => '天', + '🈘' => '交', + '🈙' => '映', + '🈚' => '無', + '🈛' => '料', + '🈜' => '前', + '🈝' => '後', + '🈞' => '再', + '🈟' => '新', + '🈠' => '初', + '🈡' => '終', + '🈢' => '生', + '🈣' => '販', + '🈤' => '声', + '🈥' => '吹', + '🈦' => '演', + '🈧' => '投', + '🈨' => '捕', + '🈩' => '一', + '🈪' => '三', + '🈫' => '遊', + '🈬' => '左', + '🈭' => '中', + '🈮' => '右', + '🈯' => '指', + '🈰' => '走', + '🈱' => '打', + '🈲' => '禁', + '🈳' => '空', + '🈴' => '合', + '🈵' => '満', + '🈶' => '有', + '🈷' => '月', + '🈸' => '申', + '🈹' => '割', + '🈺' => '営', + '🈻' => '配', + '🉀' => '〔本〕', + '🉁' => '〔三〕', + '🉂' => '〔二〕', + '🉃' => '〔安〕', + '🉄' => '〔点〕', + '🉅' => '〔打〕', + '🉆' => '〔盗〕', + '🉇' => '〔勝〕', + '🉈' => '〔敗〕', + '🉐' => '得', + '🉑' => '可', + '🯰' => '0', + '🯱' => '1', + '🯲' => '2', + '🯳' => '3', + '🯴' => '4', + '🯵' => '5', + '🯶' => '6', + '🯷' => '7', + '🯸' => '8', + '🯹' => '9', +); diff --git a/includes/vendor/symfony/polyfill-intl-normalizer/bootstrap.php b/includes/vendor/symfony/polyfill-intl-normalizer/bootstrap.php new file mode 100644 index 0000000..3608e5c --- /dev/null +++ b/includes/vendor/symfony/polyfill-intl-normalizer/bootstrap.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Intl\Normalizer as p; + +if (\PHP_VERSION_ID >= 80000) { + return require __DIR__.'/bootstrap80.php'; +} + +if (!function_exists('normalizer_is_normalized')) { + function normalizer_is_normalized($string, $form = p\Normalizer::FORM_C) { return p\Normalizer::isNormalized($string, $form); } +} +if (!function_exists('normalizer_normalize')) { + function normalizer_normalize($string, $form = p\Normalizer::FORM_C) { return p\Normalizer::normalize($string, $form); } +} diff --git a/includes/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php b/includes/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php new file mode 100644 index 0000000..e36d1a9 --- /dev/null +++ b/includes/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Intl\Normalizer as p; + +if (!function_exists('normalizer_is_normalized')) { + function normalizer_is_normalized(?string $string, ?int $form = p\Normalizer::FORM_C): bool { return p\Normalizer::isNormalized((string) $string, (int) $form); } +} +if (!function_exists('normalizer_normalize')) { + function normalizer_normalize(?string $string, ?int $form = p\Normalizer::FORM_C): string|false { return p\Normalizer::normalize((string) $string, (int) $form); } +} diff --git a/includes/vendor/symfony/polyfill-intl-normalizer/composer.json b/includes/vendor/symfony/polyfill-intl-normalizer/composer.json new file mode 100644 index 0000000..2c4de2c --- /dev/null +++ b/includes/vendor/symfony/polyfill-intl-normalizer/composer.json @@ -0,0 +1,39 @@ +{ + "name": "symfony/polyfill-intl-normalizer", + "type": "library", + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "keywords": ["polyfill", "shim", "compatibility", "portable", "intl", "normalizer"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=7.1" + }, + "autoload": { + "psr-4": { "Symfony\\Polyfill\\Intl\\Normalizer\\": "" }, + "files": [ "bootstrap.php" ], + "classmap": [ "Resources/stubs" ] + }, + "suggest": { + "ext-intl": "For best performance" + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + } +} diff --git a/src/includes/version.php b/includes/version.php similarity index 100% rename from src/includes/version.php rename to includes/version.php diff --git a/src/index.php b/index.php similarity index 100% rename from src/index.php rename to index.php diff --git a/src/init.php b/init.php similarity index 98% rename from src/init.php rename to init.php index f7c9c9e..c9339c2 100644 --- a/src/init.php +++ b/init.php @@ -51,10 +51,10 @@ date_default_timezone_set(Config::get('timezone')); //User can override language setting by cookies or query $forceLang = ''; -if (isset($_COOKIE['lang'])) $forceLang = (string) $_COOKIE['lang']; -//else if (isset($_GET['lang'])) $forceLang = (string) $_GET['lang']; +if( isset($_COOKIE['lang']) ) $forceLang = $_COOKIE['lang']; +//else if ( isset($_GET['lang']) ) $forceLang = $_GET['lang']; -if ( $forceLang !== '' && preg_match("/^[a-z-]+$/i", $forceLang) ) { +if ( $forceLang != '' && preg_match("/^[a-z-]+$/i", $forceLang) ) { Config::set('lang', $forceLang); //TODO: special for demo, do not change config } diff --git a/src/settings.php b/settings.php similarity index 100% rename from src/settings.php rename to settings.php diff --git a/src/setup.php b/setup.php similarity index 99% rename from src/setup.php rename to setup.php index 254682b..737f40a 100644 --- a/src/setup.php +++ b/setup.php @@ -266,8 +266,6 @@ function createMysqlTables(Database_Abstract $db) //$collation = hasMysqlUnicode520($db) ? 'utf8mb4_unicode_520_ci' : 'utf8mb4_unicode_ci'; $collation = 'utf8mb4_unicode_520_ci'; - //TODO: use BIGINT for time() timestamp to avoid the Year-2038 problem (2106 here) - // Mysql does not support transactions while executing DDL $db->ex( "CREATE TABLE {$db->prefix}lists ( @@ -348,8 +346,6 @@ function createMysqlTables(Database_Abstract $db) /* ===== postgres =============================================== */ function createPostgresTables(Database_Abstract $db) { - //TODO: use BIGINT for time() timestamp to avoid the Year-2038 problem - $db->ex( "CREATE TABLE {$db->prefix}lists ( id INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, diff --git a/src/.htaccess b/src/.htaccess deleted file mode 100644 index 76b8d44..0000000 --- a/src/.htaccess +++ /dev/null @@ -1,16 +0,0 @@ -# For REST API in Apache -# -# RewriteEngine On -# RewriteCond %{REQUEST_FILENAME} !-f -# RewriteCond %{REQUEST_FILENAME} !-d -# RewriteRule ^api/(.*)$ api.php/$1 [L,QSA] -# -# -# Allow from all -# - - -# In Nginx set something like this: -# location /api/ { -# rewrite ^/api/(.*) /api.php/$1 last; -# } diff --git a/src/content/theme/images/svg2base64.php b/src/content/theme/images/svg2base64.php deleted file mode 100644 index f8c45c0..0000000 --- a/src/content/theme/images/svg2base64.php +++ /dev/null @@ -1,62 +0,0 @@ - - Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. -*/ - -// call like: php -f svg2base64.php > ../images.css - -if (php_sapi_name() != 'cli') { - error_log("Supports cli only"); - exit(-1); -} - -if (isset($argv[1])) { - print base64file($argv[1]); - exit(); -} - -$files = []; -$h = opendir(__DIR__); -while ( false !== ($file = readdir($h)) ) -{ - if ( preg_match('/(.+)\.svg$/', $file, $m) ) { - $files[] = $m[1]; - } -} -closedir($h); - -if (!$files) { - exit; -} -sort($files); - -print ":root {\n"; -foreach ($files as $name) { - $b64 = base64file(__DIR__. "/$name.svg"); - print " --svg-{$name}: url('data:image/svg+xml;base64,$b64');\n"; -} -print "}\n"; - -function base64file(string $filename): string -{ - $content = file_get_contents($filename); - //$content = str_replace(["\n","\r\n"], ['',''], $content); - $content = cleanXml($content); - return base64_encode($content); -} - -function cleanXml(string $data): string -{ - $dom = new DOMDocument; - $dom->preserveWhiteSpace = false; - $dom->loadXML($data); - - $xpath = new DOMXPath($dom); - foreach ($xpath->query('//comment()') as $comment) { - $comment->parentNode->removeChild($comment); - } - return $dom->saveXML(); -} diff --git a/src/docker-config.php b/src/docker-config.php deleted file mode 100644 index 8d6dd9d..0000000 --- a/src/docker-config.php +++ /dev/null @@ -1,23 +0,0 @@ - - Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. -*/ - -if (!defined('MTTPATH')) { - die("Unexpected usage."); -} - -function mtt_ext_customcss_instance(): MTTExtension -{ - return new CustomCssExtension(); -} - -class CustomCssExtension extends MTTExtension implements MTTExtensionSettingsInterface -{ - //the same as dir name - const bundleId = 'CustomCSS'; - - // settings domain - const domain = "ext.customcss.json"; - - const cssFilename = 'custom.css'; - - function init() - { - $prefs = self::preferences(); - if (isset($prefs['css'])) { - $href = htmlspecialchars( get_unsafe_mttinfo('theme_url'). self::cssFilename. '?v='. ($prefs['edited'] ?? 0) ); - $cb = function() use ($href) { - print "\n"; - }; - add_action('theme_head_end', $cb); - } - } - - function settingsPage(): string - { - $e = function($s) { return __($s, true); }; - $prefs = self::preferences(); - $css = htmlspecialchars($prefs['css'] ?? ''); - - return -<< -
{$e('customcss.h_css')} -
{$e('customcss.d_css')}
-
-
- -EOD; - } - - function settingsPageType(): int - { - return 0; //default page - } - - function saveSettings(array $params, ?string &$outMessage): bool - { - if (defined('MTT_DEMO')) { - $outMessage = "Demo"; - return true; - } - $css = $params['css'] ?? ''; - - $cssFilename = MTT_THEME_PATH. self::cssFilename; - if (!file_exists($cssFilename)) { - @touch($cssFilename); - } - if (!is_writable($cssFilename)) { - $outMessage = __('customcss.not_writable'); - return false; - } - @file_put_contents($cssFilename, $css); - $outMessage = __('customcss.saved'); - return true; - } - - static function preferences(): array - { - $prefs['cssFilename'] = $cssFilename = MTT_THEME_PATH. self::cssFilename; - if (file_exists($prefs['cssFilename'])) { - $prefs['edited'] = filemtime($cssFilename) ?? 0; - $prefs['css'] = @file_get_contents($cssFilename) ?? ''; - } - return $prefs; - } - -} diff --git a/src/ext/_examples/CustomSmartSyntax/.htaccess b/src/ext/_examples/CustomSmartSyntax/.htaccess deleted file mode 100644 index 8d2f256..0000000 --- a/src/ext/_examples/CustomSmartSyntax/.htaccess +++ /dev/null @@ -1 +0,0 @@ -deny from all diff --git a/src/ext/_examples/CustomSmartSyntax/extension.json b/src/ext/_examples/CustomSmartSyntax/extension.json deleted file mode 100644 index a494b51..0000000 --- a/src/ext/_examples/CustomSmartSyntax/extension.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "bundleId": "CustomSmartSyntax", - "name": "Custom Smart Syntax", - "version": "1.0", - "description": "Prototype to write you own smart syntax parser" -} diff --git a/src/ext/_examples/CustomSmartSyntax/loader.php b/src/ext/_examples/CustomSmartSyntax/loader.php deleted file mode 100644 index 08306c1..0000000 --- a/src/ext/_examples/CustomSmartSyntax/loader.php +++ /dev/null @@ -1,41 +0,0 @@ - - Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. -*/ - -if (!defined('MTTPATH')) { - die("Unexpected usage."); -} - -function mtt_ext_customsmartsyntax_instance(): MTTExtension -{ - return new CustomSmartSyntaxExtension(); -} - -class CustomSmartSyntaxExtension extends MTTExtension implements MTTFilterInterface -{ - //the same as dir name - const bundleId = 'CustomSmartSyntax'; - - function init() { - \MTTFilterCenter::addFilterForAction('parseSmartSyntax', $this); - } - - // parseSmartSyntax - function filter($title, &$out) - { - $a = [ - 'prio' => 0, // int: -1 .. 2 - 'title' => $title, // string - 'tags' => '', // string: "tag1, tag2, tag3,..." - 'duedate' => null, // string: "Y-m-d" format - ]; - - // This filter just overwrites results of default parser - - $out = $a; - } -} diff --git a/src/ext/backup/.htaccess b/src/ext/backup/.htaccess deleted file mode 100644 index 8d2f256..0000000 --- a/src/ext/backup/.htaccess +++ /dev/null @@ -1 +0,0 @@ -deny from all diff --git a/src/ext/backup/class.backup.php b/src/ext/backup/class.backup.php deleted file mode 100644 index f4cb8c0..0000000 --- a/src/ext/backup/class.backup.php +++ /dev/null @@ -1,190 +0,0 @@ - - Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. -*/ - -namespace BackupExtension; - -use Exception; - -class Backup -{ - public $lastErrorString = null; - public $filename; - private $fh; - private $level = 0; - private $tagClosed = true; - - function __construct(?string $filename) - { - $this->filename = is_null($filename) ? MTTPATH. 'db/backup.xml' : $filename; - } - - function isFileWritable() - { - if (!file_exists($this->filename)) { - @touch($this->filename); - } - if (!is_writable($this->filename)) { - return false; - } - return true; - } - - function makeBackup() - { - if (!$this->isFileWritable()) { - $this->lastErrorString = __('backup.not_writable'); - return false; - } - - $this->fh = fopen($this->filename, 'w'); - if ($this->fh === false) { - $ea = error_get_last(); - $this->lastErrorString = $ea['message'] ?? "Failed to open file for writing"; - return false; - } - - $db = \DBConnection::instance(); - - fwrite($this->fh, "\n"); - $this->writeOpeningTag('mttdb', [ - 'version' => 1, - 'appversion' => \mytinytodo\Version::VERSION, - 'dbversion' => \mytinytodo\Version::DB_VERSION, - 'dbtype' => $db::DBTYPE, - 'created' => date(DATE_ATOM) - ]); - $this->level = 0; - - - $this->writeTable($db->prefix.'lists', 'lists', 'list'); - $this->writeTable($db->prefix.'todolist', 'tasks', 'task'); - $this->writeTable($db->prefix.'tags', 'tags', 'tag'); - $this->writeTable($db->prefix.'tag2task', 'tag2task', 'item'); - $this->writeTable($db->prefix.'settings', 'settings', 'item'); - - - $this->writeClosingTag('mttdb'); - fwrite($this->fh, "\n"); - - if (!fclose($this->fh)) { - $ea = error_get_last(); - $this->lastErrorString = $ea['message'] ?? "Failed to close file"; - return false; - } - return true; - } - - function writeTable(string $table, string $group, string $itemName) - { - if (!preg_match("/^[\\w:]+$/", $table)) { - throw new Exception("Malformed table name: $table"); - } - $db = \DBConnection::instance(); - $props = null; - if ($db::DBTYPE == \DBConnection::DBTYPE_MYSQL) { - $autoinc = $this->getMysqlTableAutoIncrement($table); - if ($autoinc != '') { - $props = ['auto_increment' => $autoinc]; - } - } - $this->writeOpeningTag($group, $props); - $q = $db->dq("SELECT * FROM $table"); - while ($r = $q->fetchAssoc()) { - $this->writeItem($itemName, $r); - } - $this->writeClosingTag($group); - } - - function writeItem(string $entity, $r) - { - $tagAttrs = null; - if (isset($r['id'])) { - $tagAttrs = ['id' => $r['id']]; - unset($r['id']); - } - $this->writeOpeningTag($entity, $tagAttrs); - foreach ($r as $field => $value) { - $props = null; - if (is_null($value)) { - $props['isnull'] = 'yes'; - } - $this->writeOpeningTag($field, $props); - $this->writeTagContent((string)$value); - $this->writeClosingTag($field); - } - $this->writeClosingTag($entity); - } - - function getMysqlTableAutoIncrement(string $table): string - { - $db = \DBConnection::instance(); - $r = $db->sqa("SHOW TABLE STATUS WHERE Name=?", [$table]); - return (string)$r['Auto_increment'] ?? ''; - } - - - - function writeOpeningTag(string $tag, ?array $attrs = null) - { - if (!preg_match("/^[\\w:]+$/", $tag)) { - throw new Exception("Malformed tag: $tag"); - } - $data = "<$tag"; - if ($attrs !== null) { - $a = []; - foreach ($attrs as $k => $v) { - if (!preg_match("/^[\\w:-]+$/", $k)) { - throw new Exception("Malformed attribute name: $k"); - } - $v = (string)$v; - if (preg_match("/[\\r\\n]+/", $v)) { - throw new Exception("Malformed attribute value: $v"); - } - $a[] = "$k=\"". htmlspecialchars($v). "\""; - } - if (count($a) > 0) { - $data .= " ". implode(" ", $a); - } - } - $data .= ">"; - $this->write( ($this->tagClosed ? "" : "\n"). str_repeat(' ', $this->level) . $data ); - $this->level += 1; - $this->tagClosed = false; - } - - function writeClosingTag(string $tag) - { - if (!preg_match("/^[\\w:]+$/", $tag)) { - throw new Exception("Malformed tag: $tag"); - } - $this->level -= 1; - if ($this->level < 0) $this->level = 0; - $padding = ''; - if ($this->tagClosed) { - $padding = str_repeat(' ', $this->level); - } - $this->write( $padding . "\n" ); - $this->tagClosed = true; - } - - function writeTagContent(?string $content) - { - if ($content !== null) { - $this->write( htmlspecialchars($content, ENT_XML1, 'UTF-8') ); //TODO: make xml compliant? - } - } - - function write(string $data) - { - if (false === @fwrite($this->fh, $data)) { - $ea = error_get_last(); - throw new Exception("Failed to write to file: ". ($ea['message'] ?? "unknown reason")); - } - } - -} diff --git a/src/ext/backup/class.check.php b/src/ext/backup/class.check.php deleted file mode 100644 index 9ec520d..0000000 --- a/src/ext/backup/class.check.php +++ /dev/null @@ -1,126 +0,0 @@ - - Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. -*/ - -namespace BackupExtension; - -use DBConnection; - -class Check -{ - public $lastErrorString = null; - public $report = ''; - - function check(): bool - { - $db = DBConnection::instance(); - $msg = []; - - // Task without list - $count = $db->sq("SELECT COUNT(*) FROM {$db->prefix}todolist WHERE list_id NOT IN (SELECT id FROM {$db->prefix}lists)"); - if ($count) { - $msg[] = "Tasks without list: $count"; - } - - // Tag without task (not a broblem) - $count = $db->sq("SELECT COUNT(*) FROM {$db->prefix}tags WHERE id NOT IN (SELECT tag_id FROM {$db->prefix}tag2task)"); - if ($count) { - $msg[] = "Tags without task: $count"; - } - - // tag2task no list - $count = $db->sq("SELECT COUNT(*) FROM {$db->prefix}tag2task WHERE list_id NOT IN (SELECT id FROM {$db->prefix}lists)"); - if ($count) { - $msg[] = "tag2task no list: $count"; - } - - // tag2task no tag - $count = $db->sq("SELECT COUNT(*) FROM {$db->prefix}tag2task WHERE tag_id NOT IN (SELECT id FROM {$db->prefix}tags)"); - if ($count) { - $msg[] = "tag2task no tag: $count"; - } - - // tag2task no task - $count = $db->sq("SELECT COUNT(*) FROM {$db->prefix}tag2task WHERE task_id NOT IN (SELECT id FROM {$db->prefix}todolist)"); - if ($count) { - $msg[] = "tag2task no task: $count"; - } - - $count = 0; - $uniqTag = []; // lowerTag => [id, tag] - $nonuniqTag = []; // id => [tag, lowerTag, uniqId, uniqTag, taskCount] - $q = $db->dq("SELECT id,name,COUNT(task_id) c FROM {$db->prefix}tags t LEFT JOIN {$db->prefix}tag2task tt ON t.id=tt.tag_id GROUP BY id ORDER BY id"); - while ($r = $q->fetchAssoc()) { - $v = mb_strtolower((string)$r['name'], 'UTF-8'); - if (!isset($uniqTag[$v])) { - $uniqTag[$v] = [$r['id'], $r['name']]; - } - else { - $count++; - $nonuniqTag[$r['id']] = [$r['name'], $v, $uniqTag[$v][0], $uniqTag[$v][1], $r['c']]; - } - } - if ($count > 0) { - $msg[] = "Non-unique tags: $count"; - foreach ($nonuniqTag as $id => $a) { - $msg[] = " ID:{$id} Tag:{$a[0]} (tasks: {$a[4]}) same as ID:{$a[2]} Tag:{$a[3]}"; - } - } - - if (count($msg) == 0) { - $msg[] = "OK"; - } - - $this->report = implode("\n", $msg); - return true; - } - - function repair(): bool - { - $db = DBConnection::instance(); - - $db->ex("BEGIN"); - - // Task without list - $count = (int)$db->sq("SELECT COUNT(*) FROM {$db->prefix}todolist WHERE list_id NOT IN (SELECT id FROM {$db->prefix}lists)"); - if ($count > 0) { - // Move to new list - $listID = \DBCore::default()->createListWithName("Restored tasks"); - $db->ex("UPDATE {$db->prefix}todolist SET list_id=? WHERE list_id NOT IN (SELECT id FROM {$db->prefix}lists)", [$listID]); - } - - //Tags - $db->ex("DELETE FROM {$db->prefix}tags WHERE id NOT IN (SELECT tag_id FROM {$db->prefix}tag2task)"); - $db->ex("DELETE FROM {$db->prefix}tag2task WHERE task_id NOT IN (SELECT id FROM {$db->prefix}todolist)"); - $db->ex("DELETE FROM {$db->prefix}tag2task WHERE tag_id NOT IN (SELECT id FROM {$db->prefix}tags)"); - - //Non-unique tags replace with first unique - $uniqTag = []; - $replace = []; - $q = $db->dq("SELECT id,name FROM {$db->prefix}tags t LEFT JOIN {$db->prefix}tag2task tt ON t.id=tt.tag_id GROUP BY id ORDER BY id"); - while ($r = $q->fetchAssoc()) { - $v = mb_strtolower((string)$r['name'], 'UTF-8'); - if (!isset($uniqTag[$v])) { - $uniqTag[$v] = $r['id']; - } - else { - $replace[$r['id']] = $uniqTag[$v]; - } - } - foreach ($replace as $id => $newId) { - $db->ex("UPDATE {$db->prefix}tag2task SET tag_id=? WHERE tag_id=?", [$newId, $id]); - } - $db->ex("DELETE FROM {$db->prefix}tags WHERE id NOT IN (SELECT tag_id FROM {$db->prefix}tag2task)"); - - - // TODO: tag2task no list ? - - $db->ex("COMMIT"); - return true; - } - -} diff --git a/src/ext/backup/class.controller.php b/src/ext/backup/class.controller.php deleted file mode 100644 index 813c4d0..0000000 --- a/src/ext/backup/class.controller.php +++ /dev/null @@ -1,156 +0,0 @@ - - Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. -*/ - -namespace BackupExtension; - -use BackupExtension; -use BackupExtension\Backup; -use BackupExtension\Download; -use BackupExtension\Check; - -class Controller extends \ApiController -{ - function postMakeBackup() - { - require_once('class.backup.php'); - $filename = BackupExtension::backupFilePath(); - $backup = new Backup($filename); - - if (!$backup->makeBackup()) { - $this->response->data = [ - 'total' => 0, - 'msg' => __("error"), - 'details' => $backup->lastErrorString ?? '', - ]; - } - - $this->response->data = [ - 'total' => 1, - 'ok' => true, - 'msg' => __("backup.done"), - 'alertTextOnLoad' => __("backup.done"), - ]; - } - - function postDownload() - { - require_once('class.download.php'); - $filename = BackupExtension::backupFilePath(); - $download = new Download($filename); - - if (!$download->checkFileAccess()) { - $this->response->data = [ - 'total' => 0, - 'msg' => __("error"), - 'details' => $download->lastErrorString ?? '', - ]; - return; - } - $this->response->data = [ - 'total' => 1, - 'redirect' => $download->downloadUrl() - ]; - } - - function getDownload() - { - require_once('class.download.php'); - $filename = BackupExtension::backupFilePath(); - $download = new Download($filename); - - $ott = (string)_get('t'); - if (!$download->checkFileAccess($ott)) { - $this->response->data = [ - 'total' => 0, - 'msg' => __("error"), - 'details' => $download->lastErrorString ?? '', - ]; - return; - } - $download->printFile(); - exit(); - } - - function postRestore() - { - require_once('class.restore.php'); - $restore = new Restore(); - - if (!$restore->isUploaded()) { - $this->response->data = [ - 'total' => 0, - 'msg' => __("error"), - 'details' => $restore->lastErrorString ?? '', - ]; - return; - } - - if (!$restore->restore()) { - $this->response->data = [ - 'total' => 0, - 'msg' => __("error"), - 'details' => $restore->lastErrorString ?? '', - ]; - return; - } - - $this->response->data = [ - 'total' => 1, - 'msg' => __("backup.done"), - 'redirect' => get_mttinfo('url'), - ]; - } - - function postCheckInconsistency() - { - require_once('class.check.php'); - $check = new Check(); - - if (!$check->check()) { - $this->response->data = [ - 'total' => 0, - 'msg' => __("error"), - 'details' => $check->lastErrorString ?? '', - ]; - return; - } - $this->response->data = [ - 'total' => 1, - 'ok' => true, - 'msg' => __("backup.done"), - ]; - if ($check->report == 'OK') { - $this->response->data['alertText'] = "OK"; - } - else { - $this->response->data['html'] = "
". htmlspecialchars($check->report). "
"; - } - } - - function postRepairInconsistency() - { - require_once('class.check.php'); - $check = new Check(); - - if (!$check->repair()) { - $this->response->data = [ - 'total' => 0, - 'msg' => __("error"), - 'details' => $check->lastErrorString ?? '', - ]; - return; - } - $this->response->data = [ - 'total' => 1, - 'ok' => true, - 'msg' => __("backup.done"), - 'alertText' => __("backup.done"), - ]; - } - -} diff --git a/src/ext/backup/class.download.php b/src/ext/backup/class.download.php deleted file mode 100644 index 116187c..0000000 --- a/src/ext/backup/class.download.php +++ /dev/null @@ -1,74 +0,0 @@ - - Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. -*/ - -namespace BackupExtension; - -use BackupExtension; - -class Download -{ - public $filename; - public $lastErrorString = null; - private $token = ''; - - function __construct(?string $filename) - { - $this->filename = is_null($filename) ? MTTPATH. 'db/backup.xml' : $filename; - } - - function checkFileAccess(?string $tokenHash = null): bool - { - if (!file_exists($this->filename)) { - $this->lastErrorString = "Backup file not found"; - return false; - } - - $this->token = access_token(); - if ($this->token == '') { - $this->lastErrorString = "No token provided"; - return false; - } - - if (!is_null($tokenHash)) { - $a = explode(':', $tokenHash, 2); - $rnd = $a[0] ?? ''; - $hash = $a[1] ?? ''; - if (!hash_equals(hash_hmac('sha256', $rnd, $this->token), $hash)) { - $this->lastErrorString = "No temp token provided"; - return false; - } - } - - return true; - } - - function downloadUrl() - { - $rnd = randomString(); - $hash = $rnd. ':'. hash_hmac('sha256', $rnd, $this->token); - $url = BackupExtension::extApiActionUrl("download", "t=$hash"); - return $url; - } - - function printFile() - { - header('Content-type: application/xml; charset=utf-8'); - header('Content-disposition: attachment; filename=backup.xml'); - - $fh = fopen($this->filename, "r") or die("Couldn't open file"); - if ($fh) { - while (!feof($fh)) { - $buffer = fgets($fh, 4096); - print($buffer); - } - fclose($fh); - } - exit(); - } - -} diff --git a/src/ext/backup/class.restore.php b/src/ext/backup/class.restore.php deleted file mode 100644 index eeccb31..0000000 --- a/src/ext/backup/class.restore.php +++ /dev/null @@ -1,251 +0,0 @@ - - Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. -*/ - -namespace BackupExtension; - -use XMLReader; -use DBConnection; -use Exception; - -class Restore -{ - public $lastErrorString = null; - private $filename; - /** @var XMLReader */ - private $reader; - private $tableItem; - - function __construct() - { - // xml table => [ db table, xml item ] - $this->tableItem = [ - 'lists' => ['lists', 'list'], - 'tasks' => ['todolist', 'task'], - 'tags' => ['tags', 'tag'], - 'tag2task' => ['tag2task', 'item'], - 'settings' => ['settings', 'item'], - ]; - } - - function isUploaded(): bool - { - if (!isset($_FILES['file']) || !isset($_FILES['file']['name']) || !isset($_FILES['file']['tmp_name'])) { - $this->lastErrorString = "Not uploaded"; - return false; - } - - $this->filename = $_FILES['file']['tmp_name']; - if (!file_exists($this->filename) || !is_readable($this->filename)) { - $this->lastErrorString = "Can't open file"; - return false; - } - return true; - } - - function restore(): bool - { - $this->reader = $reader = new XMLReader(); - $reader->open($this->filename); - - // root element - $reader->next('mttdb'); - if ($reader->name != 'mttdb') { - $this->lastErrorString = "Incorrect format: missing 'mttdb'."; - return false; - } - - if (!$this->moveNextElement()) { - $this->lastErrorString = "Incorrect format: tables not found."; - return false; - } - - $this->beginRestore(); - - $tables = array_keys($this->tableItem); - - // Enumerate tables - do { - if ($reader->nodeType != XMLReader::ELEMENT) { - error_log("Unexpected element '{$reader->name}' of type: {$reader->nodeType}"); - break; - } - //error_log("Found table '{$reader->name}'"); - - $result = null; - if (in_array($reader->name, $tables)) { - $result = $this->readTable($this->tableItem[$reader->name][0], $this->tableItem[$reader->name][1]); - } - else { - continue; // Unexpected table, just skip - } - if (is_null($result)) { - return false; // Incorrect format, error is set, stop - } - - } while ($this->moveNextElementSameLevel()); - - $this->endRestore(); - - $reader->close(); - return true; - } - - function moveNextElement(?string $el = null): ?bool - { - while ($this->reader->read()) { - if ($this->reader->nodeType == XMLReader::ELEMENT) { - if (!is_null($el) && $this->reader->name != $el) { - return false; - } - return true; - } - else if ($this->reader->nodeType == XMLReader::END_ELEMENT) { - return null; - } - } - return null; - } - - function moveNextElementSameLevel(?string $el = null) - { - return $this->reader->next() && ($this->reader->nodeType == XMLReader::ELEMENT || $this->moveNextElement($el)); - } - - function readTable(string $table, string $itemName): ?int - { - $autoinc = $this->reader->getAttribute("auto_increment"); - $maxId = 0; - $count = 0; - - // find first item - $found = $this->moveNextElement($itemName); - if ($found === false) { - $this->lastErrorString = "Incorrect item name {$this->reader->name}, expected '{$itemName}'"; - return null; // Error - } - else if (is_null($found)) { - return 0; // No items found - } - - do { - $count++; - $id = $this->reader->getAttribute("id"); - if (!is_null($id)) { - $maxId = max($maxId, (int)$id); - } - // error_log("# $count: found $itemName with id $id"); - - $itemXml = $this->reader->readOuterXml(); - $xml = simplexml_load_string($itemXml); //SimpleXMLElement - if ($xml === false) { - error_log("Incorrect format of $itemName"); - continue; - } - if (!$this->insertToTable($table, $xml)) { - return null; // Error - } - - } while ($this->moveNextElementSameLevel($itemName)); - - // restore table last auto_increment (mysql) - if (!is_null($autoinc)) { - $autoinc = max((int)$autoinc, $maxId); - } - else { - $autoinc = $maxId + 1; - } - if ($autoinc > 1) { - $this->updateAutoinc($table, $autoinc); - } - return $count; - } - - private function insertToTable(string $table, \SimpleXMLElement $xml): bool - { - if (!preg_match("/^[\\w]+$/", $table)) { - throw new Exception("Malformed table name: $table"); - } - $fields = []; - $values = []; - - $attrsXml = $xml->attributes(); - if (isset($attrsXml['id']) && $attrsXml['id'] != '') { - $fields[] = 'id'; - $values[] = (string)$attrsXml['id']; - } - - foreach ($xml->children() as $item) { - $field = $item->getName(); - $value = (string)$item; - if (!preg_match("/^[\\w]+$/", $field)) { - throw new Exception("Malformed field name: $field"); - } - $attrsXml = $item->attributes(); - if (isset($attrsXml['isnull']) && $attrsXml['isnull'] == 'yes') { //$attrsXml['isnull']->__toString() - $value = null; - } - $fields[] = $field; - $values[] = $value; - } - - $fieldsStr = implode(',', $fields); // id,name,title ... - $subsStr = implode(',', array_fill(0, count($fields), '?')); // ?,?,? ... - $db = DBConnection::instance(); - try { - $db->ex("INSERT INTO {$db->prefix}{$table} ($fieldsStr) VALUES ($subsStr)", $values); - } - catch (Exception $e) { - error_log("Failed query: {$db->lastQuery}"); - $this->lastErrorString = "Failed to add data to table '{$db->prefix}$table'. Database error (see query in error log): ". $e->getMessage(); - return false; - } - return true; - } - - private function updateAutoinc(string $table, int $autoinc) - { - $db = DBConnection::instance(); - switch ($db::DBTYPE) { - case DBConnection::DBTYPE_MYSQL: - $db->ex("ALTER TABLE {$db->prefix}$table AUTO_INCREMENT = ". (int)$autoinc); - break; - case DBConnection::DBTYPE_POSTGRES: - $db->ex("ALTER TABLE {$db->prefix}$table ALTER COLUMN id RESTART WITH ". (int)$autoinc); - break; - default: - break; - } - } - - private function beginRestore() - { - $db = DBConnection::instance(); - $db->ex("BEGIN"); - foreach ($this->tableItem as $a) { - $table = $db->prefix. $a[0]; - if ($db::DBTYPE == DBConnection::DBTYPE_POSTGRES) { - $db->ex("TRUNCATE TABLE $table RESTART IDENTITY"); - } - else { - // we do not use TRUNCATE on mysql due to autocommit - // sqlite has truncate optimizer - $db->ex("DELETE FROM $table"); - } - } - $db->ex("DELETE FROM {$db->prefix}sessions"); - } - - private function endRestore() - { - $db = DBConnection::instance(); - $db->ex("COMMIT"); - // vacuum? - } - - -} diff --git a/src/ext/backup/extension.json b/src/ext/backup/extension.json deleted file mode 100644 index 1ef2a14..0000000 --- a/src/ext/backup/extension.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "bundleId": "backup", - "name": "Backup", - "version": "1.0", - "description": "Backup" -} diff --git a/src/ext/backup/lang/en.json b/src/ext/backup/lang/en.json deleted file mode 100644 index 32307cf..0000000 --- a/src/ext/backup/lang/en.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "ext.backup.name": "Backup", - "backup.h_make": "Make backup", - "backup.d_make": "Will create backup file in '%s' folder.", - "backup.make": "Make", - "backup.download": "Download", - "backup.done": "Done", - "backup.not_writable": "Backup file is not writable, check permissions for db/backup.xml", - "backup.last_backup": "Last backup: %s", - "backup.h_inconsistency": "Check for inconsistency", - "backup.d_inconsistency": "If you want to restore the backup to another database version or type, it's better to fix inconsistency before making backup.", - "backup.check": "Check", - "backup.repair": "Repair", - "backup.h_restore": "Restore from backup", - "backup.d_restore": "Will delete all records in existing database before restoring.", - "backup.restore": "Restore…" -} diff --git a/src/ext/backup/lang/ru.json b/src/ext/backup/lang/ru.json deleted file mode 100644 index e8689c0..0000000 --- a/src/ext/backup/lang/ru.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "ext.backup.name": "Резервное копирование", - "backup.h_make": "Сделать копию", - "backup.d_make": "Сохранит файл в папке '%s'.", - "backup.make": "Создать", - "backup.download": "Скачать", - "backup.done": "Выполнено", - "backup.not_writable": "Ошибка записи в файл, проверьте права доступа к db/backup.xml", - "backup.last_backup": "Резервная копия: %s", - "backup.h_inconsistency": "Проверка базы данных", - "backup.d_inconsistency": "Если планируете восстановление из резервной копии в другую базу данных, то лучше исправить возможные ошибки перед резервным копированием.", - "backup.check": "Проверить", - "backup.repair": "Исправить", - "backup.h_restore": "Восстановить из резервной копии", - "backup.d_restore": "Удалит все существующие записи во время восстановления.", - "backup.restore": "Восстановить…" -} diff --git a/src/ext/backup/loader.php b/src/ext/backup/loader.php deleted file mode 100644 index 95a3872..0000000 --- a/src/ext/backup/loader.php +++ /dev/null @@ -1,140 +0,0 @@ - - Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. -*/ - -if (!defined('MTTPATH')) { - die("Unexpected usage."); -} - -require_once('class.controller.php'); - -function mtt_ext_backup_instance(): MTTExtension -{ - return new BackupExtension(); -} - -use BackupExtension\Controller; - -class BackupExtension extends MTTExtension implements MTTExtensionSettingsInterface, MTTHttpApiExtender -{ - //the same as dir name - const bundleId = 'backup'; - - // settings domain - const domain = "ext.backup.json"; - - function init() { - } - - // MTTHttpApiExtender - function extendHttpApi(): array - { - return array( - '/makeBackup' => [ - 'POST' => [ Controller::class , 'postMakeBackup' ], - ], - '/download' => [ - 'POST' => [ Controller::class , 'postDownload' ], - 'GET' => [ Controller::class , 'getDownload', true ], // doesn't check auth token - ], - '/restore' => [ - 'POST' => [ Controller::class , 'postRestore' ], - ], - '/checkInconsistency' => [ - 'POST' => [ Controller::class , 'postCheckInconsistency' ], - ], - '/repairInconsistency' => [ - 'POST' => [ Controller::class , 'postRepairInconsistency' ], - ], - - ); - } - - function settingsPage(): string - { - $warning = ''; - $e = function($s, $arg=null) { return __($s, true, $arg); }; - $ext = htmlspecialchars(self::bundleId); - - $downloadDisabled = ''; - $lastBackup = ''; - $filename = MTTPATH. 'db/backup.xml'; - if (file_exists($filename)) { - $time = filemtime($filename); - $lastBackup = htmlspecialchars( sprintf($e('backup.last_backup'), formatTime(Config::get('dateformat'). " H:i:s", $time)) ); - } - else { - $downloadDisabled = 'disabled'; - } - - return << -function onBackupFileChange(el) { - const fd = new FormData(); - fd.append('file', el.files[0]); - mytinytodo.extensionSettingsAction(el.dataset.extSettingsAction, el.dataset.ext, fd); -} - -
-
{$e('backup.h_make')} -
{$e('backup.d_make', 'db')}
-
-
-
-
$lastBackup   - -
-
-
-
{$e('backup.h_inconsistency')} -
{$e('backup.d_inconsistency')}
-
-
-   -
-
-
-
-
{$e('backup.h_restore')} -
{$e('backup.d_restore')}
-
-
- -
-
-EOD; - } - - function settingsPageType(): int - { - return 1; //no form buttons - } - - function saveSettings(array $params, ?string &$outMessage): bool - { - return false; - } -/* - static function preferences(): array - { - return [ - 'backupFilePath' => MTTPATH. 'db/backup.xml' - ]; - } -*/ - static function backupFilePath() - { - //return self::preferences()['backupFilePath']; - return MTTPATH. 'db/backup.xml'; - } - - -} diff --git a/src/ext/notifications/.htaccess b/src/ext/notifications/.htaccess deleted file mode 100644 index 8d2f256..0000000 --- a/src/ext/notifications/.htaccess +++ /dev/null @@ -1 +0,0 @@ -deny from all diff --git a/src/ext/notifications/class.controller.php b/src/ext/notifications/class.controller.php deleted file mode 100644 index a365583..0000000 --- a/src/ext/notifications/class.controller.php +++ /dev/null @@ -1,117 +0,0 @@ - - Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. -*/ - -namespace Notify; - -use NotificationsExtension; -use Config; - -class Controller extends \ApiController -{ - function postDeactivateAll() - { - $prefs = Config::requestDomain(NotificationsExtension::domain); - if (isset($prefs['chats'])) { - $prefs['chats'] = []; - Config::saveDomain(NotificationsExtension::domain, $prefs); - } - $this->response->data = [ 'total' => 1, 'msg' => __("notifications.all_chats_deactivated") ]; - } - - function postCheck() - { - $prefs = Config::requestDomain(NotificationsExtension::domain); - if (!($prefs['validToken'] ?? false)) { - $this->response->data = [ 'total' => 0, 'msg' => __("notifications.bot_not_configured") ]; - return; - } - if (!isset($prefs['chats']) || !is_array($prefs['chats'])) { - $prefs['chats'] = []; - } - $code = $prefs['code'] ?? null; - $codeExpires = $prefs['codeExpires'] ?? 0; - $token = $prefs['token'] ?? ''; - - $this->response->data = [ 'total' => 0, 'msg' => __("notifications.no_new_chats") ]; - - // Read messages since last check - $maxId = $prefs['lastUpdateId'] ?? 0; - $api = new TelegramApi($token); - $api->logApiErrors = true; - $updates = $api->getUpdates([ - 'offset' => $maxId + 1, - 'allowed_updates' => ['message'] - ]); - if (!is_array($updates) || count($updates) == 0) { - return; - } - - // Select last message in every chat - $messages = array(); - foreach ($updates as $update) { - $message = $update['message'] ?? []; - $chatId = (string)($message['chat']['id'] ?? 0); - $prefs['lastUpdateId'] = max($maxId, $update['update_id'] ?? 0); - $messages[$chatId] = $message; - } - - $total = 0; - foreach ($messages as $chatId => $message) { - $chatId = (int) $chatId; - $text = $message['text'] ?? ''; - $msgId = (int) ($message['message_id'] ?? 0); - if (in_array($chatId, $prefs['chats'])) { - $api->sendMessage([ - 'chat_id' => $chatId, - 'text' => __("notifications.already_active") - ]); - } - else if ($text === '/start') { - $api->sendMessage([ - 'chat_id' => $chatId, - 'text' => __("notifications.please_send") - ]); - } - else if ($code === null) { - $api->sendMessage([ - 'chat_id' => $chatId, - 'text' => __("notifications.code_not_set") - ]); - } - else if ($codeExpires < time()) { - $api->sendMessage([ - 'chat_id' => $chatId, - 'text' => __("notifications.code_expired") - ]); - } - else if ($text == $code) { - $prefs['chats'][] = $chatId; - $api->sendMessage([ - 'chat_id' => $chatId, - 'reply_to_message_id' => $msgId, - 'text' => __("notifications.activated") - ]); - $total++; - $this->response->data = [ - 'total' => $total, - 'msg' => __("notifications.activated") - ]; - } - else { - $api->sendMessage([ - 'chat_id' => $chatId, - 'reply_to_message_id' => $msgId, - 'text' => __("notifications.code_wrong") - ]); - } - } - - Config::saveDomain(NotificationsExtension::domain, $prefs); - } - -} diff --git a/src/ext/notifications/class.observer.php b/src/ext/notifications/class.observer.php deleted file mode 100644 index 1b0db2a..0000000 --- a/src/ext/notifications/class.observer.php +++ /dev/null @@ -1,65 +0,0 @@ - - Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. -*/ - -namespace Notify; - -use NotificationsExtension; -use MTTNotification; -use MTTNotificationCenter; -use DBConnection; - - -class NotificationObserver implements \MTTNotificationObserverInterface -{ - private $prefs = null; - private $delayedNotifications = []; - - public function notification(string $notification, $object) - { - if (!$this->prefs) { - $this->init(); - } - if (count($this->prefs['chats']) == 0 && count($this->prefs['emails']) == 0) { - return; // nobody to notify - } - - $db = DBConnection::instance(); - switch ($notification) { - case MTTNotification::didFinishRequest: - $this->processDelayed(); - break; - case MTTNotification::didCreateTask: - case MTTNotification::didCreateList: - // Get list name - $list = $db->sqa( "SELECT name FROM {$db->prefix}lists WHERE id=?", array($object['listId'] ?? 0) ); - $object['listName'] = htmlspecialchars($list['name'] ?? ''); - $this->delayedNotifications[] = [ - 'notification' => $notification, - 'object' => $object - ]; - MTTNotificationCenter::addObserverForNotification(MTTNotification::didFinishRequest, $this); - } - } - - private function processDelayed() - { - //$db = DBConnection::instance(); - $useCli = !function_exists('fastcgi_finish_request'); - $sender = new Sender( $this->prefs, $useCli ); - foreach ($this->delayedNotifications as $item) { - $sender->notify($item); - } - } - - private function init() - { - $this->prefs = NotificationsExtension::preferences(); - //$this->token = $this->prefs['token'] ?? ''; - } - -} diff --git a/src/ext/notifications/class.sender.php b/src/ext/notifications/class.sender.php deleted file mode 100644 index ac3e715..0000000 --- a/src/ext/notifications/class.sender.php +++ /dev/null @@ -1,202 +0,0 @@ - - Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. -*/ - -namespace Notify; - -use NotificationsExtension; -use MTTNotification; - - -class Sender -{ - private $prefs; - private $cli = false; - - function __construct(array $prefs, bool $useCli = false) - { - $this->prefs = $prefs; - if ($useCli && function_exists('pcntl_fork') && function_exists('posix_setsid')) { - $this->cli = true; - } - } - - function notify(array $item) - { - $notification = $item['notification'] ?? ''; - $object = $item['object'] ?? null; - switch ($notification) { - case MTTNotification::didCreateTask: $this->notifyTaskCreated($object); break; - case MTTNotification::didCreateList: $this->notifyListCreated($object); break; - } - } - - /* - $task['title'], $task['tags'], $task['duedate'], $task['listName'] are already escaped - */ - private function notifyTaskCreated($task) - { - $link = get_mttinfo('url'). '?task='. $task['id']; - - //email - if (count($this->prefs['emails']) > 0) { - $aText = []; - $aText[] = "New task in ". htmlspecialchars_decode($task['listName']). ":"; - $aText[] = htmlspecialchars_decode($task['title']); - $aText[] = ""; - if ($task['duedate'] != '') { - $aText[] = "Due: ". htmlspecialchars_decode($task['duedate']); - } - if ($task['tags'] != '') { - $aText[] = "Tags: ". implode(", ", preg_split("/,\s*/", htmlspecialchars_decode($task['tags']), -1, PREG_SPLIT_NO_EMPTY)); - } - if ($aText[count($aText)-1] != '') { - $aText[] = ""; - } - $aText[] = "Link: $link"; - $text = implode("\r\n", $aText); - - $this->sendEmails( $text, "New task #". $task['id']); - } - - // telegram - if (count($this->prefs['chats']) > 0) { - $text = "New task #". $task['id']. " in ". $task['listName'] .": ". $task['title']; - if ($task['duedate'] != '') { - $text .= "\nDue: ". $task['duedate']; - } - if ($task['tags'] != '') { - $text .= "\nTags: ". implode(", ", preg_split("/,\s*/", $task['tags'], -1, PREG_SPLIT_NO_EMPTY)); - } - - $this->sendTelegrams($text); - } - } - - /* - $list['name'] is already escaped - */ - private function notifyListCreated($list) - { - $link = get_mttinfo('url'). '?list='. $list['id']; - - //email - if (count($this->prefs['emails']) > 0) { - $aText = []; - $aText[] = "New list:"; - $aText[] = htmlspecialchars_decode($list['name']); - $aText[] = ""; - $aText[] = "Link: $link"; - $text = implode("\r\n", $aText); - - $this->sendEmails( $text, "New list"); - } - - // telegram - if (count($this->prefs['chats']) > 0) { - $text = "New list: ". $list['name']. ""; - - $this->sendTelegrams($text); - } - } - - private function sendEmails(string $text, string $subject) - { - $fromAddr = ''; - if (isset($this->prefs['mailfrom']) && $this->prefs['mailfrom'] != '') { - $fromAddr = str_replace( ["\r", "\n", ":", "\"", "'", "?"], '', $this->prefs['mailfrom']); - } - else { - $fromAddr = self::suggestedMailFrom(); - } - $from = "myTinyTodo <$fromAddr>"; - $mttTitle = str_replace( ["\r","\n"], '', get_unsafe_mttinfo('title') ); - $subject = "[$mttTitle] $subject"; - if (!mb_check_encoding($subject, 'ASCII')) { - $subject = mb_encode_mimeheader($subject, 'UTF-8', 'B', "\r\n"); - } - $headers = [ - 'From: '. $from - ]; - if (mb_check_encoding($text, 'ASCII')) { - $headers[] = 'Content-Type: text/plain'; - } - else { - $headers[] = 'Content-Type: text/plain; charset=UTF-8'; - $headers[] = 'Content-Transfer-Encoding: 8bit'; - } - foreach ($this->prefs['emails'] as $email) { - mail($email, $subject, $text, implode("\r\n", $headers)); - } - } - - private function sendTelegrams(string $text) - { - if ($this->cli) { - $this->sendTelegramsInBackground($text); - } - else { - $this->sendTelegramsWithApi($text); - } - } - - // public! - function sendTelegramsWithApi(string $text) - { - if (!isset($this->prefs['token'])) { - return; - } - $api = new TelegramApi($this->prefs['token']); - $api->logApiErrors = true; - $blockedChats = []; - foreach ($this->prefs['chats'] as $chatId) { - // try-catch? - $result = $api->sendMessage([ - 'chat_id' => $chatId, - 'parse_mode' => 'HTML', //or MarkdownV2 - 'text' => $text, - 'disable_web_page_preview' => true - ]); - if (!$result && $api->lastError && $api->lastError['error_code'] == 403) { - // User has blocked the bot - $blockedChats[] = $chatId; - error_log("Bot is blocked in chat $chatId, chat will be deactivated"); - } - } - //We can remove blocked chats from settings - if (count($blockedChats) > 0) { - $this->prefs['chats'] = array_diff($this->prefs['chats'], $blockedChats); - \Config::saveDomain(NotificationsExtension::domain, $this->prefs); - } - } - - private function sendTelegramsInBackground(string $text) - { - $hash = password_hash($this->prefs['token'], PASSWORD_DEFAULT); - $dir = __DIR__; - $outfile = ''; # or '> /dev/null 2>&1'; - //$outfile = '> /dev/null 2>&1'; - // if (MTT_DEBUG) { - // $outfile = "> $dir/../../db/cli-notify.log 2>&1"; - // } - $fh = popen("php -f $dir/cli-notify.php $outfile", 'w'); - fwrite($fh, $hash."\n".$text); - fclose($fh); - } - - public static function suggestedMailFrom(): string - { - $host = parse_url(get_unsafe_mttinfo('url'), PHP_URL_HOST); - $host = preg_replace('/^(www\.)/', '', $host); - //$host = gethostname(); - if (function_exists('posix_getpwuid') && false !== ($userinfo = posix_getpwuid(posix_getuid())) ) { - return $userinfo['name']. '@'. $host; - } - return "mytinytodo@$host"; - } - -} diff --git a/src/ext/notifications/class.telegramapi.php b/src/ext/notifications/class.telegramapi.php deleted file mode 100644 index 51df96e..0000000 --- a/src/ext/notifications/class.telegramapi.php +++ /dev/null @@ -1,128 +0,0 @@ - - Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. -*/ - -namespace Notify; - -class TelegramApi -{ - private $token = ''; - /** @var ?array $lastError */ - public $lastError = null; - public $logApiErrors = false; - public $throwExceptionOnApiError = false; - - function __construct(string $token) - { - $this->token = $token; - } - - function getMe(): ?array - { - return $this->makeGetRequest('getMe'); - } - - function getUpdates(?array $params = null): ?array - { - return $this->makePostRequest('getUpdates', $params ?? []); - } - - function sendMessage(array $params): ?array - { - return $this->makePostRequest('sendMessage', $params); - } - - private function makeGetRequest(string $method): ?array - { - $options = array( - 'http' => array( - 'ignore_errors' => true - ) - ); - $context = stream_context_create($options); - $this->lastError = null; - $body = $err = null; - set_error_handler(function ($errno, $message, $file, $line) { - throw new \ErrorException($message, $errno, $errno, $file, $line); - }); - try { - $body = @file_get_contents('https://api.telegram.org/bot'. $this->token .'/'. $method, false, $context); - } - catch (\Exception $e) { - $err = boolval(ini_get('html_errors')) ? htmlspecialchars_decode($e->getMessage()) : $e->getMessage(); - } - restore_error_handler(); - if ($body === false || null !== $err) { - $msg = "Failed to make request to Telegram API ($method)". ($err ? ": $err" : ""); - if ($this->logApiErrors) { - error_log($msg); - } - throw new \Exception($msg); - } - $decodedBody = $this->decodeBody($body, $method); - return $decodedBody['result'] ?? []; - } - - private function makePostRequest(string $method, array $params): ?array - { - $json = json_encode($params, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_INVALID_UTF8_SUBSTITUTE); - $options = array( - 'http' => array( - 'header' => "Content-type: application/json\r\n", - 'method' => 'POST', - 'content' => $json, - 'ignore_errors' => true - ) - ); - $context = stream_context_create($options); - $this->lastError = null; - $body = $err = null; - set_error_handler(function ($errno, $message, $file, $line) { - throw new \ErrorException($message, $errno, $errno, $file, $line); - }); - try { - $body = @file_get_contents('https://api.telegram.org/bot'. $this->token .'/'. $method, false, $context); - } - catch (\Exception $e) { - $err = boolval(ini_get('html_errors')) ? htmlspecialchars_decode($e->getMessage()) : $e->getMessage(); - } - restore_error_handler(); - if ($body === false || null !== $err) { - $msg = "Failed to make request to Telegram API ($method)". ($err ? ": $err" : ""); - if ($this->logApiErrors) { - error_log($msg); - } - throw new \Exception($msg); - } - $decodedBody = $this->decodeBody($body, $method); - return $decodedBody['result'] ?? []; - } - - private function decodeBody(string $body, string $method = ''): array - { - $decodedBody = json_decode($body, true); - if (!is_array($decodedBody)) { - $decodedBody = []; - } - if (!isset($decodedBody['ok'])) { - throw new \Exception("Telegram API ($method) Error"); - } - if ($decodedBody['ok'] === false) { - $this->lastError = [ - 'error_code' => $decodedBody['error_code'] ?? 0, - 'description' => ($decodedBody['description'] ?? '') - ]; - if ($this->logApiErrors) { - error_log("Telegram API ($method) Error ". $this->lastError['error_code']. "): ". $this->lastError['description']); - } - if ($this->throwExceptionOnApiError) { - throw new \Exception("Telegram API ($method) Error ". $this->lastError['error_code']. ": ". $this->lastError['description']); - } - } - return $decodedBody; - } -} diff --git a/src/ext/notifications/cli-notify.php b/src/ext/notifications/cli-notify.php deleted file mode 100644 index 3bbee92..0000000 --- a/src/ext/notifications/cli-notify.php +++ /dev/null @@ -1,63 +0,0 @@ - - Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. -*/ - -set_time_limit(30); - -if (php_sapi_name() != 'cli') { - error_log("Supports cli only"); - exit(-1); -} -if (!function_exists('pcntl_fork')) { - error_log("Required PHP module is not found: pcntl"); - exit(-2); -} -if (!function_exists('posix_setsid')) { - error_log("Required PHP module is not found: posix"); - exit(-2); -} -$dontStartSession = 1; -require(__DIR__.'/../../init.php'); - -$hash = fgets(STDIN); -if ($hash === false) { - error_log("No input"); - exit(-3); -} -$hash = trim($hash); -$text = stream_get_contents(STDIN); - -// Wi will fork a child to do a long work -$pid = pcntl_fork(); -if ($pid == -1) { - error_log("Failed to fork a child"); - exit(-1); -} -else if ($pid) { - // parent will not wait for child's exit - exit; -} - -// Child is here, detach it -if (posix_setsid() < 0) { - error_log("posix_setsid() failed"); - exit; -} - -$prefs = NotificationsExtension::preferences(); -if (!isset($prefs['token'])) { - error_log("No telegram token"); - exit(-4); -} -$token = $prefs['token'] ?? ''; -if (!password_verify($prefs['token'], $hash)) { - error_log("Not authorized"); - exit(-5); -} - -$sender = new Notify\Sender($prefs); -$sender->sendTelegramsWithApi($text); diff --git a/src/ext/notifications/extension.json b/src/ext/notifications/extension.json deleted file mode 100644 index 483f066..0000000 --- a/src/ext/notifications/extension.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "bundleId": "notifications", - "name": "Notifications", - "version": "1.2.1", - "description": "Notify about new tasks and lists on e-mail or telegram" -} diff --git a/src/ext/notifications/lang/de.json b/src/ext/notifications/lang/de.json deleted file mode 100644 index 879c315..0000000 --- a/src/ext/notifications/lang/de.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "ext.notifications.name": "Benachrichtigungen", - "notifications.urlconfigwarning": "Aktivieren Sie die PHP-Direktive 'allow_url_fopen', um Telegram-Benachrichtigungen zu verwenden.", - "notifications.check": "Check", - "notifications.bot_not_configured": "Bot ist nicht konfiguriert", - "notifications.g_email": "E-Mail", - "notifications.h_email": "E-Mail:", - "notifications.d_email": "Mehrere Adressen mit Komma trennen.", - "notifications.h_mailfrom": "Mail von:", - "notifications.d_mailfrom": "Diese E-Mail als Absenderadresse verwenden.", - "notifications.g_telegram": "Telegram", - "notifications.h_token": "Bot-Token:", - "notifications.d_token": "Telegram Bot API-Token von @BotFather", - "notifications.h_active_chats": "Aktive Chats:", - "notifications.d_active_chats": "Anzahl der Chats, bei denen der Bot Benachrichtigungen sendet.", - "notifications.deactivate_all": "Alle deaktivieren", - "notifications.h_new_chat": "Neuer Chat:", - "notifications.d_new_chat": "Starte eine neue Unterhaltung mit dem Bot, sende diesen Code an den Chat und klicke hier auf "Überprüfen".", - "notifications.saved": "Gesichert", - "notifications.invalid_email": "Ungültige E-Mail Adresse", - "notifications.no_bot_info": "Kann keine Bot-Informationen erhalten, Token scheint ungültig zu sein", - "notifications.all_chats_deactivated": "Alle Chats deaktiviert", - "notifications.no_new_chats": "Keine neuen Chats": "Keine neuen Chats", - "notifications.already_active": "Bereits aktiv", - "notifications.please_send": "Bitte senden Sie einen Code zur Aktivierung", - "notifications.code_not_set": "Code ist nicht gesetzt", - "notifications.code_expired": "Der Code ist abgelaufen", - "notifications.code_wrong": "Falscher Code", - "notifications.activated": "Aktiviert" -} diff --git a/src/ext/notifications/lang/en.json b/src/ext/notifications/lang/en.json deleted file mode 100644 index 97c303d..0000000 --- a/src/ext/notifications/lang/en.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "ext.notifications.name": "Notifications", - "notifications.urlconfigwarning": "Enable PHP 'allow_url_fopen' directive to use Telegram notifications.", - "notifications.check": "Check", - "notifications.bot_not_configured": "Bot is not configured", - "notifications.g_email": "E-Mail", - "notifications.h_email": "E-mail:", - "notifications.d_email": "Separate multiple addresses with comma.", - "notifications.h_mailfrom": "Mail from:", - "notifications.d_mailfrom": "Use this e-mail as sender's address.", - "notifications.g_telegram": "Telegram", - "notifications.h_token": "Bot token:", - "notifications.d_token": "Telegram Bot API token from @BotFather.", - "notifications.h_active_chats": "Active chats:", - "notifications.d_active_chats": "Number of chats where bot sends notifications.", - "notifications.deactivate_all": "Deactivate all", - "notifications.h_new_chat": "New chat:", - "notifications.d_new_chat": "Start new conversation with the bot, send this code to the chat and click \"Check\" here.", - "notifications.saved": "Saved", - "notifications.invalid_email": "Invalid email address", - "notifications.no_bot_info": "Can not get bot info, seems token is invalid", - "notifications.all_chats_deactivated": "All chats deactivated", - "notifications.no_new_chats": "No new chats", - "notifications.already_active": "Already active", - "notifications.please_send": "Please send a code to activate", - "notifications.code_not_set": "Code is not set", - "notifications.code_expired": "Code has expired", - "notifications.code_wrong": "Wrong code", - "notifications.activated": "Activated" -} diff --git a/src/ext/notifications/lang/ru.json b/src/ext/notifications/lang/ru.json deleted file mode 100644 index e8e5dcf..0000000 --- a/src/ext/notifications/lang/ru.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "ext.notifications.name": "Уведомления", - "notifications.urlconfigwarning": "Для использования Telegram требуется включить директиву 'allow_url_fopen' в настройках PHP .", - "notifications.check": "Проверить", - "notifications.bot_not_configured": "Бот не настроен", - "notifications.g_email": "E-Mail", - "notifications.h_email": "E-mail:", - "notifications.d_email": "Разделите несколько адресов c помощью запятой.", - "notifications.h_mailfrom": "Адрес отправителя:", - "notifications.d_mailfrom": "Этот адрес будет указан как адрес отправителя в письмах с уведомлениями.", - "notifications.g_telegram": "Telegram", - "notifications.h_token": "Токен для бота:", - "notifications.d_token": "Токен для телеграм-бота, полученный от @BotFather.", - "notifications.h_active_chats": "Активные чаты:", - "notifications.d_active_chats": "Количество чатов, куда бот присылает уведомления.", - "notifications.deactivate_all": "Отключить все", - "notifications.h_new_chat": "Новый чат:", - "notifications.d_new_chat": "Начните чат с ботом, отправьте ему этот код и нажмите \"Проверить\".", - "notifications.saved": "Сохранено", - "notifications.invalid_email": "Некорректный адрес e-mail", - "notifications.no_bot_info": "Ошибка в подключении бота; возможно, токен некорректный", - "notifications.all_chats_deactivated": "All chats deactivated", - "notifications.no_new_chats": "Нет новых чатов", - "notifications.already_active": "Уже активирован", - "notifications.please_send": "Пожалуйста, отправьте код для активации", - "notifications.code_not_set": "Код не установлен", - "notifications.code_expired": "Истек срок действия кода", - "notifications.code_wrong": "Неправильный код", - "notifications.activated": "Активирован" -} diff --git a/src/ext/notifications/loader.php b/src/ext/notifications/loader.php deleted file mode 100644 index 0ebc804..0000000 --- a/src/ext/notifications/loader.php +++ /dev/null @@ -1,244 +0,0 @@ - - Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. -*/ - -if (!defined('MTTPATH')) { - die("Unexpected usage."); -} - -if (!function_exists('mb_internal_encoding')) { - throw new Exception("Required PHP module is not found: mbstring"); -} -if (strtoupper(mb_internal_encoding()) != 'UTF-8') { - throw new Exception("mb_internal_encoding is not UTF-8"); -} - -require_once('class.observer.php'); -require_once('class.controller.php'); -require_once('class.sender.php'); -require_once('class.telegramapi.php'); - - -// on PHP-FPM we can send telegrams on didFinishRequest without delay - -// folder is the bundleId of extension -// name of function for extension loader has format "mtt_ext_${bundleId}_loader" - -function mtt_ext_notifications_instance(): MTTExtension -{ - return new NotificationsExtension(); -} - -use Notify\NotificationObserver; -use Notify\Controller; -use Notify\TelegramApi; - -class NotificationsExtension extends MTTExtension implements MTTHttpApiExtender, MTTExtensionSettingsInterface -{ - //the same as dir name - const bundleId = 'notifications'; - - // settings domain - const domain = "ext.notifications.json"; - - function init() - { - // subscribe for notifications - MTTNotificationCenter::addObserverForNotifications( - [ MTTNotification::didCreateTask, MTTNotification::didCreateList ], - new NotificationObserver() - ); - } - - // produces smth like like /ext/notifications/deactivate - function extendHttpApi(): array - { - return array( - '/deactivate' => [ - 'POST' => [ Controller::class , 'postDeactivateAll' ], - ], - '/check' => [ - 'POST' => [ Controller::class , 'postCheck' ], - ] - ); - } - - function settingsPage(): string - { - $e = function($s) { return __($s, true); }; - $ext = htmlspecialchars(self::bundleId); - $prefs = self::preferences(); - $emails = htmlspecialchars( implode(', ', $prefs['emails']) ); - $mailfrom = htmlspecialchars($prefs['mailfrom'] ?? ''); - $mailfromDefault = htmlspecialchars(Notify\Sender::suggestedMailFrom()); - $numberOfChats = count($prefs['chats']); - - $token = $prefs['token'] ?? ''; - if (defined('MTT_DEMO') && $token != '') { - $token = ""; - } - $token = htmlspecialchars($token); - - $botname = $prefs['botname'] ?? ''; - $botLink = ''; - if ($botname != '') { - $botname = htmlspecialchars($botname); - $botLink = "@$botname"; - - $code = $prefs['code'] ?? null; - $codeExpires = $prefs['codeExpires'] ?? 0; - if ($code === null || $codeExpires < time()) { - $prefs['code'] = $code = randomString(6, '0123456789'); - $prefs['codeExpires'] = $codeExpires = time() + 60*15; // 15 min - Config::saveDomain(self::domain, $prefs); - } - $newChat = "$botLink

$code   {$e('notifications.check')}"; - } - else { - $newChat = $e('notifications.bot_not_configured'); - } - - $warning = ''; - if (!boolval(ini_get('allow_url_fopen'))) { - $warning = "
⚠️ {$e('notifications.urlconfigwarning')}
"; - } - - //$e = function($s) { return __($s, true); }; - //$c = function($key) { return htmlspecialchars(Config::get($key)); }; - - return -<< -
{$e('notifications.g_email')}
- -
-
-
{$e('notifications.h_email')} -
{$e('notifications.d_email')}
-
-
-
-
-
{$e('notifications.h_mailfrom')} -
{$e('notifications.d_mailfrom')}
-
-
-
-
- -
-
{$e('notifications.g_telegram')}
-
-
-
-
{$e('notifications.h_token')} -
{$e('notifications.d_token')}
-
-
-
-
-
{$e('notifications.h_active_chats')} -
{$e('notifications.d_active_chats')}
-
- -
-
-
{$e('notifications.h_new_chat')} -
{$e('notifications.d_new_chat')}
-
-
$newChat
-
-
-EOD; - } - - function settingsPageType(): int - { - return 0; //default page - } - - function saveSettings(array $params, ?string &$outMessage): bool - { - if (defined('MTT_DEMO')) { - $outMessage = "Demo"; - return true; - } - $token = $params['token'] ?? ''; - $emails = $params['emails'] ?? ''; - $mailfrom = $params['mailfrom'] ?? ''; - if (!is_string($token) || !is_string($emails) || !is_string($mailfrom)) { - throw new Exception("Invalid format"); - } - - $prefs = Config::requestDomain(self::domain); - if ($token !== ($prefs['token'] ?? '')) { - $prefs['botname'] = ''; - $prefs['chats'] = []; - $prefs['validToken'] = false; - } - $prefs['token'] = $token; - $prefs['code'] = null; - $prefs['emails'] = []; - $prefs['mailfrom'] = str_replace(["\r", "\n", ":", "\"", "'", "?"], '', trim($mailfrom)); - - // validate emails - if ($emails != '') { - $a = explode(',', $emails); - foreach ($a as $email) { - $email = trim($email); - if (preg_match('/^[^\s\@\|]+@[^\s\@\|]+$/', $email)) { - $prefs['emails'][] = $email; - } - else { - $outMessage = __('notifications.invalid_email'); - return false; - } - } - } - - - // validate token - if ($token != '' && !$prefs['validToken']) { - $api = new TelegramApi($token); - $api->logApiErrors = true; - $api->throwExceptionOnApiError = true; - try { - $result = $api->getMe(); - if ($result && isset($result['username'])) { - $prefs['botname'] = $result['username']; - } - $prefs['validToken'] = true; - } - catch (Exception $e) { - $prefs['token'] = ''; - $outMessage = __('notifications.no_bot_info'); - if (MTT_DEBUG) { - $outMessage .= " (". $e->getMessage(). ")"; - } - return false; - } - } - - Config::saveDomain(self::domain, $prefs); - $outMessage = __('notifications.saved'); - return true; - } - - static function preferences(): array - { - $prefs = Config::requestDomain(self::domain); - if (!isset($prefs['chats']) || !is_array($prefs['chats'])) { - $prefs['chats'] = []; - } - if (!isset($prefs['emails']) || !is_array($prefs['emails'])) { - $prefs['emails'] = []; - } - return $prefs; - } -} diff --git a/src/ext/updater/.htaccess b/src/ext/updater/.htaccess deleted file mode 100644 index 8d2f256..0000000 --- a/src/ext/updater/.htaccess +++ /dev/null @@ -1 +0,0 @@ -deny from all diff --git a/src/ext/updater/class.controller.php b/src/ext/updater/class.controller.php deleted file mode 100644 index 1658ebd..0000000 --- a/src/ext/updater/class.controller.php +++ /dev/null @@ -1,82 +0,0 @@ - - Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. -*/ - -namespace UpdaterExtension; - -use \UpdaterExtension; -use \Config; - -class Controller extends \ApiController -{ - function postCheck() - { - $prefs = UpdaterExtension::preferences(); - $updater = new Updater; - $a = $updater->lastVersionInfo(); - if ($a) { - $prefs['lastCheck'] = time(); - $prefs['version'] = $a['version'] ?? ''; - $prefs['download'] = $a['download'] ?? ''; - Config::saveDomain(UpdaterExtension::domain, $prefs); - $this->response->data = [ 'total' => 1 ]; - } - else { - $this->response->data = [ - 'total' => 0, - 'msg' => __("error"), - 'details' => $updater->lastErrorString ?? '' - ]; - } - } - - function postUpdate() - { - $prefs = UpdaterExtension::preferences(); - $url = $prefs['download'] ?? ''; - if ($url == '') { - $this->response->data = [ 'total' => 0, 'msg' => __("updater.download_error") ]; - return; - } - $updater = new Updater; - $file = MTTPATH. 'update.tar.gz'; - if (!$updater->download($url, $file)) { - $this->response->data = [ - 'total' => 0, - 'msg' => __("updater.download_error"), - 'details' => $updater->lastErrorString ?? '' - ]; - return; - } - if (!$updater->extractAndReplace($file)) { - $this->response->data = [ - 'total' => 0, - 'msg' => __("updater.update_error"), - 'details' => $updater->lastErrorString ?? '' - ]; - return; - } - @unlink($file); - - if (function_exists("opcache_reset")) { - opcache_reset(); - } - - // TODO: need to run post-update by new version - // ... - // remove /includes/lang/cns.json #renamed to zh-cn.jpon - - $prefs['version'] = ''; - $prefs['download'] = ''; - $prefs['lastCheck'] = 0; - Config::saveDomain(UpdaterExtension::domain, $prefs); - - $this->response->data = [ 'total' => 1, 'msg' => __("updater.updated"), 'reload' => 'ext-settings' ]; - } - - -} diff --git a/src/ext/updater/class.updater.php b/src/ext/updater/class.updater.php deleted file mode 100644 index 5ea81ed..0000000 --- a/src/ext/updater/class.updater.php +++ /dev/null @@ -1,142 +0,0 @@ - - Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. -*/ - -namespace UpdaterExtension; - -class Updater -{ - public $lastErrorString = null; - - public function lastVersionInfo(): ?array - { - $options = array( - 'http' => array( - 'header' => "Content-type: application/json\r\nUser-Agent: mytinytodo\r\n" - ) - ); - $context = stream_context_create($options); - set_error_handler(function ($errno, $message, $file, $line) { - throw new \ErrorException($message, $errno, $errno, $file, $line); - }); - $json = null; - $this->lastErrorString = null; - try { - $json = @file_get_contents("https://api.github.com/repos/maxpozdeev/mytinytodo/releases", false, $context); - } - catch (\Exception $e) { - $this->lastErrorString = boolval(ini_get('html_errors')) ? htmlspecialchars_decode($e->getMessage()) : $e->getMessage(); - } - restore_error_handler(); - if ($json === false || $json == '') { - error_log("Failed to get releases info: ".$this->lastErrorString); - return null; - } - $releases = json_decode($json, true) ?? []; - - $a = null; - foreach ($releases as $rel) { - // find only stable - if ($rel['prerelease'] ?? false) { - continue; - } - $ver = substr($rel['tag_name'] ?? 'v', 1); - if ($ver == '') continue; - if ($a && version_compare($a['__ver'], $ver)) { - continue; // skip lower version - } - $rel['__ver'] = $ver; - $a = $rel; - } - if (null === $a) { - $this->lastErrorString = "No release to update to"; - return null; - } - - $ret = []; - $ver = ''; - if (isset($a['tag_name'])) { - $ver = substr($a['tag_name'], 1); //remove first 'v' - } - if ($ver != '' && isset($a['assets']) && - is_array($a['assets']) && count($a['assets']) > 0 && - ($asset = $a['assets'][0]) && isset($asset['browser_download_url']) ) - { - $ret['version'] = $ver; - $ret['download'] = $asset['browser_download_url']; - } - else { - error_log("HTTP response contains unexpected content"); - $this->lastErrorString = "HTTP response contains unexpected content"; - } - return $ret; - } - - public function download(string $url, string $outfile): bool - { - $this->lastErrorString = null; - $dir = dirname($outfile); - if (!is_dir($dir) || !is_writable($dir)) { - $this->lastErrorString = "myTinyTodo directory is not writable"; - return false; - } - $f = @fopen($url, 'r'); - if ($f === false) { - $ea = error_get_last(); - $this->lastErrorString = $ea['message'] ?? "Failed to open stream"; - return false; - } - $bytes = @file_put_contents($outfile, $f, LOCK_EX); - $ea = error_get_last(); - fclose($f); - if ($bytes === false) { - $this->lastErrorString = $ea['message'] ?? "Can not save file"; - return false; - } - return true; - } - - public function extractAndReplace(string $filename): bool - { - $this->lastErrorString = null; - $dir = MTTPATH; - if (!is_dir($dir) || !is_writable($dir)) { - $this->lastErrorString = "myTinyTodo directory is not writable"; - return false; - } - - $output = null; - $retval = null; - $command = "tar xzf ". escapeshellarg($filename). " --strip-components 1 -C ". escapeshellarg($dir). " 2>&1"; - @exec($command, $output, $retval); - if ($retval != 0) { - $this->lastErrorString = "Failed to execute tar command ($retval): ". ($output ? implode("\n", $output) : "no output"); - error_log($this->lastErrorString); - return false; - } - - // Extensions - $dir = MTT_EXT; - $filename = $dir . 'extensions.tar.gz'; - if (file_exists($filename)) { - if (!is_writable($dir)) { - $this->lastErrorString = "Extensions directory is not writable"; - return false; - } - $command = "tar xzf ". escapeshellarg($filename). " -C ". escapeshellarg($dir). " 2>&1"; - @exec($command, $output, $retval); - if ($retval != 0) { - $this->lastErrorString = "Extensions: failed to execute tar command ($retval): ". ($output ? implode("\n", $output) : "no output"); - error_log($this->lastErrorString); - return false; - } - unlink($filename); - } - - return true; - } -} diff --git a/src/ext/updater/extension.json b/src/ext/updater/extension.json deleted file mode 100644 index 5b05bcd..0000000 --- a/src/ext/updater/extension.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "bundleId": "updater", - "name": "Updates", - "version": "0.9.3", - "description": "myTinyTodo self-updater" -} diff --git a/src/ext/updater/lang/de.json b/src/ext/updater/lang/de.json deleted file mode 100644 index dbe78ef..0000000 --- a/src/ext/updater/lang/de.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "ext.updater.name": "Updates", - "updater.urlconfigwarning": "Aktivieren Sie die PHP-Anweisung 'allow_url_fopen', um Updates herunterladen zu können.", - "updater.tarwarning": "Update nicht möglich, 'tar' Erweiterung nicht gefunden.", - "updater.h_check_updates": "Checke Updates", - "updater.check": "Check", - "updater.no_updates": "Keine Updates", - "updater.last_version": "Letzte verfügbare Version: %s", - "updater.current_version": "Aktuelle Version", - "updater.last_checked": "Letzter Check", - "updater.new_version_available": "Neue Version verfügbar", - "updater.update": "Update", - "updater.updated": "Update komplett", - "updater.download_error": "Download fehlgeschlagen", - "updater.update_error": "Updatefehler" -} diff --git a/src/ext/updater/lang/en.json b/src/ext/updater/lang/en.json deleted file mode 100644 index af2972a..0000000 --- a/src/ext/updater/lang/en.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "ext.updater.name": "Updates", - "updater.urlconfigwarning": "Enable PHP 'allow_url_fopen' directive to be able to download updates.", - "updater.tarwarning": "Update is not possible, 'tar' utility is not found.", - "updater.h_check_updates": "Check updates", - "updater.check": "Check", - "updater.no_updates": "No updates", - "updater.last_version": "Last available version: %s", - "updater.current_version": "Current version", - "updater.last_checked": "Last checked", - "updater.new_version_available": "New version is available", - "updater.update": "Update", - "updater.updated": "Update has completed", - "updater.download_error": "Download failed", - "updater.update_error": "Update error" -} diff --git a/src/ext/updater/lang/ru.json b/src/ext/updater/lang/ru.json deleted file mode 100644 index 49a532c..0000000 --- a/src/ext/updater/lang/ru.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "ext.updater.name": "Обновления", - "updater.urlconfigwarning": "Для получения обновлений требуется включить директиву 'allow_url_fopen' в настройках PHP .", - "updater.tarwarning": "Исполняемый файл 'tar' не найден, обновление невозможно.", - "updater.h_check_updates": "Проверка обновлений", - "updater.check": "Проверить", - "updater.no_updates": "Нет обновлений", - "updater.last_version": "Актуальная версия: %s", - "updater.current_version": "Текущая версия", - "updater.last_checked": "Последняя проверка", - "updater.new_version_available": "Доступно обновление", - "updater.update": "Обновить", - "updater.updated": "Обновление завершено", - "updater.download_error": "Ошибка при загрузке", - "updater.update_error": "Ошибка при обновлении" -} diff --git a/src/ext/updater/loader.php b/src/ext/updater/loader.php deleted file mode 100644 index 8d238ac..0000000 --- a/src/ext/updater/loader.php +++ /dev/null @@ -1,129 +0,0 @@ - - Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. -*/ - -if (!defined('MTTPATH')) { - die("Unexpected usage."); -} - -require_once('class.controller.php'); -require_once('class.updater.php'); - -function mtt_ext_updater_instance(): MTTExtension -{ - return new UpdaterExtension(); -} - -use UpdaterExtension\Controller; -use UpdaterExtension\Updater; - -class UpdaterExtension extends MTTExtension implements MTTExtensionSettingsInterface, MTTHttpApiExtender -{ - //the same as dir name - const bundleId = 'updater'; - - // settings domain - const domain = "ext.updater.json"; - - function init() - { - } - - // MTTHttpApiExtender - function extendHttpApi(): array - { - return array( - '/check' => [ - 'POST' => [ Controller::class , 'postCheck' ], - ], - '/update' => [ - 'POST' => [ Controller::class , 'postUpdate' ], - ] - ); - } - - function settingsPage(): string - { - $e = function($s, $arg=null) { return __($s, true, $arg); }; - $ext = htmlspecialchars(self::bundleId); - $prefs = self::preferences(); - $lastCheck = $prefs['lastCheck'] ?? 0; - $version = $prefs['version'] ?? ''; - $updateStr = ''; - $curVersion = htmlspecialchars(mytinytodo\Version::VERSION); - $err = null; - if (time() - $lastCheck > 86400*7) { - $updater = new Updater; - $a = $updater->lastVersionInfo(); - if ($a) { - $lastCheck = $prefs['lastCheck'] = time(); - $version = $prefs['version'] = $a['version'] ?? ''; - $prefs['download'] = $a['download'] ?? ''; - Config::saveDomain(self::domain, $prefs); - } - else { - $err = $updater->lastErrorString; - } - } - $warning = ''; - if ($version != '') { - if ( version_compare($version, mytinytodo\Version::VERSION) > 0 ) { - $updateStr = "
{$e('updater.new_version_available')}: ". htmlspecialchars($version); - # allow update to v1.7.x and 1.8.x only - if ( in_array(substr($version, 0, 4), ["1.7.", "1.8."]) ) { - $updateStr .= "

\n {$e('updater.update')} "; - } - $retval = 0; - $output = null; - unset($output); - @exec('tar --version', $output, $retval); - if ($retval != 0) { - $warning = "
⚠️ {$e('updater.tarwarning')}
"; - } - } - else { - $updateStr = "
{$e('updater.no_updates')}
{$e('updater.last_version', $version)}"; - } - } - $lastCheckStr = $err ? $e('updater.download_error') : ($lastCheck ? timestampToDatetime($lastCheck, true) : ""); - - if (!boolval(ini_get('allow_url_fopen'))) { - $warning .= "
⚠️ {$e('updater.urlconfigwarning')}
"; - } - - - return -<< -
{$e('updater.h_check_updates')}
-
- {$e('updater.current_version')}: $curVersion
- {$e('updater.last_checked')}: $lastCheckStr  
- $updateStr -
- -EOD; - } - - function settingsPageType(): int - { - return 1; // no form buttons - } - - function saveSettings(array $params, ?string &$outMessage): bool - { - return true; - } - - - static function preferences(): array - { - $prefs = Config::requestDomain(self::domain); - return $prefs; - } -} diff --git a/src/includes/.htaccess b/src/includes/.htaccess deleted file mode 100644 index 8d2f256..0000000 --- a/src/includes/.htaccess +++ /dev/null @@ -1 +0,0 @@ -deny from all diff --git a/src/includes/lang/en-rtl.json b/src/includes/lang/en-rtl.json deleted file mode 100644 index a368953..0000000 --- a/src/includes/lang/en-rtl.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "_header": { - "ver": "v1.6", - "date": "2020-09-04", - "language": "English (for RTL test)", - "original_name": "English RTL", - "author": "Max Pozdeev", - "author_url": "http://www.mytinytodo.net", - "rtl": 1 - } -} diff --git a/src/mtt-edit-settings.php b/src/mtt-edit-settings.php deleted file mode 100644 index 556c61c..0000000 --- a/src/mtt-edit-settings.php +++ /dev/null @@ -1,47 +0,0 @@ - \n". - " mtt-edit-settings.php write \n". - " mtt-edit-settings.php password \n" - ); -} - -$dontStartSession = true; -require_once(__DIR__ . '/init.php'); - -$cmd = $argv[1]; -$param = $argv[2]; -$value = $argc > 3 ? $argv[3] : null; - - -switch ($cmd) { - case 'read': cmd_read($param, $value); break; - case 'write': cmd_write($param, $value); break; - case 'password': cmd_password($param); break; - default: die("Unknown command: $cmd\n"); -} - - -function cmd_read($param) { - print Config::get($param) . "\n"; -} - -function cmd_write($param, $value) { - if ($value === null) { - die("Can not write '$param': value is not specified\n"); - } - print ("Set '$param' to '$value'\n"); - Config::set($param, $value); - Config::save(); - print ("Done!\n"); -} - -function cmd_password($value) { - $value = passwordHash($value); - cmd_write('password', $value); -}