From 4782f01d06387036bcab9943f962f2a98257a871 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Sun, 8 Oct 2023 15:33:32 -0400 Subject: [PATCH 01/22] feat: initial version (#1) --- .github/workflows/CI.yml | 10 +- .github/workflows/localize.yml | 14 +- .github/workflows/python-tests.yml | 11 +- .gitignore | 5 +- .readthedocs.yaml | 7 +- .rstcheck.cfg | 11 + CHANGELOG.md | 2 +- Contents/Code/__init__.py | 24 +- Contents/Code/const.py | 16 +- Contents/Code/plugin_manager.py | 60 ++ Contents/Code/webapp.py | 359 +++++++- Contents/DefaultPrefs.json | 2 +- Contents/Libraries/Shared/requirements.txt | 10 - Contents/Resources/icon-default.png | Bin 15514 -> 3366 bytes Contents/Resources/web/css/custom.css | 11 +- .../Resources/web/images/default-thumb.png | Bin 0 -> 91315 bytes Contents/Resources/web/images/favicon.ico | Bin 114227 -> 105582 bytes Contents/Resources/web/images/icon.png | Bin 0 -> 3366 bytes Contents/Resources/web/js/discord.js | 47 - Contents/Resources/web/js/item_loader.js | 838 ++++++++++++++++++ Contents/Resources/web/js/sleep.js | 4 - Contents/Resources/web/js/translations.js | 32 + Contents/Resources/web/templates/base.html | 8 +- Contents/Resources/web/templates/home.html | 625 ++++++++++++- Contents/Resources/web/templates/logs.html | 69 +- Contents/Resources/web/templates/navbar.html | 2 +- .../Resources/web/templates/translations.html | 45 + Contents/Strings/plugger.po | 234 ++++- Dockerfile | 14 +- README.rst | 2 +- crowdin.yml | 22 + docs/source/about/changelog.rst | 1 + docs/source/about/installation.rst | 2 +- docs/source/about/troubleshooting.rst | 6 +- docs/source/about/usage.rst | 10 +- docs/source/code_docs/webapp.rst | 2 +- docs/source/conf.py | 13 +- docs/source/contributing/build.rst | 25 +- docs/source/contributing/contributing.rst | 7 + docs/source/contributing/database.rst | 6 +- docs/source/contributing/testing.rst | 8 +- docs/source/toc.rst | 2 + package.json | 4 +- requirements-dev.txt | 3 +- requirements.txt | 13 +- scripts/_locale.py | 2 +- tests/conftest.py | 18 + tests/functional/__init__.py | 0 tests/functional/test_webapp.py | 33 + 49 files changed, 2430 insertions(+), 209 deletions(-) create mode 100644 .rstcheck.cfg create mode 100644 Contents/Code/plugin_manager.py delete mode 100644 Contents/Libraries/Shared/requirements.txt create mode 100644 Contents/Resources/web/images/default-thumb.png create mode 100644 Contents/Resources/web/images/icon.png delete mode 100644 Contents/Resources/web/js/discord.js create mode 100644 Contents/Resources/web/js/item_loader.js delete mode 100644 Contents/Resources/web/js/sleep.js create mode 100644 Contents/Resources/web/js/translations.js create mode 100644 Contents/Resources/web/templates/translations.html create mode 100644 crowdin.yml create mode 100644 docs/source/about/changelog.rst create mode 100644 docs/source/contributing/contributing.rst create mode 100644 tests/functional/__init__.py create mode 100644 tests/functional/test_webapp.py diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 7a21a3b..8938ddd 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -43,17 +43,17 @@ jobs: with: path: Plugger.bundle - - name: Install Python 2.7 - uses: actions/setup-python@v4 + - name: Install Python + uses: LizardByte/action-setup-python@master with: python-version: '2.7' - - name: Set up Python 2.7 Dependencies + - name: Set up Python Dependencies working-directory: Plugger.bundle run: | echo "Installing Requirements" python --version - python -m pip --no-python-version-warning --disable-pip-version-check install --upgrade pip setuptools + python -m pip --no-python-version-warning --disable-pip-version-check install --upgrade pip setuptools wheel # install dev requirements python -m pip install --upgrade -r requirements-dev.txt @@ -97,6 +97,7 @@ jobs: !**/Plugger.bundle/Dockerfile !**/Plugger.bundle/docs !**/Plugger.bundle/scripts + !**/Plugger.bundle/tests - name: Package Release shell: bash @@ -113,6 +114,7 @@ jobs: "-xr!Plugger.bundle/Dockerfile" \ "-xr!Plugger.bundle/docs" \ "-xr!Plugger.bundle/scripts" \ + "-xr!Plugger.bundle/tests" \ a "./Plugger.bundle.zip" "Plugger.bundle" mkdir artifacts diff --git a/.github/workflows/localize.yml b/.github/workflows/localize.yml index d05080a..c516bd5 100644 --- a/.github/workflows/localize.yml +++ b/.github/workflows/localize.yml @@ -6,7 +6,7 @@ on: branches: [nightly] paths: # prevents workflow from running unless these files change - '.github/workflows/localize.yml' - - 'Contents/Scripts/plugger.po' + - 'Contents/Strings/plugger.po' - 'Contents/Code/**.py' - 'Contents/Resources/web/templates/**' workflow_dispatch: @@ -27,8 +27,8 @@ jobs: - name: Set up Python Dependencies run: | - python -m pip install --upgrade pip setuptools - python -m pip install -r requirements.txt + python -m pip install --upgrade pip setuptools requests + python -m pip install -r requirements.txt # requests is required to install python-plexapi - name: Update Strings run: | @@ -40,14 +40,14 @@ jobs: git config --global pager.diff false # print the git diff - git diff Contents/Scripts/plugger.po + git diff Contents/Strings/plugger.po # set the variable with minimal output, replacing `\t` with ` ` - OUTPUT=$(git diff --numstat locale/retroarcher.po | sed -e "s#\t# #g") + OUTPUT=$(git diff --numstat Contents/Strings/plugger.po | sed -e "s#\t# #g") echo "git_diff=${OUTPUT}" >> $GITHUB_ENV - name: git reset - if: ${{ env.git_diff == '1 1 Contents/Scripts/plugger.po' }} # only run if more than 1 line changed + if: ${{ env.git_diff == '1 1 Contents/Strings/plugger.po' }} # only run if more than 1 line changed run: | git reset --hard @@ -59,7 +59,7 @@ jobs: uses: peter-evans/create-pull-request@v4 with: add-paths: | - Contents/Scripts/*.po + Contents/Strings/*.po token: ${{ secrets.GH_BOT_TOKEN }} # must trigger PR tests commit-message: New localization template branch: localize/update diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 2248c74..cb69ce1 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -18,20 +18,21 @@ jobs: - name: Checkout uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v4 + - name: Install Python + uses: LizardByte/action-setup-python@master with: python-version: '2.7' - name: Install python dependencies shell: bash run: | - # requests is required to install python-plexapi python -m pip --no-python-version-warning --disable-pip-version-check install --upgrade \ - pip setuptools requests + pip setuptools wheel python -m pip --no-python-version-warning --disable-pip-version-check install -r requirements-dev.txt - python -m pip --no-python-version-warning --disable-pip-version-check install -r requirements.txt + python -m pip --no-python-version-warning --disable-pip-version-check install \ + --target=./Contents/Libraries/Shared -r requirements.txt --no-warn-script-location - name: Test with pytest + shell: bash # our Python 2.7 setup action doesn't support PowerShell run: | python -m pytest -v diff --git a/.gitignore b/.gitignore index 0073131..0eaec38 100644 --- a/.gitignore +++ b/.gitignore @@ -167,10 +167,7 @@ plexhints-temp *cache.sqlite # Remove python modules -Contents/Libraries/Shared/* - -# Keep requirements.txt files -!*requirements.txt +Contents/Libraries/Shared/ # npm node_modules/ diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 086d61f..a05ea65 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -11,6 +11,12 @@ build: os: ubuntu-20.04 tools: python: "2.7" + jobs: + pre_build: + - python ./scripts/build_plist.py + post_build: + - rstcheck -r . # lint rst files + # - rstfmt --check --diff -w 120 . # check rst formatting # Build documentation in the docs/ directory with Sphinx sphinx: @@ -25,4 +31,3 @@ python: install: - requirements: requirements.txt # plugin requirements - requirements: requirements-dev.txt # docs requirements - system_packages: true diff --git a/.rstcheck.cfg b/.rstcheck.cfg new file mode 100644 index 0000000..1f97fed --- /dev/null +++ b/.rstcheck.cfg @@ -0,0 +1,11 @@ +# configuration file for rstcheck, an rst linting tool +# https://rstcheck.readthedocs.io/en/latest/usage/config + +[rstcheck] +ignore_directives = + automodule, + include, + mdinclude, + todo, +ignore_roles = + modname, diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f18f0c..df0a7f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Changelog ## [0.0.1] - 2023-02-24 -### Added +**Added** - Initial Release [0.0.1]: https://github.com/lizardbyte/plugger/releases/tag/v0.0.1 diff --git a/Contents/Code/__init__.py b/Contents/Code/__init__.py index 0992640..aabcd06 100644 --- a/Contents/Code/__init__.py +++ b/Contents/Code/__init__.py @@ -1,9 +1,5 @@ # -*- coding: utf-8 -*- -# standard imports -import sys -from threading import Thread - # plex debugging try: import plexhints # noqa: F401 @@ -21,7 +17,7 @@ # local imports from default_prefs import default_prefs -from webapp import app +from webapp import start_server def ValidatePrefs(): @@ -46,7 +42,6 @@ def ValidatePrefs(): >>> ValidatePrefs() ... """ - # todo - validate username and password error_message = '' # start with a blank error message for key in default_prefs: @@ -108,24 +103,11 @@ def Start(): if prefs_valid.header == 'Error': Log.Warn('plug-in preferences are not valid.') + start_server() # start the web server if it is not running Log.Debug('plug-in started.') - # use threading to start the flask app... or else web server seems to be killed after a couple of minutes - flask_thread = Thread( - target=app.run, - kwargs=dict( - host=Prefs['str_http_host'], - port=Prefs['int_http_port'], - debug=False, - use_reloader=False # reloader doesn't work when running in a separate thread - ) - ) - - # start flask application - flask_thread.start() - -@handler(prefix='/applications/plugger', name='Plugger', thumb='attribution.png') +@handler(prefix='/applications/plugger', name='Plugger', thumb='icon-default.png') def main(): """ Create the main plug-in ``handler``. diff --git a/Contents/Code/const.py b/Contents/Code/const.py index 02f3bb2..892c633 100644 --- a/Contents/Code/const.py +++ b/Contents/Code/const.py @@ -9,6 +9,20 @@ else: # the code is running outside of Plex from plexhints.core_kit import Core # core kit -bundle_identifier = 'dev.lizardbyte.plugger' +# plex constants app_support_directory = Core.app_support_path +plex_base_url = 'http://127.0.0.1:32400' +plex_token = os.environ.get('PLEXTOKEN') +plugin_directory = os.path.join(app_support_directory, 'Plug-ins') plugin_logs_directory = os.path.join(app_support_directory, 'Logs', 'PMS Plugin Logs') +plugin_support_directory = os.path.join(app_support_directory, 'Plug-in Support') +plugin_support_caches_directory = os.path.join(plugin_support_directory, 'Caches') +plugin_support_data_directory = os.path.join(plugin_support_directory, 'Data') +plugin_support_databases_directory = os.path.join(plugin_support_directory, 'Databases') +plugin_support_metadata_combination_directory = os.path.join(plugin_support_directory, 'Metadata Combination') +plugin_support_preferences_directory = os.path.join(plugin_support_directory, 'Preferences') +system_plugins_directory = Core.bundled_plugins_path + +# plugger constants +bundle_identifier = 'dev.lizardbyte.plugger' +plugger_data_directory = os.path.join(plugin_support_data_directory, bundle_identifier) diff --git a/Contents/Code/plugin_manager.py b/Contents/Code/plugin_manager.py new file mode 100644 index 0000000..59c5e7e --- /dev/null +++ b/Contents/Code/plugin_manager.py @@ -0,0 +1,60 @@ +# plex debugging +try: + import plexhints # noqa: F401 +except ImportError: + pass +else: # the code is running outside of Plex + from plexhints.log_kit import Log # log kit + +# local imports +from const import plugger_data_directory, plugin_directory + +# servers version newer than 1.13 cannot view plugin routes, maybe we can do something with this later +# https://www.reddit.com/r/PleX/comments/ig64mz/comment/jhk5jbu/?utm_source=share&utm_medium=web2x&context=3 + + +def initialize_install(plugin_data): + # type: (dict) -> bool + """ + Initialize the plugin installation process. + + Parses the plugin data for further processing depending on the conditions. + + .. todo:: Complete this function. + + Parameters + ---------- + plugin_data : dict + The plugin data to process. + + Returns + ------- + bool + Whether the plugin was successfully installed/migrated/updated. + """ + Log.Debug("{}: {}".format("plugger_support_directory", plugger_data_directory)) + Log.Debug("{}: {}".format("plugin_directory", plugin_directory)) + + Log.Debug('Initializing plugin installation process for "{}"'.format(plugin_data['plugin']['full_name'])) + for k, v in plugin_data.items(): + Log.Debug("{}: {}".format(k, v)) + return True + + +def uninstall_plugin(plugin_name): + # type: (str) -> bool + """ + Uninstall a plugin. + + Parameters + ---------- + plugin_name : str + The name of the plugin to uninstall. + + Returns + ------- + bool + Whether or not the plugin was successfully uninstalled. + """ + Log.Debug("Uninstalling plugin: {}".format(plugin_name)) + return True diff --git a/Contents/Code/webapp.py b/Contents/Code/webapp.py index 8bd4031..a88d154 100644 --- a/Contents/Code/webapp.py +++ b/Contents/Code/webapp.py @@ -1,6 +1,9 @@ # standard imports +import json import logging import os +from threading import Thread +import xmltodict # plex debugging try: @@ -10,24 +13,33 @@ else: # the code is running outside of Plex from plexhints.core_kit import Core # core kit from plexhints.log_kit import Log # log kit + from plexhints.parse_kit import Plist # parse kit from plexhints.prefs_kit import Prefs # prefs kit # lib imports import flask -from flask import Flask -from flask import render_template, send_from_directory +from flask import Flask, Response, render_template, request, send_from_directory from flask_babel import Babel +import polib +import requests +from werkzeug.utils import secure_filename # local imports -from const import bundle_identifier, plugin_logs_directory +from const import bundle_identifier, plex_base_url, plex_token, plugin_directory, plugin_logs_directory, \ + system_plugins_directory +import plugin_manager +bundle_path = Core.bundle_path +if bundle_path.endswith('test.bundle'): + # use current directory instead, to allow for testing outside of Plex + bundle_path = os.getcwd() # setup flask app app = Flask( import_name=__name__, - root_path=os.path.join(Core.bundle_path, 'Contents', 'Resources', 'web'), - static_folder=os.path.join(Core.bundle_path, 'Contents', 'Resources', 'web'), - template_folder=os.path.join(Core.bundle_path, 'Contents', 'Resources', 'web', 'templates') + root_path=os.path.join(bundle_path, 'Contents', 'Resources', 'web'), + static_folder=os.path.join(bundle_path, 'Contents', 'Resources', 'web'), + template_folder=os.path.join(bundle_path, 'Contents', 'Resources', 'web', 'templates') ) # remove extra lines rendered jinja templates @@ -43,7 +55,7 @@ configure_jinja=True ) -app.config['BABEL_TRANSLATION_DIRECTORIES'] = os.path.join(Core.bundle_path, 'Contents', 'Strings') +app.config['BABEL_TRANSLATION_DIRECTORIES'] = os.path.join(bundle_path, 'Contents', 'Strings') # setup logging for flask Log.Info('Adding flask log handlers to plex plugin logger') @@ -60,18 +72,48 @@ # test message app.logger.info('flask app logger test message') -if Prefs['bool_log_werkzeug_messages']: - # get the werkzeug logger - werkzeug_logger = logging.getLogger('werkzeug') +try: + Prefs['bool_log_werkzeug_messages'] +except KeyError: + # this fails when building docs + pass +else: + if Prefs['bool_log_werkzeug_messages']: + # get the werkzeug logger + werkzeug_logger = logging.getLogger('werkzeug') + + # replace the werkzeug logger handlers with the plugin logger handlers + werkzeug_logger.handlers = plugin_logger.handlers + + # use the same log level as the plugin logger + werkzeug_logger.setLevel(plugin_logger.level) + + # test message + werkzeug_logger.info('werkzeug logger test message') + + +# default plex headers +PLEX_HEADERS = { + 'X-Plex-Token': plex_token, +} - # replace the werkzeug logger handlers with the plugin logger handlers - werkzeug_logger.handlers = plugin_logger.handlers - # use the same log level as the plugin logger - werkzeug_logger.setLevel(plugin_logger.level) +# global objects +plugin_directories = [ + plugin_directory, + system_plugins_directory, +] +plugins = dict() - # test message - werkzeug_logger.info('werkzeug logger test message') +# mime type map +mime_type_map = { + 'gif': 'image/gif', + 'ico': 'image/vnd.microsoft.icon', + 'jpg': 'image/jpeg', + 'jpeg': 'image/jpeg', + 'png': 'image/png', + 'svg': 'image/svg+xml', +} @babel.localeselector @@ -99,14 +141,36 @@ def get_locale(): return Prefs['enum_locale'] -@app.route('/') -@app.route('/home') +def start_server(): + # use threading to start the flask app... or else web server seems to be killed after a couple of minutes + flask_thread = Thread( + target=app.run, + kwargs=dict( + host=Prefs['str_http_host'], + port=Prefs['int_http_port'], + debug=False, + use_reloader=False # reloader doesn't work when running in a separate thread + ) + ) + + # start flask application + flask_thread.start() + + +def stop_server(): + # stop flask server + # todo - this doesn't work + request.environ.get('werkzeug.server.shutdown') + + +@app.route('/', methods=["GET"]) +@app.route('/home', methods=["GET"]) def home(): # type: () -> render_template """ Serve the webapp home page. - .. todo:: This documentation needs to be improved. + This page is where most of the functionality for Plugger is provided. Returns ------- @@ -117,8 +181,8 @@ def home(): ----- The following routes trigger this function. - `/` - `/home` + - `/` + - `/home` Examples -------- @@ -127,36 +191,138 @@ def home(): return render_template('home.html', title='Home') -@app.route('/favicon.ico') -def favicon(): - # type: () -> flask.send_from_directory +@app.route("/", methods=["GET"]) +def image(img): + # type: (str) -> flask.send_from_directory """ - Serve the favicon.ico file. - - .. todo:: This documentation needs to be improved. + Get image from static/images directory. Returns ------- flask.send_from_directory - The ico file. + The image. Notes ----- The following routes trigger this function. - `/favicon.ico` + - `/favicon.ico` Examples -------- - >>> favicon() + >>> image('favicon.ico') """ - return send_from_directory(directory=os.path.join(app.static_folder, 'images'), - filename='favicon.ico', mimetype='image/vnd.microsoft.icon') + directory = os.path.join(app.static_folder, 'images') + filename = os.path.basename(secure_filename(filename=img)) # sanitize the input + if os.path.isfile(os.path.join(directory, filename)): + file_extension = filename.rsplit('.', 1)[-1] + if file_extension in mime_type_map: + return send_from_directory(directory=directory, filename=filename, mimetype=mime_type_map[file_extension]) + else: + return Response(response='Invalid file type', status=400, mimetype='text/plain') + else: + return Response(response='Image not found', status=404, mimetype='text/plain') + + +@app.route('/api/plugin/install/', methods=["POST"]) +def install_plugin(): + # type: () -> Response + """ + Install a plugin. + + .. todo:: Complete this function. + """ + data = request.get_json(force=True) + + install_status = plugin_manager.initialize_install(plugin_data=data) + Log.Warn('Installing plugins is not yet supported, status: {}'.format(install_status)) -@app.route('/logs/', defaults={'plugin': bundle_identifier}) -@app.route('/logs/') -def logs(plugin): + +# get list of installed plugins in json format +@app.route('/installed_plugins/', methods=["GET"]) +def installed_plugins(): + # type: () -> Response + """ + Serve the list of installed plugins. + """ + # plugins known to the server + plugin_list_xml = requests.get(url='%s/:/plugins' % plex_base_url, headers=PLEX_HEADERS).content + # convert the plugin_list xml data to json + known_plugin_list = xmltodict.parse(plugin_list_xml)['MediaContainer']['Plugin'] + + known_plugin_identifiers = [plugin['@identifier'] for plugin in known_plugin_list] + + # walk plugin directory + for plugin_dir in plugin_directories: + for plugin in os.listdir(plugin_dir): + # set default plugin type and version + plugin_type = 'user' + version = None + + # get the path of the plugin + plugin_path = os.path.join(plugin_dir, plugin) + + # get the path to the plist file + plist_file_path = os.path.join(plugin_path, 'Contents', 'Info.plist') + + # for system plugins, set the plugin type and get the version from the VERSION file + if plugin_dir == system_plugins_directory: + plugin_type = 'system' + version_file_path = os.path.join(plugin_path, 'Contents', 'VERSION') + if os.path.isfile(version_file_path): + version = str(Core.storage.load(filename=version_file_path, binary=False)) + + # the plugger data file + plugger_data = None + if plugin_dir == plugin_directory: + plugger_data_file_path = os.path.join(plugin_path, 'plugger.json') + + # load plugger json file + if os.path.isfile(plugger_data_file_path): + plugger_data = json.loads(s=str(Core.storage.load(filename=plugger_data_file_path, binary=False))) + + # set the version from the plugger data + if plugger_data: + version = plugger_data.get('version', None) + + # get the bundle identifier from the plist file + if os.path.isfile(plist_file_path): + plist_contents = Plist.ObjectFromString(str(Core.storage.load(filename=plist_file_path, binary=False))) + try: + plugin_identifier = plist_contents['CFBundleIdentifier'] + except KeyError: + Log.Error('CFBundleIdentifier not found in plist file: %s' % plist_file_path) + else: + try: + plugin_description = plist_contents['PlexAgentAttributionText'] + except KeyError: + plugin_description = None + + if plugin_identifier in known_plugin_identifiers: + plugins[plugin_identifier] = dict( + bundle=plugin, + bundle_identifier=plugin_identifier, + name=plugin.split('.bundle')[0], + description=plugin_description, + path=plugin_path, + type=plugin_type, + version=version, + plugger_data=plugger_data, + ) + else: + Log.Error('Plugin not properly loaded in Plex Media Server: %s' % plugin_identifier) + else: + Log.Error('Info.plist not found in plugin directory: %s' % plugin_path) + + return Response(response=json.dumps(plugins, sort_keys=True), + status=200, + mimetype='application/json') + + +@app.route('/logs/', defaults={'plugin_identifier': bundle_identifier}, methods=["GET"]) +@app.route('/logs/', methods=["GET"]) +def logs(plugin_identifier): # type: (str) -> render_template """ Serve the plugin logs. @@ -165,7 +331,7 @@ def logs(plugin): Parameters ---------- - plugin : str + plugin_identifier : str The reverse domain name of the plugin, e.g. `dev.lizardbyte.plugger`. Returns @@ -177,15 +343,47 @@ def logs(plugin): ----- The following routes trigger this function. - `/logs/` - `/logs/` + - `/logs/` + - `/logs/` Examples -------- - >>> logs(plugin='dev.lizardbyte.plugger') + >>> logs(plugin_identifier='dev.lizardbyte.plugger') + """ + return render_template('logs.html', title='Logs', plugin_identifier=plugin_identifier) + + +@app.route('/log_stream/', defaults={'plugin_identifier': bundle_identifier}, methods=["GET"]) +@app.route("/log_stream/", methods=["GET"]) +def log_stream(plugin_identifier): + # type: (str) -> Response """ + Serve the plugin logs in plain text. - base_log_file = '%s.log' % plugin + Collect and format the logs for the specified plugin. + + Parameters + ---------- + plugin_identifier : str + The reverse domain name of the plugin, e.g. `dev.lizardbyte.plugger`. + + Returns + ------- + Response + The text of the log files. + + Notes + ----- + The following routes trigger this function. + + - `/log_stream/` + - `/log_stream/` + + Examples + -------- + >>> log_stream(plugin_identifier='dev.lizardbyte.plugger') + """ + base_log_file = '%s.log' % plugin_identifier combined_log = '' count = 5 @@ -202,10 +400,10 @@ def logs(plugin): combined_log += str(Core.storage.load(filename=log_file, binary=False)) count += -1 - return render_template('logs.html', title='Logs', logs=combined_log) + return Response(combined_log, mimetype="text/plain", content_type="text/event-stream") -@app.route('/status') +@app.route('/status', methods=["GET"]) def status(): # type: () -> dict """ @@ -224,3 +422,80 @@ def status(): """ web_status = {'result': 'success', 'message': 'Ok'} return web_status + + +@app.route("/thumbnail/", methods=["GET"]) +def thumbnail(plugin_identifier): + # see if plugin_identifier is in plugins + if plugin_identifier in plugins: + plugin_path = plugins[plugin_identifier]['path'] + else: + return Response(response='Plugin not found', status=404, mimetype='text/plain') + + # try to get the plugin thumbnail + plugin_thumbnail = None + image_priotity = [ + 'icon-default', + 'attribution' + ] + image_extensions = [ + 'png', + 'jpg', + 'jpeg', + ] + for img in image_priotity: + if plugin_thumbnail: + break # break first loop + for extension in image_extensions: + plugin_thumbnail_path = os.path.join(plugin_path, 'Contents', 'Resources', '%s.%s' % ( + img, extension)) + if os.path.isfile(plugin_thumbnail_path): + plugin_thumbnail = (os.path.dirname(plugin_thumbnail_path), + os.path.basename(plugin_thumbnail_path)) + break # break second loop + if not plugin_thumbnail: + plugin_thumbnail = (os.path.join(app.static_folder, 'images'), 'default-thumb.png') + + # get file extension + image_extension = plugin_thumbnail[1].split('.')[-1] + + return send_from_directory(directory=plugin_thumbnail[0], filename=plugin_thumbnail[1], + mimetype=mime_type_map[image_extension]) + + +@app.route("/translations", methods=["GET"]) +def translations(): + # type: () -> Response + """ + Serve the translations. + + Returns + ------- + Response + The translations. + + Examples + -------- + >>> translations() + """ + locale = get_locale() + + po_files = [ + '%s/%s/LC_MESSAGES/plugger.po' % (app.config['BABEL_TRANSLATION_DIRECTORIES'], locale), # selected locale + '%s/plugger.po' % app.config['BABEL_TRANSLATION_DIRECTORIES'], # fallback to default domain + ] + + for po_file in po_files: + if os.path.isfile(po_file): + po = polib.pofile(po_file) + + # convert the po to json + data = dict() + for entry in po: + if entry.msgid: + data[entry.msgid] = entry.msgstr + Log.Debug('Translation: %s -> %s' % (entry.msgid, entry.msgstr)) + + return Response(response=json.dumps(data), + status=200, + mimetype='application/json') diff --git a/Contents/DefaultPrefs.json b/Contents/DefaultPrefs.json index b4ee560..43ab2ba 100644 --- a/Contents/DefaultPrefs.json +++ b/Contents/DefaultPrefs.json @@ -2,7 +2,7 @@ { "id": "enum_locale", "type": "enum", - "label": "Locale", + "label": "Web UI Locale", "default": "en", "values": [ "de", diff --git a/Contents/Libraries/Shared/requirements.txt b/Contents/Libraries/Shared/requirements.txt deleted file mode 100644 index df13dbd..0000000 --- a/Contents/Libraries/Shared/requirements.txt +++ /dev/null @@ -1,10 +0,0 @@ -# these requirements must support python 2.7 -# it is doubtful that Plex will ever update to Python 3+ -flask==1.1.4;python_version<"3" -flask-babel==2.0.0;python_version<"3" -future==0.18.3 -requests==2.27.1;python_version<"3" -typing==3.10.0.0 - -# custom python-plexapi supporting python 2.7 -git+https://github.com/reenignearcher/python-plexapi.git@master-py2.7#egg=plexapi diff --git a/Contents/Resources/icon-default.png b/Contents/Resources/icon-default.png index 162dee1082ae640cd08fb9ad994130e7979d2f39..2a99d447c8710c0a7d382753f3573ebb236f4a82 100644 GIT binary patch literal 3366 zcmcgvcU05a68Y!ZR&A#KFzhxTBQxw`xriZiDTS+sod>)qf478 zx;M9kwmMdp;i@7QX%eyiqeX{f zwtVs(Y`ZnW8L+n*hM!9p)$a@~SZDyHb`+jU`r;?}Qvr8^Q#8bkWeHL3U%=FsHLcXP zue?l>tq<7)1ujMR4TSD_GBK@!>8|p*1-E;JiSMXJN)ZAWktfe!L?=4a27s@Q<9035 z+CIk-TNmKZ9l7&xeCPKM6I%ucIi4yTQ!G16=)zXstYuYZQ#bXD1%^E;B5*eiMjZJD z0rpnC4_g-9hb@XPD=Sv-8-lNOQ|nn6d4iwBXa^$x_0tZK@9A2_I3Wxx%^TPiYyj0* z4vJV6dK&_pnNh%pQmha##pW`VBm?AY-*~JFi-a(8zz_bKZBPdvQ1lB3kWd0JH@E?p z6aaWE23YBU0X16y_}i2kqWM0*(AUKs;_Am1)1tV6tkt{^^_lp@9CcZUs2c zqzuAaBnbKYGxNU$0{+OavM?}xCTQ`(Vv}6Rj)VS**>6_SBZ*dj;PJ>f_gGTayxwn` zFbZ=;p(N|2)8X-?rodMCTGn}#LN~wc7%Ir2uXw^qw|&&}=3D!1Y0ye`Vu=+Tb|!kZ zC2%F9IK;73^=!^DrP7xA=ke5;!gG<8r1sLqnk@usF!v>eNM+02T|yg&rM#HGH;nA1NLX*AVrA zLdx`mVpS~DjE*BhV2=5FF53VE!>#JY++5 z9yE-&Ke}mL6MyZ3r{~RuTS3qrIgfC;%;xCgJ#A%CaH>xUVlb9gWweXEIRFL5WlEK>Rcu$eJUl8W#2k-3`4UO&4t6?#vEUqqp#1;CakcclYH7r*| zSz-Kn^lHe)Js;?3!t%+bORiq}rGFGdi5E}YYGqjx3_mi^rGL2gHuR@d1 z69nq%t6VE(c*2!d?S;l>$eEX&51OB*>p}hLfrxK1`R!WbS(J%ti>p$-%)u zQlZ0rAHNHq!uwllgol;hsGqG@A1+3F)K{_nTSm+h5g;?T)0v?c#klhdkmXUSA^F&^ zPidPv#o`gGUYm?b9Kv$WcqZ|M|9;VqCWSy1TLR4BV@(vh-tsl}^XIaQYdiblQ~2;% zNpt9%S3MQ;gnQLSB1ZxF+C_Ue-{qN&HkUFl_(uGc(D)bDeT zFMadH+6SF2{jVuNQtmts9yHx@ei>;5UO`cMZ zV0dK%_0vWxL)B%BSDKkylhxX>dp|hY$@D~e>&4FCCt?GGm%bc2N+*LNiF=JVKYI+` z(x_X51T%7tWcuxLP`p|Zj})7sdn!?uxB?^4&?k~w(um^!@As1-3cOnfdlsEw^(0sL%xH0OOrOT zVi@C~6cvv#&04w2D}Hf1giWS~X63`jbJ=`+R(Z=$OFZ6O7_Rekl7wJ&Tf#gb(g|g*osJv&Vwo4=Ks1G?$91a%czZhef2C`UON}3@KO9 zA(mSetq-k_4#yL%=J14nQ4&T?REjUra@yNBOa6FsA3ZW zKG1~%A{1M;m3{JfN{+Bw8C#m$yI8G=f3zw2PwCsAD+)6tFj6qL5z>0QnZA_l`2HLd zQhv{R>|R96{?}wVt2|i!^gOdLmKolHz96|rnK<$FfgGoC`gcM0=MsGc1*wTQf&!EK zL2AQ3Ts3-zyhZPwWiZfM6Tr`K9EcIk<#M5M$zUXZ3f#wlw?O;QA}4>aSWL@sy*Uz2hN5(ZX0PF7EvTb9KzpqU12e7@`y=~EeR<-*p?nxqiP9MRcz78I<`(X`UX~J&&k<+Dq8L*2 zoc$c})+cK+oMt5K&Nen>WPl%dMD$+9Nim&w3fSe&1TN!jCP=IIs4~f0wn0G=pu!@a zjOC+oj4R9$6diC@A>8}*PK^}*a#c~KIWJK>qOXSWHKVT`Wif+P8Bhnh9QfR3K6rHk zKc|5-S4AbYZ)jFFFp$jBoZQ4kjw(>cHAwr$Y)9#Gzv;qR;fX9Zmm^6qNoy`3k~7-? N4riThs;qqy{sI7G&g^t3fJs%r4R<30-u}64E(z()GbgOVUzAsoB_??vXB? zAEZ*Lbl*+al+J0YX^uYg`TRc9q4@6O_lL*FXZn2J$LsxiJzvk)@ws#2xVG3bsbv5F zF`eHJp90`J{J-CU9~R=5{OBzo@XG?{Q`!eXQu(Gn{N{V>-}HV1AUSY3a&{2_3&DwF zhFbXVU_Ai%@3sK^4L}?Kc>vS^@EL$X0Qdk10bm2r20#e_X#hk5;0b^s0KWjR1RoRt zWdNMN|} z0LTKM06-N0Rsfs_U;=<}0Db@f-|#yCHUOXmKm`Cp02~6K3jh`Xx&X8TAPqnZ0JuEX z08kG=4gehh$N&%oz*zwH0$>3^H2}Q;+?kSeEdZSW*Z>d+Ko0=h0Pq3e9{}V5xCX#8 z02ly_0AK*XRRD4UXaL|R0FD6Q1V9J?ivf@X;2;1m04M;U34o&j{0l%C0Nnr(08j+r zBmj;8Tn8W+02%;K0PqLk4*<3RpaQ@}06qY~1i%acIsB*r*a|=+0HFYw0BagKLB0=U=P4b0Nw&{8UPOfZUXQTfStH5 z0iX#$0su<^PzPWDfMWop0MHCT5&+r&L<4XDfG_|m0eAy|J^;@FpaQT8fLj2l0dNL@ z6#&EnupIzzTwMX!0l+W-=K#0|z%BsH0q6rj6@cFX_!EFE0Nw+j1AsdKZUDdlyaM1b z0A2vp0q`RLn*i7hzh@^H^ZxzL#>|I4P9G# zR}v5JzE!iW&+oSH#4K}H&dGp>}FXa~kMdOUH&ALbI)xdE1&@(0Li!h5+x}R~DtfoW_-#?~d=X)^n z#J07|{=dtGf6_>!m4S)XHm#fk?v_}Wh05oqAqi>6RJObjJIJx%>U(wcBFu5(4EEwgc%9vtYu0r*8b-!5E4+utax)sLu)T)v-W~pCoZ-z1G za&kR79}dV1*%*?oo*GBvBJOJP(f;QT-kt2xnH z^nQpzXEabeMovsj8XrTOs{j7!kcar_=g0*2%lEp-nuyKHO%M8u)X5yd?lDqDX)JLSsv!~{yX?hDbu}(#oDP2>OTz-Kru}l-$F~O?tJuJFYU{BiVUqdy$rSj{2Up2XFMs)KsvVzPNgVT;H zHcg3i`hCH1*US@jQgu@&f9K2o4H$WwX_=PW%)Gf{o$|`47AK08`NuZ1p;(`DUE~Ou z!pOJS6`Xkd0V$JBWHGpgk}EF6_Z9H$zKjrrdS~Af_f2VV#OS^vwVE3|2yqG3z5S}j zri>pnM%Xv9FJ#4qSgUhmQ#-b4e{+NO`usLsZ+H_lG$Zq+*bQ1X{+pQYS)_DQeA7C& z^%Z|8Rc*kW(1lAPIzo-&>YrMNdzWW2NUWT(a`=z@<=pI;Y|PWo@pEsDz6+Al@35s= z*r^*`o-`UxnKPf;xP9^s>&8#!6!rc;jVA6bV~>(-n&*iWx3yT^5Ic*#xhor8 z6GT=))NYNd=G^v zs%Bj}AiO#(g)9=rvgKtizZeVa9IcPQhgRriFfU5#y$Gi~J^h@NI9a`td+_q*16|}i zXY;*$$J}d2HlkKs24tz-+&Y@>QV4sIoGagF`|Lx8aFyt+Mo${3)or`{n71?#;%g2) zU#dDj@fXZvQ;hawLN1jNsiLZ`gWf8F&4Vi3D$i$I{r1)m@z$sCN4V6 zAbHy8kxxBA+d0&|HXZI7r-d0;R^xx1J88WLb-s$E-b=Rh5rlaUiVs~|%UKy{!u8I~ z{6-&mx3KQO*O#1HId|SokIzKp^$rX=2A<~bJbD4~=gI3IM@pXOu2`?VGyOdCODmuS)1ov1qKN ztIoYQhWuvU!HrW}n&l*HsY^<5QK!oD`tB~#aI$bW-Hjyk^if~kt<^k><$@U%X9`st z{$O8_&5kfrI}5RGYD~=cJoTyiIB&denjCqwonvlgKfS2{sYjp5H{f4-`{3)CO0#;+ zf(d25(f(P9c2>un^p|xj*mA(bWe{yXJT%N6cr9^i1NJj^lAHC%n%1;`ex6cNK1E5m z$|Q!dIA9IwEt@z>aQ%1r*2=0UMX(XtY@hNkO1zeGA1UT*BQK6P^m!~DAJFZR#ky%V z$Ir!>!m%x6&#H*`v>a?#i0(hXSrmMQC+}&M)dQ$=q_#(JCtYL4W|=~5;Tz_fOUtM6 zXyyel?<<1nsMG2fGqx*NgQ zznp(Cm!Lr()?a11Z9YEmwxCOp7hAWw-!HRLy4yiyK;xg+9zP%J=pIk~#FON_)|LAd zCl9__jXXy?Fpr|s3Ozs`pF`$AGM2s6wl*~H^lJP&o*s!d-LjjA$+p* zaR4u^bjv4Ji3cy_GsG}RGKMX7%xueNsW^6_RPpkIE&Y%Gg%NIRhIT9T^RB!gg2cL~J~S)So;CW72s$IONCOcYa(VuZ}XqG`&sgiJZshsWHB<@1K(n8Y+1FZ zZad4qob*FTFy0|^R=0Avv}=MIF(Nr+lG^u0V?>H0aMAK>&~+NBymBAHg>$uSp?pnh zvcpIb3n~atI>QiN{bveEIwiRy&pxkk$V8LQU>Z_IybSv@f!*+l-3||@VBR?ElF`~a@1tj9BTGeYpMNeQq;k?8n3PUa=@QG=c#ezPrj1u?{+@UOg z)6x>K$Xu90`PY~HKChZ}i8@|)ktJ9EIUJU*Cjx&B^E4|Lf8>H7koTfUCspl~6gDd6 zUVFc?^%0+_!{m&*+XO(F>tEY0vAKK}S8>l0cHo99x!OAEv>JUc#NYOJr@;6XZU>cS z)n6z{8#<+4ij0Yu#)?vIN((7*Q zUR$6nH_^)(uWJuc@k{OzM2d1wHrM(U&@YW*3ghe*Sssss863{gWTg0Ix9H*8(hMsF$tEO16y*Ga@6|J zqj)Qva^Nmi2fH0&p(>2nceS{P)J|z7#Z@TKJ^W8MIT&6;!>cn7j_?dh@lzH(ihGo9 z%9E#qlAD?whw8JudXx%y+GWVt3Cj9IrKMvm#EL?-cV9p4tEWyIe+j*Pd%L&B)oi`V zH{=AYx1J1DQLHAVy#}g;9W3<&;TD|x`V^#;lQj_Cl&H_~=QZPQ&PgpViG=K>SlBRD zQQs3gI~bW`hLi|=;`TaT@H27++0Nd12MB`qb@FTIpB6k7d?llG1?P@ z9JJ?QCCu}K465zx^^*M;r?wO8Afd%picIOi8}U*$D~FzOJe76agyf4m7Rphqxx++E zp_zI>Se$QIrN`u91=8}(L;bYfs1_Ovf2TfrA_8{7{-Pdf>3*>NQt29m$!g)#+xAta zn{mGXXV!sy;eHP=X~k#8(yHsaL{K59Ui1iFag0(cLX{d?S+2wL+{dZ##9Fqha#W7R zxN9aXtQ-F#cmc=rMW;kcMfL1StdF{qSWub~+c4$PaBjq6C>ML**KCQP+Px(|hG3tu zijnKgbYFoSj}lZUeNjBPdmcnx!=hbCOItd-*gWn)#&5pjMZ#`k8+1~N_?VXVHJ0)I z#TZpBGUw~;uAxVfF(mbEvTRz;%I$?@Pt(H+UaNME*QoG z8Us6n?6P;va6cXIqt4$oC}D#68eovhtp9s*JD=m7XozVoxmMa8YMKL2{5vOm+E%AR zqXFS=66Qb8zXXpF_H@@QLvQU*HNEA;P9PeA0x;1>0eTD}7# zrYsTB1;m&qxzn^$Ok&`lY6BT8bnCIxPuenW`c3>YI0MgHG>1~FSsFfl4m6)D;*iG& z>8*7&hD9XAk33wWus7{%23Yx6-#YWx;BIA;Ub?v+r(wPjs(+)%#+> zi7!M>6v--#GHeE$6i+(k>W;D4%9M~3q^3jDPgr^Ksk=IY$1Q=ZtTYVWr=~jvJTyCf z6A~AsWavhpq2i{5hXY}|&RRB#hgUVH?-AkML#j{j&rxnZ10pK6me2itqUr!?6)B2M zd3URT>cm{@@mO+-ZNP&x%-nnH<7*M+4Be}Oz@y_?QX$I4)N-D-f{*m2x|@e_zU?g- z-(TW-bkKC#=4d%kU{Q|68jjR2(9tf&t)p}O@ z8@(meD$&LlDfmcsFE{yX-f?a5(e-I+espwT3t#kb`$W6s%)|UXueU!j!e*U&5U)TT zd9m1W@RS?}-ie2c_y(KagvouXt~MKyS3~ulTz0JTY^66QRM!&QznDX@es8w1j(5s_ zXaQ!8_LOz9{xOgcfgVm2qx-xHYLA~HJqW?Pyr~MkYu{!c9fhLfRsD0>j3nIprqo4& zg+Gq~bA%WU#J5p1s=;?-~sO?Jdy zDG=miAC<;(j9OZiVsQnTr@{E%g2%`Y5SyK4%~`VyjrI&;N6jAyBgtC-KMf zOT%A8F^yLE;LK-BKIM~Su^U094O*A3DxeiD zti;X)&tdTyW=cnx(A$f(4QqXlRdtb*ZY*5#n4O!O=KiSaq>G}J;#phR2DpGIod^S zMpZJ;ElvDI&_}>Hop5^Fjpl#%q8w7{_CPeIs6c;&3DxGoQPeaNeJ#dm8#PYmY=^)c z-IT<}NzQ%owM~oeUo54z^D^S9+_SyRrj1HrluVJKtTVAr3VX*>WwIut_?Z=cQlw0$ z>E+kZ;w@5m>*L9nkW%jbjJvTr_4ThJlg;lK4C7pxUx%Jo&0|2ZrQ-O*(HUjfS&ZYz zHfE<tYc^sNSG&?Q z=zNbX!bDp09fuM5c1DzT?2GaQS^P28`mln^&CZp;BjeqU!^Hm^&h^vQ0)+3LHaKNU1D24J) z5qn+ib>ze~-qBAG7tFXX1^X6S7 z4Y!{xnC_C2^Y6gJdm^>ai$Id_N0;_XZo+})f^_nqO@V+*KQCV!RxpBb%rc#+ffE}YP2OG(cUBTeOEw$KNOmo;bj^K ze>XSYj47C~MK9O8GZf08a|I0AFz2!0(R~R1AQ;TZ%CFjp4Q?^n`D$IkWIpLiXI)!T zOT<-e;j$u_A3JDD&>x!{PuE)zxcy4Si^Atc@H6Z^?3ul%+2Oii-F?W@dcpxVKA#mAk6H#P8I91nsAH{{}~KM@SSVzWjz z5Fd<4(#iN(pVmGHp-lDb!+By}1`+g)VY$hB8K#I?U1rjlWy2?S;!8Z=eaewO_ydQ1dkmQ z-`0p#K_1l)rBVe$KX=$B(o3o1Jjpcs##d{Sest3N2^vzUfcm1Gb8Hlb zCY~ef0-!Lj>ik;EfyeX77|sFY>>+2PJK~V-c(k0$;CG_Uq!YS3Y+t@;n&&@6B>XNC zlG_`nwby8d7kGzWxt_5zi>iOAn0z18-Kg0||3iE|HbQTK&Mc)Y;uyl;V;kjA8O;GK z{mxtXth=~LSXpSqGk7Anm-d_}FF3>TpP>FmyxP?%H6DRH;;AYo<+?+m8HQho2VCO^ z)ey|n{-`J=x9~!^)RR@Rt0xQhpk>Fdm|*9#5~x$5g&cJGv%zp%zj zw2uScMftUtiRp7>c1Ays+}m(+kWoqr?jTte?r6*UBV}bo+e3I0=9o6#2$^ZrKO^nO zE)`K%6P#J8997HSJb5Yp)#Z8FDvxAv&CZ zSjT?qdGZEDQIt`{8>LdNo>a3!;>KwZqJ1Ap%AnBXjWLc%C9nRf^STVTyO{$u`ff-{ zdBL;X+=@%H>Yy-6IKz|vz#^U$SxuqzKoOL9##v&bKH`A;aL%xWV)JqGI+1S{nY$CZ z8DlPJikrl|c`bpj5DI-WmR5Hlg));l(=yX^(JVJ=?%T)lCt&u06O6}<(e<1iqZE64 z^`z)>;m#I=so;J(H?tormk4yNO*i`yVs|m(RrHMzNt25y>4+p+AZHCVD$m<8!Ff+hSl7DrI4 ztDS@h!`4jxmke5Eh^EK*)zsQC)%%L>h`*GszUPlw*^s%3@D5L!7{jcF{B83Oeud0T zq33u*`=D{&aqlD^Q(dTyr@AM8wbRISNb&bEI)Ex4FMGcpD|So!hCFW3EY`1B0mm}w zZ#Hgb66>Kslux_{kktM1GH}-kR2}UrwqZC_A?NyW`YMI>W1EQk>kSU%Ij~Ph4(_z2K*= zdGrgEQQrr0m~e7mAZmW#gnXjegJ~3)^V_15MLS+p3sBAy>Ru2#z&^#1kim@Qrt=O) z8?k==!Z#DmLnGEro%-c7!S{^Yp1Cx8^Hd$lTnfl&bgZ|0P{qsGK8p;q4_xPnNH#s0y$0h%8tHlRLzf5gYfFS`IEilHRb*){ zOnAQ1Ll8o491qY~HphqNByt5tR8{gSBQdZo?l%@?d=d>wFD93Y)=NIx(3pNGqoSN_ zmKW28FYb1J1cxEH{dt;r#LrOpJxEMUW>n((Q4cKU&Z6mXY|gx=wg*3>VYhEnd>6dz zw&Zg?jHED4y!tmsU}7WBGV{?F2cujXcaGLi@ajLkY;dkQD5qjKHrY9Q=3kA8{6$&; z){U3#o(GC^oAD)}XF*Ji4Q9*uHsHrcA+q}5$g{`pm}H47Q|O$go(dG7aaUw+V)Q{R zm)0m9Jc&9#l_$cKZpMiwU-^THF6|8^|8ZtsYslzr&w&dP?Y3^ctCev(-MeW$`rW-3 z)QS^udLhX+x#0Jhk4e;qoACNVl4-*Nw*|k`G`gk>g0t!}rM^N*>y9mNWZc>Y`}1iL zPT1(~(%zhu@*3)6xF%?)#Ak_pNX@1^`&oq8y`i3y6?Xkfajbhr@R352Ak95jY6#&4CruSi zd<3QB+pUPLn1=YKAUta|r)+p4XHgq_d;o1xu)voO?}w7~6l0&Z9(8oMTk&OiCC$?W zbBktKLY=-_llZX1pIAPcI$Et|zDYqM{PfLlW8kS7=*5g0!*|S~F8ewi;t@n^lIqbP zt7{n(K)%7c7mxC|H>Q`Or$;pIt>s8(_waPtwBztjm)3w|HF{r#n^Ur-5B9;av9a4F z+BHexXC6Wkr2a~}$6vp=|0{S(z(z=Ilh16m;jmt!EwY(yQ*d{k>P3k4uBf|0fM=+) ze2Ev=d3Ir5wqb~`&?MpX6TW!T#hr@9U$!}?n3T7Sn$()?XXloL1$X8AE($Gf zkd^Ut=WMZi&ft-sWl=pn8huFPIQ@{oq+ehE0B7lIlUaOejJ-r|0I(h0w=I5M#wMQ!*^<&-|CsLxDbxP#?a_m<37)ry+b`zJuMgb;|m zJnNh?Dg8-9V=hP)Mn^xgiTFYN^LfVPj;U(c?UPuk`qiE+E|MehUq`pDSXd>^)s$%oT^YyXE!;)v1Q zPAkyY=#x2~>X%^|>C=Md-)@a4Bc?j$MSrcJQ$&gUE}xO-tyjg0TbX5hXFgl$q!*JY zZ8-zxTg_xb*lbD~c5CTCxzOPu&3xFcyFFqan8>2M3h8IX4i1F5la^;oc=O4vSuTRA zLu)*w_KmS}J=0lVa)WpDA7DAx#4n8K2Bg#(k>YWV_A_d3r73*E)yT8l&&!F};)4*e zYuL51J+D)SwEC^xky4tbj9bH5=k(WVh4dvkUY`#=@R8HUv;-B>LAm;ilI+7sYF*^z zSPY+(GXhy%J?PE*H>9U~+)7k2rpf6>UmPC1t|#K3bHJ+ORYjd>=pqDa`qTwofSNQ1 zm;%yY$*fetvXU?T7>4YBK6Zenpw2r2puzA|xpomNZ!>rX`w zj)0LjerH{S2rT4rI?g4(>i(W}^vHo&vHutl&Y@vO#rlw0>xdUJV$$Zx%4K;`+nUY? z=`E%|yLR9Xc^uDKLHv+kuF0F}FOaTl<7rPFW}iNG+UR@gOta7&=)$djq(t>Hg11Um zlnP#9zC*rF+W%!@8)k|A`M%9JY?|liDvhM)r3Yq)vhv~69*r~5k(5tAO=}O8%_dHD zUCh@TQEX?D*DX$3E|cIB9so^2o{1e&Iz~6&uXc#M_I0itv;kYQ2{V2axqBq>@PD`) zBvcAB=7f@jD^j1I`m)q{TUv={X~W~PD{DhtsfM5alfMkOBBiyl2DBwYzDX`!^}h^L z?K4k%#J%4oorJ}4T{d70foN~fZ2WF`^=zE;p5Du5E&OIl zLN!+p@^xG8LJr>9gewuHL~>D#n|68`_4a?*EOm4S;q{)58Z3xwT`x*8eB+OCRf(PMf?CJ?SN|bU+=W>d;<=OH{ofg8TP>TT z@N+OAa~?^#=VibvRQ`|mk^AcCnImowee~ujJ`VKAE_B@pb<}lHT+97_KQ=LqO=LW| z=cUj4j*p9?i5Ft`@d;(y38t~|J6yf$$G-Tsxp{H@U_669KHBO%r97esDcP!JqBN^D>zm z8@IL>?n0-@`n2bmdL!c<>Eg$1TtH$4bohTyStM!rgC8kZ{@1i@V{{i9rHX2am6v4X zThj54jM>%BX-XhFaIv_i;dNX03t#uu%+5@Py9i>k>b&E)77)X5E%-_*qB|Kkyme-Y zI2sLVhd1K|rL%~?CsN9XgC1%8Jp4l!xe4D7V{(k{K^2?1;o&!3+VO-!IJFQqZ_M=i z_%U5{79V($u9j};cRcoripO7{qUf$-6mQB?BCoWxOKcYLwr}Jt&$hdY_?t#VI=oBz zrSv~`tA7o_Yop&t!PLj{w%ZCurYk<>H-EyXWUcCAv@=UXSbaEHaHJCF>Roek;HabC zQzZ^wMcD_14*swSt_`vG@Qw>|f1svx_%Be|J%}*ZW-#|=axS7hG>AW=VfIaH+_dNH zsm4ks2?yMZ#Nb!;VcfwGR;RwOH&t3ONAMoT#&~+hYo|(_b0gv=G z5ZKWNbA`QB=k7BwTD=*~Hl-l$73w1;iC9+o&2&B-`BopF~W}ayzq+ZCb$AdhF7gcBtF(s1pWHW@I z(B*)SocD~H3cSe3duPad5%JnX#|!TiZOLR^IB)mb*yAUgd0KuGBW6Su5?p)eCDTm+ zHp4CM^%El-?K7fz-=N*|B8+@W(>HoD%o)$z@9+{(J)t8Li|lfnb>}s7e&M)yqD44< z*bl1{3{ULj?--{BC5qoLbNlts?IMyOnX8nWMSivCIOa*^ygoDJ_P>UQCnZU(-L1z` zxEXgHkg#l>$BL3Iws!O#P+=h{yE6N!t$xc?9xsT82Yt?r#)d-|Uy}^KEp=&@F-kn2 zI&nWb&Q-lTU>_gmlM+5bZ{9vdz~_ALj<#d>p@>Q6=iEI)P0oD*GXN4-AG-32F=-M* zjm5ipNYHUko*rl9zNmu)AMqBpoK4O8+niX8|CwS`tNv&>)XcP(_!%2Iq<+w$#_qHT zEWe_%_#G;RjCn?Mg(nzPxC1xLogPSb5>8;<@&rC2$Q7{8c))V%Y7?IIOO*1 zR5wqRSz(x# znCei@_w$B~wX07uidYz?I*{V7&Knz8*=k46ooGRB3EQxq6Bsv?k|8&DNOy7(1IG$K zVNPJ=mdQddzLFB&xXef!DA}2d|KjO!b@@D-m~~gMhEHhFgZRYSYwohfpF41Jl981m zS@-sd(L&*sgSZlUP7Y--VtiBVY+-4s8sgWTg81G`hWNFl%^?;^V=FB=(m!h6A&0XA zoshl1#FLW~=*LfIh@sm9AiLp7?kR_7=S{jSl+?|-82uN^pJf&ov=yJYnah}|Qcig# zJh4SG@u{d-zH-F!_QL`F9n6XkxMyOKoO^Oo+(#U5ud!qJiW;*1!9vu7Q` z6>_zyR(ByDZ4a8L2s2p|Bzl$Pkpsu;sWZkj1Fvj#Aw7AB`!I~UoVe)D1kICKQNojq z($rGZ#F6$0bs4M?P@pH89cG@HOZMKFlhtWAPnuk_t)<6s31RUXT&TVS94~%*QWGt z24N|2@gr^tnR}^NluLVKL`u(kxfPColzcxT^w$3lSQe&A8J5%MRs8UXQCh@F2w(@M z(k>N|q%P}pHV3$0mqmyE;46{P#G{ZY&j?!=xl9Th>%!^|Kof=VHnvUiLpkU(6aLvy zXGv@N5Tl0J3SG=_*Kb6rm5vmtM0m6~ zkn+6BSbTQ|x3fNj{BkSggzon-y>_-vvGsI{hEs2`I5N{Qg6;0@VGOm@#XfTn=Xif* zjg;OFsvWZ{E!|!J@qjD0w%1L%O%`i`^3e8twBEt>6z25B+Gvkd_Qh!r+}dZFL! zUF~;~Yu|%S3_6gr1qodL=Iu70_B-Ijc|JBV(-AXyFL>Jn*+%YjC1P|qe1)GE6_LOx zSfqo4k`ubaMDdt#&DzL=4(cXCyvMW_Nj=UJ`(RGbF_>+jF`yk^o*(~fkLhHdt17Ng2u7xp>J7({$Au;A<-%09JS&f&&*;5rM#_y;o2uu%)ql2`t2jejCR zq{>W$SD2J5Y`?1E3>VH0R9t7iIeTV7z(}7OW|9n;Uibu6E=Nw#=rm*_@ zi1FnfsRQ~`A2{@8UfOoZp>``?4O;lF=9%K63 zx!vH0$yf|w`#awKbY_UvFRzMrFre6Y-#zsyqw*?vcczejCGA8{sO!;h{5I_acEj6z zXK=3Lr9$do5Y}wIBlxX{*zYcgzeksGJ^t|#eait<%U9;zp4OEqwfg6g7nAVdQT%fy zoo3_;j|&&O9^5!o=XggzTBW)8gNI)s9yrJ9Pi7w7mf}4+d102l%g8E9g$Pl#NOoY` z4~!q;eUBTGdO|Q%m@TYYhktHW=e~x`s&lZpx*#S%_SvaOk%qetO#Ip)m0;YIa&?Am z&>UM;mU@0yb1Y?LpeHg=m)LA0t8Tc^o4?bNYm3zm5*1d(+})@hMmz)^mf2hcxGJ4x?*I}KL_lF za?`grK`e=PFW{8}c?_6IsmB7S8q$`N18F90NbjJVP!b&^9THLwaT*=D_Pob}ojiht zpeMP*0$W*WjivPJGCT%+*h><|+VtJvj?T*^)_!(%n@@JUK>z=55e=DjrUTeQh3r0; W${jTP<4pX6O|9dHlMeoI^Zx(|w*_bt;;8cY6ctySEce&r{ihEW@jnoP9fdJM$3?cFd9eh-TWqzDG_#I~sL-tF77tt`7&z zR$FgTS|40oe4@F@IsYf(R^;ijR^z-sdH?qpC%HUEKY(*PU-iGTL93om3mB}K(MXQL zivF(vUk%8A{jYQhrpOBd;%&>)p3&e@{#P*bV?&?*PwY5DUjrC=wfVL9{_kPf@^qLg z82^>QR}V*vN90&#TClzPuMma^VgK(`toQ<~XrLRRRJ%y?{}g=C&VlfMr{Xav;Zb64 z(E0>8dHheo2kk~^|DStDkaJ>p3I4sB-ub@@z6PWS{_j*aH$wJTgduhd(30W*s;BZV z!`S`TEcvSc9~x#%J0MFA4TFe@+P-`DgDe-byQR*nT9`A~O1892(mSX8WPIYP{%?gA z%GIaziz_Kb;5#$0)DM0CPg)Spb}j}W<&dGna8@R@CQEUdfp%2pJeKNicvAK#hZ#nx zh{Ns|j^DVcR_h_eS3d$Mh`qUp){mTz@LU6Yp3QaE);_y?KN9w53I15+d5eqhCj;>J zq94sO896yxUSfv(EeD!f<7^8{kI#PwK5k}VILwPc$MRj@c$BxN0w}CET4d6yEucLC zQ*TErc8urp{3sI2pI=8xa?K?lf~wTwU$7?{@N8xxGY9c8^Vv(p)vhyG%%76l*G=e% zD5NZ}Wa}2_zuT86VWL7gQ3Y!j1}L*@3EtI9^>Ra69;Oxx7a`Z1QFIEpJ2Uout z_e%PHso*(hXIXu9_i4JZuZOok&oIc?5T3b&`ZVpEYNcn={2>tEpiXly#W|%?&kUSo zlJd8(xwHGY=g0!1TmSi{6N8c}cqWilYFLA7r##rqx{R(@VgS-lKx42*sN~B{`~oiH zD-l2A6#E?!akq%;Sywm%<>BXdb{S*Otl;L($;im4_YvSor@srYkaIh~vr8!Pg6Xr> z(Bo;g0ne7^JAA~BPrmuz5Lh1!XcVj3#IlF{dedN?0uDn^TG3#H4N0Y_iB~6@t2ypA_(g=(tDIOtdFZ88{fTXw(`04#*`Ez9*wKY`(je_! zJ%V`ztc@~-abFx=^gqIrh94S78bnd!F;rnaTLUa4P=xeS`IrAx&9BCqz}>#Sa7{+P zgEgv-c38C_Y`Fq{N6zsXz{PTioj}9Ho>`zd?Vrwr-xH-D4RguX>j$aLanHUqAhwey z?H8n`%rm^`F3*7Cl!=yE5oF`fl+#R&kJBsm3EcT!pv_Pe7kMdzuipMvOmSyex#Vwq zHLMq>QoM_`A$|qFt9Rcb3h}@YkPRz$`{j(cQk`VYj^@}wH|3HAm3VbmP^S6JSyPG+ zE?h{r*ot*FSBba6&CUrbjyONPbHRPitG`Q#Hui?%#WVa-aZr6P%wfQe4J?D}Ggxwj zDQKnVwpb5zn_mqN!I~)6i%wqjBbc4H`YUa~>~?>gCI*EoAcZ32 zYg~@r`3ZZ7Pp~@bXtz@>`og)Gms!z~Lxq30r9g_dZ^m=oyZ&XnFAM887GtDs8| z)kA1*{}ToVCu40uyw`1f(Ds8{I5_}zas&8bsaTVrbwQ3^0P%r5x9|J;c*^)(L98I-Plg%#mct+x3B$rl2IF ztzGrsABgAW1O-g<#X;iNP@H)0-#yC^UY#La8u)N`O{I-A*3WXh8u$_mT#NO$4|sRj zKH^v1_gV0a-~wHNKy!obPl!?|0M~EaS(Cf^=mEP}HuiR91}o+m7HjteOS{1dBKHzb zjT5Clu%imSy8xuSWvlJ!NkZYTQ})M8^p={gHneK8dZ-4L{N(VA43L+>nNonzC$wcM z@^n{@P42u5V;Ad5d^ow>`+sHBgBOWE4yC{Y)NSf6`F7Fid>uhWDQL|lsK$Bq&kIfK zb)yZ_j`$APH+lDQ@*0Jj+R_6M?o`bzs%%$o2EnR}8l z$5N(E;X!A3tg{|M4XU&76NyLK!c0VZNG8t_^xRh~qN|NC6q+$Vyabn^1ELK~v+>>B z-Tqoi0BP^}B&P|r|84E~t2>7I0cdh-&aLx2It)G%7hh^DRpB&fjg0SU5(=8VJA8~W z3V+jK#h#s$wO^#PUa_uuXC~td12)`R$9~Kj#p`Oiot)Zp{kH|&>TwR58nk`ytV&k* zBFo;Cq0?pi%NW58NBe&yA*dLsKs+1V%A=l*0l0^wOK?XEv%m}FDBNrd{LBS)zUe9A z7xxfhZl+XY$h3dL4UMBxu<$f=e0*?!e?QnXuOTSY_tw~Zr*`$hj)E$#*fINTZzizHawJ{+(GHenbna_1{*}N;LeXtDB=~)>UH1Vb4#s z;#1I<85zy4T6sTrxxJyE(D}Q*z3yCfj(9`33l{V3fK{UOjI4~@9CJVP(o#FPgyNHP z*z}u~4U*{xun0?WDOlC{2N#1aEiS%>&|ExM_CMN|R*Sqf+A%{jXJlpF9|h#Dn5GH| z<~*IlOAKlGHVA}U0)wRA-V8T1FEU$Mnj*8pq_I8ZRfH zKS=as)xs?i5Cd1Dxvpr{+cU1V)UpK+zYkvj`}c1z{gPJIktJFo1q9A~v@O6czs}BT z<8p#y4?rl*tzJ4t{6vU7pqZ_Yez`LidHTOIHP&WU(=CP3YdmnCs2BB-nE&&bUM3+>ku3Fn%+jtcz#Gq8MZ{~U|v)k%h|>5D4wt|mN+tRX?78eeX7u4AD4r5Ct;f+i{_p;yod$*Aewp& z5Z`nqfHiFD;`sjr~1)oJ99>TMOKg16LTI5Cb9Ne#pgT;9Z*QY5M9*McEn3Pnn-~4Ixx%-}ck8~4X zG}U-WM6P5E3F-f4j%y9Wb>=H<`lVgD%Q0aK>Z8Cz{k)csmw)2sgdHai$R(uE{9mzm-R(2^&i>^(c;Xskjk5^*sF%zq8E`zAL1uGA?+&?U=%{E0t_}s zvA*kG)om=y2E?}D#QP%uQ%-Elgxoe?)2N&-@2rsFr ztC#8nDDls?2Fx+C7w)h^R?!aa#|5|d=!2!DrRpKTU11Yi0tSAHZoOcwJsiOcVY6Nt zViP#WmVW@`#RZAyRCxwUs1(HQFgON*d9k`}OF49XG%rk%ePFhF+ z#YJ?}q96Zr;M;>aj6)7!4uNln8A|42owt+oGzP5vlTB~Pq1M^B+Gmf+U)ef&Mg|~* zvB4J7h*7Lc9t;zfB|rNK7T==WNF6nn6mwbA45H#k*{%$0m6LR;v!Gl@(BBY{A#`Ej zb-Ahv@yNfhC+U5G)R%vist+|$n3rdFIs2L9=XLgkEpQekAVPkA4xfd~FGYF~9nR^$ zWqb|YxZLOWdh^DaRlZfN{na-noRIAc%TMecoa8lRq9w<{f2U2aXBsNzC5;{0-0>1S z`s}bKjfs%niiF^zgP@|Gii=LR1i>@FVZOS*H38xI!9) zIGrwpJnih=9RZZQ{!A7Z;tVG%z+v(W$-~u#S>UEmH-vaRu2CwE#I_lf8+YkgnsQ#Q z_C-npGZq3yO`X||L#4+Nv-QzFUpP`v}m!#*xKWSjUpCzqFggvcE!0$U> zZgk~P@l>S2^iND&BYmX;#Wlm0uTov|<2aG3a%CytUe2TWy8TVw?Qs9}K$6gDYL> z$xVq}88hnr9{%de5vZNf(R^b;y)*sf_EE4#uv+kwhoT*uTwg)*$$#BA&7;AvbmIQAWX(F?Z<62?eS~ANaU9~wH>}Rp2`99U25E`zRwVB~z-vpA@pY~-KeJOC6?Cy))t{!~8+rNk zSO6rjVw674njj%BBrdwy`^XabdgACW{AYHm@h5VCvI2dP5l#GO zDloUu=MK1 zW&xe`w|Qd|N#{aO(07K6HNCYTin4>5X;hpNMmD)eXs5Y;PvktuchvXy(Z2x85+{>x zkz^+qTK*fGy42z+tyIBGk4gNVb6AKMzL#_u8>;YC?0|LO(<5d0lgD zhmWhB=Vip2MRQ^6bLS&x=i7RB^+9%P#B^GcdrPfVob{%lbaJf!Px7>rh6|9|l3Dk2 zR?%nyqWzQfs;4#;#b0Kzse)88KSh@b1R2&vBxn5ieyOj!%Y`R?U2 gvK#)n4H5 z$ZC;az#zgrnSh4`50bXhOJ*uwW-9F)zy)EEyLl;~ z;kvNqeCA$%dEt}I`h_vgoJszz+@vM-qHn;qny!d!wc&cgD(#m|G^tKVh6 zC$h3+y5*wYVp(xSJVAW>TZdMeh_^L;q%5YG?+3TD6$qaa3>%^U>3rzWJQZxZ$v=dy zeC6MA{<5F>tK(WuR$iWQ;304ma>Sb~yv6h|%;~mEs%NWtafvbdxYnNASl(&P{!9}h z82akYxAaY^k$s~zdivq5UMyzhf_GDih|*c)C$d@JGBjwZ~q* z-M*~1B#Bn!q#cmqa=Jh7(82%#85TfzYPM=^R>-Hyl)x!V%-*tEeZ%r$wLbEv=h1Vj{JV#Kh{c@~?ykjY@jTzvYO0De0JrF6o4V zJUF)--oLC+Kfd~D`1|R#V(RzeQIAzT77NDovVPi@v-12bZM-RU%4?2POd!Wnij$`x z#62=4%6$effK|eT46xWQNwZRiWPGJzYLao z;=9fa_k}fOJ57u9i0Ga0y0QHxB^C)5{ZYx`9||YmJ}{Y)cDaXJkV^ZWSnSW1>qm)R z*{u&YjSiANK7rsSxXa)>vIsn&E#(fmW5>Nj^4A_OSTK!fULZ7A8= z9{YI+OV{qe`d4%i3^IDjd1}(qewe3A@Zq8B79|)9>&Oc^g3ghA$i9TcG*^EEry-cr zF8q#W|NafjY^E;!^oa6H_ScGnDXIzS&7ZHI&_$SKOXG zjh)+ss1kSfi#dV5w^D}{VQNKW4pqD#WxZ_GoMH(h1&>j+-F)_+7>==S+pQ!&@-8D> zh2G~|$4)+9tlsNBzFh}{_aFMC9E!lZ!Rx3m+eSB&3Aus$rUm^i`v#EMHKu%SgmhNo z>JKN5z=lW=UaL<7&&5T#l!r~u&Dp}&pQ6VjECgvkmwV^oZ;n{~ceeG@*a(KZFJdA> zcDE+|wR_EDlU@B~;Ri+K@qQRKfsMmjITAs#UfAIc&W&XU^?Tcl1Urk`@XN3<;6dkA?q?RlMCHTzC_enuNTo5k!H`M85 z{2ig}^RP|blFs0;Ls8M%}?rb&VkAm&bc-n91+LA(Kyp@C_rHDxS7$3VZIhN^uGkfcd zi7EXSUfk7cX464wyeL~}`cR$r%N6ui;J zzjnu^hc1vQb?`GT#a6|HF9z}Hk1!LIK`C?yMUAeVGqOf4!$K%>p%TOX0egt6zhk}x z$W{ks%QQFi=bcO8i*V4E(5BTj=(aF!Ov{WEXG z{;}Pg(^PxZWY00xlC4mX?j{9M1T`C`&ygI7F$&ty7rhqxU$V2l7p!K`>C`0(|v`}C~RfjCr@d3UbQ znj%)H$jxf!^=d?aVv|gh(FO6a(x33I6`Xh}uRPKVlkjDf#RA*-Dp7C?-M$pH)~`Zh z1{RU6is~wkEw&wa!Y1GPH^)1HJ2GEV_{VO@=-%}%46_U>MW%Gpwkjwk$5AA2<%`E= zZu#^tA`=Uhz=pIoC(X%KwY#Zm61V`r8m$3jzG25JpZEzbm;0?W~6&M+IJ@$GKy@PW=M8O>$fgyn( z)i;84^Mv_){S`j8kgpZ5hq7J}$;q^@WMs??cOh1?tAv7LN;ex1PNq-spd6p!;Gwc= z%9Fz1O8nCg0YV#P7w?VH*wmEXql@I?02E09{c^mztY=)%_YQPM{4n8%1yO0OIv5`=oF|?Ur$U>m81POX=wc$8T8pYD%pYFAVpZXXvk; z|DHsKY`r{RpQ{G^y5CP72Qm4x(E*2senECsf`-<1S-~q6WJ=|95n>H^CSwWb($(dG za){nB$k7N4a(SEb?X7=b5*&2tU^M{fEa(P(^_qsE)xM+SUf#!nx+Ae^QKl!Dwx-b(2JVAbs>V5Lr!PEMjD&~ zZ9A#mG8A$=hmKfoS*M#Xs5}1pt*G9rlBxoABX>JqYAC)F#1g<*Vj_5zAmib_a*gSH zsq2EY$3L-cv0!=CXzK(_t0eT4++#JK7Obzdd)u$`Woy5X8FK&iwm*g@8A$4&zVgc> z=nNR!5r*wPuVp#aFVyw1bUc0fvc$5jABva!9t(QS`k2D!VtPj2CS5<5==+`64x>AWZRjpDI^cU zaS>jQu(c!~$qDgMM~v)ECyj&5 zU}+iWVAyV&RHMtPdaF){_@J)WN#*-C+T#AWN7}hS@D|< z2__}`54#D|dvSy*a`C>1=7UHw()%w>4*0x-h6>NE89^0j?=5WP*2^bA!qU{gUzGa=C}ZMi0ycaJ%K822 zji6%lM!SH@+Ly9Nc6~{Uf0)vc9bIxtgVR`DC)^s$OHq$zQ-+AuSM-+QE z+r(YK7a7%Yh#;9GG#NFA4}uf?>@jp}z!<{_|B3=M&YAiatE-tR?mj88qlCwulIj-7 z2`L9O&cMEqVgooZCSxK14n>=`Ewf5imBQ?YayuDmxXgwtZ7rzuXD&Ljzn*?j(fral zeJdy@J``gY%=Gg~qi8>gOmq^@)CAWay%Y!AJn%|#U92+E6#|u8H%N4Vt zttYGBwtMPVx2&`q2Bn05E^8W23ZY?=UFma~#m_JjiQ~74m|5rf;m0jZiCnC6Y+SXv zp(M{Jqfwopb@UP3^}>p6mX(-nnC!=^)QvzstUDUzY5aC?E9Tpw_M!l>2UscO5lY z4whD*SiaJs&|xZL8rRzUah zVf(+%!q0oPnVFY?ywYuwYmxnoiz&U$b*YN2@?_?=5>XH<#7soStsyY5^FR zCa=Kh{JR?>9-%c@T@#fUjQp&RU0JZGD>Ef3RmVKWu7d{nR!AGSAWAHVlGBNM`n$$k2?U)fM_0O39v#tIIzyxHP{><`2a3sduZrFM$D`;V*rMBK3tBM{r8Wmm+* zK3hd*wo7%M?j6b2v!h*S=&YIlvO9nTUg+U8~Mb zl0%W_yF&HXe!RYXAtvXmZB2%NHniTZmFSADoZ=2ut&A=_EV@{k_#e72abVZ6Eot_= z4dPtni9>1?)Ew0pBV|Tz6F6CI)KWj8US_O;(;cQgZzr4^T!z0I}$ep0vp#V*iqEOqTO_;<*LYXjMSAEBFt61*@WH$@)wp?@(Dvx1XkHxTV+HnPAFEs_YzcLmPDkDGrgkh~>B00q+0uD>$-*gM>I zYRQ9mLp>Hrc3s&Um@fo*>2db>bxuK+5=8UI0uW|VMyQ`Gu?A+~!4n*&MM_^U_AXlM zsR3szYl2z!zmZotA#z0tRo60)Y~ITRo)^^bojPP68=_-d97piv|6txiDdj6bkp!Vl zO-~%Yvvr!ns%-)1MY5Q*ghXukZb_22eB>|T+HTTE{s0DM#j;9*3|Nl0aN-iuqK z|2G?Z!CCcm-bUz{JU$Jp(g3&Gvh`0h8g-BJdU6+Akxvy>uMgqVL@f}zu z`Hb_U)V5&%N>Au?i3s-AEzB9?b=ya?`8E-;h6YZ&48%OJIJq3YQUtlk3$E;2;o+B8zW`RXRS68 zF5-$&)4PKyElM7J0TL?m<;0{18eJJzS*XeVR<{1S?{>99O?;z*Aq2So2#BJ*yg=Qb zpl=)0(NzOIon$rF-d)J=A0Heq=eIx*_mFQ*SK7GOmKUcpUGU!-&CQn;l2+MLwTbam z``7p*?Pt5S-NV#l?#Y0WY*sMCW_#oxJZ0f&xhvoZbHdg> ztdj_^mBw#Db`*9eidzkD&Oq7w%UW_#=M=0+wOTn$H4yjzXjft7Ue zGbn33Fya(cy>T-i%mU8_oB{4WT!76`t-ID7>)r^_7t!Eg+g#@2#MkMkl}@$i7&9t7 zU!%SPX!@^AIL_iV&PWvap@|9dwFxSm{)4%|;2kz5C${)^?iQT!ry5AMI?(#b)0!RDex0%>rkq zJ67S@xi}>zaekwSLJB(H?C&+eBs1Xg_u}){--r`FzHgf;jDYzoY{;44L%0y8Fp^<(E@E=f|Kpt8 z56|M0raSKXPkk{jb%wIX{>qxN??e zTU6|DUjJzUIWsrjWTex4HR<4%f*d?m&c=v1+=x?mDnx(ffSvR{yrT#3#H+J8&)R=C z6-&w+Uf*-bku)s4c3`e2e!vcd<9!Anj+NIFd#c^${#mA??`cpks@2dHnBZ!7tyZEz%5eKlW#KMnZqIVM#!Vkm|&|X-@ksgR}=f< zdgRM2KG$8lu#?-tb1d!7muG^Wp%{k^- zZ8k<)2v9rSN^YLqahCY-1K}~BnfZ@9<4EN$!hl_N^cDuR&EzcWgTw9?0Dc!Q@_cJ3 z$-TIk9axeWH8QQfzxSY;lML~f&a?D^sH(6FR^cl!bbsoa8`*Cer|+m;2C9@U)DZK2 zVZ7+~^9MwM@ltAOrr#Y%4lC#4q{bTD6mqDFnwrWdkz-~5R9@_uSUO{OB#GGp$we!J{9 z%1NvA=MFe&A=DUzwe|T$cfufa!Cg?HlH5l@me{qRW0Yt5SDs-qwUCb21-{l49$aHc zsHLnEoGyVi4ycNrfHtgEIdPh$gc6J2Z4v8W3}vCR_e(qB{YU_g*Xl2(+N!EULmgz% z>DDl#6TGVDCw$TU?Mcr$rV>~S1=^K+1_=s9>vI6C^~4h|{Vr)sCbzb>ebNI zoz&fTx)%T~)m=!(1JrBe;m%>?>iEMG_{Gf5^(BzX%v-}8j51A=J1>Obi^1!3{8+y1 zK>o@xZlBAxTS#3nd~p+q%Qtv}z9B=Im$RAD{Png4ee}l(^6A@@h6DsqWA{j4kBDsW$6e+Ux~T`u z1>ydTwrDwM>51~7_yABnmwV;}E|Wez>eLTD*oQwCuD{%P{ne&M=L#wbvb>T_uLA^cgN|yx5sO@Fc zRTfp~_KA5fV-m!Lyq}yX!~oQILr&L#^*)6xSIW2Q5^)JBYmU+@Bbh-EMld2l%oK$i zQG?A4%gJsco%`2zo=h}+^ylhcdF&C zvV0RlF9YYLm9g6GH-Lv7P-hUS^_}PJlQ13>lbU>M)$2=g-bZ+1WY;*k+r$e1ZL#0k8JK1$78zt^SH)4C3|DU&c)L<@f>Sh zh$(`ZpfYHPs030Dt*4Z$doFWi{AJeh?geOk%9|_rmNAH7yRyIbG-BUghuv=$!90(e z!JoN(hgg_@8_@pGk^tR!GGl-{3MrPg^R*;QjSicccqQXiva@?wh?I42H zm9@$7!!Tk7$VcPsSEevg$Lo_yxYj@=YoSMUX3zXuoU%~~gXgyezWPY6O8O&nXwzyL zNyz2Q#t<{knEHD3x`5(+I!+^2PLe1H($Y|Xo7*iRRkUwf*lflffGq|3vvVHIjR{s7=z?dyt*X^eHD*jrs-UFvW&$}% zTx^n1O7Wd^ng+TLF%?B83U##$?6V-F#fVvgs5guK9S9vRCY4CoGmV5M`CS6p-Xn`-@)KkEKe$99axg%9cKOJ>)uJ1j&IVJ#hh_7pK=7AxyyszFhCks8WZ~X3`l6q!(&Co^UXm636~9huJF1{5 zkNm4fNo`~YI#}ayAeTuUT?z!o*ZOmVeI&!Rsz|}MyWNhi>S1)OAAIhCY(pQNuo9Q^ z5H0BEcwd;;{HrA|b25kOPLw6n<9+v;BCafa^({H+s2}@82BZ4q!{x9GamsD?a=L>Q zrNFU(Q=S4yx;eanzsmQ^6eTZKOhh08X8&s9&I3P=03PWIAms(rrpne%7J{Nc* zN}91H4wQGfJS2f*f${_vS4qPCm;56>x&vIA?+3wa7vCDa_`h@;SJ!@}^ zU7k*Xn2$GLFF;H)f}+_V>*bmCG4rx4#qC$Q&8O$J(Y00n3Av8hTX(jZ85z+DSAHQa z1~?+qc#5L&B$lsmtXMv%5F3IuHLNa^=m(@OwyTJR{^VV$y$K&=kS#d<&Qo&}CAY^< zx257on zCoU}NYUyA;!FK}G! zum7`%xZjzKTWIo|@VrTfuH@^;ux}2^JV%2(UA=~oU%Kz~-Ub@W3vCQWk~5liXPNXs z(<{yTIF(i@_Up0FO!|a=#$R*8o=NOJwkE2yulN4Zqh-63LhVM44`buEf96VKD@ZI; zmK>P+thk!id4&ypG0ZUo8U6(7Y_-;E4c}%3!UrxB1+V@zb~Icbb)t@PqBfg~--$K&c&0!bTfZ=L9kN(ml$G>np%88`ky5`6MliF5` zy1M(2zBv6(POw!Kzswh6u?MJ$?eb!JZY7 zH-PC)!k7HAgc#FS2CDiKwnDTbf}D}$GaiZ5i6y)24RMYWR2}#R_>qrr*ySLvi&gBy zYJ~6?3;`Nxcyv40^0#hzwu;{os@ZpGD#=SAu#c*#OV+s$krW`}x4$7yewp*ZEl#IbEDh2Ua@+Chtpf;Kr; zM9Ksx>zUql2>a^7@2*T#JnT9)zdB`)7PF3B&agN%<;Ps?hiRw2ZzLECqQ2*U@g@)5 zMPWBu)|=?N>TQTi*8XftYjsMz-Jlml9{T_lT++tA)Af=*`WQ<#LZdnwiTb$df!2ow zmx5TNLVowq?`6ZlGCu6xF!-^PHgLgmK|FNu8Hw!f3iiRqqKu}iQR_GT7TaK>FxpXH ze}{&;`W|B}hri!*pt!oboA{D7VkP_bD~a|Ku($4>jQWZdk@h_we}y{%Kk@gwFXmTL zr@sqM&bm|o0wtkxnm*!vB<0ujK_O+bPy3x!TM1*rhyhDKRO#EVXrt$vWE4M)#qGl| ziRXm_UYgLUN-EAWMrBAGuPGDktAvX0zSY0#QX6ceO=uD%Ca(8C(aGz$%sJJRescL5 z@MP}X_lhcLWWhGh#KJ-o3Bv)O;owDlby1SJVKy>#`Y#uteY;*@z%EllgK5HjI+lJK z@q|`viKrqLIBrYFI(JtwAkMZiC8e}o@raI(_LXh19hP&FFD>AXdzn=HNl*6M zoYLN#RtuWNQNj!3qLbeGiaNK5zfAVa#pd549~{~iT%}(-ig#lNI8$XfSn-%05G~ ztAfv?2|(Q3qdDxdY<&~24UL3i!YBg+ywxa3157afmVVW9c+Qq6QhcBvb&;MTZunEK ztARGr^d}A1fqHE`>6ho4&y8@rSMViv51JiS>UuPW$^pAaszjQ{)B-(U_unt=&f{DE zQe8hbrW=j+=sOo5w8M=*f2th|3f$V5@uf`>b6wL!hFqMjqXC{b zsar3eV_h=ozuKQyMG=gDpkH$ZYUg>`r*CNS;gGs|>8DVNMrW3M%FVEn?Mn_IL4a4( zv~}WUyl!8Ktl5_~C`pe&X>Ns0Zcik ziJLySc<^vcCh+iFjN!QK-2Ii&z=;6u#rjQtO-6yfQ08Mqh8xy9v@54cDLO*v!km{- zjFymXIw;YFR}(u8XK-pblYN`(iU|e0m6N`4AY4_S>PI#hOUPEqa^3HcEIP$%_! z9#SQba^UCLXP@on#eB16SvmxcoKqV`*KoIsG%luz19$(Brmj=7r(_f)^pr=x(x=FH zMW=nF)3a}dDuT+?pGwA6Db4M)1X3aYs}4@}btkCuJVmCeR~QpA1O%_L_*)~@(JlBE zV#-QmtU{{VRJD~ldCottXa3y7VRxU7znR;Tz2#K3sT#k?!|*)rH297aI!)YZyi}OE%A0A3}((J0-Oe{%Olh@GY~2ho6fKyz@VXH_QScuBQ5&Y9skr*Pjx== ziBF`RBYZH?T|YP;w8WiuS@NJo9nn)4Y4UO47&=Zh|^#|C$z*RqZmW zFJ@^1CF3B_Ppd$^a6sD&3dD3(`St&w_H_ebo@O@~`Hy zYd*Np{Lq*1MH-*@PyJTao%2IJZgb6@qbsgw8cP}@%n8Op8XI-ITdrHd{zjlry*T3V`t;LJCqw=7pZ|PS2(0NV#Fv|RWN5ANvb7JYgY3k~?QY|W4BjbY3iCJryqkBZ;r>v|C(jb#u> zeAQrpx9Fgw4~l(BCkMp5T^k? z5vWjNO@qht&T~olfi44*6Nopx=}qZTz^z-istKdP$bhVQO~r`gDMuLEl;WhR&voXZ z>!wa{WBEDm189Neq@c;Mkhp$AXb`%-buAt^?htfcy@-=$QK(K46q~K;=J-D?5^4`^ zrCp>6&0CjNkBHmZgc9@2D|mU_Wn-HnPAp@1zL=ape?A=*Glt;b#$1%O>)DSGK2Y*_ z3^(_Wd5tnO&xFng9~bcwU@w0{_tz?6AZqYMzvC<~Lep?N!E-+N$vD)w<+(7s$^CZJ z#n_CFw>o&V^XX52IvMR8A%mC3Z`}s)qpXSBr*_q8;t{u3+Igu!piesHnUCBsaJe*2 zRKLdyj~3D+hBTk+In6v4YrI3h&DH&z>XYHmc^`4=bl9EC^ba@q;|5_Hu}VhpVcC%F zxI@Dtp7ZiB;>0z|ZDky>uA}^4^{Q8Oo_OMkRG<0J*lSE$*3>_Xew+@C&VodMbq7w@3;2c>5iScR z!MkI4E<t9GXY?;LBqe0bDe~2q4d%4u>z&gm|~Z^r^$%xTKv= zoy6_Tlk-J24ZnzETwqx08hHkdP3U$+h78NYh~qdo(F1on#tkDxzAPk+4W1z~K3GT| zfBf-opLw_HK6ZV34S5F4>5LVAx+o>0-G0m31HWyqTc!=+5aIA*ULD5j%_|`{#u>>d zu2uOd?dBwaB>VI&co_uD-Tjh1butH2-HOxqC=ZN)&wlo^NttlsLw(>lBu-oG-5%00 z&u~KLk#A>MTiWnJL-f4cMJ$Lx4pdPx)T-o9d1A<@w}MFP+M3fzbZU zXFij57R2qrBMzy07xv2fvun`if*FLRnl!y}EO5Z~4}l7j@1 z9&OKTYR>9u9_>!MSmY&xfHdRYJ1)Y#IMXAC^a;Z}%O1 z5C_Mhc{4tF5wBM~&r1cz=#Sgf#FFzI8i%w!FvlH6nCGVRm?wr2(pR3dD1TnfWzI5B z86(Kr@^<}s2<_at|8h8K>P7K$8t9W4V8L}2zvy%oR$fo!%k>d*0uX48Bsy*eKoWw4 z{$-x;Sm^m1lkP6+yA-@ zv=|^9Bft60Z%#W4TdL&Y8L$j)%HY8V?)DG@bG@V;ceuUwojjB8auK%)7V}3Dho?5@ zJVJYLb9i1p$3>p@^gBi%Cp7c}yTC^tc_fVs^Jq~#G z%07U68hMtd2Fqb1_zT$mS zN8d1KIjKXo`FM#u_KH*1b?120%Q{W}Gv2^8Pc^O;zp`}0GB{}BC=;FGu2Xz3sa-Ee zoKeKb(Eyl|U|zHU2`w}PL>!p&4I`}K>5TzRY~CdBHw4mqm+n|Be5^?n0fP&gUT~me z*HoAD@{qbc7+F-yD*?ktQ?9q{Eeap(Y#p881Jfse~!q+_1rE;sI> z+mnYm-!Y#!9@#nWv|(OE_+A5x3H|f%!w+{q9D>Zfn`jyfdHqdk>f|F%%S#$p>Tl9X z{_utu3?KUhoOB2%f+^la_?WS!>4HgbDGeOe4O)o#S`L~{fTWcYfUh>%Xv*9 zFwaNgZE5!heZpMD0OWEm=_j6eB3=0Nm~cOuw_YJ-T(A2j;!`j5*eJ5=#~HuIqho!u zf1Bd3^HY%1&S)eY)pc9O%qw*{2Fcc-sey+PjH3ZSyPs=nd@k4=2SEp%t|1^{b4P%@ z?lBD~0a$k)U?>P2O2BlW<#=9KQ`&VygTVxSZm9BWWV+Xoj1G>Op@{>JGG0t5LmUT= zJ#h0yp80Z|&@`QAUdW3MytcfEcNlT=?7H%Fgg50ynB#=V3(taqp+_I{Z3#jabAHm7 zh2HY_t{=JVMmFhaQj658loLwIG*I^N!zY~i7z)mLZd(a^OThif{A6y}b8muEfhBqF z4A8ImVdM+0#{hI0FTi-E7h`~V%SAKlHhs9Q*OKo1gh$Gyz7G8luJarxG%lgxjyI(f z(wO|AJ$8<_h2W8wd*)_@dA>SC-pnZ!Ki}iPXy*%m%vV=*a zKXKr=8ehruH3T{=-RyUMLJEJtH(kKSGc2U9=-V;3L(!2$(u)0iYV~h{lXgb;hnmDHo z>@0ZZ%pm5%krx#f6c(b~!$C6ai^Q&z>u%= zh|_oWEF#F9J|&Jt&!Wykg7JqOk+F6!bJOqdNikzcoUZM0k?neeZQf2N&`9_)MJhr9Hr}NdCm(C*$3U=W~~Q5pL>IV^szgp)08-{Md9Zmws7^Ojf zBts5kj=sT=SKsq-sWYd~3}py-JP4*?-JDd3l-6mLmjJH7>A z#vNM7PB(=XJbA)ThJXfMG6d*dz;reaWo$!$Qvu)=O3EJU54_o%2acXmMko+=78n97 zBn(6!K~X38(Yc+bljnomgkxBwHR^a1@8-#Q4h<)?TnMAmXAz;V@E8EJnVr6$-`bE% zilSabhV4`MNs9ljPKoqhb$TyaFzSXE%h_QQ|FJD4zCRK`-i!y24J%{D0Y~`EW#%04 zK^*k#86)&9A)a~4$sOYWL%^Rb2ab2$Rw$H#79oy!n`6A>`Ax94^7{#I8oLqZxI@?N zG@(6tj>mb+ydjOD&b+lekvE$n{C+8Z^XD-FUDkO*cmp2Xx?t)GDT-S0(=Xsf2Q0$L zHw?TS-(`VQpX&ayU<`=ugpGJe;b61kkeE?5X@-3K;~&5I4d3t$HLsT+4cc7!??ptPRXx zk413E!`m33KH#3OgdW$_LEPgf#t%k9d#7sNW9T^4iARsj=nsdix%3Gh`LX5^;*hBy z(UEo^I0UvEN8LF3!5h5DV@*@ncT!)diw4{AgKy_PblPFWF^o{_$;e*;gpYB%1Aykj zT%LL1g%>`mf%8n8U=#D2KuykNqVNri_yI;wZfeqE`gJdPkdJ53GSL~d&}0(t)j`Le z0m>rc#e_OpL|C*Ku!Ia=FDhP8-~$i7L*h8X7&pI$wWSR|s4(^kbvSKVI7B9nBYzeV zLgeHHg!0J33Llvv2Vjjgc9_u^@R%g8ZN4^*%_f+6+V3#7*R&(d zamxZ6;-0TDL@s#C3PtaAjyQS9A+B+>6&Q{<-gPG6kbkHfxm)o=4_I(YR*!p>w_{?cWQ{-SSe(?Op;NLyQx?S5LoUX!C5DdELt~E~BIG z@r*IXA|W`;S>`87hWc!v5;ArvLtXedUKzL0AjFxz!@Ta8KCF0@f#aTsq=`Fp9C_f8 z1?|V9@bSQK$bu74%LN#+h;4_iJ@7%D`GcMx15)1n)wGnX3<2RK#SfhNqI10t$pa@( z$1;P&$K?c|_Y4@MCHseyl(5NZQar~X8pOHN@=l5AoDO*|7xFj}nbLsuML{|`-5CIv z!OAm026Qw8>hTlEv`1Ypp*`5p_u@c33{E@~208c{8F}n@S#ZE7q<$6=@}NoDFlYnA z0izzL6HtGEk+)k%`6d_Pj?)(EC++r8mUiM;oIKCvfH&mD2Y!s_cuv3$#hQ4u{l(gFdifoy$|!G|W4+;MaNZ@3sJUnneS+9r$^h;GK5mA$0-U4|i|r zUgyS5T|LoBAd)D%{{4{Zc+g0rTw{gr2BhDnm(sm;=T>KVb-DAvxd(PN_T4hZYaE*% z|BP`w2D{^)!=xGa;8NaW9y*MD)AO7KW;}-;`!OVMH_kj$-t!n9f#V2)!#~dLAjDho zdoH^i?XV(tTd2cxwimzTnNF&-#~<_TJ5mB|6#7KVy(EN^r0T4Ta(U#I0RL`Si2XV2(z(?3Q40wcr6FY@`y8!Q=2xuU$YZ9Vq zy7wj+*i3GY6j8`b7!PdI8a6bK4qYCekOu?Zp8AN}5TS0$c>y5==Cl_TaDbC0?z$Xz z+I8n4yihL=T;dUC{(zZBhsGt(<>7<2nNRcPkUEIta~}KgnkpIK5APh`xqYWItuE%L zlb5xFaa|NQzXOmeC}S)E`gBcwyP-awTbN6`R89kU<&5!Xx7+@XV}|i+nkY$VGX6am z2y@S_Il4G!iN|z4AILM`}~OgyDcM2fG3`={QS@V{2gWGhDgP9 zR^}j+TO>dvCW($5czr}QzQdQvAC zc)qo7Lx2HTjWu$2y2!`Q+$~7t(ex;54<>Qy!!t3RCJsM1=-{E@xF={1cRuA}ouqMj z-J}hNhnSx-^aq+a>U6y^PCZTDytsTGCZhZBhgUJv=VkR%w5u!C4Q1E059AApF_Qoz zc5PjX?4F+8%Yf(WjaT%hz+Zm>o1{s4J4D|7e8V# z-R(|U=7U6RkINb6b{fz5O(D3EZWB&`UH-raK2TjG3qVD!6A#T07?lCwhHh{ER%%LL z&AX!acM(KC+^tesEOsDSgLabf^7887bRR%g`i2I7_hUjHFkDQ-67>;1a8Jg_n(4Y+ z%!~1+e9F2!Avku#?ST>ZWHz4j^PPrin08D@SRSW+z@i6cxD`J65uV3mdFmz|!<4B1 z&<5uN%F_|IU;OH|tLX#YK3dj67`=rj$K#GcRb?3n|U>#gocx6PkG{l zxL8L&{3cx5hr{sj#w)f7K9m+(dZejjdaEmy0Wb1N-04`CVX2V*#JpZG$~ED-j6?NR zzmEV}m|Kgx3-5Dy*am`dpC zYp--JoWGD1Ow;^u(|hF^$KfEjjDOEx&lk$!J$D^9ye%|7^&2OTN8Xy|UYwus1x-Te zHMt0napN|@oHt15HgS@I;%9w@N5g9xN_HPjvgL0iox>w<jXYK(oLHB+w7-und6ap4iSE4FxaZe&iz`x%u?dPv6jF=o$cd$89e@SjwH(M$2&U z@J{E{1y8)%5YWI(uMWB#lbBZrSy;Hi?;W=%c}{OX(vjbsZ|ZHUJI9S_%8-UO@mL2u zljj91mLu+T9^Y+S^SXCS2Yzny%>Uj}XI97lD@!Z-!5;N>{rwN>Dem}4fbqaR8hv#` z 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 literal 0 HcmV?d00001 diff --git a/Contents/Resources/web/images/favicon.ico b/Contents/Resources/web/images/favicon.ico index 79620bf5b76dbc9bd4c49dd68c0e9fecac911f2f..58ec0795cc4318834c7c9bce5625ce9c1d4d6948 100644 GIT binary patch literal 105582 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 z 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 N4riThs;qqy{sI7G& -function getRandomIntInclusive(min, max) { - min = Math.ceil(min); - max = Math.floor(max); - return Math.floor(Math.random() * (max - min + 1) + min); -} - -function randomQuote(quote, crate) { - let the_quote = null - if (quote['quote_safe']) { - the_quote = quote['quote_safe']; - } else { - the_quote = quote['quote']; - } - - crate.notify(the_quote) -} - -let quote = null - -// get random video game quotes -$.ajax({ - url: `https://app.lizardbyte.dev/uno/random-quotes/games.json`, - type: "GET", - dataType: "json", - success: function (result) { - let quote_index = getRandomIntInclusive(0, result.length - 1); - quote = result[quote_index] - } -}); - -// use Jquery to load other javascript -$.getScript('https://cdn.jsdelivr.net/npm/@widgetbot/crate@3', function() -{ - const crate = new Crate({ - server: '804382334370578482', - channel: '804383092822900797', - defer: false, - }) - - let sleep = ms => { - return new Promise(resolve => setTimeout(resolve, ms)); - }; - // sleep for 1 second - sleep(420000).then(() => {randomQuote(quote, crate)}) -}); diff --git a/Contents/Resources/web/js/item_loader.js b/Contents/Resources/web/js/item_loader.js new file mode 100644 index 0000000..80821f8 --- /dev/null +++ b/Contents/Resources/web/js/item_loader.js @@ -0,0 +1,838 @@ +// scripts to load +let scripts = [ + '/web/js/translations.js', + 'https://app.lizardbyte.dev/js/levenshtein_distance.js', + 'https://app.lizardbyte.dev/js/ranking_sorter.js' +] + +let installed_plugins = null +let plugger_plugins = null +let all_plugins = [] + +let plugins_container = document.getElementById("plugins-container") + +// get search options, we will append each category to this list +let search_options = document.getElementById("search_type") + +$(document).ready(function(){ + // Set cache = false for all jquery ajax requests. + $.ajaxSetup({ + cache: false, + }) + + let script_queue = scripts.map(function(script) { + return $.getScript(script) + }) + + $.when.apply(null, script_queue).done(function() { + initialize() + }) +}) + +let initialize = function () { + // get installed plugins + // json data with key being the plugin_identifier + $.ajax({ + async: false, + url: "/installed_plugins", + type: "GET", + dataType: "json", + success: function (result) { + installed_plugins = result + } + }) + + // get PluggerDB plugins + // json data with key being the GitHub repo id + // will need to match the name property name or bundle property of the installed plugin data + $.ajax({ + async: false, + url: "https://app.lizardbyte.dev/PluggerDB/plugins.json", + type: "GET", + dataType: "json", + success: function (result) { + plugger_plugins = result + } + }) + + // set all plugins installed state to false and add the github_id + for (let plugger_plugin in plugger_plugins) { + plugger_plugins[plugger_plugin]['installed'] = false + plugger_plugins[plugger_plugin]['installed_data'] = null + plugger_plugins[plugger_plugin]['github_id'] = parseInt(plugger_plugin) + } + + // combine the two dictionaries + for (let installed_plugin in installed_plugins) { + let plugin_name = installed_plugins[installed_plugin]['name'] + let plugin_bundle = installed_plugins[installed_plugin]['bundle'] + + let found = false + + // if not system plugin + if (installed_plugins[installed_plugin]['type'] !== 'system') { + // try to find the plugin in PluggerDB + for (let plugger_plugin in plugger_plugins) { + if (plugger_plugins[plugger_plugin]['name'] === plugin_name || plugger_plugins[plugger_plugin]['name'] === plugin_bundle) { + // found it + found = true + plugger_plugins[plugger_plugin]['installed'] = true + plugger_plugins[plugger_plugin]['installed_data'] = installed_plugins[installed_plugin] + break + } + } + } + + // if not found, these are system or user installed plugins + if (found === false) { + // add it to PluggerDB + plugger_plugins[installed_plugin] = { + "name": plugin_name, + "full_name": plugin_name, + "description": installed_plugins[installed_plugin]['description'], + "installed": true, + "installed_data": installed_plugins[installed_plugin] + } + } + } + + // add plugger plugins to all plugins list + for (let plugger_plugin in plugger_plugins) { + plugger_plugins[plugger_plugin]['name_lower'] = plugger_plugins[plugger_plugin]['name'].toLowerCase() + all_plugins.push(plugger_plugins[plugger_plugin]) + } + + // sort the plugins by name + all_plugins = all_plugins.sort(rankingSorter('name_lower', 'full_name')).reverse() + + // populate the plugins container + populate_results(all_plugins, plugins_container, true) + + // set up the alert listener + setup_alert_listener() + + + // replace default function of enter key in search form + document.getElementById("searchForm").addEventListener("keypress", function (e) { + if (e.key === "Enter") { + e.preventDefault() + run_search() + } + }) +} + +let populate_results = function (plugins_list, container, update_counts = false) { + for (let plugin in plugins_list) { + let plugin_name = plugins_list[plugin]['name'] + + let item_container = document.createElement("div") + item_container.className = "container mb-5 shadow border-0 bg-dark rounded-0 px-0" + container.appendChild(item_container) + + let inner_container = document.createElement("div") + inner_container.className = "container py-4 px-1" + item_container.appendChild(inner_container) + + let table_row = document.createElement("div") + table_row.className = "d-flex g-0 text-white" + inner_container.appendChild(table_row) + + let thumb = document.createElement("img") + thumb.className = "d-flex flex-column px-3 rounded-0 mx-auto" + // if plugin installed + if (plugins_list[plugin]['installed']) { + thumb.src = `/thumbnail/${plugins_list[plugin]['installed_data']['bundle_identifier']}` + } else { + if (plugins_list[plugin]['thumb_image_url']) { + thumb.src = plugins_list[plugin]['thumb_image_url'] + } else if (plugins_list[plugin]['attribution_image_url']) { + thumb.src = plugins_list[plugin]['attribution_image_url'] + } else { + thumb.src = "/default-thumb.png" + } + } + thumb.alt = "" + thumb.style.minWidth = '200px'; + thumb.style.maxWidth = '200px'; + thumb.style.maxHeight = '200px'; + thumb.style.width = 'auto'; + thumb.style.height = 'auto'; + thumb.style.objectFit = 'contain'; + thumb.style.objectPosition = 'center top'; + table_row.appendChild(thumb) + + let data_column = document.createElement("div") + data_column.className = "d-flex flex-column border-white px-3 border-start w-100" + table_row.appendChild(data_column) + + let text_container = document.createElement("div") + data_column.appendChild(text_container) + + let item_title = document.createElement("h4") + item_title.className = "card-title mb-3 fw-bolder ms-0 mx-2" + item_title.textContent = plugin_name + text_container.appendChild(item_title) + + let item_summary = document.createElement("p") + item_summary.className = "card-text ms-0 mx-2" + item_summary.innerHTML = plugins_list[plugin]['description'] + text_container.appendChild(item_summary) + + let categories_row = document.createElement("div") + categories_row.className = "row w-100 mt-auto pt-4" + data_column.appendChild(categories_row) + + let urls_row = document.createElement("div") + urls_row.className = "row w-100 mt-auto pt-4" + data_column.appendChild(urls_row) + + // for PluggerDB plugins + if (plugins_list[plugin]['html_url']) { + // add archived plugin category if the plugin is archived + if (plugins_list[plugin]['archived'] === true && !plugins_list[plugin]['categories'].includes('Archived Plugin')) { + // add to beginning of array + plugins_list[plugin]['categories'].unshift('Archived Plugin') + } + + // create a badge for each category + for (let category in plugins_list[plugin]['categories']) { + // if category is not in search_type drop down, add it + let search_option = document.createElement("div") + search_option.className = "form-check" + let search_option_input = document.createElement("input") + search_option_input.className = "form-check-input" + search_option_input.type = "checkbox" + let category_id = `category_${plugins_list[plugin]['categories'][category].replace(" ", "_").toLowerCase()}` + search_option_input.id = category_id + search_option.appendChild(search_option_input) + let search_option_label = document.createElement("label") + search_option_label.className = "form-check-label" + search_option_label.setAttribute("for", category_id) + search_option_label.textContent = getTranslation(plugins_list[plugin]['categories'][category]) + search_option.appendChild(search_option_label) + let search_option_count_label = document.createElement("label") + search_option_count_label.className = "form-check-label badge bg-danger ms-2" + search_option_count_label.setAttribute("for", category_id) + search_option_count_label.textContent = "1" + search_option.appendChild(search_option_count_label) + + let add_category = true + for (let i = 0; i < search_options.children.length; i++) { + if (search_options.children[i].children[1].textContent === search_option_label.textContent) { + add_category = false + // increment the count + if (update_counts) { + let count = parseInt(search_options.children[i].children[2].textContent) + search_options.children[i].children[2].textContent = (count + 1).toString() + } + break + } + } + if (add_category) { + search_options.appendChild(search_option) + + // sort options alphabetically + for (let i = 0; i < search_options.children.length; i++) { + for (let j = i + 1; j < search_options.children.length; j++) { + if (search_options.children[i].textContent.trim() > search_options.children[j].textContent.trim()) { + let temp = search_options.children[i].innerHTML + search_options.children[i].innerHTML = search_options.children[j].innerHTML + search_options.children[j].innerHTML = temp + } + } + } + } + + let category_column = document.createElement("div") + category_column.className = "col-auto align-self-center" + categories_row.appendChild(category_column) + let category_badge = document.createElement("span") + category_badge.className = "badge bg-secondary" + category_badge.textContent = getTranslation(plugins_list[plugin]['categories'][category]) + category_column.appendChild(category_badge) + } + // add a categories edit button using fontawesome icon + // todo - pass categories to the issue form... if it's possible + let edit_link = `https://github.com/LizardByte/PluggerDB/issues/new?assignees=&labels=request-plugin&template=plugin.yml&title=${encodeURIComponent('[PLUGIN]: ')}${encodeURIComponent(plugins_list[plugin]['html_url'].replace('https://github.com/', ''))}&github_url=${encodeURIComponent(plugins_list[plugin]['html_url'])}` + let category_column = document.createElement("div") + category_column.className = "col-auto align-self-center" + categories_row.appendChild(category_column) + let category_edit_button = document.createElement("a") + category_edit_button.className = "nav-link nav-link-sm text-white" + category_edit_button.href = edit_link + category_edit_button.target = "_blank" + category_column.appendChild(category_edit_button) + let category_edit_icon = document.createElement("i") + category_edit_icon.className = "fa-solid fa-edit fa-1x align-middle" + category_edit_icon.setAttribute('title', getTranslation('Edit Categories')) + category_edit_button.appendChild(category_edit_icon) + + // GitHub url + let github_column = document.createElement("div") + github_column.className = "col-auto align-self-center me-1" + urls_row.appendChild(github_column) + let github_link = document.createElement("a") + github_link.className = "nav-link nav-link-sm text-white" + github_link.href = plugins_list[plugin]['html_url'] + github_link.target = "_blank" + github_column.appendChild(github_link) + let github_icon = document.createElement("i") + github_icon.className = "fa-brands fa-github fa-xl align-middle" + github_icon.setAttribute('title', 'GitHub') + github_link.appendChild(github_icon) + + // add homepage if it exists + if (plugins_list[plugin]['homepage']) { + if (!compare_urls(plugins_list[plugin]['homepage'], plugins_list[plugin]['html_url'])) { + let homepage_column = document.createElement("div") + homepage_column.className = "col-auto align-self-center me-1" + urls_row.appendChild(homepage_column) + let homepage_link = document.createElement("a") + homepage_link.className = "nav-link nav-link-sm text-white" + homepage_link.href = plugins_list[plugin]['homepage'] + homepage_link.target = "_blank" + homepage_column.appendChild(homepage_link) + let homepage_icon = document.createElement("i") + homepage_icon.className = "fa-solid fa-globe fa-xl align-middle" + homepage_icon.setAttribute('title', getTranslation('Homepage')) + homepage_link.appendChild(homepage_icon) + } + } + + + // add gh-pages url if it exists + if (plugins_list[plugin]['gh_pages_url']) { + if (!compare_urls(plugins_list[plugin]['gh_pages_url'], plugins_list[plugin]['html_url']) && + !compare_urls(plugins_list[plugin]['gh_pages_url'], plugins_list[plugin]['homepage'])) { + let gh_pages_column = document.createElement("div") + gh_pages_column.className = "col-auto align-self-center me-1" + urls_row.appendChild(gh_pages_column) + let gh_pages_link = document.createElement("a") + gh_pages_link.className = "nav-link nav-link-sm text-white" + gh_pages_link.href = plugins_list[plugin]['gh_pages_url'] + gh_pages_link.target = "_blank" + gh_pages_column.appendChild(gh_pages_link) + let gh_pages_icon = document.createElement("i") + gh_pages_icon.className = "fa-solid fa-file-code fa-xl align-middle" + gh_pages_icon.setAttribute('title', getTranslation('Website')) + gh_pages_link.appendChild(gh_pages_icon) + } + } + + // add license url if it exists + if (plugins_list[plugin]['license_url']) { + let license_column = document.createElement("div") + license_column.className = "col-auto align-self-center me-1" + urls_row.appendChild(license_column) + let license_link = document.createElement("a") + license_link.className = "nav-link nav-link-sm text-white" + license_link.href = plugins_list[plugin]['license_url'] + license_link.target = "_blank" + license_column.appendChild(license_link) + let license_icon = document.createElement("i") + license_icon.className = "fa-solid fa-file-contract fa-xl align-middle" + license_icon.setAttribute('title', getTranslation('License')) + license_link.appendChild(license_icon) + } + + // add wiki + if (plugins_list[plugin]['has_wiki'] === true) { + let wiki_column = document.createElement("div") + wiki_column.className = "col-auto align-self-center me-1" + urls_row.appendChild(wiki_column) + let wiki_link = document.createElement("a") + wiki_link.className = "nav-link nav-link-sm text-white" + wiki_link.href = `${plugins_list[plugin]['html_url']}/wiki` + wiki_link.target = "_blank" + wiki_column.appendChild(wiki_link) + let wiki_icon = document.createElement("i") + wiki_icon.className = "fa-solid fa-book fa-xl align-middle" + wiki_icon.setAttribute('title', getTranslation('GitHub Wiki')) + wiki_link.appendChild(wiki_icon) + } + + // add discussions + if (plugins_list[plugin]['has_discussions']) { + let discussions_column = document.createElement("div") + discussions_column.className = "col-auto align-self-center me-1" + urls_row.appendChild(discussions_column) + let discussions_link = document.createElement("a") + discussions_link.className = "nav-link nav-link-sm text-white" + discussions_link.href = `${plugins_list[plugin]['html_url']}/discussions` + discussions_link.target = "_blank" + discussions_column.appendChild(discussions_link) + let discussions_icon = document.createElement("i") + discussions_icon.className = "fa-solid fa-comments fa-xl align-middle" + discussions_icon.setAttribute('title', getTranslation('GitHub Discussions')) + discussions_link.appendChild(discussions_icon) + } + + // add stats + let stats_row = document.createElement("div") + // move to bottom of data_column + stats_row.className = "row w-100 mt-auto pt-4" + data_column.appendChild(stats_row) + + // add stars + let stars_column = document.createElement("div") + stars_column.className = "col-auto align-self-center me-1" + stats_row.appendChild(stars_column) + let stars_link = document.createElement("a") + stars_link.className = "nav-link nav-link-sm text-white" + stars_link.href = `${plugins_list[plugin]['html_url']}/stargazers` + stars_link.target = "_blank" + stars_link.setAttribute('title', getTranslation('Stars')) + stars_column.appendChild(stars_link) + let stars_icon = document.createElement("i") + stars_icon.className = "fa-solid fa-star align-middle" + stars_link.appendChild(stars_icon) + let stars_text = document.createElement("p") + stars_text.className = "card-text ms-2 d-inline" + stars_text.textContent = plugins_list[plugin]['stargazers_count'] + stars_link.appendChild(stars_text) + + // add forks + let forks_column = document.createElement("div") + forks_column.className = "col-auto align-self-center me-1" + stats_row.appendChild(forks_column) + let forks_link = document.createElement("a") + forks_link.className = "nav-link nav-link-sm text-white" + forks_link.href = `${plugins_list[plugin]['html_url']}/forks` + forks_link.target = "_blank" + forks_link.setAttribute('title', getTranslation('Forks')) + forks_column.appendChild(forks_link) + let forks_icon = document.createElement("i") + forks_icon.className = "fa-solid fa-code-fork align-middle" + forks_link.appendChild(forks_icon) + let forks_text = document.createElement("p") + forks_text.className = "card-text ms-2 d-inline" + forks_text.textContent = plugins_list[plugin]['forks_count'] + forks_link.appendChild(forks_text) + + // add open pull requests count + let prs_column = document.createElement("div") + prs_column.className = "col-auto align-self-center me-1" + stats_row.appendChild(prs_column) + let prs_link = document.createElement("a") + prs_link.className = "nav-link nav-link-sm text-white" + prs_link.href = `${plugins_list[plugin]['html_url']}/pulls` + prs_link.target = "_blank" + prs_link.setAttribute('title', getTranslation('Open Pull Requests')) + prs_column.appendChild(prs_link) + let prs_icon = document.createElement("i") + prs_icon.className = "fa-solid fa-code-pull-request align-middle" + prs_link.appendChild(prs_icon) + let prs_text = document.createElement("p") + prs_text.className = "card-text ms-2 d-inline" + prs_text.textContent = plugins_list[plugin]['open_pull_requests_count'] + prs_link.appendChild(prs_text) + + // add open issues count + if (plugins_list[plugin]['has_issues']) { + let issues_column = document.createElement("div") + issues_column.className = "col-auto align-self-center me-1" + stats_row.appendChild(issues_column) + let issues_link = document.createElement("a") + issues_link.className = "nav-link nav-link-sm text-white" + issues_link.href = `${plugins_list[plugin]['html_url']}/issues` + issues_link.target = "_blank" + issues_link.setAttribute('title', getTranslation('Open Issues')) + issues_column.appendChild(issues_link) + let issues_icon = document.createElement("i") + issues_icon.className = "fa-regular fa-circle-dot align-middle" + issues_link.appendChild(issues_icon) + let issues_text = document.createElement("p") + issues_text.className = "card-text ms-2 d-inline" + issues_text.textContent = plugins_list[plugin]['open_issues_count'] + issues_link.appendChild(issues_text) + } + + // add archived warning + if (plugins_list[plugin]['archived'] === true) { + let archived_column = document.createElement("div") + archived_column.className = "col-auto align-self-center me-1" + stats_row.appendChild(archived_column) + let archived_icon = document.createElement("i") + archived_icon.className = "fa-solid fa-triangle-exclamation align-middle" + archived_icon.style.color = "#ffb02e" + archived_icon.setAttribute('title', getTranslation('Archived')) + archived_column.appendChild(archived_icon) + } + + } else if (plugins_list[plugin]['installed_data']['type'] === "system") { + // add the system plugin category + plugins_list[plugin]['categories'] = ["System Plugin"] + // add counts (for sorting only) + plugins_list[plugin]['github_id'] = -1 + plugins_list[plugin]['stargazers_count'] = -1 + plugins_list[plugin]['forks_count'] = -1 + plugins_list[plugin]['open_pull_requests_count'] = -1 + plugins_list[plugin]['open_issues_count'] = -1 + + // increment the count in the search_options drop down + if (update_counts) { + let system_plugin_count = document.getElementById("count_system_plugin") + system_plugin_count.textContent = (parseInt(system_plugin_count.textContent) + 1).toString() + } + + let category_column = document.createElement("div") + category_column.className = "col-auto align-self-center" + categories_row.appendChild(category_column) + let category_badge = document.createElement("span") + category_badge.className = "badge bg-warning text-dark" + category_badge.textContent = getTranslation("System Plugin") + category_column.appendChild(category_badge) + + // Plex icon + let system_plugin_column = document.createElement("div") + system_plugin_column.className = "col-auto align-self-center me-1" + urls_row.appendChild(system_plugin_column) + let system_plugin_link = document.createElement("a") + system_plugin_link.className = "nav-link nav-link-sm text-white" + system_plugin_link.href = "https://forums.plex.tv" + system_plugin_link.target = "_blank" + system_plugin_column.appendChild(system_plugin_link) + let system_plugin_icon = document.createElement("span") + system_plugin_icon.className = "fa-stack fa-xs" + system_plugin_icon.setAttribute('title', getTranslation('Plex Forum')) + system_plugin_link.appendChild(system_plugin_icon) + let system_plugin_icon_outer = document.createElement("i") + system_plugin_icon_outer.className = "fa-regular fa-circle fa-stack-2x" + system_plugin_icon.appendChild(system_plugin_icon_outer) + let system_plugin_icon_inner = document.createElement("i") + system_plugin_icon_inner.className = "fa-solid fa-chevron-right fa-stack-1x" + system_plugin_icon.appendChild(system_plugin_icon_inner) + } else if (plugins_list[plugin]['installed_data']['type'] === "user") { + // these are installed plugins that are not system plugins and not in our database + + // add the installed plugin category + plugins_list[plugin]['categories'] = [] // empty list, "Installed Plugin" will be added later + // add counts (for sorting only) + plugins_list[plugin]['github_id'] = -1 + plugins_list[plugin]['stargazers_count'] = -1 + plugins_list[plugin]['forks_count'] = -1 + plugins_list[plugin]['open_pull_requests_count'] = -1 + plugins_list[plugin]['open_issues_count'] = -1 + } + + if (plugins_list[plugin]['installed']) { + // add installed category + try { + plugins_list[plugin]['categories'].includes("Installed Plugin") + } catch (e) { + // plugin is installed, but not a system plugin and not in our database + plugins_list[plugin]['categories'] = ["Installed Plugin"] + } finally { + if (plugins_list[plugin]['categories'].includes("Installed Plugin") === false) { + // add "Installed Plugin" to the beginning of the array + plugins_list[plugin]['categories'].unshift("Installed Plugin") + + // add the category badge + let category_column = document.createElement("div") + category_column.className = "col-auto align-self-center" + // categories_row.appendChild(category_column) + // move to the beginning of the row + categories_row.insertBefore(category_column, categories_row.firstChild) + let category_badge = document.createElement("span") + category_badge.className = "badge bg-info text-dark" + category_badge.textContent = getTranslation("Installed Plugin") + category_column.appendChild(category_badge) + } else { + // change the badge color + for (let category of categories_row.children) { + if (category.textContent === getTranslation("Installed Plugin")) { + category.children[0].className = "badge bg-info text-dark" + } + } + } + + // increment the count in the search_options drop down + if (update_counts) { + let installed_plugin_count = document.getElementById("count_installed_plugin") + installed_plugin_count.textContent = (parseInt(installed_plugin_count.textContent) + 1).toString() + } + } + } + + let card_footer = document.createElement("div") + // move to bottom of data_column + card_footer.className = "row w-100 mt-auto pt-4" + data_column.appendChild(card_footer) + + if (plugins_list[plugin]['installed']) { + let plugin_identifier = plugins_list[plugin]['installed_data']['bundle_identifier'] + + let installed_version = document.createElement("p") + installed_version.className = "card-text ms-0 mx-2" + installed_version.textContent = `${getTranslation('Installed Version:')} ${plugins_list[plugin]['installed_data']['version']}` + text_container.appendChild(installed_version) + + // add icon to open logs + let logs_column = document.createElement("div") + logs_column.className = "col-auto align-self-center me-1" + card_footer.appendChild(logs_column) + + + let logs_icon = document.createElement("i") + logs_icon.className = "fa-solid fa-file-lines fa-xl align-middle" + logs_icon.style.cssText = "cursor:pointer;cursor:hand" + logs_icon.setAttribute('title', getTranslation('Logs')) + logs_icon.setAttribute("data-bs-toggle", "modal") + logs_icon.setAttribute("data-bs-target", "#logsModal") + logs_icon.setAttribute("data-bs-plugin_name", plugin_name) + logs_icon.setAttribute("data-bs-plugin_identifier", plugin_identifier) + logs_column.appendChild(logs_icon) + + if (plugins_list[plugin]['installed_data']['type'] === "user") { + + // add icon to update + let update_column = document.createElement("div") + update_column.className = "col-auto align-self-center me-1" + card_footer.appendChild(update_column) + + let update_icon = document.createElement("i") + update_icon.className = "fa-solid fa-sync fa-xl align-middle" + update_icon.style.cssText = "cursor:pointer;cursor:hand" + update_icon.setAttribute('title', getTranslation('Force Update')) + update_icon.onclick = function () { + // open url + window.open(`/update/${plugin_identifier}`, "_blank") + } + update_column.appendChild(update_icon) + + // add icon to open logs + let uninstall_column = document.createElement("div") + uninstall_column.className = "col-auto align-self-center me-1" + card_footer.appendChild(uninstall_column) + + let uninstall_icon = document.createElement("i") + uninstall_icon.className = "fa-solid fa-trash fa-xl align-middle" + uninstall_icon.style.cssText = "cursor:pointer;cursor:hand" + uninstall_icon.setAttribute('title', getTranslation('Uninstall')) + uninstall_icon.onclick = function () { + // open url + window.open(`/uninstall/${plugin_identifier}`, "_blank") + } + uninstall_column.appendChild(uninstall_icon) + } + } else { + // add icon to install + let install_column = document.createElement("div") + install_column.className = "col-auto align-self-center me-1" + card_footer.appendChild(install_column) + + let install_icon = document.createElement("i") + install_icon.className = "fa-solid fa-download fa-xl align-middle" + install_icon.style.cssText = "cursor:pointer;cursor:hand" + install_icon.setAttribute('title', getTranslation('Install')) + install_icon.setAttribute("data-bs-toggle", "modal") + install_icon.setAttribute("data-bs-target", "#installModal") + install_icon.setAttribute("data-bs-plugin_name", plugin_name) + install_icon.setAttribute("data-bs-github_id", plugins_list[plugin]['github_id']) + install_column.appendChild(install_icon) + } + } +} + + +let setup_alert_listener = function () { + // add event listener to the parent element + search_options.addEventListener("click", function (event) { + // prevent dropdown-menu from closing on click + event.stopPropagation() + // check if the clicked element was an input checkbox + if (event.target.tagName === "INPUT" && event.target.type === "checkbox") { + if (event.target.getAttribute("data-event-state") === "unchecked") { + // check + event.target.checked = true + event.target.indeterminate = false + event.target.setAttribute("data-event-state", "checked") + } else if (event.target.getAttribute("data-event-state") === "checked") { + // make intermediate + event.target.checked = false + event.target.indeterminate = true + event.target.setAttribute("data-event-state", "indeterminate") + } else if (event.target.getAttribute("data-event-state") === "indeterminate") { + // uncheck + event.target.checked = false + event.target.indeterminate = false + event.target.setAttribute("data-event-state", "unchecked") + } + } + }) + + // set data attributes for each checkbox + for (let i = 0; i < search_options.children.length; i++) { + let checkbox = search_options.children[i].children[0] + if (checkbox.checked && checkbox.indeterminate === false) { + checkbox.setAttribute("data-event-state", "checked") + } else if (checkbox.checked === false && checkbox.indeterminate === true) { + checkbox.setAttribute("data-event-state", "indeterminate") + } else if (checkbox.checked === false && checkbox.indeterminate === false) { + checkbox.setAttribute("data-event-state", "unchecked") + } + } +} + +let compare_urls = function (a, b) { + // if a and b are not null + if (a && b) { + // remove trailing slash + if (a.slice(-1) === "/") { + a = a.slice(0, -1) + } + if (b.slice(-1) === "/") { + b = b.slice(0, -1) + } + } + + return a === b; +} + +let run_search = function () { + // get the search container + let search_container = document.getElementById("search-container") + search_container.innerHTML = "" + + // create FormData object + let data = new FormData() + + // append field and values to FormData object + let all = document.querySelectorAll("#searchForm input, #searchForm textarea, #searchForm select") + for (let field of all) { + // exclude submit and buttons + if (field.type !== "submit" && field.type !== "button") { + // checkbox fields + if (field.type === "checkbox") { + if (field.indeterminate === true) { + // exclude these categories completely + data.append(`exclude_${field.id}`, field.indeterminate) + } else if (field.checked) { + data.append(`include_${field.id}`, field.checked) + } + } + // radio fields... must be checked + else if (field.type === "radio") { + if (field.checked) { + data.append(field.id, field.value) + } + } + // other fields + else { + data.append(field.id, field.value) + } + } + } + + // extract the search values from the data object + // get the search term + let search_term = data.get("search_term") + // get the sort type + let sort_type = data.get("sort_type") + + // get the excluded and included categories + let excluded_categories = [] + let included_categories = [] + for (let key of data.keys()) { + if (key.startsWith("exclude_category_")) { + let category = key.replace("exclude_category_", "") + if (data.get(key) === "true") { + excluded_categories.push(category) + } + } else if (key.startsWith("include_category_")) { + let category = key.replace("include_category_", "") + if (data.get(key) === "true") { + included_categories.push(category) + } + } + } + + // hide the existing content + document.getElementById("Plugins").classList.add("d-none") + + // results list + let result = [] + + // search title + let search_title = true + if (search_term === "") { + search_title = false + } + + // add plugger plugins to all plugins list + for (let plugin in all_plugins) { + let add_plugin = false + + for (let category in all_plugins[plugin]['categories']) { + let cat_representation = all_plugins[plugin]['categories'][category].toLowerCase().replace(" ", "_") + // check if the plugin is in the excluded categories + if (excluded_categories.includes(cat_representation)) { + add_plugin = false + break + } + // check if the plugin is in the included categories + else if (included_categories.length === 0) { + add_plugin = true + } else if (included_categories.length > 0 && included_categories.includes(cat_representation)) { + add_plugin = true + } + } + + // if the plugin is not in the excluded categories and is in the included categories + if (add_plugin === true) { + // no search term provided so add all plugins + if (search_title === false) { + result.push(all_plugins[plugin]) + } else { + // search using levenshtein distance + let score = levenshteinDistance.get(search_term.toLowerCase(), all_plugins[plugin]['name'].toLowerCase()) + if (score >= 40) { + result.push(all_plugins[plugin]) + result[result.length - 1]['score'] = score + } + } + } + } + + // add a clear results button + let clear_results_button = document.createElement("button") + clear_results_button.className = "btn btn-danger rounded-0 mb-5" + clear_results_button.textContent = getTranslation("Clear Results") + search_container.appendChild(clear_results_button) + clear_results_button.onclick = function () { + search_container.innerHTML = "" + document.getElementById("Plugins").classList.remove("d-none") + } + + let item_type_container = document.createElement("div") + search_container.appendChild(item_type_container) + + let sorted + let primary_sort + let secondary_sort + if (search_title === true) { + if (sort_type === "0") { + primary_sort = 'score' + secondary_sort = 'name_lower' + } else { + primary_sort = sort_type + secondary_sort = 'score' + } + sorted = result.sort(rankingSorter(primary_sort, secondary_sort)) + } else { + if (sort_type === "0") { + primary_sort = 'name_lower' + secondary_sort = 'full_name' + } else { + primary_sort = sort_type + secondary_sort = 'full_name' + } + if (primary_sort === "name_lower") { + sorted = result.sort(rankingSorter(primary_sort, secondary_sort)).reverse() + } else { + sorted = result.sort(rankingSorter(primary_sort, secondary_sort)) + } + } + + populate_results(sorted, search_container, false) +} diff --git a/Contents/Resources/web/js/sleep.js b/Contents/Resources/web/js/sleep.js deleted file mode 100644 index c91054d..0000000 --- a/Contents/Resources/web/js/sleep.js +++ /dev/null @@ -1,4 +0,0 @@ -// sleep function -let sleep = ms => { - return new Promise(resolve => setTimeout(resolve, ms)); -}; diff --git a/Contents/Resources/web/js/translations.js b/Contents/Resources/web/js/translations.js new file mode 100644 index 0000000..fe1a239 --- /dev/null +++ b/Contents/Resources/web/js/translations.js @@ -0,0 +1,32 @@ +let translations = null + +let getTranslation = function(string) { + // download translations + if (translations === null) { + $.ajax({ + async: false, + url: "/translations/", + type: "GET", + dataType: "json", + success: function (result) { + translations = result + } + }) + } + + if (translations) { + try { + if (translations[string]) { + return translations[string] + } else { + return string + } + } catch (err) { + return string + } + } + else { + // could not download translations + return string + } +} diff --git a/Contents/Resources/web/templates/base.html b/Contents/Resources/web/templates/base.html index 35360d5..b04d67c 100644 --- a/Contents/Resources/web/templates/base.html +++ b/Contents/Resources/web/templates/base.html @@ -28,20 +28,20 @@ - + -
+ {% block modals %}{% endblock %} +
{% include 'navbar.html' %} -
- {% block content %}{% endblock %}
+ {% block scripts %}{% endblock %} diff --git a/Contents/Resources/web/templates/home.html b/Contents/Resources/web/templates/home.html index 78adb74..3ce543f 100644 --- a/Contents/Resources/web/templates/home.html +++ b/Contents/Resources/web/templates/home.html @@ -1,11 +1,624 @@ {% extends 'base.html' %} -{% block content %} -
-
-
-

Plugger

-

Something something.

+{% block modals %} + {# Install Modal #} + + + {# Logs Modal #} + +{% endblock modals %} + +{% block content %} +
+
+ + + + + +
+
+
+
+

{{ _('Plugins') }}

+
+
+
+
+
+ +
+
{% endblock content %} + +{% block scripts %} + {# Load emoji-js #} + + + + {# Load Plugin List #} + + + {# Install Modal #} + + {# Logs Modal #} + + + +{% endblock scripts %} diff --git a/Contents/Resources/web/templates/logs.html b/Contents/Resources/web/templates/logs.html index 8fcd5c7..3ca018f 100644 --- a/Contents/Resources/web/templates/logs.html +++ b/Contents/Resources/web/templates/logs.html @@ -1,15 +1,68 @@ {% extends 'base.html' %} {% block content %}
-
-
-
-

Logging will appear here:

-
-
{{ logs }}
-
-
+
+ {# Auto refresh toggle #} +
+ + +
+

{{ _('Plugin Logs:') }}

+
+

+                
             
{% endblock content %} + +{% block scripts %} + + + + +{% endblock scripts %} diff --git a/Contents/Resources/web/templates/navbar.html b/Contents/Resources/web/templates/navbar.html index 1fa6eb1..3314f1b 100644 --- a/Contents/Resources/web/templates/navbar.html +++ b/Contents/Resources/web/templates/navbar.html @@ -3,7 +3,7 @@