From d867d640a44de3e4af46c8296ee0ff748224fc9d Mon Sep 17 00:00:00 2001 From: mirzaev Date: Fri, 11 Apr 2025 03:40:05 +0700 Subject: [PATCH] added search process and main menu --- author/project/system/models/traits/files.php | 67 - composer.json | 13 +- examples/systemd/deeproots.service | 16 + .../deeproots}/system/controllers/core.php | 13 +- .../deeproots}/system/controllers/index.php | 0 .../deeproots}/system/databases/.gitignore | 0 .../system/localizations/english.php | 184 ++ .../system/localizations/russian.php | 184 ++ mirzaev/deeproots/system/models/account.php | 224 ++ mirzaev/deeproots/system/models/answer.php | 110 + .../deeproots/system/models/connection.php | 110 + .../deeproots}/system/models/core.php | 1 - .../system/models/enumerations/language.php | 36 +- mirzaev/deeproots/system/models/question.php | 98 + .../system/models/question/localization.php | 110 + mirzaev/deeproots/system/models/telegram.php | 192 ++ .../buttons/account/localization/create.php | 228 ++ .../buttons/account/localization/update.php | 102 + .../telegram/buttons/question/search.php | 579 +++++ .../system/models/telegram/commands.php | 741 ++++++ .../system/models/telegram/middlewares.php | 706 ++++++ .../telegram/processes/language/select.php | 150 ++ .../telegram/processes/question/create.php | 124 + .../question/localization/create.php | 1124 +++++++++ .../telegram/processes/question/search.php | 2226 +++++++++++++++++ .../system/models/telegram/settings.php | 156 ++ .../system/models/telegram/traits/escape.php | 57 + .../system/public/css/fonts/dejavu.css | 0 .../system/public/css/fonts/fira.css | 0 .../system/public/css/fonts/hack.css | 0 .../system/public/fonts/commissioner.ttf | Bin .../fonts/dejavu/DejaVuLGCSans-Bold.ttf | Bin .../dejavu/DejaVuLGCSans-BoldOblique.ttf | Bin .../fonts/dejavu/DejaVuLGCSans-ExtraLight.ttf | Bin .../fonts/dejavu/DejaVuLGCSans-Oblique.ttf | Bin .../public/fonts/dejavu/DejaVuLGCSans.ttf | Bin .../dejavu/DejaVuLGCSansCondensed-Bold.ttf | Bin .../DejaVuLGCSansCondensed-BoldOblique.ttf | Bin .../dejavu/DejaVuLGCSansCondensed-Oblique.ttf | Bin .../fonts/dejavu/DejaVuLGCSansCondensed.ttf | Bin .../fonts/dejavu/DejaVuLGCSansMono-Bold.ttf | Bin .../dejavu/DejaVuLGCSansMono-BoldOblique.ttf | Bin .../dejavu/DejaVuLGCSansMono-Oblique.ttf | Bin .../public/fonts/dejavu/DejaVuLGCSansMono.ttf | Bin .../fonts/dejavu/DejaVuLGCSerif-Bold.ttf | Bin .../dejavu/DejaVuLGCSerif-BoldItalic.ttf | Bin .../fonts/dejavu/DejaVuLGCSerif-Italic.ttf | Bin .../public/fonts/dejavu/DejaVuLGCSerif.ttf | Bin .../dejavu/DejaVuLGCSerifCondensed-Bold.ttf | Bin .../DejaVuLGCSerifCondensed-BoldItalic.ttf | Bin .../dejavu/DejaVuLGCSerifCondensed-Italic.ttf | Bin .../fonts/dejavu/DejaVuLGCSerifCondensed.ttf | Bin .../public/fonts/fira/FiraMono-Bold.woff | Bin .../public/fonts/fira/FiraMono-Bold.woff2 | Bin .../public/fonts/fira/FiraMono-Medium.woff | Bin .../public/fonts/fira/FiraMono-Medium.woff2 | Bin .../public/fonts/fira/FiraMono-Regular.woff | Bin .../public/fonts/fira/FiraMono-Regular.woff2 | Bin .../public/fonts/fira/FiraSans-Bold.woff | Bin .../public/fonts/fira/FiraSans-Bold.woff2 | Bin .../fonts/fira/FiraSans-BoldItalic.woff | Bin .../fonts/fira/FiraSans-BoldItalic.woff2 | Bin .../public/fonts/fira/FiraSans-Book.woff | Bin .../public/fonts/fira/FiraSans-Book.woff2 | Bin .../fonts/fira/FiraSans-BookItalic.woff | Bin .../fonts/fira/FiraSans-BookItalic.woff2 | Bin .../public/fonts/fira/FiraSans-Eight.woff | Bin .../public/fonts/fira/FiraSans-Eight.woff2 | Bin .../fonts/fira/FiraSans-EightItalic.woff | Bin .../fonts/fira/FiraSans-EightItalic.woff2 | Bin .../public/fonts/fira/FiraSans-ExtraBold.woff | Bin .../fonts/fira/FiraSans-ExtraBold.woff2 | Bin .../fonts/fira/FiraSans-ExtraBoldItalic.woff | Bin .../fonts/fira/FiraSans-ExtraBoldItalic.woff2 | Bin .../fonts/fira/FiraSans-ExtraLight.woff | Bin .../fonts/fira/FiraSans-ExtraLight.woff2 | Bin .../fonts/fira/FiraSans-ExtraLightItalic.woff | Bin .../fira/FiraSans-ExtraLightItalic.woff2 | Bin .../public/fonts/fira/FiraSans-Four.woff | Bin .../public/fonts/fira/FiraSans-Four.woff2 | Bin .../fonts/fira/FiraSans-FourItalic.woff | Bin .../fonts/fira/FiraSans-FourItalic.woff2 | Bin .../public/fonts/fira/FiraSans-Hair.woff | Bin .../public/fonts/fira/FiraSans-Hair.woff2 | Bin .../fonts/fira/FiraSans-HairItalic.woff | Bin .../fonts/fira/FiraSans-HairItalic.woff2 | Bin .../public/fonts/fira/FiraSans-Heavy.woff | Bin .../public/fonts/fira/FiraSans-Heavy.woff2 | Bin .../fonts/fira/FiraSans-HeavyItalic.woff | Bin .../fonts/fira/FiraSans-HeavyItalic.woff2 | Bin .../public/fonts/fira/FiraSans-Italic.woff | Bin .../public/fonts/fira/FiraSans-Italic.woff2 | Bin .../public/fonts/fira/FiraSans-Light.woff | Bin .../public/fonts/fira/FiraSans-Light.woff2 | Bin .../fonts/fira/FiraSans-LightItalic.woff | Bin .../fonts/fira/FiraSans-LightItalic.woff2 | Bin .../public/fonts/fira/FiraSans-Medium.woff | Bin .../public/fonts/fira/FiraSans-Medium.woff2 | Bin .../fonts/fira/FiraSans-MediumItalic.woff | Bin .../fonts/fira/FiraSans-MediumItalic.woff2 | Bin .../public/fonts/fira/FiraSans-Regular.woff | Bin .../public/fonts/fira/FiraSans-Regular.woff2 | Bin .../public/fonts/fira/FiraSans-SemiBold.woff | Bin .../public/fonts/fira/FiraSans-SemiBold.woff2 | Bin .../fonts/fira/FiraSans-SemiBoldItalic.woff | Bin .../fonts/fira/FiraSans-SemiBoldItalic.woff2 | Bin .../public/fonts/fira/FiraSans-Thin.woff | Bin .../public/fonts/fira/FiraSans-Thin.woff2 | Bin .../fonts/fira/FiraSans-ThinItalic.woff | Bin .../fonts/fira/FiraSans-ThinItalic.woff2 | Bin .../public/fonts/fira/FiraSans-Two.woff | Bin .../public/fonts/fira/FiraSans-Two.woff2 | Bin .../public/fonts/fira/FiraSans-TwoItalic.woff | Bin .../fonts/fira/FiraSans-TwoItalic.woff2 | Bin .../public/fonts/fira/FiraSans-Ultra.woff | Bin .../public/fonts/fira/FiraSans-Ultra.woff2 | Bin .../fonts/fira/FiraSans-UltraItalic.woff | Bin .../fonts/fira/FiraSans-UltraItalic.woff2 | Bin .../fonts/fira/FiraSans-UltraLight.woff | Bin .../fonts/fira/FiraSans-UltraLight.woff2 | Bin .../fonts/fira/FiraSans-UltraLightItalic.woff | Bin .../fira/FiraSans-UltraLightItalic.woff2 | Bin .../public/fonts/hack/hack-bold-subset.woff | Bin .../public/fonts/hack/hack-bold-subset.woff2 | Bin .../system/public/fonts/hack/hack-bold.woff | Bin .../system/public/fonts/hack/hack-bold.woff2 | Bin .../fonts/hack/hack-bolditalic-subset.woff | Bin .../fonts/hack/hack-bolditalic-subset.woff2 | Bin .../public/fonts/hack/hack-bolditalic.woff | Bin .../public/fonts/hack/hack-bolditalic.woff2 | Bin .../public/fonts/hack/hack-italic-subset.woff | Bin .../fonts/hack/hack-italic-subset.woff2 | Bin .../system/public/fonts/hack/hack-italic.woff | Bin .../public/fonts/hack/hack-italic.woff2 | Bin .../fonts/hack/hack-regular-subset.woff | Bin .../fonts/hack/hack-regular-subset.woff2 | Bin .../public/fonts/hack/hack-regular.woff | Bin .../public/fonts/hack/hack-regular.woff2 | Bin .../deeproots}/system/public/index.php | 0 mirzaev/deeproots/system/public/telegram.php | 104 + .../public/themes/default/css/aside.css | 0 .../public/themes/default/css/colors.css | 0 .../public/themes/default/css/fonts.css | 0 .../public/themes/default/css/footer.css | 0 .../public/themes/default/css/header.css | 0 .../system/public/themes/default/css/main.css | 0 .../public/themes/default/css/system.css | 0 .../deeproots}/system/settings/.gitignore | 0 .../system/settings/arangodb.php.sample | 0 .../system/settings/system.php.sample | 0 .../system/settings/telegram.php.sample | 3 + .../system/storage/images/mushroom.jpg | Bin 0 -> 47658 bytes .../deeproots}/system/views/templater.php | 0 .../system/views/themes/default/aside.html | 0 .../system/views/themes/default/core.html | 0 .../system/views/themes/default/footer.html | 0 .../system/views/themes/default/head.html | 0 .../system/views/themes/default/header.html | 0 .../system/views/themes/default/index.html | 0 .../system/views/themes/default/js.html | 0 160 files changed, 7566 insertions(+), 92 deletions(-) delete mode 100755 author/project/system/models/traits/files.php create mode 100644 examples/systemd/deeproots.service rename {author/project => mirzaev/deeproots}/system/controllers/core.php (79%) rename {author/project => mirzaev/deeproots}/system/controllers/index.php (100%) rename {author/project => mirzaev/deeproots}/system/databases/.gitignore (100%) create mode 100644 mirzaev/deeproots/system/localizations/english.php create mode 100644 mirzaev/deeproots/system/localizations/russian.php create mode 100755 mirzaev/deeproots/system/models/account.php create mode 100755 mirzaev/deeproots/system/models/answer.php create mode 100755 mirzaev/deeproots/system/models/connection.php rename {author/project => mirzaev/deeproots}/system/models/core.php (95%) rename {author/project => mirzaev/deeproots}/system/models/enumerations/language.php (55%) create mode 100755 mirzaev/deeproots/system/models/question.php create mode 100755 mirzaev/deeproots/system/models/question/localization.php create mode 100755 mirzaev/deeproots/system/models/telegram.php create mode 100755 mirzaev/deeproots/system/models/telegram/buttons/account/localization/create.php create mode 100755 mirzaev/deeproots/system/models/telegram/buttons/account/localization/update.php create mode 100755 mirzaev/deeproots/system/models/telegram/buttons/question/search.php create mode 100755 mirzaev/deeproots/system/models/telegram/commands.php create mode 100755 mirzaev/deeproots/system/models/telegram/middlewares.php create mode 100755 mirzaev/deeproots/system/models/telegram/processes/language/select.php create mode 100755 mirzaev/deeproots/system/models/telegram/processes/question/create.php create mode 100755 mirzaev/deeproots/system/models/telegram/processes/question/localization/create.php create mode 100755 mirzaev/deeproots/system/models/telegram/processes/question/search.php create mode 100755 mirzaev/deeproots/system/models/telegram/settings.php create mode 100644 mirzaev/deeproots/system/models/telegram/traits/escape.php rename {author/project => mirzaev/deeproots}/system/public/css/fonts/dejavu.css (100%) rename {author/project => mirzaev/deeproots}/system/public/css/fonts/fira.css (100%) rename {author/project => mirzaev/deeproots}/system/public/css/fonts/hack.css (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/commissioner.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/dejavu/DejaVuLGCSans-Bold.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/dejavu/DejaVuLGCSans-BoldOblique.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/dejavu/DejaVuLGCSans-ExtraLight.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/dejavu/DejaVuLGCSans-Oblique.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/dejavu/DejaVuLGCSans.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/dejavu/DejaVuLGCSansCondensed-Bold.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/dejavu/DejaVuLGCSansCondensed-BoldOblique.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/dejavu/DejaVuLGCSansCondensed-Oblique.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/dejavu/DejaVuLGCSansCondensed.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/dejavu/DejaVuLGCSansMono-Bold.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/dejavu/DejaVuLGCSansMono-BoldOblique.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/dejavu/DejaVuLGCSansMono-Oblique.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/dejavu/DejaVuLGCSansMono.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/dejavu/DejaVuLGCSerif-Bold.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/dejavu/DejaVuLGCSerif-BoldItalic.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/dejavu/DejaVuLGCSerif-Italic.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/dejavu/DejaVuLGCSerif.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/dejavu/DejaVuLGCSerifCondensed-Bold.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/dejavu/DejaVuLGCSerifCondensed-BoldItalic.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/dejavu/DejaVuLGCSerifCondensed-Italic.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/dejavu/DejaVuLGCSerifCondensed.ttf (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraMono-Bold.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraMono-Bold.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraMono-Medium.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraMono-Medium.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraMono-Regular.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraMono-Regular.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Bold.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Bold.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-BoldItalic.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-BoldItalic.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Book.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Book.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-BookItalic.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-BookItalic.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Eight.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Eight.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-EightItalic.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-EightItalic.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-ExtraBold.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-ExtraBold.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-ExtraBoldItalic.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-ExtraBoldItalic.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-ExtraLight.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-ExtraLight.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-ExtraLightItalic.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-ExtraLightItalic.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Four.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Four.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-FourItalic.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-FourItalic.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Hair.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Hair.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-HairItalic.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-HairItalic.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Heavy.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Heavy.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-HeavyItalic.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-HeavyItalic.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Italic.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Italic.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Light.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Light.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-LightItalic.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-LightItalic.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Medium.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Medium.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-MediumItalic.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-MediumItalic.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Regular.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Regular.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-SemiBold.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-SemiBold.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-SemiBoldItalic.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-SemiBoldItalic.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Thin.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Thin.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-ThinItalic.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-ThinItalic.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Two.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Two.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-TwoItalic.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-TwoItalic.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Ultra.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-Ultra.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-UltraItalic.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-UltraItalic.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-UltraLight.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-UltraLight.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-UltraLightItalic.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/fira/FiraSans-UltraLightItalic.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/hack/hack-bold-subset.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/hack/hack-bold-subset.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/hack/hack-bold.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/hack/hack-bold.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/hack/hack-bolditalic-subset.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/hack/hack-bolditalic-subset.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/hack/hack-bolditalic.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/hack/hack-bolditalic.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/hack/hack-italic-subset.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/hack/hack-italic-subset.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/hack/hack-italic.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/hack/hack-italic.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/hack/hack-regular-subset.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/hack/hack-regular-subset.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/hack/hack-regular.woff (100%) rename {author/project => mirzaev/deeproots}/system/public/fonts/hack/hack-regular.woff2 (100%) rename {author/project => mirzaev/deeproots}/system/public/index.php (100%) create mode 100755 mirzaev/deeproots/system/public/telegram.php rename {author/project => mirzaev/deeproots}/system/public/themes/default/css/aside.css (100%) rename {author/project => mirzaev/deeproots}/system/public/themes/default/css/colors.css (100%) rename {author/project => mirzaev/deeproots}/system/public/themes/default/css/fonts.css (100%) rename {author/project => mirzaev/deeproots}/system/public/themes/default/css/footer.css (100%) rename {author/project => mirzaev/deeproots}/system/public/themes/default/css/header.css (100%) rename {author/project => mirzaev/deeproots}/system/public/themes/default/css/main.css (100%) rename {author/project => mirzaev/deeproots}/system/public/themes/default/css/system.css (100%) rename {author/project => mirzaev/deeproots}/system/settings/.gitignore (100%) rename {author/project => mirzaev/deeproots}/system/settings/arangodb.php.sample (100%) rename {author/project => mirzaev/deeproots}/system/settings/system.php.sample (100%) create mode 100755 mirzaev/deeproots/system/settings/telegram.php.sample create mode 100755 mirzaev/deeproots/system/storage/images/mushroom.jpg rename {author/project => mirzaev/deeproots}/system/views/templater.php (100%) rename {author/project => mirzaev/deeproots}/system/views/themes/default/aside.html (100%) rename {author/project => mirzaev/deeproots}/system/views/themes/default/core.html (100%) rename {author/project => mirzaev/deeproots}/system/views/themes/default/footer.html (100%) rename {author/project => mirzaev/deeproots}/system/views/themes/default/head.html (100%) rename {author/project => mirzaev/deeproots}/system/views/themes/default/header.html (100%) rename {author/project => mirzaev/deeproots}/system/views/themes/default/index.html (100%) rename {author/project => mirzaev/deeproots}/system/views/themes/default/js.html (100%) diff --git a/author/project/system/models/traits/files.php b/author/project/system/models/traits/files.php deleted file mode 100755 index 415dff5..0000000 --- a/author/project/system/models/traits/files.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @author mirzaev - */ -trait files -{ - /** - * Delete - * - * Delete files recursively - * - * @param string $directory Directory - * @param array &$errors Registry of errors - * - * @return void - */ - private static function delete(string $directory, array &$errors = []): void - { - try { - if (file_exists($directory)) { - // Directory exists - - // Deleting descendant files and directories (enter to the recursion) - foreach (scandir($directory) as $file) { - if ($file === '.' || $file === '..') continue; - else if (is_dir("$directory/$file")) static::delete("$directory/$file", $errors); - else unlink("$directory/$file"); - } - - // Deleting the directory - rmdir($directory); - - // Exit (success) - return; - } else throw new exception('Directory does not exist'); - } catch (exception $e) { - // Writing to the registry of errors - $errors[] = [ - 'text' => $e->getMessage(), - 'file' => $e->getFile(), - 'line' => $e->getLine(), - 'stack' => $e->getTrace() - ]; - } - - // Exit (fail) - return; - } -} diff --git a/composer.json b/composer.json index e9c86b4..0c05d9f 100755 --- a/composer.json +++ b/composer.json @@ -27,7 +27,12 @@ "mirzaev/baza": "^3.3", "twig/twig": "^3.10", "twig/extra-bundle": "^3.7", - "twig/intl-extra": "^3.10" + "twig/intl-extra": "^3.10", + "svoboda/time": "^1.0", + "badfarm/zanzara": "^0.9.1", + "nyholm/psr7": "^1.8", + "react/filesystem": "^0.1.2", + "react/async": "^4.3" }, "autoload": { "psr-4": { @@ -41,5 +46,11 @@ }, "scripts": { "pre-update-cmd": "./install.sh" + }, + "config": { + "allow-plugins": { + "php-http/discovery": true, + "wyrihaximus/composer-update-bin-autoload-path": true + } } } diff --git a/examples/systemd/deeproots.service b/examples/systemd/deeproots.service new file mode 100644 index 0000000..88ad42c --- /dev/null +++ b/examples/systemd/deeproots.service @@ -0,0 +1,16 @@ +[Unit] +Description=Telegram chat-robot: @domain_of_your_robot_here + +Wants=network.target +After=syslog.target network-online.target + +[Service] +ExecStart=sudo -u www-data /usr/bin/php /var/www/deeproots/mirzaev/deeproots/system/public/telegram.php +PIDFile=/var/run/php/deeproots.pid +RemainAfterExit=no +RuntimeMaxSec=3600s +Restart=always +RestartSec=5s + +[Install] +WantedBy=multi-user.target diff --git a/author/project/system/controllers/core.php b/mirzaev/deeproots/system/controllers/core.php similarity index 79% rename from author/project/system/controllers/core.php rename to mirzaev/deeproots/system/controllers/core.php index a939477..982e8f9 100755 --- a/author/project/system/controllers/core.php +++ b/mirzaev/deeproots/system/controllers/core.php @@ -5,10 +5,7 @@ declare(strict_types=1); namespace mirzaev\deeproots\controllers; // Files of the project -use mirzaev\deeproots\views\templater, - mirzaev\deeproots\models\core as models, - mirzaev\deeproots\models\session, - mirzaev\deeproots\models\enumerations\language; +use mirzaev\deeproots\models\core as models; // Framework for PHP use mirzaev\minimal\core as minimal, @@ -25,11 +22,10 @@ use mirzaev\minimal\core as minimal, * @param response $response Response * @param array $errors Registry of errors * - * @method void __construct(minimal $minimal) Constructor + * @method void __construct(minimal $minimal, bool $initialize) Constructor * * @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License - * @author Arsen Mirzaev Tatyano-Muradovich - * @author mirzaev + * @author svoboda */ class core extends controller { @@ -58,7 +54,6 @@ class core extends controller * @var array $errors Registry of errors */ protected array $errors = [ - 'system' => [] ]; /** @@ -69,7 +64,7 @@ class core extends controller * * @return void */ - public function __construct(minimal $core) + public function __construct(minimal $core, bool $initialize = true) { // Blocking requests from CloudFlare (better to write this blocking into nginx config file) if (isset($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT'] === 'nginx-ssl early hints') return status::bruh->label; diff --git a/author/project/system/controllers/index.php b/mirzaev/deeproots/system/controllers/index.php similarity index 100% rename from author/project/system/controllers/index.php rename to mirzaev/deeproots/system/controllers/index.php diff --git a/author/project/system/databases/.gitignore b/mirzaev/deeproots/system/databases/.gitignore similarity index 100% rename from author/project/system/databases/.gitignore rename to mirzaev/deeproots/system/databases/.gitignore diff --git a/mirzaev/deeproots/system/localizations/english.php b/mirzaev/deeproots/system/localizations/english.php new file mode 100644 index 0000000..578a9f8 --- /dev/null +++ b/mirzaev/deeproots/system/localizations/english.php @@ -0,0 +1,184 @@ + 'DeepRoots', + 'empty' => 'Empty', + 'yes' => 'Yes', + 'no' => 'No', + + // Main menu + 'menu_title' => 'Main menu', + 'menu_button_start' => 'Start', + 'menu_button_rating' => 'Rating', + 'menu_button_balance' => 'Balance', + 'menu_button_system_accounts' => 'Accounts', + 'menu_button_system_questions' => 'Questions', + 'menu_button_system_settings' => 'Settings', + 'menu_system_authorized' => 'System authorization found', + + // Account + 'account_title' => 'Account', + 'account_identifier' => 'Identifier', + 'account_authorized_system' => 'Access to the system', + 'account_authorized_game_play' => 'Access to play games', + 'account_authorized_rating_display' => 'Access to display in the rating', + 'account_authorized_balance_deposit' => 'Access to deposit into the balance', + 'account_authorized_balance_withdraw' => 'Access to withdraw from the balance', + 'account_authorized_settings' => 'Access to settings', + 'account_authorized_system_accounts' => 'System access to accounts', + 'account_authorized_system_questions' => 'System access to questions', + 'account_authorized_system_settings' => 'System access to system settings', + + // Language setting + 'settings_select_language_title' => 'Select language', + 'settings_select_language_description' => 'The selected language will be writed in your account settings', + 'settings_language_update_success' => 'Language replaced:', + 'settings_language_update_fail' => 'Failed to replace language', + + // Language selection + 'select_language_title' => 'Select language', + 'select_language_description' => 'The selected language will be used in the current process', + 'select_language_button_add' => 'Add a language', + + // Repository + 'repository_title' => 'Repository', + 'repository_text' => << 'The code', + 'repository_button_issues' => 'Issues', + 'repository_button_suggestions' => 'Suggestions', + + // Author + 'author_title' => 'Author', + 'author_text' => << 'Neurojournal', + 'author_button_projects' => 'Projects', + 'author_button_twitter' => 'Twitter', + 'author_button_bluesky' => 'Bluesky', + 'author_button_bastyon' => 'Bastyon', + 'author_button_youtube_english' => 'YouTube', + 'author_button_youtube_russian' => 'YouTube', + 'author_button_message' => 'Send a message', + + // Questions (system) + 'system_questions_title' => 'The questions registry', + 'system_questions_questions' => 'Questions', + 'system_questions_answers' => 'Answers', + 'system_questions_answers_amount_matches' => 'The amount of questions matches the amount of answers', + 'system_questions_answers_amount_different' => 'The amount of questions does not match the amount of answers', + 'system_questions_amount_matches' => 'The amount of questions matches the amount of localizations', + 'system_questions_amount_different' => 'The amount of questions does not match the amount of localizations', + 'system_questions_localizations_amount_matches' => 'Amounts of localizations matches with each other', + 'system_questions_localizations_amount_different' => 'Amounts of localizations does not match with each other', + 'system_questions_button_search' => 'Search', + 'system_questions_button_create' => 'Create', + + // Question create (system) + 'system_questions_create_created' => 'The question was created', + + // Question search (system) + 'system_questions_search_title' => 'The question search process', + 'system_questions_search_continued' => 'The process of the question search found and continued', + 'system_questions_search_started' => 'The process of the question search started', + 'system_questions_search_not_started' => 'The process of the question search is not started', + 'system_questions_search_ended' => 'The process of the question search ended', + 'system_questions_search_page_next_exists' => 'There are more questions in the registry', + 'system_questions_search_page_next_not_exists' => 'There are no more questions in the registry', + 'system_questions_search_empty' => 'No questions found', + 'system_questions_search_question_title' => 'Question', + 'system_questions_search_question_answer' => 'Answer', + 'system_questions_search_identifier_request_title' => 'Enter identifier', + 'system_questions_search_identifier_request_not_acceptable' => 'Failed to process the identifier', + 'system_questions_search_identifier_request_too_short' => 'Identifier length must be \>\= 1 and \<\= 12', + 'system_questions_search_identifier_request_too_long' => 'Identifier length must be \>\= 1 and \<\= 12', + 'system_questions_search_identifier_request_restricted_characters_title' => "Restricted any characters except digits", + 'system_questions_search_identifier_request_restricted_characters_description' => "Remove these characters:", + 'system_questions_search_identifier_cancel_success' => 'Cancelled the identifier replacing process', + 'system_questions_search_identifier_delete_success' => 'Identifier deleted', + 'system_questions_search_identifier_update_success' => 'Identifier replaced:', + 'system_questions_search_identifier_update_fail' => 'Failed to replace identifier', + 'system_questions_search_text_request_title' => 'Enter text', + 'system_questions_search_text_request_not_acceptable' => 'Failed to process the text', + 'system_questions_search_text_request_too_short' => 'Text length must be \>\= 3 and \<\= 256', + 'system_questions_search_text_request_too_long' => 'Text length must be \>\= 3 and \<\= 256', + 'system_questions_search_text_cancel_success' => 'Cancelled the text replacing process', + 'system_questions_search_text_delete_success' => 'Text deleted', + 'system_questions_search_text_update_success' => 'Text replaced:', + 'system_questions_search_text_update_fail' => 'Failed to replace text', + 'system_questions_search_a_request_title' => 'Enter A\-answer', + 'system_questions_search_a_request_not_acceptable' => 'Failed to process the A\-answer', + 'system_questions_search_a_request_too_short' => 'A\-answer length must be \>\= 3 and \<\= 128', + 'system_questions_search_a_request_too_long' => 'A\-answer length must be \>\= 3 and \<\= 128', + 'system_questions_search_a_cancel_success' => 'Cancelled the A\-answer replacing process', + 'system_questions_search_a_delete_success' => 'A\-answer deleted', + 'system_questions_search_a_update_success' => 'A\-answer replaced:', + 'system_questions_search_a_update_fail' => 'Failed to replace A\-answer', + 'system_questions_search_b_request_title' => 'Enter B\-answer', + 'system_questions_search_b_request_not_acceptable' => 'Failed to process the B\-answer', + 'system_questions_search_b_request_too_short' => 'B\-answer length must be \>\= 3 and \<\= 128', + 'system_questions_search_b_request_too_long' => 'B\-answer length must be \>\= 3 and \<\= 128', + 'system_questions_search_b_cancel_success' => 'Cancelled the B\-answer replacing process', + 'system_questions_search_b_delete_success' => 'B\-answer deleted', + 'system_questions_search_b_update_success' => 'B\-answer replaced:', + 'system_questions_search_b_update_fail' => 'Failed to replace B\-answer', + 'system_questions_search_c_request_title' => 'Enter C\-answer', + 'system_questions_search_c_request_not_acceptable' => 'Failed to process the C\-answer', + 'system_questions_search_c_request_too_short' => 'C\-answer length must be \>\= 3 and \<\= 128', + 'system_questions_search_c_request_too_long' => 'C\-answer length must be \>\= 3 and \<\= 128', + 'system_questions_search_c_cancel_success' => 'Cancelled the C\-answer replacing process', + 'system_questions_search_c_delete_success' => 'C\-answer deleted', + 'system_questions_search_c_update_success' => 'C\-answer replaced:', + 'system_questions_search_c_update_fail' => 'Failed to replace C\-answer', + 'system_questions_search_d_request_title' => 'Enter D\-answer', + 'system_questions_search_d_request_not_acceptable' => 'Failed to process the D\-answer', + 'system_questions_search_d_request_too_short' => 'D\-answer length must be \>\= 3 and \<\= 128', + 'system_questions_search_d_request_too_long' => 'D\-answer length must be \>\= 3 and \<\= 128', + 'system_questions_search_d_cancel_success' => 'Cancelled the D\-answer replacing process', + 'system_questions_search_d_delete_success' => 'D\-answer deleted', + 'system_questions_search_d_update_success' => 'D\-answer replaced:', + 'system_questions_search_d_update_fail' => 'Failed to replace D\-answer', + 'system_questions_search_button_delete' => 'Delete', + 'system_questions_search_button_author' => 'Author', + 'system_questions_search_button_active' => 'Active', + 'system_questions_search_button_inactive' => 'Inactive', + 'system_questions_search_button_answer' => 'Answer', + 'system_questions_search_button_localizations' => 'Localizations', + 'system_questions_search_button_identifier' => 'Identifier', + 'system_questions_search_button_text' => 'Text', + 'system_questions_search_button_a' => 'A', + 'system_questions_search_button_b' => 'B', + 'system_questions_search_button_c' => 'C', + 'system_questions_search_button_d' => 'D', + 'system_questions_search_button_delete' => 'Delete', + 'system_questions_search_button_cancel' => 'Cancel', + 'system_questions_search_button_page_next' => 'Next page', + 'system_questions_search_button_end' => 'End the search process', + 'system_questions_search_not_localized' => 'Failed to initialize the question localization', + + // Question localization create (system) + 'system_questions_localization_create_created' => 'The question localization was created', + + // Authorization + 'not_authorized_system' => 'You do not have access to the system', + 'not_authorized_game_play' => 'You do not have access to play games', + 'not_authorized_rating_display' => 'You do not have access to display in the rating', + 'not_authorized_balance_deposit' => 'You do not have access to deposit into the balance', + 'not_authorized_balance_withdraw' => 'You do not have access to withdraw from the balance', + 'not_authorized_settings' => 'You do not have access to the settings', + 'not_authorized_system_accounts' => 'You do not have system access to the accounts', + 'not_authorized_system_questions' => 'You do not have system access to the questions', + 'not_authorized_system_settings' => 'You do not have system access to the system settings', + + // Other + 'why_so_shroomious' => 'why so shroomious', +]; diff --git a/mirzaev/deeproots/system/localizations/russian.php b/mirzaev/deeproots/system/localizations/russian.php new file mode 100644 index 0000000..4506d7e --- /dev/null +++ b/mirzaev/deeproots/system/localizations/russian.php @@ -0,0 +1,184 @@ + 'DeepRoots', + 'empty' => 'Пусто', + 'yes' => 'Да', + 'no' => 'Нет', + + // Главное меню + 'menu_title' => 'Главное меню', + 'menu_button_start' => 'Начать', + 'menu_button_rating' => 'Рейтинг', + 'menu_button_balance' => 'Баланс', + 'menu_button_system_accounts' => 'Аккаунты', + 'menu_button_system_questions' => 'Вопросы', + 'menu_button_system_settings' => 'Настройки', + 'menu_system_authorized' => 'Найдена системная авторизация', + + // Аккаунт + 'account_title' => 'Аккаунт', + 'account_identifier' => 'Идентификатор', + 'account_authorized_system' => 'Доступ к системе', + 'account_authorized_game_play' => 'Доступ к играм', + 'account_authorized_rating_display' => 'Доступ к отображению в рейтинге', + 'account_authorized_balance_deposit' => 'Доступ к пополнению баланса', + 'account_authorized_balance_withdraw' => 'Доступ к выводу баланса', + 'account_authorized_settings' => 'Доступ к настроекам', + 'account_authorized_system_accounts' => 'Системный доступ к аккаунтам', + 'account_authorized_system_questions' => 'Системный доступ к вопросам', + 'account_authorized_system_settings' => 'Системный доступ к системным настройкам', + + // Настройки языка + 'settings_select_language_title' => 'Выбери язык', + 'settings_select_language_description' => 'Выбранный язык будет записан в настройки аккаунта', + 'settings_language_update_success' => 'Язык заменён:', + 'settings_language_update_fail' => 'Не удалось заменить язык', + + // Выбор языка + 'select_language_title' => 'Выбери язык', + 'select_language_description' => 'Выбранный язык будет использован в текущем процессе', + 'select_language_button_add' => 'Добавить язык', + + // Репозиторий + 'repository_title' => 'Репозиторий', + 'repository_text' => << 'Код', + 'repository_button_issues' => 'Проблемы', + 'repository_button_suggestions' => 'Предложения', + + // Автор + 'author_title' => 'Автор', + 'author_text' => << 'Нейрожурнал', + 'author_button_projects' => 'Проекты', + 'author_button_twitter' => 'Twitter', + 'author_button_bluesky' => 'Bluesky', + 'author_button_bastyon' => 'Bastyon', + 'author_button_youtube_english' => 'YouTube', + 'author_button_youtube_russian' => 'YouTube', + 'author_button_message' => 'Отправить сообщение', + + // Вопросы (система) + 'system_questions_title' => 'Реестр вопросов', + 'system_questions_questions' => 'Вопросы', + 'system_questions_answers' => 'Ответы', + 'system_questions_answers_amount_matches' => 'Количество вопросов совпадает с количеством ответов', + 'system_questions_answers_amount_different' => 'Количество вопросов не совпадает с количеством ответов', + 'system_questions_amount_matches' => 'Количество вопросов совпадает с количеством локализаций', + 'system_questions_amount_different' => 'Количество вопросов не совпадает с количеством локализаций', + 'system_questions_localizations_amount_matches' => 'Количества локализаций совпадает друг с другом', + 'system_questions_localizations_amount_different' => 'Количества локализаций не совпадает друг с другом', + 'system_questions_button_search' => 'Поиск', + 'system_questions_button_create' => 'Создать', + + // Создание вопроса (система) + 'system_questions_create_created' => 'Создан вопрос', + + // Поиск вопроса (система) + 'system_questions_search_title' => 'Процесс поиска вопроса', + 'system_questions_search_continued' => 'Процесс поиска вопроса найден и продолжен', + 'system_questions_search_started' => 'Процесс поиска вопроса начат', + 'system_questions_search_not_started' => 'Процесс поиска вопроса не начат', + 'system_questions_search_ended' => 'Процесс поиска вопроса завершён', + 'system_questions_search_page_next_exists' => 'В реестре есть ещё вопросы', + 'system_questions_search_page_next_not_exists' => 'В реестре больше нет вопросов', + 'system_questions_search_empty' => 'Вопросы не найдены', + 'system_questions_search_question_title' => 'Вопрос', + 'system_questions_search_question_answer' => 'Ответ', + 'system_questions_search_identifier_request_title' => 'Введи идентификатор', + 'system_questions_search_identifier_request_not_acceptable' => 'Не удалось обработать идентификатор', + 'system_questions_search_identifier_request_too_short' => 'Длина идентификатора должна быть \>\= 1 и \<\= 12', + 'system_questions_search_identifier_request_too_long' => 'Длина идентификатора должна быть \>\= 1 и \<\= 12', + 'system_questions_search_identifier_request_restricted_characters_title' => "Запрещены любые символы, кроме цифр", + 'system_questions_search_identifier_request_restricted_characters_description' => "Удали эти символы:", + 'system_questions_search_identifier_cancel_success' => 'Отменён процесс замены идентификатора', + 'system_questions_search_identifier_delete_success' => 'Идентификатор удалён', + 'system_questions_search_identifier_update_success' => 'Идентификатор заменён:', + 'system_questions_search_identifier_update_fail' => 'Не удалось заменить идентификатор', + 'system_questions_search_text_request_title' => 'Введи текст', + 'system_questions_search_text_request_not_acceptable' => 'Не удалось обработать текст', + 'system_questions_search_text_request_too_short' => 'Длина текста должна быть \>\= 3 и \<\= 256', + 'system_questions_search_text_request_too_long' => 'Длина текста должна быть \>\= 3 и \<\= 256', + 'system_questions_search_text_cancel_success' => 'Отменён процесс замены текста', + 'system_questions_search_text_delete_success' => 'Текст удалён', + 'system_questions_search_text_update_success' => 'Текст заменён:', + 'system_questions_search_text_update_fail' => 'Не удалось заменить текст', + 'system_questions_search_a_request_title' => 'Введи A\-ответ', + 'system_questions_search_a_request_not_acceptable' => 'Не удалось обработать A\-ответ', + 'system_questions_search_a_request_too_short' => 'Длина A\-ответа должна быть \>\= 3 и \<\= 128', + 'system_questions_search_a_request_too_long' => 'Длина A\-ответа должна быть \>\= 3 и \<\= 128', + 'system_questions_search_a_cancel_success' => 'Отменён процесс замены A\-ответа', + 'system_questions_search_a_delete_success' => 'A\-ответ удалён', + 'system_questions_search_a_update_success' => 'A\-ответ заменён:', + 'system_questions_search_a_update_fail' => 'Не удалось заменить A\-ответ', + 'system_questions_search_b_request_title' => 'Введи B\-ответ', + 'system_questions_search_b_request_not_acceptable' => 'Не удалось обработать B\-ответ', + 'system_questions_search_b_request_too_short' => 'Длина B\-ответа должна быть \>\= 3 и \<\= 128', + 'system_questions_search_b_request_too_long' => 'Длина B\-ответа должна быть \>\= 3 и \<\= 128', + 'system_questions_search_b_cancel_success' => 'Отменён процесс замены B\-ответа', + 'system_questions_search_b_delete_success' => 'B\-ответ удалён', + 'system_questions_search_b_update_success' => 'B\-ответ заменён:', + 'system_questions_search_b_update_fail' => 'Не удалось заменить B\-ответ', + 'system_questions_search_c_request_title' => 'Введи C\-ответ', + 'system_questions_search_c_request_not_acceptable' => 'Не удалось обработать C\-ответ', + 'system_questions_search_c_request_too_short' => 'Длина C\-ответа должна быть \>\= 3 и \<\= 128', + 'system_questions_search_c_request_too_long' => 'Длина C\-ответа должна быть \>\= 3 и \<\= 128', + 'system_questions_search_c_cancel_success' => 'Отменён процесс замены C\-ответа', + 'system_questions_search_c_delete_success' => 'C\-ответ удалён', + 'system_questions_search_c_update_success' => 'C\-ответ заменён:', + 'system_questions_search_c_update_fail' => 'Не удалось заменить C\-ответ', + 'system_questions_search_d_request_title' => 'Введи D\-ответ', + 'system_questions_search_d_request_not_acceptable' => 'Не удалось обработать D\-ответ', + 'system_questions_search_d_request_too_short' => 'Длина D\-ответа должна быть \>\= 3 и \<\= 128', + 'system_questions_search_d_request_too_long' => 'Длина D\-ответа должна быть \>\= 3 и \<\= 128', + 'system_questions_search_d_cancel_success' => 'Отменён процесс замены D\-ответа', + 'system_questions_search_d_delete_success' => 'D\-ответ удалён', + 'system_questions_search_d_update_success' => 'D\-ответ заменён:', + 'system_questions_search_d_update_fail' => 'Не удалось заменить D\-ответ', + 'system_questions_search_button_delete' => 'Удалить', + 'system_questions_search_button_author' => 'Автор', + 'system_questions_search_button_active' => 'Активен', + 'system_questions_search_button_inactive' => 'Неактивен', + 'system_questions_search_button_answer' => 'Ответ', + 'system_questions_search_button_localizations' => 'Локализации', + 'system_questions_search_button_identifier' => 'Идентифиикатор', + 'system_questions_search_button_text' => 'Текст', + 'system_questions_search_button_a' => 'А', + 'system_questions_search_button_b' => 'Б', + 'system_questions_search_button_c' => 'В', + 'system_questions_search_button_d' => 'Г', + 'system_questions_search_button_delete' => 'Удалить', + 'system_questions_search_button_cancel' => 'Отменить', + 'system_questions_search_button_page_next' => 'Следующая страница', + 'system_questions_search_button_end' => 'Завершить процесс поиска', + 'system_questions_search_not_localized' => 'Не удалось инициализировать локализацию вопроса', + + // Создание локализации вопроса (система) + 'system_questions_localization_create_created' => 'Создана локализация вопроса', + + // Авторизация + 'not_authorized_system' => 'У тебя нет доступа к системе', + 'not_authorized_game_play' => 'У тебя нет доступа к играм', + 'not_authorized_rating_display' => 'У тебя нет доступа к отображению в рейтинге', + 'not_authorized_balance_deposit' => 'У тебя нет доступа к пополнению баланса', + 'not_authorized_balance_withdraw' => 'У тебя нет доступа к выводу баланса', + 'not_authorized_settings' => 'У тебя нет доступа к настройкам', + 'not_authorized_system_accounts' => 'У тебя нет системного доступа к аккаунтам', + 'not_authorized_system_questions' => 'У тебя нет системного доступа к вопросам', + 'not_authorized_system_settings' => 'У тебя нет системного доступа к системным настройкам', + + // Прочее + 'why_so_shroomious' => 'почему такой грибъёзный', +]; diff --git a/mirzaev/deeproots/system/models/account.php b/mirzaev/deeproots/system/models/account.php new file mode 100755 index 0000000..8932e5b --- /dev/null +++ b/mirzaev/deeproots/system/models/account.php @@ -0,0 +1,224 @@ + + */ +final class account extends core +{ + /** + * File + * + * @var string $database Path to the database file + */ + protected string $file = DATABASES . DIRECTORY_SEPARATOR . 'accounts.baza'; + + /** + * Database + * + * @var database $database The database + */ + public protected(set) database $database; + + /** + * Constructor + * + * @return void + */ + public function __construct() + { + // Initializing the database + $this->database = new database() + ->encoding(encoding::utf8) + ->columns( + new column('identifier', type::integer_unsigned), + new column('name', type::string, ['length' => 64]), + new column('language', type::string, ['length' => 2]), + new column('authorized_system', type::char), + new column('authorized_game_play', type::char), + new column('authorized_rating_display', type::char), + new column('authorized_balance_deposit', type::char), + new column('authorized_balance_withdraw', type::char), + new column('authorized_settings', type::char), + new column('authorized_system_accounts', type::char), + new column('authorized_system_questions', type::char), + new column('authorized_system_settings', type::char), + new column('updated', type::integer_unsigned), + new column('created', type::integer_unsigned) + ) + ->connect($this->file); + } + + /** + * Initialize + * + * Searches for the account record by the telegram account in the database, + * and if it does not find it, then create the account record and the connection record + * + * @param record $telegram The telegram account + * + * @throws exception_runtime if failed to deactivate the connection between missing account and the telegram account + * @throws exception_runtime if failed to connect the account with the telegram account + * @throws exception_runtime if failed to find the created account + * @throws exception_runtime if failed to create the account + * + * @return record The account record from the database + */ + public function initialize(record $telegram): record + { + // Initializing the connection model + $connection = new connection; + + // Searching for the connection record between theaccount and the telegram account in the database + $connected = $connection->database->read(filter: fn(record $record) => $record->telegram === $telegram->identifier, amount: 1)[0] ?? null; + + if ($connected instanceof record) { + // Found the connection record between the account and the telegram account + + // Searching for the account in the database + $account = $this->database->read(filter: fn(record $record) => $record->identifier === $connected->account, amount: 1)[0] ?? null; + + if ($account instanceof record) { + // Found the account + + // Exit (success) + return $account; + } else { + // Not found the account + + // Deactivating the connection between missing account and the telegram account + $deactivated = $connected->read( + filter: fn(record $record) => $record->identifier === $connected->identifier, + update: function (record &$record) { + $record->active = 0; + $record->updated = svoboda::timestamp(); + }, + amount: 1)[0] ?? null; + + if ($deactivated instanceof record && $deactivated->active === 0) { + // Deactivated the connection between missing account and the telegram account + + // Creating the account + goto create; + } else { + // Failed to deactivate the connection between missing account and the telegram account + + // Exit (fail) + throw new exception_runtime('Failed to deactivate the connection between missing account and the telegram account'); + } + } + } else { + // Not found the connection record between the account and the telegram account + + // Creating the account process start + create: + + // Creating the account + $identifier = $this->create("$telegram->name_first $telegram->name_second", language::{$telegram->language ?? language::en->name} ?? language::en); + + if ($identifier) { + // Created the account + + // Searching for the created account in the database + $account = $this->database->read(filter: fn(record $record) => $record->identifier === $identifier, amount: 1)[0] ?? null; + + if ($account instanceof record) { + // Found the created account + + // Connecting the created account with the telegram account + $connected = $connection->create(account: $account->identifier, telegram: $telegram->identifier); + + if ($connected) { + // Connected the created account with the telegram account + + // Exit (success) + return $account; + } else { + // Not connected the created account with the telegram account + + // Exit (fail) + throw new exception_runtime('Failed to connect the account with the telegram account'); + } + } else { + // Not found the created account + + // Exit (fail) + throw new exception_runtime('Failed to find the created account'); + } + } else { + // Not created the account + + // Exit (fail) + throw new exception_runtime('Failed to create the account'); + } + } + } + + /** + * Create + * + * Creates the account record in the database + * + * @param telegram $telegram The telegram account + * + * @return int|false The record identifier, if created + */ + public function create(string $name, language $language): int|false + { + // Initializing the identifier + $identifier = $this->database->count() + 1; + + // Initializing the record + $record = $this->database->record( + $identifier, + $name, + $language->name, + ACCOUNT_ACCESS_SYSTEM, + ACCOUNT_ACCESS_GAME_PLAY, + ACCOUNT_ACCESS_RATING_DISPLAY, + ACCOUNT_ACCESS_BALANCE_DEPOSIT, + ACCOUNT_ACCESS_BALANCE_WITHDRAW, + ACCOUNT_ACCESS_SETTINGS, + ACCOUNT_ACCESS_SYSTEM_ACCOUNTS, + ACCOUNT_ACCESS_SYSTEM_QUESTIONS, + ACCOUNT_ACCESS_SYSTEM_SETTINGS, + svoboda::timestamp(), + svoboda::timestamp() + ); + + // Creating the record in the database + $created = $this->database->write($record); + + // Exit (success) + return $created ? $identifier : false; + } +} diff --git a/mirzaev/deeproots/system/models/answer.php b/mirzaev/deeproots/system/models/answer.php new file mode 100755 index 0000000..7413ee9 --- /dev/null +++ b/mirzaev/deeproots/system/models/answer.php @@ -0,0 +1,110 @@ + + */ +final class answer extends core +{ + /** + * File + * + * @var string $database Path to the database file + */ + protected string $file = DATABASES . DIRECTORY_SEPARATOR . 'answers.baza'; + + /** + * Database + * + * @var database $database The database + */ + public protected(set) database $database; + + /** + * Constructor + * + * @param language $language Questions language + * + * @return void + */ + public function __construct() + { + // Initializing the database + $this->database = new database() + ->encoding(encoding::ascii) + ->columns( + new column('identifier', type::integer_unsigned), + new column('A', type::char), + new column('B', type::char), + new column('C', type::char), + new column('D', type::char), + new column('updated', type::integer_unsigned), + new column('created', type::integer_unsigned) + ) + ->connect($this->file); + } + + /** + * Create + * + * Creates the record in the database + * + * @param int $identifier Identifier (same for questions in every language) + * @param int $a Number of points for answer A + * @param int $b Number of points for answer B + * @param int $c Number of points for answer C + * @param int $d Number of points for answer D + * + * @return int|false The record identifier, if created + */ + public function create(?int $identifier, int $a = 0, int $b = 0, int $c = 0, int $d = 0): int|false + { + // Initializing the identifier + $identifier ??= $this->database->count() + 1; + + // Initializing the record + $record = $this->database->record( + $identifier, + $a, + $b, + $c, + $d, + svoboda::timestamp(), + svoboda::timestamp() + ); + + // Creating the record in the database + $created = $this->database->write($record); + + // Exit (success) + return $created ? $identifier : false; + } +} diff --git a/mirzaev/deeproots/system/models/connection.php b/mirzaev/deeproots/system/models/connection.php new file mode 100755 index 0000000..3d60ba2 --- /dev/null +++ b/mirzaev/deeproots/system/models/connection.php @@ -0,0 +1,110 @@ + + */ +final class connection extends core +{ + /** + * File + * + * @var string $database Path to the database file + */ + protected string $file = DATABASES . DIRECTORY_SEPARATOR . 'connection.baza'; + + /** + * Database + * + * Identifier: The record identifier + * Account: The account identifier + * Telegram: The telegram account identifier + * Updated: Timestamp of the last the record update + * Created: Timestamp of the record creating + * + * @var database $database The database + */ + public protected(set) database $database; + + /** + * Constructor + * + * @return void + */ + public function __construct() + { + // Initializing the database + $this->database = new database() + ->encoding(encoding::ascii) + ->columns( + new column('identifier', type::integer_unsigned), + new column('account', type::integer_unsigned), + new column('telegram', type::integer_unsigned), + new column('active', type::char), + new column('updated', type::integer_unsigned), + new column('created', type::integer_unsigned) + ) + ->connect($this->file); + } + + /** + * Create + * + * Creates the record in the database + * + * @param int $account Identifier of the account + * @param int $telegram Identifier of the telegram account + * @param bool $active Is the connection active? + * + * @return int|false The record identifier, if created + */ + public function create(int $account, int $telegram, bool $active = true): int|false + { + // Initializing the identifier + $identifier = $this->database->count() + 1; + + // Initializing the record + $record = $this->database->record( + $identifier, + $account, + $telegram, + (int) $active, + svoboda::timestamp(), + svoboda::timestamp() + ); + + // Creating the record in the database + $created = $this->database->write($record); + + // Exit (success) + return $created ? $identifier : false; + } +} diff --git a/author/project/system/models/core.php b/mirzaev/deeproots/system/models/core.php similarity index 95% rename from author/project/system/models/core.php rename to mirzaev/deeproots/system/models/core.php index c2e81f3..732a542 100755 --- a/author/project/system/models/core.php +++ b/mirzaev/deeproots/system/models/core.php @@ -20,7 +20,6 @@ use exception; * * @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License * @author Arsen Mirzaev Tatyano-Muradovich - * @author mirzaev */ class core extends model { diff --git a/author/project/system/models/enumerations/language.php b/mirzaev/deeproots/system/models/enumerations/language.php similarity index 55% rename from author/project/system/models/enumerations/language.php rename to mirzaev/deeproots/system/models/enumerations/language.php index 72dce07..4e00cb7 100755 --- a/author/project/system/models/enumerations/language.php +++ b/mirzaev/deeproots/system/models/enumerations/language.php @@ -7,46 +7,53 @@ namespace mirzaev\deeproots\models\enumerations; /** * Language * - * Types of languages by ISO 639-1 standart + * Types of languages by ISO 639-1 standart @deprecated * * @package mirzaev\deeproots\models\enumerations * * @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License * @author Arsen Mirzaev Tatyano-Muradovich - * @author mirzaev */ enum language { case en; case ru; + case in; /** - * Label - * + * Label + * * Initialize label of the language * * @param language|null language Language into which to translate * * @return string Translated label of the language */ - public function label(?language language = language::en): string + public function label(?language $language = language::en): string { // Exit (success) - return match (this) { - language::en => match (language) { + return match ($this) { + language::en => match ($language) { language::en => 'English', - language::ru => 'Английский' + language::ru => 'Английский', + language::in => 'अंग्रेज़ी', }, - language::ru => match (language) { + language::ru => match ($language) { language::en => 'Russian', - language::ru => 'Русский' + language::ru => 'Русский', + language::in => 'रूसी', + }, + language::in => match ($language) { + language::en => 'Hindi', + language::ru => 'Хинди', + language::in => 'हिन्दी', } }; } /** - * Flag - * + * Flag + * * Initialize the flag emoji of the language * * @return string The flag emoji of the language @@ -54,9 +61,10 @@ enum language public function flag(): string { // Exit (success) - return match (this) { + return match ($this) { language::en => '🇺🇸', - language::ru => '🇷🇺' + language::ru => '🇷🇺', + language::in => '🇮🇳', }; } } diff --git a/mirzaev/deeproots/system/models/question.php b/mirzaev/deeproots/system/models/question.php new file mode 100755 index 0000000..b8476c4 --- /dev/null +++ b/mirzaev/deeproots/system/models/question.php @@ -0,0 +1,98 @@ + + */ +final class question extends core +{ + /** + * File + * + * @var string $database Path to the database file + */ + protected string $file = DATABASES . DIRECTORY_SEPARATOR . 'questions.baza'; + + /** + * Database + * + * @var database $database The database + */ + public protected(set) database $database; + + /** + * Constructor + * + * @return void + */ + public function __construct() + { + // Initializing the database + $this->database = new database() + ->encoding(encoding::ascii) + ->columns( + new column('identifier', type::integer_unsigned), + new column('active', type::char), + new column('updated', type::integer_unsigned), + new column('created', type::integer_unsigned) + ) + ->connect($this->file); + } + + /** + * Create + * + * Creates the record in the database + * + * @param bool $active Is the question active? + * + * @return int|false The record identifier, if created + */ + public function create(bool $active = false): int|false + { + // Initializing the identifier + $identifier ??= $this->database->count() + 1; + + // Initializing the record + $record = $this->database->record( + $identifier, + (int) $active, + svoboda::timestamp(), + svoboda::timestamp() + ); + + // Creating the record in the database + $created = $this->database->write($record); + + // Exit (success) + return $created ? $identifier : false; + } +} diff --git a/mirzaev/deeproots/system/models/question/localization.php b/mirzaev/deeproots/system/models/question/localization.php new file mode 100755 index 0000000..cf6df79 --- /dev/null +++ b/mirzaev/deeproots/system/models/question/localization.php @@ -0,0 +1,110 @@ + + */ +final class localization extends core +{ + /** + * Files + * + * @var string $database Path to the database files + */ + protected string $files = DATABASES . DIRECTORY_SEPARATOR . 'questions' . DIRECTORY_SEPARATOR . 'localizations'; + + /** + * Database + * + * @var database $database The database + */ + public protected(set) database $database; + + /** + * Constructor + * + * @param language $language Language + * + * @return void + */ + public function __construct(language $language) + { + // Initializing the database + $this->database = new database() + ->encoding(encoding::ascii) + ->columns( + new column('identifier', type::integer_unsigned), + new column('text', type::string, ['length' => 256]), + new column('A', type::string, ['length' => 128]), + new column('B', type::string, ['length' => 128]), + new column('C', type::string, ['length' => 128]), + new column('D', type::string, ['length' => 128]), + new column('updated', type::integer_unsigned), + new column('created', type::integer_unsigned) + ) + ->connect($this->files . DIRECTORY_SEPARATOR . strtolower($language->label()) . '.baza'); + } + + /** + * Create + * + * Creates the record in the database + * + * @param int $identifier Identifier of the question::class record + * @param string $text Text (length: 256) + * @param string $a Answer A (length: 128) + * @param string $b Answer B (length: 128) + * @param string $c Answer C (length: 128) + * @param string $d Answer D (length: 128) + * + * @return int|false The record identifier, if created + */ + public function create(int $identifier, string $text, string $a, string $b, string $c, string $d): int|false + { + // Initializing the record + $record = $this->database->record( + $identifier, + $text, + $a, + $b, + $c, + $d, + svoboda::timestamp(), + svoboda::timestamp() + ); + + // Creating the record in the database + $created = $this->database->write($record); + + // Exit (success) + return $created ? $identifier : false; + } +} diff --git a/mirzaev/deeproots/system/models/telegram.php b/mirzaev/deeproots/system/models/telegram.php new file mode 100755 index 0000000..9bdb48d --- /dev/null +++ b/mirzaev/deeproots/system/models/telegram.php @@ -0,0 +1,192 @@ + + */ +final class telegram extends core +{ + /** + * File + * + * @var string $database Path to the database file + */ + protected string $file = DATABASES . DIRECTORY_SEPARATOR . 'telegram.baza'; + + /** + * Database + * + * @var database $database The database + */ + public protected(set) database $database; + + /** + * Constructor + * + * @return void + */ + public function __construct() + { + // Initializing the database + $this->database = new database() + ->encoding(encoding::utf8) + ->columns( + new column('identifier', type::integer_unsigned), + new column('domain', type::string, ['length' => 32]), + new column('name_first', type::string, ['length' => 64]), + new column('name_second', type::string, ['length' => 64]), + new column('language', type::string, ['length' => 2]), + new column('robot', type::char), + new column('updated', type::integer_unsigned), + new column('created', type::integer_unsigned) + ) + ->connect($this->file); + } + + /** + * Initialize + * + * Searches for the telegram account record in the database, and if it does not find it, then create + * + * @param model $telegram The telegram account + * + * @throws exception_runtime if update the telegram account record in the database by the telegram account values + * @throws exception_runtime if failed to find the created telegram account + * @throws exception_runtime if failed to create the telegram account + * + * @return record The telegram account record from the database + */ + public function initialize(model $telegram): record + { + // Searching for the account in the database + $account = $this->database->read(filter: fn(record $record) => $record->identifier === $telegram->getId(), amount: 1)[0] ?? null; + + if ($account instanceof record) { + // Found the telegram account record + + if ( + $account->name_first !== $telegram->getFirstName() || + $account->name_second !== $telegram->getLastName() || + $account->domain !== $telegram->getUsername() + ) { + // The telegram account was updated + + // Updating the account in the database + $updated = $this->database->read( + filter: fn(record $record) => $record->identifier === $telegram->getId(), + update: function (record &$record) use ($telegram){ + // Writing new values into the record + $record->name_first = $telegram->getFirstName(); + $record->name_second = $telegram->getLastName(); + $record->domain = $telegram->getUsername(); + $record->updated = svoboda::timestamp(); + }, + amount: 1 + )[0] ?? null; + + if ($updated instanceof record && $updated->values() !== $account->values()) { + // Updated the account in the database + + // Exit (success) + return $updated; + } else { + // Not updated the account in the database + + // Exit (fail) + throw new exception_runtime('Failed to update the account record in the database by the telegram account values'); + } + } + + // Exit (success) + return $account; + } else { + // Not found the account record + + if ($this->create($telegram)) { + // Created the account + + // Searching for the created telegram account in the database + $account = $this->database->read(filter: fn(record $record) => $record->identifier === $telegram->getId(), amount: 1)[0] ?? null; + + if ($account instanceof record) { + // Found the created telegram account + + // Exit (success) + return $account; + } else { + // Not found the created telegram account + + // Exit (fail) + throw new exception_runtime('Failed to find the created telegram account'); + } + } else { + // Not created the telegram account + + // Exit (fail) + throw new exception_runtime('Failed to create the telegram account'); + } + } + } + + /** + * Create + * + * Creates the account record in the database + * + * @param model $telegram The telegram account + * + * @return int|false The record identifier, if created + */ + public function create(model $telegram): int|false + { + // Initializing the identifier + $identifier = (int) $telegram->getId(); + + // Initializing the record + $record = $this->database->record( + $identifier, + $telegram->getUsername(), + $telegram->getFirstName(), + $telegram->getLastName(), + $telegram->getLanguageCode(), + (int) $telegram->isBot(), + svoboda::timestamp(), + svoboda::timestamp() + ); + + // Creating the record in the database + $created = $this->database->write($record); + + // Exit (success) + return $created ? $identifier : false; + } +} diff --git a/mirzaev/deeproots/system/models/telegram/buttons/account/localization/create.php b/mirzaev/deeproots/system/models/telegram/buttons/account/localization/create.php new file mode 100755 index 0000000..04386cb --- /dev/null +++ b/mirzaev/deeproots/system/models/telegram/buttons/account/localization/create.php @@ -0,0 +1,228 @@ + + */ +final class create extends core +{ + /** + * Language + * + * Send the language selection menu + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function language(context $context) + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing language + $language = $context->get('language'); + + if ($language) { + // Initialized language + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(process_account_localization_create::PROCESS) + ->then(function (?array $process) use ($context, $account, $localization) { + // Readed from the telegram user buffer + + if ($process) { + // Found started account localization create process + + // Initializing the account model + $model_account = new account; + + // Initializing the account localizations + $existed = $model_account->localization->database->read( + filter: fn(record $localization) => $localization->account === $account->identifier, + amount: ACCOUNT_LOCALIZATION_CREATE_ACCOUNT_LOCALIZATIONS_AMOUNT + ); + + // Declaring the buffer of languages to exclude + $exclude = []; + + // Initializing languages to exclude + foreach ($existed as $record) $exclude[] = $record->language; + + if (count($exclude) !== count(language::cases())) { + // Not all languages in the registry have localizations created (expected) + + // Sending the language selection + selections::language( + context: $context, + prefix: 'account_localization_create_select_language_', + title: '🌏 *' . $localization['account_localization_create_select_language_title'] . '*', + description: '🌏 *' . $localization['account_localization_create_select_language_description'] . '*', + exclude: $exclude + ); + } else { + // All languages in the registry have localizations created (expected) + + // Sending the message + $context->sendMessage('⚠️ *' . $localization['account_localization_create_every_language_created'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not found started account localization create process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization['account_localization_create_not_started'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized language + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize language*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Name + * + * Request to enter name + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function name(context $context) + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(process_account_localization_create::PROCESS) + ->then(function (?array $process) use ($context, $account, $localization) { + // Readed from the telegram user buffer + + if ($process) { + // Found started account localization create process + + // Sending the message + $context->sendMessage('📄 *' . $localization['account_localization_create_name_request'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Writing into the account localization create buffer + $context->nextStep([process_account_localization_create::class, 'name']); + }); + } else { + // Not found started account localization create process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization['account_localization_create_not_started'] . '*'); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } +} diff --git a/mirzaev/deeproots/system/models/telegram/buttons/account/localization/update.php b/mirzaev/deeproots/system/models/telegram/buttons/account/localization/update.php new file mode 100755 index 0000000..d5abe5e --- /dev/null +++ b/mirzaev/deeproots/system/models/telegram/buttons/account/localization/update.php @@ -0,0 +1,102 @@ + + */ +final class update extends core +{ + /** + * Name + * + * Request to enter name + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function name(context $context) + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(process_account_localization_update::PROCESS) + ->then(function (?array $process) use ($context, $account, $localization) { + // Readed from the telegram user buffer + + if ($process) { + // Found started account localization update process + + // Sending the message + $context->sendMessage('📄 *' . $localization['account_localization_update_name_request'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Writing into the account localization update buffer + $context->nextStep([process_account_localization_update::class, 'name']); + }); + } else { + // Not found started account localization update process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization['account_localization_update_not_started'] . '*'); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } +} diff --git a/mirzaev/deeproots/system/models/telegram/buttons/question/search.php b/mirzaev/deeproots/system/models/telegram/buttons/question/search.php new file mode 100755 index 0000000..2a3889a --- /dev/null +++ b/mirzaev/deeproots/system/models/telegram/buttons/question/search.php @@ -0,0 +1,579 @@ + + */ +final class search extends core +{ + /** + * Process + * + * @var const string PROCESS Name of the process in the telegram user buffer + */ + public const string PROCESS = process_question_search::PROCESS; + + /** + * Identifier + * + * Request to enter identifier + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function identifier(context $context) + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function ($search) use ($context, $localization) { + // Readed from the telegram user buffer + + if ($search) { + // Found started search process + + // Sending the message + $context->sendMessage( + '📄 *' . $localization[static::PROCESS . '_identifier_request_title'] . '*', + [ + 'reply_markup' => [ + 'inline_keyboard' => [ + [ + [ + 'text' => '🗑 ' . $localization[static::PROCESS . '_button_delete'], + 'callback_data' => 'delete' + ], + [ + 'text' => '❎ ' . $localization[static::PROCESS . '_button_cancel'], + 'callback_data' => 'cancel' + ] + ], + ], + 'disable_notification' => true + ] + ] + )->then(function (message $message) use ($context) { + // Sended the message + + // Writing into the distribution search buffer + $context->nextStep([process_question_search::class, 'identifier']); + }); + } else { + // Not found started search process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_started'] . '*'); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function ($message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function ($message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Text + * + * Request to enter text + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function text(context $context) + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function ($search) use ($context, $localization) { + // Readed from the telegram user buffer + + if ($search) { + // Found started search process + + // Sending the message + $context->sendMessage( + '📄 *' . $localization[static::PROCESS . '_text_request_title'] . '*', + [ + 'reply_markup' => [ + 'inline_keyboard' => [ + [ + [ + 'text' => '🗑 ' . $localization[static::PROCESS . '_button_delete'], + 'callback_data' => 'delete' + ], + [ + 'text' => '❎ ' . $localization[static::PROCESS . '_button_cancel'], + 'callback_data' => 'cancel' + ] + ], + ], + 'disable_notification' => true + ] + ] + )->then(function (message $message) use ($context) { + // Sended the message + + // Writing into the distribution search buffer + $context->nextStep([process_question_search::class, 'text']); + }); + } else { + // Not found started search process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_started'] . '*'); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function ($message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function ($message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * A + * + * Request to enter A-answer + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function a(context $context) + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function ($search) use ($context, $localization) { + // Readed from the telegram user buffer + + if ($search) { + // Found started search process + + // Sending the message + $context->sendMessage( + '📄 *' . $localization[static::PROCESS . '_a_request_title'] . '*', + [ + 'reply_markup' => [ + 'inline_keyboard' => [ + [ + [ + 'text' => '🗑 ' . $localization[static::PROCESS . '_button_delete'], + 'callback_data' => 'delete' + ], + [ + 'text' => '❎ ' . $localization[static::PROCESS . '_button_cancel'], + 'callback_data' => 'cancel' + ] + ], + ], + 'disable_notification' => true + ] + ] + )->then(function (message $message) use ($context) { + // Sended the message + + // Writing into the distribution search buffer + $context->nextStep([process_question_search::class, 'a']); + }); + } else { + // Not found started search process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_started'] . '*'); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function ($message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function ($message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * B + * + * Request to enter B-answer + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function b(context $context) + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function ($search) use ($context, $localization) { + // Readed from the telegram user buffer + + if ($search) { + // Found started search process + + // Sending the message + $context->sendMessage( + '📄 *' . $localization[static::PROCESS . '_b_request_title'] . '*', + [ + 'reply_markup' => [ + 'inline_keyboard' => [ + [ + [ + 'text' => '🗑 ' . $localization[static::PROCESS . '_button_delete'], + 'callback_data' => 'delete' + ], + [ + 'text' => '❎ ' . $localization[static::PROCESS . '_button_cancel'], + 'callback_data' => 'cancel' + ] + ], + ], + 'disable_notification' => true + ] + ] + )->then(function (message $message) use ($context) { + // Sended the message + + // Writing into the distribution search buffer + $context->nextStep([process_question_search::class, 'b']); + }); + } else { + // Not found started search process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_started'] . '*'); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function ($message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function ($message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * C + * + * Request to enter C-answer + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function c(context $context) + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function ($search) use ($context, $localization) { + // Readed from the telegram user buffer + + if ($search) { + // Found started search process + + // Sending the message + $context->sendMessage( + '📄 *' . $localization[static::PROCESS . '_c_request_title'] . '*', + [ + 'reply_markup' => [ + 'inline_keyboard' => [ + [ + [ + 'text' => '🗑 ' . $localization[static::PROCESS . '_button_delete'], + 'callback_data' => 'delete' + ], + [ + 'text' => '❎ ' . $localization[static::PROCESS . '_button_cancel'], + 'callback_data' => 'cancel' + ] + ], + ], + 'disable_notification' => true + ] + ] + )->then(function (message $message) use ($context) { + // Sended the message + + // Writing into the distribution search buffer + $context->nextStep([process_question_search::class, 'c']); + }); + } else { + // Not found started search process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_started'] . '*'); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function ($message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function ($message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * D + * + * Request to enter D-answer + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function d(context $context) + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function ($search) use ($context, $localization) { + // Readed from the telegram user buffer + + if ($search) { + // Found started search process + + // Sending the message + $context->sendMessage( + '📄 *' . $localization[static::PROCESS . '_d_request_title'] . '*', + [ + 'reply_markup' => [ + 'inline_keyboard' => [ + [ + [ + 'text' => '🗑 ' . $localization[static::PROCESS . '_button_delete'], + 'callback_data' => 'delete' + ], + [ + 'text' => '❎ ' . $localization[static::PROCESS . '_button_cancel'], + 'callback_data' => 'cancel' + ] + ], + ], + 'disable_notification' => true + ] + ] + )->then(function (message $message) use ($context) { + // Sended the message + + // Writing into the distribution search buffer + $context->nextStep([process_question_search::class, 'd']); + }); + } else { + // Not found started search process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_started'] . '*'); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function ($message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function ($message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } +} diff --git a/mirzaev/deeproots/system/models/telegram/commands.php b/mirzaev/deeproots/system/models/telegram/commands.php new file mode 100755 index 0000000..d7a8eb7 --- /dev/null +++ b/mirzaev/deeproots/system/models/telegram/commands.php @@ -0,0 +1,741 @@ + + */ +final class commands extends core +{ + /** + * Menu + * + * Responce for the commands: "/start", '/menu' + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function menu(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Initializing the title + $title = '📋 *' . $localization['menu_title'] . '*'; + + // Sending the message + $context->sendMessage( + << [ + 'inline_keyboard' => [ + [ + [ + 'text' => '🧠 ' . $localization['menu_button_start'], + 'callback_data' => 'projects' + ] + ], + [ + [ + 'text' => '📈 ' . $localization['menu_button_rating'], + 'callback_data' => 'rating' + ], + [ + 'text' => '💰 ' . $localization['menu_button_balance'], + 'callback_data' => 'balance' + ] + ] + ], + 'disable_notification' => true, + 'remove_keyboard' => true + ], + ] + )->then(function (message $message) use ($context, $localization, $account) { + // Sended the message + + if ( + $account->authorized_system_accounts || + $account->authorized_system_questions || + $account->authorized_system_settings + ) { + // Found at least one system authorization + + // Initializing the keyboard buffer + $keyboard = []; + + if ($account->authorized_system_accounts) { + // Authorized to accounts + + // Generating the button and writing into the keyboard buffer + $keyboard[] = [ + [ + 'text' => '🐣 ' . $localization['menu_button_system_accounts'], + 'callback_data' => 'system_accounts' + ] + ]; + } + + if ($account->authorized_system_questions) { + // Authorized to questions + + // Generating the button and writing into the keyboard buffer + $keyboard[] = [ + [ + 'text' => '🗂 ' . $localization['menu_button_system_questions'], + 'callback_data' => 'system_questions' + ] + ]; + } + + if ($account->authorized_system_settings) { + // Authorized to system settings + + // Generating the button and writing into the keyboard buffer + $keyboard[] = [ + [ + 'text' => '⚙️ ' . $localization['menu_button_system_settings'], + 'callback_data' => 'system_settings' + ] + ]; + } + + // Sending the message + $context->sendMessage( + '🛠 ' . $localization['menu_system_authorized'], + [ + 'reply_markup' => [ + 'inline_keyboard' => $keyboard, + 'disable_notification' => true, + 'remove_keyboard' => true + ], + ] + ); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Account + * + * Responce for the command: "/account" + * + * Sends information about account with menu + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function account(context $context): void + { + // Initializing the telegram account + $telegram = $context->get('telegram'); + + if ($telegram instanceof record) { + // Initialized the telegram account + + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Initializing title for the message + $title = '🫵 ' . $localization['account_title']; + + // Initializing the account identifier row for the message + $identifier = '*' . $localization['account_identifier'] . ":* $account->identifier \($telegram->identifier\)"; + + // Declaring buufer of rows about authorizations + $authorizations = ''; + + // Initializing rows about authorization + foreach ($account->values() as $key => $value) { + // Iterating over account parameters + + if (str_starts_with($key, 'authorized_')) { + // Iterating over account authorizations + + if (str_starts_with($key, 'authorized_system_') && $value) { + // A system authorization + + // Writing into buffer of rows about authorizations + $authorizations .= '✅ ⚠️ *' . ($localization["account_$key"] ?? $key) . ':* ' . $localization['yes'] . "\n"; + } else { + // Not a system authorization + + // Writing into buffer of rows about authorizations + $authorizations .= ($value ? '✅' : '❎') . ' *' . ($localization["account_$key"] ?? $key) . ':* ' . ($value ? $localization['yes'] : $localization['no']) . "\n"; + } + } + } + + // Trimming the last line break character + $authorizations = trim($authorizations, "\n"); + + // Sending the message + $context->sendMessage( + <<sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the telegram account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the telegram account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Language + * + * Responce for the command: "/language" + * + * Send the language selection menu + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function language(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing language + $language = $context->get('language'); + + if ($language instanceof language) { + // Initialized language + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Sending the language selection + process_language_select::menu( + context: $context, + prefix: 'settings_language_', + title: '🌏 *' . $localization['settings_select_language_title'] . '*', + description: '🌏 *' . $localization['settings_select_language_description'] . '*' + ); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized language + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize language*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Repository + * + * Responce for the command: "/repository" + * + * Sends information about project and menu + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function repository(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Initializing title of the message + $title = '🏛️ ' . $localization['repository_title']; + + // Sending the message + $context->sendMessage($title . "\n\n" . $localization['repository_text'], [ + 'reply_markup' => [ + 'inline_keyboard' => [ + [ + [ + 'text' => '🏛️ ' . $localization['repository_button_code'], + 'url' => 'https://git.mirzaev.sexy/mirzaev/deeproots' + ] + ], + [ + [ + 'text' => '⚠️ ' . $localization['repository_button_issues'], + 'url' => 'https://git.mirzaev.sexy/mirzaev/deeproots/issues' + ], + [ + 'text' => '🌱 ' . $localization['repository_button_suggestions'], + 'url' => 'https://git.mirzaev.sexy/mirzaev/deeproots/issues' + ] + ] + ], + 'remove_keyboard' => true, + 'disable_notification' => true + ], + 'link_preview_options' => [ + 'is_disabled' => true + ] + ]); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Author + * + * Responce for the command: "/author" + * + * Sends + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function author(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Initializing title of the message + $title = '👽 ' . $localization['author_title']; + + // Sending the message + $context->sendMessage($title . "\n\n" . $localization['author_text'], [ + 'reply_markup' => [ + 'inline_keyboard' => [ + [ + [ + 'text' => '📚 ' . $localization['author_button_neurojournal'], + 'url' => 'https://mirzaev.sexy' + ], + [ + 'text' => '🤟 ' . $localization['author_button_projects'], + 'url' => 'https://git.svoboda.works/mirzaev?tab=activity' + ] + ], + [ + [ + 'text' => '✖️ ' . $localization['author_button_twitter'], + 'url' => 'https://x.com/mirzaev_sexy' + ], + [ + 'text' => '🦋 ' . $localization['author_button_bluesky'], + 'url' => 'https://bsky.app/profile/mirzaev.bsky.social' + ], + [ + 'text' => '⛓️ ' . $localization['author_button_bastyon'], + 'url' => 'https://bsky.app/profile/mirzaev.bsky.social' + ] + ], + [ + [ + 'text' => '🇺🇸 ' . $localization['author_button_youtube_english'], + 'url' => 'https://www.youtube.com/@MIRZAEV' + ], + [ + 'text' => '🇷🇺 ' . $localization['author_button_youtube_russian'], + 'url' => 'https://www.youtube.com/@MIRZAEV' + ] + ], + [ + [ + 'text' => '✉️ ' . $localization['author_button_message'], + 'url' => 'https://t.me/mirzaev_sexy' + ] + ] + ], + 'remove_keyboard' => true, + 'disable_notification' => true + ], + 'link_preview_options' => [ + 'is_disabled' => true + ] + ]); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Society + * + * Responce for the command: "/society" + * + * Sends the "mushroom" image and the localized text "why so shroomious" + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function society(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Sending the message + $context->sendPhoto( + new file_input(STORAGE . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'mushroom.jpg'), + [ + 'caption' => $localization['why_so_shroomious'], + 'disable_notification' => true + ] + ); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Questions (system) + * + * Sends questions. answers and localizations management menu + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function system_questions(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Initializing the question model + $model_question = new question(); + + // Counting questions + $questions = $model_question->database->count(); + + // Initializing the answer model + $model_answer = new answer(); + + // Counting answers + $answers = $model_answer->database->count(); + + // Declaring the localizations amounts buffer + $localizations = []; + + // Declaring the questions list + $list = ''; + + foreach (language::cases() as $case) { + // Iterating over language + + // Initializing the localization model by the language + $model_question_localization = new question_localization(language: $case); + + // Counting localizations for the language + $amount = $model_question_localization->database->count(); + + // Writing into the localizations amounts buffer + $localizations[] = $amount; + + // Writing into the questions list + $list .= PHP_EOL . $case->flag() . ' *' . $case->label(language::{$account->language ?? LANGUAGE_DEFAULT} ?? language::{LANGUAGE_DEFAULT}) . ':* ' . $amount; + } + + // Deinitializing unnecessary variables + unset($case, $model_question, $model_question_localization, $model_answer, $amount); + + // Searching for unique values in uhe buffer of questions localizations amounts + $uniques = array_unique($localizations, SORT_REGULAR); + + // Is questions amounts matches? + $matches = count($uniques) === 1; + + // Sending the message + $context->sendMessage( + sprintf( + << [ + 'inline_keyboard' => [ + [ + [ + 'text' => '🔍 ' . $localization['system_questions_button_search'], + 'callback_data' => 'system_questions_search' + ], + [ + 'text' => '✏️ ' . $localization['system_questions_button_create'], + 'callback_data' => 'system_questions_create' + ] + ] + ], + 'remove_keyboard' => true, + 'disable_notification' => true + ], + 'link_preview_options' => [ + 'is_disabled' => true + ] + ] + ); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } +} diff --git a/mirzaev/deeproots/system/models/telegram/middlewares.php b/mirzaev/deeproots/system/models/telegram/middlewares.php new file mode 100755 index 0000000..4269615 --- /dev/null +++ b/mirzaev/deeproots/system/models/telegram/middlewares.php @@ -0,0 +1,706 @@ + + */ +final class middlewares extends core +{ + /** + * account (middleware) + * + * Initialize or registrate the account and write it to the `telegram` variable inside the `$context` + * + * @param context $context + * @param node $next + * + * @return void + */ + public static function telegram(context $context, node $next): void + { + // Is the process stopped? + if ($context->get('stop')) return; + + // Initializing the account + $telegram = $context->getEffectiveUser(); + + // Initializing the telegram accont + $telegram = (new telegram())->initialize($telegram); + + if ($telegram instanceof record) { + // Initialized the account + + // Writing the account into the context variable + $context->set('telegram', $telegram); + + // Continuation of the process + $next($context); + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Account (middleware) + * + * Initialize or registrate the account and write it to the `account` variable inside the `$context` + * + * @param context $context + * @param node $next + * + * @return void + */ + public static function account(context $context, node $next): void + { + // Is the process stopped? + if ($context->get('stop')) return; + + // Initializing the account + $telegram = $context->get('telegram'); + + if ($telegram instanceof record) { + // Initialized the account + + // Initializing the account + /* $account = new account()->initialize($telegram); */ + $account = (new account())->initialize($telegram); + + if ($account instanceof record) { + // Initialized the account + + // Writing the account into the context variable + $context->set('account', $account); + + // Continuation of the process + $next($context); + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Language (middleware) + * + * Implement the account language + * + * @param context $context + * @param node $next + * + * @return void + */ + public static function language(context $context, node $next): void + { + // Is the process stopped? + if ($context->get('stop')) return; + + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Writing the account language into the context variable + $context->set('language', language::{$account->language ?? LANGUAGE_DEFAULT} ?? language::{LANGUAGE_DEFAULT}); + + // Continuation of the process + $next($context); + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Localization (middleware) + * + * Implement the account language and initialize the localization file + * + * @param context $context + * @param node $next + * + * @return void + */ + public static function localization(context $context, node $next): void + { + // Is the process stopped? + if ($context->get('stop')) return; + + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing the language + $language = $context->get('language'); + + if ($language instanceof language) { + // Initialized the language + + // Initializing path to the localization file + $file = LOCALIZATIONS . DIRECTORY_SEPARATOR . strtolower($language->label()) . '.php'; + + if (file_exists($file) && is_readable($file)) { + // Found the localization file + + // Initializing localization + $localization = require($file); + + if (is_array($localization)) { + // Initializae localization + + // Writing localization into the context variable + $context->set('localization', $localization); + + // Continuation of the process + $next($context); + } else { + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not found the localization file + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the localization file*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized language + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize language*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * System (middleware) + * + * Check the account for access to the system + * + * @param context $context + * @param node $next + * + * @return void + */ + public static function system(context $context, node $next): void + { + // Is the process stopped? + if ($context->get('stop')) return; + + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + if ($account->authorized_system) { + // Authorized the account to the system + + // Continuation of the process + $next($context); + } else { + // Not authorized the account to the system + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Sending the message + $context->sendMessage('⛔ *' . $localization['not_authorized_system'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + + // Stopping the process + $context->set('stop', true); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Contact (middleware) + * + * Check the account for access to contact with the organization + * + * @param context $context + * @param node $next + * + * @return void + */ + public static function contact(context $context, node $next): void + { + // Is the process stopped? + if ($context->get('stop')) return; + + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + if ($account->authorized_contact) { + // Authorized the account to contact with the organization + + // Continuation of the process + $next($context); + } else { + // Not authorized the account to contact with the organization + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Sending the message + $context->sendMessage('⛔ *' . $localization['not_authorized_contact'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + + // Stopping the process + $context->set('stop', true); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Join (middleware) + * + * Check the account for access to join to distributions + * + * @param context $context + * @param node $next + * + * @return void + */ + public static function join(context $context, node $next): void + { + // Is the process stopped? + if ($context->get('stop')) return; + + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + if ($account->authorized_joins) { + // Authorized the account to joint to distributions + + // Continuation of the process + $next($context); + } else { + // Not authorized the account to joint to distributions + + // Sending the message + $context->sendMessage('⛔ *' . $localization['not_authorized_joins'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + + // Stopping the process + $context->set('stop', true); + } + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Settings (middleware) + * + * Check the account for access to settings + * + * @param context $context + * @param node $next + * + * @return void + */ + public static function settings(context $context, node $next): void + { + // Is the process stopped? + if ($context->get('stop')) return; + + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + if ($account->authorized_settings) { + // Authorized the account to the settings + + // Continuation of the process + $next($context); + } else { + // Not authorized the account to the settings + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Sending the message + $context->sendMessage('⛔ *' . $localization['not_authorized_settings'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + + // Stopping the process + $context->set('stop', true); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Questions (system) (middleware) + * + * Check the account for system access to questions + * + * @param context $context + * @param node $next + * + * @return void + */ + public static function system_questions(context $context, node $next): void + { + // Is the process stopped? + if ($context->get('stop')) return; + + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + if ($account->authorized_system_questions) { + // Authorized the account to the system settings + + // Continuation of the process + $next($context); + } else { + // Not authorized the account to the system settings + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Sending the message + $context->sendMessage('⛔ *' . $localization['not_authorized_system_questions'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + + // Stopping the process + $context->set('stop', true); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * System settings (system) (middleware) + * + * Check the account for system access to settings + * + * @param context $context + * @param node $next + * + * @return void + */ + public static function system_settings(context $context, node $next): void + { + // Is the process stopped? + if ($context->get('stop')) return; + + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + if ($account->authorized_system_settings) { + // Authorized the account to the system settings + + // Continuation of the process + $next($context); + } else { + // Not authorized the account to the system settings + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Sending the message + $context->sendMessage('⛔ *' . $localization['not_authorized_system_settings'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + + // Stopping the process + $context->set('stop', true); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } +} diff --git a/mirzaev/deeproots/system/models/telegram/processes/language/select.php b/mirzaev/deeproots/system/models/telegram/processes/language/select.php new file mode 100755 index 0000000..02f15e4 --- /dev/null +++ b/mirzaev/deeproots/system/models/telegram/processes/language/select.php @@ -0,0 +1,150 @@ + + */ +final class select extends core +{ + /** + * Language + * + * Send the language choose menu + * + * @param context $context Request data from Telegram + * @param string $prefix Prefix for 'callback_data' (`$prefix . $language->name`) + * @param string $title Title of the message + * @param string $description Description of the message + * @param array $exclude Languages that will be excluded ['ru', 'en'...] + * + * @return void + */ + public static function menu(context $context, string $prefix, string $title, string $description, array $exclude = []): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing language + $language = $context->get('language'); + + if ($language) { + // Initialized language + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Declaring the buffer of generated keyboard with languages + $keyboard = []; + + // Initializing the iterator of rows + $row = 0; + + // Initializing buffer of languages + $languages = language::cases(); + + // Deleting the actual language from buffer of languages + unset($languages[array_search($language, $languages, strict: true)]); + + // Sorting buffer of languages by the actual language + $languages = [$language, ...$languages]; + + foreach ($languages as $language) { + // Iterating over languages + + // Skipping excluded languages + if (array_search($language->name, $exclude, strict: true) !== false) continue; + + // Initializing the row + $keyboard[$row] ??= []; + + // Writing the language choose button into the buffer of generated keyboard with languages + $keyboard[$row][] = [ + 'text' => ($language->flag() ? $language->flag() . ' ' : '') . $language->label($language), + 'callback_data' => $prefix . $language->name + ]; + + // When reaching 4 buttons in a row, move to the next row + if (count($keyboard[$row]) === 4) ++$row; + } + + // Writing the button for helping lozalizing + $keyboard[$row === 0 && empty($keyboard[0]) ? 0 : ++$row] = [ + [ + 'text' => '🗂 ' . $localization['select_language_button_add'], + 'url' => 'https://git.svoboda.works/mirzaev/deeproots/src/branch/stable/mirzaev/deeproots/system/localizations' + ] + ]; + + // Sending the message + $context->sendMessage( + $title ?? '🌏 *' . $localization['select_language_title'] . "*\n" . ($description ?? $localization['select_language_description']), + [ + 'reply_markup' => [ + 'inline_keyboard' => $keyboard, + 'disable_notification' => true + ], + ] + ); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized language + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize language*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } +} diff --git a/mirzaev/deeproots/system/models/telegram/processes/question/create.php b/mirzaev/deeproots/system/models/telegram/processes/question/create.php new file mode 100755 index 0000000..8938f2a --- /dev/null +++ b/mirzaev/deeproots/system/models/telegram/processes/question/create.php @@ -0,0 +1,124 @@ + + */ +final class create extends core +{ + /** + * Process + * + * @var const string PROCESS Name of the process in the telegram user buffer + */ + public const string PROCESS = 'system_questions_create'; + + /** + * Start + * + * Starting the process + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function start(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing language + $language = $context->get('language'); + + if ($language instanceof language) { + // Initialized language + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Initializing the question model + $model_question = new question(); + + // Creating the question + $question = $model_question->create(); + + if ($question) { + // Created the question + + // Sending the message + $context->sendMessage('✅ *' . $localization[static::PROCESS . '_created'] . '*') + ->then(function (message $message) use ($context, $question) { + // Sended the message + + // Sending the question search menu + process_question_search::start($context, $question); + }); + }; + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized language + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize language*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } +} diff --git a/mirzaev/deeproots/system/models/telegram/processes/question/localization/create.php b/mirzaev/deeproots/system/models/telegram/processes/question/localization/create.php new file mode 100755 index 0000000..f441380 --- /dev/null +++ b/mirzaev/deeproots/system/models/telegram/processes/question/localization/create.php @@ -0,0 +1,1124 @@ + + */ +final class create extends core +{ + /** + * Process + * + * @var const string PROCESS Name of the process in the telegram user buffer + */ + public const string PROCESS = 'system_questions_localization_create'; + + /** + * Start + * + * Starting the process + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function start(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing language + $language = $context->get('language'); + + if ($language instanceof language) { + // Initialized language + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function (?array $question) use ($context, $account, $language, $localization) { + // Readed from the telegram user buffer + + if ($question) { + // Found started question create process + + // Sending the message + $context->sendMessage('📂 *' . $localization[static::PROCESS . '_continiued'] . '*') + ->then(function (message $message) use ($context, $account, $language, $localization) { + // Sended the message + + // Sending the question create menu + static::menu($context); + }); + } else { + // Not found started question create process + + // Initializing the question model + $model_question = new question(); + + // Creating the question + $question = $model_question->create(); + + // Writing to the telegram user buffer + $context->setUserDataItem(static::PROCESS, $question) + ->then(function () use ($context, $account, $localization) { + // Writed to the telegram user buffer + + // Sending the message + $context->sendMessage('📂 *' . $localization[static::PROCESS . '_started'] . '*') + ->then(function (message $message) use ($context, $account, $localization) { + // Sended the message + + // Sending the question create menu + static::menu($context); + }); + }); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized language + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize language*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Cancel + * + * Ending the question create process + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function cancel(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function (?array $distribution) use ($context, $localization) { + // Readed from the telegram user buffer + + if ($distribution) { + // Found started question create process + + // Deleting in the telegram user buffer + $context->deleteUserDataItem(static::PROCESS) + ->then(function () use ($context, $localization) { + // Deleted in the telegram user buffer + + // Sending the message + $context->sendMessage('🗑 *' . $localization[static::PROCESS . '_canceled'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Sending the system questions menu + commands::system_questions($context); + }); + }); + } else { + // Not found started question create process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_started'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Sending the system questions menu + commands::system_questions($context); + }); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * End + * + * Ending the question create process + * and creating the distribution record in the database + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function end(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing language + $language = $context->get('language'); + + if ($language instanceof language) { + // Initialized language + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function (?array $distribution) use ($context, $account, $language, $localization) { + // Readed from the telegram user buffer + + if ($distribution) { + // Found started question create process + + // Initializing the distribution model + $model_distribution = new distribution; + + // Creating the distribution + $created_distribution = $model_distribution->create( + creator: $account->identifier, + latitude: $distribution['latitude'], + longitude: $distribution['longitude'] + ); + + if ($created_distribution) { + // Created the distribution + + // Sending the message + $context->sendMessage('✏️ *' . $localization[static::PROCESS . '_created_distribution'] . '*') + ->then(function (message $message) use ($context, $account, $language, $localization, $distribution, $model_distribution, $created_distribution) { + // Sended the message + + // Initializing the distribution localization + $created_localization = $model_distribution->localization->create( + distribution: $created_distribution, + language: $distribution['localization']['language'], + name: $distribution['localization']['name'] + ); + + if ($created_localization) { + // Created the localization + + // Sending the message + $context->sendMessage('✏️ *' . $localization[static::PROCESS . '_created_localization'] . '*') + ->then(function (message $message) use ($context, $localization) { + // Sended the message + + // Deleting from the telegram user buffer + $context->deleteUserDataItem(static::PROCESS) + ->then(function () use ($context, $localization) { + // Deleted from the telegram user buffer + + // Sending the message + $context->sendMessage('✅ *' . $localization[static::PROCESS . '_completed'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Sending the system questions menu + commands::system_questions($context); + }); + }); + }); + } else { + // Not created the distribution localization + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_created_localization'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + }); + } else { + // Not created the distribution + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_created_distribution'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not found started question create process + + // Ending the conversation process + $context->endConversation(); + + // Sending the system questions menu + commands::system_questions($context); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized language + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize language*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Generation + * + * Sends the question create menu with parameters: language, name, location + * When all parameters was initialized then sends the complete button + * + * @param context $context Request data from Telegram + * + * @return void + */ + protected static function menu(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing language + $language = $context->get('language'); + + if ($language) { + // Initialized language + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function (?array $distribution) use ($context, $account, $language, $localization) { + // Readed from the telegram user buffer + + if ($distribution) { + // Found started question create process + + // Initializing the buffer of generated keyboard with languages + $keyboard = [ + [ + [ + 'text' => empty($distribution['localization']['language']) ? '🟢 ' . $localization[static::PROCESS . '_button_language'] : '🟢 ' . $localization['distribution_declaration_button_language'] . ': ' . $distribution['localization']['language']->flag() . ' ' . $distribution['localization']['language']->label($language), + 'callback_data' => static::PROCESS . '_language' + ] + ], + [ + [ + 'text' => empty($distribution['localization']['name']) ? '🔴 ' . $localization[static::PROCESS . '_button_name'] : '🟢 ' . $localization['distribution_declaration_button_name'] . ': ' . $distribution['localization']['name'], + 'callback_data' => static::PROCESS . '_name' + ] + ], + [ + [ + 'text' => empty($distribution['latitude']) || empty('longitude') ? '🔴 ' . $localization[static::PROCESS . '_button_location'] : '🟢 ' . $localization['distribution_declaration_button_location'] . ': ' . $distribution['latitude'] . ', ' . $distribution['longitude'], + 'callback_data' => static::PROCESS . '_location' + ] + ], + ]; + + // Initializing the index of last row + $last = count($keyboard); + + // Initializing the last row + $keyboard[$last] ??= []; + + // Initializing the button for canceling the generation process + $keyboard[$last][] = [ + 'text' => '❎ ' . $localization[static::PROCESS . '_button_cancel'], + 'callback_data' => static::PROCESS . '_cancel' + ]; + + if ( + !empty($distribution['localization']['language']) && + !empty($distribution['localization']['name']) && + !empty($distribution['latitude']) && + !empty($distribution['longitude']) + ) { + // Initialized all requeired parameters + + // Initializing the button for completing the generation process + $keyboard[$last][] = [ + 'text' => '✅ ' . $localization[static::PROCESS . '_button_confirm'], + 'callback_data' => static::PROCESS . '_end' + ]; + } + + // Ending the conversation process + $context->endConversation() + ->then(function () use ($context, $localization, $keyboard) { + // Deinitialized the conversation process + + // Sending the message + $context->sendMessage( + '📀 *' . $localization[static::PROCESS . '_generation'] . '*', + [ + 'reply_markup' => [ + 'inline_keyboard' => $keyboard, + 'disable_notification' => true, + 'remove_keyboard' => true + ], + ] + ); + }); + } else { + // Not found started question create process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_started'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Sending the system questions menu + commands::system_questions($context); + }); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function ($message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized language + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize language*') + ->then(function ($message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function ($message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Language + * + * Write language into the question create buffer + * + * @param context $context Request data from Telegram + * @param language $new The language + * + * @return void + */ + public static function language(context $context, language $new): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing language + $language = $context->get('language'); + + if ($language instanceof language) { + // Initialized language + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function (?array $distribution) use ($context, $account, $language, $localization, $new) { + // Readed from the telegram user buffer + + if ($distribution) { + // Found started question create process + + try { + // Initializing the old language + $old = $distribution['localization']['language']; + + // Writing into the question create process buffer + $distribution['localization']['language'] = $new; + + // Writing to the telegram user buffer + $context->setUserDataItem(static::PROCESS, $distribution) + ->then(function () use ($context, $account, $language, $localization, $new, $old) { + // Writed to the telegram user buffer + + // Sending the message + $context->sendMessage('✅ *' . $localization[static::PROCESS . '_language_update_success'] . '* ' . ($old->flag() ? $old->flag() . ' ' : '') . $old->label($language) . ' → *' . ($new->flag() ? $new->flag() . ' ' : '') . $new->label($language) . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Sending the question create menu + static::menu($context); + }); + }); + } catch (error $error) { + // Failed to send the message about language update + + // Sending the message + $context->sendMessage('❎ *' . $localization[static::PROCESS . '_language_update_fail']) + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not found started question create process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_started'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Sending the system questions menu + commands::system_questions($context); + }); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized language + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize language*') + ->then(function ($message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Name + * + * Write name into the question create buffer + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function name(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function (?array $distribution) use ($context, $account, $localization) { + // Readed from the telegram user buffer + + if ($distribution) { + // Found started question create process + + // Initializing the new name + $new = $context->getMessage()->getText(); + + if (!empty($new)) { + // Initialized the new name + + if (mb_strlen($new) >= 3) { + // Passed minimum length check + + if (mb_strlen($new) <= 64) { + // Passed maximum length check + + // Search for restricted characters + preg_match_all('/[\W\d]/u', $new, $matches); + + // Declaring the buffer of found restricted characters (except spaces) + $characters = []; + + // Declaring the counter of found spaces + $spaces = 0; + + foreach ($matches[0] as $match) { + // Iterating over found restricted characters + + if ($match === ' ') { + // Space-character + + // Increasing the counter of found spaces + ++$spaces; + } else { + // Not space-character + + // Writing into the buffer of found restricted characers (except spaces) + $characters[] = $match; + } + } + + if (empty($characters)) { + // Not found restricted characters + + if ($spaces <= 2) { + // Number of spaces is not more than 2 + + try { + // Initializing the old name + $old = empty($distribution['localization']['name']) ? '_' . $localization['empty'] . '_' : $distribution['localization']['name']; + + // Writing into the question create process buffer + $distribution['localization']['name'] = $new; + + // Writing to the telegram user buffer + $context->setUserDataItem(static::PROCESS, $distribution) + ->then(function () use ($context, $account, $localization, $new, $old) { + // Writed to the telegram user buffer + + // Sending the message + $context->sendMessage('✅ *' . $localization[static::PROCESS . '_name_update_success'] . "* $old → *$new*") + ->then(function (message $message) use ($context) { + // Sended the message + + // Sending the question create menu + static::menu($context); + }); + }); + } catch (error $error) { + // Failed to send the message about name update + + // Sending the message + $context->sendMessage('❎ *' . $localization[static::PROCESS . '_name_update_fail']) + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Number of spaces is more than 2 + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_name_request_spaces'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter name again + button_question_create::name($context); + }); + } + } else { + // Found restricted characters + + // Initializing title of the message + $title = '⚠️ *' . $localization[static::PROCESS . '_name_request_restricted_characters_title'] . '*'; + + // Initializing description of the message + $description = '*' . $localization[static::PROCESS . '_name_request_restricted_characters_description'] . '* \\' . implode(', \\', $characters); + + // Sending the message + $context->sendMessage( + <<then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter name again + button_question_create::name($context); + }); + } + } else { + // Not passed maximum length check + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_name_request_too_long'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter name again + button_question_create::name($context); + }); + } + } else { + // Not passed minimum length check + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_name_request_too_short'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter name again + button_question_create::name($context); + }); + } + } else { + // Failed to initialize the new name + + // Sending the message + $context->sendMessage('📄 *' . $localization[static::PROCESS . '_name_request_not_acceptable'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter name again + button_question_create::name($context); + }); + } + } else { + // Not found started question create process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_started'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Sending the system questions menu + commands::system_questions($context); + }); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Location + * + * Write latitude and longitude into the question create buffer + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function location(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function (?array $distribution) use ($context, $account, $localization) { + // Readed from the telegram user buffer + + if ($distribution) { + // Found started declaration process + + // Initializing the new location + preg_match_all('/(\-?\d{1,2})\.?(\d*)/', $context->getMessage()->getText(), $matches); + + if ($matches[0]) { + // Initialized the new location + + // Initializing the new latitude + $latitude = round((float) $matches[0][0], 6); + + // Initializing the new longitude + $longitude = round((float) $matches[0][1], 6); + + if (!empty($latitude) && !empty($longitude)) { + // Initialized the new latitude and the new longitude + + if ($latitude >= 0) { + // Passed latitude minimum value check + + if ($latitude <= 90) { + // Passed latitude maximum value check + + if ($longitude >= 0) { + // Passed longitude minimum value check + + if ($longitude <= 180) { + // Passed longitude maximum value check + + try { + // Initializing the old location + $old = str_replace('.', '\\.', (empty($distribution['latitude']) ? '_' . $localization['empty'] . '_' : $distribution['latitude']) . ', ' . (empty($distribution['longitude']) ? '_' . $localization['empty'] . '_' : $distribution['longitude'])); + + // Writing into the question create process buffer + $distribution['latitude'] = $latitude; + $distribution['longitude'] = $longitude; + + // Writing to the telegram user buffer + $context->setUserDataItem(static::PROCESS, $distribution) + ->then(function () use ($context, $account, $localization, $latitude, $longitude, $old) { + // Writed to the telegram user buffer + + // Initializing the new location + $new = str_replace('.', '\\.', $latitude . ', ' . $longitude); + + // Sending the message + $context->sendMessage('✅ *' . $localization[static::PROCESS . '_location_update_success'] . "*\n$old → *$new*") + ->then(function (message $message) use ($context) { + // Sended the message + + // Sending the question create menu + static::menu($context); + }); + }); + } catch (error $error) { + // Failed to send the message about name update + + // Sending the message + $context->sendMessage('❎ *' . $localization[static::PROCESS . '_name_update_fail']) + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not passed longitude maximum value check + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_location_send_longitude_too_big'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter locaztion again + button_question_create::location($context); + }); + } + } else { + // Not passed longitude minimum value check + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_location_send_longitude_too_small'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter locaztion again + button_question_create::location($context); + }); + } + } else { + // Not passed latitude maximum value check + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_location_send_latitude_too_big'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter locaztion again + button_question_create::location($context); + }); + } + } else { + // Not passed latitude minimum value check + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_location_send_latitude_too_small'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter locaztion again + button_question_create::location($context); + }); + } + } else { + // Failed to initialize the new name + + // Sending the message + $context->sendMessage('📄 *' . $localization[static::PROCESS . '_location_send_not_acceptable'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to send location again + button_question_create::location($context); + }); + } + } else { + // Not initialized the new location + + // Sending the message + $context->sendMessage('📄 *' . $localization[static::PROCESS . '_location_send_not_acceptable'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to send locaztion again + button_question_create::location($context); + }); + } + } else { + // Not found started distribution declaratoin process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_started'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Sending the system questions menu + commands::system_questions($context); + }); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } +} diff --git a/mirzaev/deeproots/system/models/telegram/processes/question/search.php b/mirzaev/deeproots/system/models/telegram/processes/question/search.php new file mode 100755 index 0000000..659851d --- /dev/null +++ b/mirzaev/deeproots/system/models/telegram/processes/question/search.php @@ -0,0 +1,2226 @@ + + */ +final class search extends core +{ + use escape; + + /** + * Process + * + * @var const string PROCESS Name of the process in the telegram user buffer + */ + public const string PROCESS = 'system_questions_search'; + + /** + * Start + * + * Starting the search process + * + * @param context $context Request data from Telegram + * @param int|null $identifier Identifier of the question + * + * @return void + */ + public static function start(context $context, ?int $identifier = null): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing language + $language = $context->get('language'); + + if ($language instanceof language) { + // Initialized language + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function (?array $search) use ($context, $account, $language, $localization, $identifier) { + // Readed from the telegram user buffer + + if ($search) { + // Found started search process + + // Sending the message + $context->sendMessage('🗂 *' . $localization[static::PROCESS . '_continued'] . '*') + ->then(function (message $message) use ($context, $account, $language, $localization) { + // Sended the message + + // Searching + static::search($context); + }); + } else { + // Not found started search process + + // Initializing the question search buffer + $search = [ + 'identifier' => $identifier, + 'text' => null, + 'A' => null, + 'B' => null, + 'C' => null, + 'D' => null, + 'page' => 0 + ]; + + // Writing to the telegram user buffer + $context->setUserDataItem(static::PROCESS, $search) + ->then(function () use ($context, $account, $localization) { + // Writed to the telegram user buffer + + // Sending the message + $context->sendMessage('🗂 *' . $localization[static::PROCESS . '_started'] . '*') + ->then(function (message $message) use ($context, $account, $localization) { + // Sended the message + + // Searching + static::search($context); + }); + }); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized language + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize language*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * End + * + * Ending the search process + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function end(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function (?array $search) use ($context, $localization) { + // Readed from the telegram user buffer + + if ($search) { + // Found started search process + + // Deleting from the telegram user buffer + $context->deleteUserDataItem(static::PROCESS, $search) + ->then(function () use ($context, $search, $localization) { + // Deleted from the telegram user buffer + + // Sending the message + $context->sendMessage('🗂 *' . $localization[static::PROCESS . '_ended'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Sending the system questions menu + commands::system_questions($context); + }); + }); + } else { + // Not found started search process + + // Ending the conversation process + $context->endConversation(); + + // Sending the system questions menu + commands::system_questions($context); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Search + * + * Sends the list of found questions and menu with parameters + * + * @param context $context Request data from Telegram + * + * @return void + */ + protected static function search(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing language + $language = $context->get('language'); + + if ($language) { + // Initialized language + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function (?array $search) use ($context, $account, $language, $localization) { + // Readed from the telegram user buffer + + if ($search) { + // Found started search process + + // Initializing the buffer of generated keyboard with languages + $keyboard = [ + [ + [ + 'text' => empty($search['identifier']) ? '🔴 ' . $localization[static::PROCESS . '_button_identifier'] : '🟢 ' . $localization[static::PROCESS . '_button_identifier'] . ': ' . $search['identifier'], + 'callback_data' => static::PROCESS . '_identifier' + ] + ], + [ + [ + 'text' => empty($search['text']) ? '🔴 ' . $localization[static::PROCESS . '_button_text'] : '🟢 ' . $localization[static::PROCESS . '_button_text'] . ': ' . $search['text'], + 'callback_data' => static::PROCESS . '_text' + ] + ], + [ + [ + 'text' => empty($search['A']) ? '🔴 ' . $localization[static::PROCESS . '_button_a'] : '🟢 ' . $localization[static::PROCESS . '_button_a'] . ': ' . $search['A'], + 'callback_data' => static::PROCESS . '_a' + ] + ], + [ + [ + 'text' => empty($search['B']) ? '🔴 ' . $localization[static::PROCESS . '_button_b'] : '🟢 ' . $localization[static::PROCESS . '_button_b'] . ': ' . $search['B'], + 'callback_data' => static::PROCESS . '_b' + ] + ], + [ + [ + 'text' => empty($search['C']) ? '🔴 ' . $localization[static::PROCESS . '_button_c'] : '🟢 ' . $localization[static::PROCESS . '_button_c'] . ': ' . $search['C'], + 'callback_data' => static::PROCESS . '_c' + ] + ], + [ + [ + 'text' => empty($search['D']) ? '🔴 ' . $localization[static::PROCESS . '_button_d'] : '🟢 ' . $localization[static::PROCESS . '_button_d'] . ': ' . $search['D'], + 'callback_data' => static::PROCESS . '_d' + ] + ] + ]; + + // Ending the conversation process + $context->endConversation() + ->then(function () use ($context, $account, $language, $localization, $search, $keyboard) { + // Deinitialized the conversation process + + // Initializing the question model + $model_question = new question; + + // Initializing amount of questions for reading per page + $page = SYSTEM_QUESTIONS_SEARCH_PAGE; + + if ( + empty($search['identifier']) && + empty($search['text']) && + empty($search['A']) && + empty($search['B']) && + empty($search['C']) && + empty($search['D']) + ) { + // Each parameter is empty + + // Search for questions + $questions = $model_question->database->read( + amount: $page + 1, + offset: $search['page'] < 1 ? 0 : $page * $search['page'] + ); + } else { + // The search buffer has at least one parameter + + // Search for questions + $questions = $model_question->database->read( + filter: function (record $question) use ($search) { + // Initializing the matched buffer + $matched = false; + + if (!empty($search['identifier'])) { + // Requested search by identifier + + if ($question->identifier === $search['identifier']) { + // Identifier matched + + // Reinitializing the matched buffer + $matched = true; + } else { + // Identifier not matched + + // Exit (success) + return false; + } + } + + if ( + !empty($search['text']) || + !empty($search['A']) || + !empty($search['B']) || + !empty($search['C']) || + !empty($search['D']) + ) { + // Requested search with localizations + + // Initializing the buffer of result for localizations matchings process + $result = false; + + foreach (language::cases() as $case) { + // Iterating over languages + + // Initializing the question localization model + $model_question_localization = new question_localization($case); + + // Initializing localization + $localization = $model_question_localization->database->read( + filter: fn(record $localization) => $localization->identifier === $question->identifier, + amount: 1 + )[0] ?? null; + + if ($localization instanceof record) { + // Initialized the question localization + + if (!empty($search['text'])) { + // Requested search by localizations text + + // Splitting the localization text into parts + $parts = preg_split('/[\s]/', $localization->text); + + foreach ($parts as $part) { + // Iterating over localization text parts + + if (levenshtein($part, $search['text']) <= SYSTEM_QUESTIONS_SEARCH_QUESTION_TEXT_LEVENSHTEIN_DISTANCE) { + // Text matched by Levenshtein function + + // Reinitializing the matched buffer + $result = true; + + // Exit (success) + break 1; + } + } + + if ($result) { + // Text matched by Levenshtein function + + // Reinitializing the matched buffer + $matched = true; + } else { + // Text not matched by Levenshtein function + + // Exit (success) + return false; + } + } + + if (!empty($search['A'])) { + // Requested search by localizations A + + // Initializing the result status + $result = false; + + // Splitting the localization A into parts + $parts = preg_split('/[\s]/', $localization->A); + + foreach ($parts as $part) { + // Iterating over localization A parts + + if (levenshtein($part, $search['A']) <= SYSTEM_QUESTIONS_SEARCH_QUESTION_A_LEVENSHTEIN_DISTANCE) { + // A matched by Levenshtein function + + // Reinitializing the matched buffer + $result = true; + + // Exit (success) + break 1; + } + } + + if ($result) { + // A matched by Levenshtein function + + // Reinitializing the matched buffer + $matched = true; + } else { + // A not matched by Levenshtein function + + // Exit (success) + return false; + } + } + + if (!empty($search['B'])) { + // Requested search by localizations B + + // Initializing the result status + $result = false; + + // Splitting the localization B into parts + $parts = preg_split('/[\s]/', $localization->B); + + foreach ($parts as $part) { + // Iterating over localization B parts + + if (levenshtein($part, $search['B']) <= SYSTEM_QUESTIONS_SEARCH_QUESTION_B_LEVENSHTEIN_DISTANCE) { + // B matched by Levenshtein function + + // Reinitializing the matched buffer + $result = true; + + // Exit (success) + break 1; + } + } + + if ($result) { + // B matched by Levenshtein function + + // Reinitializing the matched buffer + $matched = true; + } else { + // B not matched by Levenshtein function + + // Exit (success) + return false; + } + } + + if (!empty($search['C'])) { + // Requested search by localizations C + + // Initializing the result status + $result = false; + + // Splitting the localization C into parts + $parts = preg_split('/[\s]/', $localization->C); + + foreach ($parts as $part) { + // Iterating over localization C parts + + if (levenshtein($part, $search['C']) <= SYSTEM_QUESTIONS_SEARCH_QUESTION_C_LEVENSHTEIN_DISTANCE) { + // C matched by Levenshtein function + + // Reinitializing the matched buffer + $result = true; + + // Exit (success) + break 1; + } + } + + if ($result) { + // C matched by Levenshtein function + + // Reinitializing the matched buffer + $matched = true; + } else { + // C not matched by Levenshtein function + + // Exit (success) + return false; + } + } + + if (!empty($search['D'])) { + // Requested search by localizations D + + // Initializing the result status + $result = false; + + // Splitting the localization D into parts + $parts = preg_split('/[\s]/', $localization->D); + + foreach ($parts as $part) { + // Iterating over localization D parts + + if (levenshtein($part, $search['D']) <= SYSTEM_QUESTIONS_SEARCH_QUESTION_D_LEVENSHTEIN_DISTANCE) { + // D matched by Levenshtein function + + // Reinitializing the matched buffer + $result = true; + + // Exit (success) + break 1; + } + } + + if ($result) { + // D matched by Levenshtein function + + // Reinitializing the matched buffer + $matched = true; + } else { + // D not matched by Levenshtein function + + // Exit (success) + return false; + } + } + } + } + + // Reinitializing the matched buffer + $matched = $result; + } + + // Exit (success) + return $matched; + }, + amount: $page + 1, + offset: $search['page'] < 1 ? 0 : $page * $search['page'] + ); + } + + // Initializing the next page existence status + $next = count($questions) > $page; + + // Deleting the additional readed questions + unset($questions[$page]); + + // Sending the message + $context->sendMessage( + '🔍 *' . $localization[static::PROCESS . '_title'] . '*', + [ + 'reply_markup' => [ + 'inline_keyboard' => $keyboard, + 'disable_notification' => true, + 'remove_keyboard' => true + ], + ] + )->then(function (message $message) use ($context, $account, $language, $localization, $search, $page, $next, $questions) { + // Sended the message + + if (count($questions) > 0) { + // Initialized questions + + foreach ($questions as $question) { + // Iterating over found questions + + /* // Initializing the question localization model by the account language + $model_question_localization = new question_localization(language::{$account->language ?? LANGUAGE_DEFAULT} ?? language::{LANGUAGE_DEFAULT}); + + // Initializing the question localization + $question_localization = $model_question_localization->database->read( + filter: fn(record $localization) => $localization->identifier === $question->identifier, + amount: 1 + )[0] ?? null; + + if (is_null($question_localization)) { + // Failed to initialize the question localization by the account language + + // Reinitializing the question localization model by the default language + $model_question_localization = new question_localization(language::{LANGUAGE_DEFAULT}); + + // Initializing the question localization + $question_localization = $model_question_localization->database->read( + filter: fn(record $localization) => $localization->identifier === $question->identifier, + amount: 1 + )[0] ?? null; + + if (is_null($question_localization)) { + // Failed to initialize the question localization by the default language + + // Sending the message + await($context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_localized'] . '* \(' . $question->identifier . '\)') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + })); + + // Processing the next question + continue; + } + } */ + + // Initializing the message text + $text = static::message( + question: $question, + localization: $localization + ); + + // Initializing the message keyboard + $keyboard = static::keyboard( + question: $question, + localization: $localization + ); + + // Sending the message + await($context->sendMessage( + $text, + [ + 'reply_markup' => [ + 'inline_keyboard' => $keyboard, + 'disable_notification' => true, + 'remove_keyboard' => true + ], + ] + )); + } + + if ($next) { + // Exists the next page + + // Sending the message + $context->sendMessage( + '🔎 *' . $localization[static::PROCESS . '_page_next_exists'] . '*', + [ + 'reply_markup' => [ + 'inline_keyboard' => [ + [ + [ + 'text' => '🔒 ' . $localization[static::PROCESS . '_button_end'], + 'callback_data' => static::PROCESS . '_end' + ] + ], + [ + [ + 'text' => '📤 ' . $localization[static::PROCESS . '_button_page_next'] . ': ' . ++$search['page'], + 'callback_data' => static::PROCESS . '_next' + ] + ] + ], + 'disable_notification' => true, + 'remove_keyboard' => true + ], + ] + )->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } else { + // Not exists the next page + + // Sending the message + $context->sendMessage( + '🔎 *' . $localization[static::PROCESS . '_page_next_not_exists'] . '*', + [ + 'reply_markup' => [ + 'inline_keyboard' => [ + [ + [ + 'text' => '🔒 ' . $localization[static::PROCESS . '_button_end'], + 'callback_data' => static::PROCESS . '_end' + ] + ] + ], + 'disable_notification' => true, + 'remove_keyboard' => true + ], + ] + )->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized questions + + // Sending the message + $context->sendMessage( + '⚠️ *' . $localization[static::PROCESS . '_empty'] . '*', + [ + 'reply_markup' => [ + 'inline_keyboard' => [ + [ + [ + 'text' => '🔒 ' . $localization[static::PROCESS . '_button_end'], + 'callback_data' => static::PROCESS . '_end' + ] + ] + ], + 'disable_notification' => true, + 'remove_keyboard' => true + ], + ] + ) + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + }); + }); + } else { + // Not found started search process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_started'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Sending the system questions menu + commands::system_questions($context); + }); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized language + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize language*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Next + * + * Write actual page + 1 into the question search buffer + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function next(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function ($search) use ($context, $localization) { + // Readed from the telegram user buffer + + if ($search) { + // Found started search process + + // Writing into the question search process buffer + ++$search['page']; + + // Writing to the telegram user buffer + $context->setUserDataItem(static::PROCESS, $search) + ->then(function () use ($context) { + // Writed to the telegram user buffer + + // Searching + static::search($context); + }); + } else { + // Not found started search process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_started'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Sending the system questions menu + commands::system_questions($context); + }); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize your Telegram account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Identifier + * + * Write identifier into the question search buffer + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function identifier(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function ($search) use ($context, $localization) { + // Readed from the telegram user buffer + + if ($search) { + // Found started search process + + // Initializing the button + $button = $context->getCallbackQuery()?->getData(); + + if ($button === 'cancel') { + // Cancel + + // Sending the message + $context->sendMessage('❎ *' . $localization[static::PROCESS . '_identifier_cancel_success'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Searching + static::search($context); + }); + } else if ($button === 'delete') { + // Delete + + // Writing into the question search process buffer + $search['identifier'] = null; + + // Writing to the telegram user buffer + $context->setUserDataItem(static::PROCESS, $search) + ->then(function () use ($context, $localization) { + // Writed to the telegram user buffer + + // Sending the message + $context->sendMessage('🗑 *' . $localization[static::PROCESS . '_identifier_delete_success'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Searching + static::search($context); + }); + }); + } else { + // Write + + // Initializing the new identifier + $new = $context->getMessage()->getText(); + + if (!empty($new)) { + // Initialized the new identifier + + if (mb_strlen($new) >= 1) { + // Passed minimum length check + + if (mb_strlen($new) <= 12) { + // Passed maximum length check + + // Search for restricted characters + preg_match_all('/[^\d]/u', $new, $matches); + + // Declaring the buffer of found restricted characters + $characters = []; + + foreach ($matches[0] as $match) { + // Iterating over found restricted characters + + // Writing into the buffer of found restricted characers + $characters[] = $match; + } + + if (empty($characters)) { + // Not found restricted characters + + // Initializing the old identifier + $old = empty($search['identifier']) ? '_' . $localization['empty'] . '_' : $search['identifier']; + + // Writing into the question search process buffer + $search['identifier'] = (int) $new; + + // Writing to the telegram user buffer + $context->setUserDataItem(static::PROCESS, $search) + ->then(function () use ($context, $localization, $new, $old) { + // Writed to the telegram user buffer + + // Sending the message + $context->sendMessage('✅ *' . $localization[static::PROCESS . '_identifier_update_success'] . "* $old → *$new*") + ->then(function (message $message) use ($context) { + // Sended the message + + // Searching + static::search($context); + }); + }); + } else { + // Found restricted characters + + // Initializing title of the message + $title = '⚠️ *' . $localization[static::PROCESS . '_identifier_request_restricted_characters_title'] . '*'; + + // Initializing description of the message + $description = '*' . $localization[static::PROCESS . '_identifier_request_restricted_characters_description'] . '* \\' . implode(', \\', $characters); + + // Sending the message + $context->sendMessage( + <<then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter identifier again + buttons_question_search::identifier($context); + }); + } + } else { + // Not passed maximum length check + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_identifier_request_too_long'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter identifier again + buttons_question_search::identifier($context); + }); + } + } else { + // Not passed minimum length check + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_identifier_request_too_short'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter identifier again + buttons_question_search::identifier($context); + }); + } + } else { + // Failed to initialize the new identifier + + // Sending the message + $context->sendMessage('📄 *' . $localization[static::PROCESS . '_identifier_request_not_acceptable'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter identifier again + buttons_question_search::identifier($context); + }); + } + } + } else { + // Not found started search process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_started'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Sending the system questions menu + commands::system_questions($context); + }); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize your Telegram account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Text + * + * Write text into the question search buffer + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function text(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function ($search) use ($context, $localization) { + // Readed from the telegram user buffer + + if ($search) { + // Found started search process + + // Initializing the button + $button = $context->getCallbackQuery()?->getData(); + + if ($button === 'cancel') { + // Cancel + + // Sending the message + $context->sendMessage('❎ *' . $localization[static::PROCESS . '_text_cancel_success'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Searching + static::search($context); + }); + } else if ($button === 'delete') { + // Delete + + // Writing into the question search process buffer + $search['text'] = null; + + // Writing to the telegram user buffer + $context->setUserDataItem(static::PROCESS, $search) + ->then(function () use ($context, $localization) { + // Writed to the telegram user buffer + + // Sending the message + $context->sendMessage('🗑 *' . $localization[static::PROCESS . '_text_delete_success'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Searching + static::search($context); + }); + }); + } else { + // Write + + // Initializing the new text + $new = $context->getMessage()->getText(); + + if (!empty($new)) { + // Initialized the new text + + if (mb_strlen($new) >= 3) { + // Passed minimum length check + + if (mb_strlen($new) <= 256) { + // Passed maximum length check + + // Initializing the old text + $old = empty($search['text']) ? '_' . $localization['empty'] . '_' : $search['text']; + + // Writing into the question search process buffer + $search['text'] = $new; + + // Writing to the telegram user buffer + $context->setUserDataItem(static::PROCESS, $search) + ->then(function () use ($context, $localization, $new, $old) { + // Writed to the telegram user buffer + + // Sending the message + $context->sendMessage('✅ *' . $localization[static::PROCESS . '_text_update_success'] . "* $old → *" . escape::markdown($new) . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Searching + static::search($context); + }); + }); + } else { + // Not passed maximum length check + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_text_request_too_long'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter text again + buttons_question_search::text($context); + }); + } + } else { + // Not passed minimum length check + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_text_request_too_short'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter text again + buttons_question_search::text($context); + }); + } + } else { + // Failed to initialize the new text + + // Sending the message + $context->sendMessage('📄 *' . $localization[static::PROCESS . '_text_request_not_acceptable'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter text again + buttons_question_search::text($context); + }); + } + } + } else { + // Not found started search process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_started'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Sending the system questions menu + commands::system_questions($context); + }); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize your Telegram account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + /** + * A + * + * Write A-answer into the question search buffer + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function a(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function ($search) use ($context, $localization) { + // Readed from the telegram user buffer + + if ($search) { + // Found started search process + + // Initializing the button + $button = $context->getCallbackQuery()?->getData(); + + if ($button === 'cancel') { + // Cancel + + // Sending the message + $context->sendMessage('❎ *' . $localization[static::PROCESS . '_a_cancel_success'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Searching + static::search($context); + }); + } else if ($button === 'delete') { + // Delete + + // Writing into the question search process buffer + $search['A'] = null; + + // Writing to the telegram user buffer + $context->setUserDataItem(static::PROCESS, $search) + ->then(function () use ($context, $localization) { + // Writed to the telegram user buffer + + // Sending the message + $context->sendMessage('🗑 *' . $localization[static::PROCESS . '_a_delete_success'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Searching + static::search($context); + }); + }); + } else { + // Write + + // Initializing the new A-answer + $new = $context->getMessage()->getText(); + + if (!empty($new)) { + // Initialized the new A-answer + + if (mb_strlen($new) >= 3) { + // Passed minimum length check + + if (mb_strlen($new) <= 128) { + // Passed maximum length check + + // Initializing the old A-answer + $old = empty($search['A']) ? '_' . $localization['empty'] . '_' : $search['A']; + + // Writing into the question search process buffer + $search['A'] = $new; + + // Writing to the telegram user buffer + $context->setUserDataItem(static::PROCESS, $search) + ->then(function () use ($context, $localization, $new, $old) { + // Writed to the telegram user buffer + + // Sending the message + $context->sendMessage('✅ *' . $localization[static::PROCESS . '_a_update_success'] . "* $old → *" . escape::markdown($new) . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Searching + static::search($context); + }); + }); + } else { + // Not passed maximum length check + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_a_request_too_long'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter A-answer again + buttons_question_search::a($context); + }); + } + } else { + // Not passed minimum length check + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_a_request_too_short'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter A-answer again + buttons_question_search::a($context); + }); + } + } else { + // Failed to initialize the new A-answer + + // Sending the message + $context->sendMessage('📄 *' . $localization[static::PROCESS . '_a_request_not_acceptable'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter A-answer again + buttons_question_search::a($context); + }); + } + } + } else { + // Not found started search process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_started'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Sending the system questions menu + commands::system_questions($context); + }); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize your Telegram account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + + /** + * B + * + * Write B-answer into the question search buffer + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function b(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function ($search) use ($context, $localization) { + // Readed from the telegram user buffer + + if ($search) { + // Found started search process + + // Initializing the button + $button = $context->getCallbackQuery()?->getData(); + + if ($button === 'cancel') { + // Cancel + + // Sending the message + $context->sendMessage('❎ *' . $localization[static::PROCESS . '_b_cancel_success'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Searching + static::search($context); + }); + } else if ($button === 'delete') { + // Delete + + // Writing into the question search process buffer + $search['B'] = null; + + // Writing to the telegram user buffer + $context->setUserDataItem(static::PROCESS, $search) + ->then(function () use ($context, $localization) { + // Writed to the telegram user buffer + + // Sending the message + $context->sendMessage('🗑 *' . $localization[static::PROCESS . '_b_delete_success'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Searching + static::search($context); + }); + }); + } else { + // Write + + // Initializing the new B-answer + $new = $context->getMessage()->getText(); + + if (!empty($new)) { + // Initialized the new B-snswer + + if (mb_strlen($new) >= 3) { + // Passed minimum length check + + if (mb_strlen($new) <= 128) { + // Passed maximum length check + + // Initializing the old B-answer + $old = empty($search['B']) ? '_' . $localization['empty'] . '_' : $search['B']; + + // Writing into the question search process buffer + $search['B'] = $new; + + // Writing to the telegram user buffer + $context->setUserDataItem(static::PROCESS, $search) + ->then(function () use ($context, $localization, $new, $old) { + // Writed to the telegram user buffer + + // Sending the message + $context->sendMessage('✅ *' . $localization[static::PROCESS . '_b_update_success'] . "* $old → *" . escape::markdown($new) . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Searching + static::search($context); + }); + }); + } else { + // Not passed maximum length check + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_b_request_too_long'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter B-answer again + buttons_question_search::b($context); + }); + } + } else { + // Not passed minimum length check + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_b_request_too_short'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter B-answer again + buttons_question_search::b($context); + }); + } + } else { + // Failed to initialize the new B-answer + + // Sending the message + $context->sendMessage('📄 *' . $localization[static::PROCESS . '_b_request_not_acceptable'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter B-answer again + buttons_question_search::b($context); + }); + } + } + } else { + // Not found started search process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_started'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Sending the system questions menu + commands::system_questions($context); + }); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize your Telegram account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * C + * + * Write C-answer into the question search buffer + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function c(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function ($search) use ($context, $localization) { + // Readed from the telegram user buffer + + if ($search) { + // Found started search process + + // Initializing the button + $button = $context->getCallbackQuery()?->getData(); + + if ($button === 'cancel') { + // Cancel + + // Sending the message + $context->sendMessage('❎ *' . $localization[static::PROCESS . '_c_cancel_success'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Searching + static::search($context); + }); + } else if ($button === 'delete') { + // Delete + + // Writing into the question search process buffer + $search['C'] = null; + + // Writing to the telegram user buffer + $context->setUserDataItem(static::PROCESS, $search) + ->then(function () use ($context, $localization) { + // Writed to the telegram user buffer + + // Sending the message + $context->sendMessage('🗑 *' . $localization[static::PROCESS . '_c_delete_success'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Searching + static::search($context); + }); + }); + } else { + // Write + + // Initializing the new C-answer + $new = $context->getMessage()->getText(); + + if (!empty($new)) { + // Initialized the new C-answer + + if (mb_strlen($new) >= 3) { + // Passed minimum length check + + if (mb_strlen($new) <= 128) { + // Passed maximum length check + + // Initializing the old C-answer + $old = empty($search['C']) ? '_' . $localization['empty'] . '_' : $search['C']; + + // Writing into the question search process buffer + $search['C'] = $new; + + // Writing to the telegram user buffer + $context->setUserDataItem(static::PROCESS, $search) + ->then(function () use ($context, $localization, $new, $old) { + // Writed to the telegram user buffer + + // Sending the message + $context->sendMessage('✅ *' . $localization[static::PROCESS . '_c_update_success'] . "* $old → *" . escape::markdown($new) . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Searching + static::search($context); + }); + }); + } else { + // Not passed maximum length check + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_c_request_too_long'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter C-answer again + buttons_question_search::c($context); + }); + } + } else { + // Not passed minimum length check + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_c_request_too_short'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter C-answer again + buttons_question_search::c($context); + }); + } + } else { + // Failed to initialize the new text + + // Sending the message + $context->sendMessage('📄 *' . $localization[static::PROCESS . '_c_request_not_acceptable'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter C-answer again + buttons_question_search::c($context); + }); + } + } + } else { + // Not found started search process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_started'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Sending the system questions menu + commands::system_questions($context); + }); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize your Telegram account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * D + * + * Write D-answer into the question search buffer + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function d(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Reading from the telegram user buffer + $context->getUserDataItem(static::PROCESS) + ->then(function ($search) use ($context, $localization) { + // Readed from the telegram user buffer + + if ($search) { + // Found started search process + + // Initializing the button + $button = $context->getCallbackQuery()?->getData(); + + if ($button === 'cancel') { + // Cancel + + // Sending the message + $context->sendMessage('❎ *' . $localization[static::PROCESS . '_d_cancel_success'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Searching + static::search($context); + }); + } else if ($button === 'delete') { + // Delete + + // Writing into the question search process buffer + $search['D'] = null; + + // Writing to the telegram user buffer + $context->setUserDataItem(static::PROCESS, $search) + ->then(function () use ($context, $localization) { + // Writed to the telegram user buffer + + // Sending the message + $context->sendMessage('🗑 *' . $localization[static::PROCESS . '_d_delete_success'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Searching + static::search($context); + }); + }); + } else { + // Write + + // Initializing the new D-answer + $new = $context->getMessage()->getText(); + + if (!empty($new)) { + // Initialized the new D-answer + + if (mb_strlen($new) >= 3) { + // Passed minimum length check + + if (mb_strlen($new) <= 128) { + // Passed maximum length check + + // Initializing the old D-answer + $old = empty($search['D']) ? '_' . $localization['empty'] . '_' : $search['D']; + + // Writing into the question search process buffer + $search['D'] = $new; + + // Writing to the telegram user buffer + $context->setUserDataItem(static::PROCESS, $search) + ->then(function () use ($context, $localization, $new, $old) { + // Writed to the telegram user buffer + + // Sending the message + $context->sendMessage('✅ *' . $localization[static::PROCESS . '_d_update_success'] . "* $old → *" . escape::markdown($new) . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Searching + static::search($context); + }); + }); + } else { + // Not passed maximum length check + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_d_request_too_long'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter D-answer again + buttons_question_search::d($context); + }); + } + } else { + // Not passed minimum length check + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_d_request_too_short'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter D-answer again + buttons_question_search::d($context); + }); + } + } else { + // Failed to initialize the new D-answer + + // Sending the message + $context->sendMessage('📄 *' . $localization[static::PROCESS . '_d_request_not_acceptable'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Requesting to enter D-answer again + buttons_question_search::d($context); + }); + } + } + } else { + // Not found started search process + + // Sending the message + $context->sendMessage('⚠️ *' . $localization[static::PROCESS . '_not_started'] . '*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + + // Sending the system questions menu + commands::system_questions($context); + }); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize your Telegram account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Keyboard + * + * Generate inline keyboard + * + * @param record $question The question + * @param array $localization The account localization + * + * @return array Generated inline keyboard + */ + public static function keyboard(record $question, array $localization): array + { + // Declaring the toggle button + $toggle = []; + + if ($question->active) { + // Active + + // Initializing the toggle button + $toggle = [ + 'text' => '🟢 ' . $localization[static::PROCESS . '_button_active'], + 'callback_data' => static::PROCESS . '_deactivate' + ]; + } else { + // Inactive + + // Initializing the toggle button + $toggle = [ + 'text' => '🔴 ' . $localization[static::PROCESS . '_button_inactive'], + 'callback_data' => static::PROCESS . '_activate' + ]; + } + + // Exit (success) + return [ + [ + [ + 'text' => '🗑 ' . $localization[static::PROCESS . '_button_delete'], + 'callback_data' => static::PROCESS . '_delete' + ], + [ + 'text' => '🐣 ' . $localization[static::PROCESS . '_button_author'], + 'callback_data' => static::PROCESS . '_author' + ], + $toggle + ], + [ + [ + 'text' => '🔏 ' . $localization[static::PROCESS . '_button_answer'], + 'callback_data' => static::PROCESS . '_answer' + ], + [ + 'text' => '🌏 ' . $localization[static::PROCESS . '_button_localizations'], + 'callback_data' => static::PROCESS . '_localizations' + ], + ] + ]; + } + + /** + * Message text + * + * Generate text + * + * @param record $question The question + * @param array $localization The account localization + * + * @return string Generated text + */ + public static function message(record $question, array $localization): string + { + // Initializing the answer model + $model_answer = new answer(); + + // Initializing the answer + $answer = $model_answer->database->read( + filter: fn(record $record) => $record->identifier === $question->identifier, + amount: 1 + )[0] ?? null; + + // Declaring the questions list + $list = ''; + + foreach (language::cases() as $case) { + // Iterating over language + + // Initializing the localization model by the language + $model_question_localization = new question_localization(language: $case); + + // Initializing the localization + $_localization = $model_question_localization->database->read( + filter: fn(record $record) => $record->identifier === $question->identifier, + amount: 1 + )[0] ?? null; + + // Writing into the questions list + $list .= PHP_EOL . $case->flag() . ' *' . $case->label(language::{$account->language ?? 'en'} ?? language::en) . ':* ' . ($localization[$_localization instanceof record ? 'yes' : 'no']); + } + + // Deinitializing unnecessary variables + unset($case, $model_question, $model_question_localization, $model_answer, $amount); // Exit (success) + return sprintf( + <<identifier, + $localization[static::PROCESS . '_question_answer'], + $answer instanceof record ? "A:$answer->a B:$answer->b C:$answer->c D:$answer->d" : $localization['empty'], + $list + ); + } +} diff --git a/mirzaev/deeproots/system/models/telegram/settings.php b/mirzaev/deeproots/system/models/telegram/settings.php new file mode 100755 index 0000000..72baa1e --- /dev/null +++ b/mirzaev/deeproots/system/models/telegram/settings.php @@ -0,0 +1,156 @@ + + */ +final class settings extends core +{ + /** + * Language + * + * Write language into the account record + * + * @param context $context Request data from Telegram + * @param language $language The language + * + * @return void + */ + public static function language(context $context, language $language): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Initializing the account model + $model = new account(); + + // Updating the account in the database + $updated = $model->database->read( + filter: fn(record $record) => $record->identifier === $account->identifier, + update: function (record &$record) use ($language) { + // Writing new language value into the record + $record->language = $language->name; + }, + amount: 1 + )[0] ?? null; + + if ($updated instanceof record) { + // Updated the account in the database + + // Writing the updated account into the context variable + $context->set('account', $updated); + + middlewares::language($context, new node(function (context $context) use ($account, $updated) { + // Updated language + + middlewares::localization($context, new node(function (context $context) use ($account, $updated) { + // Updated localization + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + try { + // Initializing the old language + $old = language::{$account->language}; + + // Initializing the new language + $new = language::{$updated->language}; + + // Sending the message + $context->sendMessage('✅ *' . $localization['settings_language_update_success'] . '* ' . ($old->flag() ? $old->flag() . ' ' : '') . $old->label($new) . ' → *' . ($new->flag() ? $new->flag() . ' ' : '') . $new->label($new) . '*') + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } catch (error $error) { + // Failed to send the message about language update + + // Sending the message + $context->sendMessage('❎ *' . $localization['settings_language_update_fail']) + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + })); + })); + } else { + // Not updated the account in the database + + // Sending the message + $context->sendMessage('❎ *' . $localization['settings_language_update_fail']) + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } +} diff --git a/mirzaev/deeproots/system/models/telegram/traits/escape.php b/mirzaev/deeproots/system/models/telegram/traits/escape.php new file mode 100644 index 0000000..a9dcf87 --- /dev/null +++ b/mirzaev/deeproots/system/models/telegram/traits/escape.php @@ -0,0 +1,57 @@ + + */ +trait escape +{ + /** + * Markdown + * + * Escaping for markdown + * + * @param string $text Text + * @param array $exception Symbols excluded from escaping + * + * @return string Escaped text + */ + public static function markdown(string $text, array $exceptions = []): string + { + // Initializing the registry of symbols for escaping + $from = array_diff( + [ + '#', + '*', + '_', + '=', + '.', + '[', + ']', + '(', + ')', + '-', + '>', + '<', + '!', + '`' + ], + $exceptions + ); + + // Initializing the registry of targets for escaping + $to = []; + foreach ($from as $symbol) $to[] = "\\$symbol"; + + // Escaping and exit (success) + return str_replace($from, $to, $text); + } +} diff --git a/author/project/system/public/css/fonts/dejavu.css b/mirzaev/deeproots/system/public/css/fonts/dejavu.css similarity index 100% rename from author/project/system/public/css/fonts/dejavu.css rename to mirzaev/deeproots/system/public/css/fonts/dejavu.css diff --git a/author/project/system/public/css/fonts/fira.css b/mirzaev/deeproots/system/public/css/fonts/fira.css similarity index 100% rename from author/project/system/public/css/fonts/fira.css rename to mirzaev/deeproots/system/public/css/fonts/fira.css diff --git a/author/project/system/public/css/fonts/hack.css b/mirzaev/deeproots/system/public/css/fonts/hack.css similarity index 100% rename from author/project/system/public/css/fonts/hack.css rename to mirzaev/deeproots/system/public/css/fonts/hack.css diff --git a/author/project/system/public/fonts/commissioner.ttf b/mirzaev/deeproots/system/public/fonts/commissioner.ttf similarity index 100% rename from author/project/system/public/fonts/commissioner.ttf rename to mirzaev/deeproots/system/public/fonts/commissioner.ttf diff --git a/author/project/system/public/fonts/dejavu/DejaVuLGCSans-Bold.ttf b/mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSans-Bold.ttf similarity index 100% rename from author/project/system/public/fonts/dejavu/DejaVuLGCSans-Bold.ttf rename to mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSans-Bold.ttf diff --git a/author/project/system/public/fonts/dejavu/DejaVuLGCSans-BoldOblique.ttf b/mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSans-BoldOblique.ttf similarity index 100% rename from author/project/system/public/fonts/dejavu/DejaVuLGCSans-BoldOblique.ttf rename to mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSans-BoldOblique.ttf diff --git a/author/project/system/public/fonts/dejavu/DejaVuLGCSans-ExtraLight.ttf b/mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSans-ExtraLight.ttf similarity index 100% rename from author/project/system/public/fonts/dejavu/DejaVuLGCSans-ExtraLight.ttf rename to mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSans-ExtraLight.ttf diff --git a/author/project/system/public/fonts/dejavu/DejaVuLGCSans-Oblique.ttf b/mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSans-Oblique.ttf similarity index 100% rename from author/project/system/public/fonts/dejavu/DejaVuLGCSans-Oblique.ttf rename to mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSans-Oblique.ttf diff --git a/author/project/system/public/fonts/dejavu/DejaVuLGCSans.ttf b/mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSans.ttf similarity index 100% rename from author/project/system/public/fonts/dejavu/DejaVuLGCSans.ttf rename to mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSans.ttf diff --git a/author/project/system/public/fonts/dejavu/DejaVuLGCSansCondensed-Bold.ttf b/mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSansCondensed-Bold.ttf similarity index 100% rename from author/project/system/public/fonts/dejavu/DejaVuLGCSansCondensed-Bold.ttf rename to mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSansCondensed-Bold.ttf diff --git a/author/project/system/public/fonts/dejavu/DejaVuLGCSansCondensed-BoldOblique.ttf b/mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSansCondensed-BoldOblique.ttf similarity index 100% rename from author/project/system/public/fonts/dejavu/DejaVuLGCSansCondensed-BoldOblique.ttf rename to mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSansCondensed-BoldOblique.ttf diff --git a/author/project/system/public/fonts/dejavu/DejaVuLGCSansCondensed-Oblique.ttf b/mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSansCondensed-Oblique.ttf similarity index 100% rename from author/project/system/public/fonts/dejavu/DejaVuLGCSansCondensed-Oblique.ttf rename to mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSansCondensed-Oblique.ttf diff --git a/author/project/system/public/fonts/dejavu/DejaVuLGCSansCondensed.ttf b/mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSansCondensed.ttf similarity index 100% rename from author/project/system/public/fonts/dejavu/DejaVuLGCSansCondensed.ttf rename to mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSansCondensed.ttf diff --git a/author/project/system/public/fonts/dejavu/DejaVuLGCSansMono-Bold.ttf b/mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSansMono-Bold.ttf similarity index 100% rename from author/project/system/public/fonts/dejavu/DejaVuLGCSansMono-Bold.ttf rename to mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSansMono-Bold.ttf diff --git a/author/project/system/public/fonts/dejavu/DejaVuLGCSansMono-BoldOblique.ttf b/mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSansMono-BoldOblique.ttf similarity index 100% rename from author/project/system/public/fonts/dejavu/DejaVuLGCSansMono-BoldOblique.ttf rename to mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSansMono-BoldOblique.ttf diff --git a/author/project/system/public/fonts/dejavu/DejaVuLGCSansMono-Oblique.ttf b/mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSansMono-Oblique.ttf similarity index 100% rename from author/project/system/public/fonts/dejavu/DejaVuLGCSansMono-Oblique.ttf rename to mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSansMono-Oblique.ttf diff --git a/author/project/system/public/fonts/dejavu/DejaVuLGCSansMono.ttf b/mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSansMono.ttf similarity index 100% rename from author/project/system/public/fonts/dejavu/DejaVuLGCSansMono.ttf rename to mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSansMono.ttf diff --git a/author/project/system/public/fonts/dejavu/DejaVuLGCSerif-Bold.ttf b/mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSerif-Bold.ttf similarity index 100% rename from author/project/system/public/fonts/dejavu/DejaVuLGCSerif-Bold.ttf rename to mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSerif-Bold.ttf diff --git a/author/project/system/public/fonts/dejavu/DejaVuLGCSerif-BoldItalic.ttf b/mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSerif-BoldItalic.ttf similarity index 100% rename from author/project/system/public/fonts/dejavu/DejaVuLGCSerif-BoldItalic.ttf rename to mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSerif-BoldItalic.ttf diff --git a/author/project/system/public/fonts/dejavu/DejaVuLGCSerif-Italic.ttf b/mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSerif-Italic.ttf similarity index 100% rename from author/project/system/public/fonts/dejavu/DejaVuLGCSerif-Italic.ttf rename to mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSerif-Italic.ttf diff --git a/author/project/system/public/fonts/dejavu/DejaVuLGCSerif.ttf b/mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSerif.ttf similarity index 100% rename from author/project/system/public/fonts/dejavu/DejaVuLGCSerif.ttf rename to mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSerif.ttf diff --git a/author/project/system/public/fonts/dejavu/DejaVuLGCSerifCondensed-Bold.ttf b/mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSerifCondensed-Bold.ttf similarity index 100% rename from author/project/system/public/fonts/dejavu/DejaVuLGCSerifCondensed-Bold.ttf rename to mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSerifCondensed-Bold.ttf diff --git a/author/project/system/public/fonts/dejavu/DejaVuLGCSerifCondensed-BoldItalic.ttf b/mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSerifCondensed-BoldItalic.ttf similarity index 100% rename from author/project/system/public/fonts/dejavu/DejaVuLGCSerifCondensed-BoldItalic.ttf rename to mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSerifCondensed-BoldItalic.ttf diff --git a/author/project/system/public/fonts/dejavu/DejaVuLGCSerifCondensed-Italic.ttf b/mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSerifCondensed-Italic.ttf similarity index 100% rename from author/project/system/public/fonts/dejavu/DejaVuLGCSerifCondensed-Italic.ttf rename to mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSerifCondensed-Italic.ttf diff --git a/author/project/system/public/fonts/dejavu/DejaVuLGCSerifCondensed.ttf b/mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSerifCondensed.ttf similarity index 100% rename from author/project/system/public/fonts/dejavu/DejaVuLGCSerifCondensed.ttf rename to mirzaev/deeproots/system/public/fonts/dejavu/DejaVuLGCSerifCondensed.ttf diff --git a/author/project/system/public/fonts/fira/FiraMono-Bold.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraMono-Bold.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraMono-Bold.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraMono-Bold.woff diff --git a/author/project/system/public/fonts/fira/FiraMono-Bold.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraMono-Bold.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraMono-Bold.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraMono-Bold.woff2 diff --git a/author/project/system/public/fonts/fira/FiraMono-Medium.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraMono-Medium.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraMono-Medium.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraMono-Medium.woff diff --git a/author/project/system/public/fonts/fira/FiraMono-Medium.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraMono-Medium.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraMono-Medium.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraMono-Medium.woff2 diff --git a/author/project/system/public/fonts/fira/FiraMono-Regular.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraMono-Regular.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraMono-Regular.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraMono-Regular.woff diff --git a/author/project/system/public/fonts/fira/FiraMono-Regular.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraMono-Regular.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraMono-Regular.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraMono-Regular.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-Bold.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Bold.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Bold.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Bold.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-Bold.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Bold.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Bold.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Bold.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-BoldItalic.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-BoldItalic.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-BoldItalic.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-BoldItalic.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-BoldItalic.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-BoldItalic.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-BoldItalic.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-BoldItalic.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-Book.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Book.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Book.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Book.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-Book.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Book.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Book.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Book.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-BookItalic.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-BookItalic.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-BookItalic.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-BookItalic.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-BookItalic.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-BookItalic.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-BookItalic.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-BookItalic.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-Eight.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Eight.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Eight.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Eight.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-Eight.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Eight.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Eight.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Eight.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-EightItalic.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-EightItalic.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-EightItalic.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-EightItalic.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-EightItalic.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-EightItalic.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-EightItalic.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-EightItalic.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-ExtraBold.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-ExtraBold.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-ExtraBold.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-ExtraBold.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-ExtraBold.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-ExtraBold.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-ExtraBold.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-ExtraBold.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-ExtraBoldItalic.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-ExtraBoldItalic.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-ExtraBoldItalic.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-ExtraBoldItalic.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-ExtraBoldItalic.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-ExtraBoldItalic.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-ExtraBoldItalic.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-ExtraBoldItalic.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-ExtraLight.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-ExtraLight.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-ExtraLight.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-ExtraLight.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-ExtraLight.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-ExtraLight.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-ExtraLight.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-ExtraLight.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-ExtraLightItalic.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-ExtraLightItalic.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-ExtraLightItalic.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-ExtraLightItalic.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-ExtraLightItalic.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-ExtraLightItalic.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-ExtraLightItalic.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-ExtraLightItalic.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-Four.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Four.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Four.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Four.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-Four.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Four.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Four.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Four.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-FourItalic.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-FourItalic.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-FourItalic.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-FourItalic.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-FourItalic.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-FourItalic.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-FourItalic.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-FourItalic.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-Hair.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Hair.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Hair.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Hair.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-Hair.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Hair.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Hair.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Hair.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-HairItalic.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-HairItalic.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-HairItalic.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-HairItalic.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-HairItalic.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-HairItalic.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-HairItalic.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-HairItalic.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-Heavy.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Heavy.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Heavy.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Heavy.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-Heavy.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Heavy.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Heavy.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Heavy.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-HeavyItalic.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-HeavyItalic.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-HeavyItalic.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-HeavyItalic.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-HeavyItalic.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-HeavyItalic.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-HeavyItalic.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-HeavyItalic.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-Italic.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Italic.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Italic.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Italic.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-Italic.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Italic.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Italic.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Italic.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-Light.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Light.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Light.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Light.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-Light.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Light.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Light.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Light.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-LightItalic.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-LightItalic.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-LightItalic.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-LightItalic.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-LightItalic.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-LightItalic.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-LightItalic.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-LightItalic.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-Medium.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Medium.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Medium.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Medium.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-Medium.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Medium.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Medium.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Medium.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-MediumItalic.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-MediumItalic.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-MediumItalic.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-MediumItalic.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-MediumItalic.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-MediumItalic.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-MediumItalic.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-MediumItalic.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-Regular.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Regular.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Regular.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Regular.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-Regular.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Regular.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Regular.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Regular.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-SemiBold.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-SemiBold.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-SemiBold.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-SemiBold.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-SemiBold.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-SemiBold.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-SemiBold.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-SemiBold.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-SemiBoldItalic.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-SemiBoldItalic.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-SemiBoldItalic.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-SemiBoldItalic.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-SemiBoldItalic.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-SemiBoldItalic.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-SemiBoldItalic.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-SemiBoldItalic.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-Thin.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Thin.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Thin.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Thin.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-Thin.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Thin.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Thin.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Thin.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-ThinItalic.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-ThinItalic.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-ThinItalic.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-ThinItalic.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-ThinItalic.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-ThinItalic.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-ThinItalic.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-ThinItalic.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-Two.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Two.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Two.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Two.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-Two.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Two.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Two.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Two.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-TwoItalic.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-TwoItalic.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-TwoItalic.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-TwoItalic.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-TwoItalic.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-TwoItalic.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-TwoItalic.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-TwoItalic.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-Ultra.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Ultra.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Ultra.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Ultra.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-Ultra.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-Ultra.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-Ultra.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-Ultra.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-UltraItalic.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-UltraItalic.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-UltraItalic.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-UltraItalic.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-UltraItalic.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-UltraItalic.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-UltraItalic.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-UltraItalic.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-UltraLight.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-UltraLight.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-UltraLight.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-UltraLight.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-UltraLight.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-UltraLight.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-UltraLight.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-UltraLight.woff2 diff --git a/author/project/system/public/fonts/fira/FiraSans-UltraLightItalic.woff b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-UltraLightItalic.woff similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-UltraLightItalic.woff rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-UltraLightItalic.woff diff --git a/author/project/system/public/fonts/fira/FiraSans-UltraLightItalic.woff2 b/mirzaev/deeproots/system/public/fonts/fira/FiraSans-UltraLightItalic.woff2 similarity index 100% rename from author/project/system/public/fonts/fira/FiraSans-UltraLightItalic.woff2 rename to mirzaev/deeproots/system/public/fonts/fira/FiraSans-UltraLightItalic.woff2 diff --git a/author/project/system/public/fonts/hack/hack-bold-subset.woff b/mirzaev/deeproots/system/public/fonts/hack/hack-bold-subset.woff similarity index 100% rename from author/project/system/public/fonts/hack/hack-bold-subset.woff rename to mirzaev/deeproots/system/public/fonts/hack/hack-bold-subset.woff diff --git a/author/project/system/public/fonts/hack/hack-bold-subset.woff2 b/mirzaev/deeproots/system/public/fonts/hack/hack-bold-subset.woff2 similarity index 100% rename from author/project/system/public/fonts/hack/hack-bold-subset.woff2 rename to mirzaev/deeproots/system/public/fonts/hack/hack-bold-subset.woff2 diff --git a/author/project/system/public/fonts/hack/hack-bold.woff b/mirzaev/deeproots/system/public/fonts/hack/hack-bold.woff similarity index 100% rename from author/project/system/public/fonts/hack/hack-bold.woff rename to mirzaev/deeproots/system/public/fonts/hack/hack-bold.woff diff --git a/author/project/system/public/fonts/hack/hack-bold.woff2 b/mirzaev/deeproots/system/public/fonts/hack/hack-bold.woff2 similarity index 100% rename from author/project/system/public/fonts/hack/hack-bold.woff2 rename to mirzaev/deeproots/system/public/fonts/hack/hack-bold.woff2 diff --git a/author/project/system/public/fonts/hack/hack-bolditalic-subset.woff b/mirzaev/deeproots/system/public/fonts/hack/hack-bolditalic-subset.woff similarity index 100% rename from author/project/system/public/fonts/hack/hack-bolditalic-subset.woff rename to mirzaev/deeproots/system/public/fonts/hack/hack-bolditalic-subset.woff diff --git a/author/project/system/public/fonts/hack/hack-bolditalic-subset.woff2 b/mirzaev/deeproots/system/public/fonts/hack/hack-bolditalic-subset.woff2 similarity index 100% rename from author/project/system/public/fonts/hack/hack-bolditalic-subset.woff2 rename to mirzaev/deeproots/system/public/fonts/hack/hack-bolditalic-subset.woff2 diff --git a/author/project/system/public/fonts/hack/hack-bolditalic.woff b/mirzaev/deeproots/system/public/fonts/hack/hack-bolditalic.woff similarity index 100% rename from author/project/system/public/fonts/hack/hack-bolditalic.woff rename to mirzaev/deeproots/system/public/fonts/hack/hack-bolditalic.woff diff --git a/author/project/system/public/fonts/hack/hack-bolditalic.woff2 b/mirzaev/deeproots/system/public/fonts/hack/hack-bolditalic.woff2 similarity index 100% rename from author/project/system/public/fonts/hack/hack-bolditalic.woff2 rename to mirzaev/deeproots/system/public/fonts/hack/hack-bolditalic.woff2 diff --git a/author/project/system/public/fonts/hack/hack-italic-subset.woff b/mirzaev/deeproots/system/public/fonts/hack/hack-italic-subset.woff similarity index 100% rename from author/project/system/public/fonts/hack/hack-italic-subset.woff rename to mirzaev/deeproots/system/public/fonts/hack/hack-italic-subset.woff diff --git a/author/project/system/public/fonts/hack/hack-italic-subset.woff2 b/mirzaev/deeproots/system/public/fonts/hack/hack-italic-subset.woff2 similarity index 100% rename from author/project/system/public/fonts/hack/hack-italic-subset.woff2 rename to mirzaev/deeproots/system/public/fonts/hack/hack-italic-subset.woff2 diff --git a/author/project/system/public/fonts/hack/hack-italic.woff b/mirzaev/deeproots/system/public/fonts/hack/hack-italic.woff similarity index 100% rename from author/project/system/public/fonts/hack/hack-italic.woff rename to mirzaev/deeproots/system/public/fonts/hack/hack-italic.woff diff --git a/author/project/system/public/fonts/hack/hack-italic.woff2 b/mirzaev/deeproots/system/public/fonts/hack/hack-italic.woff2 similarity index 100% rename from author/project/system/public/fonts/hack/hack-italic.woff2 rename to mirzaev/deeproots/system/public/fonts/hack/hack-italic.woff2 diff --git a/author/project/system/public/fonts/hack/hack-regular-subset.woff b/mirzaev/deeproots/system/public/fonts/hack/hack-regular-subset.woff similarity index 100% rename from author/project/system/public/fonts/hack/hack-regular-subset.woff rename to mirzaev/deeproots/system/public/fonts/hack/hack-regular-subset.woff diff --git a/author/project/system/public/fonts/hack/hack-regular-subset.woff2 b/mirzaev/deeproots/system/public/fonts/hack/hack-regular-subset.woff2 similarity index 100% rename from author/project/system/public/fonts/hack/hack-regular-subset.woff2 rename to mirzaev/deeproots/system/public/fonts/hack/hack-regular-subset.woff2 diff --git a/author/project/system/public/fonts/hack/hack-regular.woff b/mirzaev/deeproots/system/public/fonts/hack/hack-regular.woff similarity index 100% rename from author/project/system/public/fonts/hack/hack-regular.woff rename to mirzaev/deeproots/system/public/fonts/hack/hack-regular.woff diff --git a/author/project/system/public/fonts/hack/hack-regular.woff2 b/mirzaev/deeproots/system/public/fonts/hack/hack-regular.woff2 similarity index 100% rename from author/project/system/public/fonts/hack/hack-regular.woff2 rename to mirzaev/deeproots/system/public/fonts/hack/hack-regular.woff2 diff --git a/author/project/system/public/index.php b/mirzaev/deeproots/system/public/index.php similarity index 100% rename from author/project/system/public/index.php rename to mirzaev/deeproots/system/public/index.php diff --git a/mirzaev/deeproots/system/public/telegram.php b/mirzaev/deeproots/system/public/telegram.php new file mode 100755 index 0000000..6ab3b7a --- /dev/null +++ b/mirzaev/deeproots/system/public/telegram.php @@ -0,0 +1,104 @@ +setParseMode(config::PARSE_MODE_MARKDOWN); +$config->useReactFileSystem(true); + +// Initializing the robot +$robot = new Zanzara(TELEGRAM_KEY, $config); + +// Initializing the updates listener +$robot->onUpdate(function (Context $context): void {}); + +// Initializing the robot middlewares +$robot->middleware([middlewares::class, 'telegram']); +$robot->middleware([middlewares::class, 'account']); +$robot->middleware([middlewares::class, 'language']); +$robot->middleware([middlewares::class, 'localization']); +$robot->middleware([middlewares::class, 'system']); + +// Initializing the robot commands handlers +$robot->onCommand('start', [commands::class, 'menu']); +$robot->onCommand('menu', [commands::class, 'menu']); +$robot->onCommand('account', [commands::class, 'account']); +/* $robot->onCommand('svoboda', [commands::class, 'svoboda']); */ +$robot->onCommand('language', [commands::class, 'language'])->middleware([middlewares::class, 'settings']); +$robot->onCommand('repository', [commands::class, 'repository']); +/* $robot->onCommand('projects', [commands::class, 'projects']); */ +$robot->onCommand('author', [commands::class, 'author']); +$robot->onCommand('society', [commands::class, 'society']); +/* $robot->onCommand('system_settings', [commands::class, 'system_settings'])->middleware([middlewares::class, 'system_settings']); */ + +// Initializing the robot settings language buttons handlers +foreach (language::cases() as $language) { + // Iterating over languages + + // Initializing language buttons + $robot->onCbQueryData(['settings_language_' . $language->name], fn(context $context) => settings::language($context, $language)); +}; + +$robot->onCbQueryData(['system_questions_search_identifier'], [buttons_question_search::class, 'identifier'])->middleware([middlewares::class, 'system_questions']); +$robot->onCbQueryData(['system_questions_search_text'], [buttons_question_search::class, 'text'])->middleware([middlewares::class, 'system_questions']); +$robot->onCbQueryData(['system_questions_search_a'], [buttons_question_search::class, 'a'])->middleware([middlewares::class, 'system_questions']); +$robot->onCbQueryData(['system_questions_search_b'], [buttons_question_search::class, 'b'])->middleware([middlewares::class, 'system_questions']); +$robot->onCbQueryData(['system_questions_search_c'], [buttons_question_search::class, 'c'])->middleware([middlewares::class, 'system_questions']); +$robot->onCbQueryData(['system_questions_search_d'], [buttons_question_search::class, 'd'])->middleware([middlewares::class, 'system_questions']); +$robot->onCbQueryData(['system_questions_search_end'], [process_question_search::class, 'end'])->middleware([middlewares::class, 'system_questions']); +$robot->onCbQueryData(['system_questions_search_next'], [process_question_search::class, 'next'])->middleware([middlewares::class, 'system_questions']); +$robot->onCbQueryData(['system_questions_search'], [process_question_search::class, 'start'])->middleware([middlewares::class, 'system_questions']); +$robot->onCbQueryData(['system_questions_create'], [process_question_create::class, 'start'])->middleware([middlewares::class, 'system_questions']); +$robot->onCbQueryData(['system_questions'], [commands::class, 'system_questions'])->middleware([middlewares::class, 'system_questions']); + +// Starting chat-robot +$robot->run(); diff --git a/author/project/system/public/themes/default/css/aside.css b/mirzaev/deeproots/system/public/themes/default/css/aside.css similarity index 100% rename from author/project/system/public/themes/default/css/aside.css rename to mirzaev/deeproots/system/public/themes/default/css/aside.css diff --git a/author/project/system/public/themes/default/css/colors.css b/mirzaev/deeproots/system/public/themes/default/css/colors.css similarity index 100% rename from author/project/system/public/themes/default/css/colors.css rename to mirzaev/deeproots/system/public/themes/default/css/colors.css diff --git a/author/project/system/public/themes/default/css/fonts.css b/mirzaev/deeproots/system/public/themes/default/css/fonts.css similarity index 100% rename from author/project/system/public/themes/default/css/fonts.css rename to mirzaev/deeproots/system/public/themes/default/css/fonts.css diff --git a/author/project/system/public/themes/default/css/footer.css b/mirzaev/deeproots/system/public/themes/default/css/footer.css similarity index 100% rename from author/project/system/public/themes/default/css/footer.css rename to mirzaev/deeproots/system/public/themes/default/css/footer.css diff --git a/author/project/system/public/themes/default/css/header.css b/mirzaev/deeproots/system/public/themes/default/css/header.css similarity index 100% rename from author/project/system/public/themes/default/css/header.css rename to mirzaev/deeproots/system/public/themes/default/css/header.css diff --git a/author/project/system/public/themes/default/css/main.css b/mirzaev/deeproots/system/public/themes/default/css/main.css similarity index 100% rename from author/project/system/public/themes/default/css/main.css rename to mirzaev/deeproots/system/public/themes/default/css/main.css diff --git a/author/project/system/public/themes/default/css/system.css b/mirzaev/deeproots/system/public/themes/default/css/system.css similarity index 100% rename from author/project/system/public/themes/default/css/system.css rename to mirzaev/deeproots/system/public/themes/default/css/system.css diff --git a/author/project/system/settings/.gitignore b/mirzaev/deeproots/system/settings/.gitignore similarity index 100% rename from author/project/system/settings/.gitignore rename to mirzaev/deeproots/system/settings/.gitignore diff --git a/author/project/system/settings/arangodb.php.sample b/mirzaev/deeproots/system/settings/arangodb.php.sample similarity index 100% rename from author/project/system/settings/arangodb.php.sample rename to mirzaev/deeproots/system/settings/arangodb.php.sample diff --git a/author/project/system/settings/system.php.sample b/mirzaev/deeproots/system/settings/system.php.sample similarity index 100% rename from author/project/system/settings/system.php.sample rename to mirzaev/deeproots/system/settings/system.php.sample diff --git a/mirzaev/deeproots/system/settings/telegram.php.sample b/mirzaev/deeproots/system/settings/telegram.php.sample new file mode 100755 index 0000000..7679934 --- /dev/null +++ b/mirzaev/deeproots/system/settings/telegram.php.sample @@ -0,0 +1,3 @@ +aojoB%xl{dDNR?Z5p`|7}MO|F=JSM}9zJv# z^pp6Z!{Ud8?I19K^XUJ;1Hk_8cIc;icm%CubK|UqAnVKy*-W#M{WI z=$P2Jq~s4NscHYDXXNJP7Zes1my}l5)Dr6I8ycIwwzYS3lD~Cz4-JouQfc4E#%CC_ zbMp&}OUo35B8y-0)fwA@gqlny?IRHp0UVt@3WV0 z{dN4@{r5RlUrxy1HrYD=!e{WLq=MRvBJ)4w{{#I09qu>(zkvT=xc_h1lb|D@qr!2} z&xa2IQ+QY$1OxG!N7N6^&#EWViOJ`B67E02l;#r}b`*plb9;;Mz~jYfDr>xcg0I1l zAlx+!vI#D!_(zRYvknW7(5Ix>e&1?Mn=ES>s>LT~khe5aAsP$zs?B9#H@KNiv#r zVZU?p&PiVd3kRm%*CAT32y2_39$X6nZe|R?mFgcNI3p7uL2WJPVg6p6B_<;F9ZccX zv$*R`Wtbz&LeLIvx55MVMFTwdOjYl7)iSe72)a>1|D#a|y3%rs{-w!s(`-}cwwK(7 z^J%@HUYvVkPSQ35I!bjtFd~MnW)Y+A2to6><==g7C0^~&fbSK*Y~2Qqq_|KPF1-^D zwsq*o^#~?lJ4=}BEiym4hO`a@nA^+^J)^jrM(x1;`_uT!f*@Qs*7?%A>es=;f3u1m z8q{w=P;NJ`zZ`V>sV--QWbiE!<~lgMso0R*y_1mQjuc6o{L_#^xmZY5%e3)XzM(WnUmlB%PaL-xu_8EPpIf_T-~-g2)q zHp|RTfoIOn&_OTvJ8CtHS8vB*D{Bl?^&>rU5Iq?5;R#$ zUd{`yw!2f|4$K#7I-o2u)q96sTIO4$K6zmzsioI7MBADy9N{Y*49X1Y%V$@O$Uuak z#ZlPidYDLcakvBI)l|pQ9QlE%-n!YW5Y$@gOhH{``-f!S8#a9CXR*UjD@&!xMKy8= zVye(nsG1Rz2h=*E$tX5E%^_SnV%3JaZ5@_%x6*5^(fo=gE4w1by(y@Mxt>vXL zOxw*1!{V21DdS!(F5FGbVpU#-axuR^l`I_PM+rgj?LVVF`Nu+ZD3d3X5e-TG2zn^X zXV#{!AzpBgwfnTxoyWXunfX=DwrGz)IFjD5Y+D}a0~eGMYWc6aRkA($oFE|%kF1Tq zuddCt`}IVh#}%z+_~Evxl}=BILQvX4v=K|qvP3~&k(h1w$LiK&<5iytGktk95#MO3 z#r_mZCU8~M2q)@BDY{H`+@>@U&X9}Jq^N|6O~wL6kTLE{~?-4c=59U|~RKrOZ(s=(S z!Gdqh@)xb`uORG)YSltaw!^oz4)S)`YtAlid){{S(YrN4mo4!GZ+Dx~ zUvaAG9jN*ySLa~lcY~7~YDO^beXY*w;aM4sza2Jm4PGFEwb*`{As4A*;%m3?*YkOD z`lFW<6Z`%ZPVB^?0hnn3q)L#|?80_tJGJ;&FuSacSFqrNE@zEc;Q)1rH3{vntKfO( zk-;C_`lm;KNfua{7Yis#ylQ+IOeyZk#w_%eVuki?OVqhKVzcOl^E9QmEI76|N-IE( zttIy7sL?$)FT_?hUI0k0#upaF0{o(#vixHeLPdIXZoKvlvS#>@rEe1n) zQc=A;Jd|9O>Ed^}0fQMT{_!|?)Ty~)Q+fF3gjM5<*R(H|R(o0Ego8W#iu`#L)@sDa zxKCf9rZdZJHAT6C@@?eb9{PmT)UFV;9%e|}E$<04bvo!C`$WBQGMqiCtSRI9pfvTH z<>vL#7IKAoOLG!kaF1PAV^I`U+v3!ID=7HYo1GqhyMh18A4_^0rCQ6w?8*UNG#vJW z(PR?>tLaP{sS@-HK^N5@Lx+85ln9RmYQ;RI=@y4)BSKI$&$|Lq^hnfW3TqFGVLYih zy*7_YUz_2$X?9{xW@6-Ro=_F)7nUQQ*dtl+vf#H{fwk#sDz!{lql=5XsAj5$a{ZJtY zLG8`Oj)E0kFMVdj4E`%Oaz|ANs(m5Yp`Aymzd@~COo5!L3HG@Dchy?9SmNEwPmsCj z@L5Z&%grm@`wO$|szD*>lVEZhc5J^7xbbQvQ)%6b`Kn*z?{8bQ{@I3=eAN*v_L$~d z&PO+cWpIck`op-55L96QMHV>G)Y9DA@`uomyL z5EMzqV<@A0d|nZm>0p+e9u6!%jB+AM(aK*J!ub=e9I}Ii87lDe!llSGlz}>8Ja48T zl9ZvSue^hT#ds<4n(WMbNYZZA0MyDbLIm?R&ggOYkw0>38iDWtrNO+gkq5Ro=8Qs$ z9*lEMY$F}GzM8Wt1T}uz^4p^IHaT^m^U}K045K~#ByksZoBi6Ybu0WU z)dQ$-81KOe-t}zqkOlpmjuV5jTcNtTMi>Bi#Tm7bt5mRf#|{vp^_Az09D*U{Pu!B@f7dJfw|`f3M(6YjGN zJJr_bLqd=n|Ne%$hTPQvuUTY;62GjkDX3|qSO{Wouy&u#hTN0yZ0E>l=8wm5u|TYP ztksIW*juOG&q;nl9Lx(dQMQ_c@2@U4lP2;EYcQO@ooPtYCe1icFqQFWzM5QOC9Cp0GHXLaBE z{35~mDQ|9EL8lSxE-mtIxn==Ju5Si&(j~ZM;t{`OJ7dWo8zqn%TIVehVA;gDo>_Pl zkC1$CFw05^itn|x5Q~SZg+9Xx?xi*b(Ale%I!g8<*>26&`gEOi5dF3)mF28iYYfF1T!4Wz)C!S$$n`*P3+E~ zihR1b)A!&aw)dAFvvpp`jP8p`$2t<=4E{8mdWD;GYdr(BoF;?YnIgQfjEaJl zjNHfcmay81i9R{TCLhWlA|$w)grphq;f@VnDAKn1V-HT8TBAlbvvjr=6s0M zJ6O#uG5gNC2{F?qdG7BZ`wn|VFSfVwZqrBHL22ZH`RX?YtGomvpJ+f!d4JVFf$(C- z>~EWLlsWw9e3A1|eAxuT`bK}C#pH1ZV$y86c?2V73bF5KcLk^5V}XoelGXM-p)TrM z*>>e&_+HE;@>*$FO)n({m03Qf=kTJ6cCq4n&%#Tyk4X{kKxnSKsrS($F=2l5yoL5% zh2WLY^E1ss8&bVM0MyCu?2L7~5z}gGzSJr`JogTte%=`knGs|ui2j2Ay=H4FP435| zdtYoy`dtn}leG4|k&ZLX7S~I+%weNo) zwi{R>6XqbW+OPdN`|9jF0lU(!E2j&*u{oGg{La?MMlv`&ZCkJs;k7 z|D`2@i2OV(E?c5*c+QpC=Zn||=1P5ybW#0#>mXzknlf{+P=Cos|1Y@K3aqStU}mwQ zE-_$7v5*|%rF75;v(8YlM~o>AI|yNgfgU{*p~=-MzuH&J@#l0tHdF7o{n zN`YSry^emPkx1`~f@~mDSG6iS<|n!scj`CG{wYEfDz3@BB2zIY*|TwDS`>!KFGX7sSNbX;|W}074WAWoZ;`;o2ps zs|!mL%3WlKo7IWr;n$0&=g%z^v0B2O2F%(HvU)nV*Ti8ziv7h-S^dD2rM|2vgNaT8 zF>-s}j71);;3Sd@LSNl#y=6kc(tfLHo4HmzjQ5q|s)~AZ>Ch~%E71V$R8=Y)f-9vh z*ujnJji3w!WNmbTEONb?3in4wy}es$k;zH2G*9W-d zEvSKXQF}ZYnEL9>_c>0(;tpo$9y9SYA*jw@0e4JrLsNod zz$V>)$uAUwUaj7R_7$RQ9s*0H&_~5bpvA9)y`=nXQ=2w*qxO{$^hbpsvF@!}L$UYf z+0hK+ww6#VrO)@XeeJ8rX0F2*yn`3-HuXkuQT&a3{zgM4sTsA;#0pM^ac`qPQt~+_ zflVnP$ez|aoLTTY^^2Z<2{K(4<*1V3o=g7|<3rDb2}c(E?d4oEFub?w zcDM}-L!RyMY$e#3sh5-OVd9$a-yFJYz`K0sG2NH{?5hyu6arx&SSg%##tU+m431Fc}Q6rXeT6v7TS=y3dAPLMKk?C2>vDC9{MeQLkqW$!lNv zlWwqLgT2Q2o~tu!sK52IN#J&|ap*N2JjePs;68FmbOvty;zCd$_`C}6jGaP|k(`=N z>4J|K=PIx!->(=mVx?7hX)32WFbgS^-fyHC-Wtq{p>f= zoHqWRdT6~1^VWtTZWkv*RJJRM68sXXDUN3^b|Mknh1!H`@O3$lr{}tV!_(tn!qG0O zj+G24HDV!8k9jQJMGNpEtFTv2cx|Rryc$J3W|qL|co|3X-JroBaXQauM8DzvFmlV| zab+0UaAj%2?1*5quX+lcrF22jcg;(L6T(216jW@!3AMTPh`)$`R?C^--bdR%NhF(* z42yHD_vtfW-np}e*sseobm=7vyx_-qstwPZpT=`hO7os|*r5ztho&=RU3k5qZWvG zhS!_9t<3tdJVKNGrVVhp9ch05N!#;(8cxOTA_0ToTvJL^(UrY=6oH9G}q#(BThzrA@A-AVQjJ-Q_XF`}@HHzZH0i5S-fRaAsN{P|$AsVm2A zprB0%0*@;fMunkn)i`}!Xq6k^xcMI~YO_pxFbYvfBAe-_kQ!~FWiyb;9&YK(8uUB| z&|Xp;t2mJ_-(zSU!Aft|E2a}(Fg4>V?D^!%Cs+I_WlnOMZ@m5T*RVHfyDCrn^x6ucGByFRcsKf+2dR{H)upWfH8ixx(D-~De*_AQeiHmyZm?eg<<^eQk2b0_4n^B1MChet?B7>ji z6ijphq!(=7yCNr3|DMzQuWbSjpk2emelJ^+p|8ewv4=vn3}Y=2>(Pt+IELSGAt;=% zNQLundbCbimTyh1Klf)in`ZH?h8uoJ6woChq zG|E%8wb9E{?%uoc8F&TWj&YZFoa)QGUR&<(4UDp`*Ei-EIkh-~`H1RGCF@@%g5Tts zd-`k1<*?)Ef?>lTNmw-vJX4k^+2q7sw$q5LQ;%~N4lEPF3O<)f$*8R9eR*Q)9bV}+ z{kXTY@-Xj2Z@j(vwMVzNombYvP5{P$NKlzg5`yL`JN4BMahu&vE%R5lVW&6|&q&Uc zJ>?-C7{g8vP5nATQ?$H(bKyh(3i`=Idb3Q%;18>bcDh^R_~>G*_6Wr5m!zBStWDf$ zf$UQ7TZ|{u@g?tfDpZt%nnJAql$qN4K%HTI=R)&i?xo~N=KkA}uw>{d4sIHA$rbst z!(g~IVBwrsnAmJZoU~&^OPDe9Fkq*}C^eKU0Up-~Md3cAWbYp@(btVP%neclV8X$JXnTGML}l8U zr`ZB)ib+{a1D_4Qj&2PQOp=ng?V_z1Q z2ISqj6j_Y!z~|Z9SEoz{1gQdgPxW0Ny+rb2#}w8RM@*s_r;{e?3+jP+U`Jp1>W3e& zm*8FJ_{zqIWvjph9P9l>h5-9K*RIw=`h^yz3I%oiO88~7H_X$B{JNv;kx%wnA?Wz} zXIKCZ{B|xpbbL+F=V2i+MOWV;+=^4y!`3BwqjITmQK`S?0S!5=L>+wGR$m&cKGfV$ zvA(2FH#|!wWz#8+b`QubL&AbcykEq5uw=fJ zL90K4Jzln&k)ILuy?}%lJC8E`eh?ZTHFNP=Q~j?E*k_|Jo%SViv}D)kQWOFh+8Drt z0mOALN(dq-0is6fwqs<92c;SP4r+JmrMG5A80nzV9W3CK-g2gfI~}M;hRl=J_R3bB zU|S!?1?FYXxl*VnI$fc^6NtC2i<-+my-sxba8LajSPP!V$#V#MW0V2}#jlWA?aX}) zqq>z#-|251tKt9c*8}71kCY+IIAUA$2Sd{H>v=!2n097cC)4MlYCQ$!A!=j7;SB=f z&??DkN0sQ|Cj@Ps+@XsvEjxJ&Qi`={t>FV;aUIc_uop(RXpW(?%mQ8;!+?zr0->W0p5?uG0+=&@pAFAA!YVd;x{xIxdWRO6xDJ5 z3KD^NmA-XA%s@BrqBCV}8O9b`6p67=cjiOzD-x$HjJ$WJQtTN&Y13bi`?Q3i`+P5K zlk?HgMx6I7Nu_~=f4CLhAtuI2?*0^~6i`_ZTj6HA-wPL=8&T}L{&>3#GlpxEz8@6s zS=P*@k8h7igj2GmBry4OR6Q5s)7knDAg~1%y9MB!hk18z({LQh7r~u@z2n5Qfq;`; zz5CR3@*mTRKhF1 z-R32Me2X0vvZ;`cFAD`M}M&T^vJ6QVoC-e!cC_&erse4hsV2wV%^@1O0^I=YK-5%f$n5jWw3 z>S6FOb`f6RuZzEbor+^L z(V;EeXBz)bVM- zoJIEETiFTuD{0nt(eEl=#aiMwRF%oOE@}C$CNs}c{*Y+3M7$WVD zCzBSI&w8M+WVv5j(t6U&=%_Ei3OKSj>b^d?9{O_6S1|~Z5Pk-YpNT3Rw6ku`rR8U2 z)ckzK?E_=-!vixaD*+0r6@ol_aqOY28CVSN%*&mZ)y!9U+nC`tbL0?^jpNe%w~eQj zTc8wMyOUHqF5S(nT=yvZ=?}fLkP@Sw4?-#@dv=!G-lZ<~$&h*0tWF53k5V5%V`ih* z#q+9x)C=9cvJ9l^yN1{?$OEQG6s;XtbQQtdlfD88v8X^fyAk_FJ$!88hz6|SHZo~2 z)1(ml#};Nin(5nP0~U7;G_?Ryf|oQUn@sNFn?`yR=AuA+%7tCEDt*#Ra0UOcnJMzw z=tUb}a#VcP(xBFEBlMVKM9)Iz+f!mcha$EzC(3>7uB@=cPE0Hx@SA$%N=`zyki7@w zC>|u}HT`=aS2>nh)GihSmGO^m%a-@sb{o$5hgvYgA?m^PngjmYdzpQf<^c=xa9f1z zCFM&pC&*Zwe`xd;MR4*26Y^R5#e`cOB*cy!0rP5+As@UU<1OJ1D1zKCWm29Fb31Yu zE5zPtKmo7y)@EJO4U%HDCnvUhK6wT+j-N(VdC8^fJk9o@<)Sf`9DBy&_PQzg#MZcM z2ZPrp?)y#YvXB4cm3vzn(U;P|tw}AuZ5d%L8Q0>h=R%dXNF9=i*`BG(sD%7bZRW%G z_>@0bETzTKq^c2T3Ak))_!P?raYo;pTbx&Fjr@y;Z~A|*&wSr=^CGJ1OQ>yKiqx1ImojB=^<2;pGT#`7y>P_jT5( z`-=iarq`ni7lmzkuKGx`T&aZ7(s}O_4=1+3d z@*SeK-zlD~^3TiZ=b7@0J=J;wJ`H#}1v6piLXk|R_}zWaiU5QVWT(6gJ}c;N71=7x z-qY&ncAwar!{gNHVw~Fo3B9_lxn`BUP}Y9-^SCmtY%VOUtLQ`9DQ*TbJW4E*2xEwy zIbTg^9P{jtDEVyYL&qn;nZmFZN|KBO5@I)w&z@D5%!w)tw*PSqQds7vw>^j@uSpAkH^>Ql->o)l`_{m^W55miy3) zt^6-%pDF*Op@D1E0)&oVTbK*)(YV%;)&7nik;uS8Y+?87MyiJB_#{x8JQz0Mq#sL> z8pq7z_sR?roJFR*W!f5jJQ1i38OagTxDIX7Z^P{>s}o1nNeR1QXaC8^FWi7g^y8XR zuxq_eC!eplS!9xOHhvrD>N8|L%sVf#T=-)(QfSmG-GU^@%W=nbqAtfG>n z87z8YlCuxy+bjK*s`N;Alcs;R1xG)WUNerU&sn?Xl56|zdt=yWR=Kk;nLA;#hrd?O z|5vRUGj+mMld~sREU>F9K|Q+kumEZi=I@S`iOwel>~8D&>NS&U7>@^+sRxl$Ir5@* z&<4^8bTZe%^6ixTLnHdmPz&V&6Y-gH(xu9F1$A?Hcy2$wCG42wTV)kQGPzAQI)LrN zO z6PRvKEBF2^8q9WNrlctssf4Bjy!XbINIL~E?$?UtpZJt4Vn?MiJC0uyF2{j92~p9w zvq1D5WftZzY`W!rjVaJ^gzS}pJ; zi9=OG^!E9+0uDp{lCb+1f+dO!EtvprDoYkgI{5cGJk>~9+Ms;#v) z=DDH22;aB0<2jjYF6a@0&TW#aD#NdTk--e>_Sor?-oPB5ORq>5b!zUDmKQ3;+u_cz zhFvClEy-~21OMr<#aVKqTGzNG(I&)EASlWh7!rb}bAb{s?61q)JZ=ADjRO8xT8tnud-rrxm@`NZ3t?d>Fc!zr2*>GFJ% ze_Eykw}qrn{27``I_<7v%4exBW~%|*=xz9q?7KqHy}{Z>QrI4`Q5n#SxT>MIv3?m+ zv4c_qoT>%Ui=mVNn@P*}KR7A6i`A7oZi9&Ym#@pkf%MhH53m0zd>1K3`N z)v3x-+++h_w&VSbZOD%vHjt>jsA6@g@kKMskhNayxx(s&Cb@vi2`87itM<2-f%5Bg zCGOk}2yv6+GzrYh#5T3b2rdwHobBm5%hj-tsI$P=aO3T7aKvo4K44mym+HTfSVNh! z2yvcf5`vTLmC+PlzMk)nHru`-d-CI^I3`^ht^YcUO_0vC*LOH_d^B@fS5-T~ z*rUR;?#cQNQbs9eE&;|s=2;Y`mD;YJ!Q}SvvsA*3SfabIR{4yX*Uzep$5>90u;*C0 z(BB7WmV*RQsVPF^42Giwj$vt2syTGKh^O{!1$=@7KM&)Ah}h%uG?^xW^@7cGB=G^) zPcQ^N1K3*)eD*Gne&D1C9*fS3VSH1{PiJX%hJa#lS5RMNuZBEBDE~r1NVTx?(OuphTxKe}MlMH>IC|yD#%!YP! z19r>@zwM~&7dE+KBA{yMny-Pp@0YE;_T4CJ0#&Oe=6*okH&%Rk=))29Ael8%2k-oE zJ&IJNqL|soBL(FwXn7643M$J_zs&SVu*R~B`H7pbIoKbY_A>l<%Mo~bxborlCcD1o zg=-Qmu6M2L$ctlmajlv?Ck{?H%G?wcjDbH1LDB4<0-kPk;2yE5hC$+7b6TT2{Xrdv zwTar%>DyG&9ftuypJz3>yqUCjy`wcnk<5FmnB97qt3J7eF*Bi5otwkeLgP4%Tmu)3 zl&1_==J&_XX#Y&PNr5+RAt7ExHp`2AnRRoEolebEF3E?Le``!NdT^$p8e22}@%@-J zde-JsvV=W_fLSgGM4jcAZs@3HLMPSHqMRYd>|VIJzL!%_slNgBZlEFf*X-HXmeg@* z2CV)O{h--i+)jz_oAilyk87aMh{$?imhH7S)fxnFGn87goQHLUK~gWKqO#!6fbUzc zO^c$kMrc#Pqhzc+5pzqqBE{Z-^HHSv zw@ZiD!XWHPm}B<>7NEyPKtD)bB#^Qy*vLAWH=!|2n>JHA{Cw!8(BA=HIP@Y?uGMr@ z$EjfDtbqMRqJ}jY_#lbSmwLu?TTDI9@3~oIc+q496ASp*Se<)vB@1Z1Wt}YgWiuL1 z0(u?pS=A+>gik}6&XCU1zkBYy@Ux!@UL|TWeGTiAd#F(Va(;s0+H>RyqhW(Z-y)tB zCkC)r)iyJ~H2y(9jscH_(0dx1aD9R+JId)qW^}ZACS}(O+WldZqpwy5W0~X)qxE}o z2H$+1N#4uQJ^VFXt)ZSjRpPTL;QJ49Y!J-cpbU?_B%qFljF>_vuS;Oc`#jKIj4*O^ z)Qi>v)(P9?4oA+lFZqMZl0wj7o_8)vKkPX}QwSoZtbmUYy_rg11Hn!t<^xg>&j%T4 z!wYI?NXTm<1s6Cn)7H`|erXJz)T*+8ikxrzElY10CZy#6aZhwPPy+MqqOt`$4BQ5! z6yH>o5fADchJeOGgIMLW3Vr%jKFSs4>jSN{O@xy2U1wh1&Sm_oE&5m7nbp5u2s#Zm z{3v5$Tnkt&oxTsI=leEEPvYclmaX5VC4eK>?N*6fw6%S220$>|(-4PgLmBpeLdDUl zuQ~A|3D-K$6qJ-NJ_ufCg|{Po4$K52N_9$c$r&$IeMqAgk01x(rYo#5e{(Wr$yGtGn6yV zKsGn3I;f!-h#M1}<=6#Kb1mo0@rrlJ>wCNdBVB(76FaYnuBIRG?zVW*Qq;PonIY z$0t0PAw?H#6VgpFTz?#c9)l9E$@1_BN2iDLLn~EHi^ujFPv1*5uC6+@8N<3mNt3K* zVS~!iN%}f%c>Qgp3PUVT?nu&xjcKWt7E-)0)M^;d3vRuTy4h1t7qk-R@B1bV9Q?2_ zPW>8@Rj2D_$-yhdhKN5@>) z(9?5$4(-b!1{P`rQry8pjv&9u0>V={3_$o*Kai%(z{G()vMSd78jLZmDc@EzqItDD zfg|MW3dU5OF%mXiT>83E%3L)X+k?%>3z~(;ylRmSQg!u z`Y~l?pu3cuv(wNtc2twwnV2jP$BLo!=X=~>K%LO;`dyxgOCD)FKMuHvtr0nHmy4LP z?r9;d7Qnrj5;uYJ$f6K*8Hq=zmgZH>A?{8eK&D(5g+m+xBpwKxJ^qPpjEG#wB*LJq zI5d>g4f6+gh~fc2PQ|?6Ya$loRvKHJX0O)sM~oH2Z(qu;0TPFVS09brPM^AhH6wD; znHaMRnT%HjKwV(ipo7G5Vu*eo&!WYt;sbfTSj8Zf#SZ@cS%LL#@hqpNw1fMdsDBF? zcB!)5g4~5E{|LF}iG9X};tGVIyi>=}jslh%wB$Lr%ipjFv9X`B2-_lpoepecwEwZS^fuIcf%}AlQ7y%px!8$$*Lp)mk%sjoO-mqUych{^7?gEuN=0}^r^GOHs#AM~!@Qd0_SDz5LDsKo zQ_>hlUWVfPX^Rxsopc?mOY!p^GvCCcnfnQ5PxCOOy+DZlo$8KrnERs)-X**DOYb?^ zl%9orY=>m}GV1l|f1ifZsqZ(`A9JZf(3o-6qT#!w)OWiSj=_!6g%YM*_Z_M3RAMIg zftmaTMh%Prk#F>3eIQl8Po9l!dlk&Wk&WO$ZyZwHk%OH*zfgw>Q3>kJXiviQRNUkL z3tLPc>sQY22FuI$fMd z>rGSP2rmpvPGg6u7Lz#1=RbryRu*$t`#se~ClXmd7xgZmM+0Epst)|0!pcWCg4LsA z)Dh=NX)1iL33Nz%MySo20$#4BVZ|QV&Ca`To3i{Vi7Lafjzv~H zQzDQlnR;v^aXpGZqW3s$K87z%eJ!fZr- zu`iDcy)2-0?r8!7NI6O$D7t6v~hz6W@WDYhQ!gZxyWd8NB(g}nk<4{mvyvD0z(+f_mT$XtRarWR^Z z>1u?sg3XU>!RlDB{r$Y}BJ7q2LMqQHNjpB=v5D`JXO^h7NUFy>3%(}{g5dB^(5hD~ zRsSkZTBzHZe6AZ!Np^En=f~(b-hC!nP>TJ-?*=cR?sEa|$vSC9aW79GVIRy8Oep=Ex1J>D3;!gxK9>C#IPTUz9pJ4GZMILW^Rr4H zvrZVj*cxhFdZ20Ki4oGmtANJ2z2H;Sy%HVGEiA(+UTFtYP51E607ve&oSu0}7%XcY zBw8_!&vMlx%i8Qs!hIb+4w9UL)VMIt$DXQ{3esP-n_|uSDir~m*BXLnyfd~(~Fl-YD_o}W4%`SG|u5-NDE&V$sIDm!p>j3o8e!h8*}7c1HKD6m6?;4y6oO{a=BtcR3i(A!jPs zTNy&e)xtZ(BrmS{>&q(d0KJXkT1XolVas0ZS%=xX>}Y^WU>LCVyIXX4y_<@(+N3=U zJbxp;{YJ#)o~;jg z0qMaAY(@aqd%>26wZ(Lbajt@6bTkXqv5~uAXv5_F-W6%T*|o~`rUvjOG|DhUqcLr+ z&+C$kK~)v&pHfRr*(-_3Geyw?WdZeIXmUkn%{Zeavz=5GouJ0o4W-9ie5y@OIu+%APJAcIiDxo+0thwK2$TA?m|AN~LxPF}_+kI1ab<3_Bh{mPsIt zoSCSn^XEg`l-{Z3PdSiE>*at1I6LquYZhapx>sDD{&T3a4vor6xa?cA57#FPa3iH*aRA2r?K`^f~``)#c zF@8xj^Q`E5z3(B;Asys*3Rr~Hex;@{XHaQe`kEvDE|CeXLboEvU;RhD`&T5TJLa-q z`m_Z5RUcQOD628+Z&iMDfV8vRaPO*5S5u)m%tFNeDk@wp0##7SYeSfdNV&YRSGbjmyb9`1NlT&q%JGVtVc|Q% zAzn};bEAaq|IV6fM2S(qI7bo)9y z&40~FhF>8>P6dlm%esQ2nI-c%B3s$+x2@j?f9na8)|u^JHlH7q*P+(ph{dQOeKCW? zV8gX!B=|bXvlGMqbr*nGLfU$#$A8Ip-Aj=zy4lrQYR5_3zPevmIga*M_l=x&V-?>P zocTt71G6T`wkCLn=GgMr=jRs>dX|#~%{y0|K_=i9ET& zk1qx(u3xt3Q9ONba_XjyRI3ba7RH=rsebr37$Ku~P<>Z*eP^hwE9fZTAdXKpVdfV} zyq#RwiPe9AcMn_Z^lf}Be%19fPhx|#hQr5%pr@BBfk!J}F)O(D5tv*9!7W5rEnqf=}!VL4W&OC$|N6kX#cDbzi{t9WvB5T#J6sRk@s;tj|7I0ba8+dHP{2 z6jCYoCZjl0Xa9Lg*Q7oe2*UTdmoQW3ZJzHa8`yy@>lfAa4A)Kh$nQfY+ zea*Q-@(p{a?oGH_5P02W(7YE>S1|~P4ZJ(s(f{(6o6qtxjIXjv&h{*{zypE}OgA1? zVY&*okzC*f4kK=pwMAGLyTaDTSXKNQmYVSXV6aD={|e^-#HgFw%?nt_6yE)Rj?)UhrBAX-G2Q0UI!TGn z0&+0nX`;bhaXG5y_ac7c?&b|R^6%5m+r!*ipUeBX2j{BvuJ>k@{5$w9-nP5|V7oP@ zWb_oy8eNYS1dUWpkb$*O>Ty=nL?0;PtnI=sxJu}A%lJSmM}M;sxD)JzwIC{`0UiI`=A< zc51yJvMA(IG!`fbr{aH?V=6@oz*F#r?{@MnKCQnbA;h}oE$y@vUys|zs`rTjT7?T> zCJF98wA?TBb&4t9-x+8sK| z-&ECFQ%`uY!%%Q5e1tbT$*zolz)vEcDqhA-Xh;b`EdmwRK07SZ)SZuwtRcLO3xo*= zh6dJVM^yeDRjuvA3MSprdF^cGlD%WJA>B08atNY!Dv%5AqD#QG%z`bj-a*gjm$PkQ zo3ur>TLh&l?i1d9bZ~&loiK=1qlW1|>e7>qN;pF)dX8C;Y5B-`StU5CIfrBanM=?O zu|lw^#I#wF_1LXV_$LqfuNK97Fgo5M>R1ZE&t zcUH0ISJ-J#GvoV<98#cZOM76dz-wag3Lp#mKh?jnp(<@V=pFKtY3k_|iX8s@f(~`T z(QIgu-ZyId=B~=Ys69Y7KRyFm&ia)fMHZ$;iK&szkiNk{-GHGY40ySTBTP6vM8 zkx$|=u@ul7lj_obw_^Z1+E zKWu|4{xZ^(0*#6}aNftQUc08PyM7lw7}ZQ0NKHNw(R+n8ks zts<-&Hg=#(=7kwnS2({9s*eY!w7AX%>t$UPf^7Ow!@F)_kiBFhyQvP#K3coIFW{Sp zImUplBsQf-a!pXCdI(N@!T(PBV`y-7ApzErycq+2ZqN0|XChW5si5dm9PG17(HDR5_H!qp!LTA}#+24ceHSqQ> z;S|ize(S!^=)MxjQXZV+@!tr64pFoRcs}p@lTn9K`JJOMC*^oR0IOI^Y4qZ1=&qB} zFCkF-vmr6ND&F~|q1i{1DAJae*dY!czFiP^itGAo4uxM}+(H3D1BC{A#cfl5bPi#A zx(eXOiGA}sDy;_mOPoQ#ZL|eHOi;wX-^Hhdde0i2o?yjp!cZ{2v{`iYPs z-J?n`XcOzC#e&=G^5Z4?#R;10ITKF^0lB#;56sa8JxV0Xe9#5RE|Kq`l zXk!C|z4|a|&T9J)iuWkt{>WH%@zM&^IA;_LADx%w^Qb`&v761@(D0Q8wGHZ6@m>c` zyGTPeJffNJboT7Ec8`nv}9`3C9O&v)o(W~xGD`nFMqgp<`XK% zHJoJL3+onz`M4BizvZP#*#j67 z+7S`msN}|LpbB!0yd-TaKJDbPP5R*E)bXH?bT9|a)zj|R>>)g`ea)MsrQz z%f9c5CY3(V;$GCPyEv`4sz3k_>{RO(^tWq1y&a|R}TpjHA*@T+ar23u%@2W5`4>h7_!+`_hhq85!oz!PHfIp5#DC-mKzMF{o>K9 z2VIn)HyPg;acgka@bFTBi%5~*N`}Fwl`@zVU&#m`C>(h<{P-{jYNXC;%Igo3Zqji> z6C-&=NkJ%M%^oh*yPWNKJ~UGs*qEuzt0c~%59l3Nhg|Gg?dedwbILxUcHJ=CoiG-7 zwaPc`F(g%zetoE&Pn-^Jf5AfpPis?zJloUBPi|~w9gy}Rg319_Z%}OqVc^~4@4EuZ z4X7`SB#`mBMF~N;1>n|iFm+JxknCihSXi`Qa?JN6)CFs{Ea6iuZ1ckJ%+)vq_j2{X zh^XRb)HIfP-4B;au?M3eKg)0oCYjmwo)WJkQNboktWs)>IvM>93VhNH;`x@vn+vlA z|3-{L{JcmNx+IM1!#Y1WWDCf)_O9N|=5viIh_`|tQ)1U7%GhUi7vsgtb$rM)p@g3} z+1!Ue9Rx*% z#m^J|y{xKkwo(3yqA&ylkIKuU-|_^;XH)EiB+||;r3$rwwG8X-p0(Vdzt1`v^4|kf zZJ&6$1IG<@aOPE^x#+T<=u^2x`-`6E?>Fo7*YDRZZ3#|z>#2vjB_5YPYkeJ;=cRMh z`p@bgJN!Z5E*lbQq-q~2!>zg+Y6W507; z{{Ve}U7lWuFX}p*8e?d#u#!U62v&rzh*_oq@blUSERKY}AsXi>_=1jvpG#{|BuB0~ zntJGL-()a<&BDOPw`$22^?*#iS~@Vk3U2`S-1LgwkfFJHOq-sD_7d{z3ay@SmpT^U zuzmeZ&@!3gDy{*PNmEmg$$Hc|z?EmC=AxPiF~QUW+qGc@c`gzk@g6>sa|H}S%QPc~ zo4^-#rzMrcga5okx`5z7n4a15IIqmH*wpBU#xj|p88+=n^`CP&u!w^*yYHDp+duC3 z4Cir8??Js7_|&qO7F@p~A&kJZJ@24&co!-o*_ zLzf<_S6C@NrKTZ%E)d8vEu&9}*FJ71 zhx{7-eU~1=G=L_BkIMS3?Op$TccPcz-vEP5+W~xc$V2~GR4*!1id~nmll*l#^I&fW z=5$qkB+>rZqG9!qG9~H73a(knbJvG!V`=*rK^J6ui_oOt7Oq`6lHEyuNwtkP;!Z|F zJSw(|na@cWe6xkF z^nPGua_+1J{VYxhYf8GiWmus3bhZ*wAH6g$(xxixqXy+PjJbAmFV3d-#SVKKtGgyc zUg`4)j*F1bs@jmvUqhoLhmi7Mll`B5-wNaYevdN0_e4j+590H!g&W_HxiIL{*28?r9o}GKm}^a6O()lbWh@;h*|WS~`wp zT;xLG6d|JezT_z6xd<}-Wd%R@x~RRTn9(d7ix$aWxyL6?CFi|^P1WR{+Z!H0bPV2V^q5ZtfSquyam{KtBaEt5k$Wy zO^;lVip7dWD6BS#2)j_pAwJvw6$C;!84)VYqJ=kcZfudNOV5Yb_6`5=OTdlzASOSq z%$&dcv1Z8kGyZpc2crxg!SWJWvs3M?NbR%bM(;-ZEXbw(S24m+>{<`Ytp+{rlQF-# z$m+fft%hDaKp4NYIZlk4y3n`ogpXho=+~EYt~5#Xl6)Ws;WX>hHVZ_vO!&d%>ON2( z6NceF3{@ZUSNTI^(a+VdX=D0K^~Aq-aeAY8$8VC~u@Eq4`#03mX#ww-Jhb||;LS#1QZJ~Qv*KL%-PmrEmZZ*mqv*3( z;dE+r-Qh=5Zs-%JRT|(pBA8b9Le4yUX zx8Qy1q42~7JO44C!xQ)!`k?Ar@hcc)ar#~V8d-=G2U4^-GAr|}dR4QOW{cn$(s|R< z7ys29+bj*d;i%gNUBc=a%|PfPa0@;I*0=b zJl8pIuC|FwFCi}|q{kLMDY2dX-=+VR0%w58slQBoz%nTD4xSe}Ohopxi09gpK{1F( zkDMd@QsRK*5#}>|2u+o#$eojAB!Vz`c%~Tpsm<_Yyy~~E}LsEnk;1(^lGqwkP zRF#AfeaE2>EBA$$Hoosl)=pK%*#1}DyR{sKPwwPDL;lktEOAYj9826R+BAUn?0O@5?^aRFUE?8!sbCcbeAfRO^_GR9d?}f(9R{$pp6`Ht|aJw-{o5T zpRoOC=_UWr(pduEi~{aRhBNVcR2TZZ-6Z-R0FZ3t1H_ya#XgxNIQDBU49SdB<_@F_N3*)!vN@J zgu&X#_h(cCGW+2dSL-eonrn(I4fYR+tJR9)^Z=r75nuJt*-Ha^PLSZTI~zHzni;Dc zdLH@1V{1eEoVmLaSfHd2C^;_1%j-C|h4d4=M5_Z-Pik~}?t~ZB9ZbtFEtU~Rs7#HW zI}fud^#h;rGQf-kzN^p^#p;KedStqi^dwiv+g`j2r{`~9f++EklKpGCM%{&7E?lDU zCy{n#9K2lDcfnlE43ruxMSGGzn4{Z;+iQ}bEZNaH0sJ#{_rep-$oRE`Bl!8X;mX1- zX&Fo6ImBMEusCM3+0o5Eq{PMa?$kB%XosX^+1(4f-`AH5wlL-n4fR$or3HIQz_bBkr!L!s=|3-&h38fTiXYdUcf6& z7LTo9pP<^%rRaz?=ziw)_3~&pA)_7bzragJ6Afy8k5MKSLf1w?Iv4#V6n!#J&4KUQ z_d6JaB9Uj17UP`U`Q@tZ|BZ4fsp0G!qW#iYS$| zp8+|P>hg*tt*dMBgi0M?)ktRjHEsyDUv*Dk6n~J|r0+9Z=&V3yqUEi_V%~r&&;)8v+DrPkn0;xSR@&$wB}ILY*5vmI5*$-MmHzyz(ACC&Zd9g;NzpG zRJ4yJs+_FFU?6Mnilk*+g!c<=uHAv$uUwBAW%E*%WB*I66cpb4%}m$c^hmR+5?k^% zR%7TL%AdR_KzBj7jwsTCVrz>(B~=#XHy!?$)y-?fH5 z4+9bftRu@aE&H;=rSRrO|M!_s1Pf)RPc}BLZ8TUQrIei8j^#Oj@1GFI!aYqP4xGr0 ztxE=QHTr@PX}aF_D(DnT4N5jn)92{`VUIP@z8R)p3%e_vlW0=H`2ZB{G2o*o_!`uF+Uwiht;VraZ zu^X#Fq=U;^rj_%x&O%LSGP9%V!N~CmA&${3nVM_~Eh98`O|Bb;o5vKh!gV zNBce?wB_Ch3UgaNx-sRECCl_zML{4!{8|M0R%-yFV3ecAc|p&ZX#T0aD|EI5sqMh2 zad{w_ZKCTH6B^NQ_gc)PcaqD^A9~3mlq@l>>Dz0I`MNteefDHdP3L0=D1%v~9cJPO z4LRp+?&`^=a7#hv2>kS%>2B-mxx(`06vwr=LNn^<|G*Z#yVyAHIo(un>^EgKY`YCL z)m>9CsdGxvH9=D5q~SQI!-|0Zv+W$>eQUWdWo5G@bLt4syY}Eq?+!`saE3Tf(e1yy zzVVJTgqqkK>mevIdx5Yamn@rW(-g24?4D47LhPj^7}n2`LX=59vFV#6Rj(&>p6rf2 zRRaZ9y}f8J-_wgHQR6&-tc`b|bwzi5t+I& z1;$r{f=zB6A5ETc>f$;9a!`l=jE%XHXtu%JDHs-6gBSKOUypO1^R8h-C)l3&>^&RO z`eh8vpd5!@ts367JZ_#19gp%qhMl_Q*%J!J^3(Mwv0whf;%AoPxUJfbb3u21?c7Gn z;-DNv3z}6&_(ubc?@Nf4qP|sf@4p zY$UL6BcFl_1>S5v0_vU(i(eNRCo}fS6LoX74<9$tk!kx+vUh1ecG$7!CAU(0fERQ! zj~#|oy04gyp$uVOl1dn#;l!uqq}}|fV;YzpUe#?%0_;2m29nOwdqrc>rPMf8=D}|?z$~I*33z*$EX_kKHn;pW-H``;O=BEv!x)Grr(=3I& zp#z&<9QYwDeiK=R(LHUYZCzC{KKFfBXswKF_`8kCnT^CMrKq8qx((6$yqOpy+a$y= z<5xqmPFa`(jzMw{HEbVQQ*XJwiT-SAqxDd&qNawDRoLHiVQ}1H-6DN(b9umTVz}ym zmpyM?8zY}X`1_^#oPD!RxtG!&cRQf;`|#%JTVb{@vFnJ`%+i%pOM(<)&%^NDLO9rY zLrvc;5f0s*O77*eT1orM^tlkJkrU_bEAm*R{d`ulFCf%szwhe)RM)`No>ZN#8wX9T z;g!T|IROiFC~fQeuB!4eoCzO9`9}H6RleR>r$9&d%Y~tr}2zec-bO7{$ft+VU9ePP*=OWK-?{9ll;;L?|&B?j*Am&6B;i722MtL z`4BeAk%}cm%QkS?bdj!%G}Z;D6Es_MVzoGAD8MLA*XDT!*j*bX@>Q5mqL&3O3eCi^ zpRLYs3V%g2ikGH?NWWn>EvtP0YY1oHs~1GZ-qR+}2PH!#4V!}>CMPDZ8Q%ZiD^?ei zq1GBH@nfx&HDdzpl4w)>7V00ujE%+(%%jFZi>NG74v*WS9(7UQW)Y6SAfkQz1ocl2 zqL8PFXX7tX1k(^uc|VLg=((y`0(Y_=Tl~zK5_MPsTzK` z>ui_yNMMtx{eXA#nR72oVex{2K-PBt&nyo_px)F@fziels{{!T;z&`?9DHNzX%m+K z;7V?yMXI{3Thde(g*=P+e8G6IB>k)@!I1*iNV(vaCO13zv4Yx~Ly-<-ebdfoF72dS z{!8Z6%g*=J31eQ)beC!0Xw_?yUM2ae4AsBxGi!+l=U46<0;vNYSu2K@BK>+a*`fb1wQ9n zdBwmQPAI18;Ald7JfJ32V26E@CY`+WchDQH%d2{P&8QYDU2Vb^CFwqW7<~kGWPzXz z)eKS&Hm7zJpXp3FkuiqIX{`GC%ltksS~KJ+p+avJAvEMC>a8MWt^EEj;%RTka?gOe z(v7>sanB${;We=F!~03~cs~gP@`)4&JI>#jvy^(ZQP7Ape&>^tDs{%@L7MiAMqJU& zqCX)IhSOz?V6N%ph0PErzr|-L_)ygd-4<8f8 zk1*RCrJ;m-{Hy_t*q|8E4q@LRjy?R7YXmv;gkBxdT3uwlLp#h?KYJcC#+V_PLu3g) zGXH}4-molo>KFtg+M>i0yovlX?O^N?5sDMQo^g(!tfhR0D@djwWsKN|?(!07M&j~1 zZu|bUvFL=W#_*9=$RW)9YwO9{c>!eh8P3HQ&eIYMoH*Ge<9*eBV(|F9W&DKc}5GJtYhJnv4EiwW`i{uo} zY}inV#G2aPu55+_-~9@W?IQ0Y)mTweKo&{t=bPYT1JmTTI8|-RFW8u&!_ z_O*AL)baSbQI7*;OO@MI1f`Uop%Y-iw9%BuMXKyQL%DK!<^dgajcXTB72smCK-Z zmuUCoX_-C@e~37ff5f`z#^!nyn(c^racPLzTI?%NN)9^-<|})m*e9ziT1R%Mt^L$9 zP|#Wb!Vpt{=D*vus`dzqII1sG&1{23D-aq?;uV2ntP#V57R@QulCxIfZb zwam2F;1B$Op)GgnXkv4B%r{B$G*ub={cQj?CItRztprV)IwZ~#=`kZdb_H?KT-ACh z1jjRK?a0^OpsRoz$xWWOYhf9|czW#GNVlQub}@Q5ETD9<+c_2FoTb1uA2$3jUz@on z=id~%^*Y6a4%6bpuf&1HZfNj?qQ{wE{bPE^81Z&eBhWTp_lD4GW+_Cp38Aner&aD9*$=_+qO_HPRrLXYj$zR19x@k?Jm2@D~p5o?+) zv{=$X(6fv+w`Qu958jpR0b%Y`RXjkmKT8Z;%4&>KxBwluW6-aud*Ra$aBiFv9r@VY zWsmip9Ut)_@f)ZyyjiR&Wm#m~hmdrJPyY3A%yv$x?%D|hJ-!XXDh1Ek0A+;wZj^Xs(Wsn2r{{gF*20dmk%{xY zj9=@#16AK9UJ+r?b~r#-r@xKuro56IUj(}Q1jlhgKm&=7Ds&oel=Cw~B*f)r1r7xr zYi-EP&2Qyt4GUT@kfV(9cGqq#FI|TeS#O&F>n&D$&XjbwWF1g@lf7o5b^Tv3t+mGlye`eo3@D z@7f9pB?|w7Y@E`bTm#x}{@$D71h`LZ2Rw+K3Ob3W6~M-Vk&M93Y0rsZ*R{85 zB}&HMQ~@Wap9mM178ii7xt!8Oly^Q8YE+NDx}?9keS?4GGl6YI7{Aguh2nZf1k>{X zB>qTWy+}r?#MiT%X9x}30+VmV7m6zhMLkiElQhC)o{6mWVp-_bML)v&D^E{;@z8#v&s{WA`hVW)t>2h*nu9Cz%rv|p+ zs#B|@52AncpYkm3fBoCX31MToL~asWLQ)Fvl;`p`rDp!2iV!TjQ z>fg3f$q}CMHe#eV1l5T@sSnIxPTL7k3M}GywsYdIF~f5ef7F)NaL7+ZnmId_{i&8z zuD0 zOAPEeh-Xhs;N9rc%L4QZ^@Np&b^jeFj8h)4scms^RT#;3xLE%T3iz70j(?@q+;t_s9R{j@@wfR0Ev_|MYyL{s$~R zJlHB(T(B{`u`X0)T3#WP^euA{T%!1$L`j6{Tf>=f?I<*&g5*nR&6 z^rJ*BLHM^MGJvF>abpMEtN-nw|4n-J4Cki8a_Og0(i>ncCMc^nV7StK#WA#I^pT=A zHTKLxvOtY2QsZN0^J3b{viauh2~80e6?9|nJPae#ti4a1bE$@u`6K{$dEf{yVM*tQ zGZNG6s>NxKT!#&uB*8^8F~XkBX-IPboYhoEV}i&@75?)cCuvyIF%_6&+Xaem$@1x) z$O{3Tp#T=~5#I=_JdXZ!Ci$0ibgXU`U?hUnDg82|Xo*y6zW123Jj^&@imHhJLu9O~ zG^n_Iqe1Lz3=$bB3*+~V*Hy=MP8%%U)LgH6Q>oXE9v?z^Zl7a^Ne)1SP~7!CCbfpM zq()^}a52*Sq|bQm2ptd;*k| zYfyApb!Vv)o7z@so8?tf`)^m8QJI9xBn1O%h4;$C!os&`;ZmJuE2z5gm33xU$bAm= z`R~E6`Tdtf^SuDORFf2;@L56=CX3)Tjw-@lkw}HG@f#PY6^}6)i^Vs|B;9?qv&8hs zVBRZ&FO9E(el}l9Y9aiza&nVUJ|Cb z{Gwemphl`4BMW)0quUooJ0<`o!k6-CC(LIZ8S6l9n;cCMdBm7II4%;Y{D#oi7UIn9 zYV{9p{1Ec^gkjkyQI|#B>2rv2Ru$!9e&P7pc@8-i`X|Zb(~kCA_TFadVIKvlpknmf zo6YO?&!eVwb|X`Hr5eHMs-@GWx`u!|wOA*XT<1@Cc&6D?&n=UF5uM9fC~4$M>&;2T zVeXkFA)XbMKx45(Z6+Oq?wPLt)Xj|P2eUpu+E0s5B+j-W+h<)l8|9BiY7zrrpV-tE znKH8kLen+FAO-l*bF<<34u@^|qOYj=qIS{I6dIz+YXz#`P(_u+Pe5cvw>B(v+^&<> zP>((O&&8u0vw6e;qAY%ZB()W%zf!}^y9e&*1pOk zGx4)cM12g`zdheCX4oZp<%a@7HSL6pPa-{uA37l}<=tL|$gHfxddifKMcd{)eqv9T z7uc7O)~Q{tdF;*BLzeInHAb~|8%A@ZJl3J07k1p4(0YBy&c2Xe7;fbRi|E}xu1@^9 z{8`7Mb5ErIhK{d_tvH>lh0|=mmmjwBeRu<|5A{fYcy6lHeMsLr4ryxN@Cm_uHJ5If z&J)eO=8{6ms(Bb2ME;##8Jo66YQ4bjJR;<#WUw@U!zZ)sr+XJ>;LAQX(QD}s79xy~oH{LJosOQpaZNBhtpQ;E| zXoT;(v&iL)J9Y#~=3Z1*r-zx(qB`M6pr~yA<+U5+ zH8uN>yi78(y31DyeH8z@E6#*n-a4GhG)4fU0SaIzdAL^wq9yYbNg_);dSkJcuUbtV zOXaq3+~=}_vRm=OVEWevHI7+HzBzaCA%6QoB6O!?Q+1JvBwjKt%XBHL9R}|%?r))+ zpKy?(Q8T0_gr}V;x7P_UiRsrmW*GRrmyfu`ZzOoE_-R;l*YRoju0NKsc1E30Ibpj{ zg7+$+#YuozP%COZOHRO+$)Z4_9S(-QSOf4;Rje z-_Ux`16^Z&+X36?oi5OBj&w0e(a=213am4EjRCsCyTWeOQFkiCF#Jx=g7r9l=~$u< zcmc8(IXiS4aq3iq2jvKB$t27ytc-8G``^U*A9|e$HsfWyLK3Wt5VNKY_a?861Xm%W*F#KhL+k(%Qs%4Fv3|{iJ^vD}bEY)PIis|{U_zXxlTu53CQwcN;CfZ}p5)S|`^tjOVV=W*V{e+?+4xN~v!k9v zgY%sY>}%u(lj+`gDSrEOY--KN{#dQ>MvEbxH~lW(Ti;sK86SA|)nbg;wZS zIS9Sz>niu4>)`8Nag-)|S$X<+KE-y^y5V=6UB3Zs#a9?SDwzoKwB$eaR>$AoF36@Y z0wSmxGqT?LzmUYmCwVm`+v|Ky>dHJ*39jG#oc?&IQB1y8x~j03b#{vqMtWUIIt>3b zD|Ah!pf$y11@eUQy)XS(8#ikKmAWgjVFLWPZ*f-44n_1qbdEnB1RF&BfxAAy3kkNS zTb*%N=-v5^rrBy{72v!Bu@mP*y|K9Jpw!UjA-I>!G1qG|;{1kxhT-252#PwoIme0# zcHjrx6}k0`wFjTy{e}2nQPZ7nWQgq#SmBb&B*#PB61B;NVMJxuFWm;DF#a-w0{=z= z`u8(LL4I?+I7;M?sp?SZcD;6{={IqpT+>CGNC3S#-D!%3F!W{^dQ9Q; zKLejn0CsdsnVlIgDcB4+-42+1OZvDkz}bj}B|~7^ zgM({YxTR*QR=w3x`%d4HnQni%9W{J{n$pn8mn-%$K71L(w9yoIT*tv3BR=}nEQ{(R z{ah~nm#Kay$k(bDd?el9gc^Ek`Oq2~c8jd)`3dCq=@9ty`T@&YHl#^xTF!W3r1k3% zB~r2vhpJ?gqjhi;Q%JxXB?nM)2hBO9(@JP8#`Q6wlmL;NzX@VlRWucL&r!!&k^>aY zsB+_8{PE6A8&rn^wVWIcJA0?oaFuYsJVdj-RvI}?YLV)aIo!r8m?!KtoUe&$=}>zj z`P?re2^KeoY!hP#I}3fNkw+y)ONZNwy3}px=}VH|le(-ORWERqmQzXI-G48ox20;- zw9mo>OOB;`_j3)345dN&Q|*Ma`mWx_Ac9D)X7du@`9)}=7*rmDkQ=ii}{(MnM{9COw3-{gGOC*s=FNp(fO z<}f7MCp!m({wcOHTeH24QRwX+)1eiTG)GXfGu&up0)!>Q4F<;f|0W{4f~yd*hE(_O8Q& z??bwIMkp3vV$$ue+k3Npc?b2gZL`zZpQ7y_N|9e)^9flUD)bhW<8wX&+iAiIiA`-x zvGn~WR{BE8Db{h5U($VCrJ}8LtFE_ufaGe=`>+DfxRxd%CZ+??_#x+N;W+W1(Amu84;UW(J$Bx?msPpxhvA~+NkX6P)23K z@_t+_+CYTnr%l(IRKus0sWqdLN$hYnr;W)7PSOdtmwB#b(Vac#pH_Z4ZixUwYvx-> z3c9My5O~?ZI{gj5nVFllxsOt{j)qQ(u5qrlwj_p>t^^kfiL%QIZ_LBd+E;#mTLYoo zEA1-KQq3vG+0lP{<6?h?bSzvtWPHNh|D^k{O~G=)Ns{7DrMYX5l2)_r00QjdidPM%9)tw zmNYo;cCSz7E{<+8*&lO;rdO>i$TbaS?g+TlW)3SarMH3s+S$=m4&j9iu!@Z!9uc5r*O*p;m*6XrLvKwIVY%mnZOtjj(4+pPf)r%{wRG0wsuuGzc}$_et5W z@fCg|C&2X-Tavuzb(h|hBUkKk4ug@4j`%SBm5M;(A+r}pz7ZM@}`^$(?Yo8{;{9w^= zp>N7ueN{*wb)8ehwQr&h(`O0?Z_2bOf}>c}%ybK$W}0;99_xCXysQfCTixCV;nixl z;!tGsoC)J(f@`a>stYn2n-=I}P1l8z1@@^=b>aB(&dH?`>RLnS1lzQ&EApLwl>XpC zVRhaF4|&kJ%`c_q)cdbNU-%Z6!yYu;0>J05DZR-~?c6u-aFP?!*8xBVItYiMRGGz0k7pYu;3Ud)xCbO!)qu^2|2>9o zcQtyfZj2VVbaq^sA(9K@J^?3=G53oQ*<%>9CqAMPPD6Ew=GwdR(M|d)b#?VyIHVo& zE6`85mxmPNzjmXe335Ox48$k$$Xv@31%JtbZx7qwS6mSC#0-o1hcl`kr+LxpgJ;xL zALbJQMlVd$S=U_^eaRWM;|ylkLRZX`6pYv2c`*Px_{Y^~OnkXn4;Cn_e0-v<7a?Ap zU*c3#8y0!tEf%wRnf>o8&o{e`=7h#hdIDUKmblR~R?t;6zSSM13K6FPu@sY|)-O5? ze+4Fp=xewiv!AQj=5~1wgI^k6^zmn@&V}|B>1;f!Y`te9P>hc0LTT~;a5$fuX~erHyp*P$kYF1yT4Q- zj8LLlIGHDGy!F=}HK7a+CX+u6Lvx7)tWc&u?`uHAHQ7J9nFDGBPiSOGFCq@0=lw?RS;t1aeo{ zq9+gT4azqB%uf|sfV_uz_QIv1kYWl4=`f_`>vvB)xlGSax}D^xdQ$CTOapn;kt{lD zWBQl5pGQg+;TV2O(X|aYEGcmqXh`ujwUA)*N^$4hHtmq>5}d=+30FC&Y+p}&Q`8dY z;wiHdfe9Yfc3}{ zoO~fE_-Ya3psNl9U^fN~OvYnrTX`zRsE}`jf2aQ7sI-)L|8EDdJe0re{x}-cWf&Wl zNzhGC44gIf1LyL!N7q?nD>8Sp>$xS582->2;Q;pswPOuFvA9JRL{RMbZu@f4;F7Os zpE$E{bvAYSE5s{`KUMej>X2!aa;s$?pCW`28WrJw)UgvAQ|QBdtF3UYf-PUJ8~AVg zB;Am`1|t;7si|-fS1{EeO1f1yK#^~6PIzy$3|MPx{?kymj}KNDuFjmKSOe_)J`T`t zz(>*FsLu_mA3!yx!|X;#njPq0C4G$D&?|TSO@~weevvG&;;7xK8&XTr&a-K_&EI+N z1f-q{G{?W*g=ShIlqMk=g86^nCvL8ceMPrAS^*L|=~mgD$A0k8OQ;~uk)~n6lMnr4 zt(z!!p{eM4<-oQ>AcA0TytPUw zoDC*yjj1;t`-mO+7~x5fApI7nw@3Vvst*o^F9O@-{y%cP1WG=5gDwPyoInfg?X7QuRsGpl3G53?7Y)L7FAKX5(7*5cDWy8u;??K^>Px_co1PRT zP4GiTbVz0=^&xeAGO&^)CAvIE_)=|(&oTeDE=>c%Q^!3NG3QnXoAud-P{f{)Td;2L zJjI_N{M=h$dU(eNFURk>d7_sr$}ewkl2Jqm8GHn2N2o!9*ZDX-elVGwCQtHp7SBbo zCFjx}A9F3fxO%;le$w@5+vC9>vXTJ8PyBvbZWLTB$d|?HwH%ggZ+S0o1-4W`q*;@* z{1eqGwt%>fSTlCM_V(RF%G2irr)qJ*OLltrVfKx57#L+PVysPPzv84cDV2H>8NSRd zur9Jua!g``>+T5T#Db}B#YM5@L);KyKSyg)ZPp~t!~tGsRDR&jvaGp;!lvZOG!mtd ziu1^K@P9I;;*kapaIvT$Gf+$I7~ehmRbqPY4&4%*+6`1jy5;@e=mX_lJE+d*^#ab01HcH}N;j*QhH(rimf6IMs z;d=!rJP_0H6-p6*YC}t-0>CBdO~~b{MUhTUNUp~qx2{#%O9g`*K+gmt1?&!KZCsRgeNVIQ$)#N@|{K=rYz-y z9^{vF!fVYm*ZVA)m_%o@soP_ydNX2aH2?YOI!^MNIGI>5OHkVw(}6j1Mz+JRSl407 zVxmB*%8;Sduz1$QvSLtA+E**!P0-nlJL)NnI%av@#oyzneKJ~tPo4HVu6IN1BWHE9 z@^ZfCC#)W7qi8^`UZXv&`;p{G=5>}cUalYU;eL6L?FVdCx(X4b9lt@+EMUE+1u&C_ zk-T?RFSjWV^#`tSY6e}p4>eb1KibMazib3jQzWCYqV$g8bbX62m2)z-Rzk0Bc(M(+ z%Gmtyz78PpGatB{$FsS7F~Nc;{PW=aR^g)FCCSojjd}6;?D4_f*OxLri@YR*jy;c+5!+*FeDizp4JXY15S5m*WJGtT~+lJZpH+|NP5|h1s3fCWAo8x{$EE|9uIZ?|M&adZQHW4 z9a5C3T;<#f6=PK)i_ zSzlyPyhKa?)hs|`=|e5(Ig;c6T!Vj=GI^>DjSU3uQNiw;>Qexe~aRk6OZrt`UHHfa>QU4{=FGYQDT~+0a7SVmwKiY zNnjjA+*h$)dBuRgXwqlDh1P9c{NG=fuS||h2z}JYfJtX*pzI%XDCb(UOtx76xM1_Kt;nBg{Ot#;2NhVyVTpyGnpN)J?Esso_;MZfm^TMcz8`XZ_wDnJ z+&ci0_RN?XC5(>2Y^WNcPX|`LdWJU3*`DS>T(zzoNSeteRWD!+M?dWP0Ox?UKo4}! zV$4?Y7SgKwNMp~z>- zZq1f~71WJ|u&&ps;|pgjdt!WFUK1j(iSsLmulT;XfP`|0=*fbv{T`) z(&vL30eX9~PSe?hAzCcdU1hQ;7_0Tt+%?(k3a)M_968ep3_yAnze7xI=5#Wpwe)8o#H&LC7i-$io1g(L=v&ku_RLXL4!Rz*yNdI;^bOj+Q6Bb@?=7iBq= z+B@K0;NNS?PWk7YNM)K`aj+B*cjcVnuU0P>^`c*aBWqzMZ(!ui-js8bPL(1&H8qbF zH9zgJ@pDgxCp6(mYOXQFD8@mqQfJc>*~(p;PV!x#DU!B5s<1pd~_Ik18~87Y9-4ZXzP}x_7X%mw^78wprGFtT|2p|uYwE|S($OGWUd{bROR7Veo%Nq zlv~V|l0w}O3h{)o--*ZWP2juG4`+ZDhPmSqpF4?Scz$n2-6b(Cyo%5)AF(N_@&6~n zj?2O6_`_dNfBqicLzsbKE^-y($o7HR=Any(K7cRTsUh-@H-JkHIr?{L0!Z*Ue^*k~ zHZHx!nO^nb=)AjUFkahHUeq8$evOI_*E0VrP)Sre(tcY|)F>kC4{x?fpR+{A^YE)+ zGxpOoCx;kLX)~_FPfDg&_A>^@JB#8Z@^{*faBMQ-t8r4tQP@Rf$h|=k!4aw1f}g8g zyEy~jJ<((6Rxn-PmZ*?cTrdIuWuQT<@`_HR0uzxD;lOz8oH_N$rjaUYBOjefHI+ee zLkBPidyhSRBQ3`J_t|%(PD*1t>v)iO*$Gk2jRrrBtN~Y6QMZjT%)f z)Ng9cE3_6Y<-3q>P{gRLt&)rDhElsZlcFanEKJPr5v1lsz+U;UeRg>AlOw}kcW3#K zt-3+qEt1b%&zof#B-L_xRRX!k{c7%>u6+$*ZmCUHtS1Q{E^deB7A+5UMLG#`GQcTu zE@23dRo|+9KGNrHe!B2}_N&xi_$W2HI&_DQJWbQl&*_x9VBtV%M5?Vxbvev(D@d|yWq&nWPbt2e zpm*m`XeE6bu+iV2hJzOGN0BPaL++Xtxs<OFisZw`@TP#2!u7IZe(v)}=Ypqs56VofTa-nXv1SxPXrfOvt;dkyX^5X3$^)?3tD zBWptS!GEG+(nW z9+p4_JuO_{^&wVj9_U!ym6Bl>#=~viS5yk-AGO(tR>Xm#N3#|IPy_O|04&jOJHFa+ z)WxZcl|p>OV`uSkwQDlRzQonaGu*hfhq)^$-Kt4C8?GXVvxv&|>Qs`~khKWOE@3i5 zV8VRL+LqaLX5J|>4|C^1>gR8td4R`;V_-8ok`zatjNHF3@vCW>(zUlC35Hr!k%@=7 z2wA!dmUPfC9t)wYR`#9oz7cCl+fd}+E{I%8fcsV-@tuwTT5*mqd^Vy!P1rx+2?A^4 zGo$j&F~u>Mz9p__X~;d9<1nN3s`_Ig;;`B?zYn_yRZojn)ZhNzl&)C`=W5Y|A2LKS}V#P?d2bkmIn&grMG-S~J?F$$uWIE&DHpsFj%jVQL9>&t13BJ7`Z2MaU4 zj{e+@3kO1MVwcz+++H>0pM=8|ceROF1C{M#_xvvafKX6(jkkWW%fIZ_`Z`kEWFvXM zdW7S7RLlT?DLU8&t)MJBq(+NhEXokHrL3m74P&QHYI}s>c(v8xo^_$|9Y?-PsE?NH z$vxzTzku{eAb&N{&#OXwRisc9=i=Q|F@X@p+{`x@Q*+AA3nCP2VjlRs7U91#bC0?N z)}y=&C2BQ#? zu?}OaQOukZbhXnXTwo>A&m2GwouUd{ck*KF*RVAma4OpD`Q*+d|aVgPx9@pOQ#Uim$l(jaUQ2vVkD$0f$w zU(wnFM!hqGGFubh;cJ(kLoYyxmC-B=X&Ab@h`Dya zztVN!t5m;#y1TB9&#qV0z`UaOR;{T%gsl1H4)}n_F35EZE`>TkI77kikaP46N3a5S zZHYyRAVISqn1Rn%JWaXh0ab`LuqXc1pa8+cKf%1s_Scz(vR=hl26B8RR8@fP4<2$5 zq4^L*Epjbfa3`c>UD)X8u$yZk?v`j6abHwB(H-U5 z@ij8v$o^bDr;k*ab5aCQq75$sH!{<~rzW-3l||u`NdKYWwyr&*{vK^14pV6cW>|Yt za#|Sf(&}ip;9yyz?uxTXxYGuxFm>laLj_W|=;BQYN+cfvS+6|=9RICE5UjYk7UL>; zFi6D=CB8tEnV?R z(t}8)j)BKGNRoQv&>9-J$1W^T*IpU5(l(;e3JW$|tu;Qz+vnR4Y7Y!YboGP^Yu6X2 zJMj@ax#hCYI7q`=^lIbH3CSLJg#@@iRZbK*RY)DZ`G{&X2afAMD?2e%$&-_jJaiI? z@;AUC5fq?2NCH1e`p#6UczT&`a^3l`q4~8$$9UDrV zh)_=5*4lsGAi{>w*Z7RHvjfSQQ>%A{&gdT5KK~3g`On?|JL{Oeq#1Lb3m47+ukv8^ zOb@{jo?*$^cm}D(Cm2bA1wm$CxD=2ZvTsg&B4+lE7&iA^1;)b)O4fS&ioFkwmIKfr zN$2_`8HDapcFwD?nL~4T0lip4Z8`A${m!a(EC*xlmYB?jl3Ur#qP_3CPWN(J(-~P{ z@Lkc2& zirY+Bd(e6;BJ_DRvQgf7VNG%Y8uGP=WLXznIBUX6yE+>$f%EVsZ2MpT%+iihMOBJ$ zJcQS;WasMmpQzr7ETtXQ+X0>KHl_J7$%~$tu@7`R=yjAmKnCnYWEz24hzQXdW0_9b zuPzqXEsg6i-n0(${U?amAe>^JK!LP;=B>NxY&{5dzhnWe-z>WA=wcwRHBQLQXa6D> zk$%uS~rKyQCWy^*hv zSwtu2{!*?`*mhbrsN7W@IC=ox%y`bK7Cq(7)FIb4h#LVVxD%qde1y+Jbn;01v?$*p zLiw+{KmWovFFMe4(}iY~oDVu7fP4NVHuz=}V@(hn!Bzbl$O~fkNi1e9^yj5hLr&1l zf~ALgVZ*)UO_x}~{{_0C&yt6uI5nmPc<2Q^teoFdmt>x=QSjgh^;p6*e34$62 zTmYUYkaqx)in~?qN0V}h5yf};0h-?@ua$-=3!|Nbla-6U@9yZh!f1E{AYkywm0U>1 zGe2UAhb2nhcTign#>}N`XtdqnYZ!^s&zlRN*rGt#*He@0``-56!qid3PyjMmzEfvc zP?aIw9bV~W1W>!nKX01t>w)X6D&F^ix6jEunns)pR#5^n?xPN!F4BHU)N1HftD*oS zjlanG&aKEPnx1Q-WzvpS!au%Y(qFqb^G44nnXAFZ`#*IrMxf37+#1()ApN`wW%#*r zw@J$=2Ex$RF2Q&7)BSzs&ioVWySxjsldc|L=tzA~wqUEa=cZVh=kE3LiMg=%& z?;D_BgtuDdI+VL|k9VY)--LtNN>1q9E$tfC@3mz~r;UiutNECv>2Xqrg6f90s{mtm zg=e9%W(#Nro>t;(enPAe{OUqAqwo=p!;$|KYTSvg;hx$;;+ZV$L|=sXi>v?n?Iw@m z4tzNdnf=gZ*>Y=D|>eC(f9QBC>Ki~AewWG`CYUmmG6Fu1|#r0F=dB%`TZfI>T zd9qXS9+&~N91Sj9<3Fg46j0?>faL;u%7L%a0VKGTcNwYM7@6X7CXNuKIekuh0lLdO zXrXcgGgRCAm+(&8rHj*Et!DDAs^ha(p$WFF7#}1EdBjio`;t~i&2q?^#2?4E;kau2 z%uigK+%kLsjVxQjPgdHTO{bg>J<+84BtqB-K#rRW?8MNf>Bmvz+l?$)lhczNvTi2+ zi~2T1EI=X~C=Ct1g&8EZJNjivC^xR%H0Xd^3(7TGALt97L_0{6YvBiu-Xi|-w5@g2 zkdg}Dw0xKLekW=EWky=TtLG(Mv?WLq{OfCUON6eWGJhH@ir<^)tJMVQAht^dVQ{%I z_k4s_3J)beJFqK)nDlE{^H6SAUes%wGk{&Oy}lv*kz0U$4lNpUxi9M&r^U_tovezK z-ryqITVcP9Bee}9`Gh0krpShR-?rZ4(c>Xf zN>?jCZybwOt7!=nr+0O8BKt3?{H9@0fmJ%Wy#sVHZP`BJjT(;#YNza<5ki?nvjxl$ z9H}xHim6On1wEsBl0GJl0kqWcte!7|%6dWw`PvzX95Y-F*mzBCl-l{Zc6K&(hHAvz zEWz~$Z@(1lg{0yJQnr(X6khz%1T_Tb3_v!!z%1)mp`Y|7_D4_= zi(}4$pBGws=(I<^ra+pWwx!ksJEsVYxMZkSbi8m3zzq{lw(}AGN1no7U*&?}^3X`7 zSV?!wM5*g$Y0!UMTtHS%U3okda=f*v_n713g3M~Y`g`@bBgstorgLc?AaWZ>T2Ytt zMM0lt-B9H^NeZiji>KKKT%9gahSh27{;gf4;;{0|5vMF_dLpauf_rM)+jTi5efabI zdh`XX#!XSpyTf<-axS(73Ro6F)B;CRNx0pHZG1~{Hajl~do=K->vN451yC6$K$M^$ zO6TcWD`#Qwqfpu#COc3GoN&aCca$q z&CAGECF_!Sqm6DcSFW6094X#_9O<(v*(U6DSS;wzGwn%jT(0}|K3+UvYB%Sg3kL9st)Jj_qf=DR(2n><_bveBINe9FYI_Bxmt7^Yrb zyPoEd%r6W{>0Y#um6Rib7&6UY(wEQJS9jZ)c$mo}YAFBA)~thFPvJG51qAM2bh&7n zwbc8Z-c%L8I8th3S_8@?T0{jg-*U3q{nys$a| zkwm`uvsg$M=Qv&;eVvmET_2cfIqZ!aQ4G?GE1OG-sHj#04<1oO87?4L!Fg=t`0)BY z$4|$aUQb5e$%fQ9Cz!$N)oX^EwnGnPdS_oR8LnUYwK`P22Xbo(bi9Z!W^Ak9b_T1> z@RswTiyEJ$@xvn&k`R=?8ZfhnB~?&$9M_&J%$gq?Mq z6`M7Wx@RW6hp;h*Y^4iXd5QC73n-6$J%KG5v|E{l*?-P5zs?zbU@1RYh}&UI+xf{1 z4lJAv})*^Z$iMq-!+9=)3K{ zhTTTT;GW^%>qC`<)>q{3$P8WyC4z3Jf>gR_{E&K1(el>co2G=v%-wZ^Yt$y4f9d+6 z3e{yfKFl{DnX?`LB?S>`kn<6k7pBb?z7Cr`y@p<>Ja{nPVm-$AaK_W1WawpV(CzlV z%9l99a4>*Y*L2;iOn@lOiJ>Xam~C#NnhI8=bj|`3`nKg2!^ZXeXtHXc=@Hk(6xHg8 z#o1QK4EE{#u-@oZclh5D(-MqQ;-Y(D%&xE0I26Ro-M!Ff?dwj0VNpzS+Pjbe%`YD- zuMe)NZ{M!)c_%weKxpf?MQ+OP`{)i|PqHJPn;f*yoC3m2@sEH-);!^vp6f|F6xsp6 z{g#T7R72+tg%Snd#-QbnbhDC2E*9PiRgUKQ|F>385S4Wa)~9%5XyX>89^e~)2B$T< zHj^-3kfQV1(Z9bh#<4O z2~dk-U<&pO?rn~53~qXxVX}WJmE)*h4||(-gAQMK-F(Jtcq3Fn&_oyTwVuH-W-2qs zNL&XD`CJjVARR0rMQ0H0@B^0h%0?fqkC24v28-uqedWM_uG{CQ`wl~hKs`2bNCMot zQ;kLp%W;SO+V0kQIWYFU@{tksdu%^>U1&Vl%RS574SLbUS@RZEFH|avw6d?;gOV)h z?X#T_>yIo}cni3K2wk-Au=*CCSNuEFh8?Ggq)S_jG%(=wdWFv1p)<+R_1Dm<;;02aM5F$%@YTdHVDRR#72XKJB?#Lgv$zESM~aoZzb zgP`(SI}K&VPGAqIus(+iVo%mhTxdtA|Ml$$L4RWu2!5rhCm9HD3%LGe%q3H6)hNH2 zZC%2~-RPaP)gxe|;py>U{AsBVxP$~FUErX{#cf(BTio>w+F5eDR>J!Eab)zPa#~S0 z#OS+GMnWbeK_6N$tQ9BSSu3bbHpLsCv1N@|#yCH?m>u$dYyWyvLL-*oKxu?GMGD)G zXRkH28`as4LX~`i{G>%fk4?)m)lZAInHfa~XPV`*o^kbj!yg}4Kt||cu-7T|Vik`V z(#JA+AIHIU=$G}-KO_4rv7g7fmH^Wb(Uo($Wz^_!U6bMhUJ-gS$gH{7vvsad|HIsk zpehfI2vUbU+?hg&juw2iBipK)xtqo)>>7c>_0!cpYL~ZejH~n5^`ewJdWIuu-Qr$P z5F)JVv5}?gxbngMBUk%>{$x+uAOE3P(kUeAQ5zjqoo52V)K#A2$I4)!Va70=G( zctgh5AZalU>9G(k3L0Uozz0{aTWK zjB*ZN?f5DAi+135z9PWM&mf#4!LteR&+V(F=!=qjqfkihxRq)a&sw@e=z`SkdoueM zAEVXhX~0!-WGWV3{V0fl3C4bUJ1W1bidLk% ziM%?}UT>#^ZLm&5ONvHQ-L%JWodEVl>| ztOOoJ=^jdL(y@{=4F_Y0yKmFTx$}03PQ9mWi5j(!n_^Ql_;t9TFLMBs_gaH z)$tZDDCXG@Ri#@ioNDtj$p&`elHQt{Y_(}WZLM-8C1Th#J9#IrcdlI3Sx|w}Us@Q^ zu|(R^9WaabbEzgHrg`RhKn4i6-5v?5CHZ@4<^3zR5azFGjsFcXzbq{ZT83-GYuBW^ z7ykHO$=XY>sSecfFj*|GxIhfe);Z4`hJTVS0RH{AA4aT%QNW7c3Nkjw{v)$VMSbp4 z$pzxyPA}$=JnD!OtTgy8JwYzlYFeiohA;PGGGkH;TId&PS?)}7g@xvf-tNJf;wksf z#2dsLB}&9Nq|qzYIz8%6{*EJ|uDv(}i)o9k`2qpuDu#o9Tn-JM&4RB^Y=Kz?)eU}A zs(|F6+Z)sfQfwMJhgyw}H8kzJsSZ9g_Ii-WS|6sevPViRM!kwBHATF*M+jLNkOR#5 zT^Yq)vO!h7^u#%2ysCm~04c~?z(YU7`@!QgyOwKpmdYRsqWmspT9$q*Ze7e?sCG14 zjB<{IHmSC9<+?IG=F1feMTjSQL*lQw4`qFlIFmj z7w9vi(OR5v5b2!TqA}AjSL4bbh|AeMTDyJNt)X=IfjH^vHR-|#V;!TY7x+o-@O+@N zAI|w*Df1YZ$6V)?0z3DPKG;P`xiZ^pl-O=|$NI|LrzXV~o%_dO?XSMqs+#xhpD3;? z`?6Vh%SFlVV80`1V-LZkeD&nD9Y z)x|zz-f0UHo?czI4072+?*?HOqcA1e5M)mtMyk9KS$NL`3^TbQS6gH>Zd;ORc}(_P z1oV5c*zk^AIpsafqu=%PEXTsmjj5@x$DtZJA>|Rs8i4yfu7+*%-M-gVn?he zgkdQ4vZ5rP!QFlF3oi=~8bGls^1M}fIlMixD<{XJFH&QwwevOZwjDi;i}%H`Sbv}0 zq{?>}yU1AecWcE_QM>A?1#~?@5`4?mgE8imn{aX67(A^aLKJ;?5~0GSB4r;r?%D{BlxA-x;meTo6i@ki_5~(e^+L9wWMz6A4>H~_Pl%UnR#jmgom!j}Adr%POM%ZZ_pGWg=)4lhjViaFjyP@Qv8rp%&n|#P` zXVYSBP}}K}=HB)bAjZ(hCA zU1H^g8}i>{NM$;R6^h>|#l&L8YP|gaf4M0*6adTnyLt7(sx=$&C2N$}2aM=93;#bf ztMSVE5-2+r;)9XH&@p^B89FVbS|(d1v*1|ujNM5Y;I$G& z*v5se1FiP$nJ{ut)b6oBQn%|&nZzQbc&)8|uqAU7{)EdW@^HcnWzzI(@TvAYp~A@g zu}Pfp+Yj8*$hc=4>U4Oh|9Z3bJVar>rNKobp~+XKGKugJH?Y#rxXqlo<)zp--$ZyU zu_*gEq|hJ$#c(g$o~{p%!tRPne)W~~o8Mpy#kjjZH~He40I7-jMJE7;+Ta_TM~^kQ z(m-Q&u3hLkqHp{$3`Gt{&v@hz{0`k)#X3~%3|}8LFq{|v>eq*&THzInvb30${Z;gn z=KeAJG;0AdyHiwTmC--Z3ogThAv3K8H}E+N2Pm*p(YBQB`~+8?nb)lP)0xJ~tLz8l z{5V$nov_q!m~(H06QQ2m{qKHp8A_#4f}yLEdSsuOWQiif55NM$(#K*$CrF!2dV2B2 z{Hj()_eo0IF)>8xY(TNk=Yfcq z0+o`tbSe~!=`4^LV|RRCT*qPIPE0!jNJ7M+mX{9p0?ixxj06hShdsWK{SuTk4$oN{ z*p>-b!71!b&WETn{^_Wi7ZkUt0MVRLC72kE-M)WKf-aJlaTdn-kMWSI-!| zE7&ZcKqkUScV0@;=c&rjlTwn8ZvC6KGsTqri^Jp?TON^M)Z2G(E0|$11AnI6mEvSDbM7v^%l`99Y2c8J91MsCjR%>~#CgqH!cGhZ%qbvZ&iNX;;DD z5GrNyNe4thvIBBqX`<4hf7g>tATZ$3fl~F@>Xu2}`NsH?@`2yN_wkU2wnNN$PUg&X zv+Q;^d|2zVYscQ$6&{rXF-0-EoD)$Eeco2WXRO-HC!fM)j;~iVLt2iRW_N-NDnbp2 ze*{3Z^I~|BJJ`Zxu?gQZlQ3&eYTRGbGaomp4TS#%wj`kFmcHd|hT(bRZ&KSov7IK$ zPp-H?p3yrQX@1q?c%l!)a38&0R%TDLz5e0ci^AgF!ou@W_Pc(Lty5JR8C@A2X&Ket=tvC!@Kt3>Q0F3 z2EuTDiec_D`u8MX$V9b7(KB`^u_jNBc~+3*wHifBA8p(=`nX}z>FRlUd8E(fK}9U< zbYV|?rS&-`$6VHw9pQLq!*%$}rf;V^J$aq!SzkMLD+Tm_(dmkn{tc0%tqPW@zybuw zkP?9YFS#aKJS--77{_tjyOg0A)pP^dPthZ^-mT2k;SG(Op8Hd=u;dqNUdxcDfc&st zIkSCA#^iKdpb7>OcA`M5v4;5CxY@8USRmH@L^44w3DdS_Dg#6)SqXd#vv`*NZzUL* zA0o6w@8{m1c1}`nO4kRQ#gK%}HT?kxf(?5A^6)7g{Ev)J(?8?qM)&UIx086tyvo!L zKfQgfRfMyii~M&uNP1wM^&Pp=jP0ztFfje;BF^?voRsrUF&>JPOsv> z4X=a}V%vUiY!0fsY6t$?HMp9naLTk_IOa=erAQo9?(0Wo9j2-~{2LR};cyKV2fbh* zG+B0iL$2|^TXq(xo@6QvjV9{ILHri8sT0hy9#&ow5rO)KXZKj`zK6?~b;FG#;R=o; zN{A}%-SU{D96XZ4%nb_6Fa|(xyz*fi1dPH~>$V81;6qidLft-dWihZ|t?^4ZrHk~7 z>?jRXE!F7D)x+sU^7tqfr)H@BrXEQU$4g(myGBdzWbBIV{_INqiWiT=@#aJ!)3Uji=I`QRZKRL|{-J zkYAPQ1PHOx!@%*!Up9c#nkZWKG>rxPjoRVpU~cR?*_mr~gDv*Ea3Qi@D(^Sf9R$D$ z+|6lA3A3djWwZ9Ak{Y@z#nb#A!`2^np8*Nh8b6*#oUdr_pmLW5UG8|=U}a_pgN!Aw z&#bf)z0O;4q-~^P!|LfE=E#L-(5odYD!BJb1IRisqs^5`owz|ef=bv^O^Wf-^jUGgu5X!Asaz4BLahGz&Y@j5iY1;vbNc_ zM0wBB}P~ZzBQ)c}Y0uPOje%2MT@#=fzB$mSi-ofN64*bDPhK ziRRD11!1IhM)4Q?M?=(-gO8@b^sK|pqo$AxIC`e(vh1z|c+yKW&RRr>$sQ2EegscE zc(;;A-aDwSLHtLX)}COS)7&@X>4Ym)4E=Ro3E2oyYJwkIU5Ac&Pdl5Sc1jp|mR+AM z^7A;f&N$A(oD~LhE+A+wwW*Xk9%9A)6aQtrD9zIXD|;KXRhl)7pNHYn%VuBv3L9i+ z(pI-Y5*~zmKF$T1)1Vh5MAM_Sgz-3fS|ta!-b$UJNgjHUaT<8q>-2%cefz=IE=v@f zA0GS1Xr>#cQp*eYk(f+!;A>X13cKG6QA`0G$Sk*i>61yr1+*O&*SFJ%{5lMlTEp#s z#SMg0dSwZ0z|Sq0hs;E0Cf0P8y_sI$4qd|kNS!|>SXbS%JVI|BbNQ7Ifk=!SlpsNM ziR-8gc8*eV|FsMkT;$IAEFdHNIYlVeheTj%k+{%9`W kd52-SnYaFT&jG~vG5fZ062IrAw(`m&Cx~to