gitextract_jcsuoc91/ ├── .circleci/ │ └── config.yml ├── .dockerignore ├── .github/ │ └── workflows/ │ └── ci.yml ├── .gitignore ├── .picopt_treestamps.yaml ├── .prettierignore ├── .readthedocs.yaml ├── .shellcheckrc ├── CLAUDE.md ├── Dockerfile ├── LICENSE ├── Makefile ├── NEWS.md ├── README.md ├── bin/ │ ├── benchmark-opds.sh │ ├── build-choices.sh │ ├── build-dist.sh │ ├── ci-download-dist-if-identical.sh │ ├── clean-pycache.sh │ ├── collectstatic.sh │ ├── create-output-dirs.sh │ ├── delete-files.sh │ ├── dev-docker.sh │ ├── dev-module.sh │ ├── dev-prod-server.sh │ ├── dev-reverse-proxy.sh │ ├── dev-server.sh │ ├── dev-ttabs.sh │ ├── docker-compose-exit.sh │ ├── docker-tag-latest.sh │ ├── fix-docker.sh │ ├── fix-python.sh │ ├── fix.sh │ ├── icons_transform.py │ ├── kill-codex.sh │ ├── kill-eslint_d.sh │ ├── lint-ci.sh │ ├── lint-complexity.sh │ ├── lint-darwin.sh │ ├── lint-docker.sh │ ├── lint-python.sh │ ├── lint.sh │ ├── localize-db.sh │ ├── localize_library.sql │ ├── manage.py │ ├── pm │ ├── prettier-nginx.sh │ ├── roman.py │ ├── sort-ignore.sh │ ├── test-python.sh │ ├── uml.sh │ ├── update-deps-node.sh │ ├── update-deps-python.sh │ ├── vendor-diff-package.sh │ ├── vendor-patch-imports.sh │ ├── version-node.sh │ └── version-python.sh ├── cfg/ │ ├── ci.mk │ ├── codex.mk │ ├── common.mk │ ├── django.mk │ ├── docker.mk │ ├── docs.mk │ ├── eslint.config.base.js │ ├── frontend.mk │ ├── help.mk │ ├── node.mk │ ├── node_root.mk │ └── python.mk ├── ci/ │ ├── Dockerfile │ ├── base.Dockerfile │ ├── builder-base.Dockerfile │ ├── circleci-step-halt.sh │ ├── cleanup-repo.py │ ├── debian.sources │ ├── dev.Dockerfile │ ├── dist-builder.Dockerfile │ ├── docker-bake.hcl │ ├── docker-build-image.sh │ ├── docker-compose-exit.sh │ ├── docker-init.sh │ ├── docker-push.sh │ ├── docker-tag-remote-version-as-latest.sh │ ├── machine-arch.sh │ ├── machine-env.sh │ ├── machine-init.sh │ ├── machine-packages.sh │ ├── package.Dockerfile │ ├── python-publish.sh │ ├── version-checksum.sh │ ├── version-codex-base.sh │ ├── version-codex-builder-base.sh │ ├── version-codex-dist-builder.sh │ ├── versions-create-env.sh │ └── versions-env-filename.sh ├── codex/ │ ├── __init__.py │ ├── applications/ │ │ ├── __init__.py │ │ ├── lifespan.py │ │ └── websocket.py │ ├── asgi.py │ ├── authentication.py │ ├── choices/ │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── browser.py │ │ ├── choices_to_json.py │ │ ├── jobs.py │ │ ├── notifications.py │ │ ├── reader.py │ │ ├── search.py │ │ └── statii.py │ ├── librarian/ │ │ ├── README.md │ │ ├── __init__.py │ │ ├── bookmark/ │ │ │ ├── __init__.py │ │ │ ├── bookmarkd.py │ │ │ ├── latest_version.py │ │ │ ├── tasks.py │ │ │ ├── update.py │ │ │ └── user_active.py │ │ ├── covers/ │ │ │ ├── __init__.py │ │ │ ├── coverd.py │ │ │ ├── create.py │ │ │ ├── path.py │ │ │ ├── purge.py │ │ │ ├── status.py │ │ │ └── tasks.py │ │ ├── cron/ │ │ │ ├── __init__.py │ │ │ └── crond.py │ │ ├── fs/ │ │ │ ├── README.md │ │ │ ├── __init__.py │ │ │ ├── event_batcherd.py │ │ │ ├── events.py │ │ │ ├── filters.py │ │ │ ├── poller/ │ │ │ │ ├── __init__.py │ │ │ │ ├── events.py │ │ │ │ ├── poller.py │ │ │ │ ├── snapshot.py │ │ │ │ ├── snapshot_diff.py │ │ │ │ ├── status.py │ │ │ │ └── tasks.py │ │ │ ├── status.py │ │ │ ├── tasks.py │ │ │ └── watcher/ │ │ │ ├── __init__.py │ │ │ ├── data.py │ │ │ ├── dirs.py │ │ │ ├── events.py │ │ │ ├── move.py │ │ │ ├── status.py │ │ │ ├── tasks.py │ │ │ └── watcher.py │ │ ├── librariand.py │ │ ├── memory.py │ │ ├── mp_queue.py │ │ ├── notifier/ │ │ │ ├── __init__.py │ │ │ ├── notifierd.py │ │ │ └── tasks.py │ │ ├── restarter/ │ │ │ ├── __init__.py │ │ │ ├── restarter.py │ │ │ ├── status.py │ │ │ └── tasks.py │ │ ├── scribe/ │ │ │ ├── __init__.py │ │ │ ├── importer/ │ │ │ │ ├── __init__.py │ │ │ │ ├── const.py │ │ │ │ ├── create/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── comics.py │ │ │ │ │ ├── const.py │ │ │ │ │ ├── covers.py │ │ │ │ │ ├── folders.py │ │ │ │ │ ├── foreign_keys.py │ │ │ │ │ └── link_fks.py │ │ │ │ ├── delete/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── comics.py │ │ │ │ │ ├── covers.py │ │ │ │ │ └── folders.py │ │ │ │ ├── failed/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── create.py │ │ │ │ │ ├── failed.py │ │ │ │ │ └── query.py │ │ │ │ ├── finish.py │ │ │ │ ├── importer.py │ │ │ │ ├── init.py │ │ │ │ ├── link/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── const.py │ │ │ │ │ ├── covers.py │ │ │ │ │ ├── delete.py │ │ │ │ │ ├── many_to_many.py │ │ │ │ │ ├── prepare.py │ │ │ │ │ └── sum.py │ │ │ │ ├── moved/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── comics.py │ │ │ │ │ ├── covers.py │ │ │ │ │ └── folders.py │ │ │ │ ├── query/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── covers.py │ │ │ │ │ ├── filters.py │ │ │ │ │ ├── foreign_keys.py │ │ │ │ │ ├── links.py │ │ │ │ │ ├── links_fk.py │ │ │ │ │ ├── links_m2m.py │ │ │ │ │ ├── update_comics.py │ │ │ │ │ └── update_fks.py │ │ │ │ ├── read/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── aggregate_path.py │ │ │ │ │ ├── const.py │ │ │ │ │ ├── extract.py │ │ │ │ │ ├── folders.py │ │ │ │ │ ├── foreign_keys.py │ │ │ │ │ └── many_to_many.py │ │ │ │ ├── search/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── prepare.py │ │ │ │ │ ├── sync_m2m.py │ │ │ │ │ └── update.py │ │ │ │ ├── statii/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── create.py │ │ │ │ │ ├── delete.py │ │ │ │ │ ├── failed.py │ │ │ │ │ ├── link.py │ │ │ │ │ ├── moved.py │ │ │ │ │ ├── query.py │ │ │ │ │ ├── read.py │ │ │ │ │ └── search.py │ │ │ │ ├── status.py │ │ │ │ └── tasks.py │ │ │ ├── janitor/ │ │ │ │ ├── __init__.py │ │ │ │ ├── adopt_folders.py │ │ │ │ ├── cleanup.py │ │ │ │ ├── failed_imports.py │ │ │ │ ├── integrity/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── foreign_keys.py │ │ │ │ ├── janitor.py │ │ │ │ ├── scheduled_time.py │ │ │ │ ├── status.py │ │ │ │ ├── tasks.py │ │ │ │ ├── update.py │ │ │ │ └── vacuum.py │ │ │ ├── lazy_importer.py │ │ │ ├── priority.py │ │ │ ├── scribed.py │ │ │ ├── search/ │ │ │ │ ├── __init__.py │ │ │ │ ├── const.py │ │ │ │ ├── handler.py │ │ │ │ ├── optimize.py │ │ │ │ ├── prepare.py │ │ │ │ ├── remove.py │ │ │ │ ├── status.py │ │ │ │ ├── sync.py │ │ │ │ └── tasks.py │ │ │ ├── status.py │ │ │ ├── tasks.py │ │ │ └── timestamp_update.py │ │ ├── status.py │ │ ├── status_controller.py │ │ ├── tasks.py │ │ ├── telemeter/ │ │ │ ├── __init__.py │ │ │ ├── scheduled_time.py │ │ │ ├── stats.py │ │ │ ├── tasks.py │ │ │ └── telemeter.py │ │ ├── threads.py │ │ └── worker.py │ ├── middleware.py │ ├── migrations/ │ │ ├── 0001_init.py │ │ ├── 0002_auto_20200826_0622.py │ │ ├── 0003_auto_20200831_2033.py │ │ ├── 0004_failedimport.py │ │ ├── 0005_auto_20200918_0146.py │ │ ├── 0006_update_default_names_and_remove_duplicate_comics.py │ │ ├── 0007_auto_20211210_1710.py │ │ ├── 0008_alter_comic_created_at_alter_comic_format_and_more.py │ │ ├── 0009_alter_comic_parent_folder.py │ │ ├── 0010_haystack.py │ │ ├── 0011_library_groups_and_metadata_changes.py │ │ ├── 0012_rename_description_comic_comments.py │ │ ├── 0013_int_issue_count_longer_charfields.py │ │ ├── 0014_pdf_issue_suffix_remove_cover_image_sort_name.py │ │ ├── 0015_link_comics_to_top_level_folders.py │ │ ├── 0016_remove_comic_cover_path_librarianstatus.py │ │ ├── 0017_alter_timestamp_options_alter_adminflag_name_and_more.py │ │ ├── 0018_rename_userbookmark_bookmark.py │ │ ├── 0019_delete_queuejob.py │ │ ├── 0020_remove_search_tables.py │ │ ├── 0021_bookmark_fit_to_choices_read_in_reverse.py │ │ ├── 0022_bookmark_vertical_useractive_null_statuses.py │ │ ├── 0023_rename_credit_creator_and_more.py │ │ ├── 0024_comic_gtin_comic_story_arc_number.py │ │ ├── 0025_add_story_arc_number.py │ │ ├── 0026_comicbox_1.py │ │ ├── 0027_import_order_and_covers.py │ │ ├── 0028_telemeter.py │ │ ├── 0029_comicfts.py │ │ ├── 0030_nocase_collation_day_month_indexes_status_types.py │ │ ├── 0031_adminflag_banner.py │ │ ├── 0032_alter_librarianstatus_preactive.py │ │ ├── 0033_alter_librarianstatus_status_type.py │ │ ├── 0034_comicbox2.py │ │ ├── 0035_fts_optmize.py │ │ ├── 0036_alter_comic_path_alter_customcover_path_and_more.py │ │ ├── 0037_redefine_reading_direction_filetype_choices.py │ │ ├── 0038_settings_tables.py │ │ └── __init__.py │ ├── models/ │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── base.py │ │ ├── bookmark.py │ │ ├── choices.py │ │ ├── comic.py │ │ ├── fields.py │ │ ├── functions.py │ │ ├── groups.py │ │ ├── identifier.py │ │ ├── library.py │ │ ├── named.py │ │ ├── paths.py │ │ ├── query.py │ │ ├── settings.py │ │ └── util.py │ ├── run.py │ ├── serializers/ │ │ ├── README.md │ │ ├── __init__.py │ │ ├── admin/ │ │ │ ├── __init__.py │ │ │ ├── flags.py │ │ │ ├── groups.py │ │ │ ├── libraries.py │ │ │ ├── stats.py │ │ │ ├── tasks.py │ │ │ └── users.py │ │ ├── auth.py │ │ ├── browser/ │ │ │ ├── __init__.py │ │ │ ├── choices.py │ │ │ ├── filters.py │ │ │ ├── metadata.py │ │ │ ├── mixins.py │ │ │ ├── mtime.py │ │ │ ├── page.py │ │ │ ├── saved.py │ │ │ └── settings.py │ │ ├── fields/ │ │ │ ├── __init__.py │ │ │ ├── auth.py │ │ │ ├── base.py │ │ │ ├── browser.py │ │ │ ├── group.py │ │ │ ├── reader.py │ │ │ ├── sanitized.py │ │ │ ├── settings.py │ │ │ ├── stats.py │ │ │ └── vuetify.py │ │ ├── homepage.py │ │ ├── mixins.py │ │ ├── models/ │ │ │ ├── __init__.py │ │ │ ├── admin.py │ │ │ ├── base.py │ │ │ ├── bookmark.py │ │ │ ├── comic.py │ │ │ ├── groups.py │ │ │ ├── named.py │ │ │ └── pycountry.py │ │ ├── opds/ │ │ │ ├── __init__.py │ │ │ ├── authentication.py │ │ │ ├── urls.py │ │ │ ├── v1.py │ │ │ └── v2/ │ │ │ ├── __init__.py │ │ │ ├── facet.py │ │ │ ├── feed.py │ │ │ ├── links.py │ │ │ ├── metadata.py │ │ │ ├── progression.py │ │ │ ├── publication.py │ │ │ └── unused.py │ │ ├── reader.py │ │ ├── redirect.py │ │ ├── route.py │ │ ├── settings.py │ │ └── versions.py │ ├── settings/ │ │ ├── README.md │ │ ├── __init__.py │ │ ├── codex.toml.default │ │ ├── config.py │ │ ├── hypercorn_migrate.py │ │ ├── logging.py │ │ ├── secret_key.py │ │ ├── servestatic.py │ │ └── timezone.py │ ├── signals/ │ │ ├── __init__.py │ │ ├── django_signals.py │ │ └── os_signals.py │ ├── startup/ │ │ ├── __init__.py │ │ ├── custom_cover_libraries.py │ │ ├── db.py │ │ ├── loguru.py │ │ └── registration.py │ ├── static_src/ │ │ ├── img/ │ │ │ └── .picopt_treestamps.yaml │ │ ├── pwa/ │ │ │ └── offline.html │ │ └── robots.txt │ ├── templates/ │ │ ├── README.md │ │ ├── headers-icons.html │ │ ├── headers-script-globals.html │ │ ├── index.html │ │ ├── opds_v1/ │ │ │ ├── index.xml │ │ │ └── opensearch_v1.xml │ │ └── pwa/ │ │ ├── headers.html │ │ ├── manifest.webmanifest │ │ ├── serviceworker-register.js │ │ └── serviceworker.js │ ├── urls/ │ │ ├── __init__.py │ │ ├── api/ │ │ │ ├── __init__.py │ │ │ ├── admin.py │ │ │ ├── auth.py │ │ │ ├── browser.py │ │ │ ├── reader.py │ │ │ ├── root.py │ │ │ └── v3.py │ │ ├── app.py │ │ ├── const.py │ │ ├── converters.py │ │ ├── opds/ │ │ │ ├── __init__.py │ │ │ ├── authentication.py │ │ │ ├── binary.py │ │ │ ├── root.py │ │ │ ├── v1.py │ │ │ └── v2.py │ │ ├── pwa.py │ │ ├── root.py │ │ └── spectacular.py │ ├── util.py │ ├── version.py │ ├── views/ │ │ ├── README.md │ │ ├── __init__.py │ │ ├── admin/ │ │ │ ├── __init__.py │ │ │ ├── api_key.py │ │ │ ├── auth.py │ │ │ ├── flag.py │ │ │ ├── group.py │ │ │ ├── library.py │ │ │ ├── permissions.py │ │ │ ├── stats.py │ │ │ ├── tasks.py │ │ │ └── user.py │ │ ├── auth.py │ │ ├── bookmark.py │ │ ├── browser/ │ │ │ ├── __init__.py │ │ │ ├── annotate/ │ │ │ │ ├── __init__.py │ │ │ │ ├── bookmark.py │ │ │ │ ├── card.py │ │ │ │ └── order.py │ │ │ ├── bookmark.py │ │ │ ├── breadcrumbs.py │ │ │ ├── browser.py │ │ │ ├── choices.py │ │ │ ├── const.py │ │ │ ├── cover.py │ │ │ ├── download.py │ │ │ ├── filters/ │ │ │ │ ├── __init__.py │ │ │ │ ├── bookmark.py │ │ │ │ ├── field.py │ │ │ │ ├── filter.py │ │ │ │ ├── group.py │ │ │ │ └── search/ │ │ │ │ ├── __init__.py │ │ │ │ ├── field/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── column.py │ │ │ │ │ ├── expression.py │ │ │ │ │ ├── filter.py │ │ │ │ │ ├── optimize.py │ │ │ │ │ └── parse.py │ │ │ │ ├── fts.py │ │ │ │ └── parse.py │ │ │ ├── group_mtime.py │ │ │ ├── metadata/ │ │ │ │ ├── __init__.py │ │ │ │ ├── annotate.py │ │ │ │ ├── const.py │ │ │ │ ├── copy_intersections.py │ │ │ │ └── query_intersections.py │ │ │ ├── mtime.py │ │ │ ├── order_by.py │ │ │ ├── page_in_bounds.py │ │ │ ├── paginate.py │ │ │ ├── params.py │ │ │ ├── saved_settings.py │ │ │ ├── settings.py │ │ │ ├── title.py │ │ │ └── validate.py │ │ ├── const.py │ │ ├── download.py │ │ ├── error.py │ │ ├── exceptions.py │ │ ├── frontend.py │ │ ├── healthcheck.py │ │ ├── lazy_import.py │ │ ├── mixins.py │ │ ├── opds/ │ │ │ ├── __init__.py │ │ │ ├── auth.py │ │ │ ├── authentication/ │ │ │ │ ├── __init__.py │ │ │ │ └── v1.py │ │ │ ├── binary.py │ │ │ ├── const.py │ │ │ ├── error.py │ │ │ ├── feed.py │ │ │ ├── metadata.py │ │ │ ├── opensearch/ │ │ │ │ ├── __init__.py │ │ │ │ └── v1.py │ │ │ ├── settings.py │ │ │ ├── start.py │ │ │ ├── urls.py │ │ │ ├── user_agent.py │ │ │ ├── v1/ │ │ │ │ ├── __init__.py │ │ │ │ ├── const.py │ │ │ │ ├── entry/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── entry.py │ │ │ │ │ └── links.py │ │ │ │ ├── facets.py │ │ │ │ ├── feed.py │ │ │ │ └── links.py │ │ │ └── v2/ │ │ │ ├── __init__.py │ │ │ ├── const.py │ │ │ ├── feed/ │ │ │ │ ├── __init__.py │ │ │ │ ├── feed_links.py │ │ │ │ ├── groups.py │ │ │ │ ├── links.py │ │ │ │ └── publications.py │ │ │ ├── href.py │ │ │ ├── manifest.py │ │ │ └── progression.py │ │ ├── public.py │ │ ├── pwa.py │ │ ├── reader/ │ │ │ ├── __init__.py │ │ │ ├── arcs.py │ │ │ ├── books.py │ │ │ ├── page.py │ │ │ ├── params.py │ │ │ ├── reader.py │ │ │ └── settings.py │ │ ├── settings.py │ │ ├── template.py │ │ ├── timezone.py │ │ ├── util.py │ │ └── version.py │ └── websockets/ │ ├── README.md │ ├── __init__.py │ ├── consumers.py │ ├── listener.py │ └── mp_queue.py ├── compose.yaml ├── docs/ │ ├── DOCKER.md │ ├── WINDOWS.md │ ├── requirements.txt │ ├── style.material.css │ ├── style.mkdocs.css │ └── style.readthedocs.css ├── eslint.config.js ├── frontend/ │ ├── .gitignore │ ├── .npmrc │ ├── .prettierignore │ ├── .remarkignore │ ├── .shellcheckrc │ ├── Makefile │ ├── README.md │ ├── bin/ │ │ ├── dev-server.sh │ │ ├── fix.sh │ │ ├── kill-eslint_d.sh │ │ ├── lint-darwin.sh │ │ ├── lint.sh │ │ ├── roman.py │ │ ├── sort-ignore.sh │ │ ├── update-deps-node.sh │ │ └── version-node.sh │ ├── cfg/ │ │ ├── codex-frontend.mk │ │ ├── common.mk │ │ ├── help.mk │ │ └── node.mk │ ├── jsconfig.json │ ├── package.json │ ├── src/ │ │ ├── admin.vue │ │ ├── api/ │ │ │ └── v3/ │ │ │ ├── admin.js │ │ │ ├── auth.js │ │ │ ├── base.js │ │ │ ├── browser.js │ │ │ ├── common.js │ │ │ ├── notify.js │ │ │ ├── reader.js │ │ │ └── vuetify-items.js │ │ ├── app.vue │ │ ├── browser.vue │ │ ├── comic-name.js │ │ ├── components/ │ │ │ ├── admin/ │ │ │ │ ├── admin-header.vue │ │ │ │ ├── browser-link.vue │ │ │ │ ├── create-update-dialog/ │ │ │ │ │ ├── create-update-button.vue │ │ │ │ │ ├── create-update-dialog.vue │ │ │ │ │ ├── create-update-inputs-mixin.js │ │ │ │ │ ├── duration-input.vue │ │ │ │ │ ├── group-create-update-inputs.vue │ │ │ │ │ ├── library-create-update-inputs.vue │ │ │ │ │ ├── relation-picker.vue │ │ │ │ │ ├── server-folder-picker.vue │ │ │ │ │ └── user-create-update-inputs.vue │ │ │ │ ├── drawer/ │ │ │ │ │ ├── admin-menu.vue │ │ │ │ │ ├── admin-settings-button-progress.vue │ │ │ │ │ ├── admin-settings-drawer.vue │ │ │ │ │ ├── admin-settings-panel.vue │ │ │ │ │ ├── status-list-item.vue │ │ │ │ │ └── status-list.vue │ │ │ │ ├── group-chip.vue │ │ │ │ ├── status-helpers.js │ │ │ │ ├── tabs/ │ │ │ │ │ ├── admin-table.vue │ │ │ │ │ ├── custom-covers-panel.vue │ │ │ │ │ ├── datetime-column.vue │ │ │ │ │ ├── delete-row-dialog.vue │ │ │ │ │ ├── failed-imports-panel.vue │ │ │ │ │ ├── flag-descriptions.json │ │ │ │ │ ├── flag-tab.vue │ │ │ │ │ ├── group-tab.vue │ │ │ │ │ ├── job-tab.vue │ │ │ │ │ ├── library-tab.vue │ │ │ │ │ ├── library-table.vue │ │ │ │ │ ├── relation-chips.vue │ │ │ │ │ ├── stats-tab.vue │ │ │ │ │ ├── stats-table.vue │ │ │ │ │ ├── tabs.vue │ │ │ │ │ └── user-tab.vue │ │ │ │ └── use-now-timer.js │ │ │ ├── anchors.scss │ │ │ ├── auth/ │ │ │ │ ├── auth-form-mixin.js │ │ │ │ ├── auth-menu.vue │ │ │ │ ├── auth-token.vue │ │ │ │ ├── change-password-dialog.vue │ │ │ │ └── login-dialog.vue │ │ │ ├── banner.vue │ │ │ ├── book-cover.scss │ │ │ ├── book-cover.vue │ │ │ ├── browser/ │ │ │ │ ├── browser-header.vue │ │ │ │ ├── card/ │ │ │ │ │ ├── browser-card-menu.vue │ │ │ │ │ ├── card.vue │ │ │ │ │ ├── controls.vue │ │ │ │ │ ├── order-by-caption.vue │ │ │ │ │ └── subtitle.vue │ │ │ │ ├── drawer/ │ │ │ │ │ ├── browser-settings-covers.vue │ │ │ │ │ ├── browser-settings-drawer.vue │ │ │ │ │ ├── browser-settings-group.vue │ │ │ │ │ ├── browser-settings-misc.vue │ │ │ │ │ ├── browser-settings-panel.vue │ │ │ │ │ └── browser-settings-saved.vue │ │ │ │ ├── empty.vue │ │ │ │ ├── filter-warning-snackbar.vue │ │ │ │ ├── main.vue │ │ │ │ └── toolbars/ │ │ │ │ ├── breadcrumbs/ │ │ │ │ │ ├── breadcrumbs.vue │ │ │ │ │ └── browser-toolbar-breadcrumbs.vue │ │ │ │ ├── browser-toolbar-title.vue │ │ │ │ ├── nav/ │ │ │ │ │ ├── browser-nav-button.vue │ │ │ │ │ └── browser-toolbar-nav.vue │ │ │ │ ├── search/ │ │ │ │ │ ├── browser-toolbar-search.vue │ │ │ │ │ ├── search-combobox.vue │ │ │ │ │ ├── search-help-text.vue │ │ │ │ │ └── search-help.vue │ │ │ │ ├── select-many/ │ │ │ │ │ └── browser-toolbar-select-many.vue │ │ │ │ └── top/ │ │ │ │ ├── browser-toolbar-top.vue │ │ │ │ ├── filter-by-select.vue │ │ │ │ ├── filter-sub-menu.vue │ │ │ │ ├── order-by-select.vue │ │ │ │ ├── order-reverse-button.vue │ │ │ │ ├── search-button.vue │ │ │ │ ├── toolbar-button.vue │ │ │ │ └── top-group-select.vue │ │ │ ├── cancel-button.vue │ │ │ ├── clipboard.vue │ │ │ ├── close-button.vue │ │ │ ├── codex-list-item.vue │ │ │ ├── confirm-dialog.vue │ │ │ ├── confirm-footer.vue │ │ │ ├── download-button.vue │ │ │ ├── empty.vue │ │ │ ├── mark-read-button.vue │ │ │ ├── metadata/ │ │ │ │ ├── expand-button.vue │ │ │ │ ├── metadata-activator.vue │ │ │ │ ├── metadata-body.vue │ │ │ │ ├── metadata-chip.vue │ │ │ │ ├── metadata-controls.vue │ │ │ │ ├── metadata-cover.vue │ │ │ │ ├── metadata-dialog.vue │ │ │ │ ├── metadata-header.vue │ │ │ │ ├── metadata-ratings.vue │ │ │ │ ├── metadata-tags.vue │ │ │ │ ├── metadata-text.vue │ │ │ │ ├── table.scss │ │ │ │ └── tags-table.vue │ │ │ ├── pagination-nav-button.vue │ │ │ ├── pagination-slider.vue │ │ │ ├── pagination-toolbar.vue │ │ │ ├── placeholder-loading.vue │ │ │ ├── reader/ │ │ │ │ ├── book-change-activator.vue │ │ │ │ ├── book-change-drawer.vue │ │ │ │ ├── books-window.vue │ │ │ │ ├── change-column.scss │ │ │ │ ├── drawer/ │ │ │ │ │ ├── download-panel.vue │ │ │ │ │ ├── keyboard-shortcuts-panel.vue │ │ │ │ │ ├── keyboard-shortcuts-table.vue │ │ │ │ │ ├── reader-settings-controls.vue │ │ │ │ │ ├── reader-settings-drawer.vue │ │ │ │ │ ├── reader-settings-panel.vue │ │ │ │ │ ├── reader-settings-reader.vue │ │ │ │ │ └── reader-settings-scope.vue │ │ │ │ ├── empty.vue │ │ │ │ ├── pager/ │ │ │ │ │ ├── horizontal-pages.vue │ │ │ │ │ ├── page/ │ │ │ │ │ │ ├── page-error.vue │ │ │ │ │ │ ├── page-img.vue │ │ │ │ │ │ ├── page-loading.vue │ │ │ │ │ │ └── page.vue │ │ │ │ │ ├── page-change-link.vue │ │ │ │ │ ├── pager-full-pdf.vue │ │ │ │ │ ├── pager-horizontal.vue │ │ │ │ │ ├── pager-vertical.vue │ │ │ │ │ ├── pager.vue │ │ │ │ │ ├── pdf-doc.vue │ │ │ │ │ └── scale-for-scroll.vue │ │ │ │ └── toolbars/ │ │ │ │ ├── nav/ │ │ │ │ │ ├── reader-book-change-nav-button.vue │ │ │ │ │ ├── reader-nav-button.vue │ │ │ │ │ └── reader-toolbar-nav.vue │ │ │ │ └── top/ │ │ │ │ ├── reader-arc-select.vue │ │ │ │ └── reader-toolbar-top.vue │ │ │ ├── scale-button.vue │ │ │ ├── settings/ │ │ │ │ ├── button.vue │ │ │ │ ├── docs-footer.vue │ │ │ │ ├── opds-dialog.vue │ │ │ │ ├── opds-url.vue │ │ │ │ ├── settings-drawer.vue │ │ │ │ └── version-footer.vue │ │ │ ├── submit-footer.vue │ │ │ ├── toolbar-select.vue │ │ │ └── unauthorized.vue │ │ ├── datetime.js │ │ ├── http-error.vue │ │ ├── main.js │ │ ├── platform.js │ │ ├── plugins/ │ │ │ ├── drag-scroll.js │ │ │ ├── router.js │ │ │ └── vuetify.js │ │ ├── reader.vue │ │ ├── route.js │ │ ├── stores/ │ │ │ ├── admin.js │ │ │ ├── auth.js │ │ │ ├── browser-select-many.js │ │ │ ├── browser.js │ │ │ ├── common.js │ │ │ ├── metadata.js │ │ │ ├── reader.js │ │ │ ├── socket.js │ │ │ └── store.js │ │ └── util.js │ ├── tests/ │ │ └── unit/ │ │ └── reader-nav-button.test.js │ └── vite.config.js ├── mkdocs.yml ├── mock_comics/ │ ├── __init__.py │ ├── bigbook.py │ ├── mock_comics.py │ └── mock_comics.sh ├── nginx/ │ └── default.conf ├── package.json ├── pyproject.toml ├── tests/ │ ├── README.md │ ├── __init__.py │ ├── files/ │ │ ├── comicbox-2-example.cbz │ │ ├── comicbox-2-update.cbz │ │ ├── comicbox.example.yaml │ │ └── comicbox.update.yaml │ ├── importer/ │ │ ├── __init__.py │ │ ├── test_basic.py │ │ ├── test_update_all.py │ │ └── test_update_none.py │ ├── nginx-local-codex.conf │ ├── test_asgi.py │ └── test_models.py └── vulture_ignorelist.py