From 3b581b1f03616f3939b8cd7d6da30bbd20b903b8 Mon Sep 17 00:00:00 2001 From: dunxd Date: Sun, 22 Sep 2024 10:53:15 +0000 Subject: [PATCH] Fix error in run.sh and remove 3.1.3 --- COPS/CHANGELOG.md | 2 +- COPS/config.yaml | 2 +- COPS/cops-3.1.3/.dockerignore | 24 - COPS/cops-3.1.3/.editorconfig | 10 - COPS/cops-3.1.3/.gitremotes | 9 - COPS/cops-3.1.3/.htaccess | 87 - COPS/cops-3.1.3/CHANGELOG.md | 413 - COPS/cops-3.1.3/CHANGELOG.seblucas.md | 326 - COPS/cops-3.1.3/COPYING | 340 - COPS/cops-3.1.3/README.md | 183 - COPS/cops-3.1.3/calres.php | 13 - COPS/cops-3.1.3/checkconfig.php | 338 - COPS/cops-3.1.3/config/config.php | 52 - COPS/cops-3.1.3/config/default.php | 650 - COPS/cops-3.1.3/config/loader.php | 75 - COPS/cops-3.1.3/config/local.php.example | 78 - COPS/cops-3.1.3/config/test.php | 24 - COPS/cops-3.1.3/epubfs.php | 13 - COPS/cops-3.1.3/epubreader.php | 13 - COPS/cops-3.1.3/favicon.ico | Bin 15086 -> 0 bytes COPS/cops-3.1.3/feed.php | 13 - COPS/cops-3.1.3/fetch.php | 14 - COPS/cops-3.1.3/getJSON.php | 13 - COPS/cops-3.1.3/graphql.php | 13 - COPS/cops-3.1.3/images/allbook.png | Bin 1172 -> 0 bytes COPS/cops-3.1.3/images/author.png | Bin 1198 -> 0 bytes COPS/cops-3.1.3/images/bookcover.png | Bin 3057 -> 0 bytes COPS/cops-3.1.3/images/custom.png | Bin 1687 -> 0 bytes COPS/cops-3.1.3/images/icons/icon114.png | Bin 6867 -> 0 bytes COPS/cops-3.1.3/images/icons/icon144.png | Bin 9018 -> 0 bytes COPS/cops-3.1.3/images/icons/icon57.png | Bin 3309 -> 0 bytes COPS/cops-3.1.3/images/icons/icon72.png | Bin 4330 -> 0 bytes COPS/cops-3.1.3/images/language.png | Bin 1972 -> 0 bytes COPS/cops-3.1.3/images/publisher.png | Bin 215 -> 0 bytes COPS/cops-3.1.3/images/rating.png | Bin 1304 -> 0 bytes COPS/cops-3.1.3/images/recent.png | Bin 1670 -> 0 bytes COPS/cops-3.1.3/images/serie.png | Bin 2156 -> 0 bytes COPS/cops-3.1.3/images/tag.png | Bin 1082 -> 0 bytes COPS/cops-3.1.3/index.php | 15 - COPS/cops-3.1.3/lang/Localization_af.json | 327 - COPS/cops-3.1.3/lang/Localization_bg.json | 327 - COPS/cops-3.1.3/lang/Localization_ca.json | 327 - COPS/cops-3.1.3/lang/Localization_cs.json | 327 - COPS/cops-3.1.3/lang/Localization_da.json | 327 - COPS/cops-3.1.3/lang/Localization_de.json | 327 - COPS/cops-3.1.3/lang/Localization_el.json | 327 - COPS/cops-3.1.3/lang/Localization_en.json | 333 - COPS/cops-3.1.3/lang/Localization_es.json | 327 - COPS/cops-3.1.3/lang/Localization_eu.json | 327 - COPS/cops-3.1.3/lang/Localization_fr.json | 333 - COPS/cops-3.1.3/lang/Localization_gl.json | 327 - COPS/cops-3.1.3/lang/Localization_hr.json | 327 - COPS/cops-3.1.3/lang/Localization_ht.json | 327 - COPS/cops-3.1.3/lang/Localization_hu.json | 327 - COPS/cops-3.1.3/lang/Localization_id.json | 327 - COPS/cops-3.1.3/lang/Localization_it.json | 332 - COPS/cops-3.1.3/lang/Localization_ja.json | 327 - COPS/cops-3.1.3/lang/Localization_ko.json | 327 - COPS/cops-3.1.3/lang/Localization_nb.json | 327 - COPS/cops-3.1.3/lang/Localization_nl.json | 332 - COPS/cops-3.1.3/lang/Localization_pl.json | 332 - COPS/cops-3.1.3/lang/Localization_pt_BR.json | 327 - COPS/cops-3.1.3/lang/Localization_pt_PT.json | 333 - COPS/cops-3.1.3/lang/Localization_ro.json | 332 - COPS/cops-3.1.3/lang/Localization_ru.json | 327 - COPS/cops-3.1.3/lang/Localization_sl.json | 327 - COPS/cops-3.1.3/lang/Localization_sr.json | 327 - COPS/cops-3.1.3/lang/Localization_sv.json | 327 - COPS/cops-3.1.3/lang/Localization_tr.json | 327 - COPS/cops-3.1.3/lang/Localization_uk.json | 327 - COPS/cops-3.1.3/lang/Localization_zh_CN.json | 327 - COPS/cops-3.1.3/lang/Localization_zh_TW.json | 327 - COPS/cops-3.1.3/loader.php | 18 - COPS/cops-3.1.3/login.html | 97 - COPS/cops-3.1.3/mike.php | 3 - COPS/cops-3.1.3/opds.php | 18 - COPS/cops-3.1.3/package.json | 21 - COPS/cops-3.1.3/phpstan-baseline.neon | 41 - COPS/cops-3.1.3/phpstan.neon.dist | 15 - COPS/cops-3.1.3/phpunit.xml.dist | 27 - COPS/cops-3.1.3/rector.php | 40 - COPS/cops-3.1.3/resources/dot-php/LICENSE | 339 - COPS/cops-3.1.3/resources/dot-php/README.md | 41 - .../resources/dot-php/composer.json | 22 - COPS/cops-3.1.3/resources/dot-php/doT.php | 146 - COPS/cops-3.1.3/resources/monocle/README.md | 150 - .../resources/monocle/scripts/monocore.js | 5641 -------- .../resources/monocle/scripts/monoctrl.js | 985 -- .../resources/monocle/styles/monocore.css | 195 - .../resources/monocle/styles/monoctrl.css | 169 - .../simonpioli/sortelements/README.md | 35 - .../sortelements/jquery.sortElements.js | 69 - COPS/cops-3.1.3/restapi.php | 13 - COPS/cops-3.1.3/router.php | 34 - COPS/cops-3.1.3/schema.graphql | 269 - COPS/cops-3.1.3/sendtomail.php | 13 - COPS/cops-3.1.3/src/Calibre/Annotation.php | 211 - COPS/cops-3.1.3/src/Calibre/Author.php | 88 - COPS/cops-3.1.3/src/Calibre/Base.php | 576 - COPS/cops-3.1.3/src/Calibre/BaseList.php | 635 - COPS/cops-3.1.3/src/Calibre/Book.php | 879 -- COPS/cops-3.1.3/src/Calibre/BookList.php | 622 - COPS/cops-3.1.3/src/Calibre/Category.php | 181 - COPS/cops-3.1.3/src/Calibre/Cover.php | 437 - COPS/cops-3.1.3/src/Calibre/CustomColumn.php | 216 - .../src/Calibre/CustomColumnType.php | 572 - .../src/Calibre/CustomColumnTypeBool.php | 162 - .../src/Calibre/CustomColumnTypeComment.php | 125 - .../src/Calibre/CustomColumnTypeDate.php | 241 - .../Calibre/CustomColumnTypeEnumeration.php | 151 - .../src/Calibre/CustomColumnTypeFloat.php | 137 - .../src/Calibre/CustomColumnTypeInteger.php | 231 - .../src/Calibre/CustomColumnTypeRating.php | 169 - .../src/Calibre/CustomColumnTypeSeries.php | 151 - .../src/Calibre/CustomColumnTypeText.php | 177 - COPS/cops-3.1.3/src/Calibre/Data.php | 326 - COPS/cops-3.1.3/src/Calibre/Database.php | 440 - COPS/cops-3.1.3/src/Calibre/Filter.php | 491 - COPS/cops-3.1.3/src/Calibre/Identifier.php | 191 - COPS/cops-3.1.3/src/Calibre/Language.php | 91 - COPS/cops-3.1.3/src/Calibre/Metadata.php | 197 - COPS/cops-3.1.3/src/Calibre/Note.php | 176 - COPS/cops-3.1.3/src/Calibre/Preference.php | 118 - COPS/cops-3.1.3/src/Calibre/Publisher.php | 66 - COPS/cops-3.1.3/src/Calibre/Rating.php | 72 - COPS/cops-3.1.3/src/Calibre/Resource.php | 138 - COPS/cops-3.1.3/src/Calibre/Serie.php | 69 - COPS/cops-3.1.3/src/Calibre/Tag.php | 72 - COPS/cops-3.1.3/src/Calibre/User.php | 152 - .../cops-3.1.3/src/Calibre/VirtualLibrary.php | 204 - COPS/cops-3.1.3/src/Framework.php | 132 - COPS/cops-3.1.3/src/Handlers/BaseHandler.php | 42 - .../cops-3.1.3/src/Handlers/CalResHandler.php | 48 - COPS/cops-3.1.3/src/Handlers/CheckHandler.php | 344 - .../cops-3.1.3/src/Handlers/EpubFsHandler.php | 64 - COPS/cops-3.1.3/src/Handlers/FeedHandler.php | 66 - COPS/cops-3.1.3/src/Handlers/FetchHandler.php | 235 - .../src/Handlers/GraphQLHandler.php | 345 - COPS/cops-3.1.3/src/Handlers/HtmlHandler.php | 72 - COPS/cops-3.1.3/src/Handlers/JsonHandler.php | 45 - .../cops-3.1.3/src/Handlers/LoaderHandler.php | 93 - COPS/cops-3.1.3/src/Handlers/MailHandler.php | 58 - COPS/cops-3.1.3/src/Handlers/OpdsHandler.php | 68 - COPS/cops-3.1.3/src/Handlers/PageHandler.php | 73 - .../src/Handlers/QueueBasedHandler.php | 62 - COPS/cops-3.1.3/src/Handlers/ReadHandler.php | 54 - .../src/Handlers/RestApiHandler.php | 86 - COPS/cops-3.1.3/src/Handlers/ZipFsHandler.php | 64 - .../cops-3.1.3/src/Handlers/ZipperHandler.php | 64 - COPS/cops-3.1.3/src/Input/Config.php | 93 - COPS/cops-3.1.3/src/Input/Context.php | 40 - COPS/cops-3.1.3/src/Input/Request.php | 578 - COPS/cops-3.1.3/src/Input/Route.php | 685 - COPS/cops-3.1.3/src/Language/Translation.php | 205 - COPS/cops-3.1.3/src/Model/Entry.php | 192 - COPS/cops-3.1.3/src/Model/EntryBook.php | 56 - COPS/cops-3.1.3/src/Model/Link.php | 50 - COPS/cops-3.1.3/src/Model/LinkEntry.php | 50 - COPS/cops-3.1.3/src/Model/LinkFacet.php | 47 - COPS/cops-3.1.3/src/Model/LinkFeed.php | 61 - COPS/cops-3.1.3/src/Model/LinkNavigation.php | 24 - COPS/cops-3.1.3/src/Output/BaseRenderer.php | 58 - COPS/cops-3.1.3/src/Output/DotPHPTemplate.php | 98 - COPS/cops-3.1.3/src/Output/EPubReader.php | 305 - COPS/cops-3.1.3/src/Output/FileResponse.php | 59 - COPS/cops-3.1.3/src/Output/Format.php | 156 - COPS/cops-3.1.3/src/Output/HtmlRenderer.php | 64 - COPS/cops-3.1.3/src/Output/JsonRenderer.php | 758 -- COPS/cops-3.1.3/src/Output/KiwilanOPDS.php | 237 - COPS/cops-3.1.3/src/Output/Mail.php | 136 - COPS/cops-3.1.3/src/Output/OpdsRenderer.php | 498 - COPS/cops-3.1.3/src/Output/Response.php | 167 - COPS/cops-3.1.3/src/Output/RestApi.php | 881 -- COPS/cops-3.1.3/src/Output/TwigTemplate.php | 85 - COPS/cops-3.1.3/src/Output/Zipper.php | 302 - COPS/cops-3.1.3/src/Pages/Page.php | 367 - COPS/cops-3.1.3/src/Pages/PageAbout.php | 35 - COPS/cops-3.1.3/src/Pages/PageAllAuthors.php | 45 - .../src/Pages/PageAllAuthorsLetter.php | 50 - COPS/cops-3.1.3/src/Pages/PageAllBooks.php | 47 - .../src/Pages/PageAllBooksLetter.php | 49 - .../cops-3.1.3/src/Pages/PageAllBooksYear.php | 47 - COPS/cops-3.1.3/src/Pages/PageAllCustoms.php | 134 - .../src/Pages/PageAllIdentifiers.php | 44 - .../cops-3.1.3/src/Pages/PageAllLanguages.php | 40 - .../src/Pages/PageAllPublishers.php | 40 - COPS/cops-3.1.3/src/Pages/PageAllRating.php | 44 - COPS/cops-3.1.3/src/Pages/PageAllSeries.php | 51 - COPS/cops-3.1.3/src/Pages/PageAllTags.php | 50 - .../src/Pages/PageAllVirtualLibraries.php | 39 - .../cops-3.1.3/src/Pages/PageAuthorDetail.php | 68 - COPS/cops-3.1.3/src/Pages/PageBookDetail.php | 34 - .../cops-3.1.3/src/Pages/PageCustomDetail.php | 98 - COPS/cops-3.1.3/src/Pages/PageCustomize.php | 210 - COPS/cops-3.1.3/src/Pages/PageId.php | 138 - .../src/Pages/PageIdentifierDetail.php | 56 - COPS/cops-3.1.3/src/Pages/PageIndex.php | 227 - .../src/Pages/PageLanguageDetail.php | 47 - .../src/Pages/PagePublisherDetail.php | 47 - COPS/cops-3.1.3/src/Pages/PageQueryResult.php | 309 - .../cops-3.1.3/src/Pages/PageRatingDetail.php | 47 - COPS/cops-3.1.3/src/Pages/PageRecentBooks.php | 39 - COPS/cops-3.1.3/src/Pages/PageSerieDetail.php | 69 - COPS/cops-3.1.3/src/Pages/PageTagDetail.php | 68 - COPS/cops-3.1.3/src/Pages/PageWithDetail.php | 217 - COPS/cops-3.1.3/src/functions.php | 42 - COPS/cops-3.1.3/styles/cops-monocle.css | 273 - COPS/cops-3.1.3/styles/cops-monocle.js | 184 - COPS/cops-3.1.3/templates/about.html | 26 - .../templates/bootstrap/bookdetail.html | 84 - COPS/cops-3.1.3/templates/bootstrap/file.html | 150 - .../templates/bootstrap/footer.html | 0 .../templates/bootstrap/header.html | 43 - COPS/cops-3.1.3/templates/bootstrap/main.html | 83 - COPS/cops-3.1.3/templates/bootstrap/page.html | 3 - .../templates/bootstrap/scripts/cops.js | 4 - .../templates/bootstrap/styles/style-base.css | 3 - .../bootstrap/styles/style-default.css | 3 - .../templates/bootstrap/suggestion.html | 1 - .../templates/bootstrap2/bookdetail.html | 101 - .../cops-3.1.3/templates/bootstrap2/file.html | 211 - .../templates/bootstrap2/footer.html | 0 .../templates/bootstrap2/header.html | 103 - .../cops-3.1.3/templates/bootstrap2/main.html | 176 - .../cops-3.1.3/templates/bootstrap2/page.html | 3 - .../templates/bootstrap2/scripts/cops.js | 7 - .../bootstrap2/styles/style-base.css | 3 - .../bootstrap2/styles/style-default.css | 3 - .../bootstrap2/styles/style-kindle.css | 139 - .../templates/bootstrap2/styles/typeahead.css | 200 - .../templates/bootstrap2/suggestion.html | 1 - .../templates/bootstrap5/bookdetail.html | 65 - .../cops-3.1.3/templates/bootstrap5/file.html | 107 - .../templates/bootstrap5/footer.html | 19 - .../templates/bootstrap5/header.html | 149 - .../cops-3.1.3/templates/bootstrap5/main.html | 112 - .../cops-3.1.3/templates/bootstrap5/page.html | 4 - .../templates/bootstrap5/scripts/cops.js | 16 - .../bootstrap5/styles/bootstrap5.css | 172 - .../bootstrap5/styles/style-base.css | 3 - .../bootstrap5/styles/style-default.css | 3 - .../templates/bootstrap5/styles/typeahead.css | 200 - .../templates/bootstrap5/suggestion.html | 1 - COPS/cops-3.1.3/templates/checkconfig.html | 78 - .../templates/default/bookdetail.html | 89 - COPS/cops-3.1.3/templates/default/file.html | 45 - COPS/cops-3.1.3/templates/default/footer.html | 15 - COPS/cops-3.1.3/templates/default/header.html | 57 - COPS/cops-3.1.3/templates/default/main.html | 53 - COPS/cops-3.1.3/templates/default/page.html | 5 - .../templates/default/styles/fa-solid.min.css | 5 - .../default/styles/fontawesome.min.css | 5 - .../templates/default/styles/style-base.css | 452 - .../default/styles/style-default.css | 62 - .../templates/default/styles/style-eink.css | 63 - .../templates/default/styles/style-iphone.css | 116 - .../default/styles/style-iphone7.css | 116 - .../templates/default/styles/style-kindle.css | 665 - .../templates/default/styles/typeahead.css | 200 - .../templates/default/suggestion.html | 1 - .../default/webfonts/fa-solid-900.eot | Bin 133140 -> 0 bytes .../default/webfonts/fa-solid-900.svg | 1896 --- .../default/webfonts/fa-solid-900.ttf | Bin 132920 -> 0 bytes .../default/webfonts/fa-solid-900.woff | Bin 63836 -> 0 bytes .../default/webfonts/fa-solid-900.woff2 | Bin 50372 -> 0 bytes COPS/cops-3.1.3/templates/epubjs-reader.html | 36 - COPS/cops-3.1.3/templates/epubreader.html | 52 - COPS/cops-3.1.3/templates/error.html | 13 - COPS/cops-3.1.3/templates/graphql.html | 65 - COPS/cops-3.1.3/templates/notfound.html | 12 - COPS/cops-3.1.3/templates/restapi.html | 26 - COPS/cops-3.1.3/templates/twigged/README.md | 62 - COPS/cops-3.1.3/templates/twigged/about.html | 8 - .../templates/twigged/authordetail.html | 2 - COPS/cops-3.1.3/templates/twigged/base.html | 81 - .../templates/twigged/bookdetail.html | 108 - .../templates/twigged/booklist.html | 100 - .../templates/twigged/customdetail.html | 2 - .../templates/twigged/customize.html | 13 - .../templates/twigged/extra_info.html | 21 - .../templates/twigged/extra_series.html | 20 - .../cops-3.1.3/templates/twigged/filters.html | 17 - .../templates/twigged/identifierdetail.html | 2 - COPS/cops-3.1.3/templates/twigged/index.html | 218 - .../templates/twigged/languagedetail.html | 2 - .../templates/twigged/loader/README.md | 13 - .../templates/twigged/loader/actions.html | 12 - .../templates/twigged/loader/databases.html | 24 - .../templates/twigged/loader/index.html | 131 - .../templates/twigged/mainlist.html | 58 - .../cops-3.1.3/templates/twigged/navlist.html | 23 - COPS/cops-3.1.3/templates/twigged/page.html | 16 - .../templates/twigged/publisherdetail.html | 2 - .../templates/twigged/ratingdetail.html | 2 - COPS/cops-3.1.3/templates/twigged/recent.html | 2 - .../templates/twigged/scripts/cops.js | 40 - .../templates/twigged/seriedetail.html | 2 - .../templates/twigged/styles/style-base.css | 3 - .../twigged/styles/style-default.css | 3 - .../templates/twigged/styles/typeahead.css | 200 - .../templates/twigged/suggestion.html | 1 - .../templates/twigged/tagdetail.html | 2 - .../templates/twigged/var_dump.json.twig | 2 - COPS/cops-3.1.3/util.js | 638 - COPS/cops-3.1.3/vendor/autoload.php | 25 - .../vendor/composer/ClassLoader.php | 579 - .../vendor/composer/InstalledVersions.php | 359 - COPS/cops-3.1.3/vendor/composer/LICENSE | 21 - .../vendor/composer/autoload_classmap.php | 447 - .../vendor/composer/autoload_files.php | 19 - .../vendor/composer/autoload_namespaces.php | 9 - .../vendor/composer/autoload_psr4.php | 17 - .../vendor/composer/autoload_real.php | 50 - .../vendor/composer/autoload_static.php | 533 - .../cops-3.1.3/vendor/composer/installed.json | 1107 -- COPS/cops-3.1.3/vendor/composer/installed.php | 286 - .../vendor/composer/platform_check.php | 30 - .../maennchen/zipstream-php/.editorconfig | 22 - .../zipstream-php/.php-cs-fixer.dist.php | 71 - .../maennchen/zipstream-php/.tool-versions | 1 - .../vendor/maennchen/zipstream-php/LICENSE | 24 - .../vendor/maennchen/zipstream-php/README.md | 183 - .../maennchen/zipstream-php/composer.json | 88 - .../maennchen/zipstream-php/phpdoc.dist.xml | 39 - .../maennchen/zipstream-php/phpunit.xml.dist | 15 - .../vendor/maennchen/zipstream-php/psalm.xml | 23 - .../src/CentralDirectoryFileHeader.php | 52 - .../zipstream-php/src/CompressionMethod.php | 106 - .../zipstream-php/src/DataDescriptor.php | 26 - .../src/EndOfCentralDirectory.php | 35 - .../maennchen/zipstream-php/src/Exception.php | 9 - .../Exception/DosTimeOverflowException.php | 23 - .../src/Exception/FileNotFoundException.php | 22 - .../Exception/FileNotReadableException.php | 22 - .../Exception/FileSizeIncorrectException.php | 23 - .../src/Exception/OverflowException.php | 21 - .../src/Exception/ResourceActionException.php | 29 - .../SimulationFileUnknownException.php | 19 - .../Exception/StreamNotReadableException.php | 21 - .../Exception/StreamNotSeekableException.php | 22 - .../maennchen/zipstream-php/src/File.php | 420 - .../src/GeneralPurposeBitFlag.php | 89 - .../zipstream-php/src/LocalFileHeader.php | 40 - .../zipstream-php/src/OperationMode.php | 35 - .../maennchen/zipstream-php/src/PackField.php | 57 - .../maennchen/zipstream-php/src/Time.php | 45 - .../maennchen/zipstream-php/src/Version.php | 12 - .../src/Zip64/DataDescriptor.php | 28 - .../src/Zip64/EndOfCentralDirectory.php | 43 - .../Zip64/EndOfCentralDirectoryLocator.php | 29 - .../Zip64/ExtendedInformationExtraField.php | 46 - .../maennchen/zipstream-php/src/ZipStream.php | 864 -- .../src/Zs/ExtendedInformationExtraField.php | 23 - .../mikespub/epubjs-reader/.editorconfig | 15 - .../vendor/mikespub/epubjs-reader/.gitremotes | 3 - .../vendor/mikespub/epubjs-reader/LICENSE | 21 - .../vendor/mikespub/epubjs-reader/README.md | 97 - .../mikespub/epubjs-reader/composer.json | 27 - .../vendor/mikespub/epubjs-reader/demo-ui.png | Bin 84906 -> 0 bytes .../epubjs-reader/dist/css/common.css | 120 - .../mikespub/epubjs-reader/dist/css/main.css | 204 - .../epubjs-reader/dist/css/notedlg.css | 129 - .../epubjs-reader/dist/css/sidebar.css | 471 - .../epubjs-reader/dist/css/toolbar.css | 46 - .../epubjs-reader/dist/font/fontello.eot | Bin 10204 -> 0 bytes .../epubjs-reader/dist/font/fontello.svg | 33 - .../epubjs-reader/dist/font/fontello.ttf | Bin 10036 -> 0 bytes .../epubjs-reader/dist/font/fontello.woff | Bin 6032 -> 0 bytes .../epubjs-reader/dist/img/annotations.svg | 57 - .../epubjs-reader/dist/img/bookmark.svg | 34 - .../epubjs-reader/dist/img/bookmarked.svg | 34 - .../epubjs-reader/dist/img/bookmarks.svg | 38 - .../epubjs-reader/dist/img/favicon.png | Bin 477 -> 0 bytes .../epubjs-reader/dist/img/favicon.svg | 1 - .../mikespub/epubjs-reader/dist/img/info.svg | 34 - .../epubjs-reader/dist/img/loader.gif | Bin 6820 -> 0 bytes .../mikespub/epubjs-reader/dist/img/menu.svg | 42 - .../mikespub/epubjs-reader/dist/img/next.svg | 38 - .../epubjs-reader/dist/img/open-book.svg | 42 - .../mikespub/epubjs-reader/dist/img/prev.svg | 38 - .../epubjs-reader/dist/img/resize-full.svg | 46 - .../epubjs-reader/dist/img/resize-small.svg | 46 - .../epubjs-reader/dist/img/search-clear.svg | 38 - .../epubjs-reader/dist/img/search.svg | 38 - .../epubjs-reader/dist/img/settings.svg | 34 - .../mikespub/epubjs-reader/dist/img/toc.svg | 58 - .../epubjs-reader/dist/img/upload.svg | 42 - .../mikespub/epubjs-reader/dist/index.html | 34 - .../epubjs-reader/dist/js/epubreader.js | 3222 ----- .../epubjs-reader/dist/js/epubreader.js.map | 1 - .../epubjs-reader/dist/js/epubreader.min.js | 2 - .../dist/js/epubreader.min.js.map | 1 - .../epubjs-reader/dist/js/libs/epub.min.js | 1 - .../epubjs-reader/dist/js/libs/jszip.min.js | 2 - .../dist/js/libs/jszip.min.js.LICENSE.txt | 11 - .../epubjs-reader/dist/js/libs/md5.min.js | 2 - .../dist/js/libs/md5.min.js.LICENSE.txt | 9 - .../mikespub/epubjs-reader/dist/template.html | 34 - .../epubjs-reader/docs/keybindings.md | 20 - .../mikespub/epubjs-reader/package-lock.json | 4692 ------- .../mikespub/epubjs-reader/package.json | 30 - .../mikespub/epubjs-reader/webpack.config.cjs | 75 - .../vendor/mikespub/php-epub-meta/LICENSE | 21 - .../vendor/mikespub/php-epub-meta/README.md | 55 - .../mikespub/php-epub-meta/composer.json | 46 - .../mikespub/php-epub-meta/composer.lock | 1740 --- .../mikespub/php-epub-meta/package.json | 9 - .../php-epub-meta/phpstan-baseline.neon | 6 - .../mikespub/php-epub-meta/phpstan.neon.dist | 14 - .../vendor/mikespub/php-epub-meta/phpunit.xml | 26 - .../php-epub-meta/src/App/Handler.php | 236 - .../mikespub/php-epub-meta/src/App/Util.php | 55 - .../php-epub-meta/src/Contents/Nav.php | 63 - .../php-epub-meta/src/Contents/NavPoint.php | 109 - .../src/Contents/NavPointList.php | 65 - .../php-epub-meta/src/Contents/Spine.php | 198 - .../php-epub-meta/src/Contents/Toc.php | 63 - .../mikespub/php-epub-meta/src/Data/Item.php | 193 - .../php-epub-meta/src/Data/Manifest.php | 174 - .../php-epub-meta/src/Dom/Element.php | 194 - .../mikespub/php-epub-meta/src/Dom/XPath.php | 32 - .../mikespub/php-epub-meta/src/EPub.php | 2125 --- .../mikespub/php-epub-meta/src/Other.php | 121 - .../php-epub-meta/src/Tools/HtmlTools.php | 97 - .../php-epub-meta/src/Tools/ZipEdit.php | 450 - .../php-epub-meta/src/Tools/ZipFile.php | 343 - .../src/Tools/htmlBlockLevelElements.php | 42 - .../php-epub-meta/src/Tools/htmlEntityMap.php | 260 - .../php-epub-meta/templates/epub.html | 81 - .../php-epub-meta/templates/index.html | 35 - .../php-epub-meta/templates/titlepage.xhtml | 14 - .../vendor/nikic/fast-route/LICENSE | 31 - .../vendor/nikic/fast-route/README.md | 317 - .../vendor/nikic/fast-route/composer.json | 56 - .../fast-route/src/BadRouteException.php | 50 - .../vendor/nikic/fast-route/src/Cache.php | 15 - .../nikic/fast-route/src/Cache/FileCache.php | 113 - .../nikic/fast-route/src/Cache/Psr16Cache.php | 32 - .../nikic/fast-route/src/ConfigureRoutes.php | 113 - .../nikic/fast-route/src/DataGenerator.php | 37 - .../src/DataGenerator/CharCountBased.php | 38 - .../src/DataGenerator/GroupCountBased.php | 39 - .../src/DataGenerator/GroupPosBased.php | 34 - .../src/DataGenerator/MarkBased.php | 34 - .../src/DataGenerator/RegexBasedAbstract.php | 135 - .../nikic/fast-route/src/Dispatcher.php | 26 - .../src/Dispatcher/CharCountBased.php | 43 - .../src/Dispatcher/GroupCountBased.php | 40 - .../src/Dispatcher/GroupPosBased.php | 46 - .../fast-route/src/Dispatcher/MarkBased.php | 39 - .../src/Dispatcher/RegexBasedAbstract.php | 123 - .../src/Dispatcher/Result/Matched.php | 57 - .../Dispatcher/Result/MethodNotAllowed.php | 43 - .../src/Dispatcher/Result/NotMatched.php | 36 - .../vendor/nikic/fast-route/src/Exception.php | 10 - .../vendor/nikic/fast-route/src/FastRoute.php | 183 - .../nikic/fast-route/src/GenerateUri.php | 21 - .../FromProcessedConfiguration.php | 104 - .../GenerateUri/UriCouldNotBeGenerated.php | 53 - .../vendor/nikic/fast-route/src/Route.php | 70 - .../nikic/fast-route/src/RouteCollector.php | 139 - .../nikic/fast-route/src/RouteParser.php | 42 - .../nikic/fast-route/src/RouteParser/Std.php | 152 - .../vendor/nikic/fast-route/src/functions.php | 78 - .../vendor/npm-asset/bootstrap/CHANGELOG.md | 5 - .../vendor/npm-asset/bootstrap/Gruntfile.js | 430 - .../vendor/npm-asset/bootstrap/LICENSE | 21 - .../vendor/npm-asset/bootstrap/README.md | 149 - .../bootstrap/dist/css/bootstrap-theme.css | 587 - .../dist/css/bootstrap-theme.min.css | 6 - .../bootstrap/dist/css/bootstrap.css | 6834 ---------- .../bootstrap/dist/css/bootstrap.min.css | 6 - .../fonts/glyphicons-halflings-regular.eot | Bin 20127 -> 0 bytes .../fonts/glyphicons-halflings-regular.svg | 288 - .../fonts/glyphicons-halflings-regular.ttf | Bin 45404 -> 0 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 23424 -> 0 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 18028 -> 0 bytes .../npm-asset/bootstrap/dist/js/bootstrap.js | 2580 ---- .../bootstrap/dist/js/bootstrap.min.js | 6 - .../vendor/npm-asset/bootstrap/dist/js/npm.js | 13 - .../vendor/npm-asset/bootstrap/package.json | 101 - .../npm-asset/corejs-typeahead/bower.json | 16 - .../npm-asset/corejs-typeahead/changelog.md | 240 - .../corejs-typeahead/dist/bloodhound.js | 953 -- .../corejs-typeahead/dist/bloodhound.min.js | 8 - .../corejs-typeahead/dist/typeahead.bundle.js | 2642 ---- .../dist/typeahead.bundle.min.js | 9 - .../corejs-typeahead/dist/typeahead.jquery.js | 1695 --- .../dist/typeahead.jquery.min.js | 8 - .../npm-asset/corejs-typeahead/index.js | 6 - .../vendor/npm-asset/corejs-typeahead/license | 19 - .../npm-asset/corejs-typeahead/package.json | 76 - .../npm-asset/corejs-typeahead/readme.md | 133 - .../vendor/npm-asset/dot/.eslintrc.yml | 24 - .../vendor/npm-asset/dot/.travis.yml | 8 - .../vendor/npm-asset/dot/LICENSE-DOT.txt | 24 - .../cops-3.1.3/vendor/npm-asset/dot/README.md | 117 - .../vendor/npm-asset/dot/bower.json | 21 - COPS/cops-3.1.3/vendor/npm-asset/dot/doT.js | 144 - .../vendor/npm-asset/dot/doT.min.js | 1 - COPS/cops-3.1.3/vendor/npm-asset/dot/doU.js | 56 - COPS/cops-3.1.3/vendor/npm-asset/dot/index.js | 150 - .../vendor/npm-asset/dot/package.json | 54 - .../vendor/npm-asset/jquery/AUTHORS.txt | 371 - .../vendor/npm-asset/jquery/LICENSE.txt | 20 - .../vendor/npm-asset/jquery/README.md | 60 - .../vendor/npm-asset/jquery/bower.json | 14 - .../vendor/npm-asset/jquery/dist/jquery.js | 10716 ---------------- .../npm-asset/jquery/dist/jquery.min.js | 2 - .../npm-asset/jquery/dist/jquery.slim.js | 8617 ------------- .../npm-asset/jquery/dist/jquery.slim.min.js | 2 - .../vendor/npm-asset/jquery/package.json | 122 - .../npm-asset/js-cookie/CONTRIBUTING.md | 79 - .../vendor/npm-asset/js-cookie/LICENSE | 21 - .../vendor/npm-asset/js-cookie/README.md | 327 - .../vendor/npm-asset/js-cookie/SERVER_SIDE.md | 107 - .../vendor/npm-asset/js-cookie/package.json | 47 - .../npm-asset/js-cookie/src/js.cookie.js | 163 - .../vendor/npm-asset/lru-fast/README.md | 185 - .../vendor/npm-asset/lru-fast/benchmark.js | 155 - .../npm-asset/lru-fast/benchmark.out.txt | 123 - .../vendor/npm-asset/lru-fast/lru.d.ts | 81 - .../vendor/npm-asset/lru-fast/lru.js | 281 - .../vendor/npm-asset/lru-fast/package.json | 27 - .../vendor/npm-asset/lru-fast/test.js | 177 - .../vendor/npm-asset/magnific-popup/.jshintrc | 21 - .../npm-asset/magnific-popup/.travis.yml | 7 - .../npm-asset/magnific-popup/Gruntfile.js | 219 - .../vendor/npm-asset/magnific-popup/LICENSE | 20 - .../vendor/npm-asset/magnific-popup/README.md | 79 - .../npm-asset/magnific-popup/bower.json | 16 - .../npm-asset/magnific-popup/composer.json | 5 - .../dist/jquery.magnific-popup.js | 1942 --- .../dist/jquery.magnific-popup.min.js | 1 - .../magnific-popup/dist/magnific-popup.css | 417 - .../magnific-popup/magnific-popup.jquery.json | 29 - .../npm-asset/magnific-popup/package.json | 57 - .../npm-asset/normalize.css/CHANGELOG.md | 175 - .../vendor/npm-asset/normalize.css/LICENSE.md | 21 - .../vendor/npm-asset/normalize.css/README.md | 102 - .../npm-asset/normalize.css/normalize.css | 349 - .../npm-asset/normalize.css/package.json | 15 - .../npm-asset/regenerator-runtime/LICENSE | 21 - .../npm-asset/regenerator-runtime/README.md | 31 - .../regenerator-runtime/package.json | 19 - .../npm-asset/regenerator-runtime/path.js | 11 - .../npm-asset/regenerator-runtime/runtime.js | 761 -- .../vendor/npm-asset/twig/.editorconfig | 7 - .../cops-3.1.3/vendor/npm-asset/twig/ASYNC.md | 218 - .../vendor/npm-asset/twig/CHANGELOG.md | 352 - COPS/cops-3.1.3/vendor/npm-asset/twig/LICENSE | 10 - .../vendor/npm-asset/twig/README.md | 161 - .../vendor/npm-asset/twig/package.json | 75 - COPS/cops-3.1.3/vendor/npm-asset/twig/twig.js | 9680 -------------- .../vendor/npm-asset/twig/twig.min.js | 3 - .../npm-asset/twig/twig.min.js.LICENSE.txt | 7 - .../vendor/phpmailer/phpmailer/.editorconfig | 15 - .../vendor/phpmailer/phpmailer/COMMITMENT | 46 - .../vendor/phpmailer/phpmailer/LICENSE | 502 - .../vendor/phpmailer/phpmailer/README.md | 231 - .../vendor/phpmailer/phpmailer/SECURITY.md | 37 - .../vendor/phpmailer/phpmailer/VERSION | 1 - .../vendor/phpmailer/phpmailer/composer.json | 79 - .../phpmailer/phpmailer/get_oauth_token.php | 182 - .../phpmailer/language/phpmailer.lang-af.php | 26 - .../phpmailer/language/phpmailer.lang-ar.php | 27 - .../phpmailer/language/phpmailer.lang-as.php | 35 - .../phpmailer/language/phpmailer.lang-az.php | 27 - .../phpmailer/language/phpmailer.lang-ba.php | 27 - .../phpmailer/language/phpmailer.lang-be.php | 27 - .../phpmailer/language/phpmailer.lang-bg.php | 27 - .../phpmailer/language/phpmailer.lang-bn.php | 35 - .../phpmailer/language/phpmailer.lang-ca.php | 27 - .../phpmailer/language/phpmailer.lang-cs.php | 28 - .../phpmailer/language/phpmailer.lang-da.php | 36 - .../phpmailer/language/phpmailer.lang-de.php | 28 - .../phpmailer/language/phpmailer.lang-el.php | 33 - .../phpmailer/language/phpmailer.lang-eo.php | 26 - .../phpmailer/language/phpmailer.lang-es.php | 31 - .../phpmailer/language/phpmailer.lang-et.php | 28 - .../phpmailer/language/phpmailer.lang-fa.php | 28 - .../phpmailer/language/phpmailer.lang-fi.php | 27 - .../phpmailer/language/phpmailer.lang-fo.php | 27 - .../phpmailer/language/phpmailer.lang-fr.php | 37 - .../phpmailer/language/phpmailer.lang-gl.php | 27 - .../phpmailer/language/phpmailer.lang-he.php | 27 - .../phpmailer/language/phpmailer.lang-hi.php | 35 - .../phpmailer/language/phpmailer.lang-hr.php | 27 - .../phpmailer/language/phpmailer.lang-hu.php | 27 - .../phpmailer/language/phpmailer.lang-hy.php | 27 - .../phpmailer/language/phpmailer.lang-id.php | 31 - .../phpmailer/language/phpmailer.lang-it.php | 28 - .../phpmailer/language/phpmailer.lang-ja.php | 29 - .../phpmailer/language/phpmailer.lang-ka.php | 27 - .../phpmailer/language/phpmailer.lang-ko.php | 27 - .../phpmailer/language/phpmailer.lang-lt.php | 27 - .../phpmailer/language/phpmailer.lang-lv.php | 27 - .../phpmailer/language/phpmailer.lang-mg.php | 27 - .../phpmailer/language/phpmailer.lang-mn.php | 27 - .../phpmailer/language/phpmailer.lang-ms.php | 27 - .../phpmailer/language/phpmailer.lang-nb.php | 33 - .../phpmailer/language/phpmailer.lang-nl.php | 34 - .../phpmailer/language/phpmailer.lang-pl.php | 33 - .../phpmailer/language/phpmailer.lang-pt.php | 27 - .../language/phpmailer.lang-pt_br.php | 38 - .../phpmailer/language/phpmailer.lang-ro.php | 33 - .../phpmailer/language/phpmailer.lang-ru.php | 28 - .../phpmailer/language/phpmailer.lang-si.php | 34 - .../phpmailer/language/phpmailer.lang-sk.php | 30 - .../phpmailer/language/phpmailer.lang-sl.php | 36 - .../phpmailer/language/phpmailer.lang-sr.php | 28 - .../language/phpmailer.lang-sr_latn.php | 28 - .../phpmailer/language/phpmailer.lang-sv.php | 27 - .../phpmailer/language/phpmailer.lang-tl.php | 28 - .../phpmailer/language/phpmailer.lang-tr.php | 31 - .../phpmailer/language/phpmailer.lang-uk.php | 28 - .../phpmailer/language/phpmailer.lang-vi.php | 27 - .../phpmailer/language/phpmailer.lang-zh.php | 29 - .../language/phpmailer.lang-zh_cn.php | 36 - .../phpmailer/src/DSNConfigurator.php | 245 - .../phpmailer/phpmailer/src/Exception.php | 40 - .../vendor/phpmailer/phpmailer/src/OAuth.php | 139 - .../phpmailer/src/OAuthTokenProvider.php | 44 - .../phpmailer/phpmailer/src/PHPMailer.php | 5252 -------- .../vendor/phpmailer/phpmailer/src/POP3.php | 467 - .../vendor/phpmailer/phpmailer/src/SMTP.php | 1497 --- .../vendor/psr/simple-cache/.editorconfig | 12 - .../vendor/psr/simple-cache/LICENSE.md | 21 - .../vendor/psr/simple-cache/README.md | 8 - .../vendor/psr/simple-cache/composer.json | 25 - .../psr/simple-cache/src/CacheException.php | 10 - .../psr/simple-cache/src/CacheInterface.php | 114 - .../src/InvalidArgumentException.php | 13 - .../deprecation-contracts/CHANGELOG.md | 5 - .../symfony/deprecation-contracts/LICENSE | 19 - .../symfony/deprecation-contracts/README.md | 26 - .../deprecation-contracts/composer.json | 35 - .../deprecation-contracts/function.php | 27 - .../vendor/symfony/polyfill-ctype/Ctype.php | 232 - .../vendor/symfony/polyfill-ctype/LICENSE | 19 - .../vendor/symfony/polyfill-ctype/README.md | 12 - .../symfony/polyfill-ctype/bootstrap.php | 50 - .../symfony/polyfill-ctype/bootstrap80.php | 46 - .../symfony/polyfill-ctype/composer.json | 38 - .../vendor/symfony/polyfill-mbstring/LICENSE | 19 - .../symfony/polyfill-mbstring/Mbstring.php | 1045 -- .../symfony/polyfill-mbstring/README.md | 13 - .../Resources/unidata/caseFolding.php | 119 - .../Resources/unidata/lowerCase.php | 1397 -- .../Resources/unidata/titleCaseRegexp.php | 5 - .../Resources/unidata/upperCase.php | 1489 --- .../symfony/polyfill-mbstring/bootstrap.php | 172 - .../symfony/polyfill-mbstring/bootstrap80.php | 167 - .../symfony/polyfill-mbstring/composer.json | 38 - .../vendor/symfony/polyfill-php81/LICENSE | 19 - .../vendor/symfony/polyfill-php81/Php81.php | 37 - .../vendor/symfony/polyfill-php81/README.md | 18 - .../Resources/stubs/CURLStringFile.php | 51 - .../Resources/stubs/ReturnTypeWillChange.php | 20 - .../symfony/polyfill-php81/bootstrap.php | 28 - .../symfony/polyfill-php81/composer.json | 33 - COPS/cops-3.1.3/vendor/twig/twig/CHANGELOG | 325 - COPS/cops-3.1.3/vendor/twig/twig/LICENSE | 27 - COPS/cops-3.1.3/vendor/twig/twig/README.rst | 23 - .../cops-3.1.3/vendor/twig/twig/composer.json | 53 - .../twig/twig/src/AbstractTwigCallable.php | 136 - .../Attribute/FirstClassTwigCallableReady.php | 20 - .../twig/twig/src/Attribute/YieldReady.php | 20 - .../twig/twig/src/Cache/CacheInterface.php | 46 - .../vendor/twig/twig/src/Cache/ChainCache.php | 79 - .../twig/twig/src/Cache/FilesystemCache.php | 87 - .../vendor/twig/twig/src/Cache/NullCache.php | 38 - .../src/Cache/ReadOnlyFilesystemCache.php | 25 - .../vendor/twig/twig/src/Compiler.php | 257 - .../vendor/twig/twig/src/Environment.php | 881 -- .../vendor/twig/twig/src/Error/Error.php | 227 - .../twig/twig/src/Error/LoaderError.php | 21 - .../twig/twig/src/Error/RuntimeError.php | 22 - .../twig/twig/src/Error/SyntaxError.php | 46 - .../vendor/twig/twig/src/ExpressionParser.php | 853 -- .../twig/src/Extension/AbstractExtension.php | 45 - .../twig/twig/src/Extension/CoreExtension.php | 1970 --- .../twig/src/Extension/DebugExtension.php | 62 - .../twig/src/Extension/EscaperExtension.php | 200 - .../twig/src/Extension/ExtensionInterface.php | 75 - .../twig/src/Extension/GlobalsInterface.php | 25 - .../twig/src/Extension/OptimizerExtension.php | 27 - .../twig/src/Extension/ProfilerExtension.php | 52 - .../Extension/RuntimeExtensionInterface.php | 19 - .../twig/src/Extension/SandboxExtension.php | 135 - .../twig/src/Extension/StagingExtension.php | 100 - .../src/Extension/StringLoaderExtension.php | 40 - .../src/Extension/YieldNotReadyExtension.php | 30 - .../vendor/twig/twig/src/ExtensionSet.php | 488 - .../src/FileExtensionEscapingStrategy.php | 60 - .../cops-3.1.3/vendor/twig/twig/src/Lexer.php | 584 - .../twig/twig/src/Loader/ArrayLoader.php | 75 - .../twig/twig/src/Loader/ChainLoader.php | 132 - .../twig/twig/src/Loader/FilesystemLoader.php | 283 - .../twig/twig/src/Loader/LoaderInterface.php | 49 - .../vendor/twig/twig/src/Markup.php | 52 - .../twig/twig/src/Node/AutoEscapeNode.php | 40 - .../vendor/twig/twig/src/Node/BlockNode.php | 50 - .../twig/twig/src/Node/BlockReferenceNode.php | 38 - .../vendor/twig/twig/src/Node/BodyNode.php | 24 - .../vendor/twig/twig/src/Node/CaptureNode.php | 57 - .../twig/src/Node/CheckSecurityCallNode.php | 30 - .../twig/twig/src/Node/CheckSecurityNode.php | 85 - .../twig/twig/src/Node/CheckToStringNode.php | 47 - .../twig/twig/src/Node/DeprecatedNode.php | 73 - .../vendor/twig/twig/src/Node/DoNode.php | 40 - .../vendor/twig/twig/src/Node/EmbedNode.php | 50 - .../Node/Expression/AbstractExpression.php | 28 - .../src/Node/Expression/ArrayExpression.php | 135 - .../Expression/ArrowFunctionExpression.php | 64 - .../Node/Expression/AssignNameExpression.php | 27 - .../Node/Expression/Binary/AbstractBinary.php | 42 - .../src/Node/Expression/Binary/AddBinary.php | 23 - .../src/Node/Expression/Binary/AndBinary.php | 23 - .../Expression/Binary/BitwiseAndBinary.php | 23 - .../Expression/Binary/BitwiseOrBinary.php | 23 - .../Expression/Binary/BitwiseXorBinary.php | 23 - .../Node/Expression/Binary/ConcatBinary.php | 23 - .../src/Node/Expression/Binary/DivBinary.php | 23 - .../Node/Expression/Binary/EndsWithBinary.php | 35 - .../Node/Expression/Binary/EqualBinary.php | 39 - .../Node/Expression/Binary/FloorDivBinary.php | 29 - .../Node/Expression/Binary/GreaterBinary.php | 39 - .../Expression/Binary/GreaterEqualBinary.php | 39 - .../Node/Expression/Binary/HasEveryBinary.php | 33 - .../Node/Expression/Binary/HasSomeBinary.php | 33 - .../src/Node/Expression/Binary/InBinary.php | 33 - .../src/Node/Expression/Binary/LessBinary.php | 39 - .../Expression/Binary/LessEqualBinary.php | 39 - .../Node/Expression/Binary/MatchesBinary.php | 33 - .../src/Node/Expression/Binary/ModBinary.php | 23 - .../src/Node/Expression/Binary/MulBinary.php | 23 - .../Node/Expression/Binary/NotEqualBinary.php | 39 - .../Node/Expression/Binary/NotInBinary.php | 33 - .../src/Node/Expression/Binary/OrBinary.php | 23 - .../Node/Expression/Binary/PowerBinary.php | 22 - .../Node/Expression/Binary/RangeBinary.php | 33 - .../Expression/Binary/SpaceshipBinary.php | 22 - .../Expression/Binary/StartsWithBinary.php | 35 - .../src/Node/Expression/Binary/SubBinary.php | 23 - .../Expression/BlockReferenceExpression.php | 87 - .../src/Node/Expression/CallExpression.php | 362 - .../Node/Expression/ConditionalExpression.php | 45 - .../Node/Expression/ConstantExpression.php | 31 - .../Node/Expression/Filter/DefaultFilter.php | 63 - .../src/Node/Expression/Filter/RawFilter.php | 36 - .../src/Node/Expression/FilterExpression.php | 73 - .../Node/Expression/FunctionExpression.php | 68 - .../FunctionNode/EnumCasesFunction.php | 41 - .../src/Node/Expression/GetAttrExpression.php | 87 - .../twig/src/Node/Expression/InlinePrint.php | 34 - .../Node/Expression/MethodCallExpression.php | 64 - .../src/Node/Expression/NameExpression.php | 107 - .../Expression/NullCoalesceExpression.php | 61 - .../src/Node/Expression/ParentExpression.php | 46 - .../Node/Expression/TempNameExpression.php | 31 - .../src/Node/Expression/Test/ConstantTest.php | 49 - .../src/Node/Expression/Test/DefinedTest.php | 81 - .../Node/Expression/Test/DivisiblebyTest.php | 36 - .../src/Node/Expression/Test/EvenTest.php | 35 - .../src/Node/Expression/Test/NullTest.php | 34 - .../twig/src/Node/Expression/Test/OddTest.php | 35 - .../src/Node/Expression/Test/SameasTest.php | 34 - .../src/Node/Expression/TestExpression.php | 66 - .../Node/Expression/Unary/AbstractUnary.php | 34 - .../src/Node/Expression/Unary/NegUnary.php | 23 - .../src/Node/Expression/Unary/NotUnary.php | 23 - .../src/Node/Expression/Unary/PosUnary.php | 23 - .../Node/Expression/VariadicExpression.php | 24 - .../vendor/twig/twig/src/Node/FlushNode.php | 40 - .../vendor/twig/twig/src/Node/ForLoopNode.php | 51 - .../vendor/twig/twig/src/Node/ForNode.php | 116 - .../vendor/twig/twig/src/Node/IfNode.php | 75 - .../vendor/twig/twig/src/Node/ImportNode.php | 75 - .../vendor/twig/twig/src/Node/IncludeNode.php | 110 - .../vendor/twig/twig/src/Node/MacroNode.php | 106 - .../vendor/twig/twig/src/Node/ModuleNode.php | 489 - .../twig/twig/src/Node/NameDeprecation.php | 46 - .../vendor/twig/twig/src/Node/Node.php | 281 - .../twig/src/Node/NodeCaptureInterface.php | 21 - .../twig/src/Node/NodeOutputInterface.php | 21 - .../vendor/twig/twig/src/Node/PrintNode.php | 44 - .../vendor/twig/twig/src/Node/SandboxNode.php | 54 - .../vendor/twig/twig/src/Node/SetNode.php | 96 - .../vendor/twig/twig/src/Node/TextNode.php | 41 - .../vendor/twig/twig/src/Node/TypesNode.php | 28 - .../vendor/twig/twig/src/Node/WithNode.php | 72 - .../vendor/twig/twig/src/NodeTraverser.php | 76 - .../src/NodeVisitor/AbstractNodeVisitor.php | 49 - .../src/NodeVisitor/EscaperNodeVisitor.php | 209 - .../MacroAutoImportNodeVisitor.php | 74 - .../src/NodeVisitor/NodeVisitorInterface.php | 46 - .../src/NodeVisitor/OptimizerNodeVisitor.php | 213 - .../NodeVisitor/SafeAnalysisNodeVisitor.php | 170 - .../src/NodeVisitor/SandboxNodeVisitor.php | 139 - .../NodeVisitor/YieldNotReadyNodeVisitor.php | 59 - .../vendor/twig/twig/src/Parser.php | 383 - .../twig/src/Profiler/Dumper/BaseDumper.php | 63 - .../src/Profiler/Dumper/BlackfireDumper.php | 72 - .../twig/src/Profiler/Dumper/HtmlDumper.php | 47 - .../twig/src/Profiler/Dumper/TextDumper.php | 35 - .../src/Profiler/Node/EnterProfileNode.php | 44 - .../src/Profiler/Node/LeaveProfileNode.php | 38 - .../NodeVisitor/ProfilerNodeVisitor.php | 69 - .../vendor/twig/twig/src/Profiler/Profile.php | 178 - .../vendor/twig/twig/src/Resources/core.php | 541 - .../vendor/twig/twig/src/Resources/debug.php | 25 - .../twig/twig/src/Resources/escaper.php | 51 - .../twig/twig/src/Resources/string_loader.php | 26 - .../twig/twig/src/Runtime/EscaperRuntime.php | 327 - .../RuntimeLoader/ContainerRuntimeLoader.php | 35 - .../RuntimeLoader/FactoryRuntimeLoader.php | 39 - .../RuntimeLoader/RuntimeLoaderInterface.php | 27 - .../twig/twig/src/Sandbox/SecurityError.php | 23 - .../Sandbox/SecurityNotAllowedFilterError.php | 33 - .../SecurityNotAllowedFunctionError.php | 33 - .../Sandbox/SecurityNotAllowedMethodError.php | 40 - .../SecurityNotAllowedPropertyError.php | 40 - .../Sandbox/SecurityNotAllowedTagError.php | 33 - .../twig/twig/src/Sandbox/SecurityPolicy.php | 130 - .../src/Sandbox/SecurityPolicyInterface.php | 45 - .../src/Sandbox/SourcePolicyInterface.php | 24 - .../vendor/twig/twig/src/Source.php | 47 - .../vendor/twig/twig/src/Template.php | 497 - .../vendor/twig/twig/src/TemplateWrapper.php | 90 - .../twig/src/Test/IntegrationTestCase.php | 288 - .../twig/twig/src/Test/NodeTestCase.php | 125 - .../cops-3.1.3/vendor/twig/twig/src/Token.php | 180 - .../src/TokenParser/AbstractTokenParser.php | 32 - .../twig/src/TokenParser/ApplyTokenParser.php | 60 - .../src/TokenParser/AutoEscapeTokenParser.php | 58 - .../twig/src/TokenParser/BlockTokenParser.php | 75 - .../src/TokenParser/DeprecatedTokenParser.php | 66 - .../twig/src/TokenParser/DoTokenParser.php | 38 - .../twig/src/TokenParser/EmbedTokenParser.php | 73 - .../src/TokenParser/ExtendsTokenParser.php | 49 - .../twig/src/TokenParser/FlushTokenParser.php | 38 - .../twig/src/TokenParser/ForTokenParser.php | 78 - .../twig/src/TokenParser/FromTokenParser.php | 66 - .../twig/src/TokenParser/IfTokenParser.php | 89 - .../src/TokenParser/ImportTokenParser.php | 44 - .../src/TokenParser/IncludeTokenParser.php | 69 - .../twig/src/TokenParser/MacroTokenParser.php | 66 - .../src/TokenParser/SandboxTokenParser.php | 66 - .../twig/src/TokenParser/SetTokenParser.php | 73 - .../src/TokenParser/TokenParserInterface.php | 46 - .../twig/src/TokenParser/TypesTokenParser.php | 86 - .../twig/src/TokenParser/UseTokenParser.php | 73 - .../twig/src/TokenParser/WithTokenParser.php | 56 - .../vendor/twig/twig/src/TokenStream.php | 129 - .../twig/twig/src/TwigCallableInterface.php | 53 - .../vendor/twig/twig/src/TwigFilter.php | 74 - .../vendor/twig/twig/src/TwigFunction.php | 63 - .../vendor/twig/twig/src/TwigTest.php | 67 - .../src/Util/CallableArgumentsExtractor.php | 204 - .../twig/src/Util/DeprecationCollector.php | 77 - .../twig/twig/src/Util/ReflectionCallable.php | 92 - .../twig/src/Util/TemplateDirIterator.php | 36 - COPS/cops-3.1.3/web.config | 28 - COPS/cops-3.1.3/zipfs.php | 11 - COPS/cops-3.1.3/zipper.php | 13 - .../config/local.php | 0 COPS/run.sh | 2 +- 868 files changed, 3 insertions(+), 164706 deletions(-) delete mode 100644 COPS/cops-3.1.3/.dockerignore delete mode 100644 COPS/cops-3.1.3/.editorconfig delete mode 100644 COPS/cops-3.1.3/.gitremotes delete mode 100644 COPS/cops-3.1.3/.htaccess delete mode 100644 COPS/cops-3.1.3/CHANGELOG.md delete mode 100644 COPS/cops-3.1.3/CHANGELOG.seblucas.md delete mode 100644 COPS/cops-3.1.3/COPYING delete mode 100644 COPS/cops-3.1.3/README.md delete mode 100644 COPS/cops-3.1.3/calres.php delete mode 100644 COPS/cops-3.1.3/checkconfig.php delete mode 100644 COPS/cops-3.1.3/config/config.php delete mode 100644 COPS/cops-3.1.3/config/default.php delete mode 100644 COPS/cops-3.1.3/config/loader.php delete mode 100644 COPS/cops-3.1.3/config/local.php.example delete mode 100644 COPS/cops-3.1.3/config/test.php delete mode 100644 COPS/cops-3.1.3/epubfs.php delete mode 100644 COPS/cops-3.1.3/epubreader.php delete mode 100644 COPS/cops-3.1.3/favicon.ico delete mode 100644 COPS/cops-3.1.3/feed.php delete mode 100644 COPS/cops-3.1.3/fetch.php delete mode 100644 COPS/cops-3.1.3/getJSON.php delete mode 100644 COPS/cops-3.1.3/graphql.php delete mode 100644 COPS/cops-3.1.3/images/allbook.png delete mode 100644 COPS/cops-3.1.3/images/author.png delete mode 100644 COPS/cops-3.1.3/images/bookcover.png delete mode 100644 COPS/cops-3.1.3/images/custom.png delete mode 100644 COPS/cops-3.1.3/images/icons/icon114.png delete mode 100644 COPS/cops-3.1.3/images/icons/icon144.png delete mode 100644 COPS/cops-3.1.3/images/icons/icon57.png delete mode 100644 COPS/cops-3.1.3/images/icons/icon72.png delete mode 100644 COPS/cops-3.1.3/images/language.png delete mode 100644 COPS/cops-3.1.3/images/publisher.png delete mode 100644 COPS/cops-3.1.3/images/rating.png delete mode 100644 COPS/cops-3.1.3/images/recent.png delete mode 100644 COPS/cops-3.1.3/images/serie.png delete mode 100644 COPS/cops-3.1.3/images/tag.png delete mode 100644 COPS/cops-3.1.3/index.php delete mode 100644 COPS/cops-3.1.3/lang/Localization_af.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_bg.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_ca.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_cs.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_da.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_de.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_el.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_en.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_es.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_eu.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_fr.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_gl.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_hr.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_ht.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_hu.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_id.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_it.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_ja.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_ko.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_nb.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_nl.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_pl.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_pt_BR.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_pt_PT.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_ro.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_ru.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_sl.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_sr.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_sv.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_tr.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_uk.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_zh_CN.json delete mode 100644 COPS/cops-3.1.3/lang/Localization_zh_TW.json delete mode 100644 COPS/cops-3.1.3/loader.php delete mode 100644 COPS/cops-3.1.3/login.html delete mode 100644 COPS/cops-3.1.3/mike.php delete mode 100644 COPS/cops-3.1.3/opds.php delete mode 100644 COPS/cops-3.1.3/package.json delete mode 100644 COPS/cops-3.1.3/phpstan-baseline.neon delete mode 100644 COPS/cops-3.1.3/phpstan.neon.dist delete mode 100644 COPS/cops-3.1.3/phpunit.xml.dist delete mode 100644 COPS/cops-3.1.3/rector.php delete mode 100644 COPS/cops-3.1.3/resources/dot-php/LICENSE delete mode 100644 COPS/cops-3.1.3/resources/dot-php/README.md delete mode 100644 COPS/cops-3.1.3/resources/dot-php/composer.json delete mode 100644 COPS/cops-3.1.3/resources/dot-php/doT.php delete mode 100644 COPS/cops-3.1.3/resources/monocle/README.md delete mode 100644 COPS/cops-3.1.3/resources/monocle/scripts/monocore.js delete mode 100644 COPS/cops-3.1.3/resources/monocle/scripts/monoctrl.js delete mode 100644 COPS/cops-3.1.3/resources/monocle/styles/monocore.css delete mode 100644 COPS/cops-3.1.3/resources/monocle/styles/monoctrl.css delete mode 100644 COPS/cops-3.1.3/resources/simonpioli/sortelements/README.md delete mode 100644 COPS/cops-3.1.3/resources/simonpioli/sortelements/jquery.sortElements.js delete mode 100644 COPS/cops-3.1.3/restapi.php delete mode 100644 COPS/cops-3.1.3/router.php delete mode 100644 COPS/cops-3.1.3/schema.graphql delete mode 100644 COPS/cops-3.1.3/sendtomail.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/Annotation.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/Author.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/Base.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/BaseList.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/Book.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/BookList.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/Category.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/Cover.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/CustomColumn.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/CustomColumnType.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/CustomColumnTypeBool.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/CustomColumnTypeComment.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/CustomColumnTypeDate.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/CustomColumnTypeEnumeration.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/CustomColumnTypeFloat.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/CustomColumnTypeInteger.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/CustomColumnTypeRating.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/CustomColumnTypeSeries.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/CustomColumnTypeText.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/Data.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/Database.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/Filter.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/Identifier.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/Language.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/Metadata.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/Note.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/Preference.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/Publisher.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/Rating.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/Resource.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/Serie.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/Tag.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/User.php delete mode 100644 COPS/cops-3.1.3/src/Calibre/VirtualLibrary.php delete mode 100644 COPS/cops-3.1.3/src/Framework.php delete mode 100644 COPS/cops-3.1.3/src/Handlers/BaseHandler.php delete mode 100644 COPS/cops-3.1.3/src/Handlers/CalResHandler.php delete mode 100644 COPS/cops-3.1.3/src/Handlers/CheckHandler.php delete mode 100644 COPS/cops-3.1.3/src/Handlers/EpubFsHandler.php delete mode 100644 COPS/cops-3.1.3/src/Handlers/FeedHandler.php delete mode 100644 COPS/cops-3.1.3/src/Handlers/FetchHandler.php delete mode 100644 COPS/cops-3.1.3/src/Handlers/GraphQLHandler.php delete mode 100644 COPS/cops-3.1.3/src/Handlers/HtmlHandler.php delete mode 100644 COPS/cops-3.1.3/src/Handlers/JsonHandler.php delete mode 100644 COPS/cops-3.1.3/src/Handlers/LoaderHandler.php delete mode 100644 COPS/cops-3.1.3/src/Handlers/MailHandler.php delete mode 100644 COPS/cops-3.1.3/src/Handlers/OpdsHandler.php delete mode 100644 COPS/cops-3.1.3/src/Handlers/PageHandler.php delete mode 100644 COPS/cops-3.1.3/src/Handlers/QueueBasedHandler.php delete mode 100644 COPS/cops-3.1.3/src/Handlers/ReadHandler.php delete mode 100644 COPS/cops-3.1.3/src/Handlers/RestApiHandler.php delete mode 100644 COPS/cops-3.1.3/src/Handlers/ZipFsHandler.php delete mode 100644 COPS/cops-3.1.3/src/Handlers/ZipperHandler.php delete mode 100644 COPS/cops-3.1.3/src/Input/Config.php delete mode 100644 COPS/cops-3.1.3/src/Input/Context.php delete mode 100644 COPS/cops-3.1.3/src/Input/Request.php delete mode 100644 COPS/cops-3.1.3/src/Input/Route.php delete mode 100644 COPS/cops-3.1.3/src/Language/Translation.php delete mode 100644 COPS/cops-3.1.3/src/Model/Entry.php delete mode 100644 COPS/cops-3.1.3/src/Model/EntryBook.php delete mode 100644 COPS/cops-3.1.3/src/Model/Link.php delete mode 100644 COPS/cops-3.1.3/src/Model/LinkEntry.php delete mode 100644 COPS/cops-3.1.3/src/Model/LinkFacet.php delete mode 100644 COPS/cops-3.1.3/src/Model/LinkFeed.php delete mode 100644 COPS/cops-3.1.3/src/Model/LinkNavigation.php delete mode 100644 COPS/cops-3.1.3/src/Output/BaseRenderer.php delete mode 100644 COPS/cops-3.1.3/src/Output/DotPHPTemplate.php delete mode 100644 COPS/cops-3.1.3/src/Output/EPubReader.php delete mode 100644 COPS/cops-3.1.3/src/Output/FileResponse.php delete mode 100644 COPS/cops-3.1.3/src/Output/Format.php delete mode 100644 COPS/cops-3.1.3/src/Output/HtmlRenderer.php delete mode 100644 COPS/cops-3.1.3/src/Output/JsonRenderer.php delete mode 100644 COPS/cops-3.1.3/src/Output/KiwilanOPDS.php delete mode 100644 COPS/cops-3.1.3/src/Output/Mail.php delete mode 100644 COPS/cops-3.1.3/src/Output/OpdsRenderer.php delete mode 100644 COPS/cops-3.1.3/src/Output/Response.php delete mode 100644 COPS/cops-3.1.3/src/Output/RestApi.php delete mode 100644 COPS/cops-3.1.3/src/Output/TwigTemplate.php delete mode 100644 COPS/cops-3.1.3/src/Output/Zipper.php delete mode 100644 COPS/cops-3.1.3/src/Pages/Page.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageAbout.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageAllAuthors.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageAllAuthorsLetter.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageAllBooks.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageAllBooksLetter.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageAllBooksYear.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageAllCustoms.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageAllIdentifiers.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageAllLanguages.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageAllPublishers.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageAllRating.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageAllSeries.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageAllTags.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageAllVirtualLibraries.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageAuthorDetail.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageBookDetail.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageCustomDetail.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageCustomize.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageId.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageIdentifierDetail.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageIndex.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageLanguageDetail.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PagePublisherDetail.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageQueryResult.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageRatingDetail.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageRecentBooks.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageSerieDetail.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageTagDetail.php delete mode 100644 COPS/cops-3.1.3/src/Pages/PageWithDetail.php delete mode 100644 COPS/cops-3.1.3/src/functions.php delete mode 100644 COPS/cops-3.1.3/styles/cops-monocle.css delete mode 100644 COPS/cops-3.1.3/styles/cops-monocle.js delete mode 100644 COPS/cops-3.1.3/templates/about.html delete mode 100644 COPS/cops-3.1.3/templates/bootstrap/bookdetail.html delete mode 100644 COPS/cops-3.1.3/templates/bootstrap/file.html delete mode 100644 COPS/cops-3.1.3/templates/bootstrap/footer.html delete mode 100644 COPS/cops-3.1.3/templates/bootstrap/header.html delete mode 100644 COPS/cops-3.1.3/templates/bootstrap/main.html delete mode 100644 COPS/cops-3.1.3/templates/bootstrap/page.html delete mode 100644 COPS/cops-3.1.3/templates/bootstrap/scripts/cops.js delete mode 100644 COPS/cops-3.1.3/templates/bootstrap/styles/style-base.css delete mode 100644 COPS/cops-3.1.3/templates/bootstrap/styles/style-default.css delete mode 100644 COPS/cops-3.1.3/templates/bootstrap/suggestion.html delete mode 100644 COPS/cops-3.1.3/templates/bootstrap2/bookdetail.html delete mode 100644 COPS/cops-3.1.3/templates/bootstrap2/file.html delete mode 100644 COPS/cops-3.1.3/templates/bootstrap2/footer.html delete mode 100644 COPS/cops-3.1.3/templates/bootstrap2/header.html delete mode 100644 COPS/cops-3.1.3/templates/bootstrap2/main.html delete mode 100644 COPS/cops-3.1.3/templates/bootstrap2/page.html delete mode 100644 COPS/cops-3.1.3/templates/bootstrap2/scripts/cops.js delete mode 100644 COPS/cops-3.1.3/templates/bootstrap2/styles/style-base.css delete mode 100644 COPS/cops-3.1.3/templates/bootstrap2/styles/style-default.css delete mode 100644 COPS/cops-3.1.3/templates/bootstrap2/styles/style-kindle.css delete mode 100644 COPS/cops-3.1.3/templates/bootstrap2/styles/typeahead.css delete mode 100644 COPS/cops-3.1.3/templates/bootstrap2/suggestion.html delete mode 100644 COPS/cops-3.1.3/templates/bootstrap5/bookdetail.html delete mode 100644 COPS/cops-3.1.3/templates/bootstrap5/file.html delete mode 100644 COPS/cops-3.1.3/templates/bootstrap5/footer.html delete mode 100644 COPS/cops-3.1.3/templates/bootstrap5/header.html delete mode 100644 COPS/cops-3.1.3/templates/bootstrap5/main.html delete mode 100644 COPS/cops-3.1.3/templates/bootstrap5/page.html delete mode 100644 COPS/cops-3.1.3/templates/bootstrap5/scripts/cops.js delete mode 100644 COPS/cops-3.1.3/templates/bootstrap5/styles/bootstrap5.css delete mode 100644 COPS/cops-3.1.3/templates/bootstrap5/styles/style-base.css delete mode 100644 COPS/cops-3.1.3/templates/bootstrap5/styles/style-default.css delete mode 100644 COPS/cops-3.1.3/templates/bootstrap5/styles/typeahead.css delete mode 100644 COPS/cops-3.1.3/templates/bootstrap5/suggestion.html delete mode 100644 COPS/cops-3.1.3/templates/checkconfig.html delete mode 100644 COPS/cops-3.1.3/templates/default/bookdetail.html delete mode 100644 COPS/cops-3.1.3/templates/default/file.html delete mode 100644 COPS/cops-3.1.3/templates/default/footer.html delete mode 100644 COPS/cops-3.1.3/templates/default/header.html delete mode 100644 COPS/cops-3.1.3/templates/default/main.html delete mode 100644 COPS/cops-3.1.3/templates/default/page.html delete mode 100644 COPS/cops-3.1.3/templates/default/styles/fa-solid.min.css delete mode 100644 COPS/cops-3.1.3/templates/default/styles/fontawesome.min.css delete mode 100644 COPS/cops-3.1.3/templates/default/styles/style-base.css delete mode 100644 COPS/cops-3.1.3/templates/default/styles/style-default.css delete mode 100644 COPS/cops-3.1.3/templates/default/styles/style-eink.css delete mode 100644 COPS/cops-3.1.3/templates/default/styles/style-iphone.css delete mode 100644 COPS/cops-3.1.3/templates/default/styles/style-iphone7.css delete mode 100644 COPS/cops-3.1.3/templates/default/styles/style-kindle.css delete mode 100644 COPS/cops-3.1.3/templates/default/styles/typeahead.css delete mode 100644 COPS/cops-3.1.3/templates/default/suggestion.html delete mode 100644 COPS/cops-3.1.3/templates/default/webfonts/fa-solid-900.eot delete mode 100644 COPS/cops-3.1.3/templates/default/webfonts/fa-solid-900.svg delete mode 100644 COPS/cops-3.1.3/templates/default/webfonts/fa-solid-900.ttf delete mode 100644 COPS/cops-3.1.3/templates/default/webfonts/fa-solid-900.woff delete mode 100644 COPS/cops-3.1.3/templates/default/webfonts/fa-solid-900.woff2 delete mode 100644 COPS/cops-3.1.3/templates/epubjs-reader.html delete mode 100644 COPS/cops-3.1.3/templates/epubreader.html delete mode 100644 COPS/cops-3.1.3/templates/error.html delete mode 100644 COPS/cops-3.1.3/templates/graphql.html delete mode 100644 COPS/cops-3.1.3/templates/notfound.html delete mode 100644 COPS/cops-3.1.3/templates/restapi.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/README.md delete mode 100644 COPS/cops-3.1.3/templates/twigged/about.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/authordetail.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/base.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/bookdetail.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/booklist.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/customdetail.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/customize.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/extra_info.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/extra_series.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/filters.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/identifierdetail.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/index.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/languagedetail.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/loader/README.md delete mode 100644 COPS/cops-3.1.3/templates/twigged/loader/actions.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/loader/databases.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/loader/index.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/mainlist.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/navlist.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/page.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/publisherdetail.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/ratingdetail.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/recent.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/scripts/cops.js delete mode 100644 COPS/cops-3.1.3/templates/twigged/seriedetail.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/styles/style-base.css delete mode 100644 COPS/cops-3.1.3/templates/twigged/styles/style-default.css delete mode 100644 COPS/cops-3.1.3/templates/twigged/styles/typeahead.css delete mode 100644 COPS/cops-3.1.3/templates/twigged/suggestion.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/tagdetail.html delete mode 100644 COPS/cops-3.1.3/templates/twigged/var_dump.json.twig delete mode 100644 COPS/cops-3.1.3/util.js delete mode 100644 COPS/cops-3.1.3/vendor/autoload.php delete mode 100644 COPS/cops-3.1.3/vendor/composer/ClassLoader.php delete mode 100644 COPS/cops-3.1.3/vendor/composer/InstalledVersions.php delete mode 100644 COPS/cops-3.1.3/vendor/composer/LICENSE delete mode 100644 COPS/cops-3.1.3/vendor/composer/autoload_classmap.php delete mode 100644 COPS/cops-3.1.3/vendor/composer/autoload_files.php delete mode 100644 COPS/cops-3.1.3/vendor/composer/autoload_namespaces.php delete mode 100644 COPS/cops-3.1.3/vendor/composer/autoload_psr4.php delete mode 100644 COPS/cops-3.1.3/vendor/composer/autoload_real.php delete mode 100644 COPS/cops-3.1.3/vendor/composer/autoload_static.php delete mode 100644 COPS/cops-3.1.3/vendor/composer/installed.json delete mode 100644 COPS/cops-3.1.3/vendor/composer/installed.php delete mode 100644 COPS/cops-3.1.3/vendor/composer/platform_check.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/.editorconfig delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/.php-cs-fixer.dist.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/.tool-versions delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/LICENSE delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/README.md delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/composer.json delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/phpdoc.dist.xml delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/phpunit.xml.dist delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/psalm.xml delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/CentralDirectoryFileHeader.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/CompressionMethod.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/DataDescriptor.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/EndOfCentralDirectory.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/Exception.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/Exception/DosTimeOverflowException.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/Exception/FileNotFoundException.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/Exception/FileNotReadableException.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/Exception/FileSizeIncorrectException.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/Exception/OverflowException.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/Exception/ResourceActionException.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/Exception/SimulationFileUnknownException.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/Exception/StreamNotReadableException.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/Exception/StreamNotSeekableException.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/File.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/GeneralPurposeBitFlag.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/LocalFileHeader.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/OperationMode.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/PackField.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/Time.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/Version.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/Zip64/DataDescriptor.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/Zip64/EndOfCentralDirectory.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/Zip64/EndOfCentralDirectoryLocator.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/Zip64/ExtendedInformationExtraField.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/ZipStream.php delete mode 100644 COPS/cops-3.1.3/vendor/maennchen/zipstream-php/src/Zs/ExtendedInformationExtraField.php delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/.editorconfig delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/.gitremotes delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/LICENSE delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/README.md delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/composer.json delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/demo-ui.png delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/css/common.css delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/css/main.css delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/css/notedlg.css delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/css/sidebar.css delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/css/toolbar.css delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/font/fontello.eot delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/font/fontello.svg delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/font/fontello.ttf delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/font/fontello.woff delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/img/annotations.svg delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/img/bookmark.svg delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/img/bookmarked.svg delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/img/bookmarks.svg delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/img/favicon.png delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/img/favicon.svg delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/img/info.svg delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/img/loader.gif delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/img/menu.svg delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/img/next.svg delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/img/open-book.svg delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/img/prev.svg delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/img/resize-full.svg delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/img/resize-small.svg delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/img/search-clear.svg delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/img/search.svg delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/img/settings.svg delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/img/toc.svg delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/img/upload.svg delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/index.html delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/js/epubreader.js delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/js/epubreader.js.map delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/js/epubreader.min.js delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/js/epubreader.min.js.map delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/js/libs/epub.min.js delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/js/libs/jszip.min.js delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/js/libs/jszip.min.js.LICENSE.txt delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/js/libs/md5.min.js delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/js/libs/md5.min.js.LICENSE.txt delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/dist/template.html delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/docs/keybindings.md delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/package-lock.json delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/package.json delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/epubjs-reader/webpack.config.cjs delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/LICENSE delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/README.md delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/composer.json delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/composer.lock delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/package.json delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/phpstan-baseline.neon delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/phpstan.neon.dist delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/phpunit.xml delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/src/App/Handler.php delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/src/App/Util.php delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/src/Contents/Nav.php delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/src/Contents/NavPoint.php delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/src/Contents/NavPointList.php delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/src/Contents/Spine.php delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/src/Contents/Toc.php delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/src/Data/Item.php delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/src/Data/Manifest.php delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/src/Dom/Element.php delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/src/Dom/XPath.php delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/src/EPub.php delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/src/Other.php delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/src/Tools/HtmlTools.php delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/src/Tools/ZipEdit.php delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/src/Tools/ZipFile.php delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/src/Tools/htmlBlockLevelElements.php delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/src/Tools/htmlEntityMap.php delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/templates/epub.html delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/templates/index.html delete mode 100644 COPS/cops-3.1.3/vendor/mikespub/php-epub-meta/templates/titlepage.xhtml delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/LICENSE delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/README.md delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/composer.json delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/BadRouteException.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/Cache.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/Cache/FileCache.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/Cache/Psr16Cache.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/ConfigureRoutes.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/DataGenerator.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/DataGenerator/CharCountBased.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/DataGenerator/GroupCountBased.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/DataGenerator/GroupPosBased.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/DataGenerator/MarkBased.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/DataGenerator/RegexBasedAbstract.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/Dispatcher.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/Dispatcher/CharCountBased.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/Dispatcher/GroupCountBased.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/Dispatcher/GroupPosBased.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/Dispatcher/MarkBased.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/Dispatcher/RegexBasedAbstract.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/Dispatcher/Result/Matched.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/Dispatcher/Result/MethodNotAllowed.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/Dispatcher/Result/NotMatched.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/Exception.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/FastRoute.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/GenerateUri.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/GenerateUri/FromProcessedConfiguration.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/GenerateUri/UriCouldNotBeGenerated.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/Route.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/RouteCollector.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/RouteParser.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/RouteParser/Std.php delete mode 100644 COPS/cops-3.1.3/vendor/nikic/fast-route/src/functions.php delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/bootstrap/CHANGELOG.md delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/bootstrap/Gruntfile.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/bootstrap/LICENSE delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/bootstrap/README.md delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/bootstrap/dist/css/bootstrap-theme.css delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/bootstrap/dist/css/bootstrap-theme.min.css delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/bootstrap/dist/css/bootstrap.css delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/bootstrap/dist/css/bootstrap.min.css delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/bootstrap/dist/fonts/glyphicons-halflings-regular.eot delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/bootstrap/dist/fonts/glyphicons-halflings-regular.svg delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/bootstrap/dist/fonts/glyphicons-halflings-regular.woff delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2 delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/bootstrap/dist/js/bootstrap.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/bootstrap/dist/js/bootstrap.min.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/bootstrap/dist/js/npm.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/bootstrap/package.json delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/corejs-typeahead/bower.json delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/corejs-typeahead/changelog.md delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/corejs-typeahead/dist/bloodhound.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/corejs-typeahead/dist/bloodhound.min.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/corejs-typeahead/dist/typeahead.bundle.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/corejs-typeahead/dist/typeahead.bundle.min.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/corejs-typeahead/dist/typeahead.jquery.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/corejs-typeahead/dist/typeahead.jquery.min.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/corejs-typeahead/index.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/corejs-typeahead/license delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/corejs-typeahead/package.json delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/corejs-typeahead/readme.md delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/dot/.eslintrc.yml delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/dot/.travis.yml delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/dot/LICENSE-DOT.txt delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/dot/README.md delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/dot/bower.json delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/dot/doT.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/dot/doT.min.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/dot/doU.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/dot/index.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/dot/package.json delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/jquery/AUTHORS.txt delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/jquery/LICENSE.txt delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/jquery/README.md delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/jquery/bower.json delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/jquery/dist/jquery.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/jquery/dist/jquery.min.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/jquery/dist/jquery.slim.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/jquery/dist/jquery.slim.min.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/jquery/package.json delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/js-cookie/CONTRIBUTING.md delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/js-cookie/LICENSE delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/js-cookie/README.md delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/js-cookie/SERVER_SIDE.md delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/js-cookie/package.json delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/js-cookie/src/js.cookie.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/lru-fast/README.md delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/lru-fast/benchmark.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/lru-fast/benchmark.out.txt delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/lru-fast/lru.d.ts delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/lru-fast/lru.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/lru-fast/package.json delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/lru-fast/test.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/magnific-popup/.jshintrc delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/magnific-popup/.travis.yml delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/magnific-popup/Gruntfile.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/magnific-popup/LICENSE delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/magnific-popup/README.md delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/magnific-popup/bower.json delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/magnific-popup/composer.json delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/magnific-popup/dist/jquery.magnific-popup.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/magnific-popup/dist/jquery.magnific-popup.min.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/magnific-popup/dist/magnific-popup.css delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/magnific-popup/magnific-popup.jquery.json delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/magnific-popup/package.json delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/normalize.css/CHANGELOG.md delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/normalize.css/LICENSE.md delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/normalize.css/README.md delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/normalize.css/normalize.css delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/normalize.css/package.json delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/regenerator-runtime/LICENSE delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/regenerator-runtime/README.md delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/regenerator-runtime/package.json delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/regenerator-runtime/path.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/regenerator-runtime/runtime.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/twig/.editorconfig delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/twig/ASYNC.md delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/twig/CHANGELOG.md delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/twig/LICENSE delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/twig/README.md delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/twig/package.json delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/twig/twig.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/twig/twig.min.js delete mode 100644 COPS/cops-3.1.3/vendor/npm-asset/twig/twig.min.js.LICENSE.txt delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/.editorconfig delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/COMMITMENT delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/LICENSE delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/README.md delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/SECURITY.md delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/VERSION delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/composer.json delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/get_oauth_token.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-af.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-ar.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-as.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-az.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-ba.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-be.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-bg.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-bn.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-ca.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-cs.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-da.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-de.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-el.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-eo.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-es.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-et.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-fa.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-fi.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-fo.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-fr.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-gl.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-he.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-hi.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-hr.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-hu.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-hy.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-id.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-it.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-ja.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-ka.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-ko.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-lt.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-lv.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-mg.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-mn.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-ms.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-nb.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-nl.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-pl.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-pt.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-pt_br.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-ro.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-ru.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-si.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-sk.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-sl.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-sr.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-sr_latn.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-sv.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-tl.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-tr.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-uk.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-vi.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-zh.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/language/phpmailer.lang-zh_cn.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/src/DSNConfigurator.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/src/Exception.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/src/OAuth.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/src/OAuthTokenProvider.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/src/PHPMailer.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/src/POP3.php delete mode 100644 COPS/cops-3.1.3/vendor/phpmailer/phpmailer/src/SMTP.php delete mode 100644 COPS/cops-3.1.3/vendor/psr/simple-cache/.editorconfig delete mode 100644 COPS/cops-3.1.3/vendor/psr/simple-cache/LICENSE.md delete mode 100644 COPS/cops-3.1.3/vendor/psr/simple-cache/README.md delete mode 100644 COPS/cops-3.1.3/vendor/psr/simple-cache/composer.json delete mode 100644 COPS/cops-3.1.3/vendor/psr/simple-cache/src/CacheException.php delete mode 100644 COPS/cops-3.1.3/vendor/psr/simple-cache/src/CacheInterface.php delete mode 100644 COPS/cops-3.1.3/vendor/psr/simple-cache/src/InvalidArgumentException.php delete mode 100644 COPS/cops-3.1.3/vendor/symfony/deprecation-contracts/CHANGELOG.md delete mode 100644 COPS/cops-3.1.3/vendor/symfony/deprecation-contracts/LICENSE delete mode 100644 COPS/cops-3.1.3/vendor/symfony/deprecation-contracts/README.md delete mode 100644 COPS/cops-3.1.3/vendor/symfony/deprecation-contracts/composer.json delete mode 100644 COPS/cops-3.1.3/vendor/symfony/deprecation-contracts/function.php delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-ctype/Ctype.php delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-ctype/LICENSE delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-ctype/README.md delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-ctype/bootstrap.php delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-ctype/bootstrap80.php delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-ctype/composer.json delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-mbstring/LICENSE delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-mbstring/Mbstring.php delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-mbstring/README.md delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-mbstring/bootstrap.php delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-mbstring/bootstrap80.php delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-mbstring/composer.json delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-php81/LICENSE delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-php81/Php81.php delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-php81/README.md delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-php81/bootstrap.php delete mode 100644 COPS/cops-3.1.3/vendor/symfony/polyfill-php81/composer.json delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/CHANGELOG delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/LICENSE delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/README.rst delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/composer.json delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/AbstractTwigCallable.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Attribute/FirstClassTwigCallableReady.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Attribute/YieldReady.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Cache/CacheInterface.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Cache/ChainCache.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Cache/FilesystemCache.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Cache/NullCache.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Cache/ReadOnlyFilesystemCache.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Compiler.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Environment.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Error/Error.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Error/LoaderError.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Error/RuntimeError.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Error/SyntaxError.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/ExpressionParser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Extension/AbstractExtension.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Extension/CoreExtension.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Extension/DebugExtension.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Extension/EscaperExtension.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Extension/ExtensionInterface.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Extension/GlobalsInterface.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Extension/OptimizerExtension.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Extension/ProfilerExtension.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Extension/RuntimeExtensionInterface.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Extension/SandboxExtension.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Extension/StagingExtension.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Extension/StringLoaderExtension.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Extension/YieldNotReadyExtension.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/ExtensionSet.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/FileExtensionEscapingStrategy.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Lexer.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Loader/ArrayLoader.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Loader/ChainLoader.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Loader/FilesystemLoader.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Loader/LoaderInterface.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Markup.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/AutoEscapeNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/BlockNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/BlockReferenceNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/BodyNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/CaptureNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/CheckSecurityCallNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/CheckSecurityNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/CheckToStringNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/DeprecatedNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/DoNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/EmbedNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/AbstractExpression.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/ArrayExpression.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/ArrowFunctionExpression.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/AssignNameExpression.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/AbstractBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/AddBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/AndBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/BitwiseAndBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/BitwiseOrBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/BitwiseXorBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/ConcatBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/DivBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/EndsWithBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/EqualBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/FloorDivBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/GreaterBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/GreaterEqualBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/HasEveryBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/HasSomeBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/InBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/LessBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/LessEqualBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/MatchesBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/ModBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/MulBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/NotEqualBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/NotInBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/OrBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/PowerBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/RangeBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/SpaceshipBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/StartsWithBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Binary/SubBinary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/BlockReferenceExpression.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/CallExpression.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/ConditionalExpression.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/ConstantExpression.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Filter/DefaultFilter.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Filter/RawFilter.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/FilterExpression.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/FunctionExpression.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/FunctionNode/EnumCasesFunction.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/GetAttrExpression.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/InlinePrint.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/MethodCallExpression.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/NameExpression.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/NullCoalesceExpression.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/ParentExpression.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/TempNameExpression.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Test/ConstantTest.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Test/DefinedTest.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Test/DivisiblebyTest.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Test/EvenTest.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Test/NullTest.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Test/OddTest.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Test/SameasTest.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/TestExpression.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Unary/AbstractUnary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Unary/NegUnary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Unary/NotUnary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/Unary/PosUnary.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Expression/VariadicExpression.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/FlushNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/ForLoopNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/ForNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/IfNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/ImportNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/IncludeNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/MacroNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/ModuleNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/NameDeprecation.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/Node.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/NodeCaptureInterface.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/NodeOutputInterface.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/PrintNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/SandboxNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/SetNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/TextNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/TypesNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Node/WithNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/NodeTraverser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/NodeVisitor/AbstractNodeVisitor.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/NodeVisitor/EscaperNodeVisitor.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/NodeVisitor/MacroAutoImportNodeVisitor.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/NodeVisitor/NodeVisitorInterface.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/NodeVisitor/OptimizerNodeVisitor.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/NodeVisitor/SafeAnalysisNodeVisitor.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/NodeVisitor/SandboxNodeVisitor.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/NodeVisitor/YieldNotReadyNodeVisitor.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Parser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Profiler/Dumper/BaseDumper.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Profiler/Dumper/BlackfireDumper.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Profiler/Dumper/HtmlDumper.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Profiler/Dumper/TextDumper.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Profiler/Node/EnterProfileNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Profiler/Node/LeaveProfileNode.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Profiler/NodeVisitor/ProfilerNodeVisitor.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Profiler/Profile.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Resources/core.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Resources/debug.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Resources/escaper.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Resources/string_loader.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Runtime/EscaperRuntime.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/RuntimeLoader/ContainerRuntimeLoader.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/RuntimeLoader/FactoryRuntimeLoader.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/RuntimeLoader/RuntimeLoaderInterface.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Sandbox/SecurityError.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Sandbox/SecurityNotAllowedFilterError.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Sandbox/SecurityNotAllowedFunctionError.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Sandbox/SecurityNotAllowedMethodError.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Sandbox/SecurityNotAllowedPropertyError.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Sandbox/SecurityNotAllowedTagError.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Sandbox/SecurityPolicy.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Sandbox/SecurityPolicyInterface.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Sandbox/SourcePolicyInterface.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Source.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Template.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TemplateWrapper.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Test/IntegrationTestCase.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Test/NodeTestCase.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Token.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenParser/AbstractTokenParser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenParser/ApplyTokenParser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenParser/AutoEscapeTokenParser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenParser/BlockTokenParser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenParser/DeprecatedTokenParser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenParser/DoTokenParser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenParser/EmbedTokenParser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenParser/ExtendsTokenParser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenParser/FlushTokenParser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenParser/ForTokenParser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenParser/FromTokenParser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenParser/IfTokenParser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenParser/ImportTokenParser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenParser/IncludeTokenParser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenParser/MacroTokenParser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenParser/SandboxTokenParser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenParser/SetTokenParser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenParser/TokenParserInterface.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenParser/TypesTokenParser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenParser/UseTokenParser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenParser/WithTokenParser.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TokenStream.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TwigCallableInterface.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TwigFilter.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TwigFunction.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/TwigTest.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Util/CallableArgumentsExtractor.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Util/DeprecationCollector.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Util/ReflectionCallable.php delete mode 100644 COPS/cops-3.1.3/vendor/twig/twig/src/Util/TemplateDirIterator.php delete mode 100644 COPS/cops-3.1.3/web.config delete mode 100644 COPS/cops-3.1.3/zipfs.php delete mode 100644 COPS/cops-3.1.3/zipper.php rename COPS/{cops-3.1.3 => cops-3.2.2}/config/local.php (100%) diff --git a/COPS/CHANGELOG.md b/COPS/CHANGELOG.md index 1683df42..472b1aa0 100644 --- a/COPS/CHANGELOG.md +++ b/COPS/CHANGELOG.md @@ -1,6 +1,6 @@ # HA COPS Changelog -## [1.27] - 2024-09-22 +## [1.27.1] - 2024-09-22 - Incorporate [COPS 3.2.2](https://github.com/mikespub-org/seblucas-cops/releases/tag/3.2.2) - Fix to new locaation for config file diff --git a/COPS/config.yaml b/COPS/config.yaml index 35e25bab..e3e33e75 100644 --- a/COPS/config.yaml +++ b/COPS/config.yaml @@ -1,5 +1,5 @@ name: "HA COPS" -version: "1.27" +version: "1.27.1" slug: "ha-cops" description: "Minimal Calibre library web interface" url: "https://github.com/dunxd/HomeAssistantAddons/tree/main/COPS" diff --git a/COPS/cops-3.1.3/.dockerignore b/COPS/cops-3.1.3/.dockerignore deleted file mode 100644 index 931e2370..00000000 --- a/COPS/cops-3.1.3/.dockerignore +++ /dev/null @@ -1,24 +0,0 @@ -.git/ -*.zip -tests/ -# keep the test database in the image here -!tests/BaseWithSomeBooks/ -tests/BaseWithSomeBooks/.calnotes/backup/ -tests/BaseWithSomeBooks/.calnotes/retired/ -tests/BaseWithSomeBooks/.caltrash/ -tests/BaseWithSomeBooks/metadata_db_prefs_backup.json -vendor/ -# remove docker files -docker/ -docker-compose*.yaml -# remove development files -.vscode/ -.yarn/ -#!.yarn/releases -#!.yarn/plugins -.pnp.* -# remove unused directories -tools/ -clover.xml -coverage/ -*.cache diff --git a/COPS/cops-3.1.3/.editorconfig b/COPS/cops-3.1.3/.editorconfig deleted file mode 100644 index 1ed453a3..00000000 --- a/COPS/cops-3.1.3/.editorconfig +++ /dev/null @@ -1,10 +0,0 @@ -root = true - -[*] -end_of_line = lf -insert_final_newline = true - -[*.{js,json,yml}] -charset = utf-8 -indent_style = space -indent_size = 2 diff --git a/COPS/cops-3.1.3/.gitremotes b/COPS/cops-3.1.3/.gitremotes deleted file mode 100644 index 3c3ceccf..00000000 --- a/COPS/cops-3.1.3/.gitremotes +++ /dev/null @@ -1,9 +0,0 @@ -[remote "upstream"] - url = https://github.com/seblucas/cops.git - fetch = +refs/heads/*:refs/remotes/upstream/* -[remote "tryme"] - url = https://github.com/SenorSmartyPants/cops.git - fetch = +refs/heads/*:refs/remotes/tryme/* -[remote "peltos"] - url = https://github.com/peltos/cops.git - fetch = +refs/heads/*:refs/remotes/peltos/* diff --git a/COPS/cops-3.1.3/.htaccess b/COPS/cops-3.1.3/.htaccess deleted file mode 100644 index 4068d617..00000000 --- a/COPS/cops-3.1.3/.htaccess +++ /dev/null @@ -1,87 +0,0 @@ -DirectoryIndex index.php - - - - XSendFile on - - - -########################################### -# If the notation above don't work, you can try that one -# Disclaimer : I'm no apache expert it can be bad security wise :( -########################################### -#XSendFile On -#XSendFileAllowAbove on - -########################################### -# On WAMP one user had to add this line in his httpd.conf -# None of the above was working -########################################### -#XSendFilePath - -########################################### -# If you want to use user based configuration with -# apache 2.4 + php-fpm enable this -# https://github.com/seblucas/cops/issues/213 -########################################### -#SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 - - -RewriteEngine on -# @deprecated 3.1.0 use route urls instead -RewriteRule ^download/(\d+)/(\d+)/.*\.(.*)$ index.php/fetch/$2/$1/ignore.$3 [L] -RewriteRule ^download/(\d+)/.*\.(.*)$ index.php/fetch/0/$1/ignore.$2 [L] -RewriteRule ^view/(\d+)/(\d+)/.*\.(.*)$ index.php/inline/$2/$1/ignore.$3 [L] -RewriteRule ^view/(\d+)/.*\.(.*)$ index.php/inline/0/$1/ignore.$2 [L] -# with $config['cops_front_controller'] = 'index.php' -RewriteCond %{REQUEST_FILENAME} !-d -RewriteCond %{REQUEST_FILENAME} !-f -RewriteRule ^(.*) index.php [L,E=PATH_INFO:/$1] - - - -ExpiresActive on - -# Data -ExpiresByType text/xml "access plus 0 seconds" -ExpiresByType application/xml "access plus 0 seconds" -ExpiresByType application/json "access plus 0 seconds" -ExpiresByType application/xhtml+xml "access plus 0 seconds" - -# Favicon (cannot be renamed) -ExpiresByType image/x-icon "access plus 1 week" - -# Media: images -ExpiresByType image/png "access plus 1 month" -ExpiresByType image/jpg "access plus 1 month" -ExpiresByType image/jpeg "access plus 1 month" - -# Webfonts -ExpiresByType font/truetype "access plus 1 month" -ExpiresByType font/opentype "access plus 1 month" -ExpiresByType application/x-font-woff "access plus 1 month" -ExpiresByType image/svg+xml "access plus 1 month" -ExpiresByType application/vnd.ms-fontobject "access plus 1 month" - -# CSS and JavaScript -ExpiresByType text/css "access plus 1 year" -ExpiresByType application/javascript "access plus 1 year" -ExpiresByType text/javascript "access plus 1 year" - - -########################################### -# Uncomment if you wish to protect access with a password -########################################### -# If your covers and books are not available as soon as you protect it -# You can try replacing the FilesMatch directive by this one -# -# it helps for Sony PRS-TX and Aldiko, but beware fetch.php can be accessed -# without authentication (see $config ['cops_fetch_protect'] for a workaround). -########################################### -# -#AuthUserFile /path/to/file -#AuthGroupFile /dev/null -#AuthName "Acces securise" -#AuthType Basic -#Require valid-user -# diff --git a/COPS/cops-3.1.3/CHANGELOG.md b/COPS/cops-3.1.3/CHANGELOG.md deleted file mode 100644 index 14bfbcbb..00000000 --- a/COPS/cops-3.1.3/CHANGELOG.md +++ /dev/null @@ -1,413 +0,0 @@ -# Change Log for COPS (this fork) - -For the original releases 0.0.1 to 1.1.3 see [CHANGELOG.seblucas](CHANGELOG.seblucas.md) -or directly at https://github.com/seblucas/cops/blob/master/CHANGELOG - -x.x.x - TODO - * Upgrade npm-asset/bootstrap 3.4.1 to 5.3.3 - * Upgrade npm-asset/js-cookie 2.2.1 to 3.0.5 - -2.8.x - 2024xxxx Maintenance release for 2.x (PHP >= 8.1) - * ... - -1.5.x - 2024xxxx Maintenance release for 1.x (PHP >= 7.4) - * ... - -3.1.3 - 20240912 Fix mail link + show list of series in author details - * Fix mail link producing an [object Object] message - see issue #105 by @marioscube - * Show list of series in author details for bootstrap2 and twigged templates - * Add extra params in links generated by getFilters() + use canFilter() - * Simplify adding entries in pages + clean up constructors - -3.1.2 - 20240909 Minor fix for docker release - * Handle index.php/check to check configuration - * Upgrade twig/twig package to 3.14.0 - -3.1.1 - 20240909 Release candidate for 3.x - * Changes in config/default.php file: - - new $config['cops_front_controller'] = '' value - * Set front controller to remove index.php/ from route URLs - -3.1.0 - 20240908 Breaking changes for 3.x - * Changes in config/default.php file: - - set $config['cops_use_route_urls'] = '1' as default - - new $config['cops_twig_templates'] = ['twigged'] list - * Split off templates from HtmlRenderer - * BC: Redirect other endpoints + add deprecations - * Split off RouteTest + fix route urls - * Add basic middleware dispatcher - * BC: Enable route urls by default in config/default.php - * BC: Move config_*.php files to config/*.php to align dir structure - * BC: Rename lib/ to src/ and test/ to tests/ to align dir structure - -3.0.0 - 20240905 Update requirements (PHP >= 8.2) - * Update phpunit tests + upgrade code with rector - -2.8.2 - 20240905 More clean-up of handlers & renderers - * Expand Data mimetypes to cover common EPUB file components - * Add Response class + move notFound() + add redirect() and sendError() - * Rename FileRenderer to FileResponse and inherit from Response - * Replace header() and echo with Response() in handlers - * Use FileResponse::sendFile() for covers and thumbnails - * Fix monocle epub reader when using route urls - * Move getting zip content from ZipFsHandler to EPubReader - * Add GraphQL query field tests - * Show filters in main page for bootstrap2 and twigged templates - * Show links to PAGE_ALL in filters page to find all authors etc. for a filter - * Pass along Response() from handler to renderer + align constructor args - -2.8.1 - 20240902 Fix download filenames - * Fix FileRenderer to send the right Content-Disposition - see issue #102 by @Chirishman - -2.8.0 - 20240901 Support 'kepubify' tool for Kobo - * Add FileRenderer class to send files + use sendHeaders - * Fix Zipper to allow unicode chars in file names - * Refactor FetchHandler and getUpdatedEpub to support kepubify - * Use optional kepubify tool to convert EPUB files for Kobo - see #77 by @SenorSmartyPants - -2.7.5 - 20240831 Show extra data files in book detail + start GraphQL - * Changes in config_default.php file: - - new $config['cops_kepubify_path'] - * Start experimental GraphQL interface (dev only) - * Upgrade twig/twig package and add webonyx/graphql-php package (dev only) - * Show extra data files in book detail - see feature #97 by @russell-phillips - * Add tests for new handler classes + clean-up tests - * Remove deprecated methods for releases older than 2.7.4 - -2.7.4 - 20240828 Replace Transliteration + prepare using kepubify - * Support splitting books or authors by non-ascii first letter - * Add kepubify tool to linuxserver docker image - see issue #77 by @SenorSmartyPants and linuxserver/docker-cops#56 - * Drop old Transliteration class and use PHP Transliterator for normalized search option - -2.7.3 - 20240823 Update language files + add fixes - * Upgrade magnific-popup package to 1.2.0 - * Upgrade swagger-ui-dist package and link to 5.17.14 - * Update language files via Gitlocalize - see PRs from @horus68 and his intrepid band of translators ;-) - * Fix transparent search suggestions box - see pull request #96 from @dunxd for issue #95 by @marioscube - * Catch potential null custom columns for multi-database setup - see issue #89 by @Chirishman - * Use link handler for database entries with multi-database setup - see issue #85 by @erdoking and @shaoyangx - * Upgrade kiwilan, mikespub, symfony and twig composer packages - -2.7.1 - 20240526 Use external storage + settings for epubjs reader - * Changes in config_default.php file: - - new $config['calibre_external_storage'] - * Support external storage for Calibre library - see seblucas/cops#506 and seblucas/cops#513 - * Pass along request handler in baselist, booklist and virtual libraries - * Adjust default settings for epubjs-reader - see pull request #81 from @dunxd - * Rename IndexHandler to HtmlHandler and use default 'index' in request - * Rename download.php etc. to zipper* to avoid conflict with url rewrite - -2.7.0 - 20240512 Use handlers instead of endpoints - * Start front-end controller and router script (WIP) - * Use handlers instead of endpoints for route links - * Fix path_info for handlers when using route urls - * Add minimal framework + move endpoint code to handlers - * Change restapi routes to use endpoint instead of dummy pageId - * Add more endpoints to routes and return instead of exit - * Add getUri() for annotations and notes - -2.6.1 - 20240507 Reverse proxies, url rewriting with docker + clean-up - * Changes in config_default.php file: - - new $config['cops_trusted_proxies'] (dev only) - - new $config['cops_trusted_headers'] (dev only) - * Upgrade swagger-ui-dist package and link to 5.17.6 - * Fix rewriting rules in nginx default site conf - see #79 and linuxserver/docker-cops#31 - * Support X-Forwarded-* and Forwarded headers from trusted proxies (dev only) - * Add Wiki page to clarify [Reverse proxy configurations](https://github.com/mikespub-org/seblucas-cops/wiki/Reverse-proxy-configurations) - * Rename JSON_renderer and OPDS_renderer files and classes - * Add HtmlRenderer class and move html template rendering from index.php - * Use dcterms:modified instead of mtime as link attribute in OPDS feeds - -2.5.6 - 20240503 Support TXT files in OPDS feeds + add length and mtime - * Add length + mtime to OPDS acquisition links - perhaps for #79 - * Fix Opds connection under docker deployment cannot display books in TXT files - see #79 by @shaoyangx - -2.5.5 - 20240423 Update epubjs-reader - * Update epubjs-reader version + template - -2.5.4 - 20240409 Add settings for epubjs-reader - * Changes in config_default.php file: - - new $config['cops_epubjs_reader_settings'] - * Configurable epubjs-reader settings - see issue mikespub-org/intity-epubjs-reader#2 by @intity - -2.5.3 - 20240404 Expand rest api + update epubjs reader - * Upgrade mikespub/epubjs-reader from @intity theme - see issue #76 - * Upgrade mikespub/epub-loader to 3.0 for wikidata (dev only) - * Upgrade swagger-ui-dist package and link to 5.12.0 - * Get annotations from database or metadata.opf file - * Add Annotation and Metadata classes - * Add annotations in test data files - * Add cover and thumbnail route urls - * Match routes with endpoints in rest api - * Get user details in rest api - -2.5.1 - 20240307 User accounts database + route to endpoints - * Changes in config_default.php file: - - new $config['cops_http_auth_user'] - - new $config['calibre_user_database'] - - add $config['cops_basic_authentication'] option - * Upgrade mikespub/epub-loader to 2.5 to use route urls (dev only) - * Start use of Calibre user accounts database (TODO) - * Add support for authentication via reverse proxy - -2.5.0 - 20240306 Use virtual libraries + support epubjs reader - * Changes in config_default.php file: - - new $config['cops_virtual_library'] - - new $config['cops_epub_reader'] - * Select virtual library via customize page or config_local - * Propose epubjs-reader as alternative for monocle - * Clarify WebDriver tests with selenium container (dev only) - * Split off index page and filter by virtual library - -2.4.3 - 20240302 Start virtual libraries + switch to phpunit 10.5 - * Changes in config_default.php file: - - new $config['cops_calibre_virtual_libraries'] - * Update dependencies + switch to phpunit 10.5 - * Add identifier filter links - * Start support for virtual libraries from Calibre (TODO) - -2.4.2 - 20240227 Show category notes for Calibre 7.x (bootstrap2 & twigged) - * Show use of db parameter in openapi for REST API - * Add notes and preferences routes in REST API - * Add Preference class for Calibre preferences - * Show notes in page detail for bootstrap2 & twigged templates - * Get notes for author, publisher, serie and tag if available - -2.4.1 - 20240226 Support cops_full_url in REST API swagger ui - * Fix restapi.php when cops_full_url is needed - see issue #74 from @bcleonard - -2.4.0 - 20240225 Add rating and instance link if available - * Changes in config_default.php file: - - new $config['cops_download_template'] - * Add instance link for extra information on author, publisher, serie and tag - * Save to disk template for book filenames inside the .zip download file (TODO) - * Upgrade mikespub/epub-loader to 2.4 to get rid of superglobals (dev only) - * Add missing rating to bookdetail templates - -2.3.1 - 20240220 Fix cover popup for default template - * Fix no large book covers and white screen with viewer - see issue #73 from @marioscube - -2.3.0 - 20240218 Update OPDS 2.0 and EPub Loader (dev only) - * Upgrade kiwilan/php-opds to 2.0 to fix OPDS 2.0 pagination - * Upgrade mikespub/epub-loader to 2.3 to include OpenLibrary lookup - -2.2.2 - 20240215 Fix multi-database for epub reader and email - * Error sending or reading book from additional dbs - see issue #72 from @malkavi - -2.2.1 - 20231116 Consolidate PRs for next release (PHP >= 8.1) - * Support display settings for custom columns - see pull request #69 from @Mikescher - * Add Japanese language file - see pull request #67 from @horus68 translated by Rentaro Yoshidumi - * Use server side rendering for Kobo - see pull request #62 from @dunxd - * Add bootstrap2 Kindle theme - see pull request #61 from @dunxd - * Improve Kindle style - see pull request #60 from @dunxd - * Fix default values in util.js for Kindle - see pull request #58 from @dunxd - -2.2.0 - 20230925 Update dependencies (PHP >= 8.1) - * Upgrade mikespub/epub-loader to 2.2 (dev only) - * Upgrade mikespub/php-epub-meta to 2.2 - -2.1.5 - 20230925 Tweaks and fixes on previous release (PHP >= 8.1) - * Fix download by page with route urls, customize link in default footer, header links in bootstrap5 - * Add first & last paging in bootstrap2 & twigged templates - * Refresh page on style change - see pull request #55 from @dunxd - * Fix style css not being prefixed with Route::base() - see pull request #54 from @Mikescher - -2.1.4 - 20230924 Translations, Bootstrap5, Route URLs and REST API (PHP >= 8.1) - * Changes in config_default.php file: - - new $config['cops_use_route_urls'] - - new $config['cops_api_key'] - * Translations update sept 2023 - see pull request #52 from @horus68 - * Improve submenu and filters in bootstrap5 template - see pull requests from @dunxd - * Fix distinct count for identifiers - * Add swagger-ui interface and api key config for REST API tests - * Add json schema validation for OPDS 2.0 tests - ok with 1.0.30 except pagination - * Use nikic/fast-route to match route urls (if enabled) - * Use route urls in code and absolute paths in templates - -2.1.3 - 20230919 Try route urls + improve sort in bootstrap5 (PHP >= 8.1) - * Use nikic/fast-route to match route urls (dev only) - * Start route urls in code and absolute paths in templates - * Improve sorting in bootstrap5 template - see pull requests from @dunxd - -2.1.2 - 20230917 Fix TOC children + improve bootstrap5 template (PHP >= 8.1) - * Fix sort asc/desc for author and rating - see issue #44 - * Show TOC with children in epub reader with mikespub/php-epub-meta 2.1+ - * Improve bootstrap5 template some more - see pull requests from @dunxd - -2.1.1 - 20230914 Download books per page/series/author, fix search form + add epub-loader (PHP >= 8.1) - * Changes in config_default.php file: - - new $config['cops_download_page'] - - new $config['cops_download_series'] - - new $config['cops_download_author'] - * Use kiwilan/php-opds to generate OPDS 2.0 catalog with opds.php (besides OPDS 1.2 with feed.php) (dev only) - * Add download.php to allow downloading all books of a series or author, or all books on a page - * Fix search form with server-side rendering in bootstrap* templates - see pull request #38 from @dunxd - * Add loader.php for integration of epub-loader (development mode only) - -2.0.1 - 20230910 Initial release for PHP >= 8.1 with new EPub update package - * More spacing tweaks on the bootstrap5 template - see pull request #35 from @dunxd - * Use maennchen/zipstream-php to update epub files on the fly (PHP 8.x) - -1.5.4 - 20230910 Split off resources in preparation of 2.x - * Changes in config_default.php file: - - new $config['cops_assets'] - * Use it.assets variable in doT templates to refer to 'vendor/npm-asset' - * Use asset() function in Twig templates to get versioned asset URLs - * Split off epub-loader, php-epub-meta and tbszip resources again - * Align resources folders to src and app in code - -1.5.0 - 20230909 New baseline for next releases - * Support class inheritance for most COPS lib and resource classes in code - * Minor updates for templates - pass ignored categories #30 + set document title #31 - * Add resources/epub-loader actions for books, series and wikidata - * Update bootstrap5 template - see pull request #29 from @dunxd - feedback still appreciated - * Add support for .m4b files in COPS - see issue #28 from @Chirishman - * Add twigged template using Twig template engine as alternative for doT - -1.4.5 - 20230905 Make sort links optional in OPDS feeds for old e-readers - * Changes in config_default.php file: - - new $config['cops_opds_sort_links'] - - new $config['cops_html_sort_links'] - * Make sort links optional in HTML page detail and OPDS catalog - see #27 - -1.4.4 - 20230904 Revert OPDS feed changes for old e-readers - * Switch section to subsection in OPDS link rel for koreader and Kybook3 - see #26 and #27 - * Add class label for #24 + authors & tags for #25 in JSON renderer - * Prepare move from clsTbsZip to ZipEdit when updating EPUB in code - -1.4.3 - 20230831 Sort & Filter in OPDS Catalog + Add bootstrap v5 template - * Changes in config_default.php file: - - new $config['cops_thumbnail_default'] - - new $config['cops_opds_filter_limit'] - - new $config['cops_opds_filter_links'] - - new $config['cops_html_filter_limit'] - - new $config['cops_html_filter_links'] - - drop $config['cops_show_filter_links'] - * Add bootstrap5 template for modern devices - see pull request #22 from @dunxd - feedback appreciated - * Add optional Identifier pages in code - * Fix updating author & date in epub-loader - * Start WebDriver and BrowserKit test classes for functional testing - * Split off new Calibre\Cover class + move various thumbnail code there - * Add default thumbnail and link numbers for OPDS catalog if e-reader uses them - * Add first & last links + sorting & filtering options for OPDS catalog (if e-reader supports facets) - * Keep track of changes in ZipFile + fix setCoverInfo() in EPub in code - * Split off new Pages\PageId class + move PAGE_ID constants there in code - * Mark combined getsetters for EPub() as deprecated for 1.5.0 in php-epub-meta - * Add updated php-epub-meta methods and classes to version in resources - see https://github.com/epubli/epub - * Fix code base to work with phpstan level 6 - -1.4.2 - 20230814 Fix OPDS renderer + add sorting & filtering options to bootstrap2 - * Changes in config_default.php file: - - new $config['calibre_categories_using_hierarchy'] - - set $config['cops_template'] = 'bootstrap2' again - - new $config['cops_custom_integer_split_range'] - - new $config['cops_custom_date_split_year'] - - new $config['cops_titles_split_publication_year'] (if not $config['cops_titles_split_first_letter']) - * Add optional hierarchical tags and custom columns in bootstrap2 template - * Split off new Calibre\Category class + support hierarchical tags and custom columns in code - * Remove global $config everywhere and replace with Config::get() except in config.php - * Switch back to bootstrap2 as standard template in config_default.php - * Move endpoint dependency from LinkNavigation to JSON/OPDS renderer - * Update checkconfig.php to better reflect current requirements - * Downgrade level set to PHP 7.4 with rector to fix a few compatibility issues - * Rebase Calibre\Book and Calibre\CustomColumnType classes - * Split off new Calibre\BaseList class and move SQL statements - * Add sorting of non-book lists with URL param in code - * Add optional filter links in bootstrap2 template - * Add filtering of non-book lists in pages - * Add sort options for book lists in bootstrap2 template - * Add pagination for custom columns + split by range for Integer - * Add pagination for non-book lists if not already split - * Add option to split custom columns of type Date by year - * Fix OPDS renderer for HTML content - see pull request seblucas/cops#488 from @cbckly - * Add other .title translations to i18n array for use in templates - see pull request #11 from @dunxd - * Add sorting of booklist entries with URL param in code - * Add option to split titles by publication year - * Add Librera reader to detected OPDS compatible readers - see pull request #10 from @dunxd - -1.4.1 - 20230728 Clean-up before next release - * Changes in config_default.php file: - - new $config['cops_home_page'] for @dunxd - - new $config['cops_show_not_set_filter'] - * Add parent url and customize link in templates - * Allow filtering non-book queries on other params in code ('a', 'l', 'p', 'r', 's', 't', 'c') = e.g. get Series for AuthorId - * Allow filtering booklist queries on other params in code ('a', 'l', 'p', 'r', 's', 't', 'c') = get books for a combination - * Expand OpenAPI document for REST API - * Fix cookie javascript code for server-side rendering - * Fix tag filter, multi-database navigation and feed link - * Split off new Calibre\Database, Calibre\BookList, Calibre\Filter, Input\Config and Output\Mail classes - -1.4.0 - 20230721 Use namespaces in PHP lib, upgrade jquery npm asset + sausage package - * Split off new Input\Request, Language\Translation, Output\Format and Output\EPubReader classes - * Pass database and/or request param in static method calls to remove dependency on global $_GET - * Update OPDSValidator, jing and tests for OPDS 1.2 (last updated in 2018) - * Add namespace hierarchy, move page constants + make Calibre classes a bit more generic - * Switch from npm-asset/typeahead.js 0.11.0 to npm-asset/corejs-typeahead 1.3.3 - * Upgrade sauce/sausage 0.18.0 to dev-php8x = PHP 8 compatible fork from https://github.com/IMrahulpai/sausage - * Upgrade npm-asset/jquery 1.12.4 to 3.7.0 - * Use PHP namespace in lib: SebLucas\Cops - -1.3.6 - 20230714 Add REST API, limit email address, clean up constants + fix book test - * Add REST API endpoint (basic) - * Limit sending to a single email address - see pull request #7 from @dunxd - * Clean up global base constants - * Fix kindle book text - -1.3.5 - 20230712 Send EPUB, fix custom columns, support wildcard + add tests - * Changes in config_default.php file: - - set $config['cops_template'] = 'default' for issues with Kindle Paperwhite - - set $config['default_timezone'] = 'UTC' - - new wildcard option for $config['cops_calibre_custom_column'] = ["*"]; - - new wildcard option for $config['cops_calibre_custom_column_list'] = ["*"]; - - new wildcard option for $config['cops_calibre_custom_column_preview'] = ["*"]; - * Replace offering to email MOBI with EPUB - see pull request #6 from @dunxd - * Use wildcard to get all custom columns : ["*"] - * Update tests for custom columns - * Fix multiple values of custom columns for csv text - * Fix display value of custom columns for series - * Revert octal number notation in tbszip for PHP 8.0 - * Add tests for JSON renderer - * Add tests for book methods called by epub reader - -1.3.4 - 20230609 Fix EPUB 3 TOC, replace other npm assets and use namespace in PHP resources - * Fix TOC for EPUB 3 files in resources/php-epub-meta for epubreader - * Switch from dimsemenov/magnific-popup 1.1.0 to npm-asset/magnific-popup 1.1.0 (last updated in 2016) - * Switch from twitter/typeahead.js 0.11.1 to npm-asset/typeahead.js 0.11.1 (last updated in 2015) - * Switch from twbs/bootstrap 3.4.1 to npm-asset/bootstrap 3.4.1 - * Use PHP namespace in resources/dot-php: SebLucas\Template - * Use PHP namespace in resources/epub-loader: Marsender\EPubLoader - * Use PHP namespace in resources/php-epub-meta: SebLucas\EPubMeta - * Use PHP namespace in resources/tbszip: SebLucas\TbsZip - -1.3.3 - 20230327 Update npm asset dependencies - * Fix link to typeahead.css for bootstrap2 templates - * Move simonpioli/sortelements dev-master to resources (last updated in 2012) - * Switch from bower-asset/dot 1.1.3 to npm-asset/dot 1.1.3 - * Switch from bower-asset/jquery 1.12.4 to npm-asset/jquery 1.12.4 - * Switch from bower-asset/jquery-cookie 1.4.1 to npm-asset/js-cookie 2.2.1 - * Switch from bower-asset/normalize.css 7.0.0 to npm-asset/normalize.css 8.0.1 - * Switch from rsms/js-lru dev-v2 to npm-asset/lru-fast 0.2.2 - -1.3.2 - 20230325 Improve tests and security - * Merge branch 'master' of https://github.com/peltos/cops - see @peltos - -1.3.1 - 20230325 Update epub-loader resources - * Merge commit 'refs/pull/424/head' of https://github.com/seblucas/cops - see seblucas/cops#424 from @marsender - -1.3.0 - 20230324 Add bootstrap2 templates - * Merge branch 'master' of https://github.com/SenorSmartyPants/cops - see seblucas/cops#497 and earlier from @SenorSmartyPants - -1.2.3 - 20230324 Add fixes for PHP 8.2 - -1.2.2 - 20230324 Update fetch.php to lower memory consumption - * Merge commit 'refs/pull/518/head' of https://github.com/seblucas/cops - see seblucas/cops#518 from @allandanton - -1.2.1 - 20230321 Add phpstan baseline + fixes - -1.2.0 - 20230319 Migration to PHP 8.x - -1.1.3 - 20190624 -to -0.0.1 - 20120302 - -Moved to [CHANGELOG.seblucas](CHANGELOG.seblucas.md) diff --git a/COPS/cops-3.1.3/CHANGELOG.seblucas.md b/COPS/cops-3.1.3/CHANGELOG.seblucas.md deleted file mode 100644 index f757c8d2..00000000 --- a/COPS/cops-3.1.3/CHANGELOG.seblucas.md +++ /dev/null @@ -1,326 +0,0 @@ -# Change Log for COPS (original) - -For the forked releases 1.2.0 and beyond see [CHANGELOG](CHANGELOG.md) -or directly at https://github.com/mikespub-org/seblucas-cops/blob/main/CHANGELOG.md - -1.1.3 - 20190624 - * Fixed an error with PHP > 7.2.X where create_function is deprecated, also fixed another error with PHP 7.3.X. Thanks to Turkish for the report. - * Fixed the view button when URL Rewriting is enabled. - * Fixed an error in epubreader with headers. thanks to worstje for the report. - * Added a real logo for COPS. Thanks to horus68 for doing all the work ;). - * Added a proper translation for `_CLEAR_` text. Was reported for many year :(. - * Added Galician translation. Thanks to Sadrarin Highland. - * Added Afrikaan translation. Thanks to PetrusVermaak. - * Updated Spanish, Basque, Italian, Dutch, French, Portuguese, Romanian, Russian, Swedish, Turkish. Thanks to the translators and horus68. - * Upgraded to latest phpmailer 5.2.27 and bootstrap 3.4.1. - -1.1.2 - 20180626 - * Fixed the download of Kepub with recent firmware from Kobo. Thanks to ospring for the report. - * Fixed the cache headers. Thanks to CgX for the fix. - * Added Bulgarian, Indonesian, Chinese (China and Taywan) translation. Check Transifex for the authors. - * Added an open button to use automatically your prefered reader. Thanks to ttan. - * Updated Hungarian, Ukranian, Polish, Spanish and Swedish translations. Check Transifex for the authors. - * Updated a lot of documentation and checkconfig.php to better help users. - * Upgraded to latest jQuery 1.12.X, Normalise 7.0, PHP Mailer 5.2.26, Font Awesome Free 5.0.13. - -1.1.1 - 20170502 - * Fixed the handling of user specific configuration files. Thanks to marioscube, chadberg for the diagnostic / fix and Neil for the PR. - * Changed the cog on the upper right to a magnifying glass icon. Thanks to horus68. - * Added test on travis on PHP 5.4. - * Added a way to specify the secure SMTP port. Thanks to ubupl. - -1.1.0 - 20170402 - * Upgraded to PHPMailer 5.2.21. - * Merged a huge PR that clean most of COPS source code. Thanks to Markus Birth for his work and his patience. - * Updated German, Greek, Italian, Polish, Romanian, Russian, Turkish translations. Check Transifex for the authors. - * Fixed a bad external dependency in login.html causing problem with HTTPS. Thanks to polytan02. - * Fixed minor gui nitpick. - * Added automatic redirection to the OPDS feed for many new Android apps (see #309). Thanks to horus68. - * Added a configuration item to set the mail subject. - -1.0.1 - 20161015 - * Fixed some type of custom column showing id instead of text - Thanks to Mike Schwörer. - * Fixed the redirection to the OPDS catalog for Moon+ Reader. - * Fixed the mail character encoding, now in UTF-8. - * Fixed checkconfig.php to avoid sending content before headers. Thanks to Luke Stevenson. - * Fixed server side rendering with custom columns. - * Moved /icons to /images (Apache issues). Thanks to CgX. - -1.0.0 - 20160708 - * Updated the OPDS icons to better looking ones. Thanks to Horus68. - * Updated the README.md. - * Updated Brazillian, French, Hungarian, Portuguese, Russian translations. - * Added support of language and country code. This allow to have proper Brazil Portuguese and Portugal Portuguese. - * Added Korean translation. Thanks to Jin, Heonkyu. - * Added Romanian translation. Thanks to mtzro2003. - * Added Greek translation. Thanks to George Litos. - * Added Turkish Translation. Thanks to Yunus Emre Deligöz. - * Added Serbian Translation. Thanks to Dalibor Vinkić. - * Added the transliteration of search text. You can enable it with $config ['cops_normalized_search']. Thanks to George Litos. - * Added Ebookdroid, Chunky and AlReader in the know OPDS clients. Thanks to Mike Ferenduros and Horus68. - * Added some mime types for audio books. - * Added the rewrite rule for IIS. - * Added a now parameter to set the style ($config['cops_style']). Thanks to Pablo Santiago Blum de Aguiar. - * Added a directory cache ($config['cops_thumbnail_cache_directory']) to store the resized thumbnails (should help on slow NAS). Thanks to O2 Graphics. - * Added support of all kind of custom columns (see configuration file). Thanks to Mike Schwörer. - * Fixed COPS so that it's completely embedded (no external resources to download needed anymore). - * Fixed a Reflected XSS vulnerability. - * Fixed the tag filters with Bootstrap. Thanks to Klaus Broelemann. - * Fixed some COPS path errors with reverse proxy. Thanks to Benjamin Kitt. - * Fixed the publication date (wasn't working for date before 1901). - * Fixed the download file name (replace + by %20 to be RFC compliant). - - -1.0.0RC3 - 20141229 - * Fixed server side render with Bootstrap template (a proper unit test was also added). - * Upgraded to latest doT-php, Typeahead 0.10.5, jquery-cookie 1.4.1, JQuery 1.11.1 - * Fixed book count with custom columns. - * Updated Catalan, Dutch, French and Russian translations. - * Added AZW3 to the format that can be sent to Kindle (by mail). - * Fixed $config['cops_thumbnail_handling'] with bootstrap template. - * Added Hungarian translation. Thanks to harunibn. - * Added Ukrainian translation. Thanks to Anatoliy Zavalinich - * Added full PHP password check (without any need from specific webserver configuration). Thanks to Mark Bond. - * Added new IOS7 style with default template. Thanks to an anonymous source ;). - * Fixed display of authors names for books with more than one author. - * Added PHP version to checkconfig.php (will help debugging for me). - * Added a configuration item ($config['cops_template']) to change the default template. Thanks to Shin. - * Added a configuration item ($config['cops_language']) to force COPS language. Thanks to Sandy Pleyte. - * Added a trick to have user based configuration, check https://github.com/seblucas/cops/wiki/User-based-config for more information. Thanks to Sandy Pleyte. - * Changed the default sort order on books by author page to show books in a series before all other books. - - -1.0.0RC2 - 20140731 - * Updated Italian, Spanish, Portuguese, Norwegian translations. - * Added Polish translation. Thanks to macak_pl. - * Added Haitian Creole translation. Thanks to Ian Macdonald & Jacinta. - * Added Basque translation. Thanks to Turutarena. - * Upgraded to JQuery 1.11.0, Magnific Popup 0.9.9, Normalize 3.0.1, Typeahead 0.10.2 - * Fixed search with accentuated characters on Internet Explorer. - * Author can now be searched by sort or by name (Carroll, Lewis or Lewis Carroll will work). - * Added a new bootstrap user interface. - * Added correct mimetype for *.ibooks. Reported by Flowney. - * Added an empty line at the end of .htaccess to make it easier to modify. Reported by Mariosipad. - * Modified the README and checkconfig.php to check for php5-json. Reported by Mariosipad. - * Handled properly the cancelling of a mail. Reported by coach0742. - * Added an ugly hack to try to fix bad rendering with Kindle. Please report if it's better or not. - -1.0.0RC1 - 20140404 - * Updated English, Spanish, German, Italian, Portuguese, Dutch translation files. Huge thanks to all to the translators. - * Added Swedish translation. Thanks to Bo Rosén. - * Added Czech translation. Thanks to Zdenek Hadrava. - * Added a lot of refactoring to simplify the code. - * Added a lot of new unit tests. - * Fixed a caching bug causing problems with IE. - * Added an embedded Epub Reader based on Monocle. Thanks to all the beta testers. - * Cleaned up a lot of stuff to prepare for bootstrap template. Note to all CSS hackers, the stylesheets are now in templates/default/styles. - * Fixed the charset of most of the pages. Thanks to edent. - * Added a new category : ratings. Thanks to Michael. - * Fixed the URL rewriting in the OPDS stream, should fix file naming with FBReader. Reported by Rassie. - * Fixed a confusion between author's name and author's sort. Reported by At_Libitum. - * Fixed the style of the tag filters to show that they're clickable. Thanks to cycojesus. - * Replaced | by space in author name. - -0.9.0 - 20131231 - * Add a lot of unit testing. I hope it will limit the risks of regression. - * Added a "smart / autocomplete" search. - * Updated the way locales are handled. Should be easier to add new languages. - * Fixed display of Cyrillic characters. - * Upgraded doT to version 1.0.1, Magnific-Popup to 0.9.8, Normalize.css to 2.1.3, Jquery-cookie to 1.4.0. - * Fixed OPDS stream validity. Reported by Didier. - * Added a new check in checkconfig.php to detect case problem between the actual path and the path stored in Calibre database. Try checkconfig.php?full=1. Reported by Ruud. - * Fixed the display of the rating stars with Chrome. Thanks to At_Libitum. - * Added a new parameter ($config['cops_titles_split_first_letter']) to avoid splitting the books by first letter. Thanks to At_Libitum. - * Fixed non compliant OPDS search (for Stanza, Moon+ Reader, ...). Reported by At_Libitum. - * Fixed the redirection in case the Calibre database is not found. Reported by At_Libitum - * Changed .htaccess to allow the use of password protected catalogs with Sony's eReader (PRS-TX). Thanks to Ruud for the beta testing. - * Updated Chinese, German, Norwegian, Portuguese, Russian translations. Huge thanks to all the translators. - * Fixed a small problem : If a book had no summary the cover could be cut. - * Fix COPS on Internet Explorer 9. Reported by At_Libitum. - * Added publishers in home categories / search / autocomplete search. - * Added a new configuration item ($config ['cops_ignored_categories']) to ignore some categories (author, tag, publisher, ...) in home screen and searches. It's also available in the "Customize UI" page. - * Updated .htaccess to allow downloading books with a password protected COPS on a Sony PRS-TX. Reported by Ruud. - * Changed the default search to search by categories also (should help with OPDS). Thanks to At_Libitum. - * Fixed the tag filtering in the HTML catalog when two tags starts by the same word. Reported by Tyler. - -0.6.2 - 20130913 - * Added server side rendering for devices like PRS-TX / Kindle / Cybook. Thanks to all the testers. - * Added a configuration item to tweak how thumbnail are handled. - * Fixed the click on cog on IOS. Thanks to sb domo. - * Added dashboard icons / standalone mode for IOS. Thanks to sb domo. - * Fixed a regression about custom favicon.ico. Thanks to Tyler. - * Fixed another regression about COPS's version in the about box. Reported by Ian. - * Upgraded Magnific Popup to v0.9.5. - * Added a style for IPhone. Thanks to sb domo. - * Added Portuguese translation. Thanks to Pablo Aguiar. - * Fixed rendering on Internet Explorer < 9.0. - -0.6.1 - 20130730 - * Properly close the lightbox when clicking in a link. Reported by le_. - * Fix the book by languages list when the language is not found in the resources. Reported by le_. - * Fix the string for Portuguese. Reported by le_. - * Add again the series Index in the book list. Reported by fatzgenfatz. - -0.6.0 - 20130724 - * COPS HTML catalog now use templated client side rendering. You can build your own template if you want. Should be a lot faster. - * Fancybox has been replaced by Magnific Popup, it seems faster. - * Added a way to send book by mail (to send to Kindle or to send to your friends). - * Added expires instruction in .htaccess (won't crash if you haven't enabled mod_expires). - * Upgrade to JQuery 1.10.2. - * Changed the way thumbnails are handled to offer greater visual quality (especially on high pixel density devices : Retina, Nexus, ...). - * Changed all icon by a vectorial font (again better visual quality). - * Added a way to filter books by tags. - * Added a login page (login.html) to allow access to a password protected COPS on a Kobo ereader (that does not support basic auth). - * Fixed cookie expiry date. - * Added a default web.config for IIS installation. - * The eink style doesn't use shadow anymore. - * Fixed the link to the series in book detail. - -0.5.0 - 20130605 - * Upgrade COPS UI to HTML5 / CSS3 to hopefully make it prettier. Most of the code was contributed by Thomas Severinsen. - * Add the number of books in each databases (when multiple database is enabled). - * Add Norwegian Bokmål strings. Thanks to Rune Mathisen for the pull request. - * Add a split by language of catalog. Thanks to Puiu Ionut for the pull request. - * You can now change the theme and fancybox use on all your devices (You have to enable cookies). - * Add an eink theme. Thanks to Gregory Bodin for the code. - -0.4.0 - 20130507 - * Add multiple database support. Check the documentation of $config['calibre_directory'] in config-default.php to see how to enable it. - * Include jquery library in COPS's repository to be sure that COPS will work on LAN (without Internet access). - * Prepare the switch to HTML5. Thanks to Thomas Severinsen for most of the code. - * Update the locale strings to be more strict with plurals. Thanks to Tobias Ausländer for the code. - * If Fancybox is not enabled ($config['cops_use_fancyapps'] = "0") then it's not used at all (even in the about box). - * Fix book comments if it contains UTF8 characters. Reported by Alain. - * Link to the book permalink was not working correctly in some cases. Reported by celta. - * Moved some external resources to a resources directory. - * Add chinese translation. Thanks to wogong for the pull request. - -0.3.4 - 20130327 - * Hopefully fix metadata update. Beware you should remove the directory php-epub-meta if you have one. Thanks to Mario for his time. - * Fix two warnings. Reported by Goner and Mario. - -0.3.3 - 20130323 - * Fix catalog if book summary contains bad HTML again :(. - * Upgrade to Fancybox 2.4.0 and JQuery 1.9.1. - * Search is now dependant on the page you're in. For now if you're on author page it'll look for author name. - * Update checkconfig to check if the database provided comes from Calibre. - * Update to latest php-epub-meta should fix the metadata update with Epub. - * Fix OPDS catalog with Ibis Reader. It didn't like empty language. - -0.3.2 - 20130303 - * Add dutch translation. Provided by Northguy. - * Fix an ugly bug introduced in 0.3.1. Reported by mariosipad. - * Small fixes/enhancement to the update metadata tools : - * The book's name is Author - Title.epub - * Add the Calibre uuid so that the book is automatically recognised by Calibre. - * Update the cover - * Fix display of the HTML catalog on Kobo's browser. - * Enable kepub.epub download with cover fix (enable with $config['cops_provide_kepub']). - * Hopefully fix browsing with PRS-T1. Thanks to Northguy. - * Hopefully fix the OPDS catalog when the summary is full of HTML crap. - * Merged 3 patches from Tyler J. Wagner : - * Detect empty publication date set in Calibre to avoid having (0101) as publication year. - * Don't print "Languages" if there are none defined. - * Don't print the tag string if there's no tags. - * If an OPDS client try to access index.php it will be automatically redirected to feed.php. - * Move the search & sort tool box to a new line (also fix a w3c error). - - -0.3.1 - 20130127 - * Add Facets to the OPDS catalog (check config item cops_books_filter). - So far the only OPDS client that support facets are Mantano Reader and Bluefire - * Fix book sort in some list. Patch provided by Tyler J. Wagner. - * Update .htaccess to check if Xsendfile is available. Thanks to Gaspine for the patch. - * Add basic support of custom columns. Check the following config item : cops_calibre_custom_column - * Usage of X-Accel-Redirect / X-Sendfile is not necessary anymore. Warning all Nginx users - who wants to still use X-Accel-Redirect must add - $config['cops_x_accel_redirect'] = "X-Accel-Redirect" in their config_local.php - * Fix COPS on IIS / Windows. Reported by Kevnancy. - * Simplified config_default.php - * Add a new config_local.php.example with the minimal configuration item to change. - - -0.3.0 - 20130106 - * Add a config item to avoid using Fancyapps (pop-ups). Reported by mcister and Northguy. - * Update documentation of .htaccess. Thanks to Stephane. - * Add a config item to specify a custom icon. Based on a patch by Tyler J. Wagner. - * Better handling of content type for book. Reported by Morg. - * Upped the size of thumbnails for OPDS. They look way better with Mantano. - * Add language in OPDS feed (shown in Mantano for example). - * Update metadata on downloaded epub. Disabled by default (check config item cops_update_epub-metadata). - * New Catalan translation provided by David Ciscar Presas. - * Add a permalink to books, that way direct link to books can be shared. Reported by mcister and Tyler J. Wagner. - * Add checkconfig.php that should allow to better detect the configuration problem (page in english only for now). - * Fix some plural strings / some missing title. Reported by David Ciscar Presas. - * Add an hint about the OPDS catalog in the HTML catalog. - -0.2.3 - 20121205 - * Add a .htaccess to make it easier to use with Apache - * Fix a typo in book download. Reported by jillmess - * Update localization (thanks to Calibre2Opds) - * Add some missing information from Calibre (language, rating for now). Reported by mcister - * Upgrade Fancybox to 2.1.3 - - -0.2.2 - 20121020 - * Changed JQuery URL to https (thanks to Dan Greve for the patch) - * Added paging to both OPDS and HTML catalog (use new config item cops_max_item_per_page) - * lots of code refactoring - * Authors are now splitted by first letter, this is the new default. You can go back to the old way with the config item cops_author_split_first_letter (reported by Northguy) - * Fix the link to books starting by special characters (reported by vinpel) - * Upgrade to Fancyapps 2.1.0. I had to adapt the CSS so maybe it'll display better in PRS-T1 - * Add an about box on the HTML catalog which show the current version - -0.2.1 - 20120916 - * Fix one last error (hopefully) in link generation (thanks to gaspine) - * Add Sony PRS-T1 to the list of E-Ink device (thanks to Northguy) - * Fix another HTML special characters problem (thanks to NeilBryant) - * Add an ugly config parameter to allow search in non-compliant OPDS reader (thanks to Don Caruana and David Lee) - -0.2.0 - 20120722 - * Fix all rewriting rule I forgot to change it in last release - * Fix
in book comment (thanks to jillmess) - * Fix cover zoom in HTML catalog (you can also navigate through cover with keyboard) - * Simplify Fancybox transition for e-Ink devices (for now Kobo and Kindle) - -0.1.1 - 20120702 - * A lot of bug fixes in HTML catalog - * Fixed the book comment in OPDS (broken in some rare case) - * Fixed handling of HTML reserved characters - * Changed book OPDS id to use an UUID (thanks to ilovejedd for the bug report) - * Add new config item for the default timezone (thanks to gaspine) - * Better handling of missing covers - * Should support every book format supported by Calibre (thanks to Artem) - * URL rewriting is off by default for the HTML catalog - * Add some documentation about URL rewriting (thanks to gaspine and Christophe) - * Tested and ready to use with PHP5.4 - -0.1.0 - 20120605 - * Add localization support (thanks to Calibre2Opds) - * Hopefully fixed an issue with & in comment - * HTML catalog is in the sources with no support (WIP) - -0.0.4 - 20120523 - * More code refactoring to simplify code. - * Changed OPDS Page id to match Calibre2Opds - * Add icons to author, serie, tags and recent items (there is config item to disable it) - * Fixed author URL - * Added publishing date (works on Mantano) - * Added Tags support - -0.0.3 - 20120507 - * Fixed many things blocking opensearch from working - * There was a bug introduced in 0.0.2 - * The URL can't be relative for Mantano reader, so I added a configuration item. - * I continued the refactoring to bring HTML to COPS - * Thumbnails have bigger size (I'll add a configuration item later) - * Add headers to help caching image and thumbnail to the browser - * - -0.0.2 - 20120411 - * Add support for MOBI and PDF - * Major refactoring to prepare something nice for the future ;) - * Add a config item to make use of X-Sendfile instead of X-Accel-Redirect if needed - -0.0.1 - 20120302 - * First public release diff --git a/COPS/cops-3.1.3/COPYING b/COPS/cops-3.1.3/COPYING deleted file mode 100644 index d60c31a9..00000000 --- a/COPS/cops-3.1.3/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/COPS/cops-3.1.3/README.md b/COPS/cops-3.1.3/README.md deleted file mode 100644 index 69585565..00000000 --- a/COPS/cops-3.1.3/README.md +++ /dev/null @@ -1,183 +0,0 @@ -# COPS for PHP 8.x - -## Breaking changes for 3.x release (PHP >= 8.2) - -### For everyone -- move your customized *config_local.php* file to *config/local.php* on the web server/container -- replace any *feed.php* links with *index.php/feed* for OPDS feeds in your e-reader - -### Less common -- if you map the *lib/* or *test/* directory somewhere, like a docker compose file, web server config etc. you'll need to replace that with *src/* or *tests/* respectively -- if you use other endpoints for links elsewhere, like the REST API for a widget, you'll need to use route URLs and replace *restapi.php* with *index.php/restapi* etc. - -## Prerequisites for this fork - -- PHP 8.x with DOM, GD, Intl, Json, PDO SQLite, SQLite3, XML, XMLWriter and ZLib support (PHP 8.1 or later recommended) -- Release 3.x.x will only work with PHP >= 8.2 - typical for most source code & docker image installs in 2024 and later. *Note: updating .epub files for metadata or cover requires a 64-bit platform* -- Release 2.x.x will only work with PHP >= 8.1 - typical for most source code & docker image installs in 2023 and later. *Note: updating .epub files for metadata or cover requires a 64-bit platform* -- Release 1.x.x still works with PHP 7.4 if necessary - earlier PHP 7.x (or 5.x) versions are *not* supported with this fork - -User support issues remain available at https://github.com/seblucas/cops/issues - please use it if you need help with COPS in general. -For the 2.x and 3.x versions please report any new issues at https://github.com/mikespub-org/seblucas-cops/issues - -Pull requests should be against the latest source code at https://github.com/mikespub-org/seblucas-cops/pulls - thanks for any contributions :-) - -See [CHANGELOG](CHANGELOG.md) for changes compared to upstream repository https://github.com/seblucas/cops from @seblucas - -## Installation of this fork - -Same options as original: - -1. Release package - - get latest cops-1.x.x.zip file from https://github.com/mikespub-org/seblucas-cops/releases - -2. Source code - - git clone https://github.com/mikespub-org/seblucas-cops.git # or download [latest main as zip](https://github.com/mikespub-org/seblucas-cops/archive/refs/heads/main.zip) - - run *composer* to install project dependencies - ``` - $ cd seblucas-cops - $ composer install --no-dev -o - ``` - -3. Docker image - - use latest [linuxserver/cops](https://hub.docker.com/r/linuxserver/cops) image from [linuxserver.io](https://github.com/linuxserver/docker-cops) - see setup and usage there - - or use [docker/Dockerfile.alpine](docker/Dockerfile.alpine) and [docker-compose.yaml](docker-compose.yaml) (or [docker-compose-dev.yaml](docker-compose-dev.yaml)) as starting point - **not** optimized for size/performance - -4. Home Assistant Add-on - - see [HA COPS](https://github.com/dunxd/HomeAssistantAddons/tree/main/COPS) from [dunxd](https://github.com/dunxd/HomeAssistantAddons) - -The rest of the installation process is very similar to the original below. But if you install from source, just use your regular composer 2.x - you don't need to download an old composer 1.x version or install global asset plugins anymore :-) - -Notice: for a first-time installation, you need to copy *[config/local.php.example](config/local.php.example)* to *config/local.php* and customize the calibre directory etc. as needed. Afterwards, if you get an error or blank page the first time you browse to COPS, you can check for common issues by browsing to http://.../checkconfig.php - ---- - -# COPS (original) - -COPS stands for Calibre OPDS (and HTML) Php Server. - -See : [COPS's home](http://blog.slucas.fr/en/oss/calibre-opds-php-server) for more details. - -Don't forget to check the [Wiki](https://github.com/seblucas/cops/wiki). - -# Why ? - -In my opinion Calibre is a marvelous tool but is too big and has too much -dependencies to be used for its content server. - -That's the main reason why I coded this OPDS server. I needed a simple -tool to be installed on a small server (Seagate Dockstar in my case). - -I initially thought of Calibre2OPDS but as it generate static file no -search was possible. - -Later I added an simple HTML catalog that should be usable on my Kobo. - -So COPS's main advantages are : - * No need for many dependencies. - * No need for a lot of CPU or RAM. - * Not much code. - * Search is available. - * It was fun to code. - -If you want to use the OPDS feed don't forget to specify feed.php at the end of your URL. - -You just have to sync your Calibre directory to your COPS server the way you prefer (Dropbox, Bt Sync, Syncthing, use a directory shared with Nextcloud, ...). - -# Prerequisites (outdated) - -1. PHP 5.3, 5.4, 5.5, 5.6, 7.X or hhvm with GD image processing, Libxml, Intl, Json & SQLite3 support (PHP 5.6 or later recommended). -2. A web server with PHP support. I tested with various version of Nginx and Apache. - Other people reported it working with Apache and Cherokee. You can also use PHP embedded server (https://github.com/seblucas/cops/wiki/Howto---PhpEmbeddedServer) -3. The path to a calibre library (metadata.db, format, & cover files). - -On any Debian based Linux you can use : - `apt-get install php5-gd php5-sqlite php5-json php5-intl` - -If you use Debian Stretch : - `apt-get install php7.0-gd php7.0-sqlite3 php7.0-json php7.0-intl php7.0-xml php7.0-mbstring php7.0-zip` - -On Centos you may have to add : - yum install php-xml - -# Install a release (Easiest way) - -1. Extract the zip file you got from [the release page](https://github.com/seblucas/cops/releases) to a folder in web space (visible to the web server). -2. If you're doing a first-time install, copy config_local.php.example to config_local.php -3. Edit config_local.php to match your config. -4. If needed add other configuration item from config_default.php - -If you like Docker, you can also try this multiarch docker container from [linuxserver.io](https://hub.docker.com/r/linuxserver/cops/) It has builds for x64 and arm64. - -# Install from sources - -```bash -git clone https://github.com/seblucas/cops.git # or download lastest zip see below -cd cops -# use standard composer 2.x now, no need to install older 1.x version and plugin for PHP 8.x version -#wget https://getcomposer.org/composer.phar -#php composer.phar global require "fxp/composer-asset-plugin:~1.1" -#php composer.phar install --no-dev --optimize-autoloader -composer install --no-dev --optimize-autoloader -``` - -After that you can use the previous how-to starting at the second step. - -Note that instead of cloning you can also get [latest master as zip](https://github.com/seblucas/cops/archive/master.zip) - -Note that if your PHP version is lower that 5.6, then you may have to remove `composer.lock` before starting the last line. - -# Where to put my Calibre directory ? - -Long story short : ALWAYS outside of COPS's directory especially if COPS is installed on a VPS / Server. If you follow my advice then your data will be safe. - -If you choose to put your Calibre directory inside your web directory and use Nginx then you will have to edit /etc/nginx/mime.types to add these lines : - -``` -application/epub+zip epub; -application/x-mobipocket-ebook mobi prc azw; -``` - -# Known problems - -Not a lot, except for the bad quality of the code (first PHP project ever) ;) - -Please see https://github.com/seblucas/cops/issues for open issues - -# Need help - -Please read https://github.com/seblucas/cops/wiki and check the FAQ. - -# Contributing - -As you could see [here](https://github.com/seblucas/cops/graphs/contributors), I appreciate every contributions and there were a lot over time. So don't be shy and submit your Pull Requests. - -Note to translators : please prefer using [Transifex](https://github.com/seblucas/cops/wiki/Update-translations) instead of doing a PR. - -I only have one limit (I may have more but that one is the worse) : COPS' goal is to provide an alternative to Calibre's content server and not to replace Calibre entirely. So I will refuse any PR making changes to the database content. - -# Credits - - * Locale message handling is inspired of https://www.mind-it.info/2010/02/22/a-simple-approach-to-localization-in-php - * str_format function come from http://tmont.com/blargh/2010/1/string-format-in-php - * All icons come from Font Awesome : https://github.com/FortAwesome/Font-Awesome - * The unofficial OPDS validator : http://opds-validator.appspot.com/ - * Thanks to all testers, translators and contributors. - * Feed icons made by Freepik from Flaticon website licensed under Creative Commons BY 3.0 http://www.flaticon.com and http://www.freepik.com - * A huge thanks to Jetbrains for supporting COPS by providing a set of free licenses to their products for several years now! - -External libraries used : - * JQuery : http://jquery.com/ - * Magnific Popup : http://dimsemenov.com/plugins/magnific-popup/ - * Php-epub-meta : https://github.com/splitbrain/php-epub-meta with some modification by me (https://github.com/seblucas/php-epub-meta) - * TbsZip : http://www.tinybutstrong.com/apps/tbszip/tbszip_help.html - * DoT.js : http://olado.github.io/doT/index.html - * PHPMailer : https://github.com/PHPMailer/PHPMailer - * js-lru : https://github.com/rsms/js-lru - -# Copyright & License - -COPS - 2012-2019 (c) Sébastien Lucas - -See COPYING and file headers for license info - diff --git a/COPS/cops-3.1.3/calres.php b/COPS/cops-3.1.3/calres.php deleted file mode 100644 index 463c6e95..00000000 --- a/COPS/cops-3.1.3/calres.php +++ /dev/null @@ -1,13 +0,0 @@ - - * @author mikespub - * @deprecated 3.1.0 use index.php/calres instead - */ - -$link = str_replace('calres.php', 'index.php/calres', $_SERVER['REQUEST_URI'] ?? ''); -header('Location: ' . $link); diff --git a/COPS/cops-3.1.3/checkconfig.php b/COPS/cops-3.1.3/checkconfig.php deleted file mode 100644 index 6c90343f..00000000 --- a/COPS/cops-3.1.3/checkconfig.php +++ /dev/null @@ -1,338 +0,0 @@ - - - - * @author mikespub - */ - -use SebLucas\Cops\Calibre\Database; -use SebLucas\Cops\Input\Request; -use SebLucas\Cops\Input\Route; - -require_once __DIR__ . '/config/config.php'; -/** @var array $config */ - -$request = new Request(); -$err = $request->get('err', -1); -$full = $request->get('full'); -$error = null; -switch ($err) { - case 1: - $error = 'Database error'; - break; -} - -?> - - - - COPS Configuration Check - - - -
-
-
-

COPS Configuration Check

-
-
- -
- -
-

You've been redirected because COPS is not configured properly

-

-
- -
-

Check if PHP version is correct

-

- = 70400) { - echo 'OK (' . PHP_VERSION . ')'; - } else { - echo 'Please install PHP >= 7.4 (' . PHP_VERSION . ')'; - } - } else { - echo 'Please install PHP >= 7.4'; - } -?> -

-
-
-

Check if GD is properly installed and loaded

-

- -

-
-
-

Check if Sqlite is properly installed and loaded

-

- -

-
-
-

Check if libxml is properly installed and loaded

-

- -

-
-
-

Check if DOM is properly installed and loaded

-

- -

-
-
-

Check if XMLWriter is properly installed and loaded

-

- -

-
-
-

Check if Json is properly installed and loaded

-

- -

-
-
-

Check if mbstring is properly installed and loaded

-

- -

-
-
-

Check if intl is properly installed and loaded

-

- -

-
-
-

Check if Normalizer class is properly installed and loaded

-

- -

-
-
-

Check if zlib is properly installed and loaded

-

- -

-
-
-

Check if the base URL looks OK

-

- '; -echo 'Full URL specified in $config[\'cops_full_url\']: ' . $config['cops_full_url'] . '
'; -if (Route::hasTrustedProxies()) { - echo 'Trusted proxies configured: ' . $config['cops_trusted_proxies'] . '
'; - echo 'Trusted headers configured: ' . json_encode($config['cops_trusted_headers']) . '
'; - foreach ($config['cops_trusted_headers'] as $name) { - $header = 'HTTP_' . strtoupper(str_replace('-', '_', $name)); - echo $header . ': ' . ($_SERVER[$header] ?? '') . '
'; - } - echo 'Base URL via trusted proxies: ' . Route::base() . '
'; -} -echo 'REMOTE_ADDR: ' . ($_SERVER['REMOTE_ADDR'] ?? '') . '
'; -echo '
'; -echo 'SCRIPT_NAME: ' . ($_SERVER['SCRIPT_NAME'] ?? '') . '
'; -echo 'HTTP_HOST: ' . ($_SERVER['HTTP_HOST'] ?? '') . '
'; -echo 'SERVER_NAME: ' . ($_SERVER['SERVER_NAME'] ?? '') . '
'; -echo 'SERVER_ADDR: ' . ($_SERVER['SERVER_ADDR'] ?? '') . '
'; -echo 'SERVER_PORT: ' . ($_SERVER['SERVER_PORT'] ?? '') . '
'; -echo 'REQUEST_SCHEME: ' . ($_SERVER['REQUEST_SCHEME'] ?? '') . '
'; -echo 'REQUEST_URI: ' . ($_SERVER['REQUEST_URI'] ?? '') . '
'; -?> -

-
-
-

Check if the rendering will be done on client side or server side

-

- render()) { - echo 'Server side rendering'; -} else { - echo 'Client side rendering'; -} -?> -

-

User agent detected

-

-
- $database) { - ?> -
-

Check if Calibre database path is not an URL

-

- -

-
-
-

Check if Calibre database file exists and is readable

-

- -
  • Value of $config[\'calibre_directory\'] in config/local.php (Does it end with a \'/\'?)
  • -
  • Value of open_basedir in your php.ini
  • -
  • The access rights of the Calibre Database
  • -
  • Synology users please read this
  • -
  • Note that hosting your Calibre Library in /home is almost impossible due to access rights restriction
  • -'; - } - ?> -

    -
    - -
    -

    Check if Calibre database file can be opened with PHP

    -

    - -

    -
    -
    -

    Check if Calibre database file contains at least some of the needed tables

    -

    - query('select count(*) FROM sqlite_master WHERE type="table" AND name in ("books", "authors", "tags", "series")')->fetchColumn(); - if ($count == 4) { - echo $name . ' OK'; - } else { - echo $name . ' Not all Calibre tables were found. Are you sure you\'re using the correct database.'; - } - } catch (Exception $e) { - echo $name . ' If the file is readable, check your php configuration. Exception detail : ' . $e; - } - ?> -

    -
    - -
    -

    Check if all Calibre books are found

    -

    - prepare('select books.path || "/" || data.name || "." || lower (format) as fullpath from data join books on data.book = books.id'); - $result->execute(); - while ($post = $result->fetchObject()) { - if (!is_file(Database::getDbDirectory($i) . $post->fullpath)) { - echo '

    ' . Database::getDbDirectory($i) . $post->fullpath . '

    '; - } - } - } catch (Exception $e) { - echo $name . ' If the file is readable, check your php configuration. Exception detail : ' . $e; - } - */ - ?> -

    -
    - -
    -
    -
    - - diff --git a/COPS/cops-3.1.3/config/config.php b/COPS/cops-3.1.3/config/config.php deleted file mode 100644 index 5102fc4c..00000000 --- a/COPS/cops-3.1.3/config/config.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @author mikespub - */ - -require_once dirname(__DIR__) . '/vendor/autoload.php'; -require __DIR__ . '/default.php'; -if (php_sapi_name() !== 'cli') { - if (file_exists(__DIR__ . '/local.php')) { - try { - require __DIR__ . '/local.php'; - } catch (Throwable $e) { - echo "Error loading local.php
    \n"; - echo $e->getMessage() . ' in ' . $e->getFile() . ' line ' . $e->getLine(); - exit; - } - } elseif (file_exists(dirname(__DIR__) . '/config_local.php')) { - // @deprecated 3.0.0 move config_local.php file to config/local.php - require dirname(__DIR__) . '/config_local.php'; - } -} -/** @var array $config */ - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Calibre\User; - -// Get user authentication from server -$http_auth_user = $config['cops_http_auth_user'] ?? 'PHP_AUTH_USER'; -$remote_user = array_key_exists($http_auth_user, $_SERVER) ? $_SERVER[$http_auth_user] : ''; -// Clean username, only allow a-z, A-Z, 0-9, -_ chars -$remote_user = preg_replace('/[^a-zA-Z0-9_-]/', '', $remote_user); -if (!empty($remote_user)) { - $user_config_file = 'local.' . $remote_user . '.php'; - if (file_exists(__DIR__ . '/' . $user_config_file) && (php_sapi_name() !== 'cli')) { - require __DIR__ . '/' . $user_config_file; - } -} - -// from here on, we assume that all global $config variables have been loaded -Config::load($config); -date_default_timezone_set(Config::get('default_timezone')); - -if (!User::verifyLogin($_SERVER)) { - header('WWW-Authenticate: Basic realm="COPS Authentication"'); - header('HTTP/1.0 401 Unauthorized'); - echo 'This site is password protected'; - exit; -} diff --git a/COPS/cops-3.1.3/config/default.php b/COPS/cops-3.1.3/config/default.php deleted file mode 100644 index ab998425..00000000 --- a/COPS/cops-3.1.3/config/default.php +++ /dev/null @@ -1,650 +0,0 @@ - - * @author mikespub - */ - -if (!isset($config)) { - $config = []; -} - -/* - * The directory containing calibre's metadata.db file, with sub-directories - * containing all the formats. - * BEWARE : it has to end with a / - * You can enable multiple database with this notation instead of a simple string : - * $config['calibre_directory'] = array ("My database name" => "/home/directory/calibre1/", "My other database name" => "/home/directory/calibre2/"); - */ -$config['calibre_directory'] = './'; - -/* - * SPECIFIC TO NGINX - * The internal directory set in nginx config file - * Leave empty if you don't know what you're doing - */ -$config['calibre_internal_directory'] = ''; - -/** - * Custom configuration if your Calibre library is stored elsewhere and - * you cannot sync it or mount a remote volume to it on your COPS server. - * For example a static website, AWS S3 bucket, Nextcloud site, Google Drive, ... - * You will still need to copy the metadata.db database file to the calibre - * directory above for this to work though... - * Note: not all features will be available in this configuration, e.g. - * no kepub version or metadata updates, and no monocle epub reader - * Example (test): - * $config['calibre_external_storage'] = 'http://localhost/cops/tests/BaseWithSomeBooks/'; - */ -$config['calibre_external_storage'] = ''; - -/* - * Full URL prefix (with trailing /) - * useful where a full URL is required, COPS is behind a proxy or the script name shows the wrong place - * Older e-readers like Mantano, Aldiko and Marvin may require it for Opensearch too. - * e.g. - * $config['cops_full_url'] = '/cops/'; - * $config['cops_full_url'] = 'http://localhost/cops/'; - * $config['cops_full_url'] = 'http://192.168.1.xxx/cops/'; - * $config['cops_full_url'] = 'https://www.domainname.com/cops/'; - */ -$config['cops_full_url'] = ''; - -/* - * As an alternative for cops_full_url above, if you're using a reverse proxy and you want to - * change how COPS is accessed depending on the entrypoint (e.g. direct, local network, internet) - * you can define trusted proxies and trusted headers here (dev only) - * Note: using symfony/http-foundation to support X-Forwarded-* and Forwarded headers from proxies - * @see https://symfony.com/doc/current/deployment/proxies.html - */ -$config['cops_trusted_proxies'] = ''; -$config['cops_trusted_headers'] = []; - -/* - * Number of recent books to show - */ -$config['cops_recentbooks_limit'] = '50'; - -/* - * Catalog's author name - */ -$config['cops_author_name'] = 'Sébastien Lucas'; - -/* - * Catalog's author uri - */ -$config['cops_author_uri'] = 'http://blog.slucas.fr'; - -/* - * Catalog's author email - */ -$config['cops_author_email'] = 'sebastien@slucas.fr'; - -/* - * Catalog's title - */ -$config['cops_title_default'] = 'COPS'; - -/* - * Catalog's subtitle - */ -$config['cops_subtitle_default'] = ''; - -/* - * Wich header to use when downloading books outside the web directory - * Possible values are : - * X-Accel-Redirect : For Nginx - * X-Sendfile : For Lightttpd or Apache (with mod_xsendfile) - * No value (default) : Let PHP handle the download - */ -$config['cops_x_accel_redirect'] = ''; - -/* - * Height of thumbnail image for OPDS (thumb=opds) - * Note: book detail uses image height x 2 (thumb=opds2) - */ -$config['cops_opds_thumbnail_height'] = '164'; - -/* - * Height of thumbnail image for HTML (thumb=html) - * Note: book detail uses image height x 2 (thumb=html2) - */ -$config['cops_html_thumbnail_height'] = '225'; - -/* - * Icon for both OPDS and HTML catalog - * Note that this has to be a real icon (.ico) - */ -$config['cops_icon'] = 'favicon.ico'; - -/* - * Show icon for authors, series, tags and books on OPDS feed - * 1 : enable - * 0 : disable - */ -$config['cops_show_icons'] = '1'; - -/* - * Default timezone - * Check following link for other timezones : - * http://www.php.net/manual/en/timezones.php - */ -$config['default_timezone'] = 'UTC'; - -/* - * Prefered format for HTML catalog - * The two first will be displayed in book entries - * The other only appear in book detail - */ -$config['cops_prefered_format'] = ['EPUB', 'PDF', 'AZW3', 'AZW', 'MOBI', 'CBR', 'CBZ']; - -/* - * Specify the ignored formats that will never display in COPS - */ -$config['cops_ignored_formats'] = []; - -/* - * use URL rewriting for downloading of ebook in HTML catalog - * See Github wiki for more information - * 1 : enable - * 0 : disable - * @deprecated 3.1.0 use route urls instead - */ -$config['cops_use_url_rewriting'] = '0'; - -/* - * generate a invalid OPDS stream to allow bad OPDS client to use search - * Example of non compliant OPDS client : Moon+ Reader - * Example of good OPDS client : Mantano, FBReader - * 1 : enable support for non compliant OPDS client - * 0 : always generate valid OPDS code - */ -$config['cops_generate_invalid_opds_stream'] = '0'; - -/* - * Max number of items per page - * -1 unlimited - */ -$config['cops_max_item_per_page'] = '48'; - -/* - * split authors by first letter - * 1 : Yes - * 0 : No - */ -$config['cops_author_split_first_letter'] = '1'; - -/* - * split titles by first letter - * 1 : Yes - * 0 : No - */ -$config['cops_titles_split_first_letter'] = '1'; - -/* - * split titles by publication year (if not split by first letter) - * 1 : Yes - * 0 : No - */ -$config['cops_titles_split_publication_year'] = '1'; - -/* - * Enable the Lightboxes (for popups) - * 1 : Yes (enable) - * 0 : No - */ -$config['cops_use_fancyapps'] = '1'; - -/* - * Update Epub metadata before download - * 1 : Yes (enable) - * 0 : No - */ -$config['cops_update_epub-metadata'] = '0'; - -/* - * Filter on tags to book list - * Only works with the OPDS catalog - * Usage : array ("I only want to see books using the tag : Tag1" => "Tag1", - * "I only want to see books not using the tag : Tag1" => "!Tag1", - * "I want to see every books" => "", - * - * Example : array ("All" => "", "Unread" => "!Read", "Read" => "Read") - */ -$config['cops_books_filter'] = []; - -/* - * Virtual libraries - * to add as an array containing the library names configured in Calibre - * - * For example : ["Short Stories in English", "Fiction from this Century"]; - * - * To select all Calibre virtual libraries you can use wildcard : ["*"]; - * - * @todo https://manual.calibre-ebook.com/virtual_libraries.html - * Note that search criteria for virtual libraries are very limited in COPS (TODO) - */ -$config['cops_calibre_virtual_libraries'] = []; -//$config['cops_calibre_virtual_libraries'] = ["*"]; - -/* - * Default virtual library to use (and filter on) in COPS - * based on the Calibre list of virtual libraries (starting with 1) - */ -$config['cops_virtual_library'] = '0'; - -/* - * Custom Columns for the index page - * to add as an array containing the lookup names configured in Calibre - * - * For example : ["genre", "mycolumn"]; - * - * To select all Calibre custom columns you can use wildcard : ["*"]; - * - * Note that the composite custom columns are not supported - */ -$config['cops_calibre_custom_column'] = []; - -/* - * Custom Columns for the list representation - * to add as an array containing the lookup names configured in Calibre - * - * For example : ["genre", "mycolumn"]; - * - * To select all Calibre custom columns you can use wildcard : ["*"]; - * - * Note that the composite custom columns are not supported - */ -$config['cops_calibre_custom_column_list'] = []; - -/* - * Custom Columns for the book preview panel - * to add as an array containing the lookup names configured in Calibre - * - * For example : ["genre", "mycolumn"]; - * - * To select all Calibre custom columns you can use wildcard : ["*"]; - * - * Note that the composite custom columns are not supported - */ -$config['cops_calibre_custom_column_preview'] = []; - -/* - * split custom columns of type Date by year - * 1 : Yes - * 0 : No - * For example for 'last_read' column - */ -$config['cops_custom_date_split_year'] = '1'; - -/* - * split custom columns of type Integer by range - * >1 : Yes using this number of ranges - * 1 : Yes using 'max_item_per_page' ranges - * 0 : No - * For example for 'num_pages' column split into 10 ranges: - * $config['cops_custom_integer_split_range'] = 10; - */ -$config['cops_custom_integer_split_range'] = 0; - -/* - * Start working on hierarchical tags or custom columns - * @todo https://manual.calibre-ebook.com/sub_groups.html - * - * For example for 'tags' and 'Type2' custom column in csv format: - * $config['calibre_categories_using_hierarchy'] = ['tags', 'Type2']; - * Note: here you need to specify the title/name of the custom column, not the lookup name = different from above - */ -$config['calibre_categories_using_hierarchy'] = []; - -/* - * Rename .epub to .kepub.epub if downloaded from a Kobo eReader - * The ebook will then be recognized a Kepub so with chaptered paging, statistics, ... - * You have to enable URL rewriting if you want to enable kepup.epub download - * 1 : Yes (enable) - * 0 : No - */ -$config['cops_provide_kepub'] = '0'; - -/* - * Use external 'kepubify' tool to convert .epub files to .kepub.epub format for Kobo - @todo - * Example: - * $config['cops_kepubify_path'] = '/usr/bin/kepubify'; - */ -$config['cops_kepubify_path'] = ''; - -/* - * Enable and configure Send To Kindle (or Email) feature. - * - * Don't forget to authorize the sender email you configured in your Kindle's Approved Personal Document E-mail List. - * - * If you want to use a simple smtp server (provided by your ISP for example), you can configure it like that : - * $config['cops_mail_configuration'] = array( "smtp.host" => "smtp.free.fr", - * "smtp.username" => "", - * "smtp.password" => "", - * "smtp.secure" => "", - * "smtp.port" => "", // Not mandatory, if smtp.secure is set then defaults to 465 - * "address.from" => "cops@slucas.fr", - * "subject" => "Sent by COPS : " // Not mandatory - * ); - * - * For Gmail (ssl is mandatory) : - * $config['cops_mail_configuration'] = array( "smtp.host" => "smtp.gmail.com", - * "smtp.username" => "YOUR GMAIL ADRESS", - * "smtp.password" => "YOUR GMAIL PASSWORD", - * "smtp.secure" => "ssl", - * "address.from" => "cops@slucas.fr" - * ); - * - * For GMX (tls and 587 is mandatory) : - * $config['cops_mail_configuration'] = array( "smtp.host" => "mail.gmx.com", - * "smtp.username" => "YOUR GMX ADRESS", - * "smtp.password" => "YOUR GMX PASSWORD", - * "smtp.secure" => "tls", - * "smtp.port" => "587", - * "address.from" => "cops@slucas.fr" - * ); - */ -$config['cops_mail_configuration'] = null; - -/* - * Use filter in HTML catalog - * 1 : Yes (enable) - * 0 : No - */ -$config['cops_html_tag_filter'] = '0'; - -/* - * Thumbnails are generated on-the-fly so it can be problematic on servers with slow CPU (Raspberry Pi, Dockstar, Piratebox, ...). - * This configuration item allow to customize how thumbnail will be generated - * "" : Generate thumbnail (CPU hungry) - * "1" : always send the full size image (Network hungry) - * any url : Send a constant image as the thumbnail (you can try "images/bookcover.png") - */ -$config['cops_thumbnail_handling'] = ''; - -/* - * Default thumbnail to use in OPDS and HTML catalog if none is available - * Set to '' if you don't want to use some default thumbnail as fallback - */ -$config['cops_thumbnail_default'] = 'images/icons/icon144.png'; - -/* - * Directory to keep resized thumbnails: allow to resize thumbnails only on first access, then use this cache. - * $config['cops_thumbnail_handling'] must be "" - * "" : don't cache thumbnail - * "/tmp/cache/" (example) : will generate thumbnails in /tmp/cache/ - * BEWARE : it has to end with a / - */ -$config['cops_thumbnail_cache_directory'] = ''; - -/* - * Contains a list of user agent for browsers not compatible with client side rendering - * For now : Kindle, Sony PRS-T1, Sony PRS-T2, All Cybook devices (maybe a little extreme). - * This item is used as regular expression so "." will force server side rendering for all devices - */ -$config['cops_server_side_render'] = 'Kindle\/1\.\d|Kindle\/2\.\d|Kindle\/3\.\d|EBRD1101|EBRD1201|cybook|Kobo'; - -/* - * Specify the ignored categories for the home screen and with search - * Meaning that if you don't want to search in publishers or tags just add them from the list - * Only accepted values : - * - author - * - book - * - series - * - tag - * - publisher - * - rating - * - language - * - libraries - */ -$config ['cops_ignored_categories'] = []; - -/* - * If you use a Sony eReader or Aldiko you can't download ebooks if your catalog - * is password protected. A simple workaround is to leave fetch.php not protected (see .htaccess). - * But In that case your COPS installation is not completely safe. - * Setting this parameter to "1" ensure that nobody can access fetch.php before accessing - * index.php or feed.php first. - * BEWARE : Do not touch this if you're not using password, not using PRS-TX or not using Aldiko. - */ -$config ['cops_fetch_protect'] = '0'; - -/* - * WARNING NOT READY FOR PRODUCTION USE - * Make the search better (don't care about diacritics, uppercase should work on Cyrillic) but slower. - * 1 : Yes (enable) - * 0 : No - */ -$config ['cops_normalized_search'] = '0'; - -/* - * Get remote user authentication from server for: - * 1. basic authentication: use 'PHP_AUTH_USER' for Apache or Nginx if configured to pass Authorization header - * 2. auth done by reverse proxy: use 'REMOTE_USER' or 'X-WEBAUTH-USER' or ... depending on auth proxy config - * In the 2nd case, authentication is already done by the reverse proxy, and only the remote user is passed - */ -$config['cops_http_auth_user'] = 'PHP_AUTH_USER'; - -/* - * Calibre user accounts database as configured for content server - * e.g. '/config/.config/calibre/server-users.sqlite' - WARNING: passwords are in clear! - * This can be used to get user info for auth done by reverse proxy, or to verify password for basic authentication - */ -$config['calibre_user_database'] = null; - -/* - * Enable PHP password protection (You can use if htpasswd is not possible for you) - * If possible prefer htpasswd or authentication done by reverse proxy! - * array( "username" => "xxx", "password" => "secret") : Enable PHP password protection - * NULL : Disable PHP password protection (You can still use htpasswd or reverse proxy) - * $config['calibre_user_database'] : Calibre user accounts database - WARNING: passwords are in clear! - */ -$config['cops_basic_authentication'] = null; - -/* - * Which template is used by default : - * 'default' - * 'bootstrap' - * 'bootstrap2' - * 'bootstrap5' - * 'twigged' - */ -$config['cops_template'] = 'bootstrap2'; - -/* - * Which style is used by default : - * 'base' - * 'default' - * 'eink' (only available for the 'default' template) - * 'iphone' (only available for the 'default' template) - * 'iphone7' (only available for the 'default' template) - * 'kindle' (only available for the 'default' template) - */ -$config['cops_style'] = 'default'; - -/* - * Which of these templates use the Twig template engine - * Only the 'twigged' template for now... - */ -$config['cops_twig_templates'] = ['twigged']; - -/* - * Which URL prefix to use in templates for js & css assets (without trailing /) - */ -$config['cops_assets'] = 'vendor/npm-asset'; - -/* - * Set language code to force a language (see lang/ directory for available languages). - * When empty it will auto detect the language. - */ -$config['cops_language'] = ''; - -/* - * Set Home page for library - * Can be any of the pages defined as constants in src/Pages/PageId.php - * e.g. ALL_RECENT_BOOKS to get straight to most recent books - * AUTHORS_FIRST_LETTER to list all authors - * ALL_TAGS to list all tags - * INDEX to use the default - */ -$config['cops_home_page'] = 'INDEX'; - -/* - * Show book count for "Not Set" columns in All pages and filter "Not Set" books in Detail pages - * Use cases: unrated books, or books not tagged, or books without custom lastread date, ... - * Note: author, language and publisher are always assumed present and cannot be filtered here - */ -$config['cops_show_not_set_filter'] = ['custom', 'rating', 'series', 'tag']; - -/* - * Show links to sort by title, author, pubdate, rating or timestamp in HTML page detail - * - * Available values: ['title', 'author', 'pubdate', 'rating', 'timestamp'] - */ -$config['cops_html_sort_links'] = ['title', 'author', 'pubdate', 'rating', 'timestamp']; - -/* - * Show links to filter by Author, Language, Publisher, Rating, Serie or Tag in HTML page detail - * Note: this replaces 'cops_show_filter_links' in previous release, and now expects an array - * - * Available values: ['author', 'language', 'publisher', 'rating', 'series', 'tag', 'identifier'] - */ -$config['cops_html_filter_links'] = ['author', 'language', 'publisher', 'rating', 'series', 'tag']; - -/* - * Number of filter links to show per category in HTML page detail - */ -$config['cops_html_filter_limit'] = '8'; - -/* - * Show links to sort by title, author, pubdate, rating or timestamp in OPDS catalog (using facets) - * Note: this will only work if your e-reader supports facets in OPDS feeds, like Thorium Reader for example - * See https://specs.opds.io/opds-1.2.html#4-facets for specification details - * To disable this feature, use an empty array in config/local.php: - * $config['cops_opds_sort_links'] = []; - * - * Available values: ['title', 'author', 'pubdate', 'rating', 'timestamp'] - */ -$config['cops_opds_sort_links'] = ['title', 'author', 'pubdate', 'rating', 'timestamp']; - -/* - * Show links to filter by Author, Language, Publisher, Rating, Serie or Tag in OPDS catalog (using facets) - * Note: this will only work if your e-reader supports facets in OPDS feeds, like Thorium Reader for example - * See https://specs.opds.io/opds-1.2.html#4-facets for specification details - * To disable this feature, use an empty array in config/local.php: - * $config['cops_opds_filter_links'] = []; - * - * Available values: ['author', 'language', 'publisher', 'rating', 'series', 'tag'] - */ -$config['cops_opds_filter_links'] = ['author', 'language', 'rating', 'tag']; - -/* - * Number of filter links to show per category in OPDS catalog - */ -$config['cops_opds_filter_limit'] = '8'; - -/* - * Allow downloading all books shown on a page for a specific format - * Example: $config['cops_download_page'] = ['EPUB']; - * - * To get any format in prefered_format order you can use : ['ANY']; - * Example: $config['cops_download_page'] = ['ANY']; - */ -$config['cops_download_page'] = []; - -/* - * Allow downloading all books of a series for a specific format or 'ANY' - * Example: $config['cops_download_series'] = ['EPUB', 'MOBI']; - */ -$config['cops_download_series'] = []; - -/* - * Allow downloading all books of an author for a specific format or 'ANY' - * Example: $config['cops_download_author'] = ['EPUB']; - */ -$config['cops_download_author'] = []; - -/* - * Save to disk template for book filenames inside the .zip download file - @todo - */ -$config['cops_download_template'] = '{author} - {series} #{series_index} - {title}'; - -/* - * Use route URLs (/books/12/The_Author/My_Book) instead of URL parameters (?page=13&id=12) - * - * You may also need to specify the full_url if COPS is running in a sub-directory: - * $config['cops_full_url'] = '/cops/'; - * - * Note: this is independent of the URL rewriting for downloading ebooks (files) for Kobo - * 1 : enable - * 0 : disable - */ -$config['cops_use_route_urls'] = '1'; - -/* - * Set front controller to remove index.php/ from route URLs generated in COPS - * - * Note: this assumes your web server config will rewrite /... to /index.php/... - * - Apache: .htaccess - * - Nginx: nginx.conf - * - PHP built-in: router.php - * - ... - * - * $config['cops_front_controller'] = 'index.php'; - */ -$config['cops_front_controller'] = ''; - -/* - * Specify api key to access some restricted features via REST API (dev only) - * - * Example: generate a random api key once via command line - * $ php -r 'echo bin2hex(random_bytes(20));' - */ -$config['cops_api_key'] = ''; - -/* - * Choose preferred epub reader when viewing epub files online: - * 'monocle' (default) - * 'epubjs' - */ -$config['cops_epub_reader'] = 'monocle'; - -/* - * Configure epubjs-reader as used in templates/epubjs-reader.html - * This is a javascript object stored as text string for the template - * - * const settings = {{=it.settings}}; - * - * Note: we could put this into a separate .json file that is downloaded - * by the template javascript at some point - * - * See https://github.com/mikespub-org/intity-epubjs-reader/issues/2#issuecomment-2043469571 - * for examples - * -$config['cops_epubjs_reader_settings'] = '{ - arrows: "content", // none | content | toolbar - depending on this.isMobile - restore: true, - history: true, - openbook: false, - language: "en", - sectionId: undefined, - bookmarks: [], // array | false - annotations: [], // array | false - flow: "paginated", // paginated | scrolled - spread: { - mod: "auto", // auto | none - min: 800 - }, - styles: { - fontSize: 100 - }, - pagination: undefined, // not implemented - fullscreen: document.fullscreenEnabled // default behaviour -}'; - */ -$config['cops_epubjs_reader_settings'] = '{ arrows: "content", flow: "paginated", openbook: false }'; diff --git a/COPS/cops-3.1.3/config/loader.php b/COPS/cops-3.1.3/config/loader.php deleted file mode 100644 index 43a5cbe6..00000000 --- a/COPS/cops-3.1.3/config/loader.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @author mikespub - */ - -$gConfig = []; - -/** - * URL endpoint for your application - */ -$gConfig['endpoint'] = $_SERVER['SCRIPT_NAME'] ?? null; - -/** - * Application name - */ -$gConfig['app_name'] = 'Epub Loader'; - -/** - * Application version - */ -$gConfig['version'] = '3.0'; - -/** - * Admin email - */ -$gConfig['admin_email'] = ''; - -/** - * Create Calibre databases ? - * - * If true: databases are removed and recreated before loading ebooks - * If false: append ebooks into databases - */ -$gConfig['create_db'] = false; - -/** - * Databases infos - * - * For each database: - * name: The database name to display - * db_path: The path where to create the database - * epub_path: The relative path from db_path where to look for the epub files - */ -$gConfig['databases'] = []; -$gConfig['databases'][] = ['name' => 'Some Books', 'db_path' => dirname(__DIR__) . '/tests/BaseWithSomeBooks', 'epub_path' => '.']; -$gConfig['databases'][] = ['name' => 'One Book', 'db_path' => dirname(__DIR__) . '/tests/BaseWithOneBook', 'epub_path' => '.']; -$gConfig['databases'][] = ['name' => 'Custom Columns', 'db_path' => dirname(__DIR__) . '/tests/BaseWithCustomColumns', 'epub_path' => '.']; - -/** - * Available actions - */ -$gConfig['actions'] = []; -$gConfig['actions']['csv_export'] = 'Csv export'; -// only if you start without an existing calibre database -//$gConfig['actions']['db_load'] = 'Create database'; -$gConfig['actions']['authors'] = 'List authors in database'; -$gConfig['actions']['wd_author'] = 'Check authors in database'; -$gConfig['actions']['wd_books'] = 'Check books for author'; -$gConfig['actions']['wd_series'] = 'Check series for author'; -$gConfig['actions']['wd_entity'] = 'Check Wikidata entity'; -$gConfig['actions']['gb_books'] = 'Search Google Books'; -$gConfig['actions']['gb_volume'] = 'Search Google Books Volume'; -$gConfig['actions']['ol_author'] = 'Find OpenLibrary author'; -$gConfig['actions']['ol_books'] = 'Find OpenLibrary books'; -$gConfig['actions']['ol_work'] = 'Find OpenLibrary work'; -$gConfig['actions']['notes'] = 'Get Calibre Notes'; -$gConfig['actions']['resource'] = 'Get Calibre Resource'; -$gConfig['actions']['hello_world'] = 'Example: Hello, World - see app/example.php'; -//$gConfig['actions']['goodbye'] = 'Example: Goodbye - see app/example.php'; - -return $gConfig; diff --git a/COPS/cops-3.1.3/config/local.php.example b/COPS/cops-3.1.3/config/local.php.example deleted file mode 100644 index 863a486b..00000000 --- a/COPS/cops-3.1.3/config/local.php.example +++ /dev/null @@ -1,78 +0,0 @@ - "smtp.free.fr", - "smtp.username" => "", - "smtp.password" => "", - "smtp.secure" => "", - "address.from" => "cops@slucas.fr", -]; - -// from here on, we assume that all global $config variables have been loaded -Config::load($config); - -// initialize framework with routes etc. for tests -Framework::init(); diff --git a/COPS/cops-3.1.3/epubfs.php b/COPS/cops-3.1.3/epubfs.php deleted file mode 100644 index 85d9de5f..00000000 --- a/COPS/cops-3.1.3/epubfs.php +++ /dev/null @@ -1,13 +0,0 @@ - - * @author mikespub - * @deprecated 3.1.0 use index.php/epubfs instead - */ - -$link = str_replace('epubfs.php', 'index.php/epubfs', $_SERVER['REQUEST_URI'] ?? ''); -header('Location: ' . $link); diff --git a/COPS/cops-3.1.3/epubreader.php b/COPS/cops-3.1.3/epubreader.php deleted file mode 100644 index 1613566e..00000000 --- a/COPS/cops-3.1.3/epubreader.php +++ /dev/null @@ -1,13 +0,0 @@ - - * @author mikespub - * @deprecated 3.1.0 use index.php/read instead - */ - -$link = str_replace('epubreader.php', 'index.php/read', $_SERVER['REQUEST_URI'] ?? ''); -header('Location: ' . $link); diff --git a/COPS/cops-3.1.3/favicon.ico b/COPS/cops-3.1.3/favicon.ico deleted file mode 100644 index 70b0402c8d594dae53e72fc66621d4dd3e525f67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15086 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 diff --git a/COPS/cops-3.1.3/feed.php b/COPS/cops-3.1.3/feed.php deleted file mode 100644 index 6a92942b..00000000 --- a/COPS/cops-3.1.3/feed.php +++ /dev/null @@ -1,13 +0,0 @@ - - * @author mikespub - * @deprecated 3.1.0 use index.php/feed instead - */ - -$link = str_replace('feed.php', 'index.php/feed', $_SERVER['REQUEST_URI'] ?? ''); -header('Location: ' . $link); diff --git a/COPS/cops-3.1.3/fetch.php b/COPS/cops-3.1.3/fetch.php deleted file mode 100644 index 334d00af..00000000 --- a/COPS/cops-3.1.3/fetch.php +++ /dev/null @@ -1,14 +0,0 @@ - - * @author mikespub - */ - -$link = str_replace('fetch.php', 'index.php/fetch', $_SERVER['REQUEST_URI'] ?? ''); -header('Location: ' . $link); diff --git a/COPS/cops-3.1.3/getJSON.php b/COPS/cops-3.1.3/getJSON.php deleted file mode 100644 index 39cdfbc9..00000000 --- a/COPS/cops-3.1.3/getJSON.php +++ /dev/null @@ -1,13 +0,0 @@ - - * @author mikespub - * @deprecated 3.1.0 use index.php instead (with Accept: application/json or X-Requested-With: XMLHttpRequest) - */ - -$link = str_replace('getJSON.php', 'index.php', $_SERVER['REQUEST_URI'] ?? ''); -header('Location: ' . $link); diff --git a/COPS/cops-3.1.3/graphql.php b/COPS/cops-3.1.3/graphql.php deleted file mode 100644 index b0dd2801..00000000 --- a/COPS/cops-3.1.3/graphql.php +++ /dev/null @@ -1,13 +0,0 @@ - - * @author mikespub - * @deprecated 3.1.0 use index.php/graphql instead - */ - -$link = str_replace('graphql.php', 'index.php/graphql', $_SERVER['REQUEST_URI'] ?? ''); -header('Location: ' . $link); diff --git a/COPS/cops-3.1.3/images/allbook.png b/COPS/cops-3.1.3/images/allbook.png deleted file mode 100644 index 6803171687f7372b5600272d6f439f07ac084fb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1172 zcmV;F1Z(?=P)2d&sbRVeC9q$swvjWt-@tPi_)cQU!z-8RW)gEMd-%$)x@ z_x$eMnLB$)DpjWmWj2J2)5Mq|MsbDMOvpH$mc#eetFLY&*6+4JL04rVrl7$+nUan|;n*-x0FOhEhMi;No2Xg7MX&1YN`?7+Y-sTh!RvMNQxV zcmN*2idzIJ!Zym~JC^{!%CaTc23MF#?Ek+5IN$+z03Lt`-~o659)JhXN&sd^;&{k7 zQn3hM6XQ~Y`g0_4oESe6RP#|ggdlWXhhm$!LnRHT~Y zkorkmBiIbj<2&6*PQmyr32tqTessA2Oa{S3yRGS#!}n0~cZ9#4*sl`f8)6(JrLK?r zL&lEE-H-B*#r=U&9fFM{#$mxYlu_6;D_$v9a{+{`-$>Gh5xz|DzvRT;ACF}ikHr1< zuRLPc?pv$=rr(M8tNln3n-7}}ppceWpQIBJM1ucc$pFkR*_}h{to|2c&2wtcja4v7 zkCu6;G+JzvfwA?x=YU{m$-DW$HZ(jH$VMlq|@4b^x+y#=|M0RHIf8(S6om8X26 zTaDgT(dP1=ZjAAe_ zvbqj{-v#Tvg7Ixr0rV(rY!JW;mhMkyY}|$uDAf^YgC_BxQ!V9l(pw;04UmvC`EXE&Lc2)7npXo!F^2uAlN(;kN5SBtqLQ& zQ<{b)BWe1bLJuYZ2&Mk08guqnCz5!tG}A`zj{7nSn~3pSSyOP|L5Oj9$pM6nDSK}w zMpwckGX3<+Z{1Xlp`R%CpR;49CDw;*9?Wolv%R1O!9+VTelF$HFWH)4U}SYS=kFJ} z{2g|GR+(GKJxDFl3>cp^&iad_H9|0Yoq{e9<7^{2g){?Jtn>CPNN&Y8lIG)PErON9 zNsV{@BC$RhpAojGv9;y9Q`q{-=zyt6AJOB^C1MmPm01vmgfbfh maMNOfbecF}erYBxm%h58u8hMDs}Gm=FhVxcCHIse1)L6bS( znG^yswP-;UL()=l+ama?xX?uxwpD0#;{&<~*4EOdbX-g_m}U~^aqs<)`QY2k;`05z zd+yAC&b>F4N>F6{{bWN%SsWmXLz*$I8PjBOsPb9JwPVjLvK@5CtA z>EDP^%DLh_()pWKIz7{++3zRD=QPzy(>GVvOG~a(pv41OS_^K_OG~bHKxr6r+<63M5Fs|hbVUslH zvLb``VuYW!pOogTslCG^>xpqS{sQp#-r*{b%HV?=iLC&}Tw4uBSyy@>Dfk7q)t@HK{_&&>P=)ZAGdZf7*i5TA|Re)xEBh9-++T!iRR)EEu(!5KQ>@egXmFBG} zGWb4$0=|>xTvpnKmtw#Et$$IPb6NHEy?Yxmeu}Yxv(CA0Y0edu<MR>t1Yy2 z{zyd5Z%`KRD8^rPfL|iUM8@H6>D-YkH&|RlHe|^7kI3LOu|H4j&y&Gv#rRO!(3=}9 zu942!g329a!)|hZL)1qm=QofIyW8^1&^gzs*k_4xc77ROA%mePZfB>{GhJjbM2ss7 z!%$^6s7;C>gI#2CYMJZ#b8W*D&4n#@knv9v<5YQV|~Z=Cy2xL#K7|oTjn2sx!KI`x?)@;#%GFglnf4& z!C}QXI{(?lCg+8lnsHq5=!3C==eV?0F-}G}-NjnMWg70?|J(_W*4S<^U51IYAv*`ke!$=!Iv}9#*pegviq0x0z8B4_>TJ)v9 zq0w~>7obhp*9PIE@~aKOJLkHI@k<*7kI3QYhNe7T-B3FU^A1PWLn;y-2HbsnMZ4gAn znlYWq7s4j0ysRu9C}ICveFrh`#_l5a!^D^(4l}FUm?DFrg;($X0kA02H|M0m8~^|S M07*qoM6N<$f`Y47kN^Mx diff --git a/COPS/cops-3.1.3/images/bookcover.png b/COPS/cops-3.1.3/images/bookcover.png deleted file mode 100644 index 6c3c8c743ca0c53cf2eb0888e09fa0488d6cbc11..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3057 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 diff --git a/COPS/cops-3.1.3/images/custom.png b/COPS/cops-3.1.3/images/custom.png deleted file mode 100644 index 86020c34a06b6049aec1d34e9bb84203351270ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1687 zcmV;I259+-P)oWRypH^Pjt7 z18GduD3}91so?|yCeU)Wd?g4P5djKg4Xtoqwgnox1Ev>Gnk$C_( zGJi$m*km4{c_Yu@Z1%S!uL&>(Xu4D7w|hNc7MG)iT-_0K4(=+V8p+hI(}d z{Ow+KaY4^G2Jf~8Ff^Z(2tXGPM`xsbl=PSnT^&lPK?MQ8SFRfeNS{G*e~FKCNjzz@ zuC8SmAnoy}t2-1nGjj&-7Ccg%u({tmT=NSkHN5BmikSduhv(9lW}Y9zl>*?bCjgSZb=B=T7%n>id$XpO(*Gxf z(L4MZuK)n{+P+<#X$_#>21wm~0bqjO^liM500PTnBfPv95|K$s+esau^qqjz)(e0W zsZ9=kQXv3vrKbQ=J0Nv4VP0_SLoghfX4^fNr5nvcKsuG>qo4-2b{vym03gl784mV6 z3E`|G4oJtGY7s|0D`P@*PhDNhutaXWDr>RBm2n>cxHOMuwce7nYagTzr0F;W!Ym5} zwhXo`%i`haHFld|=j*-cKUQ24FUvl`U^p_3A)U;4uiHzjY*+KF?hS-l21v*4dtDsq z)%2}1pqeiQq=O{~5E79|4C&8gwM~2PC}8Y1w?1&x^}V(B9BF4JSUdQwfF<538VtwA z1JXYGxt{^`u8en&aisV1o{_OEi=kefBlvS5sG+v@wTmwBLDCa|^hc^YEENEIz|vuV zi-&uiACP845NUcy(Cm<)*`ctR8B)y?oW|@RO^bt$j-aC3)1O;Pn zZ`t{$xYAQN>X&U8+rXZ`%X9haG($QNM4F!PLAUksTsaBRH&AHSbT`WggnO4kF4og5zl(pPEiMsn20Ez7caI64E6j)FAbhr*G&a`{>| z0HLs%2}tJ?d8V;9eSzh%5r8_BYlk*pxo%uy;H2+!`x8?(037LU`+i%m>ug0%Wdl&# z&@_fgnp3OP#lEBPkp>P-3;-w{fb)qXClx1-J5&aa%?$wX2jKsGbavqIbkFhmBjpap hrE~#Ohu`D#{{q61Z{o4R%qai>002ovPDHLkV1gF92#Wv! diff --git a/COPS/cops-3.1.3/images/icons/icon114.png b/COPS/cops-3.1.3/images/icons/icon114.png deleted file mode 100644 index 677ec79a059a93147ccb5f862a95bae931cf3372..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6867 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 diff --git a/COPS/cops-3.1.3/images/icons/icon144.png b/COPS/cops-3.1.3/images/icons/icon144.png deleted file mode 100644 index facdfe1e72dde17f4a574d44204b3bc5e3159f9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9018 zcmZ`rs3O*eLzaRw1!Vv&q zf2*OaXyiA$mxW9-T1!66g&u$qDtUq|Xxg#b%rTsFB`CS;Y%SS<%ei8ng99`rx8BNOx*$|GBG) zkBNkjwTY$Z{O6zkIU7Oez5389WvC36J^?e%OTw3AL)f&#S&$01-qM|Y;)=Y$Lk+u7 zbO$c%(IMXwDCGUMH*2kGE=xj$A9idvECTB@4i#zyYb8`JPv`ju$>4YeS&HZGnoEV9 zjQD^R(siXJjwO2-%p_auL4rHg<N_ zCo*0NnCHupF~7T&l*Jdr_Mr@Pn8rHrTw*RH$-!aPr2+jY%2&+=D(T9_q0@tClSMc3 z50z$Gzt5u>Q3G+MM>AaTPtq$S*t(E0XCd4Kf@|N4s}D?K*dMS=f;?!?5;~QvV`VFU zN^Wre%>{o8#1w?v>J~;R{ zlv^JvgM!ez&J~6PGZuxgcn)}$O6C%Za%Z!pzuBZZdHBI*b3Avo9=({PpQ|7-ozM`b>S61S*v2hC?-&MUR5e?LR&)r% z*bhrW9{1CS?in1|f2Ks%Q}ODO1P`r+*8^f{1!Hat^s=Q_GjE>6ykuRy|A~ErA`fi` zw2Sx1Y-8MC+u7Mg208b~pfv6|Jqf^HnD&3OEOEmihu}lT2p(6`6UUc}>o3db8~!}o zRbadCWLo0yOV((d>r&jg6M(&#(7g*f#cCr8OiU=QRh&WgUgl__tZ^E@RW{3MGMbHj z#=h5`N_LVz|2#M1vfQw% z5U&BJze&XX)ty7bjqL?&X`cn@d^}yY57gOU>o*;4 z;|WV%(Cl{S@W#whygFX(H+5CSyFoeB;-q2yNfaP^s;P&XEaHzqWEafcT?N(Q$`ZP5 zjepj|6cu%2MO^mY&?XD#sKso_vU9f>PDdARanxzI;_Wsr&X}mkKfEBdMII28E3R`!!qUMc8Pa0}c z>p*bXQH;~!HduLpde?qG&O$`uNp?qQ&46@fsQQVsJ<)os&7OjxBjur5;j{WeL+9;n zTm4qExbQ5KQ)4taI7R_SU&dMDYnti9&i%P!8GN-?S63IhFk4+;_gIigs�unle4E zAnC0o5cTPo;hFIz+%<|9%wig8)3GHUAm0hvg<{5S?@xf!t-o}AzqqT}&QPl4DqPJ) zzdT1SzyD0OC1}$^)?%W`P|z`yJ2xx zH>Ua0<@GuCy-+3bUiRKi_AJ?p>`)N)9`xsTTL`1n=yyL_${Kp+cjcMXS+PE5-~5!;;Q? z$l$Ww8ig+nqpswg#|oEv-&3F(u5LhQ7$KZzq%X`?Umu%s!E;o!7VR!E&r`m`J4Hv$ z)3*)FwBcbD9fKtqT{9iRQ$8nX82C_c@4OMqujUuk5zU!@iXx$*k#DM>WthISik$qA zyFIrYt^k%X3Vt5tbr9##=w1jUi>-H*^o;1=)U6+wI1Gt{n7Tgi!+d*mNw+E$EWbTi zxnmm#nVc<4A|zkoqb394+o4r(%~jug{Pu|cYlxTp*ziZTzb)T(qAZ&u%2@~gq%$~N zZZlC$JX##lF5re?>kh9HG&dh`5$Z$G-ssWSYtQ94aFVpuVg zQ!A!BIgF8uW{Dxw>rGY4K;eQ3!fEC3|2S0y_4~{_*4aOfoV*_y8?A50l`Xd&x+u_( zU{^<5l7Rznao_r{aM+-a=N_WMP%x_-y;+?zYGm`@Itj4DxrVT*Z(A7VhicLG8XV5! ziJKWW;@*F0R@;vff74ycclg~;S%8#6ViZLDv4Tm<@y!om`*3)WQk_nZZ|RuT(C@fD zrnP|Z=b(t+?~=c(Cbv^~h-q>J$W7}}^XO(q+9fvN;3HIldo?(%ssVhnh-i2 z2dEeD$I-RU8oXOnWlY*U4ENX=35Iqx&Yg_)_azK?OW8PWsE=h~&Skmy=`M+YXrm|f zEtQo*$uezqUix$YPJWS;5g{g?vJjlpQY!VwlrCn3$1_x);sm_RF}3^^du8OW{-2Aw z27B-Op#EJaeRc9wDmw%P+;G8|!%Eywwdjo){>t2@CWb=LA_|cWBdPs1(Z z{t>;Q&rxnye#9(-KiAVg^$)KkkE*YEGP19l^-9|qah#?>%{UzqDBGOW=udY%=mvFs z<3xe;a^#Z-d#j_Un8P=YO+yFB2TcPLlg3{sE#Z^qEdHB$nvY$;hd3^UrIMI91#-Dd zn2D8%keV&2gR&wnkgq*5eE6&SvtirKF1HW<-I;1^%wL*6Zb}0r1%; z2TKQ{Sn6?oL$nb?~jn9Ydt2OJl@ zW+q`?#<toUiHdTzfvlI}MchuLYHMP2)JJ#!N+60l z*QXTJ94Im&do?p~Vb{TL!U?Fp#S@oJYTzh*jM_=X2cMuTs&L_5AnrB4C*70wQbaOF z<>Q>FF!xU}BPnmnKAd3eKdgwg5-ug3(!rJjMVFT-xTIIphRZ)7ei9uJ^pt&q-ii-G?ll##kamu(mU$ZYmMPfR1X`wJ&1r#Yx`Bu;9TaMi* zF3?QthknCyZ$r>*y^D zzxMj`(f;?m2iir3A9g23pHqlRhA`LD1c0&nD}N~Y;0?;u;kdh}ZL($S4gZ}qa@qvi}=?|FwaUgwSF zh!|WUzWdBqT=j%pJlcg8UvSt5w*y7ZW_3gH1r2E9I$7fSyop>s`EWJmr~pfWTA@-f zYiwwxfnE_CKT0Wi!)>X3Q?iFoLBtydS5=98mgK<^&ZQet_%vP_{#xyqcz-YmXdQ=D zDbmxzx*x~tU*V5oShU$M@0@doy!*_CqaDrb2_VMl%>L`!(@t1VKlGbK^cDQJFeFZX zC6Nyv66ekSaIrdOCcm|wP44CRDsZBQz%Pwp?=n`^8(k{MxhaA)Hfl~f)W zVe6k{rQACKy}A*bsH>G=1GnaI*!g>~eLwwoOX>?QS@_XzVpl?Op|scni3Dd%}JeS%|EC1`_=vS8C}IU)m&aW;^;%`Y+vO*)Sf$HlBBYaPmvi+XR7 z)ZN|^fQes~b|pXh^x>Ltd)JHHpQ(5J>f`qhN?;2&EdSh{K0ANjWe{iU!6TqZ>jhR- zQq6=F&ZoGuG?9~M^FenNub^xrC)Ja-aZ==4Tza|1OEm0yp%l^oLbY#P4Wz%vSh`x- z^g(!iY!4iM$cd`$u?rXb*49TLMdmUV;Om~5@kXfEd_$*JVfa@>=luJ7PCZr=zpq>ts@?M#?h+yeR?jF7~oNs&HaScdpJG> zcm>8VHYX+f(ZD{^$=>079(2t%ksfmT=e2p zbk#hhiC>qCTB(Tw&+;K3`8XW`JvpZ%I}6trKA9CW{w0zTAmgD&NfB|kJ=WSc|ME7h zu=TM4u8XQ&&4}9L4QnsU#?@&PG(GXlmHS(nr1G7q(v$@?ln0}owN?Px#Wh*GF+Wgl z9mc~RekppK*bzsTtTc1t<`0~u0IgD5VZV$Nrbxw3eD@kLKzg6{Dc9k^r>+QJy>~IH&a;4{C#MkRd?C~|5(p%WvwOCS*5Xk?e~ub1fJYa zME(gMBAPTrA8tXpsExc1l2Zjm-Ilei>9dnpahI45u8ShwR43 z*|st*KEqob{r`5b>3|X?S-(=gl0ST1sLVqCCstMc-$PgjCAB+P%3T_MW)b7a*=HS8 zj5!Ixy3woyNEATUJg|qdW;C;dOJGOOR)uiYah~R_d5{AAt%QC2zoRPor*~9wv;H0< z$4~;{;s1UF0psBqh7Y@cNM8bP<(Ja6p0*+)H;^hH*6R3)q;W2tR=Xcl&hDD1U)Ojp zD>3R`8P!NE(V3ordK%C&B`2<#w?F&o4NLS2Cgu5_a&YUv`g38aUen5W`tXPb7X_W!ERw$AeJoR4*^GbJO6G6%h_>-(aU_8H)H9t^8gJ>?fduAz+ z3h4~+3eXw*@0w=fy4(L5V9ulu z@AsBvqA{9o0MiyfFTSZ0rj!h-9{MHKV+&KUl+a8E*9NngEiarb8vMetPK!?K8{ECnDBXzqX?mv((kPrHEwAIrWhG2;T&5t&h0! z4S=fV${T42gjcXpzp z;1}#cr6EumgW3k^?;Jbda*JBW?@&tbULDCl172kxP{vhKZ;dQ8O9>l% zKycg zo&8g;-zdCkengjiWdq`GDOA1TDO^S_L?*1OQ60f!VsnZNvgWMF6O573xz=!M${aqrFw=86>s`Y|DuEx|g z8I*H5CeTdcSQ}9hxz^V?la6G40i3&fw>ZXQ(4bg}PNkZ?bC>vf4n^c9&qwNJ8Y83yuYXx+yTcgSqkfdAyh>Q zGNaSe-(0uGiX7l^46{>)OALieRzz^8VJ4#JppGzQ@{q0AmcgJJ$oj&pW>lm>Nug{+ z{@1+&tRD|~xw6U2c&4%}GIu<=krc(FM}}zvXUDa#1-tH9Sb9R54ThyaHRYr?8}^#+ zEF1yj;l%n@l+XXxs%tU1U-{Mx% zYc>P;22bK4G+IvK;=r@oD0N;OR<$C?UJd2%-TTZ0twV|w*~7P;ZdbqI;}i@-E=xNd zPo3w$#H;+*%wGg7ohy*|ensrrm!bP*@q>{D4zqf)m=P$`-{@*G1cf(nLnVbw6tG4V zW^0^f{4us8ps(Q8fJ=im^23&X!bliM-CwawPA*=U+`~PJH~IRfTSr?c^^ch-@LuXc zFi3!^u3lr*=k-`j800K#kqE{R1(DAy;1aIevrDIWz!orJ$AfW&_k3YZCT!4mFrQv4bqgJMBAmyc*avuCpzd0`%*H)*}elZmdS&&$U2nv}p1+C<39@l@=y zf`=-p5|<`B(Zq-O)$vOQ;XcT8=Z=iiI%#LLeDvbwlR>eejzg7PU9L~GDGP2`?kc)t z&kU%-_ubgX3n=T~ovC;%x*Mhc`rxUwAsQ;cSMtx$(ct*bbYiCdj!A@B(1a6}Bi=>T zyrV;PFSs-GP>Zxux*oIayS>LfZc9{psxSL{hm}zY$*5<_H9Xg@kPvcztcd|(BmX5_ z7-kRrvIQq$^UB_E%|<5wi_FKpJ0}k${Q6ZF-(6=mn4jq{5mT}%%b`0|=16F)?D}ev zAqo+?&6QN&m}mR$XJ<8&Yx`RWzw?edGtm(AUq|KxD6q1>e$zYrEH3V9L7RoYk9X8~ z$$HcRLGyU=lmDv8wPac|>OS3neD`c}aH99--dwnp_eHcmTA^wETam&0Xo*>=N4^vl zj0lAkvO1g>W+cTOv$;PxR>8L!zaWi<9f?KT8THT% z6o2l4Y2_EHWi%*H+N=&r!JQ4)z8FXAR_7->46~mqIwC!jUHLp^&`+b^3&E3&+G1pWd=~>SHfA2aefk+hF7K%K630`x z;@@&=?N6e7mq!BBwZKDcy!ACD{%G^$x<4j*Idn-+H-Y&@C5k(@%J<{%ZuK%k$>VM4 z(mvWIEQW*WMeZg2uvby>=4CHaOiF_S zX?kS}C%~4|l80#FO7C)yB49+c6vLmemAybeP1!@2Cy8&WT2Y zk#%SsiK)|1qg2_hvhtuPTWPq44TINqk zB%-CJZ$~a^U+Ngqfafr$n zGv~f+1-}iCTaa;b+r&~nY<7XM1FHA%jW+)6fQX`FHUraaW{aTrr@3wH|L`bBEb8y|Fvr z^`9;GXAoDjZ%v8T!{dwj2Zbxm_w(chM|c?efB&s(WO6>zVR9GryYKmvIFxKNq^gx9 zL(Y^SkkqcSH?8cIi+@K;jqq@UFF!{(P}~wqg>O=j)EQDx-g%Owi;x^cey7z=nxXUa zUsRRLmd|fl4v16?;0w_PvZYg@B!8^AxA zL`o|T?-hsX-?Pth$d+GkX3w5Z@N(zKG9Sc<$%6$2Irq}M9AZm8?8*=e zN;nsC!W9QRNiDHP!blHnC)<8&YYooRzvi!|aZQsrnXAaSf_%T5l=Nj9vFN=yn72t5 z?45y<2@*%UEKFq+_M$2*z!u`c>QBx%nNNrXhGzn$UOQ>qY0B7;%GfUlHMn8McV~|n z#+=7zj@O@@H%unsMA#298kRo&D=9yyk_|X<)c&#URRyRlZo0B6KO@jcO?W5~vM^JV zUUKx9h1TPxI*eo?Wi>{yrb8i9c?*kKPe7OV4(}XyJwFHj*Ym-RP%%Z=+aMgI?Ytcx z2tXJNkrD)p3kr)ELByp+MWjW=_`$-`U~r|1;P3xq0QazWc0~UF28;9`oF5G6|C`~t zha7$d~NOK;pAcc-%3X9 z)c$K>G4VGtMHt%nvUz%YI6AvIupyA14s6bz2s;44FLULXgwV?v1RBsA9MV`b1mJKI z3)vA; diff --git a/COPS/cops-3.1.3/images/icons/icon57.png b/COPS/cops-3.1.3/images/icons/icon57.png deleted file mode 100644 index a1609bbfec1d6f90b1875b12d4030de8d8de7a0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3309 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 diff --git a/COPS/cops-3.1.3/images/icons/icon72.png b/COPS/cops-3.1.3/images/icons/icon72.png deleted file mode 100644 index eb9735789024360dc79ec66e4eced14d74e2d888..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4330 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 H*hl{Z^i<_x diff --git a/COPS/cops-3.1.3/images/language.png b/COPS/cops-3.1.3/images/language.png deleted file mode 100644 index 5b18b4fa33817aafffa0b92fe5c80c1f7513c2c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1972 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 O00001 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 A3;+NC diff --git a/COPS/cops-3.1.3/index.php b/COPS/cops-3.1.3/index.php deleted file mode 100644 index ca0081a3..00000000 --- a/COPS/cops-3.1.3/index.php +++ /dev/null @@ -1,15 +0,0 @@ - - * @author mikespub - */ - -use SebLucas\Cops\Framework; - -require_once __DIR__ . '/config/config.php'; - -Framework::run('index'); diff --git a/COPS/cops-3.1.3/lang/Localization_af.json b/COPS/cops-3.1.3/lang/Localization_af.json deleted file mode 100644 index 7e90945f..00000000 --- a/COPS/cops-3.1.3/lang/Localization_af.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "Meer oor COPS", - "addeddate.title": "Added", - "allbooks.alphabetical.many": " Alfabetiese indeks van die {0} boeke", - "allbooks.alphabetical.none": "Alfabetiese indeks van absoluut geen boeke", - "allbooks.alphabetical.one": "Alfabetiese indeks van die enigste boek", - "allbooks.title": "Alle boeke", - "authors.alphabetical.many": "Alfabetiese indeks van die {0} outeurs", - "authors.alphabetical.none": "Alfabetiese indeks van absoluut geen outeurs nie", - "authors.alphabetical.one": "Alfabetiese indeks van die enigste outeur", - "authors.title": "Outeurs", - "author.title": "Author", - "authorword.many": "{0} outeurs", - "authorword.none": "Geen outeurs", - "authorword.one": "1 outeur", - "bookentry.author": "{0} by {1}", - "bookword.many": "boeke", - "bookword.none": "Geen boeke", - "bookword.one": "1 boek", - "bookword.title": "Boeke", - "cog.alternate": "Soek, sorteer en filtreer", - "content.series": "Reeks:", - "content.series.data": "Boek {0} in die {1} reeks", - "content.summary": "Opsomming", - "customcolumn.boolean.no": "Nee", - "customcolumn.boolean.unknown": "Nie gestel nie", - "customcolumn.boolean.yes": "Ja", - "customcolumn.date.format": "J-m-d", - "customcolumn.date.unknown": "Nie gestel nie", - "customcolumn.description": "Gepasmaakte kolom '{0}'", - "customcolumn.description.bool": "Indeks van 'n Boolean waarde", - "customcolumn.description.enum.many": "Alfabetiese indeks van die {0} waardes", - "customcolumn.description.enum.none": "Alfabetiese indeks van absoluut geen waardes", - "customcolumn.description.enum.one": "Alfabetiese indeks van een waarde", - "customcolumn.description.rating": "Indeks van graderings", - "customcolumn.description.series.many": " Alfabetiese indeks van die {0} reeks", - "customcolumn.description.series.none": " Alfabetiese indeks van absoluut geen reeks", - "customcolumn.description.series.one": "Alfabetiese indeks van die enigste reeks", - "customcolumn.enum.unknown": "Nie gestel nie", - "customcolumn.float.unknown": "Nie gestel nie", - "customcolumn.int.unknown": "Nie gestel nie", - "customcolumn.rating.unknown": "Nie gestel nie", - "customcolumn.stars.many": " {0} Sterre", - "customcolumn.stars.none": "Geen Sterre", - "customcolumn.stars.one": "1 Ster", - "customize.email": "Stel jou e-pos in (om e-pos toe te laat)", - "customize.fancybox": "Gebruik Ligboks (boeke laai in sweef raam)", - "customize.filter": " Aktiveer etiket filtreering", - "customize.ignored": "Geïgnoreerde Kategorieë ", - "customize.paging": "Maksimum aantal boeke per bladsy (-1 om te deaktiveer)", - "customize.style": "Tema", - "customize.template": "Template", - "customize.title": " Pas COPS UI aan", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Verwyder Alles", - "filters.title": "Filters", - "home.alternate": "Tuisblad", - "i18n.coversection": "Omslag", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Taal", - "languages.alphabetical.many": "Alfabetiese indeks van die {0} tale", - "languages.alphabetical.none": "Alfabetiese indeks van absoluut geen tale nie", - "languages.alphabetical.one": " Alfabetiese indeks van die enigste taal", - "languages.title": "Tale", - "links.title": "Skakel", - "mail.messagenotsent": "Boodskap kon nie gestuur word nie.", - "mail.messagesent": "Boodskap is gestuur", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "Volgende", - "paging.previous.alternate": "Vorige", - "permalink.alternate": "Permalink", - "pubdate.title": "Published", - "publisher.name": "Uitgewer", - "publishers.alphabetical.many": " Alfabetiese indeks van die {0} uitgewers", - "publishers.alphabetical.none": "Alfabetiese indeks van absoluut geen uitgewers", - "publishers.alphabetical.one": "Alfabetiese indeks van die enigste uitgewer", - "publishers.title": "Uitgewers", - "publisherword.many": "{0} uitgewers", - "publisherword.none": "Geen uitgewers", - "publisherword.one": "1 uitgewer", - "ratings.many": " {0} graderings", - "ratings.none": "geen graderings nie", - "ratings.one": "1 gradering", - "ratings.title": "Graderings", - "rating.title": "Rating", - "ratingword.many": "{0} sterre", - "ratingword.none": "Geen ster nie", - "ratingword.one": "1 ster ", - "recent.list": "{0} mees onlangse boeke", - "recent.title": " Onlangse toevoegings", - "search.alternate": "Soek", - "search.result": " Soekresultaat vir * {0} *", - "search.result.author": "Soekresultaat vir * {0} * in outeurs", - "search.result.book": "Soekresultaat vir * {0} * in boeke", - "search.result.publisher": "Soekresultaat vir * {0} * in uitgewers", - "search.result.series": "Soekresultaat vir * {0} * in reeks", - "search.result.tag": "Soekresultaat vir * {0} * in etikette", - "search.sortorder.asc": "Opgaan", - "search.sortorder.desc": "Afgaan", - "series.alphabetical.many": "Alfabetiese indeks van die {0} reeks", - "series.alphabetical.none": "Alfabetiese indeks van absoluut geen reeks", - "series.alphabetical.one": "Alfabetiese indeks van die enigste reeks", - "series.title": "Reeks", - "seriesword.many": "{0} reeks", - "seriesword.none": "Geen reeks nie", - "seriesword.one": "1 reeks", - "sort.alternate": "Sorteer", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "Ander boeke", - "splitByLetter.letter": "{0} begin met {1}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "Alfabetiese indeks van die {0} etikette", - "tags.alphabetical.none": "Alfabetiese indeks van absoluut geen etikette", - "tags.alphabetical.one": "Alfabetiese indeks van die enigste etiket", - "tags.title": "Etiket", - "tagword.many": "{0} etikette", - "tagword.none": "Geen etikette", - "tagword.one": "1 etiket", - "tagword.title": "Etikette", - "title.title": "Title", - "languages.abk": "Abkhaz", - "languages.aaf": "Afar", - "languages.afr": "Afrikaans", - "languages.aka": "Akan", - "languages.sqi": "Albanies", - "languages.amh": "Amharies", - "languages.ara": "Arabies", - "languages.arg": "Aragonees", - "languages.arc": "Aramees", - "languages.hye": "Armenies", - "languages.asm": "Assamees", - "languages.ava": "Avaric", - "languages.ave": "Avestan", - "languages.aym": "Aymara", - "languages.aze": "Azerbeidjans", - "languages.bam": "Bambaraans", - "languages.bak": "Bashkir", - "languages.eus": "Baskies", - "languages.bel": "Wit‐Russies", - "languages.ben": "Bengaals", - "languages.bih": "Bihari", - "languages.bis": "Bislama", - "languages.bos": "Bosniëse", - "languages.bre": "Breton", - "languages.bul": "Bulgaars", - "languages.mya": "Birmaans", - "languages.cat": "Katalaans", - "languages.cha": "Chamorro", - "languages.che": "Tsjetsjeens", - "languages.nya": "Chichewaans", - "languages.zho": "Sjinees", - "languages.chv": "Chuvash", - "languages.cor": "Cornish", - "languages.cos": "Korsikaans", - "languages.cre": "Cree", - "languages.hrv": "Kroaties", - "languages.ces": "Tsjeg", - "languages.dan": "Deense", - "languages.div": "Divehi", - "languages.nld": "Nederlands", - "languages.dzo": "Dzongkha", - "languages.eng": "Engels", - "languages.epo": "Esperanto", - "languages.est": "Ests", - "languages.ewe": "Ewe", - "languages.fao": "Faroees", - "languages.fij": "Fidjiaans", - "languages.fin": "Finse", - "languages.fra": "Frans", - "languages.ful": "Fulaans", - "languages.glg": "Galisies", - "languages.kat": "Georgies", - "languages.deu": "Duits", - "languages.ell": "Grieks", - "languages.egy": "Egipties (antieke)", - "languages.grn": "Guaraní", - "languages.guj": "Gujarati", - "languages.hat": "Haïties", - "languages.hau": "Hausaans", - "languages.heb": "Hebreeus", - "languages.her": "Herero", - "languages.hin": "Hindi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Hongaars", - "languages.ina": "Interlingua", - "languages.ind": "Indonesies", - "languages.ile": "Interlingue", - "languages.gle": "Iers", - "languages.grc": "Grieks, Antieke (tot 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Yslands", - "languages.ita": "Italiaans", - "languages.iku": "Inuktitut", - "languages.jpn": "Japanees", - "languages.jav": "Javanees", - "languages.kal": "Kalaallisut", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kashmiri", - "languages.kaz": "Kazakh", - "languages.khm": "Khmer", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kirgisië", - "languages.kom": "Komi", - "languages.kon": "Kongo", - "languages.kor": "Koreaans", - "languages.kur": "Koerdies", - "languages.kua": "Kwanyama", - "languages.lat": "Latyns", - "languages.ltz": "Luxemburgs", - "languages.lug": "Ganda", - "languages.lim": "Limburgs", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Litaus", - "languages.lub": "Luba-Katanga", - "languages.lav": "Lets", - "languages.glv": "Manx", - "languages.mkd": "Macedoniës", - "languages.mlg": "Malagasies", - "languages.msa": "Maleis", - "languages.mal": "Malabaars", - "languages.mlt": "Maltees", - "languages.mri": "Maori", - "languages.mar": "Marathi", - "languages.mah": "Marshallese", - "languages.mon": "Mongools", - "languages.nau": "Nauru", - "languages.nav": "Navajo", - "languages.nob": "Noorse Bokmål", - "languages.nde": "Noorse Ndebele", - "languages.nep": "Nepal", - "languages.ndo": "Ndonga", - "languages.nno": "Noorweegse Nynorsk", - "languages.nor": "Noorse", - "languages.iii": "Nuosu", - "languages.nbl": "Suid Ndebele", - "languages.oci": "Occitan", - "languages.oji": "Ojibwe", - "languages.chu": "Ou Kerk Slawies", - "languages.orm": "Oromo", - "languages.ori": "Oriya", - "languages.oss": "Ossetië", - "languages.pan": "Punjabi", - "languages.pli": "Pali", - "languages.fas": "Persies", - "languages.pol": "Pools", - "languages.pus": "Pashto", - "languages.por": "Portugees", - "languages.que": "Quechua", - "languages.roh": "Roemeens", - "languages.run": "Kirundi", - "languages.ron": "Roemeens", - "languages.rus": "Russies", - "languages.sam": "Samaritaan Aramees", - "languages.san": "Sanskrit", - "languages.srd": "Sardies", - "languages.snd": "Sindhi", - "languages.sme": " Noordelike Sami", - "languages.smo": "Samoa", - "languages.sag": "Sango", - "languages.srp": "Serwies", - "languages.gla": "Skotse Kelties", - "languages.sna": "Shona", - "languages.sin": "Sinhala", - "languages.slk": "Slowakies", - "languages.slv": "Sloweens", - "languages.som": "Somalies", - "languages.sot": "Suid-Sotho", - "languages.spa": "Spaans", - "languages.sun": "Soendanees", - "languages.sux": "Sumeries", - "languages.swa": "Swahili", - "languages.ssw": "Swati", - "languages.swe": "Sweeds", - "languages.syc": "Klassieke Siriës", - "languages.syr": "Siriës", - "languages.tam": "Tamil", - "languages.tel": "Telugu", - "languages.tgk": "Tajik", - "languages.tha": "Thais", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetaanse Standaard", - "languages.tuk": "Turkmen", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tonga", - "languages.tur": "Turks", - "languages.tso": "Tsonga", - "languages.tat": "Tatar", - "languages.twi": "Twi", - "languages.tah": "Tahitiaans", - "languages.uga": "Ugaritic", - "languages.uig": "Uighur", - "languages.ukr": "Oekrains", - "languages.urd": "Urdu", - "languages.uzb": "Oesbekistan ", - "languages.ven": "Venda", - "languages.vie": "Viëtnamees", - "languages.vol": "Volapük", - "languages.win": "Walloon", - "languages.cym": "Wallies", - "languages.wol": "Wolof", - "languages.fry": "Wes-Fries", - "languages.xho": "Xhosa", - "languages.yid": "Jiddisj", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_bg.json b/COPS/cops-3.1.3/lang/Localization_bg.json deleted file mode 100644 index a96a3f7b..00000000 --- a/COPS/cops-3.1.3/lang/Localization_bg.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "За COPS", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "{0} книги", - "allbooks.alphabetical.none": "0 книги ", - "allbooks.alphabetical.one": "1 книга", - "allbooks.title": "Всички книги", - "authors.alphabetical.many": "{0} автора", - "authors.alphabetical.none": "0 автора", - "authors.alphabetical.one": "1 автор", - "authors.title": "Автори", - "author.title": "Author", - "authorword.many": "{0} автора", - "authorword.none": "0 автора", - "authorword.one": "1 автор", - "bookentry.author": "{0} от {1}", - "bookword.many": "{0} книги", - "bookword.none": "0 книги", - "bookword.one": "1 книга", - "bookword.title": "Книги", - "cog.alternate": "Търсене, сортиране и филтри", - "content.series": "Поредици:", - "content.series.data": "Книга {0} от поредицата '{1}'", - "content.summary": "Резюме", - "customcolumn.boolean.no": "Не", - "customcolumn.boolean.unknown": "Неизвестно", - "customcolumn.boolean.yes": "Да", - "customcolumn.date.format": "Y-m-d", - "customcolumn.date.unknown": "Неизвестна", - "customcolumn.description": "Потребителска колона '{0}'", - "customcolumn.description.bool": "Логически стойности", - "customcolumn.description.enum.many": "{0} стойности", - "customcolumn.description.enum.none": "0 стойности", - "customcolumn.description.enum.one": "1 стойност", - "customcolumn.description.rating": "Рейтинги", - "customcolumn.description.series.many": "{0} поредици", - "customcolumn.description.series.none": "0 поредица", - "customcolumn.description.series.one": "1 поредица", - "customcolumn.enum.unknown": "Няма", - "customcolumn.float.unknown": "Няма", - "customcolumn.int.unknown": "Няма", - "customcolumn.rating.unknown": "Няма", - "customcolumn.stars.many": "{0} Звезди", - "customcolumn.stars.none": "0 Звезди", - "customcolumn.stars.one": "1 Звезда", - "customize.email": "Въведете e-mail (за да активирате изпращане по e-mail)", - "customize.fancybox": "Използване на Lightbox", - "customize.filter": "Филтриране по тагове", - "customize.ignored": "Игнорирани категории на началната страница", - "customize.paging": "Книги на страница (-1 за неограничен брой)", - "customize.style": "Тема на интерфейса", - "customize.template": "Template", - "customize.title": "Персонализиране на COPS интерфейса", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Изчисти всички полета", - "filters.title": "Filters", - "home.alternate": "Начало", - "i18n.coversection": "Корица", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Език", - "languages.alphabetical.many": "{0} езика", - "languages.alphabetical.none": "0 езика", - "languages.alphabetical.one": "1 език", - "languages.title": "Езици", - "links.title": "Връзки", - "mail.messagenotsent": "Книгата не може да бъде изпратена.", - "mail.messagesent": "Книгата е изпратена.", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "Следваща", - "paging.previous.alternate": "Предишна", - "permalink.alternate": "Постоянна хипервръзка", - "pubdate.title": "Published", - "publisher.name": "Издател", - "publishers.alphabetical.many": "{0} издателя", - "publishers.alphabetical.none": "0 издателя", - "publishers.alphabetical.one": "1 издател", - "publishers.title": "Издатели", - "publisherword.many": "{0} издателя", - "publisherword.none": "0 издателя", - "publisherword.one": "1 издател", - "ratings.many": "{0} рейтинга", - "ratings.none": "0 рейтинга", - "ratings.one": "1 рейтинг", - "ratings.title": "Рейтинги", - "rating.title": "Rating", - "ratingword.many": "{0} звезди", - "ratingword.none": "0 звезди", - "ratingword.one": "1 звезда", - "recent.list": "{0} последно добавени", - "recent.title": "Последно добавени", - "search.alternate": "Търсене", - "search.result": "Резултат за *{0}*", - "search.result.author": "Резултат за *{0}* в Автори", - "search.result.book": "Резултат за *{0}* в Книги", - "search.result.publisher": "Резултат за *{0}* в Издатели", - "search.result.series": "Резултат за *{0}* в Поредици", - "search.result.tag": "Резултат за *{0}* в тагове", - "search.sortorder.asc": "A-Я", - "search.sortorder.desc": "Я-А", - "series.alphabetical.many": "{0} поредици", - "series.alphabetical.none": "0 поредици", - "series.alphabetical.one": "1 поредица", - "series.title": "Поредици", - "seriesword.many": "{0} поредици", - "seriesword.none": "0 поредици", - "seriesword.one": "1 поредица", - "sort.alternate": "Сортиране", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "Други Книги", - "splitByLetter.letter": "{0} започват с {1}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "{0} тага", - "tags.alphabetical.none": "0 тага", - "tags.alphabetical.one": "1 таг", - "tags.title": "Тагове", - "tagword.many": "{0} тага", - "tagword.none": "0 тага", - "tagword.one": "1 таг", - "tagword.title": "Тагове", - "title.title": "Title", - "languages.abk": "Абхазки", - "languages.aaf": "Афарски", - "languages.afr": "Африканс", - "languages.aka": "Акана", - "languages.sqi": "Албански", - "languages.amh": "Амхарски", - "languages.ara": "Арабски", - "languages.arg": "Арагонски", - "languages.arc": "Aramaic", - "languages.hye": "Арменски", - "languages.asm": "Асамски", - "languages.ava": "Аварски", - "languages.ave": "Авестански", - "languages.aym": "Аймара", - "languages.aze": "Азербайджански", - "languages.bam": "Бамбарски", - "languages.bak": "Башкирски", - "languages.eus": "Баски", - "languages.bel": "Белоруски", - "languages.ben": "Бенгали", - "languages.bih": "Бихарски", - "languages.bis": "Бислама", - "languages.bos": "Босненски", - "languages.bre": "Бретонски", - "languages.bul": "Български", - "languages.mya": "Бирмански", - "languages.cat": "Каталонски", - "languages.cha": "Цамору", - "languages.che": "Чеченски", - "languages.nya": "Chichewa", - "languages.zho": "Китайски", - "languages.chv": "Chuvash", - "languages.cor": "Cornish", - "languages.cos": "Corsican", - "languages.cre": "Cree", - "languages.hrv": "Хърватски", - "languages.ces": "Чешки", - "languages.dan": "Датски", - "languages.div": "Divehi", - "languages.nld": "Холандски", - "languages.dzo": "Dzongkha", - "languages.eng": "English", - "languages.epo": "Есперанто", - "languages.est": "Естонски", - "languages.ewe": "Ewe", - "languages.fao": "Faroese", - "languages.fij": "Фиджийски", - "languages.fin": "Финландски", - "languages.fra": "Френски", - "languages.ful": "Fula", - "languages.glg": "Galician", - "languages.kat": "Georgian", - "languages.deu": "Немски", - "languages.ell": "Гръцки", - "languages.egy": "Egyptian (Ancient)", - "languages.grn": "Guaraní", - "languages.guj": "Gujarati", - "languages.hat": "Haitian", - "languages.hau": "Hausa", - "languages.heb": "Еврейски", - "languages.her": "Herero", - "languages.hin": "Хинди", - "languages.hmo": "Hiri Motu", - "languages.hun": "Унгарски", - "languages.ina": "Interlingua", - "languages.ind": "Индонезийски", - "languages.ile": "Interlingue", - "languages.gle": "Ирландски", - "languages.grc": "Greek, Ancient (to 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Исландски", - "languages.ita": "Италиански", - "languages.iku": "Inuktitut", - "languages.jpn": "Японски", - "languages.jav": "Javanese", - "languages.kal": "Kalaallisut", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kashmiri", - "languages.kaz": "Kazakh", - "languages.khm": "Khmer", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kyrgyz", - "languages.kom": "Komi", - "languages.kon": "Kongo", - "languages.kor": "Корейски", - "languages.kur": "Кюрдски", - "languages.kua": "Kwanyama", - "languages.lat": "Латински", - "languages.ltz": "Luxembourgish", - "languages.lug": "Ganda", - "languages.lim": "Limburgish", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Литовски", - "languages.lub": "Luba-Katanga", - "languages.lav": "Латвийски", - "languages.glv": "Manx", - "languages.mkd": "Македонски", - "languages.mlg": "Malagasy", - "languages.msa": "Malay", - "languages.mal": "Malayalam", - "languages.mlt": "Малтийски", - "languages.mri": "Māori", - "languages.mar": "Marathi", - "languages.mah": "Marshallese", - "languages.mon": "Монголски", - "languages.nau": "Nauru", - "languages.nav": "Navajo", - "languages.nob": "Norwegian Bokmål", - "languages.nde": "North Ndebele", - "languages.nep": "Непалски", - "languages.ndo": "Ndonga", - "languages.nno": "Norwegian Nynorsk", - "languages.nor": "Норвежки", - "languages.iii": "Nuosu", - "languages.nbl": "South Ndebele", - "languages.oci": "Occitan", - "languages.oji": "Ojibwe", - "languages.chu": "Old Church Slavonic", - "languages.orm": "Oromo", - "languages.ori": "Oriya", - "languages.oss": "Ossetian", - "languages.pan": "Пенджабски", - "languages.pli": "Pāli", - "languages.fas": "Персийски", - "languages.pol": "Полски", - "languages.pus": "Pashto", - "languages.por": "Португалски", - "languages.que": "Quechua", - "languages.roh": "Romansh", - "languages.run": "Kirundi", - "languages.ron": "Румънски", - "languages.rus": "Руски", - "languages.sam": "Samaritan Aramaic", - "languages.san": "Санскрит", - "languages.srd": "Sardinian", - "languages.snd": "Sindhi", - "languages.sme": "Northern Sami", - "languages.smo": "Samoan", - "languages.sag": "Sango", - "languages.srp": "Сръбски", - "languages.gla": "Scottish Gaelic", - "languages.sna": "Shona", - "languages.sin": "Sinhala", - "languages.slk": "Словашки", - "languages.slv": "Словенски", - "languages.som": "Сомалийски", - "languages.sot": "Southern Sotho", - "languages.spa": "Испански", - "languages.sun": "Sundanese", - "languages.sux": "Sumerian", - "languages.swa": "Суахили", - "languages.ssw": "Swati", - "languages.swe": "Шведски", - "languages.syc": "Classical Syriac", - "languages.syr": "Syriac", - "languages.tam": "Tamil", - "languages.tel": "Telugu", - "languages.tgk": "Tajik", - "languages.tha": "Тай", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetan Standard", - "languages.tuk": "Turkmen", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tonga", - "languages.tur": "Турски", - "languages.tso": "Tsonga", - "languages.tat": "Tatar", - "languages.twi": "Twi", - "languages.tah": "Tahitian", - "languages.uga": "Ugaritic", - "languages.uig": "Uighur", - "languages.ukr": "Украински", - "languages.urd": "Урду", - "languages.uzb": "Узбекски", - "languages.ven": "Venda", - "languages.vie": "Виетнамски", - "languages.vol": "Volapük", - "languages.win": "Walloon", - "languages.cym": "Уелски", - "languages.wol": "Wolof", - "languages.fry": "Western Frisian", - "languages.xho": "Xhosa", - "languages.yid": "Yiddish", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_ca.json b/COPS/cops-3.1.3/lang/Localization_ca.json deleted file mode 100644 index 68d11242..00000000 --- a/COPS/cops-3.1.3/lang/Localization_ca.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "Sobre COPS", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "Llistat alfabètic de {0} llibres", - "allbooks.alphabetical.none": "Llistat sense llibres", - "allbooks.alphabetical.one": "Llistat amb un llibre", - "allbooks.title": "Tots els llibres", - "authors.alphabetical.many": "Llistat alfabètic de {0} autors", - "authors.alphabetical.none": "Llistat sense autors", - "authors.alphabetical.one": "Llistat amb un autor", - "authors.title": "Autors", - "author.title": "Author", - "authorword.many": "{0} autors", - "authorword.none": "Cap autor", - "authorword.one": "1 autor", - "bookentry.author": "{0} de {1}", - "bookword.many": "{0} llibres", - "bookword.none": "Cap llibre", - "bookword.one": "1 llibre", - "bookword.title": "Llibres", - "cog.alternate": "Buscar, ordenar i filtres", - "content.series": "Series:", - "content.series.data": "Llibre {0} de la sèrie {1}", - "content.summary": "Sinopsi:", - "customcolumn.boolean.no": "No", - "customcolumn.boolean.unknown": "No Establert", - "customcolumn.boolean.yes": "Si", - "customcolumn.date.format": "A-m-d", - "customcolumn.date.unknown": "No Establert", - "customcolumn.description": "Columna personalitzada '{0}'", - "customcolumn.description.bool": "Índes d'un valor booleà", - "customcolumn.description.enum.many": "Índex alfabètic de {0} valors", - "customcolumn.description.enum.none": "Índex alfabètic sense valors", - "customcolumn.description.enum.one": "índex alfabètic d'un valor", - "customcolumn.description.rating": "Índex de valoracions", - "customcolumn.description.series.many": "{0} sèries ordenades alfabèticament", - "customcolumn.description.series.none": "Llistat sense sèries", - "customcolumn.description.series.one": "Llistat alfabètic d'una sola sèrie", - "customcolumn.enum.unknown": "No Establert", - "customcolumn.float.unknown": "No Establert", - "customcolumn.int.unknown": "No Establert", - "customcolumn.rating.unknown": "No Establert", - "customcolumn.stars.many": "{0} Estrelles", - "customcolumn.stars.none": "Cap estrella", - "customcolumn.stars.one": "1 Estrella", - "customize.email": "Introdueix el teu email (permitir enviament de llibres per e-mail)", - "customize.fancybox": "Usar Lightbox (llibres en marc flotant)", - "customize.filter": "Habilitar filtre per etiqueta", - "customize.ignored": "Ocultar categories", - "customize.paging": "Nombre màx de llibres per pàgina (-1 per deshabilitar)", - "customize.style": "Tema", - "customize.template": "Template", - "customize.title": "Configura COPS UI", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Desmarcar Tots", - "filters.title": "Filters", - "home.alternate": "Inici", - "i18n.coversection": "Portada", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Idioma", - "languages.alphabetical.many": "Llistat alfabètic de {0} idiomes", - "languages.alphabetical.none": "Llistat sense idiomes disponibles", - "languages.alphabetical.one": "llistat amb un idioma", - "languages.title": "Idiomes", - "links.title": "Enllaços", - "mail.messagenotsent": "El missatge no por ser enviat.", - "mail.messagesent": "Missatge enviat", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "Següent", - "paging.previous.alternate": "Anterior", - "permalink.alternate": "Enllaç permanent", - "pubdate.title": "Published", - "publisher.name": "Publicador", - "publishers.alphabetical.many": "Llistat alfabètic de {0} editorials", - "publishers.alphabetical.none": "Llistat sense editorials", - "publishers.alphabetical.one": "Llistat amb una editorial", - "publishers.title": "Editorials", - "publisherword.many": "{0} editorials", - "publisherword.none": "Sense editorials", - "publisherword.one": "1 editorial", - "ratings.many": "{0} valoració", - "ratings.none": "sense valoracions", - "ratings.one": "1 valoració", - "ratings.title": "Valoracions", - "rating.title": "Rating", - "ratingword.many": "{0} estrelles", - "ratingword.none": "Sense estrella", - "ratingword.one": "1 estrella", - "recent.list": "{0} darrers títols incorporats", - "recent.title": "Els més recents", - "search.alternate": "Cerca", - "search.result": "Resultats de búsqueda per *{0}*", - "search.result.author": "Resultats de búsqueda per *{0}* per autors", - "search.result.book": "Resultats de búsqueda per *{0}* per llibres", - "search.result.publisher": "Resultats de búsqueda per *{0}* per editorials", - "search.result.series": "Resultats de búsqueda per *{0}* per sèries", - "search.result.tag": "Resultats de búsqueda per *{0}* per etiquetes", - "search.sortorder.asc": "Asc", - "search.sortorder.desc": "Desc", - "series.alphabetical.many": "{0} sèries ordenades alfabèticament", - "series.alphabetical.none": "Llistat sense sèries", - "series.alphabetical.one": "Llistat alfabètic d'una sola sèrie", - "series.title": "Sèries", - "seriesword.many": "sèries", - "seriesword.none": "Cap sèrie", - "seriesword.one": "1 sèrie", - "sort.alternate": "Ordenar", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "Altres llibres", - "splitByLetter.letter": "{0} ({1})", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "{0} etiquetes ordenades alfabèticament", - "tags.alphabetical.none": "Llistat sense etiquetes", - "tags.alphabetical.one": "Llistat alfabètic de la única etiqueta", - "tags.title": "Etiquetes", - "tagword.many": "etiquetes", - "tagword.none": "Cap etiqueta", - "tagword.one": "1 etiqueta", - "tagword.title": "Etiquetes", - "title.title": "Title", - "languages.abk": "Abkhaz", - "languages.aaf": "Afar", - "languages.afr": "Africà", - "languages.aka": "Akan", - "languages.sqi": "Albani", - "languages.amh": "Amharic", - "languages.ara": "Àrab", - "languages.arg": "Aragonès", - "languages.arc": "Arameu", - "languages.hye": "Armeni", - "languages.asm": "Assamese", - "languages.ava": "Avaric", - "languages.ave": "Avestan", - "languages.aym": "Aymara", - "languages.aze": "Azerbaijani", - "languages.bam": "Bambara", - "languages.bak": "Bashkir", - "languages.eus": "Basc", - "languages.bel": "Belarusian", - "languages.ben": "Bengalí", - "languages.bih": "Bihari", - "languages.bis": "Bislama", - "languages.bos": "Bosnià", - "languages.bre": "Bretó", - "languages.bul": "Bulgar", - "languages.mya": "Birmà", - "languages.cat": "Català", - "languages.cha": "Chamorro", - "languages.che": "Chechen", - "languages.nya": "Chichewa", - "languages.zho": "Chinès", - "languages.chv": "Chuvash", - "languages.cor": "Cornish", - "languages.cos": "Corsican", - "languages.cre": "Cree", - "languages.hrv": "Croat", - "languages.ces": "Txec", - "languages.dan": "Danès", - "languages.div": "Divehi", - "languages.nld": "Holandès", - "languages.dzo": "Dzongkha", - "languages.eng": "Anglès", - "languages.epo": "Esperant", - "languages.est": "Estoni", - "languages.ewe": "Ewe", - "languages.fao": "Faroese", - "languages.fij": "Fijian", - "languages.fin": "Finlandès", - "languages.fra": "Francès", - "languages.ful": "Fula", - "languages.glg": "Gallec", - "languages.kat": "Georgià", - "languages.deu": "Alemany", - "languages.ell": "Grec", - "languages.egy": "Egipci (Antic)", - "languages.grn": "Guaraní", - "languages.guj": "Gujarati", - "languages.hat": "Haitià", - "languages.hau": "Hausa", - "languages.heb": "Hebreu", - "languages.her": "Herero", - "languages.hin": "Indi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Hungarià", - "languages.ina": "Interlingua", - "languages.ind": "Indonesian", - "languages.ile": "Interlingue", - "languages.gle": "Irlandès", - "languages.grc": "Grec, Antic (de 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Islandès", - "languages.ita": "Italià", - "languages.iku": "Inuktitut", - "languages.jpn": "Japonès", - "languages.jav": "Javanese", - "languages.kal": "Kalaallisut", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kashmiri", - "languages.kaz": "Kazakh", - "languages.khm": "Khmer", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kyrgyz", - "languages.kom": "Komi", - "languages.kon": "Kongo", - "languages.kor": "Coreà", - "languages.kur": "Kurd", - "languages.kua": "Kwanyama", - "languages.lat": "Latí", - "languages.ltz": "Luxemburguès", - "languages.lug": "Ganda", - "languages.lim": "Limburgish", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Lituà", - "languages.lub": "Luba-Katanga", - "languages.lav": "Latvian", - "languages.glv": "Manx", - "languages.mkd": "Macedoni", - "languages.mlg": "Malagasy", - "languages.msa": "Malay", - "languages.mal": "Malayalam", - "languages.mlt": "Maltès", - "languages.mri": "Maorí", - "languages.mar": "Marathi", - "languages.mah": "Marshallese", - "languages.mon": "Mongol", - "languages.nau": "Nauru", - "languages.nav": "Navajo", - "languages.nob": "Norwegian Bokmål", - "languages.nde": "North Ndebele", - "languages.nep": "Nepalí", - "languages.ndo": "Ndonga", - "languages.nno": "Norwegian Nynorsk", - "languages.nor": "Noruec", - "languages.iii": "Nuosu", - "languages.nbl": "South Ndebele", - "languages.oci": "Occità", - "languages.oji": "Ojibwe", - "languages.chu": "Old Church Slavonic", - "languages.orm": "Oromo", - "languages.ori": "Oriya", - "languages.oss": "Ossetian", - "languages.pan": "Panjabi", - "languages.pli": "Pāli", - "languages.fas": "Persa", - "languages.pol": "Polac", - "languages.pus": "Pashto", - "languages.por": "Portuguès", - "languages.que": "Quechua", - "languages.roh": "Romansh", - "languages.run": "Kirundi", - "languages.ron": "Romanià", - "languages.rus": "Rus", - "languages.sam": "Samaritan Aramaic", - "languages.san": "Sànscrit", - "languages.srd": "Sardinian", - "languages.snd": "Sindhi", - "languages.sme": "Northern Sami", - "languages.smo": "Samoan", - "languages.sag": "Sango", - "languages.srp": "Serbi", - "languages.gla": "Gaèlic escocès", - "languages.sna": "Shona", - "languages.sin": "Sinhala", - "languages.slk": "Eslovac", - "languages.slv": "Eslovè", - "languages.som": "Somalí", - "languages.sot": "Southern Sotho", - "languages.spa": "Espanyol", - "languages.sun": "Sundanese", - "languages.sux": "Sumerian", - "languages.swa": "Suahili", - "languages.ssw": "Swati", - "languages.swe": "Suec", - "languages.syc": "Sirià clàssic", - "languages.syr": "Sirià", - "languages.tam": "Tamil", - "languages.tel": "Telugu", - "languages.tgk": "Tajik", - "languages.tha": "Tailandès", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetan Standard", - "languages.tuk": "Turkmen", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tonga", - "languages.tur": "Turc", - "languages.tso": "Tsonga", - "languages.tat": "Tatar", - "languages.twi": "Twi", - "languages.tah": "Tahitian", - "languages.uga": "Ugaritic", - "languages.uig": "Uighur", - "languages.ukr": "Ukrainian", - "languages.urd": "Urdu", - "languages.uzb": "Uzbek", - "languages.ven": "Venda", - "languages.vie": "Vietnamita", - "languages.vol": "Volapük", - "languages.win": "Walloon", - "languages.cym": "Welsh", - "languages.wol": "Wolof", - "languages.fry": "Western Frisian", - "languages.xho": "Xhosa", - "languages.yid": "Yiddish", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_cs.json b/COPS/cops-3.1.3/lang/Localization_cs.json deleted file mode 100644 index abc90c27..00000000 --- a/COPS/cops-3.1.3/lang/Localization_cs.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "Více o COPS", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "Abecední seznam {0} knih", - "allbooks.alphabetical.none": "Abecední seznam neobsahuje žádné knihy", - "allbooks.alphabetical.one": "Abecední seznam obsahuje jednu knihu", - "allbooks.title": "Všechny knihy", - "authors.alphabetical.many": "Abecední seznam {0} autorů", - "authors.alphabetical.none": "Abecední seznam neobsahuje žádné autory", - "authors.alphabetical.one": "Abecední seznam obsahuje jednoho autora", - "authors.title": "Autoři", - "author.title": "Author", - "authorword.many": "{0} autorů", - "authorword.none": "Žádný autor", - "authorword.one": "Jeden autor", - "bookentry.author": "{0} z {1}", - "bookword.many": "{0} knih", - "bookword.none": "Žádná kniha", - "bookword.one": "Jedna kniha", - "bookword.title": "Knihy", - "cog.alternate": "Hledání, třídění a filtry", - "content.series": "Série:", - "content.series.data": "Kniha {0} ze série {1}", - "content.summary": "Shrnutí", - "customcolumn.boolean.no": "Ne", - "customcolumn.boolean.unknown": "Není nastaveno", - "customcolumn.boolean.yes": "Ano", - "customcolumn.date.format": "Rok-měsíc-den", - "customcolumn.date.unknown": "Není nastaveno", - "customcolumn.description": "Vlastní sloupec '{0}'", - "customcolumn.description.bool": "Seznam logických hodnot", - "customcolumn.description.enum.many": "Abecední seznam {0} položek", - "customcolumn.description.enum.none": "Abecední výpis neobsahuje žádné hodnoty", - "customcolumn.description.enum.one": "Abecední výpis obsahuje jednu hodnotu ", - "customcolumn.description.rating": "Seznam hodnocení", - "customcolumn.description.series.many": "Abecední výpis {0} sérií", - "customcolumn.description.series.none": "Abecední výpis neobsahuje žádné série", - "customcolumn.description.series.one": "Abecední výpis jedné série", - "customcolumn.enum.unknown": "Není nastaveno", - "customcolumn.float.unknown": "Není nastaveno", - "customcolumn.int.unknown": "Není nastaveno", - "customcolumn.rating.unknown": "Není nastaveno", - "customcolumn.stars.many": "{0} Hvězdiček", - "customcolumn.stars.none": "Bez hvězd", - "customcolumn.stars.one": "1 hvězda", - "customize.email": "Nastavit email (umožní zasílání knih)", - "customize.fancybox": "Použít Lightbox", - "customize.filter": "Povolit filtrování štítků", - "customize.ignored": "Ignorované kategorie", - "customize.paging": "Maximální počet knih na stránku (-1 pro vypnutí)", - "customize.style": "Téma", - "customize.template": "Template", - "customize.title": "Úpravy vzhledu COPS", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Smazat vše", - "filters.title": "Filters", - "home.alternate": "Domů", - "i18n.coversection": "Obálka", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Jazyk", - "languages.alphabetical.many": "Abecední seznam {0} jazyků", - "languages.alphabetical.none": "Abecední seznam neobsahuje žádné jazyky", - "languages.alphabetical.one": "Abecední seznam obsahuje jeden jazyk", - "languages.title": "Jazyky", - "links.title": "Odkazy", - "mail.messagenotsent": "Zprávu se nepodařilo odeslat.", - "mail.messagesent": "Zpráva byla odeslána", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "Další", - "paging.previous.alternate": "Předchozí", - "permalink.alternate": "Permalink", - "pubdate.title": "Published", - "publisher.name": "Vydavatel", - "publishers.alphabetical.many": "Abecední výpis {0} vydavatelů", - "publishers.alphabetical.none": "Abecední výpis neobsahuje žádné vydavetele", - "publishers.alphabetical.one": "Abecední výpis jednoho vydavetele", - "publishers.title": "Vydavatelé", - "publisherword.many": "{0} vydavatelů", - "publisherword.none": "Žádný vydavatel", - "publisherword.one": "Jeden vydavatel", - "ratings.many": "{0} hodnocení", - "ratings.none": "bez hodnocení", - "ratings.one": "1 hodnocení", - "ratings.title": "Hodnocení", - "rating.title": "Rating", - "ratingword.many": "{0} hvězd", - "ratingword.none": "Bez hvězd", - "ratingword.one": "1 hvězda", - "recent.list": "{0} posledních přidaných knih", - "recent.title": "Poslední přidané knihy", - "search.alternate": "Hledat", - "search.result": "Výsledek hledání pro *{0}*", - "search.result.author": "Výsledek hledání pro *{0}* mezi autory", - "search.result.book": "Výsledek hledání pro *{0}* mezi knihami", - "search.result.publisher": "Výsledek hledání pro *{0}* vydavateli", - "search.result.series": "Výsledek hledání pro *{0}* sériemi", - "search.result.tag": "Výsledek hledání pro *{0}* mezi štítky", - "search.sortorder.asc": "Vzestupně", - "search.sortorder.desc": "Sestupně", - "series.alphabetical.many": "Abecední výpis {0} sérií", - "series.alphabetical.none": "Abecední výpis neobsahuje žádné série", - "series.alphabetical.one": "Abecední výpis jedné série", - "series.title": "Série", - "seriesword.many": "{0} sérií", - "seriesword.none": "Žádné série", - "seriesword.one": "Jedna série", - "sort.alternate": "Třídit", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "Other books", - "splitByLetter.letter": "{0} knih začínajících na {1}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "Abecední výpis {0} štítků", - "tags.alphabetical.none": "Abecední výpis neobsahuje žádné štítky", - "tags.alphabetical.one": "Abecední výpis obsahuje jeden štítek", - "tags.title": "Štítky", - "tagword.many": "{0} štítků", - "tagword.none": "Žádné štítky", - "tagword.one": "Jeden štítek", - "tagword.title": "Štítky", - "title.title": "Title", - "languages.abk": "Abcházština", - "languages.aaf": "Afarština", - "languages.afr": "Afrikánština", - "languages.aka": "Akanština", - "languages.sqi": "Albánština", - "languages.amh": "Amharština", - "languages.ara": "Arabština", - "languages.arg": "Aragonština", - "languages.arc": "Aramejština", - "languages.hye": "Arménština", - "languages.asm": "Ásámština", - "languages.ava": "Avarština", - "languages.ave": "Avestánština", - "languages.aym": "Ajmarština", - "languages.aze": "Ázerbájdžánština", - "languages.bam": "Bambarština", - "languages.bak": "Baškirština", - "languages.eus": "Baskičtina", - "languages.bel": "Běloruština", - "languages.ben": "Bengálština", - "languages.bih": "Bihárština", - "languages.bis": "Bislamština", - "languages.bos": "Bosenština", - "languages.bre": "Bretonština", - "languages.bul": "Bulharština", - "languages.mya": "Barmština", - "languages.cat": "Katalánština", - "languages.cha": "Chamorro", - "languages.che": "Čečenština", - "languages.nya": "Čičevština", - "languages.zho": "Čínština", - "languages.chv": "Čuvaština", - "languages.cor": "Kornština", - "languages.cos": "Korsičtina", - "languages.cre": "Kríjština", - "languages.hrv": "Chorvatština", - "languages.ces": "Čeština", - "languages.dan": "Dánština", - "languages.div": "Divehi", - "languages.nld": "Nizozemština", - "languages.dzo": "Dzongkha", - "languages.eng": "Angličtina", - "languages.epo": "Esperanto", - "languages.est": "Estonština", - "languages.ewe": "Eveština", - "languages.fao": "Faerština", - "languages.fij": "Fidžijština", - "languages.fin": "Finština", - "languages.fra": "Francouština", - "languages.ful": "Fulbština", - "languages.glg": "Galicijština", - "languages.kat": "Gruzínština", - "languages.deu": "Němčina", - "languages.ell": "Řečtina", - "languages.egy": "Egyptština (starověká)", - "languages.grn": "Guaraní", - "languages.guj": "Gudžarátština", - "languages.hat": "Haitština", - "languages.hau": "Hauština", - "languages.heb": "Hebrejština", - "languages.her": "Hererština", - "languages.hin": "Hindština", - "languages.hmo": "Hiri motu", - "languages.hun": "Maďarština", - "languages.ina": "Interlingua", - "languages.ind": "Indonéština", - "languages.ile": "Interlingue", - "languages.gle": "Irština", - "languages.grc": "Řečtina (starověká, do 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Islandština", - "languages.ita": "Italština", - "languages.iku": "Inuitština", - "languages.jpn": "Japonština", - "languages.jav": "Javánština", - "languages.kal": "Grónština", - "languages.kan": "Kannadština", - "languages.kau": "Kanurijština", - "languages.kas": "Kašmírština", - "languages.kaz": "Kazaština", - "languages.khm": "Khmerština", - "languages.kik": "Kikujština", - "languages.kin": "Rwandština", - "languages.kir": "Kyrgyzština", - "languages.kom": "Komijština", - "languages.kon": "Konžština", - "languages.kor": "Korejština", - "languages.kur": "Kurdština", - "languages.kua": "Kuanyama", - "languages.lat": "Latina", - "languages.ltz": "Lucemburština", - "languages.lug": "Gandština", - "languages.lim": "Limburština", - "languages.lin": "Ngalština", - "languages.lao": "Laoština", - "languages.lit": "Litevština", - "languages.lub": "Lubština", - "languages.lav": "Lotyština", - "languages.glv": "Manština", - "languages.mkd": "Makedonština", - "languages.mlg": "Malgaština", - "languages.msa": "Malajština", - "languages.mal": "Malajámština", - "languages.mlt": "Maltština", - "languages.mri": "Maorština", - "languages.mar": "Maráthština", - "languages.mah": "Maršálština", - "languages.mon": "Mongolština", - "languages.nau": "Nauruština", - "languages.nav": "Navažština", - "languages.nob": "Bokmål", - "languages.nde": "Severní Ndebelština", - "languages.nep": "Nepálština", - "languages.ndo": "Ndonga", - "languages.nno": "Nynorsk", - "languages.nor": "Norština", - "languages.iii": "Yi", - "languages.nbl": "Jižní Ndebelština", - "languages.oci": "Okcitánština", - "languages.oji": "Odžibvejština", - "languages.chu": "Staroslověnština", - "languages.orm": "Oromština", - "languages.ori": "Urijština", - "languages.oss": "Osetština", - "languages.pan": "Paňdžábština", - "languages.pli": "Páli", - "languages.fas": "Perština", - "languages.pol": "Polština", - "languages.pus": "Paštština", - "languages.por": "Portugalština", - "languages.que": "Kečuánština", - "languages.roh": "Románština", - "languages.run": "Kirundština", - "languages.ron": "Rumunština", - "languages.rus": "Ruština", - "languages.sam": "Samaritánská aramejština", - "languages.san": "Sanskrt", - "languages.srd": "Sardština", - "languages.snd": "Sindhština", - "languages.sme": "Severní Sámština", - "languages.smo": "Samojština", - "languages.sag": "Sangština", - "languages.srp": "Srbština", - "languages.gla": "Skotská Gaelština", - "languages.sna": "Šonština", - "languages.sin": "Sinhálština", - "languages.slk": "Slovenština", - "languages.slv": "Slovinština", - "languages.som": "Somálština", - "languages.sot": "Sotština", - "languages.spa": "Španělština", - "languages.sun": "Sundština", - "languages.sux": "Sumerština", - "languages.swa": "Svahilština", - "languages.ssw": "Svazijština", - "languages.swe": "Švédština", - "languages.syc": "Původní syrština", - "languages.syr": "Syrština", - "languages.tam": "Tamilština", - "languages.tel": "Telugština", - "languages.tgk": "Tádžičtina", - "languages.tha": "Thajština", - "languages.tir": "Tigriňňa", - "languages.bod": "Tibetština", - "languages.tuk": "Turkmenština", - "languages.tgl": "Tagalština", - "languages.tsn": "Čwanština", - "languages.ton": "Tonžština", - "languages.tur": "Turečtina", - "languages.tso": "Tsonga", - "languages.tat": "Tatarština", - "languages.twi": "Ťwiština", - "languages.tah": "Tahitština", - "languages.uga": "Ugaritština", - "languages.uig": "Ujgurština", - "languages.ukr": "Ukrajinština", - "languages.urd": "Urdština", - "languages.uzb": "Uzbečtina", - "languages.ven": "Luvendština", - "languages.vie": "Vietnamština", - "languages.vol": "Volapük", - "languages.win": "Walonština", - "languages.cym": "Velština", - "languages.wol": "Volofština", - "languages.fry": "Západofríština", - "languages.xho": "Xhoština", - "languages.yid": "Jidiš", - "languages.yor": "Jorubština", - "languages.zha": "Čuangština", - "languages.zul": "Zulština", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_da.json b/COPS/cops-3.1.3/lang/Localization_da.json deleted file mode 100644 index 5f67245e..00000000 --- a/COPS/cops-3.1.3/lang/Localization_da.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "Om COPS", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "Alfabetisk index af {0} bøger", - "allbooks.alphabetical.none": "Alfabetisk index af absolut ingen bøger", - "allbooks.alphabetical.one": "Alfabetisk index af en enkelt bog", - "allbooks.title": "Alle bøger", - "authors.alphabetical.many": "Alfabetisk index af {0} forfattere", - "authors.alphabetical.none": "Alfabetisk index af absolut ingen forfattere", - "authors.alphabetical.one": "Alfabetiskl index af en enkelt forfatter", - "authors.title": "Forfattere", - "author.title": "Author", - "authorword.many": "{0} forfattere", - "authorword.none": "Ingen forfattere", - "authorword.one": "1 forfatter", - "bookentry.author": "{0} af {1}", - "bookword.many": "{0} bøger", - "bookword.none": "Ingen bøger", - "bookword.one": "1 bog", - "bookword.title": "Bøger", - "cog.alternate": "Søg, sorter og filtrer", - "content.series": "Serier:", - "content.series.data": "Bog {0} i {1} serien", - "content.summary": "Oversigt", - "customcolumn.boolean.no": "Nej", - "customcolumn.boolean.unknown": "Ikke sat", - "customcolumn.boolean.yes": "Ja", - "customcolumn.date.format": "Å-m-d", - "customcolumn.date.unknown": "Ikke sat", - "customcolumn.description": "Custom column '{0}'", - "customcolumn.description.bool": "Index af en sand/falsk værdi value", - "customcolumn.description.enum.many": "Alfabetisk index af {0} værdier", - "customcolumn.description.enum.none": "Alfabetisk index af absolt ingen værdier", - "customcolumn.description.enum.one": "Alfabetisk index af én værdi", - "customcolumn.description.rating": "Index af ratings", - "customcolumn.description.series.many": "Alfabetisk index af {0} serier", - "customcolumn.description.series.none": "Alfabetisk index af absolut ingen serier", - "customcolumn.description.series.one": "Alfabetisk index af en enkelt serie", - "customcolumn.enum.unknown": "Ikke sat", - "customcolumn.float.unknown": "Ikke sat", - "customcolumn.int.unknown": "Ikke sat", - "customcolumn.rating.unknown": "Ikke sat", - "customcolumn.stars.many": "{0} Stjerner", - "customcolumn.stars.none": "Ingen stjerner", - "customcolumn.stars.one": "1 Stjerne", - "customize.email": "Intast mailadresse (for at tillade at maile bøger)", - "customize.fancybox": "Brug Lightbox (bøger loader i flydende ramme)", - "customize.filter": "Tillad mærke filtrering", - "customize.ignored": "Ignorer kategorier", - "customize.paging": "Max antal bøger pr side (-1 for at slå fra)", - "customize.style": "Tema", - "customize.template": "Template", - "customize.title": "Indstil brugergrænseflade", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Slet alt", - "filters.title": "Filters", - "home.alternate": "Startside", - "i18n.coversection": "Cover", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Sprog", - "languages.alphabetical.many": "Alfabetisk index af {0} sprog", - "languages.alphabetical.none": "Alfabetisk index af absolut in sprog", - "languages.alphabetical.one": "Alfabetisk index af et enkelt sprog", - "languages.title": "Sprog", - "links.title": "Links", - "mail.messagenotsent": "Besked kunne ikke sendes.", - "mail.messagesent": "Besked er sendt", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "Næste", - "paging.previous.alternate": "Foregående", - "permalink.alternate": "Permalink", - "pubdate.title": "Published", - "publisher.name": "Forlag", - "publishers.alphabetical.many": "Alfabetisk index af {0} forlag", - "publishers.alphabetical.none": "Alfabetisk index af absolut ingen forlag", - "publishers.alphabetical.one": "Alfabetisk index af et enkelt forlag", - "publishers.title": "Forlag", - "publisherword.many": "{0} forlag", - "publisherword.none": "Ingen forlag", - "publisherword.one": "1 forlag", - "ratings.many": "{0} ratings", - "ratings.none": "ingen ratings", - "ratings.one": "1 rating", - "ratings.title": "Ratings", - "rating.title": "Rating", - "ratingword.many": "{0} stjerner", - "ratingword.none": "Ingen stjerner", - "ratingword.one": "1 stjerne", - "recent.list": "{0} seneste bøger", - "recent.title": "Seneste tilføjelser", - "search.alternate": "Søg", - "search.result": "Søgeresultat for *{0}*", - "search.result.author": "Søgeresultat for *{0}* i forfattere", - "search.result.book": "Søgeresultat for *{0}* i bøger", - "search.result.publisher": "Søgeresultat for *{0}* i forlag", - "search.result.series": "Søgeresutat for *{0}* i serier", - "search.result.tag": "Søgeresultat for *{0}* i mærker", - "search.sortorder.asc": "Stigende", - "search.sortorder.desc": "Faldende", - "series.alphabetical.many": "Alfabetisk index af {0} serier", - "series.alphabetical.none": "Alfabetisk index af absolut ingen serier", - "series.alphabetical.one": "Alfabertisk index af den eneste serie", - "series.title": "Serier", - "seriesword.many": "{0} serier", - "seriesword.none": "Ingen serier", - "seriesword.one": "1 serie", - "sort.alternate": "Sorter", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "Andre bøger", - "splitByLetter.letter": "{0} startende med {1}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "Alfabetisk index af {0} mærker", - "tags.alphabetical.none": "Alfabetisk index af absolut ingen mærker", - "tags.alphabetical.one": "Alfabetisk index af det eneste mærke", - "tags.title": "Mærker", - "tagword.many": "{0} mærker", - "tagword.none": "Ingen mærker", - "tagword.one": "1 mærke", - "tagword.title": "Mærker", - "title.title": "Title", - "languages.abk": "Abkhaz", - "languages.aaf": "Afar", - "languages.afr": "Afrikaans", - "languages.aka": "Akan", - "languages.sqi": "Albansk", - "languages.amh": "Amharic", - "languages.ara": "Arabisk", - "languages.arg": "Aragonese", - "languages.arc": "Aramaic", - "languages.hye": "Armensk", - "languages.asm": "Assamese", - "languages.ava": "Avaric", - "languages.ave": "Avestan", - "languages.aym": "Aymara", - "languages.aze": "Azerbaijani", - "languages.bam": "Bambara", - "languages.bak": "Bashkir", - "languages.eus": "Basque", - "languages.bel": "Belarusian", - "languages.ben": "Bengali", - "languages.bih": "Bihari", - "languages.bis": "Bislama", - "languages.bos": "Bosnisk", - "languages.bre": "Breton", - "languages.bul": "Bulgarisk", - "languages.mya": "Burmese", - "languages.cat": "Catalansk", - "languages.cha": "Chamorro", - "languages.che": "Chechen", - "languages.nya": "Chichewa", - "languages.zho": "Kinesisk", - "languages.chv": "Chuvash", - "languages.cor": "Cornish", - "languages.cos": "Corsican", - "languages.cre": "Cree", - "languages.hrv": "Croatian", - "languages.ces": "Czech", - "languages.dan": "Dansk", - "languages.div": "Divehi", - "languages.nld": "Hollandsk", - "languages.dzo": "Dzongkha", - "languages.eng": "Engelsk", - "languages.epo": "Esperanto", - "languages.est": "Estonian", - "languages.ewe": "Ewe", - "languages.fao": "Færøsk", - "languages.fij": "Fijian", - "languages.fin": "Finsk", - "languages.fra": "Fransk", - "languages.ful": "Fula", - "languages.glg": "Galician", - "languages.kat": "Georgian", - "languages.deu": "Tysk", - "languages.ell": "Græsk", - "languages.egy": "Egyptian (Ancient)", - "languages.grn": "Guaraní", - "languages.guj": "Gujarati", - "languages.hat": "Haitian", - "languages.hau": "Hausa", - "languages.heb": "Hebrew", - "languages.her": "Herero", - "languages.hin": "Hindi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Hungarian", - "languages.ina": "Interlingua", - "languages.ind": "Indonesian", - "languages.ile": "Interlingue", - "languages.gle": "Irish", - "languages.grc": "Græsk, Oldgræsk (to 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Islandsk", - "languages.ita": "Italian", - "languages.iku": "Inuktitut", - "languages.jpn": "Japanese", - "languages.jav": "Javanese", - "languages.kal": "Kalaallisut", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kashmiri", - "languages.kaz": "Kazakh", - "languages.khm": "Khmer", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kyrgyz", - "languages.kom": "Komi", - "languages.kon": "Kongo", - "languages.kor": "Koreansk", - "languages.kur": "Kurdisk", - "languages.kua": "Kwanyama", - "languages.lat": "Latin", - "languages.ltz": "Luxembourgish", - "languages.lug": "Ganda", - "languages.lim": "Limburgish", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Lithuanian", - "languages.lub": "Luba-Katanga", - "languages.lav": "Latvian", - "languages.glv": "Manx", - "languages.mkd": "Macedonian", - "languages.mlg": "Malagasy", - "languages.msa": "Malay", - "languages.mal": "Malayalam", - "languages.mlt": "Maltese", - "languages.mri": "Māori", - "languages.mar": "Marathi", - "languages.mah": "Marshallese", - "languages.mon": "Mongolian", - "languages.nau": "Nauru", - "languages.nav": "Navajo", - "languages.nob": "Norsk Bokmål", - "languages.nde": "North Ndebele", - "languages.nep": "Nepali", - "languages.ndo": "Ndonga", - "languages.nno": "Norsk Nynorsk", - "languages.nor": "Norsk", - "languages.iii": "Nuosu", - "languages.nbl": "South Ndebele", - "languages.oci": "Occitan", - "languages.oji": "Ojibwe", - "languages.chu": "Old Church Slavonic", - "languages.orm": "Oromo", - "languages.ori": "Oriya", - "languages.oss": "Ossetian", - "languages.pan": "Panjabi", - "languages.pli": "Pāli", - "languages.fas": "Persian", - "languages.pol": "Polish", - "languages.pus": "Pashto", - "languages.por": "Portuguese", - "languages.que": "Quechua", - "languages.roh": "Romansh", - "languages.run": "Kirundi", - "languages.ron": "Romanian", - "languages.rus": "Russian", - "languages.sam": "Samaritan Aramaic", - "languages.san": "Sanskrit", - "languages.srd": "Sardinian", - "languages.snd": "Sindhi", - "languages.sme": "Northern Sami", - "languages.smo": "Samoan", - "languages.sag": "Sango", - "languages.srp": "Serbisk", - "languages.gla": "Scottish Gaelic", - "languages.sna": "Shona", - "languages.sin": "Sinhala", - "languages.slk": "Slovak", - "languages.slv": "Slovene", - "languages.som": "Somali", - "languages.sot": "Southern Sotho", - "languages.spa": "Spanish", - "languages.sun": "Sundanese", - "languages.sux": "Sumerian", - "languages.swa": "Swahili", - "languages.ssw": "Swati", - "languages.swe": "Svensk", - "languages.syc": "Classical Syriac", - "languages.syr": "Syriac", - "languages.tam": "Tamilsk", - "languages.tel": "Telugu", - "languages.tgk": "Tajik", - "languages.tha": "Thai", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetan Standard", - "languages.tuk": "Turkmen", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tonga", - "languages.tur": "Turkish", - "languages.tso": "Tsonga", - "languages.tat": "Tatar", - "languages.twi": "Twi", - "languages.tah": "Tahitian", - "languages.uga": "Ugaritic", - "languages.uig": "Uighur", - "languages.ukr": "Ukrainian", - "languages.urd": "Urdu", - "languages.uzb": "Uzbek", - "languages.ven": "Venda", - "languages.vie": "Vietnamese", - "languages.vol": "Volapük", - "languages.win": "Walloon", - "languages.cym": "Welsh", - "languages.wol": "Wolof", - "languages.fry": "Western Frisian", - "languages.xho": "Xhosa", - "languages.yid": "Yiddish", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_de.json b/COPS/cops-3.1.3/lang/Localization_de.json deleted file mode 100644 index 831016fa..00000000 --- a/COPS/cops-3.1.3/lang/Localization_de.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "Über COPS", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "Alphabetischer Index der {0} Bücher", - "allbooks.alphabetical.none": "Alphabetischer Index von absolut keinem Buch", - "allbooks.alphabetical.one": "Alphabetischer Index des einzigen Buchs", - "allbooks.title": "Alle Bücher", - "authors.alphabetical.many": "Alphabetischer Index der {0} Autoren", - "authors.alphabetical.none": "Alphabetischer Index von absolut keinem Autor", - "authors.alphabetical.one": "Alphabetischer Index des einzigen Autors", - "authors.title": "Autoren", - "author.title": "Author", - "authorword.many": "{0} Autoren", - "authorword.none": "Kein Autor", - "authorword.one": "1 Autor", - "bookentry.author": "{0} von {1}", - "bookword.many": "{0} Bücher", - "bookword.none": "Kein Buch", - "bookword.one": "1 Buch", - "bookword.title": "Bücher", - "cog.alternate": "Suche, Sortierung und Filter", - "content.series": "Serien:", - "content.series.data": "Buch {0} der {1} - Reihe", - "content.summary": "Inhalt", - "customcolumn.boolean.no": "Nein", - "customcolumn.boolean.unknown": "Nicht gesetzt", - "customcolumn.boolean.yes": "Ja", - "customcolumn.date.format": "d.m.Y", - "customcolumn.date.unknown": "Nicht gesetzt", - "customcolumn.description": "Bentzerdefinierte Spalte '{0}", - "customcolumn.description.bool": "Index eines Wahrheitswertes", - "customcolumn.description.enum.many": "Alphabetischer Index der {0} Werte", - "customcolumn.description.enum.none": "Alphabetischer Index von absolut keinen Werten", - "customcolumn.description.enum.one": "Alphabetischer Index von einem Wert", - "customcolumn.description.rating": "Index von Bewertungen", - "customcolumn.description.series.many": "Alphabetischer Index der {0} Serien", - "customcolumn.description.series.none": "Alphabetischer Index von absolut keinen Serien", - "customcolumn.description.series.one": "Alphabetischer Index der einzigen Serie", - "customcolumn.enum.unknown": "Nicht gesetzt", - "customcolumn.float.unknown": "Nicht gesetzt", - "customcolumn.int.unknown": "Nicht gesetzt", - "customcolumn.rating.unknown": "Nicht gesetzt", - "customcolumn.stars.many": "{0} Sterne", - "customcolumn.stars.none": "Kein Stern", - "customcolumn.stars.one": "1 Stern", - "customize.email": "Geben Sie Ihre E-Mail-Adresse an (erlaubt das Zusenden von Büchern)", - "customize.fancybox": "Benutze die Lightbox", - "customize.filter": "Erlaube das Filtern nach Stichworten", - "customize.ignored": "Nicht verwendete Kategorien", - "customize.paging": "Maximale Anzahl von Büchern pro Seite (-1 zum Deaktivieren)", - "customize.style": "Thema", - "customize.template": "Template", - "customize.title": "Anpassungen an COPS", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Alle Markierungen entfernen", - "filters.title": "Filters", - "home.alternate": "Startseite", - "i18n.coversection": "Umschlag", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Sprache", - "languages.alphabetical.many": "Alphabetischer Index der {0} Sprachen", - "languages.alphabetical.none": "Alphabetischer Index von absolut keiner Sprache", - "languages.alphabetical.one": "Alphabetischer Index der einzigen Sprache", - "languages.title": "Sprachen", - "links.title": "Links", - "mail.messagenotsent": "E-Mail konnte nicht gesendet werden.", - "mail.messagesent": "E-Mail wurde gesendet.", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "Nächste", - "paging.previous.alternate": "Vorherige", - "permalink.alternate": "Permalink", - "pubdate.title": "Published", - "publisher.name": "Verlag", - "publishers.alphabetical.many": "Alphabetischer Index der {0} Verlage", - "publishers.alphabetical.none": "Alphabetischer Index von absolut keinem Verlag", - "publishers.alphabetical.one": "Alphabetischer Index des einzigen Verlags", - "publishers.title": "Verlage", - "publisherword.many": "{0} Verlage", - "publisherword.none": "Kein Verlag", - "publisherword.one": "1 Verlag", - "ratings.many": "{0} verschiedene Bewertungen", - "ratings.none": "Keine Bewertungen", - "ratings.one": "{0} Bewertung", - "ratings.title": "Bewertung", - "rating.title": "Rating", - "ratingword.many": "{0} Sterne", - "ratingword.none": "{0} Sterne", - "ratingword.one": "{0} Stern", - "recent.list": "{0} neue Bücher", - "recent.title": "Neuzugänge", - "search.alternate": "Suche", - "search.result": "Suchergebnis für", - "search.result.author": "Suchergebnis für *{0}* in Autoren", - "search.result.book": "Suchergebnis für *{0}* in Bücher", - "search.result.publisher": "Suchergebnis für *{0}* in Verlage", - "search.result.series": "Suchergebnis für *{0}* in Serien", - "search.result.tag": "Suchergebnis für *{0}* in Schlagwörter", - "search.sortorder.asc": "Auf", - "search.sortorder.desc": "Ab", - "series.alphabetical.many": "Alphabetischer Index der {0} Serien", - "series.alphabetical.none": "Alphabetischer Index von absolut keiner Serie", - "series.alphabetical.one": "Alphabetischer Index der Serie", - "series.title": "Serien", - "seriesword.many": "{0} Serien", - "seriesword.none": "Keine Serie", - "seriesword.one": "1 Serie", - "sort.alternate": "Sortierung", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "Andere Bücher", - "splitByLetter.letter": "{0} unter {1}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "Alphabetischer Index der {0} Schlagwörter", - "tags.alphabetical.none": "Alphabetischer Index von absolut keinem Schlagwort", - "tags.alphabetical.one": "Alphabetischer Index des Schlagworts", - "tags.title": "Schlagwörter", - "tagword.many": "{0} Schlagwörter", - "tagword.none": "Kein Schlagwort", - "tagword.one": "1 Schlagwort", - "tagword.title": "Schlagwörter", - "title.title": "Title", - "languages.abk": "Abchasisch", - "languages.aaf": "Afar", - "languages.afr": "Afrikaans", - "languages.aka": "Akan", - "languages.sqi": "Albanisch", - "languages.amh": "Amharisch", - "languages.ara": "Arabisch", - "languages.arg": "Aragonisch", - "languages.arc": "Aramäisch", - "languages.hye": "Armenisch", - "languages.asm": "Assamesisch", - "languages.ava": "Awarisch", - "languages.ave": "Avestisch", - "languages.aym": "Aymara", - "languages.aze": "Aserbaidschanisch", - "languages.bam": "Bambara", - "languages.bak": "Baschkirisch", - "languages.eus": "Baskisch", - "languages.bel": "Weissrussisch", - "languages.ben": "Bengalisch", - "languages.bih": "Biharisch", - "languages.bis": "Bislamisch", - "languages.bos": "Bosnisch", - "languages.bre": "Bretonisch", - "languages.bul": "Bulgarisch", - "languages.mya": "Burmesisch", - "languages.cat": "Katalanisch", - "languages.cha": "Chamorro", - "languages.che": "Tschetschenisch", - "languages.nya": "Chichewa", - "languages.zho": "Chinesisch", - "languages.chv": "Tschuwaschisch", - "languages.cor": "Kornisch", - "languages.cos": "Korsisch", - "languages.cre": "Cree", - "languages.hrv": "Kroatisch", - "languages.ces": "Tschechisch", - "languages.dan": "Dänisch", - "languages.div": "Divehi", - "languages.nld": "Niederländisch", - "languages.dzo": "Dzongkha", - "languages.eng": "Englisch", - "languages.epo": "Esperanto", - "languages.est": "Estisch", - "languages.ewe": "Ewe", - "languages.fao": "Färöisch", - "languages.fij": "Fidschi", - "languages.fin": "Finnisch", - "languages.fra": "Französisch", - "languages.ful": "Fulfulde", - "languages.glg": "Galizisch", - "languages.kat": "Georgisch", - "languages.deu": "Deutsch", - "languages.ell": "Griechisch", - "languages.egy": "Altägyptisch", - "languages.grn": "Guaraní", - "languages.guj": "Gujarati", - "languages.hat": "Haitianisch", - "languages.hau": "Haussa", - "languages.heb": "Hebräisch", - "languages.her": "Herero", - "languages.hin": "Hindi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Ungarisch", - "languages.ina": "Interlingua", - "languages.ind": "Indonesisch", - "languages.ile": "Interlingue", - "languages.gle": "Irisch", - "languages.grc": "Altgriechisch (bis 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Isländisch", - "languages.ita": "Italienisch", - "languages.iku": "Inuktitut (Eskimo)", - "languages.jpn": "Japanisch", - "languages.jav": "Javanisch", - "languages.kal": "Kalaallisut (Grönländisch)", - "languages.kan": "Kanarisch", - "languages.kau": "Kanuri", - "languages.kas": "Kaschmirisch", - "languages.kaz": "Kasachisch", - "languages.khm": "Kambodschanisch", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kirgisisch", - "languages.kom": "Komi", - "languages.kon": "Kongolesisch", - "languages.kor": "Koreanisch", - "languages.kur": "Kurdisch", - "languages.kua": "Oshivambo", - "languages.lat": "Lateinisch", - "languages.ltz": "Luxemburgisch", - "languages.lug": "Luganda", - "languages.lim": "Limburgisch", - "languages.lin": "Lingála", - "languages.lao": "Laotisch", - "languages.lit": "Litauisch", - "languages.lub": "Kiluba", - "languages.lav": "Lettisch", - "languages.glv": "Manx", - "languages.mkd": "Mazedonisch", - "languages.mlg": "Malagasy", - "languages.msa": "Malaiisch", - "languages.mal": "Malaysisch", - "languages.mlt": "Maltesisch", - "languages.mri": "Maorisch", - "languages.mar": "Marathi", - "languages.mah": "Marshallesisch", - "languages.mon": "Mongolisch", - "languages.nau": "Nauruisch", - "languages.nav": "Navajo", - "languages.nob": "Norwegisch (Bokmål)", - "languages.nde": "Nord-Ndebele", - "languages.nep": "Nepalesisch", - "languages.ndo": "Ndonga", - "languages.nno": "Norwegisch (Nynorsk)", - "languages.nor": "Norwegisch", - "languages.iii": "Yiyu", - "languages.nbl": "Süd-Ndebele", - "languages.oci": "Okzitanisch", - "languages.oji": "Ojibwe", - "languages.chu": "Altkirchenslawisch", - "languages.orm": "Oromo", - "languages.ori": "Oriya", - "languages.oss": "Ossetisch", - "languages.pan": "Punjabisch", - "languages.pli": "Pali", - "languages.fas": "Persisch", - "languages.pol": "Polnisch", - "languages.pus": "Pashtu", - "languages.por": "Portugisisch", - "languages.que": "Quechua", - "languages.roh": "Bündnerromanisch", - "languages.run": "Kirundisch", - "languages.ron": "Rumänisch", - "languages.rus": "Russisch", - "languages.sam": "Samaritanisches Aramäisch", - "languages.san": "Sanskrit", - "languages.srd": "Sardisch", - "languages.snd": "Sindhi", - "languages.sme": "Nordsamisch", - "languages.smo": "Samoanisch", - "languages.sag": "Sango", - "languages.srp": "Serbisch", - "languages.gla": "Schottisches Gälisch", - "languages.sna": "Schonisch", - "languages.sin": "Singhalesisch", - "languages.slk": "Slowakisch", - "languages.slv": "Slowenisch", - "languages.som": "Somalisch", - "languages.sot": "Sesotho", - "languages.spa": "Spanisch", - "languages.sun": "Sundanesisch", - "languages.sux": "Sumerisch", - "languages.swa": "Kisuaheli", - "languages.ssw": "Siswati", - "languages.swe": "Schwedisch", - "languages.syc": "Altsyrisch", - "languages.syr": "Syrisch", - "languages.tam": "Tamilisch", - "languages.tel": "Telugisch", - "languages.tgk": "Tadschikisch", - "languages.tha": "Thai", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetisch", - "languages.tuk": "Turkmenisch", - "languages.tgl": "Tagalog", - "languages.tsn": "Setswana", - "languages.ton": "Tongaisch", - "languages.tur": "Türkisch", - "languages.tso": "Tsongaisch", - "languages.tat": "Tatarisch", - "languages.twi": "Twi", - "languages.tah": "Tahitianisch", - "languages.uga": "Ugaritisch", - "languages.uig": "Uigur", - "languages.ukr": "Ukrainisch", - "languages.urd": "Urdu", - "languages.uzb": "Usbekisch", - "languages.ven": "Tshivenda", - "languages.vie": "Vietnamesisch", - "languages.vol": "Volapük", - "languages.win": "Wallonisch", - "languages.cym": "Walisisch", - "languages.wol": "Wolof", - "languages.fry": "Westfriesisch", - "languages.xho": "IsiXhosa", - "languages.yid": "Yi (Jiddisch)", - "languages.yor": "Joruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_el.json b/COPS/cops-3.1.3/lang/Localization_el.json deleted file mode 100644 index fc5e87ea..00000000 --- a/COPS/cops-3.1.3/lang/Localization_el.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "Σχετικά με COPS", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "Αλφαβητικό ευρετήριο των {0} βιβλίων", - "allbooks.alphabetical.none": "Αλφαβητικός κατάλογος από απολύτως κανένα βιβλίο", - "allbooks.alphabetical.one": "Αλφαβητικό ευρετήριο του μοναδικού βιβλίου", - "allbooks.title": "Όλα τα βιβλία", - "authors.alphabetical.many": "Αλφαβητικό ευρετήριο των {0} συγγραφέων", - "authors.alphabetical.none": "Αλφαβητικός κατάλογος από απολύτως κανένα συγγραφέα", - "authors.alphabetical.one": "Αλφαβητικό ευρετήριο του μοναδικού συγγραφέα", - "authors.title": "Συγγραφείς", - "author.title": "Author", - "authorword.many": "{0} συγγραφείς", - "authorword.none": "Χωρίς συγγραφείς", - "authorword.one": "1 συγγραφέας", - "bookentry.author": "{0} από {1}", - "bookword.many": "{0} βιβλία", - "bookword.none": "Δεν υπάρχουν βιβλία", - "bookword.one": "1 βιβλίο", - "bookword.title": "Βιβλία", - "cog.alternate": "Αναζήτηση, ταξινόμηση και φίλτρα", - "content.series": "Σειρά:", - "content.series.data": "Βιβλίο {0} από την σειρά {1}", - "content.summary": "Περίληψη", - "customcolumn.boolean.no": "Όχι", - "customcolumn.boolean.unknown": "Προεπιλογή", - "customcolumn.boolean.yes": "Ναι", - "customcolumn.date.format": "d-m-Y", - "customcolumn.date.unknown": "Προεπιλογή", - "customcolumn.description": "Προσαρμοσμένη στήλη '{0}'", - "customcolumn.description.bool": "Ευρετήριο από τιμές boolean", - "customcolumn.description.enum.many": "Αλφαβητικό ευρετήριο των {0} τιμών", - "customcolumn.description.enum.none": "Αλφαβητικό ευρετήριο από καμία απολύτως τιμή", - "customcolumn.description.enum.one": "Αλφαβητικό ευρετήριο μιας τιμής", - "customcolumn.description.rating": "Ευρετήριο αξιολογήσεων", - "customcolumn.description.series.many": "Αλφαβητικό ευρετήριο των {0} σειρών", - "customcolumn.description.series.none": "Αλφαβητικός κατάλογος από απολύτως καμία σειρά", - "customcolumn.description.series.one": "Αλφαβητικό ευρετήριο της μοναδικής σειράς", - "customcolumn.enum.unknown": "Προεπιλογή", - "customcolumn.float.unknown": "Προεπιλογή", - "customcolumn.int.unknown": "Προεπιλογή", - "customcolumn.rating.unknown": "Προεπιλογή", - "customcolumn.stars.many": "{0} Αστέρια", - "customcolumn.stars.none": "Χωρίς Αστέρι", - "customcolumn.stars.one": "1 Αστέρι", - "customize.email": "Ρυθμίστε το email σας (για να επιτραπεί αποστολή email)", - "customize.fancybox": "Χρήση Lightbox (τα βιβλία φορτώνουν σε πλαίσιο)", - "customize.filter": "Ενεργοποίηση φιλτραρίσματος ανά ετικέτα", - "customize.ignored": "Αγνοείστε κατηγορίες", - "customize.paging": "Μέγιστος αριθμός βιβλίων ανά σελίδα (-1 για απενεργοποίηση)", - "customize.style": "Θέμα", - "customize.template": "Template", - "customize.title": "Προσαρμογή COPS UI", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Εκκαθάριση Όλων", - "filters.title": "Filters", - "home.alternate": "Αρχική", - "i18n.coversection": "Εξώφυλλο", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Γλώσσα", - "languages.alphabetical.many": "Αλφαβητικό ευρετήριο των {0} γλωσσών", - "languages.alphabetical.none": "Αλφαβητικός κατάλογος από απολύτως καμία γλώσσες", - "languages.alphabetical.one": "Αλφαβητικό ευρετήριο της μοναδικής γλώσσας", - "languages.title": "Γλώσσες", - "links.title": "Σύνδεσμοι", - "mail.messagenotsent": "Το μήνυμα δεν μπόρεσε να σταλεί.", - "mail.messagesent": "Το μήνυμα εστάλη", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "Επόμενος", - "paging.previous.alternate": "Προηγούμενος", - "permalink.alternate": "Μόνιμος σύνδεσμος", - "pubdate.title": "Published", - "publisher.name": "Εκδότης", - "publishers.alphabetical.many": "Αλφαβητικό ευρετήριο από {0} εκδότες", - "publishers.alphabetical.none": "Αλφαβητικός κατάλογος από απολύτως κανένα εκδότη", - "publishers.alphabetical.one": "Αλφαβητικό ευρετήριο του μοναδικού εκδότη", - "publishers.title": "Εκδότες", - "publisherword.many": "{0} εκδότες", - "publisherword.none": "Δεν υπάρχουν εκδότες", - "publisherword.one": "1 εκδότης", - "ratings.many": "{0} αξιολογήσεις", - "ratings.none": "Δεν υπάρχουν αξιολογήσεις", - "ratings.one": "1 αξιολόγηση", - "ratings.title": "Αξιολογήσεις", - "rating.title": "Rating", - "ratingword.many": "{0} αστέρια", - "ratingword.none": "Χωρίς αστέρι", - "ratingword.one": "1 αστέρι", - "recent.list": "{0} πιο πρόσφατα βιβλία", - "recent.title": "Πρόσφατες προσθήκες", - "search.alternate": "Αναζήτηση", - "search.result": "Αποτέλεσμα αναζήτησης για * {0} *", - "search.result.author": "Αποτέλεσμα αναζήτησης για * {0} * σε συγγραφείς", - "search.result.book": "Αποτέλεσμα αναζήτησης για * {0} * στα βιβλία", - "search.result.publisher": "Αποτέλεσμα αναζήτησης για * {0} * σε εκδότες", - "search.result.series": "Αποτέλεσμα αναζήτησης για * {0} * σε σειρά", - "search.result.tag": "Αποτέλεσμα αναζήτησης για * {0} * σε ετικέτες", - "search.sortorder.asc": "Αυξ", - "search.sortorder.desc": "Φθιν", - "series.alphabetical.many": "Αλφαβητικό ευρετήριο των {0} σειρών", - "series.alphabetical.none": "Αλφαβητικός κατάλογος από απολύτως καμία σειρά", - "series.alphabetical.one": "Αλφαβητικό ευρετήριο της μοναδικής σειράς", - "series.title": "Σειρά", - "seriesword.many": "{0} σειρά", - "seriesword.none": "Χωρίς σειρά", - "seriesword.one": "Σειρά 1", - "sort.alternate": "Ταξινόμηση", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "Άλλα βιβλία", - "splitByLetter.letter": "{0} ξεκινά με {1}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "Αλφαβητικό ευρετήριο των {0} ετικετών", - "tags.alphabetical.none": "Αλφαβητικός κατάλογος από απολύτως καμία ετικέτες", - "tags.alphabetical.one": "Αλφαβητικό ευρετήριο της μοναδικής ετικέτας", - "tags.title": "Ετικέτες", - "tagword.many": "{0} ετικέτες", - "tagword.none": "Δεν υπάρχουν ετικέτες", - "tagword.one": "1 ετικέτα", - "tagword.title": "Ετικέτες", - "title.title": "Title", - "languages.abk": "Αμπχαζίας", - "languages.aaf": "Αφάρ", - "languages.afr": "Αφρικάνικα", - "languages.aka": "Akan", - "languages.sqi": "Αλβανικά", - "languages.amh": "Αμαρικά", - "languages.ara": "Αραβικά", - "languages.arg": "Αραγονίας", - "languages.arc": "Aramaic", - "languages.hye": "Αρμενικός", - "languages.asm": "Ασαμέζικα", - "languages.ava": "Avaric", - "languages.ave": "Avestan", - "languages.aym": "Aymara", - "languages.aze": "Αζερμπαϊτζάν", - "languages.bam": "Μπαμπάρα", - "languages.bak": "Μπασκίρ", - "languages.eus": "Βάσκων", - "languages.bel": "Λευκορωσίας", - "languages.ben": "Βεγγαλική", - "languages.bih": "Μπιχάρι", - "languages.bis": "Μπισλάμα", - "languages.bos": "Βοσνιακά", - "languages.bre": "Breton", - "languages.bul": "Βούλγαρος", - "languages.mya": "Βιρμανίας", - "languages.cat": "Καταλανικά", - "languages.cha": "Chamorro", - "languages.che": "Της Τσετσενίας", - "languages.nya": "Chichewa", - "languages.zho": "Κινέζικα", - "languages.chv": "Χουβάς", - "languages.cor": "Cornish", - "languages.cos": "Κορσικανός", - "languages.cre": "Κρι", - "languages.hrv": "Κροατία", - "languages.ces": "Τσέχος", - "languages.dan": "Δανός", - "languages.div": "Ντιβέχι", - "languages.nld": "Ολλανδός", - "languages.dzo": "Dzongkha", - "languages.eng": "Αγγλικά", - "languages.epo": "Εσπεράντο", - "languages.est": "Εσθονική", - "languages.ewe": "Προβατίνα", - "languages.fao": "Των Νήσων Φερόε", - "languages.fij": "Φίτζι", - "languages.fin": "Φινλανδικά", - "languages.fra": "Γαλλικά", - "languages.ful": "Fula", - "languages.glg": "Γαλικίας", - "languages.kat": "Γεωργιανά", - "languages.deu": "Γερμανός", - "languages.ell": "Ελληνικά", - "languages.egy": "Egyptian (Ancient)", - "languages.grn": "Γκουαρανί", - "languages.guj": "Γκουτζαρατικά", - "languages.hat": "Αϊτής", - "languages.hau": "Χάουσα", - "languages.heb": "Εβραϊκά", - "languages.her": "Herero", - "languages.hin": "Χίντι", - "languages.hmo": "Hiri Motu", - "languages.hun": "Ούγγρος", - "languages.ina": "Ιντερλίνγκουα", - "languages.ind": "Ινδονησίας", - "languages.ile": "Ιντερλίνγκουε", - "languages.gle": "Ιρλανδικός", - "languages.grc": "Greek, Ancient (to 1453)", - "languages.ibo": "Ίγκμπο", - "languages.ipk": "Ινουπιάκ", - "languages.ido": "Ιντο", - "languages.isl": "Ισλανδικός", - "languages.ita": "Ιταλικά", - "languages.iku": "Ινουκτιτούτ", - "languages.jpn": "Ιαπωνικά", - "languages.jav": "Ιάβας", - "languages.kal": "Kalaallisut", - "languages.kan": "Κανάντα", - "languages.kau": "Κανούρι", - "languages.kas": "Κασμίρ", - "languages.kaz": "Του Καζακστάν", - "languages.khm": "Χμερ", - "languages.kik": "Κικούγιου", - "languages.kin": "Kinyarwanda", - "languages.kir": "Κιργιζίας", - "languages.kom": "Κώμη", - "languages.kon": "Kongo", - "languages.kor": "Κορέατικα", - "languages.kur": "Κουρδικά", - "languages.kua": "Kwanyama", - "languages.lat": "Λατινικά", - "languages.ltz": "Λουξεμβούργου", - "languages.lug": "Ganda", - "languages.lim": "Λιμβουργιανά", - "languages.lin": "Lingala", - "languages.lao": "Λάος", - "languages.lit": "Λιθουανικά", - "languages.lub": "Λούμπα-Κατάνγκα", - "languages.lav": "Της Λετονίας", - "languages.glv": "Μανξ", - "languages.mkd": "ΦΥΡΟΜ", - "languages.mlg": "Μαδαγασκάρης", - "languages.msa": "Μαλαισίας", - "languages.mal": "Μαλαγιάλαμ", - "languages.mlt": "Της Μάλτας", - "languages.mri": "Μαορί", - "languages.mar": "Μαράθι", - "languages.mah": "Μάρσαλ", - "languages.mon": "Μογγόλος", - "languages.nau": "Ναουρού", - "languages.nav": "Navajo", - "languages.nob": "Νορβηγικά", - "languages.nde": "Βόρεια Ντέμπελε", - "languages.nep": "Νεπάλ", - "languages.ndo": "Ndonga", - "languages.nno": "Νορβηγικά Νινόρσκ", - "languages.nor": "Νορβηγός", - "languages.iii": "Nuosu", - "languages.nbl": "Ισλανδική γλώσσα", - "languages.oci": "Occitan", - "languages.oji": "Ojibwe", - "languages.chu": "Παλιά εκκλησιαστική σλαβονική", - "languages.orm": "Ορόμο", - "languages.ori": "Οριγικά", - "languages.oss": "Οσετίας", - "languages.pan": "Panjabi", - "languages.pli": "Pāli", - "languages.fas": "Πέρσης", - "languages.pol": "Πολωνός", - "languages.pus": "Πάστο", - "languages.por": "Πορτογάλος", - "languages.que": "Κέτσουα", - "languages.roh": "Ρωμανικά", - "languages.run": "Kirundi", - "languages.ron": "Ρουμανικός", - "languages.rus": "Ρωσικός", - "languages.sam": "Samaritan Aramaic", - "languages.san": "Σανσκριτικά", - "languages.srd": "Σαρδηνίας", - "languages.snd": "Σίντι", - "languages.sme": "Βόρεια Σάμι", - "languages.smo": "Σαμόα", - "languages.sag": "Σάνγκο", - "languages.srp": "Σέρβικα", - "languages.gla": "Scottish Gaelic", - "languages.sna": "Σόνα", - "languages.sin": "Sinhala", - "languages.slk": "Σλοβάκος", - "languages.slv": "Σλοβενικά", - "languages.som": "Της Σομαλίας", - "languages.sot": "Νότια Σόθο", - "languages.spa": "Ισπανικά", - "languages.sun": "Σουδανικά", - "languages.sux": "Sumerian", - "languages.swa": "Σουαχίλι", - "languages.ssw": "Swati", - "languages.swe": "Σουηδικά", - "languages.syc": "Classical Syriac", - "languages.syr": "Syriac", - "languages.tam": "Ταμίλ", - "languages.tel": "Τελούγκου", - "languages.tgk": "Τατζικιστάν", - "languages.tha": "Ταϊλάνδης", - "languages.tir": "Τιγκρινιανά", - "languages.bod": "Θιβετιανά κανονικά", - "languages.tuk": "Τουρκμενιστάν", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Τόνγκα", - "languages.tur": "Τουρκική", - "languages.tso": "Τσόνγκα", - "languages.tat": "Ταταρικά", - "languages.twi": "Twi", - "languages.tah": "Tahitian", - "languages.uga": "Ugaritic", - "languages.uig": "Ουιγούρων", - "languages.ukr": "Ουκρανός", - "languages.urd": "Ούρντου", - "languages.uzb": "Ουζμπεκιστάν", - "languages.ven": "Venda", - "languages.vie": "Βιετνάμ", - "languages.vol": "Βόλαπικ", - "languages.win": "Βαλλονίας", - "languages.cym": "Ουαλίας", - "languages.wol": "Γουόλοφ", - "languages.fry": "Δυτικά Φριζιανά", - "languages.xho": "Xhosa", - "languages.yid": "Γίντις", - "languages.yor": "Γιορούμπα", - "languages.zha": "Zhuang", - "languages.zul": "Ζουλού", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_en.json b/COPS/cops-3.1.3/lang/Localization_en.json deleted file mode 100644 index 65a872b6..00000000 --- a/COPS/cops-3.1.3/lang/Localization_en.json +++ /dev/null @@ -1,333 +0,0 @@ -{ - "about.title": "About COPS", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "Alphabetical index of the {0} books", - "allbooks.alphabetical.none": "Alphabetical index of absolutely no books", - "allbooks.alphabetical.one": "Alphabetical index of the single book", - "allbooks.title": "All books", - "authors.alphabetical.many": "Alphabetical index of the {0} authors", - "authors.alphabetical.none": "Alphabetical index of absolutely no authors", - "authors.alphabetical.one": "Alphabetical index of the single author", - "authors.title": "Authors", - "author.title": "Author", - "authorword.many": "{0} authors", - "authorword.none": "No authors", - "authorword.one": "1 author", - "bookentry.author": "{0} by {1}", - "bookword.many": "{0} books", - "bookword.none": "No books", - "bookword.one": "1 book", - "bookword.title": "Books", - "cog.alternate": "Search, sort and filters", - "content.series": "Series:", - "content.series.data": "Book {0} in the {1} series", - "content.summary": "Summary", - "customcolumn.boolean.no": "No", - "customcolumn.boolean.unknown": "Not Set", - "customcolumn.boolean.yes": "Yes", - "customcolumn.date.format": "Y-m-d", - "customcolumn.date.unknown": "Not Set", - "customcolumn.description": "Custom column '{0}'", - "customcolumn.description.bool": "Index of a boolean value", - "customcolumn.description.enum.many": "Alphabetical index of the {0} values", - "customcolumn.description.enum.none": "Alphabetical index of absolutely no values", - "customcolumn.description.enum.one": "Alphabetical index of one value", - "customcolumn.description.rating": "Index of ratings", - "customcolumn.description.series.many": "Alphabetical index of the {0} series", - "customcolumn.description.series.none": "Alphabetical index of absolutely no series", - "customcolumn.description.series.one": "Alphabetical index of the single series", - "customcolumn.enum.unknown": "Not Set", - "customcolumn.float.unknown": "Not Set", - "customcolumn.int.unknown": "Not Set", - "customcolumn.rating.unknown": "Not Set", - "customcolumn.stars.many": "{0} Stars", - "customcolumn.stars.none": "No Stars", - "customcolumn.stars.one": "1 Star", - "customize.email": "Set your email (to allow book emailing)", - "customize.fancybox": "Use Lightbox (books load in floating frame)", - "customize.filter": "Enable tag filtering", - "customize.ignored": "Ignored categories", - "customize.paging": "Max number of books per page (-1 to disable)", - "customize.style": "Theme", - "customize.template": "Template", - "customize.title": "Customize COPS UI", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.files": "Extra Files", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Clear all", - "filters.title": "Filters", - "home.alternate": "Home", - "i18n.coversection": "Cover", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Language", - "languages.alphabetical.many": "Alphabetical index of the {0} languages", - "languages.alphabetical.none": "Alphabetical index of absolutely no languages", - "languages.alphabetical.one": "Alphabetical index of the single language", - "languages.title": "Languages", - "libraries.many": "{0} virtual libraries", - "libraries.none": "No virtual libraries", - "libraries.one": "1 virtual library", - "libraries.title": "Virtual libraries", - "library.title": "Virtual library", - "links.title": "Links", - "mail.messagenotsent": "Message could not be sent.", - "mail.messagesent": "Message has been sent", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "Next", - "paging.previous.alternate": "Previous", - "permalink.alternate": "Permalink", - "pubdate.title": "Published", - "publisher.name": "Publisher", - "publishers.alphabetical.many": "Alphabetical index of the {0} publishers", - "publishers.alphabetical.none": "Alphabetical index of absolutely no publishers", - "publishers.alphabetical.one": "Alphabetical index of the single publisher", - "publishers.title": "Publishers", - "publisherword.many": "{0} publishers", - "publisherword.none": "No publishers", - "publisherword.one": "1 publisher", - "ratings.many": "{0} ratings", - "ratings.none": "no ratings", - "ratings.one": "1 rating", - "ratings.title": "Ratings", - "rating.title": "Rating", - "ratingword.many": "{0} stars", - "ratingword.none": "No star", - "ratingword.one": "1 star", - "recent.list": "{0} most recent books", - "recent.title": "Recent additions", - "search.alternate": "Search", - "search.result": "Search result for *{0}*", - "search.result.author": "Search result for *{0}* in authors", - "search.result.book": "Search result for *{0}* in books", - "search.result.publisher": "Search result for *{0}* in publishers", - "search.result.series": "Search result for *{0}* in series", - "search.result.tag": "Search result for *{0}* in tags", - "search.sortorder.asc": "Asc", - "search.sortorder.desc": "Desc", - "series.alphabetical.many": "Alphabetical index of the {0} series", - "series.alphabetical.none": "Alphabetical index of absolutely no series", - "series.alphabetical.one": "Alphabetical index of the single series", - "series.title": "Series", - "seriesword.many": "{0} series", - "seriesword.none": "No series", - "seriesword.one": "1 series", - "sort.alternate": "Sort", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "Other books", - "splitByLetter.letter": "{0} starting with {1}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "Alphabetical index of the {0} tags", - "tags.alphabetical.none": "Alphabetical index of absolutely no tags", - "tags.alphabetical.one": "Alphabetical index of the single tag", - "tags.title": "Tags", - "tagword.many": "{0} tags", - "tagword.none": "No tags", - "tagword.one": "1 tag", - "tagword.title": "Tags", - "title.title": "Title", - "languages.abk": "Abkhaz", - "languages.aaf": "Afar", - "languages.afr": "Afrikaans", - "languages.aka": "Akan", - "languages.sqi": "Albanian", - "languages.amh": "Amharic", - "languages.ara": "Arabic", - "languages.arg": "Aragonese", - "languages.arc": "Aramaic", - "languages.hye": "Armenian", - "languages.asm": "Assamese", - "languages.ava": "Avaric", - "languages.ave": "Avestan", - "languages.aym": "Aymara", - "languages.aze": "Azerbaijani", - "languages.bam": "Bambara", - "languages.bak": "Bashkir", - "languages.eus": "Basque", - "languages.bel": "Belarusian", - "languages.ben": "Bengali", - "languages.bih": "Bihari", - "languages.bis": "Bislama", - "languages.bos": "Bosnian", - "languages.bre": "Breton", - "languages.bul": "Bulgarian", - "languages.mya": "Burmese", - "languages.cat": "Catalan", - "languages.cha": "Chamorro", - "languages.che": "Chechen", - "languages.nya": "Chichewa", - "languages.zho": "Chinese", - "languages.chv": "Chuvash", - "languages.cor": "Cornish", - "languages.cos": "Corsican", - "languages.cre": "Cree", - "languages.hrv": "Croatian", - "languages.ces": "Czech", - "languages.dan": "Danish", - "languages.div": "Divehi", - "languages.nld": "Dutch", - "languages.dzo": "Dzongkha", - "languages.eng": "English", - "languages.epo": "Esperanto", - "languages.est": "Estonian", - "languages.ewe": "Ewe", - "languages.fao": "Faroese", - "languages.fij": "Fijian", - "languages.fin": "Finnish", - "languages.fra": "French", - "languages.ful": "Fula", - "languages.glg": "Galician", - "languages.kat": "Georgian", - "languages.deu": "German", - "languages.ell": "Greek", - "languages.egy": "Egyptian (Ancient)", - "languages.grn": "Guaraní", - "languages.guj": "Gujarati", - "languages.hat": "Haitian", - "languages.hau": "Hausa", - "languages.heb": "Hebrew", - "languages.her": "Herero", - "languages.hin": "Hindi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Hungarian", - "languages.ina": "Interlingua", - "languages.ind": "Indonesian", - "languages.ile": "Interlingue", - "languages.gle": "Irish", - "languages.grc": "Greek, Ancient (to 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Icelandic", - "languages.ita": "Italian", - "languages.iku": "Inuktitut", - "languages.jpn": "Japanese", - "languages.jav": "Javanese", - "languages.kal": "Kalaallisut", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kashmiri", - "languages.kaz": "Kazakh", - "languages.khm": "Khmer", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kyrgyz", - "languages.kom": "Komi", - "languages.kon": "Kongo", - "languages.kor": "Korean", - "languages.kur": "Kurdish", - "languages.kua": "Kwanyama", - "languages.lat": "Latin", - "languages.ltz": "Luxembourgish", - "languages.lug": "Ganda", - "languages.lim": "Limburgish", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Lithuanian", - "languages.lub": "Luba-Katanga", - "languages.lav": "Latvian", - "languages.glv": "Manx", - "languages.mkd": "Macedonian", - "languages.mlg": "Malagasy", - "languages.msa": "Malay", - "languages.mal": "Malayalam", - "languages.mlt": "Maltese", - "languages.mri": "Māori", - "languages.mar": "Marathi", - "languages.mah": "Marshallese", - "languages.mon": "Mongolian", - "languages.nau": "Nauru", - "languages.nav": "Navajo", - "languages.nob": "Norwegian Bokmål", - "languages.nde": "North Ndebele", - "languages.nep": "Nepali", - "languages.ndo": "Ndonga", - "languages.nno": "Norwegian Nynorsk", - "languages.nor": "Norwegian", - "languages.iii": "Nuosu", - "languages.nbl": "South Ndebele", - "languages.oci": "Occitan", - "languages.oji": "Ojibwe", - "languages.chu": "Old Church Slavonic", - "languages.orm": "Oromo", - "languages.ori": "Oriya", - "languages.oss": "Ossetian", - "languages.pan": "Panjabi", - "languages.pli": "Pāli", - "languages.fas": "Persian", - "languages.pol": "Polish", - "languages.pus": "Pashto", - "languages.por": "Portuguese", - "languages.que": "Quechua", - "languages.roh": "Romansh", - "languages.run": "Kirundi", - "languages.ron": "Romanian", - "languages.rus": "Russian", - "languages.sam": "Samaritan Aramaic", - "languages.san": "Sanskrit", - "languages.srd": "Sardinian", - "languages.snd": "Sindhi", - "languages.sme": "Northern Sami", - "languages.smo": "Samoan", - "languages.sag": "Sango", - "languages.srp": "Serbian", - "languages.gla": "Scottish Gaelic", - "languages.sna": "Shona", - "languages.sin": "Sinhala", - "languages.slk": "Slovak", - "languages.slv": "Slovene", - "languages.som": "Somali", - "languages.sot": "Southern Sotho", - "languages.spa": "Spanish", - "languages.sun": "Sundanese", - "languages.sux": "Sumerian", - "languages.swa": "Swahili", - "languages.ssw": "Swati", - "languages.swe": "Swedish", - "languages.syc": "Classical Syriac", - "languages.syr": "Syriac", - "languages.tam": "Tamil", - "languages.tel": "Telugu", - "languages.tgk": "Tajik", - "languages.tha": "Thai", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetan Standard", - "languages.tuk": "Turkmen", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tonga", - "languages.tur": "Turkish", - "languages.tso": "Tsonga", - "languages.tat": "Tatar", - "languages.twi": "Twi", - "languages.tah": "Tahitian", - "languages.uga": "Ugaritic", - "languages.uig": "Uighur", - "languages.ukr": "Ukrainian", - "languages.urd": "Urdu", - "languages.uzb": "Uzbek", - "languages.ven": "Venda", - "languages.vie": "Vietnamese", - "languages.vol": "Volapük", - "languages.win": "Walloon", - "languages.cym": "Welsh", - "languages.wol": "Wolof", - "languages.fry": "Western Frisian", - "languages.xho": "Xhosa", - "languages.yid": "Yiddish", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_es.json b/COPS/cops-3.1.3/lang/Localization_es.json deleted file mode 100644 index b72df031..00000000 --- a/COPS/cops-3.1.3/lang/Localization_es.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "Acerca de COPS", - "addeddate.title": "Agregado", - "allbooks.alphabetical.many": "Listado alfabético de {0} libros", - "allbooks.alphabetical.none": "Listado sin libros", - "allbooks.alphabetical.one": "Listado con un libro", - "allbooks.title": "Todos los libros", - "authors.alphabetical.many": "Listado alfabético de {0} autores", - "authors.alphabetical.none": "Listado sin autores", - "authors.alphabetical.one": "Listado con un autor", - "authors.title": "Autores", - "author.title": "Autor", - "authorword.many": "{0} autores", - "authorword.none": "Sin autor", - "authorword.one": "1 autor", - "bookentry.author": "{0} de {1}", - "bookword.many": "{0} libros", - "bookword.none": "Sin libros", - "bookword.one": "1 libro", - "bookword.title": "Libros", - "cog.alternate": "Búsqueda, ordenación y filtros", - "content.series": "Series:", - "content.series.data": "Libro {0} en la {1} serie", - "content.summary": "Resumen", - "customcolumn.boolean.no": "No", - "customcolumn.boolean.unknown": "No Establecido", - "customcolumn.boolean.yes": "Sí", - "customcolumn.date.format": "Y-m-d", - "customcolumn.date.unknown": "No Establecido", - "customcolumn.description": "Columna personalizada '{0}'", - "customcolumn.description.bool": "Índice de un valor booleano", - "customcolumn.description.enum.many": "Índice alfabético de {0} valores", - "customcolumn.description.enum.none": "Índice alfabético de ningún valor", - "customcolumn.description.enum.one": "Índice alfabético de un valor", - "customcolumn.description.rating": "Índice de calificaciones", - "customcolumn.description.series.many": "Listado alfabético de {0} series", - "customcolumn.description.series.none": "Listado sin series", - "customcolumn.description.series.one": "Listado de una serie", - "customcolumn.enum.unknown": "No Establecido", - "customcolumn.float.unknown": "No Establecido", - "customcolumn.int.unknown": "No Establecido", - "customcolumn.rating.unknown": "No Establecido", - "customcolumn.stars.many": "{0} Estrellas", - "customcolumn.stars.none": "Sin estrellas", - "customcolumn.stars.one": "1 Estrella", - "customize.email": "Su correo (Para envío de libros por correo)", - "customize.fancybox": "Usar LightBox", - "customize.filter": "Activar filtro por etiqueta", - "customize.ignored": "Ocultar categorías", - "customize.paging": "Max. número de libros por página (-1 para desactivar)", - "customize.style": "Tema", - "customize.template": "Plantilla", - "customize.title": "Configurar COPS UI", - "default.template": "Plantilla COPS predeterminada", - "downloadall.title": "Descargar todo", - "downloadall.tooltip": "Descargue un archivo zip que contenga todos los libros de esta página en este formato", - "extra.content": "Descripción", - "extra.link": "Link", - "extra.title": "Información Extra", - "filter.clearall": "Borrar todos", - "filters.title": "Filtros", - "home.alternate": "Inicio", - "i18n.coversection": "Cubierta", - "identifiers.title": "Identificadores", - "identifierword.many": "{0} identificadores", - "identifierword.none": "Sin identificadores", - "identifierword.one": "1 identificador", - "language.title": "Idioma", - "languages.alphabetical.many": "Listado alfabético de {0} idiomas", - "languages.alphabetical.none": "Listado sin idiomas disponibles", - "languages.alphabetical.one": "Listado con un idioma", - "languages.title": "Idiomas", - "links.title": "Enlaces", - "mail.messagenotsent": "El mensaje no pudo enviarse.", - "mail.messagesent": "El mensaje se ha enviado", - "paging.first.alternate": "Primero", - "paging.last.alternate": "Último", - "paging.next.alternate": "Siguiente", - "paging.previous.alternate": "Anterior", - "permalink.alternate": "Enlace permanente", - "pubdate.title": "Publicado", - "publisher.name": "Editorial", - "publishers.alphabetical.many": "Listado alfabético de {0} editoriales", - "publishers.alphabetical.none": "Listado sin editoriales", - "publishers.alphabetical.one": "Listado con una editorial", - "publishers.title": "Editoriales", - "publisherword.many": "{0} editoriales", - "publisherword.none": "No hay editoriales", - "publisherword.one": "1 editorial", - "ratings.many": "{0} valoraciones", - "ratings.none": "sin valoraciones", - "ratings.one": "1 valoración", - "ratings.title": "Puntuaciones", - "rating.title": "Clasificación", - "ratingword.many": "{0} estrellas", - "ratingword.none": "Sin estrellas", - "ratingword.one": "1 estrella", - "recent.list": "{0} libros más recientes", - "recent.title": "Añadidos recientemente", - "search.alternate": "Buscar", - "search.result": "Resultados de buscar *{0}*", - "search.result.author": "Resultados de buscar *{0}* en autores", - "search.result.book": "Resultados de buscar *{0}* en libros", - "search.result.publisher": "Resultados de buscar *{0}* en editoriales", - "search.result.series": "Resultados de buscar *{0}* en series", - "search.result.tag": "Resultados de buscar *{0}* en etiquetas", - "search.sortorder.asc": "Asc", - "search.sortorder.desc": "Desc", - "series.alphabetical.many": "Listado alfabético de {0} series", - "series.alphabetical.none": "Listado sin series", - "series.alphabetical.one": "Listado de una serie", - "series.title": "Series", - "seriesword.many": "{0} series", - "seriesword.none": "Sin series", - "seriesword.one": "1 serie", - "sort.alternate": "Ordenar", - "sort.count": "Contar", - "sort.names": "Nombre", - "sort.titles": "Títulos", - "sortby.title": "Ordenar por", - "splitByLetter.book.other": "Otros libros", - "splitByLetter.letter": "{0} que empiezan por {1}", - "splitByRange.range": "{0} en el rango {1}", - "splitByYear.year": "{0} publicado en {1}", - "tags.alphabetical.many": "Listado alfabético de las {0} etiquetas", - "tags.alphabetical.none": "Listado sin etiquetas", - "tags.alphabetical.one": "Listado alfabético de la unica etiqueta", - "tags.title": "Etiquetas", - "tagword.many": "etiquetas", - "tagword.none": "Sin etiquetas", - "tagword.one": "1 etiqueta", - "tagword.title": "Etiquetas", - "title.title": "Título", - "languages.abk": "Abjasio", - "languages.aaf": "Afar", - "languages.afr": "Afrikáans", - "languages.aka": "Ákan", - "languages.sqi": "Albano", - "languages.amh": "Amárico", - "languages.ara": "Arabe", - "languages.arg": "Aragonés", - "languages.arc": "Arameo", - "languages.hye": "Armenio", - "languages.asm": "Assamese", - "languages.ava": "Avaric", - "languages.ave": "Avéstica", - "languages.aym": "Aymara", - "languages.aze": "Azerbaiyán", - "languages.bam": "Bambara", - "languages.bak": "Bashkir", - "languages.eus": "Euskera", - "languages.bel": "Belaruso", - "languages.ben": "Bengalí", - "languages.bih": "Bihari", - "languages.bis": "Bislama", - "languages.bos": "Bosnio", - "languages.bre": "Bretón", - "languages.bul": "Bulgaro", - "languages.mya": "Birmano", - "languages.cat": "Catalán", - "languages.cha": "Chamorro", - "languages.che": "Checheno", - "languages.nya": "Chichewa", - "languages.zho": "Chino", - "languages.chv": "Chuvash", - "languages.cor": "Cornish", - "languages.cos": "Córcega", - "languages.cre": "Cree", - "languages.hrv": "Croata", - "languages.ces": "Checo", - "languages.dan": "Danés", - "languages.div": "Maldivo", - "languages.nld": "Alemán", - "languages.dzo": "Butanés", - "languages.eng": "Inglés", - "languages.epo": "Esperanto", - "languages.est": "Estonio", - "languages.ewe": "Ewé", - "languages.fao": "Feroés", - "languages.fij": "Fiji", - "languages.fin": "Finlandés", - "languages.fra": "Francés", - "languages.ful": "Fula", - "languages.glg": "Gallego", - "languages.kat": "Georgiano", - "languages.deu": "Alemán", - "languages.ell": "Griego", - "languages.egy": "Egipcio (Antiguo)", - "languages.grn": "Guaraní", - "languages.guj": "Guyaratí", - "languages.hat": "Haitiano", - "languages.hau": "Hausa", - "languages.heb": "Hebreo", - "languages.her": "Herero", - "languages.hin": "Hindú", - "languages.hmo": "Hiri Motu", - "languages.hun": "Hungaro", - "languages.ina": "Interlingua", - "languages.ind": "Indonesio", - "languages.ile": "Interlingue", - "languages.gle": "Irlandés", - "languages.grc": "Griego, Antiguo (hasta 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Iñupiaq", - "languages.ido": "Ido", - "languages.isl": "Islandés", - "languages.ita": "Italiano", - "languages.iku": "Inui", - "languages.jpn": "Japonés", - "languages.jav": "Javanés", - "languages.kal": "Groenlandés", - "languages.kan": "Canarés", - "languages.kau": "Kanurí", - "languages.kas": "Cachemir", - "languages.kaz": "Kazajo", - "languages.khm": "Camboyano", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kirguís", - "languages.kom": "Komi", - "languages.kon": "Congoleño", - "languages.kor": "Coreano", - "languages.kur": "Kurdo", - "languages.kua": "Kuanyama", - "languages.lat": "Latín", - "languages.ltz": "Luxemburgés", - "languages.lug": "Ganda", - "languages.lim": "Limburgish", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Lituano", - "languages.lub": "Luba-Katanga", - "languages.lav": "Letón", - "languages.glv": "Manx", - "languages.mkd": "Macedonio", - "languages.mlg": "Malgache", - "languages.msa": "Malayo", - "languages.mal": "Malayalam", - "languages.mlt": "Maltés", - "languages.mri": "Maorí", - "languages.mar": "Marathi", - "languages.mah": "Marshalés", - "languages.mon": "Mongol", - "languages.nau": "Nauru", - "languages.nav": "Navajo", - "languages.nob": "Norwego Bokmål", - "languages.nde": "Ndebele Norte", - "languages.nep": "Nepalí", - "languages.ndo": "Ndonga", - "languages.nno": "Norwego Nynorsk", - "languages.nor": "Noruego", - "languages.iii": "Nuousu", - "languages.nbl": "Ndebele del Sur", - "languages.oci": "Occitano", - "languages.oji": "Ojibwa ", - "languages.chu": "Antiguo Eslavo Eclesiástico", - "languages.orm": "Oromo", - "languages.ori": "Oriya", - "languages.oss": "Osetio", - "languages.pan": "Panyabí", - "languages.pli": "Pali", - "languages.fas": "Persa", - "languages.pol": "Polaco", - "languages.pus": "Pastún", - "languages.por": "Portugués", - "languages.que": "Quechua", - "languages.roh": "Romanche", - "languages.run": "Kirundí", - "languages.ron": "Rumano", - "languages.rus": "Ruso", - "languages.sam": "Arameo Samaritano", - "languages.san": "Sánscrito", - "languages.srd": "Sardo", - "languages.snd": "Sindi", - "languages.sme": "Sami Septentrional", - "languages.smo": "Samoa", - "languages.sag": "Sango", - "languages.srp": "Serbio", - "languages.gla": "Escocés Gaélico", - "languages.sna": "Shona", - "languages.sin": "Cingalés", - "languages.slk": "Eslovaco", - "languages.slv": "Sloveno", - "languages.som": "Somalí", - "languages.sot": "Sotho del Sur", - "languages.spa": "Español", - "languages.sun": "Sudanés", - "languages.sux": "Summerio", - "languages.swa": "Swahili", - "languages.ssw": "Swati", - "languages.swe": "Sueco", - "languages.syc": "Asirio Clásico", - "languages.syr": "Asirio", - "languages.tam": "Tamil", - "languages.tel": "Telugu", - "languages.tgk": "Tayiko", - "languages.tha": "Tailandés", - "languages.tir": "Tigriña", - "languages.bod": "Tibetano Standard", - "languages.tuk": "Turcomano", - "languages.tgl": "Tagalo", - "languages.tsn": "Setsuana", - "languages.ton": "Tonga", - "languages.tur": "Turco", - "languages.tso": "Tsonga", - "languages.tat": "Tártaro", - "languages.twi": "Twi", - "languages.tah": "Tahitiano", - "languages.uga": "Ugarítico", - "languages.uig": "Uigur", - "languages.ukr": "Ucrainiano", - "languages.urd": "Urdu", - "languages.uzb": "Uzbeko", - "languages.ven": "Venda", - "languages.vie": "Vietnamita", - "languages.vol": "Volapük", - "languages.win": "Valón", - "languages.cym": "Galés", - "languages.wol": "Wólof", - "languages.fry": "Frisio Occidental", - "languages.xho": "Xhosa", - "languages.yid": "Yiddish", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulú", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_eu.json b/COPS/cops-3.1.3/lang/Localization_eu.json deleted file mode 100644 index 9fb91e2c..00000000 --- a/COPS/cops-3.1.3/lang/Localization_eu.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "COPS-i buruz", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "{0} libururen zerrenda alfabetikoa", - "allbooks.alphabetical.none": "Liburu gabeko zerrenda", - "allbooks.alphabetical.one": "Liburu bakarreko zerrenda", - "allbooks.title": "Liburu guztiak", - "authors.alphabetical.many": "{0} egileren zerrenda alfabetikoa", - "authors.alphabetical.none": "Egile gabeko zerrenda", - "authors.alphabetical.one": "Egile bakarreko zerrenda", - "authors.title": "Egileak", - "author.title": "Author", - "authorword.many": "{0} egile", - "authorword.none": "Egile gabe", - "authorword.one": "Egile 1", - "bookentry.author": "{1}-tik {0}", - "bookword.many": "{0} liburu", - "bookword.none": "Liburu gabe", - "bookword.one": "Liburu 1", - "bookword.title": "Liburuak", - "cog.alternate": "Bilaketa, ordena eta filtroak", - "content.series": "Sailak:", - "content.series.data": "{0} liburu {1} sailekoak", - "content.summary": "Laburpena:", - "customcolumn.boolean.no": "Ez", - "customcolumn.boolean.unknown": "Ezarrik gabe", - "customcolumn.boolean.yes": "Bai", - "customcolumn.date.format": "U-H-E", - "customcolumn.date.unknown": "Ezarrik gabe", - "customcolumn.description": "Zutabe pertsonalizatua '{0}'", - "customcolumn.description.bool": "Index of a boolean value", - "customcolumn.description.enum.many": "{0} baloren zerrenda alfabetikoa", - "customcolumn.description.enum.none": "Alphabetical index of absolutely no values", - "customcolumn.description.enum.one": "Alphabetical index of one value", - "customcolumn.description.rating": "Balorazioaren indizea", - "customcolumn.description.series.many": "{0} sailen zerrenda alfabetikoa", - "customcolumn.description.series.none": "Sail gabeko zerrenda", - "customcolumn.description.series.one": "Sail bakarreko zerrenda", - "customcolumn.enum.unknown": "Ezarrik gabe", - "customcolumn.float.unknown": "Ezarrik gabe", - "customcolumn.int.unknown": "Ezarrik gabe", - "customcolumn.rating.unknown": "Ezarrik gabe", - "customcolumn.stars.many": "{0} Izarrak", - "customcolumn.stars.none": "Izarrik gabe", - "customcolumn.stars.one": "Izar 1", - "customize.email": "Zure posta elektronikoa (posta bidezko liburu bidalketarako)", - "customize.fancybox": "LightBox erabili", - "customize.filter": "Etiketa bidezko filtroa aktibatu", - "customize.ignored": "Kategoriak ezkutatu", - "customize.paging": "Liburu kopuru maximoa orrialdeko (-1 desaktibatzeko)", - "customize.style": "Gaia", - "customize.template": "Template", - "customize.title": "COPS UI konfiguratu", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Ezabatu denak", - "filters.title": "Filters", - "home.alternate": "Hasiera", - "i18n.coversection": "Azala", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Hizkuntza", - "languages.alphabetical.many": "{0} hizkuntzen zerrenda alfabetikoa", - "languages.alphabetical.none": "Hizkutzarik gabeko zerrenda", - "languages.alphabetical.one": "Hizkuntza bakarreko zerrenda", - "languages.title": "Hizkuntza", - "links.title": "Estekak", - "mail.messagenotsent": "Mezua ezin izan da bidali.", - "mail.messagesent": "Mezua bidali da", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "Hurrengoa", - "paging.previous.alternate": "Aurrekoa", - "permalink.alternate": "Esteka iraunkorra", - "pubdate.title": "Published", - "publisher.name": "Argitaletxea", - "publishers.alphabetical.many": "{0} argitaletxeren zerrenda alfabetikoa", - "publishers.alphabetical.none": "Argitaletxe gabeko zerrenda", - "publishers.alphabetical.one": "Argitaletxe bakarreko zerrenda", - "publishers.title": "Argitaletxeak", - "publisherword.many": "{0} argitaletxe", - "publisherword.none": "Ez dago argitaletxerik", - "publisherword.one": "Argitaletxe 1", - "ratings.many": "{0} puntuaketa", - "ratings.none": "Ez dago puntuaketarik", - "ratings.one": "Puntuaketa 1", - "ratings.title": "Puntuaketak", - "rating.title": "Rating", - "ratingword.many": "{0} izar", - "ratingword.none": "Izar gabe", - "ratingword.one": "Izar 1", - "recent.list": "{0} liburu berrienak", - "recent.title": "Berriki zerrendatuak", - "search.alternate": "Bilatu", - "search.result": "*{0}* bilaketaren emaitzak", - "search.result.author": "*{0}* bilaketaren emaitzak egileetan", - "search.result.book": "*{0}* bilaketaren emaitzak liburuetan", - "search.result.publisher": "*{0}* bilaketaren emaitzak argitaletxetan", - "search.result.series": "*{0}* bilaketaren emaitzak sailetan", - "search.result.tag": "*{0}* bilaketaren emaitzak etiketetan", - "search.sortorder.asc": "Gora", - "search.sortorder.desc": "Behera", - "series.alphabetical.many": "{0} sailen zerrenda alfabetikoa", - "series.alphabetical.none": "Sail gabeko zerrenda", - "series.alphabetical.one": "Sail bakarreko zerrenda", - "series.title": "Sailak", - "seriesword.many": "{0} sail", - "seriesword.none": "Sail gabe", - "seriesword.one": "Sail 1", - "sort.alternate": "Ordenatu", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "Beste liburu batzuk", - "splitByLetter.letter": "{1}-tik haste d(ir)en {0}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "{0} etiketen zerrenda alfabetikoa", - "tags.alphabetical.none": "Etiketa gabeko zerrenda", - "tags.alphabetical.one": "Etiketa bakarreko zerrenda", - "tags.title": "Etiketak", - "tagword.many": "{0} etiketa", - "tagword.none": "Etiketa gabe", - "tagword.one": "Etiketa 1", - "tagword.title": "Etiketak", - "title.title": "Title", - "languages.abk": "Abkhaz", - "languages.aaf": "Afar", - "languages.afr": "Afrikaans", - "languages.aka": "Akan", - "languages.sqi": "Albanian", - "languages.amh": "Amharic", - "languages.ara": "Arabic", - "languages.arg": "Aragonese", - "languages.arc": "Aramearra", - "languages.hye": "Armenian", - "languages.asm": "Assamese", - "languages.ava": "Avaric", - "languages.ave": "Avestan", - "languages.aym": "Aymara", - "languages.aze": "Azerbaijani", - "languages.bam": "Bambara", - "languages.bak": "Bashkir", - "languages.eus": "Euskara", - "languages.bel": "Belarusian", - "languages.ben": "Bengali", - "languages.bih": "Bihari", - "languages.bis": "Bislama", - "languages.bos": "Bosnian", - "languages.bre": "Breton", - "languages.bul": "Bulgarian", - "languages.mya": "Burmese", - "languages.cat": "Katalana", - "languages.cha": "Chamorro", - "languages.che": "Chechen", - "languages.nya": "Chichewa", - "languages.zho": "Chinese", - "languages.chv": "Chuvash", - "languages.cor": "Cornish", - "languages.cos": "Corsican", - "languages.cre": "Cree", - "languages.hrv": "Croatian", - "languages.ces": "Czech", - "languages.dan": "Danish", - "languages.div": "Divehi", - "languages.nld": "Dutch", - "languages.dzo": "Dzongkha", - "languages.eng": "Ingelesa", - "languages.epo": "Esperanto", - "languages.est": "Estonian", - "languages.ewe": "Ewe", - "languages.fao": "Faroese", - "languages.fij": "Fijian", - "languages.fin": "Finnish", - "languages.fra": "Frantzesa", - "languages.ful": "Fula", - "languages.glg": "Galician", - "languages.kat": "Georgian", - "languages.deu": "Alemana", - "languages.ell": "Greek", - "languages.egy": "Egiptoera (Antzinako)", - "languages.grn": "Guaraní", - "languages.guj": "Gujarati", - "languages.hat": "Haitian", - "languages.hau": "Hausa", - "languages.heb": "Hebreera", - "languages.her": "Herero", - "languages.hin": "Hindi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Hungarian", - "languages.ina": "Interlingua", - "languages.ind": "Indonesian", - "languages.ile": "Interlingue", - "languages.gle": "Irish", - "languages.grc": "Greziera, Antzinakoa (1453ra arte)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Icelandic", - "languages.ita": "Italiera", - "languages.iku": "Inuktitut", - "languages.jpn": "Japanese", - "languages.jav": "Javanese", - "languages.kal": "Kalaallisut", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kashmiri", - "languages.kaz": "Kazakh", - "languages.khm": "Khmer", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kyrgyz", - "languages.kom": "Komi", - "languages.kon": "Kongo", - "languages.kor": "Korean", - "languages.kur": "Kurdish", - "languages.kua": "Kwanyama", - "languages.lat": "Latina", - "languages.ltz": "Luxembourgish", - "languages.lug": "Ganda", - "languages.lim": "Limburgish", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Lithuanian", - "languages.lub": "Luba-Katanga", - "languages.lav": "Latvian", - "languages.glv": "Manx", - "languages.mkd": "Macedonian", - "languages.mlg": "Malagasy", - "languages.msa": "Malay", - "languages.mal": "Malayalam", - "languages.mlt": "Maltese", - "languages.mri": "Māori", - "languages.mar": "Marathi", - "languages.mah": "Marshallese", - "languages.mon": "Mongolian", - "languages.nau": "Nauru", - "languages.nav": "Navajo", - "languages.nob": "Norwegian Bokmål", - "languages.nde": "North Ndebele", - "languages.nep": "Nepali", - "languages.ndo": "Ndonga", - "languages.nno": "Norwegian Nynorsk", - "languages.nor": "Norwegian", - "languages.iii": "Nuosu", - "languages.nbl": "South Ndebele", - "languages.oci": "Occitan", - "languages.oji": "Ojibwe", - "languages.chu": "Old Church Slavonic", - "languages.orm": "Oromo", - "languages.ori": "Oriya", - "languages.oss": "Ossetian", - "languages.pan": "Panjabi", - "languages.pli": "Pāli", - "languages.fas": "Persian", - "languages.pol": "Polish", - "languages.pus": "Pashto", - "languages.por": "Portuguese", - "languages.que": "Quechua", - "languages.roh": "Romansh", - "languages.run": "Kirundi", - "languages.ron": "Romanian", - "languages.rus": "Russian", - "languages.sam": "Samaritan Aramaic", - "languages.san": "Sanskrit", - "languages.srd": "Sardinian", - "languages.snd": "Sindhi", - "languages.sme": "Northern Sami", - "languages.smo": "Samoan", - "languages.sag": "Sango", - "languages.srp": "Serbian", - "languages.gla": "Scottish Gaelic", - "languages.sna": "Shona", - "languages.sin": "Sinhala", - "languages.slk": "Slovak", - "languages.slv": "Slovene", - "languages.som": "Somali", - "languages.sot": "Southern Sotho", - "languages.spa": "Gaztelania", - "languages.sun": "Sundanese", - "languages.sux": "Sumeriera", - "languages.swa": "Swahili", - "languages.ssw": "Swati", - "languages.swe": "Swedish", - "languages.syc": "Classical Syriac", - "languages.syr": "Siriano", - "languages.tam": "Tamil", - "languages.tel": "Telugu", - "languages.tgk": "Tajik", - "languages.tha": "Thai", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetan Standard", - "languages.tuk": "Turkmen", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tonga", - "languages.tur": "Turkish", - "languages.tso": "Tsonga", - "languages.tat": "Tatar", - "languages.twi": "Twi", - "languages.tah": "Tahitian", - "languages.uga": "Ugaritic", - "languages.uig": "Uighur", - "languages.ukr": "Ukrainian", - "languages.urd": "Urdu", - "languages.uzb": "Uzbek", - "languages.ven": "Venda", - "languages.vie": "Vietnamese", - "languages.vol": "Volapük", - "languages.win": "Walloon", - "languages.cym": "Welsh", - "languages.wol": "Wolof", - "languages.fry": "Western Frisian", - "languages.xho": "Xhosa", - "languages.yid": "Yiddish", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_fr.json b/COPS/cops-3.1.3/lang/Localization_fr.json deleted file mode 100644 index 17ed3cbf..00000000 --- a/COPS/cops-3.1.3/lang/Localization_fr.json +++ /dev/null @@ -1,333 +0,0 @@ -{ - "about.title": "A propos de COPS", - "addeddate.title": "Ajouté", - "allbooks.alphabetical.many": "Index alphabétique des {0} livres", - "allbooks.alphabetical.none": "Index alphabétique - aucun livre", - "allbooks.alphabetical.one": "Index alphabétique du seul livre", - "allbooks.title": "Tous les livres", - "authors.alphabetical.many": "Index alphabétique des {0} auteurs", - "authors.alphabetical.none": "Index alphabétique - aucun auteur", - "authors.alphabetical.one": "Index alphabétique du seul auteur", - "authors.title": "Auteurs", - "author.title": "Auteur", - "authorword.many": "{0} auteurs", - "authorword.none": "Pas d'auteur", - "authorword.one": "1 auteur", - "bookentry.author": "{0} de {1}", - "bookword.many": "{0} livres", - "bookword.none": "Aucun livre", - "bookword.one": "1 livre", - "bookword.title": "Livres", - "cog.alternate": "Recherche, tri et filtres", - "content.series": "Collection:", - "content.series.data": "Livre {0} dans la collection {1}", - "content.summary": "Résumé", - "customcolumn.boolean.no": "Non", - "customcolumn.boolean.unknown": "Non défini", - "customcolumn.boolean.yes": "Oui", - "customcolumn.date.format": "Y-m-d", - "customcolumn.date.unknown": "Non défini", - "customcolumn.description": "Colonne personnalisée '{0}'", - "customcolumn.description.bool": "Index des valeurs booléenne", - "customcolumn.description.enum.many": "Index alphabétique de {0} valeurs", - "customcolumn.description.enum.none": "Index alphabétique - aucune valeur", - "customcolumn.description.enum.one": "Index alphabétique - une seule valeur", - "customcolumn.description.rating": "Index des appréciations", - "customcolumn.description.series.many": "Index alphabétique de {0} collections", - "customcolumn.description.series.none": "Index alphabétique - aucune collection", - "customcolumn.description.series.one": "Index alphabétique - Une seule collection", - "customcolumn.enum.unknown": "Non défini", - "customcolumn.float.unknown": "Non défini", - "customcolumn.int.unknown": "Non défini", - "customcolumn.rating.unknown": "Non défini", - "customcolumn.stars.many": "{0} étoiles", - "customcolumn.stars.none": "Aucune étoile", - "customcolumn.stars.one": "1 étoile", - "customize.email": "Adresse email (pour l'envoi automatique de livres)", - "customize.fancybox": "Utiliser une Lightbox", - "customize.filter": "Filtrage via les thèmes", - "customize.ignored": "Catégories ignorées", - "customize.paging": "Nombre de livres par page (-1 pour désactiver)", - "customize.style": "Thème", - "customize.template": "Template", - "customize.title": "Paramétrage de COPS", - "default.template": "Template COPS par défaut", - "downloadall.title": "Télécharger tout", - "downloadall.tooltip": "Téléchargez un fichier zip contenant tous les livres de cette page dans ce format", - "extra.content": "Description", - "extra.files": "Fichiers", - "extra.link": "Lien", - "extra.title": "Informations supplémentaires", - "filter.clearall": "Effacer tout", - "filters.title": "Filtres", - "home.alternate": "Accueil", - "i18n.coversection": "Couverture", - "identifiers.title": "Identifiants", - "identifierword.many": "{0} identifiants", - "identifierword.none": "Aucun identifiant", - "identifierword.one": "1 identifiant", - "language.title": "Langue", - "languages.alphabetical.many": "Index alphabétique des {0} langues", - "languages.alphabetical.none": "Index alphabétique - Aucune langue", - "languages.alphabetical.one": "Index alphabétique - Une seule langue", - "languages.title": "Langues", - "libraries.many": "{0} bibliothèques virtuelles", - "libraries.none": "Pas de bibliothèques virtuelles", - "libraries.one": "1 bibliothèque virtuelle", - "libraries.title": "Bibliothèques virtuelles", - "library.title": "Bibliothèque virtuelle", - "links.title": "Liens", - "mail.messagenotsent": "Le message n'a pas pu être envoyé.", - "mail.messagesent": "Le message a été envoyé", - "paging.first.alternate": "Premier", - "paging.last.alternate": "Dernier", - "paging.next.alternate": "Suivant", - "paging.previous.alternate": "Précédent", - "permalink.alternate": "Permalien", - "pubdate.title": "Publié", - "publisher.name": "Editeur", - "publishers.alphabetical.many": "Index alphabétique des {0} éditeurs", - "publishers.alphabetical.none": "Index alphabétique - Aucun éditeur", - "publishers.alphabetical.one": "Index alphabétique - Un seul éditeur", - "publishers.title": "Editeurs", - "publisherword.many": "{0} éditeurs", - "publisherword.none": "Aucun éditeur", - "publisherword.one": "1 éditeur", - "ratings.many": "{0} Appréciations", - "ratings.none": "Pas d'appréciations", - "ratings.one": "1 appréciation", - "ratings.title": "Appréciations", - "rating.title": "Appréciation", - "ratingword.many": "{0} étoiles", - "ratingword.none": "Aucune étoile", - "ratingword.one": "1 étoile", - "recent.list": "{0} livres les plus récents", - "recent.title": "Ajouts récents", - "search.alternate": "Rechercher", - "search.result": "Résultats pour *{0}*", - "search.result.author": "Résultats pour *{0}* dans les auteurs", - "search.result.book": "Résultats pour *{0}* dans les livres", - "search.result.publisher": "Résultats pour *{0}* dans les éditeurs", - "search.result.series": "Résultats pour *{0}* dans les colllections", - "search.result.tag": "Résultats pour *{0}* dans les thèmes", - "search.sortorder.asc": "Asc", - "search.sortorder.desc": "Desc", - "series.alphabetical.many": "Index alphabétique de {0} collections", - "series.alphabetical.none": "Index alphabétique - aucune collection", - "series.alphabetical.one": "Index alphabétique - Une seule collection", - "series.title": "Collections", - "seriesword.many": "{0} collections", - "seriesword.none": "Pas de collection", - "seriesword.one": "1 collection", - "sort.alternate": "Trier", - "sort.count": "Nombre", - "sort.names": "Noms", - "sort.titles": "Titres", - "sortby.title": "Trier par", - "splitByLetter.book.other": "Autres livres", - "splitByLetter.letter": "{0} débutant par {1}", - "splitByRange.range": "{0} dans la plage {1}", - "splitByYear.year": "{0} publié en {1}", - "tags.alphabetical.many": "Index alphabétique des {0} thèmes", - "tags.alphabetical.none": "Index alphabétique - aucune thème", - "tags.alphabetical.one": "Index alphabétique - Une seule thème", - "tags.title": "Thèmes", - "tagword.many": "{0} thèmes", - "tagword.none": "Sans thème", - "tagword.one": "1 thème", - "tagword.title": "Thèmes", - "title.title": "Titre", - "languages.abk": "Abkhaze", - "languages.aaf": "Afar", - "languages.afr": "Afrikaner", - "languages.aka": "Akan", - "languages.sqi": "Albanais", - "languages.amh": "Amharique", - "languages.ara": "Arabe", - "languages.arg": "Aragonais", - "languages.arc": "Araméen", - "languages.hye": "Armenien", - "languages.asm": "Assamais", - "languages.ava": "Avar", - "languages.ave": "Avestique", - "languages.aym": "Aymara", - "languages.aze": "Azerbaïjanais", - "languages.bam": "Bambara", - "languages.bak": "Bachkir", - "languages.eus": "Basque", - "languages.bel": "Bielorusse", - "languages.ben": "Bengalais", - "languages.bih": "Bihari", - "languages.bis": "Bichelamar", - "languages.bos": "Bosnien", - "languages.bre": "Breton", - "languages.bul": "Bulgare", - "languages.mya": "Birman", - "languages.cat": "Catalan", - "languages.cha": "Chamorro", - "languages.che": "Tchétchène", - "languages.nya": "Chichewa", - "languages.zho": "Chinois", - "languages.chv": "Tchouvache", - "languages.cor": "Cornique", - "languages.cos": "Corse", - "languages.cre": "Cree", - "languages.hrv": "Croate", - "languages.ces": "Tchèque", - "languages.dan": "Danois", - "languages.div": "Divehi", - "languages.nld": "Néerlandais", - "languages.dzo": "Dzongkha", - "languages.eng": "Anglais", - "languages.epo": "Esperanto", - "languages.est": "Estonien", - "languages.ewe": "Ewe", - "languages.fao": "Féroïen", - "languages.fij": "Fidjien", - "languages.fin": "Finnois", - "languages.fra": "Français", - "languages.ful": "Peul", - "languages.glg": "Galicien", - "languages.kat": "Georgien", - "languages.deu": "Allemand", - "languages.ell": "Grec", - "languages.egy": "Égyptien (Ancien)", - "languages.grn": "Guaraní", - "languages.guj": "Gujarati", - "languages.hat": "Haitien", - "languages.hau": "Hausa", - "languages.heb": "Hébreu", - "languages.her": "Héréro", - "languages.hin": "Hindi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Hongrois", - "languages.ina": "Interlingua", - "languages.ind": "Indonésien", - "languages.ile": "Interlingue", - "languages.gle": "Irlandais", - "languages.grc": "Grec ancien (avant 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiak", - "languages.ido": "Ido", - "languages.isl": "Islandais", - "languages.ita": "Italien", - "languages.iku": "Inuktitut", - "languages.jpn": "Japonais", - "languages.jav": "Javanais", - "languages.kal": "Groenlandais", - "languages.kan": "Kannada", - "languages.kau": "Kanouri", - "languages.kas": "Kashmiri", - "languages.kaz": "Kazak", - "languages.khm": "Khmer", - "languages.kik": "Kikouyou", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kyrgize", - "languages.kom": "Komi", - "languages.kon": "Kikongo", - "languages.kor": "Coréen", - "languages.kur": "Kurde", - "languages.kua": "Kuanyama", - "languages.lat": "Latin", - "languages.ltz": "Luxembourgeois", - "languages.lug": "Ganda", - "languages.lim": "Limburgeois", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Lithuanien", - "languages.lub": "Luba-Katanga", - "languages.lav": "Latvien", - "languages.glv": "Mannois", - "languages.mkd": "Macédonien", - "languages.mlg": "Malagais", - "languages.msa": "Malais", - "languages.mal": "Malayalam", - "languages.mlt": "Maltais", - "languages.mri": "Māori", - "languages.mar": "Marathi", - "languages.mah": "Marshallais", - "languages.mon": "Mongol", - "languages.nau": "Nauruan", - "languages.nav": "Navajo", - "languages.nob": "Norvégien Bokmål", - "languages.nde": "Ndébélé", - "languages.nep": "Népalais", - "languages.ndo": "Ndonga", - "languages.nno": "Norvégien Nynorsk", - "languages.nor": "Norvégien", - "languages.iii": "Nuosu", - "languages.nbl": "Sindebele", - "languages.oci": "Occitan", - "languages.oji": "Ojibwe", - "languages.chu": "Vieux-slave", - "languages.orm": "Oromo", - "languages.ori": "Odia", - "languages.oss": "Ossete", - "languages.pan": "Penjabais", - "languages.pli": "Pāli", - "languages.fas": "Perse", - "languages.pol": "Polonais", - "languages.pus": "Pachtoune", - "languages.por": "Portugais", - "languages.que": "Quechua", - "languages.roh": "Romanche", - "languages.run": "Kirundi", - "languages.ron": "Roumain", - "languages.rus": "Russe", - "languages.sam": "Araméen samaritain", - "languages.san": "Sanscrit", - "languages.srd": "Sarde", - "languages.snd": "Sindhi", - "languages.sme": "Sami du Nord", - "languages.smo": "Samoais", - "languages.sag": "Sango", - "languages.srp": "Serbe", - "languages.gla": "Gaélique Écossais", - "languages.sna": "Shona", - "languages.sin": "Cingalais", - "languages.slk": "Slovaque", - "languages.slv": "Slovene", - "languages.som": "Somalien", - "languages.sot": "Sotho du Sud", - "languages.spa": "Espagnol", - "languages.sun": "Soudanais", - "languages.sux": "Sumérien", - "languages.swa": "Swahili", - "languages.ssw": "Swati", - "languages.swe": "Suédois", - "languages.syc": "Syriaque classique", - "languages.syr": "Syriaque", - "languages.tam": "Tamile", - "languages.tel": "Telougou", - "languages.tgk": "Tajik", - "languages.tha": "Thai", - "languages.tir": "Tigrinia", - "languages.bod": "Tibétain Standard", - "languages.tuk": "Turkmène", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tongien", - "languages.tur": "Turc", - "languages.tso": "Tsonga", - "languages.tat": "Tatar", - "languages.twi": "Twi", - "languages.tah": "Tahitien", - "languages.uga": "Ougaritique", - "languages.uig": "Ouïghour", - "languages.ukr": "Ukrainien", - "languages.urd": "Ourdou", - "languages.uzb": "Ouzbeque", - "languages.ven": "Venda", - "languages.vie": "Vietnamien", - "languages.vol": "Volapük", - "languages.win": "Wallon", - "languages.cym": "Gallois", - "languages.wol": "Wolof", - "languages.fry": "Frison occidental", - "languages.xho": "Xhosa", - "languages.yid": "Yiddish", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zoulou", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_gl.json b/COPS/cops-3.1.3/lang/Localization_gl.json deleted file mode 100644 index 3fcd169e..00000000 --- a/COPS/cops-3.1.3/lang/Localization_gl.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "Acerca de COPS", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "Listaxe alfabética de {0} libros", - "allbooks.alphabetical.none": "Listaxe alfabética de absolutamente ningún libro", - "allbooks.alphabetical.one": "Listaxe alfabética de un só libro", - "allbooks.title": "Todos os libros", - "authors.alphabetical.many": "Listaxe alfabética de {0} autores", - "authors.alphabetical.none": "Listaxe alfabética de absolutamente ningún autor", - "authors.alphabetical.one": "Listaxe alfabética de un autor", - "authors.title": "Autores", - "author.title": "Author", - "authorword.many": "{0} autores", - "authorword.none": "Sen autores", - "authorword.one": "1 autor", - "bookentry.author": "{0} de {1}", - "bookword.many": "{0} libros", - "bookword.none": "Sen libros", - "bookword.one": "1 libro", - "bookword.title": "Libros", - "cog.alternate": "Buscar, ordear e filtros", - "content.series": "Series:", - "content.series.data": "Libro {0} na serie {1}", - "content.summary": "Resume", - "customcolumn.boolean.no": "Non", - "customcolumn.boolean.unknown": "Non establecido", - "customcolumn.boolean.yes": "Sí", - "customcolumn.date.format": "Y-m-d", - "customcolumn.date.unknown": "Non establecido", - "customcolumn.description": "Columna personalizada '{0}'", - "customcolumn.description.bool": "Listaxe de un valor ó azar", - "customcolumn.description.enum.many": "Listaxe alfabética de {0} valores", - "customcolumn.description.enum.none": "Listaxe alfabética de absolutamente ningún valor", - "customcolumn.description.enum.one": "Listaxe alfabética de un valor", - "customcolumn.description.rating": "Listaxe de cualificacións", - "customcolumn.description.series.many": "Listaxe alfabética de {0} series", - "customcolumn.description.series.none": "Listaxe alfabética de absolumente ningunha serie", - "customcolumn.description.series.one": "Listaxe de unha serie", - "customcolumn.enum.unknown": "Non establecido", - "customcolumn.float.unknown": "Non establecido", - "customcolumn.int.unknown": "Non establecido", - "customcolumn.rating.unknown": "Non establecido", - "customcolumn.stars.many": "{0} Estrelas", - "customcolumn.stars.none": "Sen estrelas", - "customcolumn.stars.one": "1 Estrela", - "customize.email": "O seu correo (Para envío de libros por correo)", - "customize.fancybox": "Usar LightBox (os libros cargan nun cadro flotante)", - "customize.filter": "Activar filtro por etiqueta", - "customize.ignored": "Ocultar categorías", - "customize.paging": "Max. número de libros por páxina (-1 para desactivar)", - "customize.style": "Tema", - "customize.template": "Template", - "customize.title": "Configurar COPS UI", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Limpar todo", - "filters.title": "Filters", - "home.alternate": "Inicio", - "i18n.coversection": "Cuberta", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Idioma", - "languages.alphabetical.many": "Listaxe alfabética de {0} idiomas", - "languages.alphabetical.none": "Listaxe alfabética de absolutamente ningún idioma", - "languages.alphabetical.one": "Listaxe alfabética de un idioma", - "languages.title": "Idiomas", - "links.title": "Ligazóns", - "mail.messagenotsent": "A mensaxe non se puido enviar.", - "mail.messagesent": "A mensaxe enviouse", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "Seguinte", - "paging.previous.alternate": "Anterior", - "permalink.alternate": "Ligazón permanente", - "pubdate.title": "Published", - "publisher.name": "Editorial", - "publishers.alphabetical.many": "Listaxe alfabética de {0} editoriais", - "publishers.alphabetical.none": "Listaxe alfabética de absolutamente ningunha editorial", - "publishers.alphabetical.one": "Listaxe alfabética de unha editorial", - "publishers.title": "Editoriais", - "publisherword.many": "{0} editoriais", - "publisherword.none": "Sen editoriais", - "publisherword.one": "1 editorial", - "ratings.many": "{0} valoracións", - "ratings.none": "sen valoracións", - "ratings.one": "1 valoración", - "ratings.title": "Puntuacións", - "rating.title": "Rating", - "ratingword.many": "{0} estrelas", - "ratingword.none": "Sen estrelas", - "ratingword.one": "1 estrela", - "recent.list": "{0} libros máis recentes", - "recent.title": "Engadidos recentemente", - "search.alternate": "Buscar", - "search.result": "Resultados de buscar *{0}*", - "search.result.author": "Resultados de buscar *{0}* en autores", - "search.result.book": "Resultados de buscar *{0}* en libros", - "search.result.publisher": "Resultados de buscar *{0}* en editoriais", - "search.result.series": "Resultados de buscar *{0}* en series", - "search.result.tag": "Resultados de buscar *{0}* en etiquetas", - "search.sortorder.asc": "Ascendente", - "search.sortorder.desc": "Descendente", - "series.alphabetical.many": "Listaxe alfabética de {0} series", - "series.alphabetical.none": "Listaxe alfabética de absolutamente ningunha serie", - "series.alphabetical.one": "Listaxe de unha serie", - "series.title": "Series", - "seriesword.many": "{0} series", - "seriesword.none": "Sen series", - "seriesword.one": "1 serie", - "sort.alternate": "Ordenar", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "Outros libros", - "splitByLetter.letter": "{0} que comezan por {1}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "Listaxe alfabética das {0} etiquetas", - "tags.alphabetical.none": "Listaxe alfabética de absolutamente ningunha etiqueta", - "tags.alphabetical.one": "Listaxe alfabética de unha única etiqueta", - "tags.title": "Etiquetas", - "tagword.many": "etiquetas", - "tagword.none": "Sen etiquetas", - "tagword.one": "1 etiqueta", - "tagword.title": "Etiquetas", - "title.title": "Title", - "languages.abk": "Abkhazo", - "languages.aaf": "Afar", - "languages.afr": "Afrikáans", - "languages.aka": "Ákan", - "languages.sqi": "Albano", - "languages.amh": "Amárico", - "languages.ara": "Arabe", - "languages.arg": "Aragonés", - "languages.arc": "Arameo", - "languages.hye": "Armenio", - "languages.asm": "Assamese", - "languages.ava": "Avaric", - "languages.ave": "Avéstica", - "languages.aym": "Aymara", - "languages.aze": "Azerbaiyán", - "languages.bam": "Bambara", - "languages.bak": "Bashkir", - "languages.eus": "Euskera", - "languages.bel": "Belaruso", - "languages.ben": "Bengalí", - "languages.bih": "Bihari", - "languages.bis": "Bislama", - "languages.bos": "Bosnio", - "languages.bre": "Bretón", - "languages.bul": "Bulgaro", - "languages.mya": "Birmano", - "languages.cat": "Catalán", - "languages.cha": "Chamorro", - "languages.che": "Chechen", - "languages.nya": "Chichewa", - "languages.zho": "Chino", - "languages.chv": "Chuvash", - "languages.cor": "Cornish", - "languages.cos": "Córcega", - "languages.cre": "Cree", - "languages.hrv": "Croata", - "languages.ces": "Checo", - "languages.dan": "Danés", - "languages.div": "Divehi", - "languages.nld": "Alemán", - "languages.dzo": "Dzongkha", - "languages.eng": "Inglés", - "languages.epo": "Esperanto", - "languages.est": "Estonio", - "languages.ewe": "Ewe", - "languages.fao": "Faroese", - "languages.fij": "Fiji", - "languages.fin": "Finlandés", - "languages.fra": "Francés", - "languages.ful": "Fula", - "languages.glg": "Galego", - "languages.kat": "Georgiano", - "languages.deu": "Alemán", - "languages.ell": "Griego", - "languages.egy": "Exipcio (antigo)", - "languages.grn": "Guaraní", - "languages.guj": "Gujarati", - "languages.hat": "Haitiano", - "languages.hau": "Hausa", - "languages.heb": "Hebreo", - "languages.her": "Herero", - "languages.hin": "Hindú", - "languages.hmo": "Hiri Motu", - "languages.hun": "Húngaro", - "languages.ina": "Interlingua", - "languages.ind": "Indonesio", - "languages.ile": "Interlingue", - "languages.gle": "Irlandés", - "languages.grc": "Griego antiguo (a 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Islandés", - "languages.ita": "Italiano", - "languages.iku": "Inuktitut", - "languages.jpn": "Xaponés", - "languages.jav": "Xavanés", - "languages.kal": "Kalaallisut", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kashmiri", - "languages.kaz": "Kazakh", - "languages.khm": "Khmer", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kyrgyz", - "languages.kom": "Komi", - "languages.kon": "Congoleño", - "languages.kor": "Coreano", - "languages.kur": "Kurdo", - "languages.kua": "Kwanyama", - "languages.lat": "Latín", - "languages.ltz": "Luxemburgés", - "languages.lug": "Ganda", - "languages.lim": "Limburgish", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Lituano", - "languages.lub": "Luba-Katanga", - "languages.lav": "Letón", - "languages.glv": "Manx", - "languages.mkd": "Macedonio", - "languages.mlg": "Malgache", - "languages.msa": "Malayo", - "languages.mal": "Malayalam", - "languages.mlt": "Maltés", - "languages.mri": "Maorí", - "languages.mar": "Marathi", - "languages.mah": "Marshalés", - "languages.mon": "Mongol", - "languages.nau": "Nauru", - "languages.nav": "Navajo", - "languages.nob": "Bokmål Noruego", - "languages.nde": "Ndebele do Norte", - "languages.nep": "Nepalí", - "languages.ndo": "Ndonga", - "languages.nno": "Nynorsk Noruego", - "languages.nor": "Noruego", - "languages.iii": "Nuosu", - "languages.nbl": "Ndebele do Sur", - "languages.oci": "Occitan", - "languages.oji": "Ojibwe", - "languages.chu": "Antigo eslavo eclesiástico", - "languages.orm": "Oromo", - "languages.ori": "Oriya", - "languages.oss": "Ossetian", - "languages.pan": "Panjabi", - "languages.pli": "Pāli", - "languages.fas": "Persa", - "languages.pol": "Polaco", - "languages.pus": "Pashto", - "languages.por": "Portugués", - "languages.que": "Quechua", - "languages.roh": "Romance", - "languages.run": "Kirundi", - "languages.ron": "Rumano", - "languages.rus": "Ruso", - "languages.sam": "Arameo Samaritano", - "languages.san": "Sánscrito", - "languages.srd": "Sardo", - "languages.snd": "Sindhi", - "languages.sme": "Sami do Norte", - "languages.smo": "Samoano", - "languages.sag": "Sango", - "languages.srp": "Serbio", - "languages.gla": "Escocés Gaélico", - "languages.sna": "Shona", - "languages.sin": "Sinhala", - "languages.slk": "Eslovaco", - "languages.slv": "Sloveno", - "languages.som": "Somalí", - "languages.sot": "Sotho do Sur", - "languages.spa": "Español", - "languages.sun": "Sudanés", - "languages.sux": "Sumerio", - "languages.swa": "Suahili", - "languages.ssw": "Swati", - "languages.swe": "Sueco", - "languages.syc": "Siríaco Clásico", - "languages.syr": "Siríaco", - "languages.tam": "Tamil", - "languages.tel": "Telugu", - "languages.tgk": "Tajik", - "languages.tha": "Tailandés", - "languages.tir": "Tigrinya", - "languages.bod": "Estándar Tibetano", - "languages.tuk": "Turcomano", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tonga", - "languages.tur": "Turco", - "languages.tso": "Tsonga", - "languages.tat": "Tatar", - "languages.twi": "Twi", - "languages.tah": "Tahitiano", - "languages.uga": "Ugarítico", - "languages.uig": "Uighur", - "languages.ukr": "Ucraíno", - "languages.urd": "Urdu", - "languages.uzb": "Uzbek", - "languages.ven": "Venda", - "languages.vie": "Vietnamita", - "languages.vol": "Volapük", - "languages.win": "Valón", - "languages.cym": "Welsh", - "languages.wol": "Wolof", - "languages.fry": "Frisón Occidental", - "languages.xho": "Xhosa", - "languages.yid": "Yiddish", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulú", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_hr.json b/COPS/cops-3.1.3/lang/Localization_hr.json deleted file mode 100644 index 1242e799..00000000 --- a/COPS/cops-3.1.3/lang/Localization_hr.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "O sustavu COPS", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "Abecedni popis {0} knjiga", - "allbooks.alphabetical.none": "Alphabetical index of absolutely no books", - "allbooks.alphabetical.one": "Alphabetical index of the single book", - "allbooks.title": "Sve knjige", - "authors.alphabetical.many": "Alphabetical index of the {0} authors", - "authors.alphabetical.none": "Alphabetical index of absolutely no authors", - "authors.alphabetical.one": "Alphabetical index of the single author", - "authors.title": "Autori", - "author.title": "Author", - "authorword.many": "{0} autori", - "authorword.none": "Nema autora", - "authorword.one": "1 autor", - "bookentry.author": "{0} by {1}", - "bookword.many": "{0} knjiga", - "bookword.none": "Nema knjiga", - "bookword.one": "1 knjiga", - "bookword.title": "Knjige", - "cog.alternate": "Search, sort and filters", - "content.series": "Series:", - "content.series.data": "Book {0} in the {1} series", - "content.summary": "Sadržaj", - "customcolumn.boolean.no": "Ne", - "customcolumn.boolean.unknown": "Not Set", - "customcolumn.boolean.yes": "Da", - "customcolumn.date.format": "G-m-d", - "customcolumn.date.unknown": "Nije postavljeno", - "customcolumn.description": "Custom column '{0}'", - "customcolumn.description.bool": "Index of a boolean value", - "customcolumn.description.enum.many": "Alphabetical index of the {0} values", - "customcolumn.description.enum.none": "Alphabetical index of absolutely no values", - "customcolumn.description.enum.one": "Alphabetical index of one value", - "customcolumn.description.rating": "Index of ratings", - "customcolumn.description.series.many": "Alphabetical index of the {0} series", - "customcolumn.description.series.none": "Alphabetical index of absolutely no series", - "customcolumn.description.series.one": "Alphabetical index of the single series", - "customcolumn.enum.unknown": "Not Set", - "customcolumn.float.unknown": "Not Set", - "customcolumn.int.unknown": "Not Set", - "customcolumn.rating.unknown": "Not Set", - "customcolumn.stars.many": "{0} Stars", - "customcolumn.stars.none": "No Stars", - "customcolumn.stars.one": "1 Star", - "customize.email": "Set your email (to allow book emailing)", - "customize.fancybox": "Use Lightbox (books load in floating frame)", - "customize.filter": "Enable tag filtering", - "customize.ignored": "Ignored categories", - "customize.paging": "Max number of books per page (-1 to disable)", - "customize.style": "Tema", - "customize.template": "Template", - "customize.title": "Promijeni izgled COPS sučelja", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Clear all", - "filters.title": "Filters", - "home.alternate": "Home", - "i18n.coversection": "Cover", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Jezik", - "languages.alphabetical.many": "Alphabetical index of the {0} languages", - "languages.alphabetical.none": "Alphabetical index of absolutely no languages", - "languages.alphabetical.one": "Alphabetical index of the single language", - "languages.title": "Jezici", - "links.title": "Linkovi", - "mail.messagenotsent": "Message could not be sent.", - "mail.messagesent": "Message has been sent", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "Next", - "paging.previous.alternate": "Previous", - "permalink.alternate": "Permalink", - "pubdate.title": "Published", - "publisher.name": "Izdavač", - "publishers.alphabetical.many": "Alphabetical index of the {0} publishers", - "publishers.alphabetical.none": "Alphabetical index of absolutely no publishers", - "publishers.alphabetical.one": "Alphabetical index of the single publisher", - "publishers.title": "Izdavači", - "publisherword.many": "{0} publishers", - "publisherword.none": "No publishers", - "publisherword.one": "1 publisher", - "ratings.many": "{0} ratings", - "ratings.none": "no ratings", - "ratings.one": "1 rating", - "ratings.title": "Ratings", - "rating.title": "Rating", - "ratingword.many": "{0} stars", - "ratingword.none": "No star", - "ratingword.one": "1 star", - "recent.list": "{0} most recent books", - "recent.title": "Recent additions", - "search.alternate": "Search", - "search.result": "Search result for *{0}*", - "search.result.author": "Search result for *{0}* in authors", - "search.result.book": "Search result for *{0}* in books", - "search.result.publisher": "Search result for *{0}* in publishers", - "search.result.series": "Search result for *{0}* in series", - "search.result.tag": "Search result for *{0}* in tags", - "search.sortorder.asc": "Uzlazno", - "search.sortorder.desc": "Silazno", - "series.alphabetical.many": "Abecedni popis {0} serijala", - "series.alphabetical.none": "Abecedni popis bez serijala", - "series.alphabetical.one": "Abecedni popis jednog serijala", - "series.title": "Serijali", - "seriesword.many": "{0} serijala", - "seriesword.none": "Nema unosa", - "seriesword.one": "1 serijal", - "sort.alternate": "Rasporedi", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "Ostale knjige", - "splitByLetter.letter": "{0} koje počinju sa {1}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "Abecedni popis {0} oznaka", - "tags.alphabetical.none": "Abecedni popis bez oznaka", - "tags.alphabetical.one": "Abecedni popis jedne oznake", - "tags.title": "Oznake", - "tagword.many": "{0} oznaka", - "tagword.none": "Nema oznaka", - "tagword.one": "1 oznaka", - "tagword.title": "Oznake", - "title.title": "Title", - "languages.abk": "Abkhaz", - "languages.aaf": "Afarski", - "languages.afr": "Afrikaans", - "languages.aka": "Akanski", - "languages.sqi": "Albanski", - "languages.amh": "Amharic", - "languages.ara": "Arapski", - "languages.arg": "Aragonski", - "languages.arc": "Aramejski", - "languages.hye": "Armenski", - "languages.asm": "Assamese", - "languages.ava": "Avarski", - "languages.ave": "Avestanski", - "languages.aym": "Aymarski", - "languages.aze": "Azerbajdžanski", - "languages.bam": "Bambarski", - "languages.bak": "Bashkirski", - "languages.eus": "Baskijski", - "languages.bel": "Bjeloruski", - "languages.ben": "Bengalski", - "languages.bih": "Bihari", - "languages.bis": "Bislamski", - "languages.bos": "Bosanski", - "languages.bre": "Bretonski", - "languages.bul": "Bugarski", - "languages.mya": "Burmeški", - "languages.cat": "Katalonski", - "languages.cha": "Chamorro", - "languages.che": "Čečenski", - "languages.nya": "Chichewa", - "languages.zho": "Kineski", - "languages.chv": "Chuvash", - "languages.cor": "Cornish", - "languages.cos": "Korzikanski", - "languages.cre": "Cree", - "languages.hrv": "Hrvatski", - "languages.ces": "Češki", - "languages.dan": "Danski", - "languages.div": "Divehi", - "languages.nld": "Nizozemski", - "languages.dzo": "Dzongkha", - "languages.eng": "Engleski", - "languages.epo": "Esperanto", - "languages.est": "Estonski", - "languages.ewe": "Ewe", - "languages.fao": "Faroeški", - "languages.fij": "Fidžijski", - "languages.fin": "Finski", - "languages.fra": "Francuski", - "languages.ful": "Fula", - "languages.glg": "Galićanski", - "languages.kat": "Gruzijski", - "languages.deu": "Njemački", - "languages.ell": "Grčki", - "languages.egy": "Egipatski (Drevni)", - "languages.grn": "Guaraní", - "languages.guj": "Gujarati", - "languages.hat": "Haićanski", - "languages.hau": "Hausa", - "languages.heb": "Hebrejski", - "languages.her": "Herero", - "languages.hin": "Hindi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Mađarski", - "languages.ina": "Interlingua", - "languages.ind": "Indonezijski", - "languages.ile": "Interlingue", - "languages.gle": "Irski", - "languages.grc": "Starogrčki", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Islandski", - "languages.ita": "Talijanski", - "languages.iku": "Inuktitut", - "languages.jpn": "Japanski", - "languages.jav": "Javanski", - "languages.kal": "Kalaallisut", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kašmirski", - "languages.kaz": "Kazački", - "languages.khm": "Kmerski", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kirgiški", - "languages.kom": "Komi", - "languages.kon": "Kongoanski", - "languages.kor": "Korejski", - "languages.kur": "Kurdski", - "languages.kua": "Kwanyama", - "languages.lat": "Latinski", - "languages.ltz": "Luksemburški", - "languages.lug": "Gandski", - "languages.lim": "Limburgish", - "languages.lin": "Lingala", - "languages.lao": "Laoški", - "languages.lit": "Litvanski", - "languages.lub": "Luba-Katanga", - "languages.lav": "Latvijski", - "languages.glv": "Manx", - "languages.mkd": "Makedonski", - "languages.mlg": "Malagasy", - "languages.msa": "Malajski", - "languages.mal": "Malayalam", - "languages.mlt": "Malteški", - "languages.mri": "Maorski", - "languages.mar": "Marathi", - "languages.mah": "Maršalski", - "languages.mon": "Mongolski", - "languages.nau": "Nauru", - "languages.nav": "Navajo", - "languages.nob": "Norveški Bokmål", - "languages.nde": "Sjeverni Ndebele", - "languages.nep": "Nepalski", - "languages.ndo": "Ndonga", - "languages.nno": "Norveški Nynorsk", - "languages.nor": "Norveški", - "languages.iii": "Nuosu", - "languages.nbl": "Južni Ndebele", - "languages.oci": "Occitan", - "languages.oji": "Ojibwe", - "languages.chu": "Crkveni Staroslavenski", - "languages.orm": "Oromo", - "languages.ori": "Oriya", - "languages.oss": "Osečki", - "languages.pan": "Panjabi", - "languages.pli": "Pāli", - "languages.fas": "Perzijski", - "languages.pol": "Poljski", - "languages.pus": "Pashto", - "languages.por": "Portugalski", - "languages.que": "Quenchua", - "languages.roh": "Romansh", - "languages.run": "Kirundi", - "languages.ron": "Rumunjski", - "languages.rus": "Ruski", - "languages.sam": "Samaritanski Aramejski", - "languages.san": "Sanskrt", - "languages.srd": "Sardinski", - "languages.snd": "Sindhi", - "languages.sme": "Sjeverni Sami", - "languages.smo": "Samoanski", - "languages.sag": "Sangoanski", - "languages.srp": "Srbski", - "languages.gla": "Škotski Galski", - "languages.sna": "Shona", - "languages.sin": "Sinhala", - "languages.slk": "Slovački", - "languages.slv": "Slovenski", - "languages.som": "Somalski", - "languages.sot": "Južni Sotho", - "languages.spa": "Španjolski", - "languages.sun": "Sundanski", - "languages.sux": "Sumerski", - "languages.swa": "Swahili", - "languages.ssw": "Swati", - "languages.swe": "Švedski", - "languages.syc": "Klasični Sirijski", - "languages.syr": "Sirijski", - "languages.tam": "Tamilski", - "languages.tel": "Telugu", - "languages.tgk": "Ta‮‭đjikistanski", - "languages.tha": "Thai", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetanski", - "languages.tuk": "Turkmenski", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tonga", - "languages.tur": "Turski", - "languages.tso": "Tsonga", - "languages.tat": "Tatarski", - "languages.twi": "Twi", - "languages.tah": "Tahićanski", - "languages.uga": "Ugaritic", - "languages.uig": "Ujgurski", - "languages.ukr": "Ukrajinski", - "languages.urd": "Urdu", - "languages.uzb": "Uzbečki", - "languages.ven": "Venda", - "languages.vie": "Vijetnamski", - "languages.vol": "Volapük", - "languages.win": "Walloon", - "languages.cym": "Velški", - "languages.wol": "Wolof", - "languages.fry": "Zapadni Frižanski", - "languages.xho": "Xhosa", - "languages.yid": "Jidiš", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_ht.json b/COPS/cops-3.1.3/lang/Localization_ht.json deleted file mode 100644 index b446d1dd..00000000 --- a/COPS/cops-3.1.3/lang/Localization_ht.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "A pwopo COPS", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "lòd endèks nan {0} liv", - "allbooks.alphabetical.none": "lòd endèks nan yon liv", - "allbooks.alphabetical.one": "lòd endèks nan yon sèl liv", - "allbooks.title": "Tout liv", - "authors.alphabetical.many": "lòd endèks nan otè {0}", - "authors.alphabetical.none": "lòd endèks ki pa gen otè", - "authors.alphabetical.one": "lòd endèks nan yon sèl otè", - "authors.title": "Otè", - "author.title": "Author", - "authorword.many": "{0} Otè", - "authorword.none": "Pa gen otè", - "authorword.one": "1 otè", - "bookentry.author": "{0} de {1}", - "bookword.many": "{0} liv", - "bookword.none": "Pa gen liv", - "bookword.one": "1 liv", - "bookword.title": "Liv", - "cog.alternate": "Chèche, sòt ak filtre", - "content.series": "Koleksyon:", - "content.series.data": "Liv {0} ki nan koleksyon an {1}", - "content.summary": "Rezime:", - "customcolumn.boolean.no": "No", - "customcolumn.boolean.unknown": "Not Set", - "customcolumn.boolean.yes": "Yes", - "customcolumn.date.format": "Y-m-d", - "customcolumn.date.unknown": "Not Set", - "customcolumn.description": "Custom column '{0}'", - "customcolumn.description.bool": "Index of a boolean value", - "customcolumn.description.enum.many": "Alphabetical index of the {0} values", - "customcolumn.description.enum.none": "Alphabetical index of absolutely no values", - "customcolumn.description.enum.one": "Alphabetical index of one value", - "customcolumn.description.rating": "Index of ratings", - "customcolumn.description.series.many": "Lòd endèks nan {0} koleksyon s", - "customcolumn.description.series.none": "Lòd endèks nan absoliman okenn seri", - "customcolumn.description.series.one": "Lòd endèks nan koleksyon an sèlman", - "customcolumn.enum.unknown": "Not Set", - "customcolumn.float.unknown": "Not Set", - "customcolumn.int.unknown": "Not Set", - "customcolumn.rating.unknown": "Not Set", - "customcolumn.stars.many": "{0} Stars", - "customcolumn.stars.none": "No Stars", - "customcolumn.stars.one": "1 Star", - "customize.email": "adrès Imèl (pou otomatik voye nan liv )", - "customize.fancybox": "Sèvi ak yon bwat limyè", - "customize.filter": "Filtraj atravè Tags", - "customize.ignored": "inyore Kategori", - "customize.paging": "Nimewo nan liv pou chak paj (-1 vin enfim )", - "customize.style": "Tèm", - "customize.template": "Template", - "customize.title": "Mete flik COPS", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Clear all", - "filters.title": "Filters", - "home.alternate": "Kay", - "i18n.coversection": "Kouvri", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Lang", - "languages.alphabetical.many": "Lòd endèks nan {0} lang", - "languages.alphabetical.none": "Lòd endèks nan absoliman okenn lang", - "languages.alphabetical.one": "Lòd endèks pale yon sèl lang", - "languages.title": "Lang", - "links.title": "Links", - "mail.messagenotsent": "Mesaj la pa t 'kapab ap voye.", - "mail.messagesent": "te mesaj la te voye", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "Suivant", - "paging.previous.alternate": "Pwochen", - "permalink.alternate": "Permalien", - "pubdate.title": "Published", - "publisher.name": "Editè", - "publishers.alphabetical.many": "Lòd endèks nan {0} editè", - "publishers.alphabetical.none": "Lòd endèks nan absoliman okenn piblikatè", - "publishers.alphabetical.one": "Lòd Index Editè", - "publishers.title": "Piblikatè", - "publisherword.many": "{0} editè", - "publisherword.none": "Pa gen editè", - "publisherword.one": "1 editè", - "ratings.many": "{0} Li renmen", - "ratings.none": "Pa gen evalyasyon", - "ratings.one": "1 Revizyon", - "ratings.title": "Li renmen", - "rating.title": "Rating", - "ratingword.many": "{0} zetwal", - "ratingword.none": "Pa gen Etwal", - "ratingword.one": "1 etwal", - "recent.list": "{0} liv ki pi resan", - "recent.title": "Dènyèman te ajoute", - "search.alternate": "Chèche", - "search.result": "Rezilta pou *{0}*", - "search.result.author": "Rezilta pou * {0} * nan otè yo", - "search.result.book": "Rezilta pou * {0} * nan liv yo", - "search.result.publisher": "Rezilta pou * {0} * nan editè yo", - "search.result.series": "Rezilta pou * {0} * nan koleksyon", - "search.result.tag": "Rezilta pou * {0} * nan etikèt", - "search.sortorder.asc": "Mete konfyans nou.", - "search.sortorder.desc": "Ap desann.", - "series.alphabetical.many": "Lòd endèks nan {0} koleksyon s", - "series.alphabetical.none": "Lòd endèks nan absoliman okenn seri", - "series.alphabetical.one": "Lòd endèks nan koleksyon an sèlman", - "series.title": "Koleksyon", - "seriesword.many": "{0} koleksyon", - "seriesword.none": "Pa gen koleksyon", - "seriesword.one": "1 koleksyon", - "sort.alternate": "Triye", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "lòt liv", - "splitByLetter.letter": "{0} kòmanse avèk {1}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "Lòd endèks nan etikèt {0}", - "tags.alphabetical.none": "Lòd endèks nan absoliman okenn tags", - "tags.alphabetical.one": "Lòd endèks nan etikèt la sèl", - "tags.title": "Etikèt", - "tagword.many": "{0} etikèt", - "tagword.none": "Tagless", - "tagword.one": "1 tag", - "tagword.title": "Etikèt", - "title.title": "Title", - "languages.abk": "Abkhaz", - "languages.aaf": "Afar", - "languages.afr": "Afrikaans", - "languages.aka": "Akan", - "languages.sqi": "Albanian", - "languages.amh": "Amharic", - "languages.ara": "Arabic", - "languages.arg": "Aragonese", - "languages.arc": "Aramaic", - "languages.hye": "Armenian", - "languages.asm": "Assamese", - "languages.ava": "Avaric", - "languages.ave": "Avestan", - "languages.aym": "Aymara", - "languages.aze": "Azerbaijani", - "languages.bam": "Bambara", - "languages.bak": "Bashkir", - "languages.eus": "Basque", - "languages.bel": "Belarusian", - "languages.ben": "Bengali", - "languages.bih": "Bihari", - "languages.bis": "Bislama", - "languages.bos": "Bosnian", - "languages.bre": "Breton", - "languages.bul": "Bulgarian", - "languages.mya": "Burmese", - "languages.cat": "Catalan", - "languages.cha": "Chamorro", - "languages.che": "Chechen", - "languages.nya": "Chichewa", - "languages.zho": "Chinese", - "languages.chv": "Chuvash", - "languages.cor": "Cornish", - "languages.cos": "Corsican", - "languages.cre": "Cree", - "languages.hrv": "Croatian", - "languages.ces": "Czech", - "languages.dan": "Danish", - "languages.div": "Divehi", - "languages.nld": "Dutch", - "languages.dzo": "Dzongkha", - "languages.eng": "Anglais", - "languages.epo": "Esperanto", - "languages.est": "Estonian", - "languages.ewe": "Ewe", - "languages.fao": "Faroese", - "languages.fij": "Fijian", - "languages.fin": "Finnish", - "languages.fra": "Français", - "languages.ful": "Fula", - "languages.glg": "Galician", - "languages.kat": "Georgian", - "languages.deu": "German", - "languages.ell": "Greek", - "languages.egy": "Egyptian (Ancient)", - "languages.grn": "Guaraní", - "languages.guj": "Gujarati", - "languages.hat": "Haitian", - "languages.hau": "Hausa", - "languages.heb": "Hebrew", - "languages.her": "Herero", - "languages.hin": "Hindi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Hungarian", - "languages.ina": "Interlingua", - "languages.ind": "Indonesian", - "languages.ile": "Interlingue", - "languages.gle": "Irish", - "languages.grc": "Greek, Ancient (to 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Icelandic", - "languages.ita": "Italian", - "languages.iku": "Inuktitut", - "languages.jpn": "Japanese", - "languages.jav": "Javanese", - "languages.kal": "Kalaallisut", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kashmiri", - "languages.kaz": "Kazakh", - "languages.khm": "Khmer", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kyrgyz", - "languages.kom": "Komi", - "languages.kon": "Kongo", - "languages.kor": "Korean", - "languages.kur": "Kurdish", - "languages.kua": "Kwanyama", - "languages.lat": "Latin", - "languages.ltz": "Luxembourgish", - "languages.lug": "Ganda", - "languages.lim": "Limburgish", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Lithuanian", - "languages.lub": "Luba-Katanga", - "languages.lav": "Latvian", - "languages.glv": "Manx", - "languages.mkd": "Macedonian", - "languages.mlg": "Malagasy", - "languages.msa": "Malay", - "languages.mal": "Malayalam", - "languages.mlt": "Maltese", - "languages.mri": "Māori", - "languages.mar": "Marathi", - "languages.mah": "Marshallese", - "languages.mon": "Mongolian", - "languages.nau": "Nauru", - "languages.nav": "Navajo", - "languages.nob": "Norwegian Bokmål", - "languages.nde": "North Ndebele", - "languages.nep": "Nepali", - "languages.ndo": "Ndonga", - "languages.nno": "Norwegian Nynorsk", - "languages.nor": "Norwegian", - "languages.iii": "Nuosu", - "languages.nbl": "South Ndebele", - "languages.oci": "Occitan", - "languages.oji": "Ojibwe", - "languages.chu": "Old Church Slavonic", - "languages.orm": "Oromo", - "languages.ori": "Oriya", - "languages.oss": "Ossetian", - "languages.pan": "Panjabi", - "languages.pli": "Pāli", - "languages.fas": "Persian", - "languages.pol": "Polish", - "languages.pus": "Pashto", - "languages.por": "Portuguese", - "languages.que": "Quechua", - "languages.roh": "Romansh", - "languages.run": "Kirundi", - "languages.ron": "Romanian", - "languages.rus": "Russian", - "languages.sam": "Samaritan Aramaic", - "languages.san": "Sanskrit", - "languages.srd": "Sardinian", - "languages.snd": "Sindhi", - "languages.sme": "Northern Sami", - "languages.smo": "Samoan", - "languages.sag": "Sango", - "languages.srp": "Serbian", - "languages.gla": "Scottish Gaelic", - "languages.sna": "Shona", - "languages.sin": "Sinhala", - "languages.slk": "Slovak", - "languages.slv": "Slovene", - "languages.som": "Somali", - "languages.sot": "Southern Sotho", - "languages.spa": "Spanish", - "languages.sun": "Sundanese", - "languages.sux": "Sumerian", - "languages.swa": "Swahili", - "languages.ssw": "Swati", - "languages.swe": "Swedish", - "languages.syc": "Classical Syriac", - "languages.syr": "Syriac", - "languages.tam": "Tamil", - "languages.tel": "Telugu", - "languages.tgk": "Tajik", - "languages.tha": "Thai", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetan Standard", - "languages.tuk": "Turkmen", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tonga", - "languages.tur": "Turkish", - "languages.tso": "Tsonga", - "languages.tat": "Tatar", - "languages.twi": "Twi", - "languages.tah": "Tahitian", - "languages.uga": "Ugaritic", - "languages.uig": "Uighur", - "languages.ukr": "Ukrainian", - "languages.urd": "Urdu", - "languages.uzb": "Uzbek", - "languages.ven": "Venda", - "languages.vie": "Vietnamese", - "languages.vol": "Volapük", - "languages.win": "Walloon", - "languages.cym": "Welsh", - "languages.wol": "Wolof", - "languages.fry": "Western Frisian", - "languages.xho": "Xhosa", - "languages.yid": "Yiddish", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_hu.json b/COPS/cops-3.1.3/lang/Localization_hu.json deleted file mode 100644 index c27d31c6..00000000 --- a/COPS/cops-3.1.3/lang/Localization_hu.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "A COPS névjegye", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "{0} könyv betűrendben", - "allbooks.alphabetical.none": "Egy könyv sincs", - "allbooks.alphabetical.one": "Egyetlen könyv", - "allbooks.title": "Minden könyv", - "authors.alphabetical.many": "{0} szerző betűrendben", - "authors.alphabetical.none": "Szerző nélkül betűrendben", - "authors.alphabetical.one": "Egyetlen szerző", - "authors.title": "Szerzők", - "author.title": "Author", - "authorword.many": "{0} szerző", - "authorword.none": "Nincs szerző", - "authorword.one": "Egy szerző", - "bookentry.author": "{0} {1} szerint", - "bookword.many": "{0} könyv", - "bookword.none": "Nincs könyv", - "bookword.one": "1 könyv", - "bookword.title": "Könyvek", - "cog.alternate": "Keresés, rendezés és szürés", - "content.series": "Sorozatok:", - "content.series.data": "{1} sorozat {0}. könyve", - "content.summary": "Ismertető", - "customcolumn.boolean.no": "Nem", - "customcolumn.boolean.unknown": "Nincs megadva", - "customcolumn.boolean.yes": "Igen", - "customcolumn.date.format": "Y. m. d.", - "customcolumn.date.unknown": "Nincs megadva", - "customcolumn.description": "„{0}” saját oszlop", - "customcolumn.description.bool": "Logikai értékek listája", - "customcolumn.description.enum.many": "{0} érték betűrendben", - "customcolumn.description.enum.none": "Érték nélkül betűrendben", - "customcolumn.description.enum.one": "Egyetlen érték", - "customcolumn.description.rating": "Értékelések listája", - "customcolumn.description.series.many": "{0} sorozat betűrendben", - "customcolumn.description.series.none": "Sorozat nélkül betűrendben", - "customcolumn.description.series.one": "Egyetlen sorozat", - "customcolumn.enum.unknown": "Nincs megadva", - "customcolumn.float.unknown": "Nincs megadva", - "customcolumn.int.unknown": "Nincs megadva", - "customcolumn.rating.unknown": "Nincs megadva", - "customcolumn.stars.many": "{0} csillag", - "customcolumn.stars.none": "Nincs csillag", - "customcolumn.stars.one": "Egy csillag", - "customize.email": "Állítsd be az email címed (engedélyezi a könyvek küldését emailben)", - "customize.fancybox": "Lightbox használata (a könyvek részletei lebegő keretben fognak megjelenni)", - "customize.filter": "Engedélyezi a címke alapú a szűrést", - "customize.ignored": "Figyelmen kivül hagyott kategóriák", - "customize.paging": "Maximum könyv oldalanként (-1 kikapcsolja)", - "customize.style": "Téma", - "customize.template": "Template", - "customize.title": "Saját COPS felület", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Összes törlése", - "filters.title": "Filters", - "home.alternate": "Kezdőlap", - "i18n.coversection": "Boritó", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Nyelv", - "languages.alphabetical.many": "{0} nyelv betűrendben", - "languages.alphabetical.none": "Nyelv nélkül betűrendben", - "languages.alphabetical.one": "Egyetlen nyelv", - "languages.title": "Nyelvek", - "links.title": "Hivatkozások", - "mail.messagenotsent": "Az üzenetet nem sikerült elküldeni.", - "mail.messagesent": "Az üzenet elküldve", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "Következő", - "paging.previous.alternate": "Elöző", - "permalink.alternate": "Permalink", - "pubdate.title": "Published", - "publisher.name": "Kiadó", - "publishers.alphabetical.many": "{0} kiadó betűrendben", - "publishers.alphabetical.none": "Kiadó nélkül betűrendben", - "publishers.alphabetical.one": "Egyetlen kiadó", - "publishers.title": "Kiadók", - "publisherword.many": "{0} kiadó", - "publisherword.none": "Nincs kiadó", - "publisherword.one": "Egy kiadó", - "ratings.many": "{0} értékelés", - "ratings.none": "Nincs értékelés", - "ratings.one": "Egy értékelés", - "ratings.title": "Értékelések", - "rating.title": "Rating", - "ratingword.many": "{0} csillag", - "ratingword.none": "Nincs csillag", - "ratingword.one": "Egy csillag", - "recent.list": "{0} legutóbbi könyv", - "recent.title": "Utoljára hozzáadottak", - "search.alternate": "Keresés", - "search.result": "Keresés eredménye a következőre: „{0}”", - "search.result.author": "Keresés eredménye „{0}”-ra a szerzők között:", - "search.result.book": "Keresés eredménye „{0}”-ra a könyvcímek között:", - "search.result.publisher": "Keresés eredménye „{0}”-ra a kiadók között:", - "search.result.series": "Keresés eredménye „{0}”-ra a sorozatok között:", - "search.result.tag": "Keresés eredménye „{0}”-ra a címkék között:", - "search.sortorder.asc": "Emelkedő", - "search.sortorder.desc": "Csökkenő", - "series.alphabetical.many": "{0} sorozat betűrendben", - "series.alphabetical.none": "Sorozat nélkül betűrendben", - "series.alphabetical.one": "Egyetlen sorozat", - "series.title": "Sorozatok", - "seriesword.many": "{0} sorozat", - "seriesword.none": "Nincs sorozat", - "seriesword.one": "1 sorozat", - "sort.alternate": "Rendezés", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "Egyéb könyvek", - "splitByLetter.letter": "{0} kezdőbetűje {1}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "{0} címke betűrendben", - "tags.alphabetical.none": "Címke nélkül betűrendben", - "tags.alphabetical.one": "Egyetlen címke", - "tags.title": "Címkék", - "tagword.many": "{0} címke", - "tagword.none": "Nincs címke", - "tagword.one": "1 címke", - "tagword.title": "Címkék", - "title.title": "Title", - "languages.abk": "abház", - "languages.aaf": "afari", - "languages.afr": "afrikaans", - "languages.aka": "akan", - "languages.sqi": "albán", - "languages.amh": "amhara", - "languages.ara": "arab", - "languages.arg": "aragóni", - "languages.arc": "Aramaic", - "languages.hye": "örmény", - "languages.asm": "asszámi", - "languages.ava": "avar", - "languages.ave": "avesztai", - "languages.aym": "ajmara", - "languages.aze": "azeri", - "languages.bam": "bambara", - "languages.bak": "baskír", - "languages.eus": "baszk", - "languages.bel": "fehérorosz", - "languages.ben": "bengáli", - "languages.bih": "bihári", - "languages.bis": "biszlama", - "languages.bos": "bosnyák", - "languages.bre": "breton", - "languages.bul": "bolgár", - "languages.mya": "burmai", - "languages.cat": "katalán", - "languages.cha": "csaromo", - "languages.che": "csecsen", - "languages.nya": "cseva", - "languages.zho": "kínai", - "languages.chv": "csuvas", - "languages.cor": "korni", - "languages.cos": "korzikai", - "languages.cre": "krí", - "languages.hrv": "horvát", - "languages.ces": "cseh", - "languages.dan": "dán", - "languages.div": "maldív", - "languages.nld": "holland", - "languages.dzo": "dzongkha", - "languages.eng": "angol", - "languages.epo": "eszperantó", - "languages.est": "észt", - "languages.ewe": "eve", - "languages.fao": "feröeri", - "languages.fij": "fidzsi", - "languages.fin": "finn", - "languages.fra": "francia", - "languages.ful": "ful", - "languages.glg": "galíciai", - "languages.kat": "grúz", - "languages.deu": "német", - "languages.ell": "görög", - "languages.egy": "Egyptian (Ancient)", - "languages.grn": "guarani", - "languages.guj": "gudzsaráti", - "languages.hat": "haiti", - "languages.hau": "hausza", - "languages.heb": "héber", - "languages.her": "herero", - "languages.hin": "hindi", - "languages.hmo": "hiri motu", - "languages.hun": "magyar", - "languages.ina": "interlingva", - "languages.ind": "indonéz", - "languages.ile": "interlingue", - "languages.gle": "ír", - "languages.grc": "Greek, Ancient (to 1453)", - "languages.ibo": "igbo", - "languages.ipk": "inupiak", - "languages.ido": "ido", - "languages.isl": "izlandi", - "languages.ita": "olasz", - "languages.iku": "inuktitut", - "languages.jpn": "japán", - "languages.jav": "jávai", - "languages.kal": "grönlandi", - "languages.kan": "kannada", - "languages.kau": "kanuri", - "languages.kas": "kasmíri", - "languages.kaz": "kazah", - "languages.khm": "khmer", - "languages.kik": "kikuju", - "languages.kin": "kinyarvanda", - "languages.kir": "kirgiz", - "languages.kom": "komi", - "languages.kon": "kikongo", - "languages.kor": "koreai", - "languages.kur": "kurd", - "languages.kua": "kvanyama", - "languages.lat": "latin", - "languages.ltz": "luxemburgi", - "languages.lug": "luganda", - "languages.lim": "limburgi", - "languages.lin": "lingala", - "languages.lao": "lao", - "languages.lit": "litván", - "languages.lub": "luba-katanga", - "languages.lav": "lett", - "languages.glv": "manx", - "languages.mkd": "makedón", - "languages.mlg": "malgas", - "languages.msa": "maláj", - "languages.mal": "malajálam", - "languages.mlt": "máltai", - "languages.mri": "maori", - "languages.mar": "maráthi", - "languages.mah": "marshall-szigeteki", - "languages.mon": "mongol", - "languages.nau": "naurui", - "languages.nav": "navahó", - "languages.nob": "norvég", - "languages.nde": "észak ndebele", - "languages.nep": "nepáli", - "languages.ndo": "ndonga", - "languages.nno": "norvég (nynorsk)", - "languages.nor": "norvég", - "languages.iii": "nuoszu", - "languages.nbl": "dél ndebele", - "languages.oci": "okcitán", - "languages.oji": "odzsibva", - "languages.chu": "óegyházi szláv", - "languages.orm": "oromó", - "languages.ori": "orija", - "languages.oss": "oszét", - "languages.pan": "pandzsabi", - "languages.pli": "páli", - "languages.fas": "perzsa", - "languages.pol": "lengyel", - "languages.pus": "pastu", - "languages.por": "portugál", - "languages.que": "kecsua", - "languages.roh": "romans", - "languages.run": "rundi", - "languages.ron": "román", - "languages.rus": "orosz", - "languages.sam": "Samaritan Aramaic", - "languages.san": "szanszkrit", - "languages.srd": "szárd", - "languages.snd": "szindhi", - "languages.sme": "északi számi", - "languages.smo": "szamoai", - "languages.sag": "szangó", - "languages.srp": "szerb", - "languages.gla": "skót", - "languages.sna": "sona", - "languages.sin": "sinhala", - "languages.slk": "szlovák", - "languages.slv": "szlovén", - "languages.som": "szomáli", - "languages.sot": "déli szoto", - "languages.spa": "spanyol", - "languages.sun": "szundai", - "languages.sux": "Sumerian", - "languages.swa": "szuahéli", - "languages.ssw": "szvázi", - "languages.swe": "svéd", - "languages.syc": "Classical Syriac", - "languages.syr": "Syriac", - "languages.tam": "tamil", - "languages.tel": "telugu", - "languages.tgk": "tádzsik", - "languages.tha": "thai", - "languages.tir": "tigrinyai", - "languages.bod": "tibeti", - "languages.tuk": "türkmén", - "languages.tgl": "tagalog", - "languages.tsn": "csvana", - "languages.ton": "tonga", - "languages.tur": "török", - "languages.tso": "conga", - "languages.tat": "tatár", - "languages.twi": "tvi", - "languages.tah": "tahiti", - "languages.uga": "Ugaritic", - "languages.uig": "ulgur", - "languages.ukr": "ukrán", - "languages.urd": "urdu", - "languages.uzb": "üzbég", - "languages.ven": "venda", - "languages.vie": "vietnámi", - "languages.vol": "volapük", - "languages.win": "vallon", - "languages.cym": "walesi", - "languages.wol": "volof", - "languages.fry": "fríz", - "languages.xho": "xhosza", - "languages.yid": "jiddis", - "languages.yor": "joruba", - "languages.zha": "csuang", - "languages.zul": "zulu", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_id.json b/COPS/cops-3.1.3/lang/Localization_id.json deleted file mode 100644 index 1aa400bc..00000000 --- a/COPS/cops-3.1.3/lang/Localization_id.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "Tentang COPS", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "Alphabetical index of the {0} books", - "allbooks.alphabetical.none": "Alphabetical index of absolutely no books", - "allbooks.alphabetical.one": "Alphabetical index of the single book", - "allbooks.title": "Semua Buku", - "authors.alphabetical.many": "Urutan Penulis ke {0} berdasarkan huruf", - "authors.alphabetical.none": "Alphabetical index of absolutely no authors", - "authors.alphabetical.one": "Alphabetical index of the single author", - "authors.title": "Penulis", - "author.title": "Author", - "authorword.many": "{0} penulis", - "authorword.none": "Tidak ada penulis", - "authorword.one": "1 penulis", - "bookentry.author": "{0} dari {1}", - "bookword.many": "{0} buku", - "bookword.none": "Tidak ada buku", - "bookword.one": "1 buku", - "bookword.title": "Buku - buku", - "cog.alternate": "Cari, urut dan saring", - "content.series": "Seri:", - "content.series.data": "Buku ke {0} pada {1} seri", - "content.summary": "Ringkasan", - "customcolumn.boolean.no": "Kosong", - "customcolumn.boolean.unknown": "Tidak diatur", - "customcolumn.boolean.yes": "Ada", - "customcolumn.date.format": "Tahun-Bulan-Tanggal", - "customcolumn.date.unknown": "Tidak diatur", - "customcolumn.description": "Custom column '{0}'", - "customcolumn.description.bool": "Index of a boolean value", - "customcolumn.description.enum.many": "Alphabetical index of the {0} values", - "customcolumn.description.enum.none": "Alphabetical index of absolutely no values", - "customcolumn.description.enum.one": "Alphabetical index of one value", - "customcolumn.description.rating": "Index of ratings", - "customcolumn.description.series.many": "Alphabetical index of the {0} series", - "customcolumn.description.series.none": "Alphabetical index of absolutely no series", - "customcolumn.description.series.one": "Alphabetical index of the single series", - "customcolumn.enum.unknown": "Not Set", - "customcolumn.float.unknown": "Not Set", - "customcolumn.int.unknown": "Not Set", - "customcolumn.rating.unknown": "Not Set", - "customcolumn.stars.many": "{0} Stars", - "customcolumn.stars.none": "No Stars", - "customcolumn.stars.one": "1 Star", - "customize.email": "Set your email (to allow book emailing)", - "customize.fancybox": "Use Lightbox (books load in floating frame)", - "customize.filter": "Enable tag filtering", - "customize.ignored": "Ignored categories", - "customize.paging": "Max number of books per page (-1 to disable)", - "customize.style": "Tema", - "customize.template": "Template", - "customize.title": "Customize COPS UI", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Clear all", - "filters.title": "Filters", - "home.alternate": "Beranda", - "i18n.coversection": "Cover", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Bahasa", - "languages.alphabetical.many": "Alphabetical index of the {0} languages", - "languages.alphabetical.none": "Alphabetical index of absolutely no languages", - "languages.alphabetical.one": "Alphabetical index of the single language", - "languages.title": "Bahasa", - "links.title": "Tautan", - "mail.messagenotsent": "Pesan tidak dapat dikirim", - "mail.messagesent": "Pesan telah terkirim", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "Selanjutnya", - "paging.previous.alternate": "Sebelumnya", - "permalink.alternate": "Permalink", - "pubdate.title": "Published", - "publisher.name": "Penerbit", - "publishers.alphabetical.many": "Alphabetical index of the {0} publishers", - "publishers.alphabetical.none": "Alphabetical index of absolutely no publishers", - "publishers.alphabetical.one": "Alphabetical index of the single publisher", - "publishers.title": "Penerbit", - "publisherword.many": "{0} penerbit", - "publisherword.none": "Tidak ada penulis", - "publisherword.one": "1 penulis", - "ratings.many": "{0} ratings", - "ratings.none": "tidak ada peringkat", - "ratings.one": "1 rating", - "ratings.title": "Ratings", - "rating.title": "Rating", - "ratingword.many": "{0} stars", - "ratingword.none": "No star", - "ratingword.one": "1 star", - "recent.list": "{0} most recent books", - "recent.title": "Recent additions", - "search.alternate": "Cari", - "search.result": "Hasil pencarian ke *{0}*", - "search.result.author": "Hasil pencarian penulis ke *{0}* ", - "search.result.book": "Hasil pencarian buku ke *{0}*", - "search.result.publisher": "Hasil pencarian penerbit ke *{0}*", - "search.result.series": "Hasil pencarian seri ke *{0}*", - "search.result.tag": "Hasil pencarian tag ke *{0}*", - "search.sortorder.asc": "Asc", - "search.sortorder.desc": "Desc", - "series.alphabetical.many": "Alphabetical index of the {0} series", - "series.alphabetical.none": "Alphabetical index of absolutely no series", - "series.alphabetical.one": "Alphabetical index of the single series", - "series.title": "Series", - "seriesword.many": "{0} series", - "seriesword.none": "No series", - "seriesword.one": "1 series", - "sort.alternate": "Urutkan", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "Buku lainnya", - "splitByLetter.letter": "{0} starting with {1}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "Alphabetical index of the {0} tags", - "tags.alphabetical.none": "Alphabetical index of absolutely no tags", - "tags.alphabetical.one": "Alphabetical index of the single tag", - "tags.title": "Tags", - "tagword.many": "{0} tags", - "tagword.none": "Tidak ada Tag", - "tagword.one": "1 tag", - "tagword.title": "Tags", - "title.title": "Title", - "languages.abk": "Abkhaz", - "languages.aaf": "Afar", - "languages.afr": "Afrikaans", - "languages.aka": "Akan", - "languages.sqi": "Albanian", - "languages.amh": "Amharic", - "languages.ara": "Arabic", - "languages.arg": "Aragonese", - "languages.arc": "Aramaic", - "languages.hye": "Armenian", - "languages.asm": "Assamese", - "languages.ava": "Avaric", - "languages.ave": "Avestan", - "languages.aym": "Aymara", - "languages.aze": "Azerbaijani", - "languages.bam": "Bambara", - "languages.bak": "Bashkir", - "languages.eus": "Basque", - "languages.bel": "Belarusian", - "languages.ben": "Bengali", - "languages.bih": "Bihari", - "languages.bis": "Bislama", - "languages.bos": "Bosnian", - "languages.bre": "Breton", - "languages.bul": "Bulgarian", - "languages.mya": "Burmese", - "languages.cat": "Catalan", - "languages.cha": "Chamorro", - "languages.che": "Chechen", - "languages.nya": "Chichewa", - "languages.zho": "Chinese", - "languages.chv": "Chuvash", - "languages.cor": "Cornish", - "languages.cos": "Corsican", - "languages.cre": "Cree", - "languages.hrv": "Croatian", - "languages.ces": "Czech", - "languages.dan": "Danish", - "languages.div": "Divehi", - "languages.nld": "Dutch", - "languages.dzo": "Dzongkha", - "languages.eng": "English", - "languages.epo": "Esperanto", - "languages.est": "Estonian", - "languages.ewe": "Ewe", - "languages.fao": "Faroese", - "languages.fij": "Fijian", - "languages.fin": "Finnish", - "languages.fra": "French", - "languages.ful": "Fula", - "languages.glg": "Galician", - "languages.kat": "Georgian", - "languages.deu": "German", - "languages.ell": "Greek", - "languages.egy": "Egyptian (Ancient)", - "languages.grn": "Guaraní", - "languages.guj": "Gujarati", - "languages.hat": "Haitian", - "languages.hau": "Hausa", - "languages.heb": "Hebrew", - "languages.her": "Herero", - "languages.hin": "Hindi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Hungarian", - "languages.ina": "Interlingua", - "languages.ind": "Indonesian", - "languages.ile": "Interlingue", - "languages.gle": "Irish", - "languages.grc": "Greek, Ancient (to 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Icelandic", - "languages.ita": "Italian", - "languages.iku": "Inuktitut", - "languages.jpn": "Japanese", - "languages.jav": "Javanese", - "languages.kal": "Kalaallisut", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kashmiri", - "languages.kaz": "Kazakh", - "languages.khm": "Khmer", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kyrgyz", - "languages.kom": "Komi", - "languages.kon": "Kongo", - "languages.kor": "Korean", - "languages.kur": "Kurdish", - "languages.kua": "Kwanyama", - "languages.lat": "Latin", - "languages.ltz": "Luxembourgish", - "languages.lug": "Ganda", - "languages.lim": "Limburgish", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Lithuanian", - "languages.lub": "Luba-Katanga", - "languages.lav": "Latvian", - "languages.glv": "Manx", - "languages.mkd": "Macedonian", - "languages.mlg": "Malagasy", - "languages.msa": "Malay", - "languages.mal": "Malayalam", - "languages.mlt": "Maltese", - "languages.mri": "Māori", - "languages.mar": "Marathi", - "languages.mah": "Marshallese", - "languages.mon": "Mongolian", - "languages.nau": "Nauru", - "languages.nav": "Navajo", - "languages.nob": "Norwegian Bokmål", - "languages.nde": "North Ndebele", - "languages.nep": "Nepali", - "languages.ndo": "Ndonga", - "languages.nno": "Norwegian Nynorsk", - "languages.nor": "Norwegian", - "languages.iii": "Nuosu", - "languages.nbl": "South Ndebele", - "languages.oci": "Occitan", - "languages.oji": "Ojibwe", - "languages.chu": "Old Church Slavonic", - "languages.orm": "Oromo", - "languages.ori": "Oriya", - "languages.oss": "Ossetian", - "languages.pan": "Panjabi", - "languages.pli": "Pāli", - "languages.fas": "Persian", - "languages.pol": "Polish", - "languages.pus": "Pashto", - "languages.por": "Portuguese", - "languages.que": "Quechua", - "languages.roh": "Romansh", - "languages.run": "Kirundi", - "languages.ron": "Romanian", - "languages.rus": "Russian", - "languages.sam": "Samaritan Aramaic", - "languages.san": "Sanskrit", - "languages.srd": "Sardinian", - "languages.snd": "Sindhi", - "languages.sme": "Northern Sami", - "languages.smo": "Samoan", - "languages.sag": "Sango", - "languages.srp": "Serbian", - "languages.gla": "Scottish Gaelic", - "languages.sna": "Shona", - "languages.sin": "Sinhala", - "languages.slk": "Slovak", - "languages.slv": "Slovene", - "languages.som": "Somali", - "languages.sot": "Southern Sotho", - "languages.spa": "Spanish", - "languages.sun": "Sundanese", - "languages.sux": "Sumerian", - "languages.swa": "Swahili", - "languages.ssw": "Swati", - "languages.swe": "Swedish", - "languages.syc": "Classical Syriac", - "languages.syr": "Syriac", - "languages.tam": "Tamil", - "languages.tel": "Telugu", - "languages.tgk": "Tajik", - "languages.tha": "Thai", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetan Standard", - "languages.tuk": "Turkmen", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tonga", - "languages.tur": "Turkish", - "languages.tso": "Tsonga", - "languages.tat": "Tatar", - "languages.twi": "Twi", - "languages.tah": "Tahitian", - "languages.uga": "Ugaritic", - "languages.uig": "Uighur", - "languages.ukr": "Ukrainian", - "languages.urd": "Urdu", - "languages.uzb": "Uzbek", - "languages.ven": "Venda", - "languages.vie": "Vietnamese", - "languages.vol": "Volapük", - "languages.win": "Walloon", - "languages.cym": "Welsh", - "languages.wol": "Wolof", - "languages.fry": "Western Frisian", - "languages.xho": "Xhosa", - "languages.yid": "Yiddish", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_it.json b/COPS/cops-3.1.3/lang/Localization_it.json deleted file mode 100644 index 6453683d..00000000 --- a/COPS/cops-3.1.3/lang/Localization_it.json +++ /dev/null @@ -1,332 +0,0 @@ -{ - "about.title": "Informazioni su COPS", - "addeddate.title": "Aggiunto", - "allbooks.alphabetical.many": "Indice alfabetico di {0} libri", - "allbooks.alphabetical.none": "Indice alfabetico indipendente dal libro", - "allbooks.alphabetical.one": "Indice alfabetico di un solo libro", - "allbooks.title": "Tutti i libri", - "authors.alphabetical.many": "Indice alfabetico di {0} autori", - "authors.alphabetical.none": "Indice alfabetico indipendente dall'autore", - "authors.alphabetical.one": "Indice alfabetico di un solo autore", - "authors.title": "Autori", - "author.title": "Autore", - "authorword.many": "{0} autori", - "authorword.none": "Senza autore", - "authorword.one": "1 autore", - "bookentry.author": "{0} di {1}", - "bookword.many": "{0} libri", - "bookword.none": "Nessun libro", - "bookword.one": "1 libro", - "bookword.title": "Libri", - "cog.alternate": "Ricerca, ordinamento e filtri", - "content.series": "Serie:", - "content.series.data": "Libro {0} della serie {1}", - "content.summary": "Riassunto", - "customcolumn.boolean.no": "no", - "customcolumn.boolean.unknown": "Non impostato", - "customcolumn.boolean.yes": "Sí", - "customcolumn.date.format": "A-m-g", - "customcolumn.date.unknown": "Non impostato", - "customcolumn.description": "Colonna personalizzata '{0}'", - "customcolumn.description.bool": "Indice di un valore booleano", - "customcolumn.description.enum.many": "Indice alfabetico dei {0} valori", - "customcolumn.description.enum.none": "Indice alfabetico indipendente dal valore", - "customcolumn.description.enum.one": "Indice alfabetico di un solo valore", - "customcolumn.description.rating": "Indice delle valutazioni", - "customcolumn.description.series.many": "Indice alfabetico di {0} serie", - "customcolumn.description.series.none": "Indice alfabetico indipendente dalla serie", - "customcolumn.description.series.one": "Indice alfabetico di una sola serie", - "customcolumn.enum.unknown": "Non Impostato", - "customcolumn.float.unknown": "Non Impostato", - "customcolumn.int.unknown": "Non Impostato", - "customcolumn.rating.unknown": "Non Impostato", - "customcolumn.stars.many": "{0} Stelle", - "customcolumn.stars.none": "Senza stelle", - "customcolumn.stars.one": "1 stella", - "customize.email": "Imposta la tua email (per permettere l'invio di email)", - "customize.fancybox": "Usa una Lightbox (visualizza in sovrimpressione i libri selezionati)", - "customize.filter": "Abilita il filtro per argomento", - "customize.ignored": "Categorie ignorate", - "customize.paging": "Numero massimo di libri per pagina (-1 per disabilitare)", - "customize.style": "Tema", - "customize.template": "Template", - "customize.title": "Personalizza l'interfaccia di COPS", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Descrizione", - "extra.link": "Link", - "extra.title": "Ulteriori informazioni", - "filter.clearall": "Azzera tutto", - "filters.title": "Filtri", - "home.alternate": "Home", - "i18n.coversection": "Copertina", - "identifiers.title": "Identificatori", - "identifierword.many": "{0} identificatori", - "identifierword.none": "Nessun identificatore", - "identifierword.one": "1 identificatore", - "language.title": "Lingua", - "languages.alphabetical.many": "Indice alfabetico delle {0} lingue", - "languages.alphabetical.none": "Indice alfabetico indipendente dalla lingua", - "languages.alphabetical.one": "Indice alfabetico della singola lingua", - "languages.title": "Lingue", - "libraries.many": "{0} biblioteche virtuali", - "libraries.none": "Nessuna biblioteca virtuale", - "libraries.one": "1 biblioteca virtuale", - "libraries.title": "Biblioteche virtuali", - "library.title": "Biblioteca virtuale", - "links.title": "Link", - "mail.messagenotsent": "L'e-mail non può essere spedita.", - "mail.messagesent": "L'e-mail è stata spedita", - "paging.first.alternate": "Primo", - "paging.last.alternate": "Ultimo", - "paging.next.alternate": "Prossimo", - "paging.previous.alternate": "Precedente", - "permalink.alternate": "Permalink", - "pubdate.title": "Pubblicato", - "publisher.name": "Editore", - "publishers.alphabetical.many": "Indice alfabetico degli {0} editori", - "publishers.alphabetical.none": "Indice alfabetico indipendente dall'editore", - "publishers.alphabetical.one": "Indice alfabetico del singolo editore", - "publishers.title": "Editori", - "publisherword.many": "{0} editori", - "publisherword.none": "Nessun editore", - "publisherword.one": "1 editore", - "ratings.many": "{0} valutazioni", - "ratings.none": "nessuna valutazione", - "ratings.one": "1 valutazione", - "ratings.title": "Valutazioni", - "rating.title": "Valutazione", - "ratingword.many": "{0} stelle", - "ratingword.none": "Nessuna stella", - "ratingword.one": "1 stella", - "recent.list": "I {0} libri più recenti", - "recent.title": "Ultime aggiunte", - "search.alternate": "Cerca", - "search.result": "Risultati per *{0}*", - "search.result.author": "Risultato della ricerca di *{0}* negli autori", - "search.result.book": "Risultato della ricerca di *{0}* nei libri", - "search.result.publisher": "Risultato della ricerca di *{0}* negli editori", - "search.result.series": "Risultato della ricerca di *{0}* nelle serie", - "search.result.tag": "Risultato della ricerca di *{0}* negli argomenti", - "search.sortorder.asc": "Asc", - "search.sortorder.desc": "Desc", - "series.alphabetical.many": "Indice alfabetico di {0} serie", - "series.alphabetical.none": "Indice alfabetico indipendente dalla serie", - "series.alphabetical.one": "Indice alfabetico di una sola serie", - "series.title": "Serie", - "seriesword.many": "{0} serie", - "seriesword.none": "Nessuna serie", - "seriesword.one": "1 serie", - "sort.alternate": "Tipo", - "sort.count": "Count", - "sort.names": "Nomi", - "sort.titles": "Titoli", - "sortby.title": "Ordina per", - "splitByLetter.book.other": "Altri libri", - "splitByLetter.letter": "{0} che iniziano per {1}", - "splitByRange.range": "{0} nell'intervallo {1}", - "splitByYear.year": "{0} pubblicato in {1}", - "tags.alphabetical.many": "Indice alfabetico di {0} argomenti", - "tags.alphabetical.none": "Indice alfabetico indipendente dall'argomento", - "tags.alphabetical.one": "Indice alfabetico del solo argomento", - "tags.title": "Argomenti", - "tagword.many": "{0} argomenti", - "tagword.none": "Senza argomento", - "tagword.one": "1 argomento", - "tagword.title": "Argomenti", - "title.title": "Titolo", - "languages.abk": "Abkhazo", - "languages.aaf": "Afar", - "languages.afr": "Afrikaans", - "languages.aka": "Akan", - "languages.sqi": "Albanese", - "languages.amh": "Amarico", - "languages.ara": "Arabo", - "languages.arg": "Aragonese", - "languages.arc": "Aramaico", - "languages.hye": "Armeno", - "languages.asm": "Assamese", - "languages.ava": "Avaro", - "languages.ave": "Avestico", - "languages.aym": "Aymara", - "languages.aze": "Azero", - "languages.bam": "Bambara", - "languages.bak": "Baschiro", - "languages.eus": "Basco", - "languages.bel": "Bielorusso", - "languages.ben": "Bengalese", - "languages.bih": "Bihari", - "languages.bis": "Bislama", - "languages.bos": "Bosniaco", - "languages.bre": "Bretone", - "languages.bul": "Bulgaro", - "languages.mya": "Birmano", - "languages.cat": "Catalano", - "languages.cha": "Chamorro", - "languages.che": "Ceceno", - "languages.nya": "Chewa", - "languages.zho": "Cinese", - "languages.chv": "Ciuvascio", - "languages.cor": "Cornico", - "languages.cos": "Corso", - "languages.cre": "Cree", - "languages.hrv": "Croato", - "languages.ces": "Ceco", - "languages.dan": "Danese", - "languages.div": "Maldiviano", - "languages.nld": "Olandese", - "languages.dzo": "Dzongkha", - "languages.eng": "Inglese", - "languages.epo": "Esperanto", - "languages.est": "Estone", - "languages.ewe": "Ewe", - "languages.fao": "Faringio", - "languages.fij": "Figiano", - "languages.fin": "Finnico", - "languages.fra": "Francese", - "languages.ful": "Fula", - "languages.glg": "Galiziano", - "languages.kat": "Georgiano", - "languages.deu": "Tedesco", - "languages.ell": "Greco", - "languages.egy": "Egiziano (antico)", - "languages.grn": "Guaraní", - "languages.guj": "Gujarati", - "languages.hat": "Haitiano", - "languages.hau": "Hausa", - "languages.heb": "Ebraico", - "languages.her": "Herero", - "languages.hin": "Hindi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Ungherese", - "languages.ina": "Interlingua", - "languages.ind": "Indonesiano", - "languages.ile": "Interlingua", - "languages.gle": "Irlandese", - "languages.grc": "Greco, antico (fino al 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Islandese", - "languages.ita": "Italiano", - "languages.iku": "Inuktitut", - "languages.jpn": "Giapponese", - "languages.jav": "Giavanese", - "languages.kal": "Kalaallisut", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kashmiri", - "languages.kaz": "Kazaco", - "languages.khm": "Khmer", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kirghiso", - "languages.kom": "Sirieno", - "languages.kon": "Kikongo", - "languages.kor": "Coreano", - "languages.kur": "Curdo", - "languages.kua": "Kwanyama", - "languages.lat": "Latino", - "languages.ltz": "Lussemburghese", - "languages.lug": "Luganda", - "languages.lim": "Limburgish", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Lituano", - "languages.lub": "Kiluba", - "languages.lav": "Lettone", - "languages.glv": "Mannese", - "languages.mkd": "Macedone", - "languages.mlg": "Malgascio", - "languages.msa": "Malese", - "languages.mal": "Malayalam", - "languages.mlt": "Maltese", - "languages.mri": "Māori", - "languages.mar": "Marathi", - "languages.mah": "Marshallese", - "languages.mon": "Mongolo", - "languages.nau": "Nauruano", - "languages.nav": "Navajo", - "languages.nob": "Norvegese Bokmål", - "languages.nde": "Ndebele del nord", - "languages.nep": "Nepalese", - "languages.ndo": "Ndonga", - "languages.nno": "Norvegese Nynorsk", - "languages.nor": "Norvegese", - "languages.iii": "Nuosu", - "languages.nbl": "Ndebele del sud", - "languages.oci": "Occitano", - "languages.oji": "Ojibwe", - "languages.chu": "Slavo ecclesiastico antico", - "languages.orm": "Oromonico", - "languages.ori": "Oriya", - "languages.oss": "Osseto", - "languages.pan": "Punjabi", - "languages.pli": "Pāli", - "languages.fas": "Farsi", - "languages.pol": "Polacco", - "languages.pus": "Pashtu", - "languages.por": "Portoghese", - "languages.que": "Quechua", - "languages.roh": "Romancio", - "languages.run": "Kirundi", - "languages.ron": "Rumeno", - "languages.rus": "Russo", - "languages.sam": "Aramaico samaritano", - "languages.san": "Sanscrito", - "languages.srd": "Sardo", - "languages.snd": "Sindhi", - "languages.sme": "Sami settentrionale", - "languages.smo": "Samoano", - "languages.sag": "Sango", - "languages.srp": "Serbo", - "languages.gla": "Gaelico scozzese", - "languages.sna": "Shona", - "languages.sin": "Singalese", - "languages.slk": "Slovacco", - "languages.slv": "Sloveno", - "languages.som": "Somalo", - "languages.sot": "Sotho del sud", - "languages.spa": "Spagnolo", - "languages.sun": "Sundanese", - "languages.sux": "Sumero", - "languages.swa": "Swahili", - "languages.ssw": "Swati", - "languages.swe": "Svedese", - "languages.syc": "Siriaco classico", - "languages.syr": "Siriaco", - "languages.tam": "Tamil", - "languages.tel": "Telugu", - "languages.tgk": "Tagico", - "languages.tha": "Tailandese", - "languages.tir": "Tigrino", - "languages.bod": "Tibetano Standard", - "languages.tuk": "Turkmeno", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tongano", - "languages.tur": "Turco", - "languages.tso": "Tsonga", - "languages.tat": "Tartaro", - "languages.twi": "Twi", - "languages.tah": "Tahitiano", - "languages.uga": "Ugaritico", - "languages.uig": "Uiguro", - "languages.ukr": "Ucraino", - "languages.urd": "Urdu", - "languages.uzb": "Uzbek", - "languages.ven": "Venda", - "languages.vie": "Vietnamita", - "languages.vol": "Volapük", - "languages.win": "vallone", - "languages.cym": "Gallese", - "languages.wol": "Senegalese", - "languages.fry": "Frisone del est", - "languages.xho": "Xhosa", - "languages.yid": "Yiddish", - "languages.yor": "Yoruba", - "languages.zha": "cinese semplificato", - "languages.zul": "Zuù", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_ja.json b/COPS/cops-3.1.3/lang/Localization_ja.json deleted file mode 100644 index d505aa8f..00000000 --- a/COPS/cops-3.1.3/lang/Localization_ja.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "COPSについて", - "addeddate.title": "追加", - "allbooks.alphabetical.many": "アルファベット順に並べた計{0}冊の本", - "allbooks.alphabetical.none": "アルファベット順に並べる本がありません", - "allbooks.alphabetical.one": "アルファベット順に並べた計1冊の本", - "allbooks.title": "すべての本", - "authors.alphabetical.many": "アルファベット順に並べた計{0}人の著者", - "authors.alphabetical.none": "アルファベット順に並べる著者がいません", - "authors.alphabetical.one": "アルファベット順に並べた計1人の著者", - "authors.title": "著者", - "author.title": "著者", - "authorword.many": "著者{0}人", - "authorword.none": "著者なし", - "authorword.one": "計1人の著者", - "bookentry.author": "{1}による{0}", - "bookword.many": "計{0}冊の本", - "bookword.none": "本なし", - "bookword.one": "計1冊の本", - "bookword.title": "本", - "cog.alternate": "検索・並替・選択", - "content.series": "叢書: ", - "content.series.data": "叢書{1}の{0}冊目の本", - "content.summary": "抄訳", - "customcolumn.boolean.no": "否", - "customcolumn.boolean.unknown": "未設定", - "customcolumn.boolean.yes": "是", - "customcolumn.date.format": "年-月-日", - "customcolumn.date.unknown": "未設定", - "customcolumn.description": "独自の欄「{0}」", - "customcolumn.description.bool": "真偽値による順位", - "customcolumn.description.enum.many": "アルファベット順に並べた計{0}個の値", - "customcolumn.description.enum.none": "アルファベット順に並べる値がありません", - "customcolumn.description.enum.one": "アルファベット順に並べた計1個の値", - "customcolumn.description.rating": "評価による順位", - "customcolumn.description.series.many": "アルファベット順に並べた計{0}部の叢書", - "customcolumn.description.series.none": "アルファベット順に並べる叢書がありません", - "customcolumn.description.series.one": "アルファベット順に並べた計1部の叢書", - "customcolumn.enum.unknown": "未設定", - "customcolumn.float.unknown": "未設定", - "customcolumn.int.unknown": "未設定", - "customcolumn.rating.unknown": "未設定", - "customcolumn.stars.many": "{0}つ星", - "customcolumn.stars.none": "星なし", - "customcolumn.stars.one": "1つ星", - "customize.email": "電子メールの設定(本の送信に用います)", - "customize.fancybox": "Lightboxを用いる(本を浮動表示します)", - "customize.filter": "タグによる選択を有効にする", - "customize.ignored": "無視する分類", - "customize.paging": "1ページあたりの最大表示数(-1にすると無効になります)", - "customize.style": "外観", - "customize.template": "雛形", - "customize.title": "COPSのUIを調整する", - "default.template": "COPSの既定の外観", - "downloadall.title": "すべて入手する", - "downloadall.tooltip": "このページにある全ての本について選択した形式が格納されたZIPファイルを入手する", - "extra.content": "説明", - "extra.link": "リンク", - "extra.title": "追加情報", - "filter.clearall": "選択を外す", - "filters.title": "選択", - "home.alternate": "拠点", - "i18n.coversection": "表紙", - "identifiers.title": "識別子", - "identifierword.many": "{0}個の識別子", - "identifierword.none": "識別子なし", - "identifierword.one": "1個の識別子", - "language.title": "言語", - "languages.alphabetical.many": "アルファベット順に並べた計{0}語の言語", - "languages.alphabetical.none": "アルファベット順に並べる言語がありません", - "languages.alphabetical.one": "アルファベット順に並べた計1語の言語", - "languages.title": "言語", - "links.title": "リンク", - "mail.messagenotsent": "送信できませんでした。", - "mail.messagesent": "送信しました", - "paging.first.alternate": "最初", - "paging.last.alternate": "最後", - "paging.next.alternate": "次", - "paging.previous.alternate": "前", - "permalink.alternate": "恒久リンク", - "pubdate.title": "出版日", - "publisher.name": "出版社", - "publishers.alphabetical.many": "アルファベット順に並べた計{0}社の出版社", - "publishers.alphabetical.none": "アルファベット順に並べる出版社がありません", - "publishers.alphabetical.one": "アルファベット順に並べた計1社の出版社", - "publishers.title": "出版社", - "publisherword.many": "{0}社の出版社", - "publisherword.none": "出版社なし", - "publisherword.one": "1社の出版社", - "ratings.many": "{0}件の評価", - "ratings.none": "評価なし", - "ratings.one": "1件の評価", - "ratings.title": "評価", - "rating.title": "評価", - "ratingword.many": "{0}つ星", - "ratingword.none": "星なし", - "ratingword.one": "1つ星", - "recent.list": "最近追加された{0}冊の本", - "recent.title": "最近の追加", - "search.alternate": "検索", - "search.result": "*{0}*の検索結果", - "search.result.author": "*{0}*の検索結果(著者)", - "search.result.book": "*{0}*の検索結果(本)", - "search.result.publisher": "*{0}*の検索結果(出版社)", - "search.result.series": "*{0}*の検索結果(叢書)", - "search.result.tag": "*{0}*の検索結果(タグ)", - "search.sortorder.asc": "昇順", - "search.sortorder.desc": "降順", - "series.alphabetical.many": "アルファベット順に並べた計{0}部の叢書", - "series.alphabetical.none": "アルファベット順に並べる叢書がありません", - "series.alphabetical.one": "アルファベット順に並べた計1部の叢書", - "series.title": "叢書", - "seriesword.many": "{0}部の叢書", - "seriesword.none": "叢書なし", - "seriesword.one": "1部の叢書", - "sort.alternate": "並替", - "sort.count": "個数", - "sort.names": "名前", - "sort.titles": "題名", - "sortby.title": "並替基準", - "splitByLetter.book.other": "そのほかの本", - "splitByLetter.letter": "{1}から始まる{0}", - "splitByRange.range": "{1}の範囲の{0}", - "splitByYear.year": "{1}年に発行された{0}", - "tags.alphabetical.many": "アルファベット順に並べた計{0}件のタグ", - "tags.alphabetical.none": "アルファベット順に並べるタグがありません", - "tags.alphabetical.one": "アルファベット順に並べた計1件のタグ", - "tags.title": "タグ", - "tagword.many": "{0}件のタグ", - "tagword.none": "タグなし", - "tagword.one": "1件のタグ", - "tagword.title": "タグ", - "title.title": "題名", - "languages.abk": "アブハズ語", - "languages.aaf": "アファル語", - "languages.afr": "アフリカーンス語", - "languages.aka": "アカン語", - "languages.sqi": "アルバニア語", - "languages.amh": "アムハラ語", - "languages.ara": "アラビア語", - "languages.arg": "アラゴン語", - "languages.arc": "アラム語", - "languages.hye": "アルメニア語", - "languages.asm": "アッサム語", - "languages.ava": "アバール語", - "languages.ave": "アベスタ語", - "languages.aym": "アイマラ語", - "languages.aze": "アゼルバイジャン語", - "languages.bam": "バンバラ語", - "languages.bak": "バシュキール語", - "languages.eus": "バスク語", - "languages.bel": "白ロシア語", - "languages.ben": "ベンガル語", - "languages.bih": "ビハール語", - "languages.bis": "ビスラマ語", - "languages.bos": "ボスニア語", - "languages.bre": "ブルトン語", - "languages.bul": "ブルガリア語", - "languages.mya": "ミャンマー語", - "languages.cat": "カタロニア語", - "languages.cha": "チャモロ語", - "languages.che": "チェチェン語", - "languages.nya": "ニャンジャ語", - "languages.zho": "中国語", - "languages.chv": "チュワシュ語", - "languages.cor": "コーンウォール語", - "languages.cos": "コルシカ語", - "languages.cre": "クリー語", - "languages.hrv": "クロアチア語", - "languages.ces": "チェコ語", - "languages.dan": "デンマーク語", - "languages.div": "モルジブ語", - "languages.nld": "オランダ語", - "languages.dzo": "ブータン語", - "languages.eng": "英語", - "languages.epo": "エスペラント語", - "languages.est": "エストニア語", - "languages.ewe": "エウェ語群", - "languages.fao": "フェーロー語", - "languages.fij": "フィジー語", - "languages.fin": "フィンランド語", - "languages.fra": "フランス語", - "languages.ful": "フルフルデ語", - "languages.glg": "ガリシア語", - "languages.kat": "グルジア語", - "languages.deu": "ドイツ語", - "languages.ell": "現代ギリシア語", - "languages.egy": "古代エジプト語", - "languages.grn": "グァラニ語", - "languages.guj": "グジャラート語", - "languages.hat": "ハイチ語", - "languages.hau": "ハウサ語", - "languages.heb": "ヘブライ語", - "languages.her": "ヘレロ語", - "languages.hin": "ヒンディー語", - "languages.hmo": "ヒリモトゥ語", - "languages.hun": "ハンガリー語", - "languages.ina": "インターリンガ語", - "languages.ind": "インドネシア語", - "languages.ile": "インターリング", - "languages.gle": "アイルランド語", - "languages.grc": "古代ギリシア語", - "languages.ibo": "イボ語", - "languages.ipk": "イヌピアック語", - "languages.ido": "イド語", - "languages.isl": "アイスランド語", - "languages.ita": "イタリア語", - "languages.iku": "イヌイット語", - "languages.jpn": "日本語", - "languages.jav": "ジャワ語", - "languages.kal": "グリーンランド語", - "languages.kan": "カンナダ語", - "languages.kau": "カヌリ語", - "languages.kas": "カシュミール語", - "languages.kaz": "カザフ語", - "languages.khm": "カンボジア語", - "languages.kik": "キクユ語", - "languages.kin": "ルワンダ語", - "languages.kir": "キルギス語", - "languages.kom": "コミ語", - "languages.kon": "コンゴ語", - "languages.kor": "朝鮮語", - "languages.kur": "クルド語", - "languages.kua": "クワニャマ語", - "languages.lat": "ラテン語", - "languages.ltz": "ルクセンブルク語", - "languages.lug": "ガンダ語", - "languages.lim": "リンブルガー語", - "languages.lin": "リンガラ語", - "languages.lao": "ラオ語", - "languages.lit": "リトアニア語", - "languages.lub": "キルバ語", - "languages.lav": "ラトビア語", - "languages.glv": "マン島語", - "languages.mkd": "マケドニア語", - "languages.mlg": "マラガシ語", - "languages.msa": "マレー語", - "languages.mal": "マラヤーラム語", - "languages.mlt": "マルタ語", - "languages.mri": "マオリ語", - "languages.mar": "マラーティー語", - "languages.mah": "マーシャル語", - "languages.mon": "モンゴル語", - "languages.nau": "ナウル語", - "languages.nav": "ナバホ語", - "languages.nob": "ブークモール", - "languages.nde": "北ンデベレ語", - "languages.nep": "ネパール語", - "languages.ndo": "ンドゥンガ語", - "languages.nno": "ニューノシュク", - "languages.nor": "ノルウェー語", - "languages.iii": "彝語", - "languages.nbl": "南ンデベレ語", - "languages.oci": "オック語", - "languages.oji": "オジブワ語", - "languages.chu": "教会スラブ語", - "languages.orm": "オロモ語;ガッラ語", - "languages.ori": "オリヤー語", - "languages.oss": "オセット語", - "languages.pan": "パンジャーブ語", - "languages.pli": "パーリ語", - "languages.fas": "ペルシア語", - "languages.pol": "ポーランド語", - "languages.pus": "パシュトー語", - "languages.por": "ポルトガル語", - "languages.que": "ケチュア語", - "languages.roh": "レト・ロマンス語", - "languages.run": "ルンディ語", - "languages.ron": "ルーマニア語", - "languages.rus": "ロシア語", - "languages.sam": "サマリア・アラム語", - "languages.san": "サンスクリット語", - "languages.srd": "サルデーニャ語", - "languages.snd": "シンド語", - "languages.sme": "北サーミ語", - "languages.smo": "サモア語", - "languages.sag": "サンゴ語", - "languages.srp": "セルビア語", - "languages.gla": "高地スコットランド・ゲール語", - "languages.sna": "ショナ語", - "languages.sin": "シンハラ語", - "languages.slk": "スロバキア語", - "languages.slv": "スロベニア語", - "languages.som": "ソマリ語", - "languages.sot": "南ソト語", - "languages.spa": "スペイン語", - "languages.sun": "スンダ語", - "languages.sux": "シュメール語", - "languages.swa": "スワヒリ語", - "languages.ssw": "スワティ語", - "languages.swe": "スウェーデン語", - "languages.syc": "古典シリア語", - "languages.syr": "シリア語", - "languages.tam": "タミル語", - "languages.tel": "テルグ語", - "languages.tgk": "タジク語", - "languages.tha": "タイ語", - "languages.tir": "ティグリニア語", - "languages.bod": "チベット語", - "languages.tuk": "トルクメン語", - "languages.tgl": "タガログ語", - "languages.tsn": "ツワナ語", - "languages.ton": "トンガ語", - "languages.tur": "トルコ語", - "languages.tso": "ツォンガ語", - "languages.tat": "タタール語", - "languages.twi": "チュイ語", - "languages.tah": "タヒチ語", - "languages.uga": "ウガリト語", - "languages.uig": "ウイグル語", - "languages.ukr": "ウクライナ語", - "languages.urd": "ウルドゥー語", - "languages.uzb": "ウズベク語", - "languages.ven": "ベンダ語", - "languages.vie": "ベトナム語", - "languages.vol": "ボラピューク語", - "languages.win": "ワロン語", - "languages.cym": "ウェールズ語", - "languages.wol": "ウォロフ語", - "languages.fry": "西フリジア語", - "languages.xho": "コサ語", - "languages.yid": "イディッシュ語", - "languages.yor": "ヨルバ語", - "languages.zha": "チュワン語", - "languages.zul": "ズールー語", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_ko.json b/COPS/cops-3.1.3/lang/Localization_ko.json deleted file mode 100644 index 48dbdc7a..00000000 --- a/COPS/cops-3.1.3/lang/Localization_ko.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "COPS에 대해", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "{0}권의 도서별 색인", - "allbooks.alphabetical.none": "0권의 도서별 색인", - "allbooks.alphabetical.one": "1권의 도서별 색인", - "allbooks.title": "전체 도서", - "authors.alphabetical.many": "{0}명의 저자별 색인", - "authors.alphabetical.none": "0명의 저자별 색인", - "authors.alphabetical.one": "1명의 저자별 색인", - "authors.title": "저자", - "author.title": "Author", - "authorword.many": "{0}명의 저자", - "authorword.none": "0명의 저자", - "authorword.one": "1명의 저자", - "bookentry.author": "{0} by {1}", - "bookword.many": "{0}권", - "bookword.none": "(없음)", - "bookword.one": "1권", - "bookword.title": "도서", - "cog.alternate": "검색, 정렬 및 필터링", - "content.series": "Series:", - "content.series.data": "Book {0} in the {1} series", - "content.summary": "요약", - "customcolumn.boolean.no": "2월", - "customcolumn.boolean.unknown": "Not Set", - "customcolumn.boolean.yes": "1월", - "customcolumn.date.format": "Y-m-d", - "customcolumn.date.unknown": "Not Set", - "customcolumn.description": "Custom column '{0}'", - "customcolumn.description.bool": "Index of a boolean value", - "customcolumn.description.enum.many": "Alphabetical index of the {0} values", - "customcolumn.description.enum.none": "Alphabetical index of absolutely no values", - "customcolumn.description.enum.one": "Alphabetical index of one value", - "customcolumn.description.rating": "Index of ratings", - "customcolumn.description.series.many": "{0}개의 시리즈별 색인", - "customcolumn.description.series.none": "0개의 시리즈별 색인", - "customcolumn.description.series.one": "1개의 시리즈별 색인", - "customcolumn.enum.unknown": "Not Set", - "customcolumn.float.unknown": "Not Set", - "customcolumn.int.unknown": "Not Set", - "customcolumn.rating.unknown": "Not Set", - "customcolumn.stars.many": "{0} Stars", - "customcolumn.stars.none": "No Stars", - "customcolumn.stars.one": "1 Star", - "customize.email": "이메일주소 (도서 메일발송용)", - "customize.fancybox": "Lightbox 사용 (도서정보를 프레임으로 표시)", - "customize.filter": "태그 필터링기능 사용", - "customize.ignored": "무시할 카테고리", - "customize.paging": "페이지마다 표시할 도서 권수 (-1인 경우 무시)", - "customize.style": "스타일", - "customize.template": "Template", - "customize.title": "COPS 설정", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "모두 지우기", - "filters.title": "Filters", - "home.alternate": "최초", - "i18n.coversection": "Cover", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "언어", - "languages.alphabetical.many": "4개의 언어별 색인", - "languages.alphabetical.none": "0개의 언어별 색인", - "languages.alphabetical.one": "1개의 언어별 색인", - "languages.title": "언어", - "links.title": "링크", - "mail.messagenotsent": "Message could not be sent.", - "mail.messagesent": "Message has been sent", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "다음", - "paging.previous.alternate": "이전", - "permalink.alternate": "Permalink", - "pubdate.title": "Published", - "publisher.name": "출판사", - "publishers.alphabetical.many": "{0}개 출판사별 색인", - "publishers.alphabetical.none": "0개 출판사별 색인", - "publishers.alphabetical.one": "1개 출판사별 색인", - "publishers.title": "출판사", - "publisherword.many": "{0}개 출판사", - "publisherword.none": "출판사 없음", - "publisherword.one": "1개 출판사", - "ratings.many": "{0}개 별점", - "ratings.none": "별점 없음", - "ratings.one": "1개 별점", - "ratings.title": "별점", - "rating.title": "Rating", - "ratingword.many": "별 {0}개", - "ratingword.none": "별 없음", - "ratingword.one": "별 1개", - "recent.list": "최근 추가된 {0}권의 책", - "recent.title": "최근 추가됨", - "search.alternate": "검색", - "search.result": "*{0}*의 검색결과", - "search.result.author": "저자명에서 *{0}* 검색", - "search.result.book": "도서정보에서 *{0}* 검색", - "search.result.publisher": "출판사명에서 *{0}* 검색", - "search.result.series": "시리즈명에서 *{0}* 검색", - "search.result.tag": "태그에서 *{0}* 검색", - "search.sortorder.asc": "오름차순", - "search.sortorder.desc": "내림차순", - "series.alphabetical.many": "{0}개의 시리즈별 색인", - "series.alphabetical.none": "0개의 시리즈별 색인", - "series.alphabetical.one": "1개의 시리즈별 색인", - "series.title": "시리즈", - "seriesword.many": "{0}개 시리즈", - "seriesword.none": "시리즈 없음", - "seriesword.one": "1개 시리즈", - "sort.alternate": "Sort", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "Other books", - "splitByLetter.letter": "{0} starting with {1}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "{0}개의 태그별 색인", - "tags.alphabetical.none": "0개의 태그별 색인", - "tags.alphabetical.one": "1개의 태그별 색인", - "tags.title": "태그", - "tagword.many": "{0} tags", - "tagword.none": "No tags", - "tagword.one": "1 tag", - "tagword.title": "태그", - "title.title": "Title", - "languages.abk": "압하스어", - "languages.aaf": "아파르어", - "languages.afr": "아프리칸스어", - "languages.aka": "아칸어", - "languages.sqi": "알바니아어", - "languages.amh": "암하라어", - "languages.ara": "아랍어", - "languages.arg": "아라곤어", - "languages.arc": "Aramaic", - "languages.hye": "아르메니아어", - "languages.asm": "아삼어", - "languages.ava": "아바르어", - "languages.ave": "아베스타어", - "languages.aym": "아이마라어", - "languages.aze": "아제르바이잔어", - "languages.bam": "밤바라어", - "languages.bak": "바슈키르어", - "languages.eus": "바스크어", - "languages.bel": "벨로루시어", - "languages.ben": "벵골어", - "languages.bih": "비하르어", - "languages.bis": "비슐라마어", - "languages.bos": "보스니아어", - "languages.bre": "브르타뉴어", - "languages.bul": "불가리아어", - "languages.mya": "버마어", - "languages.cat": "카탈루냐어", - "languages.cha": "차모로어", - "languages.che": "체첸어", - "languages.nya": "니안자어", - "languages.zho": "중국어", - "languages.chv": "추바슈어", - "languages.cor": "콘월어", - "languages.cos": "코르시카어", - "languages.cre": "크리어", - "languages.hrv": "크로아티아어", - "languages.ces": "체크어", - "languages.dan": "덴마크어", - "languages.div": "디베히어", - "languages.nld": "네덜란드어", - "languages.dzo": "종카어", - "languages.eng": "영어", - "languages.epo": "에스페란토", - "languages.est": "에스토이나어", - "languages.ewe": "에웨어", - "languages.fao": "페로어", - "languages.fij": "피지어", - "languages.fin": "핀란드어", - "languages.fra": "프랑스어", - "languages.ful": "풀라어", - "languages.glg": "갈리시아어", - "languages.kat": "조지아어", - "languages.deu": "독일어", - "languages.ell": "그리스어", - "languages.egy": "Egyptian (Ancient)", - "languages.grn": "과라니어", - "languages.guj": "구자라트어", - "languages.hat": "아이티어", - "languages.hau": "하우사어", - "languages.heb": "히브리어", - "languages.her": "헤레로어", - "languages.hin": "힌디어", - "languages.hmo": "히리 모투어", - "languages.hun": "헝가리어", - "languages.ina": "인테르링구아", - "languages.ind": "인도네시아어", - "languages.ile": "인테르링구에", - "languages.gle": "아일랜드어", - "languages.grc": "Greek, Ancient (to 1453)", - "languages.ibo": "이그보어", - "languages.ipk": "이누피아크어", - "languages.ido": "이도", - "languages.isl": "아이슬란드어", - "languages.ita": "이탈리아어", - "languages.iku": "이누크티투트어", - "languages.jpn": "일본어", - "languages.jav": "자바어", - "languages.kal": "그린란드어", - "languages.kan": "칸나다어", - "languages.kau": "카누리어", - "languages.kas": "카슈미르어", - "languages.kaz": "카자흐어", - "languages.khm": "크메르어", - "languages.kik": "키쿠유어", - "languages.kin": "르완다어", - "languages.kir": "키르기스어", - "languages.kom": "코미어", - "languages.kon": "콩고어", - "languages.kor": "한국어", - "languages.kur": "쿠르드어", - "languages.kua": "콰냐마어", - "languages.lat": "라틴어", - "languages.ltz": "룩셈부르크어", - "languages.lug": "간다어", - "languages.lim": "림뷔르흐어", - "languages.lin": "링갈라어", - "languages.lao": "라오어", - "languages.lit": "리투아니아어", - "languages.lub": "루바-카탕가어", - "languages.lav": "라트비아어", - "languages.glv": "맨어", - "languages.mkd": "마케도니아어", - "languages.mlg": "마다가스카르어", - "languages.msa": "말레이어", - "languages.mal": "말라얄람어", - "languages.mlt": "몰타어", - "languages.mri": "마오리어", - "languages.mar": "마라티어", - "languages.mah": "마셜어", - "languages.mon": "몽골어", - "languages.nau": "나우루어", - "languages.nav": "나바호어", - "languages.nob": "덴마크-노르웨이어", - "languages.nde": "은데벨레어(북)", - "languages.nep": "네팔어", - "languages.ndo": "은동가어", - "languages.nno": "신노르웨이어", - "languages.nor": "노르웨이어", - "languages.iii": "쓰촨 이어", - "languages.nbl": "은데벨레어(남)", - "languages.oci": "오크어", - "languages.oji": "오지브와어", - "languages.chu": "슬라브어", - "languages.orm": "오로모어", - "languages.ori": "오리야어", - "languages.oss": "오세트어", - "languages.pan": "펀자브어", - "languages.pli": "팔리어", - "languages.fas": "페르시아어", - "languages.pol": "폴란드어", - "languages.pus": "파슈토어", - "languages.por": "포르투갈어", - "languages.que": "케추아어", - "languages.roh": "로만슈어", - "languages.run": "룬디어", - "languages.ron": "루마니아어", - "languages.rus": "러시아어", - "languages.sam": "Samaritan Aramaic", - "languages.san": "산스크리트어", - "languages.srd": "사르데냐어", - "languages.snd": "신드어", - "languages.sme": "사미어(북)", - "languages.smo": "사모아어", - "languages.sag": "상고어", - "languages.srp": "세르비아어", - "languages.gla": "게일어", - "languages.sna": "쇼나어", - "languages.sin": "싱할라어", - "languages.slk": "슬로바키아어", - "languages.slv": "슬로베니아어", - "languages.som": "소말리어", - "languages.sot": "소토어(남)", - "languages.spa": "스페인어", - "languages.sun": "순다어", - "languages.sux": "Sumerian", - "languages.swa": "스와힐리어", - "languages.ssw": "스와티어", - "languages.swe": "스웨덴어", - "languages.syc": "Classical Syriac", - "languages.syr": "Syriac", - "languages.tam": "타밀어", - "languages.tel": "텔루구어", - "languages.tgk": "타지크어", - "languages.tha": "태국어", - "languages.tir": "티그리냐어", - "languages.bod": "티베트어", - "languages.tuk": "투르크멘어", - "languages.tgl": "타갈로그어", - "languages.tsn": "츠와나어", - "languages.ton": "통가어", - "languages.tur": "터키어", - "languages.tso": "총가어", - "languages.tat": "타타르어", - "languages.twi": "트위어", - "languages.tah": "타히티어", - "languages.uga": "Ugaritic", - "languages.uig": "위구르어", - "languages.ukr": "우크라이나어", - "languages.urd": "우르두어", - "languages.uzb": "우즈베크어", - "languages.ven": "벤다어", - "languages.vie": "베트남어", - "languages.vol": "볼라퓌크", - "languages.win": "왈론어", - "languages.cym": "웨일스어", - "languages.wol": "월로프어", - "languages.fry": "프리지아어", - "languages.xho": "코사어", - "languages.yid": "이디시어", - "languages.yor": "요루바어", - "languages.zha": "좡어", - "languages.zul": "줄루어", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_nb.json b/COPS/cops-3.1.3/lang/Localization_nb.json deleted file mode 100644 index fb12497e..00000000 --- a/COPS/cops-3.1.3/lang/Localization_nb.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "Om COPS", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "Alfabetisk indeks for {0} bøker", - "allbooks.alphabetical.none": "Alfabetisk indeks for absolutt ingen bøker", - "allbooks.alphabetical.one": "Alfabetisk indeks for èn enkelt bok", - "allbooks.title": "Alle bøker", - "authors.alphabetical.many": "Alfabetisk indeks for {0} forfattere", - "authors.alphabetical.none": "Alfabetisk indeks for ingen forfattere", - "authors.alphabetical.one": "Alfabetisk indeks for èn forfatter", - "authors.title": "Forfattere", - "author.title": "Author", - "authorword.many": "{0} forfattere", - "authorword.none": "Ingen forfattere", - "authorword.one": "1 forfatter", - "bookentry.author": "{0} av {1}", - "bookword.many": "{0} bøker", - "bookword.none": "Ingen bøker", - "bookword.one": "1 bok", - "bookword.title": "Bøker", - "cog.alternate": "Søk, sortering og filtrering", - "content.series": "Serier:", - "content.series.data": "Bok {0} i serien {1}", - "content.summary": "Sammendrag", - "customcolumn.boolean.no": "Nei", - "customcolumn.boolean.unknown": "Ikke satt", - "customcolumn.boolean.yes": "Ja", - "customcolumn.date.format": "Y-m-d", - "customcolumn.date.unknown": "Ikke satt", - "customcolumn.description": "Custom column '{0}'", - "customcolumn.description.bool": "Index of a boolean value", - "customcolumn.description.enum.many": "Alphabetical index of the {0} values", - "customcolumn.description.enum.none": "Alphabetical index of absolutely no values", - "customcolumn.description.enum.one": "Alphabetical index of one value", - "customcolumn.description.rating": "Index of ratings", - "customcolumn.description.series.many": "Alfabetisk indeks for {0} serier", - "customcolumn.description.series.none": "Alfabetisk indeks for ingen serier", - "customcolumn.description.series.one": "Alfabetisk indeks for èn enkelt serie", - "customcolumn.enum.unknown": "Ikke satt", - "customcolumn.float.unknown": "Ikke satt", - "customcolumn.int.unknown": "Ikke satt", - "customcolumn.rating.unknown": "Ikke satt", - "customcolumn.stars.many": "{0} Stars", - "customcolumn.stars.none": "No Stars", - "customcolumn.stars.one": "1 Star", - "customize.email": "Sett e-postadresse (for å sende bøker i e-post)", - "customize.fancybox": "Bruk en Lightbox", - "customize.filter": "Tillat filtrering på nøkkelord", - "customize.ignored": "Ignorerte kategorier", - "customize.paging": "Maks antall bøker per side (-1 for å deaktivere)", - "customize.style": "Tema", - "customize.template": "Template", - "customize.title": "Tilpass COPS brukergrensesnitt", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Fjern alt", - "filters.title": "Filters", - "home.alternate": "Hjem", - "i18n.coversection": "Omslag", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Språk", - "languages.alphabetical.many": "Alfabetisk indek for de {0} språkene", - "languages.alphabetical.none": "Alfabetisk indeks for absolutt ingen språk", - "languages.alphabetical.one": "Alfabetisk indeks for ett enkelt språk", - "languages.title": "Språk", - "links.title": "Nettlenker", - "mail.messagenotsent": "Meldingen kunne ikke sendes.", - "mail.messagesent": "Meldingen er sendt", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "Neste", - "paging.previous.alternate": "Forrige", - "permalink.alternate": "Permalenke", - "pubdate.title": "Published", - "publisher.name": "Utgiver", - "publishers.alphabetical.many": "Alfabetisk indeks for {0} utgivere", - "publishers.alphabetical.none": "Alfabetisk indeks for absolutt ingen utgivere", - "publishers.alphabetical.one": "Alfabetisk indeks for en enkelt utgiver", - "publishers.title": "Utgivere", - "publisherword.many": "{0} utgivere", - "publisherword.none": "Ingen utgivere", - "publisherword.one": "1 utgiver", - "ratings.many": "{0} vurderinger", - "ratings.none": "ingen vurderinger", - "ratings.one": "1 vurdering", - "ratings.title": "Vurderinger", - "rating.title": "Rating", - "ratingword.many": "{0} stjerner", - "ratingword.none": "Ingen stjerner", - "ratingword.one": "1 stjerne", - "recent.list": "{0} nyeste bøker", - "recent.title": "Nylig lagt til", - "search.alternate": "Søk", - "search.result": "Søkeresultat for *{0}*", - "search.result.author": "Søkeresultat for *{0}* i forfattere", - "search.result.book": "Søkeresultat for *{0}* i bøker", - "search.result.publisher": "Søkeresultat for *{0}* i utgivere", - "search.result.series": "Søkeresultat for *{0}* i serier", - "search.result.tag": "Søkeresultat for *{0}* i nøkkelord", - "search.sortorder.asc": "Stigende", - "search.sortorder.desc": "Synkende", - "series.alphabetical.many": "Alfabetisk indeks for {0} serier", - "series.alphabetical.none": "Alfabetisk indeks for ingen serier", - "series.alphabetical.one": "Alfabetisk indeks for èn enkelt serie", - "series.title": "Serier", - "seriesword.many": "{0} serier", - "seriesword.none": "Ingen serier", - "seriesword.one": "1 serie", - "sort.alternate": "Sorter", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "Andre bøker", - "splitByLetter.letter": "{0} begynner med {1}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "Alfabetisk indeks for {0} stikkord", - "tags.alphabetical.none": "Alfabetisk indeks for ingen stikkord", - "tags.alphabetical.one": "Alfabetisk indeks for ett enkelt stikkord", - "tags.title": "Stikkord", - "tagword.many": "{0} stikkord", - "tagword.none": "Ingen stikkord", - "tagword.one": "1 stikkord", - "tagword.title": "Stikkord", - "title.title": "Title", - "languages.abk": "Abkhaz", - "languages.aaf": "Afar", - "languages.afr": "Afrikaans", - "languages.aka": "Akan", - "languages.sqi": "Albanian", - "languages.amh": "Amharic", - "languages.ara": "Arabic", - "languages.arg": "Aragonese", - "languages.arc": "Aramaic", - "languages.hye": "Armenian", - "languages.asm": "Assamese", - "languages.ava": "Avaric", - "languages.ave": "Avestan", - "languages.aym": "Aymara", - "languages.aze": "Azerbaijani", - "languages.bam": "Bambara", - "languages.bak": "Bashkir", - "languages.eus": "Basque", - "languages.bel": "Belarusian", - "languages.ben": "Bengali", - "languages.bih": "Bihari", - "languages.bis": "Bislama", - "languages.bos": "Bosnian", - "languages.bre": "Breton", - "languages.bul": "Bulgarian", - "languages.mya": "Burmese", - "languages.cat": "Catalan", - "languages.cha": "Chamorro", - "languages.che": "Chechen", - "languages.nya": "Chichewa", - "languages.zho": "Chinese", - "languages.chv": "Chuvash", - "languages.cor": "Cornish", - "languages.cos": "Corsican", - "languages.cre": "Cree", - "languages.hrv": "Croatian", - "languages.ces": "Czech", - "languages.dan": "Danish", - "languages.div": "Divehi", - "languages.nld": "Dutch", - "languages.dzo": "Dzongkha", - "languages.eng": "English", - "languages.epo": "Esperanto", - "languages.est": "Estonian", - "languages.ewe": "Ewe", - "languages.fao": "Faroese", - "languages.fij": "Fijian", - "languages.fin": "Finnish", - "languages.fra": "French", - "languages.ful": "Fula", - "languages.glg": "Galician", - "languages.kat": "Georgian", - "languages.deu": "German", - "languages.ell": "Greek", - "languages.egy": "Egyptian (Ancient)", - "languages.grn": "Guaraní", - "languages.guj": "Gujarati", - "languages.hat": "Haitian", - "languages.hau": "Hausa", - "languages.heb": "Hebrew", - "languages.her": "Herero", - "languages.hin": "Hindi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Hungarian", - "languages.ina": "Interlingua", - "languages.ind": "Indonesian", - "languages.ile": "Interlingue", - "languages.gle": "Irish", - "languages.grc": "Greek, Ancient (to 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Icelandic", - "languages.ita": "Italian", - "languages.iku": "Inuktitut", - "languages.jpn": "Japanese", - "languages.jav": "Javanese", - "languages.kal": "Kalaallisut", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kashmiri", - "languages.kaz": "Kazakh", - "languages.khm": "Khmer", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kyrgyz", - "languages.kom": "Komi", - "languages.kon": "Kongo", - "languages.kor": "Korean", - "languages.kur": "Kurdish", - "languages.kua": "Kwanyama", - "languages.lat": "Latin", - "languages.ltz": "Luxembourgish", - "languages.lug": "Ganda", - "languages.lim": "Limburgish", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Lithuanian", - "languages.lub": "Luba-Katanga", - "languages.lav": "Latvian", - "languages.glv": "Manx", - "languages.mkd": "Macedonian", - "languages.mlg": "Malagasy", - "languages.msa": "Malay", - "languages.mal": "Malayalam", - "languages.mlt": "Maltese", - "languages.mri": "Māori", - "languages.mar": "Marathi", - "languages.mah": "Marshallese", - "languages.mon": "Mongolian", - "languages.nau": "Nauru", - "languages.nav": "Navajo", - "languages.nob": "Norsk bokmål", - "languages.nde": "North Ndebele", - "languages.nep": "Nepali", - "languages.ndo": "Ndonga", - "languages.nno": "Norsk nynorsk", - "languages.nor": "Norsk", - "languages.iii": "Nuosu", - "languages.nbl": "South Ndebele", - "languages.oci": "Occitan", - "languages.oji": "Ojibwe", - "languages.chu": "Old Church Slavonic", - "languages.orm": "Oromo", - "languages.ori": "Oriya", - "languages.oss": "Ossetian", - "languages.pan": "Panjabi", - "languages.pli": "Pāli", - "languages.fas": "Persian", - "languages.pol": "Polish", - "languages.pus": "Pashto", - "languages.por": "Portuguese", - "languages.que": "Quechua", - "languages.roh": "Romansh", - "languages.run": "Kirundi", - "languages.ron": "Romanian", - "languages.rus": "Russian", - "languages.sam": "Samaritan Aramaic", - "languages.san": "Sanskrit", - "languages.srd": "Sardinian", - "languages.snd": "Sindhi", - "languages.sme": "Northern Sami", - "languages.smo": "Samoan", - "languages.sag": "Sango", - "languages.srp": "Serbian", - "languages.gla": "Scottish Gaelic", - "languages.sna": "Shona", - "languages.sin": "Sinhala", - "languages.slk": "Slovak", - "languages.slv": "Slovene", - "languages.som": "Somali", - "languages.sot": "Southern Sotho", - "languages.spa": "Spanish", - "languages.sun": "Sundanese", - "languages.sux": "Sumerian", - "languages.swa": "Swahili", - "languages.ssw": "Swati", - "languages.swe": "Swedish", - "languages.syc": "Classical Syriac", - "languages.syr": "Syriac", - "languages.tam": "Tamil", - "languages.tel": "Telugu", - "languages.tgk": "Tajik", - "languages.tha": "Thai", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetan Standard", - "languages.tuk": "Turkmen", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tonga", - "languages.tur": "Turkish", - "languages.tso": "Tsonga", - "languages.tat": "Tatar", - "languages.twi": "Twi", - "languages.tah": "Tahitian", - "languages.uga": "Ugaritic", - "languages.uig": "Uighur", - "languages.ukr": "Ukrainian", - "languages.urd": "Urdu", - "languages.uzb": "Uzbek", - "languages.ven": "Venda", - "languages.vie": "Vietnamese", - "languages.vol": "Volapük", - "languages.win": "Walloon", - "languages.cym": "Welsh", - "languages.wol": "Wolof", - "languages.fry": "Western Frisian", - "languages.xho": "Xhosa", - "languages.yid": "Yiddish", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_nl.json b/COPS/cops-3.1.3/lang/Localization_nl.json deleted file mode 100644 index c9785acb..00000000 --- a/COPS/cops-3.1.3/lang/Localization_nl.json +++ /dev/null @@ -1,332 +0,0 @@ -{ - "about.title": "Over COPS", - "addeddate.title": "Toegevoegd", - "allbooks.alphabetical.many": "Alfabetische index van {0} boeken", - "allbooks.alphabetical.none": "Alfabetische index van absoluut geen enkel boek", - "allbooks.alphabetical.one": "Alfabetische index van 1 boek", - "allbooks.title": "Alle boeken", - "authors.alphabetical.many": "Alfabetische index van {0} auteurs", - "authors.alphabetical.none": "Alfabetische index van absoluut geen enkele auteur", - "authors.alphabetical.one": "Alfabetische index van 1 auteur", - "authors.title": "Auteurs", - "author.title": "Auteur", - "authorword.many": "{0} auteurs", - "authorword.none": "Geen auteur", - "authorword.one": "1 auteur", - "bookentry.author": "{0} door {1}", - "bookword.many": "{0} boeken", - "bookword.none": "Geen boek", - "bookword.one": "1 boek", - "bookword.title": "Boeken", - "cog.alternate": "Zoeken, sorteren en filters", - "content.series": "Reeksen:", - "content.series.data": "Boek {0} in de {1} reeks", - "content.summary": "Samenvatting", - "customcolumn.boolean.no": "Nee", - "customcolumn.boolean.unknown": "Niet ingesteld", - "customcolumn.boolean.yes": "Ja", - "customcolumn.date.format": "J-m-d", - "customcolumn.date.unknown": "Niet ingesteld", - "customcolumn.description": "Aangepaste kolom '{0}'", - "customcolumn.description.bool": "Index van een booleaanse waarde", - "customcolumn.description.enum.many": "Alfabetische index van {0} waarden", - "customcolumn.description.enum.none": "Alfabetische index van absoluut geen enkele waarde", - "customcolumn.description.enum.one": "Alfabetische index van één waarde", - "customcolumn.description.rating": "Index van waarderingen", - "customcolumn.description.series.many": "Alfabetische index van {0} reeksen", - "customcolumn.description.series.none": "Alfabetische index van absoluut geen enkele reeks", - "customcolumn.description.series.one": "Alfabetische index van 1 reeks", - "customcolumn.enum.unknown": "Niet ingesteld", - "customcolumn.float.unknown": "Niet ingesteld", - "customcolumn.int.unknown": "Niet ingesteld", - "customcolumn.rating.unknown": "Niet ingesteld", - "customcolumn.stars.many": "{0} Sterren", - "customcolumn.stars.none": "Geen sterren", - "customcolumn.stars.one": "1 Ster", - "customize.email": "E-mailadres ontvanger (om boeken te versturen per elektronische post)", - "customize.fancybox": "Gebruik een Lightbox", - "customize.filter": "Zet filteren op label aan", - "customize.ignored": "Niet opgenomen categorieën", - "customize.paging": "Maximaal aantal boeken per pagina (-1 voor oneindig aantal)", - "customize.style": "Opmaak COPS gebruikersomgeving", - "customize.template": "Sjabloon", - "customize.title": "Aanpassen COPS gebruikersomgeving", - "default.template": "Standaard COPS sjabloon", - "downloadall.title": "Download alles", - "downloadall.tooltip": "Download een zip bestand met alle boeken op deze pagina in dit formaat", - "extra.content": "Omschrijving", - "extra.link": "Koppeling", - "extra.title": "Extra Informatie", - "filter.clearall": "Wis alles", - "filters.title": "Filters", - "home.alternate": "Terug", - "i18n.coversection": "Omslag", - "identifiers.title": "identificatiegegevens", - "identifierword.many": "{0} identificatiegegevens", - "identifierword.none": "Geen identificatiegegevens", - "identifierword.one": "1 identificatiegegeven", - "language.title": "Taal", - "languages.alphabetical.many": "Alfabetische index van {0} talen", - "languages.alphabetical.none": "Alfabetische index van absoluut geen enkele taal", - "languages.alphabetical.one": "Alfabetische index van een enkele taal", - "languages.title": "Talen", - "libraries.many": "{0} virtuele bibliotheken", - "libraries.none": "Geen virtuele bibliotheken", - "libraries.one": "1 virtuele bibliotheek", - "libraries.title": "Virtuele bibliotheken", - "library.title": "Virtuele bibliotheek", - "links.title": "Koppeling", - "mail.messagenotsent": "Bericht kon niet verzonden worden.", - "mail.messagesent": "Bericht is verzonden", - "paging.first.alternate": "Eerste", - "paging.last.alternate": "Laatste", - "paging.next.alternate": "Volgende", - "paging.previous.alternate": "Vorige", - "permalink.alternate": "Permanente koppeling", - "pubdate.title": "Gepubliceerd", - "publisher.name": "Uitgever", - "publishers.alphabetical.many": "Alfabetische index van {0} uitgevers", - "publishers.alphabetical.none": "Alfabetische index van afwezige uitgevers", - "publishers.alphabetical.one": "Alfabetische index van een uitgever", - "publishers.title": "Uitgevers", - "publisherword.many": "{0} uitgevers", - "publisherword.none": "Geen uitgever", - "publisherword.one": "1 uitgever", - "ratings.many": "{0} verschillende waarderingen", - "ratings.none": "geen waarderingen", - "ratings.one": "{0} waarderingen", - "ratings.title": "Waardering", - "rating.title": "Beoordeling", - "ratingword.many": "{0} sterren", - "ratingword.none": "Geen ster", - "ratingword.one": "1 ster", - "recent.list": "{0} meest recente boeken", - "recent.title": "Recent toegevoegde boeken", - "search.alternate": "Zoeken", - "search.result": "Zoekresultaat voor *{0}*", - "search.result.author": "Zoekresultaat voor *{0}* in auteurs", - "search.result.book": "Zoekresultaat voor *{0}* in boeken", - "search.result.publisher": "Zoekresultaat voor *{0}* in uitgevers", - "search.result.series": "Zoekresultaat voor *{0}* in reeksen", - "search.result.tag": "Zoekresultaat voor *{0}* in labels", - "search.sortorder.asc": "A-Z", - "search.sortorder.desc": "Z-A", - "series.alphabetical.many": "Alfabetische index van {0} reeksen", - "series.alphabetical.none": "Alfabetische index van absoluut geen enkele reeks", - "series.alphabetical.one": "Alfabetische index van 1 reeks", - "series.title": "Reeksen", - "seriesword.many": "{0} reeksen", - "seriesword.none": "Geen reeks", - "seriesword.one": "1 reeks", - "sort.alternate": "Sorteren", - "sort.count": "Aantal", - "sort.names": "Namen", - "sort.titles": "Titels", - "sortby.title": "Sorteer op", - "splitByLetter.book.other": "Andere boeken", - "splitByLetter.letter": "{0} beginnend met {1}", - "splitByRange.range": "{0} binnen het bereik {1}", - "splitByYear.year": "{0} gepubliseerd in {1}", - "tags.alphabetical.many": "Alfabetische index van {0} labels", - "tags.alphabetical.none": "Alfabetische index van absoluut geen enkele label", - "tags.alphabetical.one": "Alfabetische index van 1 label", - "tags.title": "Labels", - "tagword.many": "{0} labels", - "tagword.none": "Geen label", - "tagword.one": "1 label", - "tagword.title": "Labels", - "title.title": "Titel", - "languages.abk": "Abchazisch", - "languages.aaf": "Afar", - "languages.afr": "Afrikaans", - "languages.aka": "Akan", - "languages.sqi": "Albanees", - "languages.amh": "Amhaars", - "languages.ara": "Arabisch", - "languages.arg": "Aragonees", - "languages.arc": "Aramees", - "languages.hye": "Armeens", - "languages.asm": "Assamees", - "languages.ava": "Avarisch", - "languages.ave": "Avestisch", - "languages.aym": "Aymara", - "languages.aze": "Azerbeidzjaans", - "languages.bam": "Bambara", - "languages.bak": "Basjkiers", - "languages.eus": "Baskisch", - "languages.bel": "Wit-Russisch", - "languages.ben": "Bengaals", - "languages.bih": "Biharitalen", - "languages.bis": "Bislama", - "languages.bos": "Bosnisch", - "languages.bre": "Bretons", - "languages.bul": "Bulgaars", - "languages.mya": "Birmees", - "languages.cat": "Catalaans", - "languages.cha": "Chamorro", - "languages.che": "Tsjetsjeens", - "languages.nya": "Nyanja", - "languages.zho": "Chinees", - "languages.chv": "Tsjoevasjisch", - "languages.cor": "Cornish", - "languages.cos": "Corsicaans", - "languages.cre": "Cree", - "languages.hrv": "Kroatisch", - "languages.ces": "Tsjechisch", - "languages.dan": "Deens", - "languages.div": "Divehi", - "languages.nld": "Nederlands", - "languages.dzo": "Dzongkha", - "languages.eng": "Engels", - "languages.epo": "Esperanto", - "languages.est": "Ests", - "languages.ewe": "Ewe", - "languages.fao": "Faeröers", - "languages.fij": "Fijisch", - "languages.fin": "Fins", - "languages.fra": "Frans", - "languages.ful": "Fulah", - "languages.glg": "Galicisch", - "languages.kat": "Georgisch", - "languages.deu": "Duits", - "languages.ell": "Grieks", - "languages.egy": "(Oud) Egyptisch", - "languages.grn": "Guaraní", - "languages.guj": "Gujarati", - "languages.hat": "Haïtiaans", - "languages.hau": "Hausa", - "languages.heb": "Hebreeuws", - "languages.her": "Herero", - "languages.hin": "Hindi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Hongaars", - "languages.ina": "Interlingua", - "languages.ind": "Indonesisch", - "languages.ile": "Interlingue", - "languages.gle": "Iers", - "languages.grc": "Oud Grieks (tot 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "IJslands", - "languages.ita": "Italiaans", - "languages.iku": "Inuktitut", - "languages.jpn": "Japans", - "languages.jav": "Javaans", - "languages.kal": "Groenlands", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kasjmiri", - "languages.kaz": "Kazachs", - "languages.khm": "Khmer", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kirgizisch", - "languages.kom": "Komi", - "languages.kon": "Kongo", - "languages.kor": "Koreaans", - "languages.kur": "Koerdisch", - "languages.kua": "Kuanyama", - "languages.lat": "Latijn", - "languages.ltz": "Luxemburgs", - "languages.lug": "Ganda", - "languages.lim": "Limburgs", - "languages.lin": "Lingala", - "languages.lao": "Laotiaans", - "languages.lit": "Litouws", - "languages.lub": "Luba-Katanga", - "languages.lav": "Lets", - "languages.glv": "Manx", - "languages.mkd": "Macedonisch", - "languages.mlg": "Malagasisch", - "languages.msa": "Maleis", - "languages.mal": "Malayalam", - "languages.mlt": "Maltees", - "languages.mri": "Māori", - "languages.mar": "Marathi", - "languages.mah": "Marshallees", - "languages.mon": "Mongools", - "languages.nau": "Nauruaans", - "languages.nav": "Navajo", - "languages.nob": "Noors Bokmål", - "languages.nde": "Noord-Ndbele", - "languages.nep": "Nepalees", - "languages.ndo": "Ndonga", - "languages.nno": "Noors Nynorsk", - "languages.nor": "Noors", - "languages.iii": "Sichuan Yi", - "languages.nbl": "Zuid-Ndbele", - "languages.oci": "Occitaans", - "languages.oji": "Ojibwa", - "languages.chu": "Kerkslavisch", - "languages.orm": "Oromo", - "languages.ori": "Odia", - "languages.oss": "Ossetisch", - "languages.pan": "Punjabi", - "languages.pli": "Pāli", - "languages.fas": "Perzisch", - "languages.pol": "Pools", - "languages.pus": "Pasjtoe", - "languages.por": "Portugees", - "languages.que": "Quechua", - "languages.roh": "Reto-Romaans", - "languages.run": "Kirundi", - "languages.ron": "Roemeens", - "languages.rus": "Russisch", - "languages.sam": "Samaritaans Aramees", - "languages.san": "Sanskriet", - "languages.srd": "Sardinisch", - "languages.snd": "Sindhi", - "languages.sme": "Noord-Samisch", - "languages.smo": "Samoaans", - "languages.sag": "Sango", - "languages.srp": "Servisch", - "languages.gla": "Schots Gaelic", - "languages.sna": "Shona", - "languages.sin": "Singalees", - "languages.slk": "Slovaaks", - "languages.slv": "Sloveens", - "languages.som": "Somalisch", - "languages.sot": "Zuid-Sotho", - "languages.spa": "Spaans", - "languages.sun": "Sudanees", - "languages.sux": "Sumerisch", - "languages.swa": "Swahili", - "languages.ssw": "Swazi", - "languages.swe": "Zweeds", - "languages.syc": "Klassiek Syrisch", - "languages.syr": "Syrisch", - "languages.tam": "Tamil", - "languages.tel": "Telugu", - "languages.tgk": "Tadzjieks", - "languages.tha": "Thais", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetaans", - "languages.tuk": "Turkmeens", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tonga", - "languages.tur": "Turks", - "languages.tso": "Tongaans", - "languages.tat": "Tataars", - "languages.twi": "Twi", - "languages.tah": "Tahitisch", - "languages.uga": "Ugaritisch", - "languages.uig": "Oeigoers", - "languages.ukr": "Oekraïens", - "languages.urd": "Urdu", - "languages.uzb": "Oezbeeks", - "languages.ven": "Venda", - "languages.vie": "Vietnamees", - "languages.vol": "Volapük", - "languages.win": "Waals", - "languages.cym": "Welsh", - "languages.wol": "Wolof", - "languages.fry": "Fries", - "languages.xho": "Xhosa", - "languages.yid": "Jiddisch", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_pl.json b/COPS/cops-3.1.3/lang/Localization_pl.json deleted file mode 100644 index 38f65ecf..00000000 --- a/COPS/cops-3.1.3/lang/Localization_pl.json +++ /dev/null @@ -1,332 +0,0 @@ -{ - "about.title": "Informacje", - "addeddate.title": "Dodany", - "allbooks.alphabetical.many": "Indeks alfabetyczny według {0} tytułów książek", - "allbooks.alphabetical.none": "Brak książek w spisie", - "allbooks.alphabetical.one": "Indeks alfabetyczny jednej książki", - "allbooks.title": "Wszystkie książki", - "authors.alphabetical.many": "Indeks alfabetyczny według {0} autorów", - "authors.alphabetical.none": "Indeks książek w których autor jest nieznany", - "authors.alphabetical.one": "Indeks książek", - "authors.title": "Autorzy", - "author.title": "Autor", - "authorword.many": "{0} autorów", - "authorword.none": "Brak autorów", - "authorword.one": "1 autor", - "bookentry.author": "{0} przez {1}", - "bookword.many": "{0} książek", - "bookword.none": "Brak ksiażek", - "bookword.one": "1 książka", - "bookword.title": "Książki", - "cog.alternate": "Wyszukiwanie, sortowanie i filtrowanie", - "content.series": "Serie:", - "content.series.data": "{0} książka w serii {1}", - "content.summary": "Podsumowanie", - "customcolumn.boolean.no": "Nie", - "customcolumn.boolean.unknown": "Domyślny dostęp", - "customcolumn.boolean.yes": "Tak", - "customcolumn.date.format": "R-m-d", - "customcolumn.date.unknown": "Domyślny dostęp", - "customcolumn.description": "Kolumna własna '{0}'", - "customcolumn.description.bool": "Indeks wartości logicznej", - "customcolumn.description.enum.many": "Alfabetyczny indeks wartości {0}", - "customcolumn.description.enum.none": "Indeks alfabetyczny absolutnie żadnych wartości", - "customcolumn.description.enum.one": "Indeks alfabetyczny jednej wartości", - "customcolumn.description.rating": "Indeks ocen", - "customcolumn.description.series.many": "Indeks alfabetyczny serii {0}", - "customcolumn.description.series.none": "Indeks alfabetyczny - brak serii", - "customcolumn.description.series.one": "Indeks alfabetyczny jednej serii", - "customcolumn.enum.unknown": "Nie ustawiony", - "customcolumn.float.unknown": "Nie ustawiony", - "customcolumn.int.unknown": "Nie ustawiony", - "customcolumn.rating.unknown": "Nie ustawiony", - "customcolumn.stars.many": "gwiazdek: {0}", - "customcolumn.stars.none": "Brak gwiazdek", - "customcolumn.stars.one": "1 gwiazdka", - "customize.email": "Ustaw swój adres e-mail (aby wysyłać książki)", - "customize.fancybox": "Używaj Lightbox (wyświetla książki w okienku)", - "customize.filter": "Używaj filtrowania po kategoriach", - "customize.ignored": "Zignorowane kategorie", - "customize.paging": "Maksymalna liczba książek na stronie (-1 bez stronicowania)", - "customize.style": "Szablon wyglądu", - "customize.template": "Szablon", - "customize.title": "Ustawienia COPS", - "default.template": "Domyślny szablon COPS", - "downloadall.title": "Ściągnij wszystko", - "downloadall.tooltip": "Pobierz plik zip zawierający wszystkie książki na tej stronie w tym formacie", - "extra.content": "Opis", - "extra.link": "Link", - "extra.title": "Dodatkowe informacje", - "filter.clearall": "Usuń Wszystkie", - "filters.title": "Filtry", - "home.alternate": "Strona głowna", - "i18n.coversection": "Okładka", - "identifiers.title": "Identyfikatory", - "identifierword.many": "{0} identyfikatory", - "identifierword.none": "Brak identyfikatora", - "identifierword.one": "1 identyfikator", - "language.title": "Język", - "languages.alphabetical.many": "Indeks alfabetyczny według {0} jezyków", - "languages.alphabetical.none": "Indeks alfabetyczny według języków - brak języków", - "languages.alphabetical.one": "Indeks alfabetyczny według języków jeden język", - "languages.title": "Języki", - "libraries.many": "{0} biblioteki wirtualne", - "libraries.none": "Brak bibliotek wirtualnych", - "libraries.one": "1 wirtualna biblioteka", - "libraries.title": "Biblioteki wirtualne", - "library.title": "Wirtualna biblioteka", - "links.title": "Łącza", - "mail.messagenotsent": "Wiadomość nie może być wysłana", - "mail.messagesent": "Wiadomość wysłana", - "paging.first.alternate": "Pierwsza", - "paging.last.alternate": "Ostatnia", - "paging.next.alternate": "Następna", - "paging.previous.alternate": "Poprzednia", - "permalink.alternate": "Bezpośrednie łącze", - "pubdate.title": "Opublikowany", - "publisher.name": "Wydawca", - "publishers.alphabetical.many": "Indeks alfabetyczny według {0} wydawców", - "publishers.alphabetical.none": "Indeks alfabetyczny wydawców - brak wydawców", - "publishers.alphabetical.one": "Indeks alfabetyczny wydawców - jeden wydawca", - "publishers.title": "Wydawcy", - "publisherword.many": "{0} wydawców", - "publisherword.none": "brak wydawców", - "publisherword.one": "jeden wydawca", - "ratings.many": "{0} oceny", - "ratings.none": "brak ocen", - "ratings.one": "1 ocena", - "ratings.title": "Oceny", - "rating.title": "Ocena", - "ratingword.many": "gwiazdek: {0}", - "ratingword.none": "brak gwiazdek", - "ratingword.one": "1 gwiazdka", - "recent.list": "{0} ostatnio dodanych książek", - "recent.title": "Ostatnio dodane książki", - "search.alternate": "Szukaj", - "search.result": "Wyniki wyszukiwania dla *{0}*", - "search.result.author": "Wyniki wyszukiwania dla *{0}* w autorach", - "search.result.book": "Wyniki wyszukiwania dla *{0}* w ksiązkach", - "search.result.publisher": "Wyniki wyszukiwania dla *{0}* w wydwcach", - "search.result.series": "Wyniki wyszukiwania dla *{0}* W seriach", - "search.result.tag": "Wyniki wyszukiwania dla *{0}* w tagach", - "search.sortorder.asc": "Rosnąco", - "search.sortorder.desc": "Malejąco", - "series.alphabetical.many": "Indeks alfabetyczny {0} serii", - "series.alphabetical.none": "Indeks alfabetyczny - brak serii", - "series.alphabetical.one": "Indeks alfabetyczny jedna seria", - "series.title": "Serie", - "seriesword.many": "Serii: {0}", - "seriesword.none": "Brak serii", - "seriesword.one": "Jedna seria", - "sort.alternate": "Sortowanie", - "sort.count": "Ilość", - "sort.names": "Nazwy", - "sort.titles": "Tytuły", - "sortby.title": "Sortuj według", - "splitByLetter.book.other": "Pozostałe książki", - "splitByLetter.letter": "{0} na literę {1}", - "splitByRange.range": "{0} w zakresie {1}", - "splitByYear.year": "{0} opublikowane w {1}", - "tags.alphabetical.many": "Indeks alfabetyczny według {0} etykiet", - "tags.alphabetical.none": "Indeks alfabetyczny tagów brak etykiet", - "tags.alphabetical.one": "Indeks alfabetyczny według jednej etykiety", - "tags.title": "Etykiety", - "tagword.many": "{0} etykiet", - "tagword.none": "Brak etykiet", - "tagword.one": "Jedna eykieta", - "tagword.title": "Etykiety", - "title.title": "Tytuł", - "languages.abk": "Abchazki", - "languages.aaf": "Afar", - "languages.afr": "Afrykanerski", - "languages.aka": "Akan", - "languages.sqi": "Albański", - "languages.amh": "Amharski", - "languages.ara": "Arabski", - "languages.arg": "Aragoński", - "languages.arc": "Aramejski", - "languages.hye": "Ormiański", - "languages.asm": "Asamski", - "languages.ava": "Awaryk", - "languages.ave": "Awestyjski", - "languages.aym": "Ajmara", - "languages.aze": "Azerbejdżański", - "languages.bam": "Bambara", - "languages.bak": "Baszkir", - "languages.eus": "Baskijski", - "languages.bel": "Białoruski", - "languages.ben": "Bengalski", - "languages.bih": "Bihari", - "languages.bis": "Bislama", - "languages.bos": "Bośniacki", - "languages.bre": "Breton", - "languages.bul": "Bułgarski", - "languages.mya": "Burmese", - "languages.cat": "Catalan", - "languages.cha": "Chamorro", - "languages.che": "Chechen", - "languages.nya": "Chichewa", - "languages.zho": "Chiński", - "languages.chv": "Chuvash", - "languages.cor": "Cornish", - "languages.cos": "Corsican", - "languages.cre": "Cree", - "languages.hrv": "Chorwacki", - "languages.ces": "Czeski", - "languages.dan": "Duński", - "languages.div": "Divehi", - "languages.nld": "Holenderski", - "languages.dzo": "Dzongkha", - "languages.eng": "Angielski", - "languages.epo": "Esperanto", - "languages.est": "Estoński", - "languages.ewe": "Ewe", - "languages.fao": "Farerski", - "languages.fij": "Fijian", - "languages.fin": "Fiński", - "languages.fra": "French", - "languages.ful": "Fula", - "languages.glg": "Galician", - "languages.kat": "Gruziński", - "languages.deu": "Niemiecki", - "languages.ell": "Grecki", - "languages.egy": "Egyptian (Ancient)", - "languages.grn": "Guaraní", - "languages.guj": "Gudżarati", - "languages.hat": "Haitian", - "languages.hau": "Hausa", - "languages.heb": "Hebrew", - "languages.her": "Herero", - "languages.hin": "Hindi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Hungarian", - "languages.ina": "Interlingua", - "languages.ind": "Indonesian", - "languages.ile": "Interlingue", - "languages.gle": "Irish", - "languages.grc": "Greek, Ancient (to 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Islandzki", - "languages.ita": "Włoski", - "languages.iku": "Inuktitut", - "languages.jpn": "Japoński", - "languages.jav": "Javanese", - "languages.kal": "Kalaallisut", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kashmiri", - "languages.kaz": "Kazakh", - "languages.khm": "Khmer", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kyrgyz", - "languages.kom": "Komi", - "languages.kon": "Kongo", - "languages.kor": "Koreański", - "languages.kur": "Kurdish", - "languages.kua": "Kwanyama", - "languages.lat": "Latin", - "languages.ltz": "Luxembourgish", - "languages.lug": "Ganda", - "languages.lim": "Limburgish", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Litewski", - "languages.lub": "Luba-Katanga", - "languages.lav": "Latvian", - "languages.glv": "Manx", - "languages.mkd": "Macedonian", - "languages.mlg": "Malagasy", - "languages.msa": "Malay", - "languages.mal": "Malayalam", - "languages.mlt": "Maltese", - "languages.mri": "Māori", - "languages.mar": "Marathi", - "languages.mah": "Marshallese", - "languages.mon": "Mongolian", - "languages.nau": "Nauru", - "languages.nav": "Navajo", - "languages.nob": "Norwegian Bokmål", - "languages.nde": "North Ndebele", - "languages.nep": "Nepali", - "languages.ndo": "Ndonga", - "languages.nno": "Norweski Nynorsk", - "languages.nor": "Norweski", - "languages.iii": "Nuosu", - "languages.nbl": "South Ndebele", - "languages.oci": "Occitan", - "languages.oji": "Ojibwe", - "languages.chu": "Old Church Slavonic", - "languages.orm": "Oromo", - "languages.ori": "Oriya", - "languages.oss": "Osetiański", - "languages.pan": "Panjabi", - "languages.pli": "Pāli", - "languages.fas": "Perski", - "languages.pol": "Polski", - "languages.pus": "Paszto", - "languages.por": "Portugalski", - "languages.que": "Quechua", - "languages.roh": "Romansh", - "languages.run": "Kirundi", - "languages.ron": "Romanian", - "languages.rus": "Russian", - "languages.sam": "Samaritan Aramaic", - "languages.san": "Sanskrit", - "languages.srd": "Sardinian", - "languages.snd": "Sindhi", - "languages.sme": "Northern Sami", - "languages.smo": "Samoan", - "languages.sag": "Sango", - "languages.srp": "Serbian", - "languages.gla": "Szkocki gaelicki", - "languages.sna": "Shona", - "languages.sin": "Sinhala", - "languages.slk": "Słowacki", - "languages.slv": "Słowieński", - "languages.som": "Somali", - "languages.sot": "Southern Sotho", - "languages.spa": "Hiszpański", - "languages.sun": "Sundanese", - "languages.sux": "Sumerian", - "languages.swa": "Swahili", - "languages.ssw": "Swati", - "languages.swe": "Szwedzki", - "languages.syc": "Classical Syriac", - "languages.syr": "Syriac", - "languages.tam": "Tamil", - "languages.tel": "Telugu", - "languages.tgk": "Tajik", - "languages.tha": "Thai", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetan Standard", - "languages.tuk": "Turkmenski", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tonga", - "languages.tur": "Turecki", - "languages.tso": "Tsonga", - "languages.tat": "Tatar", - "languages.twi": "Twi", - "languages.tah": "Tahitański", - "languages.uga": "Ugarycki", - "languages.uig": "Ujgur", - "languages.ukr": "Ukraiński", - "languages.urd": "Urdu", - "languages.uzb": "Uzbecki", - "languages.ven": "Venda", - "languages.vie": "Wietnamski", - "languages.vol": "Volapük", - "languages.win": "Walonia", - "languages.cym": "Walijski", - "languages.wol": "Wolof", - "languages.fry": "Zachodniofryzyjski", - "languages.xho": "Xhosa", - "languages.yid": "Jidysz", - "languages.yor": "Joruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "koniec" -} diff --git a/COPS/cops-3.1.3/lang/Localization_pt_BR.json b/COPS/cops-3.1.3/lang/Localization_pt_BR.json deleted file mode 100644 index 994535a7..00000000 --- a/COPS/cops-3.1.3/lang/Localization_pt_BR.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "Sobre o COPS", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "Índice alfabético dos {0} livros", - "allbooks.alphabetical.none": "Índice alfabético - nenhum livro", - "allbooks.alphabetical.one": "Índice alfabético de um livro", - "allbooks.title": "Todos os livros", - "authors.alphabetical.many": "Índice alfabético dos {0} autores", - "authors.alphabetical.none": "Índice alfabético - nenhum autor", - "authors.alphabetical.one": "Índice alfabético de um autor", - "authors.title": "Autores", - "author.title": "Author", - "authorword.many": "{0} autores", - "authorword.none": "Nenhum autor", - "authorword.one": "1 autor", - "bookentry.author": "{0} por {1}", - "bookword.many": "{0} livros", - "bookword.none": "Nenhum livro", - "bookword.one": "1 livro", - "bookword.title": "Livros", - "cog.alternate": "Pesquisar, ordenar e filtrar", - "content.series": "Séries:", - "content.series.data": "Livro {0} da série {1}", - "content.summary": "Resumo", - "customcolumn.boolean.no": "Não", - "customcolumn.boolean.unknown": "Não definido", - "customcolumn.boolean.yes": "Sim", - "customcolumn.date.format": "d-m-A", - "customcolumn.date.unknown": "Não definido", - "customcolumn.description": "Coluna personalizada '{0}'", - "customcolumn.description.bool": "Index of a boolean value", - "customcolumn.description.enum.many": "Alphabetical index of the {0} values", - "customcolumn.description.enum.none": "Alphabetical index of absolutely no values", - "customcolumn.description.enum.one": "Alphabetical index of one value", - "customcolumn.description.rating": "Índice de avaliações", - "customcolumn.description.series.many": "Índice alfabético das {0} séries", - "customcolumn.description.series.none": "Índice alfabético - nenhuma série", - "customcolumn.description.series.one": "Índice alfabético de uma série", - "customcolumn.enum.unknown": "Não definido", - "customcolumn.float.unknown": "Não definido", - "customcolumn.int.unknown": "Não definido", - "customcolumn.rating.unknown": "Não definido", - "customcolumn.stars.many": "{0} Stars", - "customcolumn.stars.none": "Sem estrelas", - "customcolumn.stars.one": "1 estrela", - "customize.email": "Forneça o seu email (para ativar envio de ebooks)", - "customize.fancybox": "Usar o Lightbox (detalhes do livro numa janela flutuante)", - "customize.filter": "Ativar filtro por etiqueta", - "customize.ignored": "Categorias ignoradas", - "customize.paging": "Número máximo de livros por página (-1 para desabilitar)", - "customize.style": "Tema", - "customize.template": "Template", - "customize.title": "Personalizar a interface do COPS", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Limpar tudo", - "filters.title": "Filters", - "home.alternate": "Principal", - "i18n.coversection": "Capa", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Idioma", - "languages.alphabetical.many": "Índice alfabético dos {0} idiomas", - "languages.alphabetical.none": "Índice alfabético - nenhum idioma", - "languages.alphabetical.one": "Índice alfabético de um idioma", - "languages.title": "Idiomas", - "links.title": "Links", - "mail.messagenotsent": "Não foi possível enviar a mensagem.", - "mail.messagesent": "A mensagem foi enviada", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "Próximo", - "paging.previous.alternate": "Anterior", - "permalink.alternate": "Link permanente", - "pubdate.title": "Published", - "publisher.name": "Editora", - "publishers.alphabetical.many": "Índice alfabético das {0} editoras", - "publishers.alphabetical.none": "Índice alfabético - nenhuma editora", - "publishers.alphabetical.one": "Índice alfabético de uma editora", - "publishers.title": "Editoras", - "publisherword.many": "{0} editoras", - "publisherword.none": "Nenhuma editora", - "publisherword.one": "1 editora", - "ratings.many": "{0} avaliações", - "ratings.none": "nenhuma avaliação", - "ratings.one": "1 avaliação", - "ratings.title": "Avaliações", - "rating.title": "Rating", - "ratingword.many": "{0} estrelas", - "ratingword.none": "Nenhuma estrela", - "ratingword.one": "1 estrela", - "recent.list": "{0} livros mais recentes", - "recent.title": "Recentemente adicionados", - "search.alternate": "Pesquisar", - "search.result": "Resultado da pesquisa por *{0}*", - "search.result.author": "Resultado da pesquisa por *{0}* em autores", - "search.result.book": "Resultado da pesquisa por *{0}* em livros", - "search.result.publisher": "Resultado da pesquisa por *{0}* em editoras", - "search.result.series": "Resultado da pesquisa por *{0}* em séries", - "search.result.tag": "Resultado da pesquisa por *{0}* em etiquetas", - "search.sortorder.asc": "Asc", - "search.sortorder.desc": "Desc", - "series.alphabetical.many": "Índice alfabético das {0} séries", - "series.alphabetical.none": "Índice alfabético - nenhuma série", - "series.alphabetical.one": "Índice alfabético de uma série", - "series.title": "Séries", - "seriesword.many": "{0} séries", - "seriesword.none": "Nenhuma série", - "seriesword.one": "1 série", - "sort.alternate": "Classificar", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "Outros livros", - "splitByLetter.letter": "{0} começando com {1}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "Índice alfabético das {0} etiquetas", - "tags.alphabetical.none": "Índice alfabético - nenhuma etiqueta", - "tags.alphabetical.one": "Índice alfabético de uma etiqueta", - "tags.title": "Etiquetas", - "tagword.many": "{0} etiquetas", - "tagword.none": "Nenhuma etiqueta", - "tagword.one": "1 etiqueta", - "tagword.title": "Etiquetas", - "title.title": "Title", - "languages.abk": "Abcázia", - "languages.aaf": "Afar", - "languages.afr": "Sul Africano", - "languages.aka": "Akan", - "languages.sqi": "Albanês", - "languages.amh": "Amárico", - "languages.ara": "Árabe", - "languages.arg": "Aragonês", - "languages.arc": "Aramaic", - "languages.hye": "Armênio", - "languages.asm": "Assamês", - "languages.ava": "Avari", - "languages.ave": "Avéstico", - "languages.aym": "Aymara", - "languages.aze": "Azerbaidjanês", - "languages.bam": "Bambara", - "languages.bak": "Basquir", - "languages.eus": "Basco", - "languages.bel": "Bielorrusso", - "languages.ben": "Bengali", - "languages.bih": "Bihari", - "languages.bis": "Bislamá", - "languages.bos": "Bósnio", - "languages.bre": "Bretão", - "languages.bul": "Búlgaro", - "languages.mya": "Birmanês", - "languages.cat": "Catalão", - "languages.cha": "Chamorro", - "languages.che": "Checheno", - "languages.nya": "Chichewa", - "languages.zho": "Chinês", - "languages.chv": "Chuvache", - "languages.cor": "Corniso", - "languages.cos": "Córsego", - "languages.cre": "Cree", - "languages.hrv": "Croata", - "languages.ces": "Checo", - "languages.dan": "Dinamarquês", - "languages.div": "Divehi", - "languages.nld": "Holandês", - "languages.dzo": "Dzonga", - "languages.eng": "Inglês", - "languages.epo": "Esperanto", - "languages.est": "Estoniano", - "languages.ewe": "Ewe", - "languages.fao": "Faroense", - "languages.fij": "fijiano", - "languages.fin": "Finlandês", - "languages.fra": "Francês", - "languages.ful": "Fula", - "languages.glg": "Galego", - "languages.kat": "Georgiano", - "languages.deu": "Alemão", - "languages.ell": "Grego", - "languages.egy": "Egyptian (Ancient)", - "languages.grn": "Guarani", - "languages.guj": "Gujarati", - "languages.hat": "Haitiano", - "languages.hau": "Hauçá", - "languages.heb": "Hebraico", - "languages.her": "Herero", - "languages.hin": "Híndi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Húngaro", - "languages.ina": "Interlíngua", - "languages.ind": "Indonésio", - "languages.ile": "Interlíngue", - "languages.gle": "Irlandês", - "languages.grc": "Greek, Ancient (to 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaque", - "languages.ido": "Ido", - "languages.isl": "Islandês", - "languages.ita": "Italiano", - "languages.iku": "Inuktitut", - "languages.jpn": "Japonês", - "languages.jav": "Javanês", - "languages.kal": "Kal", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kashmiri", - "languages.kaz": "Cazaque", - "languages.khm": "Khmer", - "languages.kik": "Quicuio", - "languages.kin": "Ruanda", - "languages.kir": "Quirguistão", - "languages.kom": "Komi", - "languages.kon": "Kongo", - "languages.kor": "Coreano", - "languages.kur": "Curdo", - "languages.kua": "Kwanyama", - "languages.lat": "Latim", - "languages.ltz": "Luxemburguês", - "languages.lug": "Ganda", - "languages.lim": "Limburguês", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Lituânio", - "languages.lub": "Luba-Katanga", - "languages.lav": "Letã", - "languages.glv": "Manês", - "languages.mkd": "Macedônio", - "languages.mlg": "Malgaxe", - "languages.msa": "Malaio", - "languages.mal": "Malaiala", - "languages.mlt": "Maltês", - "languages.mri": "Maori", - "languages.mar": "Marathi", - "languages.mah": "Marshalês", - "languages.mon": "Mongol", - "languages.nau": "Nauru", - "languages.nav": "Navajo", - "languages.nob": "Norueguês de Bokmal", - "languages.nde": "Ndebelê do Norte", - "languages.nep": "Nepalês", - "languages.ndo": "Ndonga", - "languages.nno": "Novo Norueguês", - "languages.nor": "Norueguês", - "languages.iii": "Nuosu", - "languages.nbl": "Ndebelê do Sul", - "languages.oci": "Occitan", - "languages.oji": "Ojíbua", - "languages.chu": "Eslavo Eclesiástico", - "languages.orm": "Oromo", - "languages.ori": "Oriá", - "languages.oss": "Osseta", - "languages.pan": "Panjabi", - "languages.pli": "Páli", - "languages.fas": "Pérsio", - "languages.pol": "Polonês", - "languages.pus": "Pachto", - "languages.por": "Português", - "languages.que": "Quíchua", - "languages.roh": "Romanche", - "languages.run": "Kirundi", - "languages.ron": "Romeno", - "languages.rus": "Russo", - "languages.sam": "Samaritan Aramaic", - "languages.san": "Sânscrito", - "languages.srd": "Sardenho", - "languages.snd": "Sindi", - "languages.sme": "Sami do Norte", - "languages.smo": "Samoano", - "languages.sag": "Sango", - "languages.srp": "Sérvio", - "languages.gla": "Gaélico Escocês", - "languages.sna": "Xichona", - "languages.sin": "Sinhala", - "languages.slk": "Eslovaco", - "languages.slv": "Esloveno", - "languages.som": "Somali", - "languages.sot": "Soto do Sul", - "languages.spa": "Espanhol", - "languages.sun": "Sundanês", - "languages.sux": "Sumerian", - "languages.swa": "Suaíle", - "languages.ssw": "Swati", - "languages.swe": "Sueco", - "languages.syc": "Classical Syriac", - "languages.syr": "Syriac", - "languages.tam": "Tâmil", - "languages.tel": "Telugu", - "languages.tgk": "Tadjique", - "languages.tha": "Tailandês", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetano Padrão", - "languages.tuk": "Turcomeno", - "languages.tgl": "Tagalo", - "languages.tsn": "Tswana", - "languages.ton": "Tonganês", - "languages.tur": "Turco", - "languages.tso": "Tsonga", - "languages.tat": "Tártaro", - "languages.twi": "Twi", - "languages.tah": "Taitiano", - "languages.uga": "Ugaritic", - "languages.uig": "Uigur", - "languages.ukr": "Ucraniano", - "languages.urd": "Urdu", - "languages.uzb": "Uzbeque", - "languages.ven": "Venda", - "languages.vie": "Vietnamita", - "languages.vol": "Volapuque", - "languages.win": "Valão", - "languages.cym": "Galês", - "languages.wol": "Uólofe", - "languages.fry": "Frísico Ocidental", - "languages.xho": "Xhosa", - "languages.yid": "Iídiche", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_pt_PT.json b/COPS/cops-3.1.3/lang/Localization_pt_PT.json deleted file mode 100644 index 8d8e6c26..00000000 --- a/COPS/cops-3.1.3/lang/Localization_pt_PT.json +++ /dev/null @@ -1,333 +0,0 @@ -{ - "about.title": "Sobre a aplicação", - "addeddate.title": "Adicionado", - "allbooks.alphabetical.many": "Índice alfabético ({0} livros)", - "allbooks.alphabetical.none": "Índice alfabético (sem livros)", - "allbooks.alphabetical.one": "Índice alfabético (1 livro)", - "allbooks.title": "Todos os livros", - "authors.alphabetical.many": "Índice alfabético ({0} autores)", - "authors.alphabetical.none": "Índice alfabético (autores)", - "authors.alphabetical.one": "Índice alfabético (1 autor)", - "authors.title": "Autores", - "author.title": "Autor", - "authorword.many": "{0} autores", - "authorword.none": "Sem autores", - "authorword.one": "1 autor", - "bookentry.author": "{0} por {1}", - "bookword.many": "{0} livros", - "bookword.none": "Sem livros", - "bookword.one": "1 livro", - "bookword.title": "Títulos", - "cog.alternate": "Pesquisar, ordenar e filtrar", - "content.series": "Séries:", - "content.series.data": "Livro {0} da série {1}", - "content.summary": "Informações/Resumo", - "customcolumn.boolean.no": "Não", - "customcolumn.boolean.unknown": "Não indicado", - "customcolumn.boolean.yes": "Sim", - "customcolumn.date.format": "d-m-A", - "customcolumn.date.unknown": "Não indicado", - "customcolumn.description": "Coluna personalizada '{0}'", - "customcolumn.description.bool": "Índice - valor booliano", - "customcolumn.description.enum.many": "Índice alfabético ({0} grupos)", - "customcolumn.description.enum.none": "Índice alfabético (sem grupos)", - "customcolumn.description.enum.one": "Índice alfabético (1 grupo)", - "customcolumn.description.rating": "Índice de avaliações", - "customcolumn.description.series.many": "Índice alfabético ({0} séries)", - "customcolumn.description.series.none": "Índice alfabético (sem séries)", - "customcolumn.description.series.one": "Índice alfabético (1 série)", - "customcolumn.enum.unknown": "Não indicado", - "customcolumn.float.unknown": "Não indicado", - "customcolumn.int.unknown": "Não indicado", - "customcolumn.rating.unknown": "Não indicado", - "customcolumn.stars.many": "{0} estrelas", - "customcolumn.stars.none": "Sem estrelas", - "customcolumn.stars.one": "1 estrela", - "customize.email": "Definir o seu email (para ativar envio de ebooks)", - "customize.fancybox": "Usar o Lightbox (detalhes do livro numa janela flutuante)", - "customize.filter": "Ativar filtragem por etiquetas", - "customize.ignored": "Categorias ignoradas", - "customize.paging": "Número máximo de títulos por página (-1 para desativar)", - "customize.style": "Estilo", - "customize.template": "Tema", - "customize.title": "Personalizar interface do utilizador", - "default.template": "Tema predefinido COPS", - "downloadall.title": "Descarregar tudo", - "downloadall.tooltip": "Descarregar um ficheiro zip contendo todos os livros desta página e neste formato", - "extra.content": "Descrição", - "extra.files": "Ficheiros extra", - "extra.link": "Hiperligação", - "extra.title": "Informação adicional", - "filter.clearall": "Limpar tudo", - "filters.title": "Filtros", - "home.alternate": "Entrada", - "i18n.coversection": "Capa", - "identifiers.title": "Identificadores", - "identifierword.many": "{0} identificadores", - "identifierword.none": "Sem identificadores", - "identifierword.one": "1 identificador", - "language.title": "Idioma", - "languages.alphabetical.many": "Índice alfabético ({0} idiomas)", - "languages.alphabetical.none": "Índice alfabético (sem idiomas)", - "languages.alphabetical.one": "Índice alfabético (1 idioma)", - "languages.title": "Idiomas", - "libraries.many": "{0} bibliotecas virtuais", - "libraries.none": "Sem bibliotecas virtuais", - "libraries.one": "1 biblioteca virtual", - "libraries.title": "Bibliotecas virtuais", - "library.title": "Biblioteca virtual", - "links.title": "Ligações", - "mail.messagenotsent": "Não foi possível enviar a mensagem.", - "mail.messagesent": "A mensagem foi enviada", - "paging.first.alternate": "Primeiro", - "paging.last.alternate": "Último", - "paging.next.alternate": "Seguinte", - "paging.previous.alternate": "Anterior", - "permalink.alternate": "Ligação permanente", - "pubdate.title": "Publicação", - "publisher.name": "Editora", - "publishers.alphabetical.many": "Índice alfabético ({0} editoras)", - "publishers.alphabetical.none": "Índice alfabético (sem editoras)", - "publishers.alphabetical.one": "Índice alfabético (1 editora)", - "publishers.title": "Editoras", - "publisherword.many": "{0} editoras", - "publisherword.none": "Sem editoras", - "publisherword.one": "1 editora", - "ratings.many": "{0} avaliações", - "ratings.none": "sem avaliações", - "ratings.one": "1 avaliação", - "ratings.title": "Avaliações", - "rating.title": "Pontuação", - "ratingword.many": "{0} estrelas", - "ratingword.none": "Sem estrelas", - "ratingword.one": "1 estrela", - "recent.list": "{0} livros mais recentes", - "recent.title": "Adicionados recentemente", - "search.alternate": "Pesquisar", - "search.result": "Resultado da pesquisa por *{0}*", - "search.result.author": "Resultado da pesquisa por *{0}* em autores", - "search.result.book": "Resultado da pesquisa por *{0}* em livros", - "search.result.publisher": "Resultado da pesquisa por *{0}* em editoras", - "search.result.series": "Resultado da pesquisa por *{0}* em séries", - "search.result.tag": "Resultado da pesquisa por *{0}* em etiquetas", - "search.sortorder.asc": "A-Z", - "search.sortorder.desc": "Z-A", - "series.alphabetical.many": "Índice alfabético ({0} séries)", - "series.alphabetical.none": "Índice alfabético (sem séries)", - "series.alphabetical.one": "Índice alfabético (1 série)", - "series.title": "Séries", - "seriesword.many": "{0} séries", - "seriesword.none": "Sem séries", - "seriesword.one": "1 série", - "sort.alternate": "Ordenar", - "sort.count": "Contagem", - "sort.names": "Nomes", - "sort.titles": "Títulos", - "sortby.title": "Ordenar por", - "splitByLetter.book.other": "Outros livros", - "splitByLetter.letter": "{0} pela letra: {1}", - "splitByRange.range": "{0} no intervalo {1}", - "splitByYear.year": "{0} publicado em {1}", - "tags.alphabetical.many": "Índice alfabético ({0} etiquetas)", - "tags.alphabetical.none": "Índice alfabético (sem etiquetas)", - "tags.alphabetical.one": "Índice alfabético (1 etiqueta)", - "tags.title": "Etiquetas", - "tagword.many": "{0} etiquetas", - "tagword.none": "Sem etiquetas", - "tagword.one": "1 etiqueta", - "tagword.title": "Etiquetas", - "title.title": "Título", - "languages.abk": "Abcázia", - "languages.aaf": "Afar", - "languages.afr": "Africânder", - "languages.aka": "Akan", - "languages.sqi": "Albanês", - "languages.amh": "Amárico", - "languages.ara": "Árabe", - "languages.arg": "Aragonês", - "languages.arc": "Aramaico", - "languages.hye": "Armênio", - "languages.asm": "Assamês", - "languages.ava": "Avari", - "languages.ave": "Avéstico", - "languages.aym": "Aymara", - "languages.aze": "Azerbaidjanês", - "languages.bam": "Bambara", - "languages.bak": "Basquir", - "languages.eus": "Basco", - "languages.bel": "Bielorrusso", - "languages.ben": "Bengali", - "languages.bih": "Bihari", - "languages.bis": "Bislamá", - "languages.bos": "Bósnio", - "languages.bre": "Bretão", - "languages.bul": "Búlgaro", - "languages.mya": "Birmanês", - "languages.cat": "Catalão", - "languages.cha": "Chamorro", - "languages.che": "Checheno", - "languages.nya": "Chichewa", - "languages.zho": "Chinês", - "languages.chv": "Chuvache", - "languages.cor": "Corniso", - "languages.cos": "Córsego", - "languages.cre": "Cree", - "languages.hrv": "Croata", - "languages.ces": "Checo", - "languages.dan": "Dinamarquês", - "languages.div": "Divehi", - "languages.nld": "Holandês", - "languages.dzo": "Dzonga", - "languages.eng": "Inglês", - "languages.epo": "Esperanto", - "languages.est": "Estoniano", - "languages.ewe": "Ewe", - "languages.fao": "Faroense", - "languages.fij": "Fijiano", - "languages.fin": "Finlandês", - "languages.fra": "Francês", - "languages.ful": "Fula", - "languages.glg": "Galego", - "languages.kat": "Georgiano", - "languages.deu": "Alemão", - "languages.ell": "Grego", - "languages.egy": "Egípcio (Antigo)", - "languages.grn": "Guarani", - "languages.guj": "Gujarati", - "languages.hat": "Haitiano", - "languages.hau": "Hauçá", - "languages.heb": "Hebraico", - "languages.her": "Herero", - "languages.hin": "Híndi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Húngaro", - "languages.ina": "Interlíngua", - "languages.ind": "Indonésio", - "languages.ile": "Interlíngue", - "languages.gle": "Irlandês", - "languages.grc": "Grego, Antigo (até 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaque", - "languages.ido": "Ido", - "languages.isl": "Islandês", - "languages.ita": "Italiano", - "languages.iku": "Inuktitut", - "languages.jpn": "Japonês", - "languages.jav": "Javanês", - "languages.kal": "Kal", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kashmiri", - "languages.kaz": "Cazaque", - "languages.khm": "Khmer", - "languages.kik": "Quicuio", - "languages.kin": "Ruanda", - "languages.kir": "Quirguistão", - "languages.kom": "Komi", - "languages.kon": "Kongo", - "languages.kor": "Coreano", - "languages.kur": "Curdo", - "languages.kua": "Kwanyama", - "languages.lat": "Latim", - "languages.ltz": "Luxemburguês", - "languages.lug": "Ganda", - "languages.lim": "Limburguês", - "languages.lin": "Lingala", - "languages.lao": "Laociano", - "languages.lit": "Lituânio", - "languages.lub": "Luba-Katanga", - "languages.lav": "Letã", - "languages.glv": "Manês", - "languages.mkd": "Macedônio", - "languages.mlg": "Malgaxe", - "languages.msa": "Malaio", - "languages.mal": "Malaiala", - "languages.mlt": "Maltês", - "languages.mri": "Maori", - "languages.mar": "Marathi", - "languages.mah": "Marshalês", - "languages.mon": "Mongol", - "languages.nau": "Nauru", - "languages.nav": "Navajo", - "languages.nob": "Norueguês de Bokmal", - "languages.nde": "Ndebelê do Norte", - "languages.nep": "Nepalês", - "languages.ndo": "Ndonga", - "languages.nno": "Novo Norueguês", - "languages.nor": "Norueguês", - "languages.iii": "Nuosu", - "languages.nbl": "Ndebelê do Sul", - "languages.oci": "Occitan", - "languages.oji": "Ojíbua", - "languages.chu": "Eslavo Eclesiástico", - "languages.orm": "Oromo", - "languages.ori": "Oriá", - "languages.oss": "Osseta", - "languages.pan": "Panjabi", - "languages.pli": "Páli", - "languages.fas": "Persa", - "languages.pol": "Polaco", - "languages.pus": "Pachto", - "languages.por": "Português", - "languages.que": "Quíchua", - "languages.roh": "Romanche", - "languages.run": "Kirundi", - "languages.ron": "Romeno", - "languages.rus": "Russo", - "languages.sam": "Aramaico samaritano", - "languages.san": "Sânscrito", - "languages.srd": "Sardenho", - "languages.snd": "Sindi", - "languages.sme": "Sami do Norte", - "languages.smo": "Samoano", - "languages.sag": "Sango", - "languages.srp": "Sérvio", - "languages.gla": "Gaélico Escocês", - "languages.sna": "Xichona", - "languages.sin": "Sinhala", - "languages.slk": "Eslovaco", - "languages.slv": "Esloveno", - "languages.som": "Somali", - "languages.sot": "Soto do Sul", - "languages.spa": "Espanhol", - "languages.sun": "Sundanês", - "languages.sux": "Sumério", - "languages.swa": "Suaíle", - "languages.ssw": "Swati", - "languages.swe": "Sueco", - "languages.syc": "Siríaco clássico", - "languages.syr": "Siríaco", - "languages.tam": "Tâmil", - "languages.tel": "Telugu", - "languages.tgk": "Tadjique", - "languages.tha": "Tailandês", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetano Padrão", - "languages.tuk": "Turcomeno", - "languages.tgl": "Tagalo", - "languages.tsn": "Tswana", - "languages.ton": "Tonganês", - "languages.tur": "Turco", - "languages.tso": "Tsonga", - "languages.tat": "Tártaro", - "languages.twi": "Twi", - "languages.tah": "Taitiano", - "languages.uga": "Ugarítico", - "languages.uig": "Uigur", - "languages.ukr": "Ucraniano", - "languages.urd": "Urdu", - "languages.uzb": "Uzbeque", - "languages.ven": "Venda", - "languages.vie": "Vietnamita", - "languages.vol": "Volapuque", - "languages.win": "Valão", - "languages.cym": "Galês", - "languages.wol": "Uólofe", - "languages.fry": "Frísico Ocidental", - "languages.xho": "Xhosa", - "languages.yid": "Iídiche", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_ro.json b/COPS/cops-3.1.3/lang/Localization_ro.json deleted file mode 100644 index a5ebdb5d..00000000 --- a/COPS/cops-3.1.3/lang/Localization_ro.json +++ /dev/null @@ -1,332 +0,0 @@ -{ - "about.title": "Despre COPS", - "addeddate.title": "Adaugat", - "allbooks.alphabetical.many": "Index alfabetic: {0} cărţi", - "allbooks.alphabetical.none": "Index alfabetic: 0 cărţi", - "allbooks.alphabetical.one": "Index alfabetic: 1 carte", - "allbooks.title": "Toate cărţile", - "authors.alphabetical.many": "Index alfabetic: {0} autori", - "authors.alphabetical.none": "Index alfabetic: 0 autori", - "authors.alphabetical.one": "Index alfabetic: 1 autor", - "authors.title": "Autori", - "author.title": "Autor", - "authorword.many": "{0} autori", - "authorword.none": "Nici un autor", - "authorword.one": "1 autor", - "bookentry.author": "{0} din {1}", - "bookword.many": "{0} cărţi", - "bookword.none": "Fără cărţi", - "bookword.one": "1 carte", - "bookword.title": "Cărţi", - "cog.alternate": "Căutare, sortare şi filtrare", - "content.series": "Serii:", - "content.series.data": "Cartea {0} din serie de {1}", - "content.summary": "Sumar", - "customcolumn.boolean.no": "Nu", - "customcolumn.boolean.unknown": "Ne setat", - "customcolumn.boolean.yes": "Da", - "customcolumn.date.format": "an-luna-zi", - "customcolumn.date.unknown": "Ne setat", - "customcolumn.description": "Coloană custom", - "customcolumn.description.bool": "Index valoare boolean", - "customcolumn.description.enum.many": "Index alfabetic pentru {0} valori", - "customcolumn.description.enum.none": "Index alfabetic fără valori", - "customcolumn.description.enum.one": "Index alfabetic o singură valoare", - "customcolumn.description.rating": "Index voturi", - "customcolumn.description.series.many": "Index alfabetic: {0} serii", - "customcolumn.description.series.none": "Index alfabetic: 0 serii", - "customcolumn.description.series.one": "Index alfabetic: 1 serie", - "customcolumn.enum.unknown": "Ne setat", - "customcolumn.float.unknown": "Ne setat", - "customcolumn.int.unknown": "Ne setat", - "customcolumn.rating.unknown": "Ne setat", - "customcolumn.stars.many": "{0} stele", - "customcolumn.stars.none": "Fără stele", - "customcolumn.stars.one": "1 Stea", - "customize.email": "Setează-ţi adresa de mail (pentru a putea trimite cărţi prin email)", - "customize.fancybox": "Foloseşte Lightbox (cărţile se încarcă într-un cadru plutitor)", - "customize.filter": "Activează filtrarea după tag-uri", - "customize.ignored": "Categorii ignorate", - "customize.paging": "Număr maxim de cărţi pe pagină (-1 pentru dezactivare)", - "customize.style": "Temă", - "customize.template": "Șablon", - "customize.title": "Customizează interfaţa COPS", - "default.template": "Default COPS template", - "downloadall.title": "Descarcaţi toate", - "downloadall.tooltip": "Descărcaţi un fișier zip care conține toate cărțile de pe aceasta pagina in acest format", - "extra.content": "Descriere", - "extra.link": "Link", - "extra.title": "Informație suplimentara", - "filter.clearall": "Anulează tot", - "filters.title": "Filtre", - "home.alternate": "Acasă", - "i18n.coversection": "Copertă", - "identifiers.title": "Identificatori", - "identifierword.many": "{0} identificatori", - "identifierword.none": "Nici un identificator", - "identifierword.one": "1 identificator", - "language.title": "Limbă", - "languages.alphabetical.many": "Index alfabetic: {0} limbi", - "languages.alphabetical.none": "Index alfabetic: 0 limbi", - "languages.alphabetical.one": "Index alfabetic: 1 limbă", - "languages.title": "Limbi", - "libraries.many": "{0} librării virtuale", - "libraries.none": "Nici o librărie virtuala", - "libraries.one": "O librărie virtuala", - "libraries.title": "Librării virtuale", - "library.title": "Librărie virtuala", - "links.title": "Link-uri", - "mail.messagenotsent": "Mesajul nu a putut fi trimis.", - "mail.messagesent": "Mesajul a fost trimis", - "paging.first.alternate": "Primul", - "paging.last.alternate": "Ultimul", - "paging.next.alternate": "Următor", - "paging.previous.alternate": "Anterior", - "permalink.alternate": "Link permanent", - "pubdate.title": "Publicat", - "publisher.name": "Editură", - "publishers.alphabetical.many": "Index alfabetic: {0} edituri", - "publishers.alphabetical.none": "Index alfabetic: 0 edituri", - "publishers.alphabetical.one": "Index alfabetic: 1 editură", - "publishers.title": "Edituri", - "publisherword.many": "{0} edituri", - "publisherword.none": "Fără edituri", - "publisherword.one": "1 editură", - "ratings.many": "{0} voturi", - "ratings.none": "fără voturi", - "ratings.one": "1 vot", - "ratings.title": "Voturi", - "rating.title": "Rating", - "ratingword.many": "{0} stele", - "ratingword.none": "Fără stele", - "ratingword.one": "1 stea", - "recent.list": "{0} cărţi recente", - "recent.title": "Recent adăugate", - "search.alternate": "Căutare", - "search.result": "Rezultatul căutării *{0}*", - "search.result.author": "Rezultatul căutării *{0}* în autori", - "search.result.book": "Rezultatul căutării *{0}* în cărţi", - "search.result.publisher": "Rezultatul căutării *{0}* în edituri", - "search.result.series": "Rezultatul căutării *{0}* in serii", - "search.result.tag": "Rezultatul căutării *{0}* in tag-uri", - "search.sortorder.asc": "Asc", - "search.sortorder.desc": "Desc", - "series.alphabetical.many": "Index alfabetic: {0} serii", - "series.alphabetical.none": "Index alfabetic: 0 serii", - "series.alphabetical.one": "Index alfabetic: 1 serie", - "series.title": "Serii", - "seriesword.many": "{0} serii", - "seriesword.none": "Fără serii", - "seriesword.one": "1 serie", - "sort.alternate": "Sortare", - "sort.count": "Numarare", - "sort.names": "Nume", - "sort.titles": "Titluri", - "sortby.title": "Sorteaza dupa", - "splitByLetter.book.other": "Alte cărţi", - "splitByLetter.letter": "{0} care încep cu {1}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "Index alfabetic: {0} tag-uri", - "tags.alphabetical.none": "Index alfabetic: 0 tag-uri", - "tags.alphabetical.one": "Index alfabetic: 1 tag", - "tags.title": "Tag-uri", - "tagword.many": "{0} tag-uri", - "tagword.none": "Fără tag-uri", - "tagword.one": "1 tag", - "tagword.title": "Tag-uri", - "title.title": "Titlu", - "languages.abk": "Ahază", - "languages.aaf": "Afară", - "languages.afr": "Sud-africană", - "languages.aka": "Akan", - "languages.sqi": "Albaneză", - "languages.amh": "Amharică", - "languages.ara": "Arabă", - "languages.arg": "Aragoneză", - "languages.arc": "Aramaică", - "languages.hye": "Armeană", - "languages.asm": "Assameză", - "languages.ava": "Avaric", - "languages.ave": "Avestană", - "languages.aym": "Aymara", - "languages.aze": "Azeră", - "languages.bam": "Bambara", - "languages.bak": "Bashkir", - "languages.eus": "Bască", - "languages.bel": "Bielorusă", - "languages.ben": "Bengaleză", - "languages.bih": "Bihari", - "languages.bis": "Bislama", - "languages.bos": "Bosniacă", - "languages.bre": "Bretonă", - "languages.bul": "Bulgară", - "languages.mya": "Burmeză", - "languages.cat": "Catalană", - "languages.cha": "Chamorro", - "languages.che": "Cecenă", - "languages.nya": "Chichewa", - "languages.zho": "Chineză", - "languages.chv": "Chuvash", - "languages.cor": "Cornică", - "languages.cos": "Corsicană", - "languages.cre": "Cree", - "languages.hrv": "Croată", - "languages.ces": "Cehă", - "languages.dan": "Daneză", - "languages.div": "Divehi", - "languages.nld": "Olandeză", - "languages.dzo": "Dzongkha", - "languages.eng": "Engleză", - "languages.epo": "Esperanto", - "languages.est": "Estoniană", - "languages.ewe": "Ewe", - "languages.fao": "Faroese", - "languages.fij": "Fijian", - "languages.fin": "Finlandeză", - "languages.fra": "Franceză", - "languages.ful": "Fula", - "languages.glg": "Galiciană", - "languages.kat": "Georgiană", - "languages.deu": "Germană", - "languages.ell": "Greacă", - "languages.egy": "Egipteană (antică)", - "languages.grn": "Guaraní", - "languages.guj": "Gujarati", - "languages.hat": "Haitiană", - "languages.hau": "Hausa", - "languages.heb": "Ebraică", - "languages.her": "Herero", - "languages.hin": "Hindusă", - "languages.hmo": "Hiri Motu", - "languages.hun": "Maghiară", - "languages.ina": "Interlingua", - "languages.ind": "Indoneziană", - "languages.ile": "Interlingue", - "languages.gle": "Irlandeză", - "languages.grc": "Greacă, antică (până la 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Islandeză", - "languages.ita": "Italiană", - "languages.iku": "Inuktitut", - "languages.jpn": "Japoneză", - "languages.jav": "Javaneză", - "languages.kal": "Kalaallisut", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kashmiri", - "languages.kaz": "Kazakh", - "languages.khm": "Khmer", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kyrgyz", - "languages.kom": "Komi", - "languages.kon": "Congoleză", - "languages.kor": "Coreană", - "languages.kur": "Kurdish", - "languages.kua": "Kwanyama", - "languages.lat": "Latină", - "languages.ltz": "Luxemburgheză", - "languages.lug": "Ganda", - "languages.lim": "Limburgheză", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Lituaniană", - "languages.lub": "Luba-Katanga", - "languages.lav": "Letonă", - "languages.glv": "Manx", - "languages.mkd": "Macedoneană", - "languages.mlg": "Malagasy", - "languages.msa": "Malay", - "languages.mal": "Malayalam", - "languages.mlt": "Malteză", - "languages.mri": "Maori", - "languages.mar": "Marathi", - "languages.mah": "Marshallese", - "languages.mon": "Mongolă", - "languages.nau": "Nauru", - "languages.nav": "Navajo", - "languages.nob": "Norwegian Bokmal", - "languages.nde": "North Ndebele", - "languages.nep": "Nepaleză", - "languages.ndo": "Ndonga", - "languages.nno": "Norvegiană Nynorsk", - "languages.nor": "Norvegiană", - "languages.iii": "Nuosu", - "languages.nbl": "South Ndebele", - "languages.oci": "Occitană", - "languages.oji": "Ojibwe", - "languages.chu": "Old Church Slavonic", - "languages.orm": "Oromo", - "languages.ori": "Oriya", - "languages.oss": "Ossetian", - "languages.pan": "Panjabi", - "languages.pli": "Pali", - "languages.fas": "Persană", - "languages.pol": "Poloneză", - "languages.pus": "Pashto", - "languages.por": "Portugheză", - "languages.que": "Quechua", - "languages.roh": "Romani", - "languages.run": "Kirundi", - "languages.ron": "Română", - "languages.rus": "Rusă", - "languages.sam": "Samariteană aramaică", - "languages.san": "Sanscrită", - "languages.srd": "Sardă", - "languages.snd": "Sindhi", - "languages.sme": "Northern Sami", - "languages.smo": "Samoan", - "languages.sag": "Sango", - "languages.srp": "Sârbă", - "languages.gla": "Scoţiană", - "languages.sna": "Shona", - "languages.sin": "Sinhala", - "languages.slk": "Slovacă", - "languages.slv": "Slovenă", - "languages.som": "Somali", - "languages.sot": "Southern Sotho", - "languages.spa": "Spaniolă", - "languages.sun": "Sundaneză", - "languages.sux": "Sumeriană", - "languages.swa": "Swahili", - "languages.ssw": "Swati", - "languages.swe": "Suedeză", - "languages.syc": "Siriacă clasică", - "languages.syr": "Siriacă", - "languages.tam": "Tamilă", - "languages.tel": "Telugu", - "languages.tgk": "Tajik", - "languages.tha": "Thailandeză", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetan Standard", - "languages.tuk": "Turkmenă", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tonga", - "languages.tur": "Turcă", - "languages.tso": "Tsonga", - "languages.tat": "Tatară", - "languages.twi": "Twi", - "languages.tah": "Tahitian", - "languages.uga": "Ugaritică", - "languages.uig": "Uighur", - "languages.ukr": "Ucrainiană", - "languages.urd": "Urdu", - "languages.uzb": "Uzbecă", - "languages.ven": "Venda", - "languages.vie": "Vietnameză", - "languages.vol": "Volapük", - "languages.win": "Valonă", - "languages.cym": "Galeză", - "languages.wol": "Wolof", - "languages.fry": "Western Frisian", - "languages.xho": "Xhosa", - "languages.yid": "Idiş", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_ru.json b/COPS/cops-3.1.3/lang/Localization_ru.json deleted file mode 100644 index e03eb29f..00000000 --- a/COPS/cops-3.1.3/lang/Localization_ru.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "О Программе COPS", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "Алфавитный указатель по {0} книгам", - "allbooks.alphabetical.none": "Алфавитный указатель. Книги без названия", - "allbooks.alphabetical.one": "Алфавитный указатель. Одна книга", - "allbooks.title": "Все книги", - "authors.alphabetical.many": "Алфавитный указатель по {0} авторам", - "authors.alphabetical.none": "Алфавитный указатель. Книги без указания автора", - "authors.alphabetical.one": "Алфавитный указатель. Один автор", - "authors.title": "Авторы", - "author.title": "Author", - "authorword.many": "{0} авторов(а)", - "authorword.none": "Нет автора", - "authorword.one": "1 автор", - "bookentry.author": "{0} из {1}", - "bookword.many": "{0} книг(и)", - "bookword.none": "Нет книг", - "bookword.one": "1 книга", - "bookword.title": "Книги", - "cog.alternate": "Поиск, сортировка и фильтры", - "content.series": "Серии:", - "content.series.data": "Книга {0} в {1} серии", - "content.summary": "Резюме", - "customcolumn.boolean.no": "Нет", - "customcolumn.boolean.unknown": "Не задано", - "customcolumn.boolean.yes": "Да", - "customcolumn.date.format": "Г-м-д", - "customcolumn.date.unknown": "Не задано", - "customcolumn.description": "Дополнительный столбец '{0}'", - "customcolumn.description.bool": "Должно быть либо 0 либо 1", - "customcolumn.description.enum.many": "Алфавитный указатель {0} ", - "customcolumn.description.enum.none": "Алфавитный указатель", - "customcolumn.description.enum.one": "Алфавитный указатель. Одно значение", - "customcolumn.description.rating": "Рейтинги", - "customcolumn.description.series.many": "Алфавитный указатель по {0} сериям", - "customcolumn.description.series.none": "Алфавитный указатель. Книги без указания серии", - "customcolumn.description.series.one": "Алфавитный указатель. Одна серия", - "customcolumn.enum.unknown": "Не задано", - "customcolumn.float.unknown": "Не задано", - "customcolumn.int.unknown": "Не задано", - "customcolumn.rating.unknown": "Не задано", - "customcolumn.stars.many": "{0} звезд", - "customcolumn.stars.none": "Нет оценок", - "customcolumn.stars.one": "1 звезда", - "customize.email": "Укажите Ваш e-mail (возможность отправлять книги по почте)", - "customize.fancybox": "Эффектно всплывающее окно при увеличении обложки", - "customize.filter": "Включить фильтрацию по категориям", - "customize.ignored": "Исключить категории", - "customize.paging": "Максимальное число книг на странице (-1 - не ограничивать)", - "customize.style": "Тема", - "customize.template": "Template", - "customize.title": "Изменить Интерфейс COPS", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Очистить все", - "filters.title": "Filters", - "home.alternate": "Домой", - "i18n.coversection": "Обложка", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Язык", - "languages.alphabetical.many": "Алфавитный указатель по {0} языкам", - "languages.alphabetical.none": "Алфавитный указатель. Книги без указания языка", - "languages.alphabetical.one": "Алфавитный указатель. Один язык", - "languages.title": "Язык", - "links.title": "Ссылки", - "mail.messagenotsent": "Сообщение не может быть отправлено", - "mail.messagesent": "Сообщение было отправлено", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "След.", - "paging.previous.alternate": "Пред.", - "permalink.alternate": "Постоянная Ссылка", - "pubdate.title": "Published", - "publisher.name": "Издательство", - "publishers.alphabetical.many": "Алфавитный указатель по {0} издательствам", - "publishers.alphabetical.none": "Алфавитный указатель. Книги без указания издательства", - "publishers.alphabetical.one": "Алфавитный указатель. Одно издательство", - "publishers.title": "Издательства", - "publisherword.many": "{0} издательств", - "publisherword.none": "Нет издательства", - "publisherword.one": "1 издательство", - "ratings.many": "{0} рейтинга", - "ratings.none": "Рейтинг не указан", - "ratings.one": "1 рейтинг", - "ratings.title": "Рейтинг", - "rating.title": "Rating", - "ratingword.many": "{0} звезд (ы)", - "ratingword.none": "Звезды не указаны", - "ratingword.one": "1 звезда", - "recent.list": "{0} недавно поступивших(ие) книг(и)", - "recent.title": "Недавние поступления", - "search.alternate": "Поиск", - "search.result": "Результаты поиска для *{0}*", - "search.result.author": "Результаты поиска для *{0}* авторов", - "search.result.book": "Результаты поиска для *{0}* книг", - "search.result.publisher": "Результаты поиска для *{0}* издательств", - "search.result.series": "Результаты поиска для *{0}* серий", - "search.result.tag": "Результаты поиска для *{0}* меток", - "search.sortorder.asc": "Возр.", - "search.sortorder.desc": "Убыв.", - "series.alphabetical.many": "Алфавитный указатель по {0} сериям", - "series.alphabetical.none": "Алфавитный указатель. Книги без указания серии", - "series.alphabetical.one": "Алфавитный указатель. Одна серия", - "series.title": "Серии", - "seriesword.many": "{0} серий(и)", - "seriesword.none": "Нет серий", - "seriesword.one": "1 серия", - "sort.alternate": "Сортировка", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "Другие книги", - "splitByLetter.letter": "{0} начать с {1}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "Алфавитный указатель по {0} жанрам", - "tags.alphabetical.none": "Алфавитный указатель. Книги без указания жанра", - "tags.alphabetical.one": "Алфавитный указатель. Один жанр", - "tags.title": "Жанры", - "tagword.many": "{0} жанра(ов)", - "tagword.none": "Жанр не указан", - "tagword.one": "1 жанр", - "tagword.title": "Жанры", - "title.title": "Title", - "languages.abk": "Абхазский", - "languages.aaf": "Афарский", - "languages.afr": "Бурский", - "languages.aka": "Аканский", - "languages.sqi": "Албанский", - "languages.amh": "Амхарский", - "languages.ara": "Арабский", - "languages.arg": "Арагонский", - "languages.arc": "Арамейский", - "languages.hye": "Армянский", - "languages.asm": "Ассамский", - "languages.ava": "Аварский", - "languages.ave": "Авестийский", - "languages.aym": "Аймара", - "languages.aze": "Азербайджанский", - "languages.bam": "Бамана", - "languages.bak": "Башкирский", - "languages.eus": "Баскский", - "languages.bel": "Белорусский", - "languages.ben": "Бенгальский", - "languages.bih": "Бихарский", - "languages.bis": "Бислама", - "languages.bos": "Боснийский", - "languages.bre": "Бретонский", - "languages.bul": "Болгарский", - "languages.mya": "Бирманский", - "languages.cat": "Каталонский", - "languages.cha": "Чаморро", - "languages.che": "Чеченский", - "languages.nya": "Ньянджа", - "languages.zho": "Китайский", - "languages.chv": "Чувашский", - "languages.cor": "Корнский", - "languages.cos": "Корсиканский", - "languages.cre": "Кри", - "languages.hrv": "Хорватский", - "languages.ces": "Чешский", - "languages.dan": "Датский", - "languages.div": "Мальдивский", - "languages.nld": "Нидерландский", - "languages.dzo": "Дзонг-кэ", - "languages.eng": "Английский", - "languages.epo": "Эсперанто", - "languages.est": "Эстонский", - "languages.ewe": "Эве", - "languages.fao": "Фарерский", - "languages.fij": "Фиджийский", - "languages.fin": "Финский", - "languages.fra": "Французский", - "languages.ful": "Фула", - "languages.glg": "Галисийский", - "languages.kat": "Грузинский", - "languages.deu": "Немецкий", - "languages.ell": "Греческий", - "languages.egy": "Древнеегипетский", - "languages.grn": "Гуарани", - "languages.guj": "Гуджарати", - "languages.hat": "Гаитянский креольский", - "languages.hau": "Хауса", - "languages.heb": "Иврит", - "languages.her": "Гереро", - "languages.hin": "Хинди", - "languages.hmo": "Хири-моту", - "languages.hun": "Венгерский", - "languages.ina": "Интерлингва", - "languages.ind": "Индонезийский", - "languages.ile": "Окциденталь", - "languages.gle": "Ирландский", - "languages.grc": "Древнегреческий", - "languages.ibo": "Игбо", - "languages.ipk": "Инюпик", - "languages.ido": "Идо", - "languages.isl": "Исландский", - "languages.ita": "Итальянский", - "languages.iku": "Инуктитут", - "languages.jpn": "Японский", - "languages.jav": "Яванский", - "languages.kal": "Гренландский", - "languages.kan": "Ка́ннада (дравидийский)", - "languages.kau": "Канури", - "languages.kas": "Кашмирский", - "languages.kaz": "Казахский", - "languages.khm": "Кхмерский", - "languages.kik": "Кикуйю", - "languages.kin": "Руанда", - "languages.kir": "Киргизский", - "languages.kom": "Коми", - "languages.kon": "Конго", - "languages.kor": "Корейский", - "languages.kur": "Курдский", - "languages.kua": "Кваньяма", - "languages.lat": "Латинский", - "languages.ltz": "Люксембургский", - "languages.lug": "Луганда", - "languages.lim": "Лимбургский", - "languages.lin": "Лингала", - "languages.lao": "Лаосский", - "languages.lit": "Литовский", - "languages.lub": "Луба-катанга", - "languages.lav": "Латышский", - "languages.glv": "Мэнский", - "languages.mkd": "Македонский", - "languages.mlg": "Малагасийский", - "languages.msa": "Малайский", - "languages.mal": "Малаялам", - "languages.mlt": "Мальтийский", - "languages.mri": "Маори", - "languages.mar": "Маратхи", - "languages.mah": "Маршалльский", - "languages.mon": "Монгольский", - "languages.nau": "Науру", - "languages.nav": "Навахо", - "languages.nob": "Букмол (норвежский)", - "languages.nde": "Северный ндебеле", - "languages.nep": "Непальский", - "languages.ndo": "Ндонга", - "languages.nno": "Нюнорск (норвежский)", - "languages.nor": "Норвежский", - "languages.iii": "Носу (сычуаньский)", - "languages.nbl": "Южный ндебеле", - "languages.oci": "Окситанский", - "languages.oji": "Оджибве", - "languages.chu": "Старославянский", - "languages.orm": "Оромо", - "languages.ori": "Ория", - "languages.oss": "Осетинский", - "languages.pan": "Панджаби", - "languages.pli": "Пали", - "languages.fas": "Персидский", - "languages.pol": "Польский", - "languages.pus": "Пушту", - "languages.por": "Португальский", - "languages.que": "Кечуанский", - "languages.roh": "Ретороманский диалект", - "languages.run": "Рунди", - "languages.ron": "Румынский", - "languages.rus": "Русский", - "languages.sam": "Samaritan Aramaic", - "languages.san": "Санскрит", - "languages.srd": "Сардинский", - "languages.snd": "Синди", - "languages.sme": "Северносаамский", - "languages.smo": "Самоанский", - "languages.sag": "Санго", - "languages.srp": "Сербский", - "languages.gla": "Гэльский", - "languages.sna": "Шона", - "languages.sin": "Сингальский", - "languages.slk": "Словацкий", - "languages.slv": "Словенский", - "languages.som": "Сомали", - "languages.sot": "Сесото", - "languages.spa": "Испанский", - "languages.sun": "Суданский", - "languages.sux": "Sumerian", - "languages.swa": "Суахили", - "languages.ssw": "Свати", - "languages.swe": "Шведский", - "languages.syc": "Классический Сиирийский", - "languages.syr": "Сирийский", - "languages.tam": "Тамильский", - "languages.tel": "Телугу", - "languages.tgk": "Таджикский", - "languages.tha": "Тайский", - "languages.tir": "Тигринья", - "languages.bod": "Тибетский Стандартный", - "languages.tuk": "Туркменский", - "languages.tgl": "Тагальский", - "languages.tsn": "Тсвана", - "languages.ton": "Тонга", - "languages.tur": "Турецкий", - "languages.tso": "Тсонга", - "languages.tat": "Татарский", - "languages.twi": "Тви", - "languages.tah": "Таитянский", - "languages.uga": "Ugaritic", - "languages.uig": "Уйгурский", - "languages.ukr": "Украинский", - "languages.urd": "Урду", - "languages.uzb": "Узбекский", - "languages.ven": "Венда", - "languages.vie": "Вьетнамский", - "languages.vol": "Волапюк", - "languages.win": "Валлонский", - "languages.cym": "Валлийский", - "languages.wol": "Волоф", - "languages.fry": "Фризский", - "languages.xho": "Коса", - "languages.yid": "Идиш", - "languages.yor": "Йоруба", - "languages.zha": "Чжуанский", - "languages.zul": "Зулусский", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_sl.json b/COPS/cops-3.1.3/lang/Localization_sl.json deleted file mode 100644 index 3fa8a004..00000000 --- a/COPS/cops-3.1.3/lang/Localization_sl.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "O COPS", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "Abecedni seznam {0} knjig", - "allbooks.alphabetical.none": "Abecedni seznam popolnoma nobene knjige", - "allbooks.alphabetical.one": "Abecedni seznam posamezne knjige", - "allbooks.title": "Vse knjige", - "authors.alphabetical.many": "Abecedni seznam {0} avtorjev", - "authors.alphabetical.none": "Abecedni seznam popolnoma nobenega avtorja", - "authors.alphabetical.one": "Abecedni seznam posameznega avtorja", - "authors.title": "Avtorji", - "author.title": "Author", - "authorword.many": "{0} avtorjev", - "authorword.none": "Ni avtorjev", - "authorword.one": "En avtor", - "bookentry.author": "{0} by {1}", - "bookword.many": "{0} knjig", - "bookword.none": "Ni knjig", - "bookword.one": "Ena knjiga", - "bookword.title": "Knjige", - "cog.alternate": "Iskanje, sortiranje in filtriranje", - "content.series": "Serija:", - "content.series.data": "Knjiga {0} v {1} seriji", - "content.summary": "Povzetek", - "customcolumn.boolean.no": "Ne", - "customcolumn.boolean.unknown": "Ni določeno", - "customcolumn.boolean.yes": "Da", - "customcolumn.date.format": "L-m-d", - "customcolumn.date.unknown": "Ni določeno", - "customcolumn.description": "Stolpec po meri '{0}'", - "customcolumn.description.bool": "Indeks logične vrednosti", - "customcolumn.description.enum.many": "Abecedni indeks {0} vrednosti", - "customcolumn.description.enum.none": "Abecedni seznam popolnoma nobene vrednosti", - "customcolumn.description.enum.one": "Abecedni indeks ene vrednosti", - "customcolumn.description.rating": "Indeks ocen", - "customcolumn.description.series.many": "Abecedni indeks {0} serije", - "customcolumn.description.series.none": "Abecedni seznam popolnoma nobene serije", - "customcolumn.description.series.one": "Abecedni indeks posamezne serije", - "customcolumn.enum.unknown": "Ni določeno", - "customcolumn.float.unknown": "Ni določeno", - "customcolumn.int.unknown": "Ni določeno", - "customcolumn.rating.unknown": "Ni določeno", - "customcolumn.stars.many": "{0} zvezdic", - "customcolumn.stars.none": "brez zvezdic", - "customcolumn.stars.one": "1 zvezdica", - "customize.email": "Natsavite elektronski naslov (za pošiljanje knjig)", - "customize.fancybox": "Uporabi Lightbox (knjige se naložijo v lebdeč okvir)", - "customize.filter": "Vklopi filter oznak", - "customize.ignored": "Prezrte kategorije", - "customize.paging": "Največje število knjig na stran (-1 za izklop)", - "customize.style": "Tema", - "customize.template": "Template", - "customize.title": "Prilagoditev COPS grafičnega vmesnika", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Izbriši vse", - "filters.title": "Filters", - "home.alternate": "Domov", - "i18n.coversection": "Naslovnica", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Jezik", - "languages.alphabetical.many": "Abecedni seznam {0} jezikov", - "languages.alphabetical.none": "Abecedni seznam popolnoma nobenega jezika", - "languages.alphabetical.one": "Abecedni seznam posameznega jezika", - "languages.title": "Jeziki", - "links.title": "Povezave", - "mail.messagenotsent": "Sporočila ni bilo mogoče poslati", - "mail.messagesent": "Sporočilo ni bilo poslano", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "Naprej", - "paging.previous.alternate": "Prejšnje", - "permalink.alternate": "Stalna povezava", - "pubdate.title": "Published", - "publisher.name": "Izdajatelj", - "publishers.alphabetical.many": "Abecedni seznam {0} izdajateljev", - "publishers.alphabetical.none": "Abecedni seznam popolnoma nobenega izdajatelja", - "publishers.alphabetical.one": "Abecedni seznam posameznega izdajatelja", - "publishers.title": "Izdajatelji", - "publisherword.many": "{0} izdajateljev", - "publisherword.none": "Ni izdajateljev", - "publisherword.one": "En izdajatelj", - "ratings.many": "{0} ocen", - "ratings.none": "brez ocen", - "ratings.one": "ena ocena", - "ratings.title": "Ocene", - "rating.title": "Rating", - "ratingword.many": "{0} zvezdic", - "ratingword.none": "brez zvezdic", - "ratingword.one": "1 zvezdica", - "recent.list": "{0} zadnjih knjig", - "recent.title": "Zadnje dodano", - "search.alternate": "Iskanje", - "search.result": "Iskanje rezultata za *{0}*", - "search.result.author": "Iskanje rezultata za *{0}* med avtorji", - "search.result.book": "Iskanje rezultata za *{0}* med knjigami", - "search.result.publisher": "Iskanje rezultata za *{0}* med izdajatelji", - "search.result.series": "Iskanje rezultata za *{0}* med zbirkami", - "search.result.tag": "Iskanje rezultata za *{0}* v oznakah", - "search.sortorder.asc": "Naraščajoče", - "search.sortorder.desc": "Padajoče", - "series.alphabetical.many": "Abecedni indeks {0} serije", - "series.alphabetical.none": "Abecedni seznam popolnoma nobene serije", - "series.alphabetical.one": "Abecedni indeks posamezne serije", - "series.title": "Serija", - "seriesword.many": "{0} serija", - "seriesword.none": "ni serije", - "seriesword.one": "ena serija", - "sort.alternate": "Razvrsti", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "druge knjige", - "splitByLetter.letter": "{0} začenši z {1}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "Abecedni indeks {0} oznak", - "tags.alphabetical.none": "Abecedni seznam popolnoma nobenih oznak", - "tags.alphabetical.one": "Abecedni seznam posamezne oznake", - "tags.title": "Oznake", - "tagword.many": "{0} oznak", - "tagword.none": "brez oznak", - "tagword.one": "ena oznaka", - "tagword.title": "Oznake", - "title.title": "Title", - "languages.abk": "abhaščina", - "languages.aaf": "afarščina", - "languages.afr": "afrikanščina", - "languages.aka": "akanščina", - "languages.sqi": "albanščina", - "languages.amh": "amharščina", - "languages.ara": "arabščina", - "languages.arg": "aragonščina", - "languages.arc": "aramejščina", - "languages.hye": "armenščina", - "languages.asm": "asamščina", - "languages.ava": "avarščina", - "languages.ave": "avestijščina", - "languages.aym": "aimarščina", - "languages.aze": "azerbajdžanščina", - "languages.bam": "bambarščina", - "languages.bak": "baškirščina", - "languages.eus": "baskovščina", - "languages.bel": "belorusčina", - "languages.ben": "bengalščina", - "languages.bih": "biharščina", - "languages.bis": "bislamščina", - "languages.bos": "bosansko", - "languages.bre": "bretonščina", - "languages.bul": "bolgarščina", - "languages.mya": "burmanščina", - "languages.cat": "katalonščina", - "languages.cha": "čamorščina", - "languages.che": "čečenščina", - "languages.nya": "čevščina", - "languages.zho": "kitajščina", - "languages.chv": "čuvaščina", - "languages.cor": "kornijščina", - "languages.cos": "korziščina", - "languages.cre": "krijščina", - "languages.hrv": "hrvaščina", - "languages.ces": "češčina", - "languages.dan": "danščina", - "languages.div": "diveščina", - "languages.nld": "nizozemščina", - "languages.dzo": "dzonka", - "languages.eng": "angleščina", - "languages.epo": "esperanto", - "languages.est": "estonščina", - "languages.ewe": "evenščina", - "languages.fao": "ferščina", - "languages.fij": "fidžijščina", - "languages.fin": "finščina", - "languages.fra": "francoščina", - "languages.ful": "fulščina", - "languages.glg": "galicijščina", - "languages.kat": "gruzinščina", - "languages.deu": "nemščina", - "languages.ell": "grščina", - "languages.egy": "egipščanščina (staroegiptovski)", - "languages.grn": "gvaranijščina", - "languages.guj": "gudžaratščina", - "languages.hat": "haidščina", - "languages.hau": "havščina", - "languages.heb": "hebrejščina", - "languages.her": "Herero", - "languages.hin": "Hindi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Hungarian", - "languages.ina": "Interlingua", - "languages.ind": "Indonesian", - "languages.ile": "Interlingue", - "languages.gle": "Irish", - "languages.grc": "Greek, Ancient (to 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Icelandic", - "languages.ita": "Italian", - "languages.iku": "Inuktitut", - "languages.jpn": "Japanese", - "languages.jav": "Javanese", - "languages.kal": "Kalaallisut", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kashmiri", - "languages.kaz": "Kazakh", - "languages.khm": "Khmer", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kyrgyz", - "languages.kom": "Komi", - "languages.kon": "Kongo", - "languages.kor": "Korean", - "languages.kur": "Kurdish", - "languages.kua": "Kwanyama", - "languages.lat": "Latin", - "languages.ltz": "Luxembourgish", - "languages.lug": "Ganda", - "languages.lim": "Limburgish", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Lithuanian", - "languages.lub": "Luba-Katanga", - "languages.lav": "Latvian", - "languages.glv": "Manx", - "languages.mkd": "Macedonian", - "languages.mlg": "Malagasy", - "languages.msa": "Malay", - "languages.mal": "Malayalam", - "languages.mlt": "Maltese", - "languages.mri": "Māori", - "languages.mar": "Marathi", - "languages.mah": "Marshallese", - "languages.mon": "Mongolian", - "languages.nau": "Nauru", - "languages.nav": "Navajo", - "languages.nob": "Norwegian Bokmål", - "languages.nde": "North Ndebele", - "languages.nep": "Nepali", - "languages.ndo": "Ndonga", - "languages.nno": "Norwegian Nynorsk", - "languages.nor": "Norwegian", - "languages.iii": "Nuosu", - "languages.nbl": "South Ndebele", - "languages.oci": "Occitan", - "languages.oji": "Ojibwe", - "languages.chu": "Old Church Slavonic", - "languages.orm": "Oromo", - "languages.ori": "Oriya", - "languages.oss": "Ossetian", - "languages.pan": "Panjabi", - "languages.pli": "Pāli", - "languages.fas": "Persian", - "languages.pol": "Polish", - "languages.pus": "Pashto", - "languages.por": "Portuguese", - "languages.que": "Quechua", - "languages.roh": "Romansh", - "languages.run": "Kirundi", - "languages.ron": "Romanian", - "languages.rus": "Russian", - "languages.sam": "Samaritan Aramaic", - "languages.san": "Sanskrit", - "languages.srd": "Sardinian", - "languages.snd": "Sindhi", - "languages.sme": "Northern Sami", - "languages.smo": "Samoan", - "languages.sag": "Sango", - "languages.srp": "Serbian", - "languages.gla": "Scottish Gaelic", - "languages.sna": "Shona", - "languages.sin": "Sinhala", - "languages.slk": "Slovak", - "languages.slv": "Slovene", - "languages.som": "Somali", - "languages.sot": "Southern Sotho", - "languages.spa": "Spanish", - "languages.sun": "Sundanese", - "languages.sux": "Sumerian", - "languages.swa": "Swahili", - "languages.ssw": "Swati", - "languages.swe": "Swedish", - "languages.syc": "Classical Syriac", - "languages.syr": "Syriac", - "languages.tam": "Tamil", - "languages.tel": "Telugu", - "languages.tgk": "Tajik", - "languages.tha": "Thai", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetan Standard", - "languages.tuk": "Turkmen", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tonga", - "languages.tur": "Turkish", - "languages.tso": "Tsonga", - "languages.tat": "Tatar", - "languages.twi": "Twi", - "languages.tah": "Tahitian", - "languages.uga": "Ugaritic", - "languages.uig": "Uighur", - "languages.ukr": "Ukrainian", - "languages.urd": "Urdu", - "languages.uzb": "Uzbek", - "languages.ven": "Venda", - "languages.vie": "Vietnamese", - "languages.vol": "Volapük", - "languages.win": "Walloon", - "languages.cym": "Welsh", - "languages.wol": "Wolof", - "languages.fry": "Western Frisian", - "languages.xho": "Xhosa", - "languages.yid": "Yiddish", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "" -} diff --git a/COPS/cops-3.1.3/lang/Localization_sr.json b/COPS/cops-3.1.3/lang/Localization_sr.json deleted file mode 100644 index 9028b986..00000000 --- a/COPS/cops-3.1.3/lang/Localization_sr.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "About COPS", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "Азбучни индекс {0} књига", - "allbooks.alphabetical.none": "Азбучни индекс без књига", - "allbooks.alphabetical.one": "Азбучни индекс једне књиге", - "allbooks.title": "Све књиге", - "authors.alphabetical.many": "Азбучни индекс {0} аутора", - "authors.alphabetical.none": "Азбучни индекс без аутора", - "authors.alphabetical.one": "Азбучни индекс једног аутора", - "authors.title": "Аутори", - "author.title": "Author", - "authorword.many": "{0} аутора", - "authorword.none": "Нема аутора", - "authorword.one": "1 аутор", - "bookentry.author": "{0} до {1}", - "bookword.many": "{0} књига", - "bookword.none": "Нема књига", - "bookword.one": "1 књига", - "bookword.title": "Књиге", - "cog.alternate": "Претрага, филтери и сортирање", - "content.series": "Комплет:", - "content.series.data": "Књига {0} у {1} комплету", - "content.summary": "Укупно", - "customcolumn.boolean.no": "No", - "customcolumn.boolean.unknown": "Not Set", - "customcolumn.boolean.yes": "Yes", - "customcolumn.date.format": "Y-m-d", - "customcolumn.date.unknown": "Not Set", - "customcolumn.description": "Custom column '{0}'", - "customcolumn.description.bool": "Index of a boolean value", - "customcolumn.description.enum.many": "Alphabetical index of the {0} values", - "customcolumn.description.enum.none": "Alphabetical index of absolutely no values", - "customcolumn.description.enum.one": "Alphabetical index of one value", - "customcolumn.description.rating": "Index of ratings", - "customcolumn.description.series.many": "Alphabetical index of the {0} series", - "customcolumn.description.series.none": "Alphabetical index of absolutely no series", - "customcolumn.description.series.one": "Alphabetical index of the single series", - "customcolumn.enum.unknown": "Not Set", - "customcolumn.float.unknown": "Not Set", - "customcolumn.int.unknown": "Not Set", - "customcolumn.rating.unknown": "Not Set", - "customcolumn.stars.many": "{0} Stars", - "customcolumn.stars.none": "No Stars", - "customcolumn.stars.one": "1 Star", - "customize.email": "Поставите вашу адресу (да се омогући слање књиге)", - "customize.fancybox": "Користи Lightbox", - "customize.filter": "Омогућити филтрирање по таговима", - "customize.ignored": "Категорије које се приказују", - "customize.paging": "Максималан број књига по страни (-1 онемогућити)", - "customize.style": "Тема", - "customize.template": "Template", - "customize.title": "Подешавање COPS корисничког прегледа", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Obriši sve", - "filters.title": "Filters", - "home.alternate": "Почетна", - "i18n.coversection": "Насловна", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Језик", - "languages.alphabetical.many": "Азбучни индекс {0} језика", - "languages.alphabetical.none": "Индекс без језика", - "languages.alphabetical.one": "Азбучни индекс једног језика", - "languages.title": "Језици", - "links.title": "Линкови", - "mail.messagenotsent": "Поруку није могуће послати.", - "mail.messagesent": "Порука је послата", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "Следеће", - "paging.previous.alternate": "Претходно", - "permalink.alternate": "Везе", - "pubdate.title": "Published", - "publisher.name": "Издавач", - "publishers.alphabetical.many": "Азбучни индекс {0} издавача", - "publishers.alphabetical.none": "Индекс без издавача", - "publishers.alphabetical.one": "Индекс једног издавача", - "publishers.title": "Издавачи", - "publisherword.many": "{0} издавача", - "publisherword.none": "Нема издавача", - "publisherword.one": "1 издавач", - "ratings.many": "{0} ratings", - "ratings.none": "no ratings", - "ratings.one": "1 rating", - "ratings.title": "Ratings", - "rating.title": "Rating", - "ratingword.many": "{0} stars", - "ratingword.none": "No star", - "ratingword.one": "1 star", - "recent.list": "{0} најновије књиге", - "recent.title": "Последње постављено", - "search.alternate": "Претрага", - "search.result": "Резултати претраге за *{0}*", - "search.result.author": "Резултат претраге за *{0}* у ауторима", - "search.result.book": "Резултат претраге за *{0}* у књигама", - "search.result.publisher": "Резултат претраге за *{0}* у издавачима", - "search.result.series": "Резултат претраге за *{0}* у комплетима", - "search.result.tag": "Резултат претраге за *{0}* у ознакама", - "search.sortorder.asc": "Растуће", - "search.sortorder.desc": "Опадајуће", - "series.alphabetical.many": "Азбучни индекс {0} комплета", - "series.alphabetical.none": "Азбучни индекс без комплета", - "series.alphabetical.one": "Азбучни индекс у једном комплету", - "series.title": "Комплети", - "seriesword.many": "{0} комплета", - "seriesword.none": "Нема комплета", - "seriesword.one": "1 комплет", - "sort.alternate": "Сертирање", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "Друге књиге", - "splitByLetter.letter": "{0} почиње {1}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "Азбучни индекс у {0} ознакама", - "tags.alphabetical.none": "Азбучни индекс без ознака", - "tags.alphabetical.one": "Азбучни индекс једне ознаке", - "tags.title": "Ознаке", - "tagword.many": "{0} ознака", - "tagword.none": "Нема ознака", - "tagword.one": "1 ознака", - "tagword.title": "Ознаке", - "title.title": "Title", - "languages.abk": "Abkhaz", - "languages.aaf": "Afar", - "languages.afr": "Afrikaans", - "languages.aka": "Akan", - "languages.sqi": "Albanian", - "languages.amh": "Amharic", - "languages.ara": "Arabic", - "languages.arg": "Aragonese", - "languages.arc": "Aramaic", - "languages.hye": "Armenian", - "languages.asm": "Assamese", - "languages.ava": "Avaric", - "languages.ave": "Avestan", - "languages.aym": "Aymara", - "languages.aze": "Azerbaijani", - "languages.bam": "Bambara", - "languages.bak": "Bashkir", - "languages.eus": "Basque", - "languages.bel": "Belarusian", - "languages.ben": "Bengali", - "languages.bih": "Bihari", - "languages.bis": "Bislama", - "languages.bos": "Bosnian", - "languages.bre": "Breton", - "languages.bul": "Bulgarian", - "languages.mya": "Burmese", - "languages.cat": "Catalan", - "languages.cha": "Chamorro", - "languages.che": "Chechen", - "languages.nya": "Chichewa", - "languages.zho": "Chinese", - "languages.chv": "Chuvash", - "languages.cor": "Cornish", - "languages.cos": "Corsican", - "languages.cre": "Cree", - "languages.hrv": "Croatian", - "languages.ces": "Czech", - "languages.dan": "Danish", - "languages.div": "Divehi", - "languages.nld": "Dutch", - "languages.dzo": "Dzongkha", - "languages.eng": "English", - "languages.epo": "Esperanto", - "languages.est": "Estonian", - "languages.ewe": "Ewe", - "languages.fao": "Faroese", - "languages.fij": "Fijian", - "languages.fin": "Finnish", - "languages.fra": "French", - "languages.ful": "Fula", - "languages.glg": "Galician", - "languages.kat": "Georgian", - "languages.deu": "German", - "languages.ell": "Greek", - "languages.egy": "Egyptian (Ancient)", - "languages.grn": "Guaraní", - "languages.guj": "Gujarati", - "languages.hat": "Haitian", - "languages.hau": "Hausa", - "languages.heb": "Hebrew", - "languages.her": "Herero", - "languages.hin": "Hindi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Hungarian", - "languages.ina": "Interlingua", - "languages.ind": "Indonesian", - "languages.ile": "Interlingue", - "languages.gle": "Irish", - "languages.grc": "Greek, Ancient (to 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Icelandic", - "languages.ita": "Italian", - "languages.iku": "Inuktitut", - "languages.jpn": "Japanese", - "languages.jav": "Javanese", - "languages.kal": "Kalaallisut", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kashmiri", - "languages.kaz": "Kazakh", - "languages.khm": "Khmer", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kyrgyz", - "languages.kom": "Komi", - "languages.kon": "Kongo", - "languages.kor": "Korean", - "languages.kur": "Kurdish", - "languages.kua": "Kwanyama", - "languages.lat": "Latin", - "languages.ltz": "Luxembourgish", - "languages.lug": "Ganda", - "languages.lim": "Limburgish", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Lithuanian", - "languages.lub": "Luba-Katanga", - "languages.lav": "Latvian", - "languages.glv": "Manx", - "languages.mkd": "Macedonian", - "languages.mlg": "Malagasy", - "languages.msa": "Malay", - "languages.mal": "Malayalam", - "languages.mlt": "Maltese", - "languages.mri": "Māori", - "languages.mar": "Marathi", - "languages.mah": "Marshallese", - "languages.mon": "Mongolian", - "languages.nau": "Nauru", - "languages.nav": "Navajo", - "languages.nob": "Norwegian Bokmål", - "languages.nde": "North Ndebele", - "languages.nep": "Nepali", - "languages.ndo": "Ndonga", - "languages.nno": "Norwegian Nynorsk", - "languages.nor": "Norwegian", - "languages.iii": "Nuosu", - "languages.nbl": "South Ndebele", - "languages.oci": "Occitan", - "languages.oji": "Ojibwe", - "languages.chu": "Old Church Slavonic", - "languages.orm": "Oromo", - "languages.ori": "Oriya", - "languages.oss": "Ossetian", - "languages.pan": "Panjabi", - "languages.pli": "Pāli", - "languages.fas": "Persian", - "languages.pol": "Polish", - "languages.pus": "Pashto", - "languages.por": "Portuguese", - "languages.que": "Quechua", - "languages.roh": "Romansh", - "languages.run": "Kirundi", - "languages.ron": "Romanian", - "languages.rus": "Russian", - "languages.sam": "Samaritan Aramaic", - "languages.san": "Sanskrit", - "languages.srd": "Sardinian", - "languages.snd": "Sindhi", - "languages.sme": "Northern Sami", - "languages.smo": "Samoan", - "languages.sag": "Sango", - "languages.srp": "Serbian", - "languages.gla": "Scottish Gaelic", - "languages.sna": "Shona", - "languages.sin": "Sinhala", - "languages.slk": "Slovak", - "languages.slv": "Slovene", - "languages.som": "Somali", - "languages.sot": "Southern Sotho", - "languages.spa": "Spanish", - "languages.sun": "Sundanese", - "languages.sux": "Sumerian", - "languages.swa": "Swahili", - "languages.ssw": "Swati", - "languages.swe": "Swedish", - "languages.syc": "Classical Syriac", - "languages.syr": "Syriac", - "languages.tam": "Tamil", - "languages.tel": "Telugu", - "languages.tgk": "Tajik", - "languages.tha": "Thai", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetan Standard", - "languages.tuk": "Turkmen", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tonga", - "languages.tur": "Turkish", - "languages.tso": "Tsonga", - "languages.tat": "Tatar", - "languages.twi": "Twi", - "languages.tah": "Tahitian", - "languages.uga": "Ugaritic", - "languages.uig": "Uighur", - "languages.ukr": "Ukrainian", - "languages.urd": "Urdu", - "languages.uzb": "Uzbek", - "languages.ven": "Venda", - "languages.vie": "Vietnamese", - "languages.vol": "Volapük", - "languages.win": "Walloon", - "languages.cym": "Welsh", - "languages.wol": "Wolof", - "languages.fry": "Western Frisian", - "languages.xho": "Xhosa", - "languages.yid": "Yiddish", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_sv.json b/COPS/cops-3.1.3/lang/Localization_sv.json deleted file mode 100644 index b8af1770..00000000 --- a/COPS/cops-3.1.3/lang/Localization_sv.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "Om COPS", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "Alfabetiskt index av {0} böckerna", - "allbooks.alphabetical.none": "Alfabetiskt index av absolut inga böcker", - "allbooks.alphabetical.one": "Alfabetiskt index av den enskilda boken", - "allbooks.title": "Alla böcker", - "authors.alphabetical.many": "Alfabetiskt index av {0} författarna", - "authors.alphabetical.none": "Alfabetiskt index av absolut inga författare", - "authors.alphabetical.one": "Alfabetiskt index av den enskilde författaren", - "authors.title": "Författare", - "author.title": "Author", - "authorword.many": "{0} författare", - "authorword.none": "Inga författare", - "authorword.one": "1 författare", - "bookentry.author": "{0} av {1}", - "bookword.many": "{0} böcker", - "bookword.none": "Inga böcker", - "bookword.one": "1 bok", - "bookword.title": "Böcker", - "cog.alternate": "Sök, sortera och filtrera", - "content.series": "Serier:", - "content.series.data": "Bok {0} i {1} serien", - "content.summary": "Sammanfattning", - "customcolumn.boolean.no": "Nej", - "customcolumn.boolean.unknown": "Ej inställd", - "customcolumn.boolean.yes": "Ja", - "customcolumn.date.format": "Å-m-d", - "customcolumn.date.unknown": "Ej inställd", - "customcolumn.description": "Anpassad kolumn \"{0}\"", - "customcolumn.description.bool": "Index av ett booleskt värde", - "customcolumn.description.enum.many": "Alfabetiskt index av {0} värdena", - "customcolumn.description.enum.none": "Alfabetiskt index med absolut inga värden", - "customcolumn.description.enum.one": "Alfabetiskt index av ett värde", - "customcolumn.description.rating": "Index över betyg", - "customcolumn.description.series.many": "Alfabetiskt index av {0} serier", - "customcolumn.description.series.none": "Alfabetiskt index av inte en enda serie", - "customcolumn.description.series.one": "Alfabetiskt index av en enda serie", - "customcolumn.enum.unknown": "Ej inställd", - "customcolumn.float.unknown": "Ej inställd", - "customcolumn.int.unknown": "Ej inställd", - "customcolumn.rating.unknown": "Ej inställd", - "customcolumn.stars.many": "{0} stjärnor", - "customcolumn.stars.none": "Inga stjärnor", - "customcolumn.stars.one": "1 stjärna", - "customize.email": "Ange din e-postadress (för att aktivera e-post)", - "customize.fancybox": "Använd Lightbox (böcker belastas i flytande ram)", - "customize.filter": "Aktivera etikettfiltrering", - "customize.ignored": "Ignorerade kategorier", - "customize.paging": "Max antal böcker per sida (-1 för att inaktivera)", - "customize.style": "Tema", - "customize.template": "Template", - "customize.title": "Anpassa COPS gränssnitt", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Rensa alla", - "filters.title": "Filters", - "home.alternate": "Hem", - "i18n.coversection": "Omslag", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Språk", - "languages.alphabetical.many": "Alfabetiskt index av {0} språk", - "languages.alphabetical.none": "Alfabetiskt index av {0} språk", - "languages.alphabetical.one": "Alfabetiskt index av enskilt språk", - "languages.title": "Språk", - "links.title": "Länkar", - "mail.messagenotsent": "Mejlet kunde inte skickas.", - "mail.messagesent": "Mejlet är skickat", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "Nästa", - "paging.previous.alternate": "Föregående", - "permalink.alternate": "Permalink", - "pubdate.title": "Published", - "publisher.name": "Förlag", - "publishers.alphabetical.many": "Alfabetiskt index av {0} förlag", - "publishers.alphabetical.none": "Alfabetiskt index av inte ett enda förlag", - "publishers.alphabetical.one": "Alfabetiskt index av ett enda förlag", - "publishers.title": "Förlag", - "publisherword.many": "{0} förlag", - "publisherword.none": "Inget förlag", - "publisherword.one": "1 förlag", - "ratings.many": "{0} betyg", - "ratings.none": "inga betyg", - "ratings.one": "1 betyg", - "ratings.title": "Betyg", - "rating.title": "Rating", - "ratingword.many": "{0} stjärnor", - "ratingword.none": "Inga stjärnor", - "ratingword.one": "1 stjärna", - "recent.list": "{0} senaste böckerna", - "recent.title": "Senaste tillagda", - "search.alternate": "Sök", - "search.result": "Sökresultat för *{0}*", - "search.result.author": "Sökresultat för *{0}* i författare", - "search.result.book": "Sökresultat för *{0}* i böcker", - "search.result.publisher": "Sökresultat för *{0}* i förlag", - "search.result.series": "Sökresultat för *{0}* i serier", - "search.result.tag": "Sökresultat för *{0}* i etiketter", - "search.sortorder.asc": "Stigande", - "search.sortorder.desc": "Fallande", - "series.alphabetical.many": "Alfabetiskt index av {0} serier", - "series.alphabetical.none": "Alfabetiskt index av inte en enda serie", - "series.alphabetical.one": "Alfabetiskt index av en enda serie", - "series.title": "Serier", - "seriesword.many": "{0} serier", - "seriesword.none": "Inga serier", - "seriesword.one": "1 serie", - "sort.alternate": "Sortera", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "Övriga böcker", - "splitByLetter.letter": "{0} börjar med {1}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "Alfabetiskt index av {0} etiketter", - "tags.alphabetical.none": "Alfabetiskt index av inte en enda etikett", - "tags.alphabetical.one": "Alfabetiskt index av en enda etikett", - "tags.title": "Etiketter", - "tagword.many": "{0} etiketter", - "tagword.none": "Inga etiketter", - "tagword.one": "1 etikett", - "tagword.title": "Etiketter", - "title.title": "Title", - "languages.abk": "Abchaziska", - "languages.aaf": "Afar", - "languages.afr": "Afrikaans", - "languages.aka": "Akan", - "languages.sqi": "Albanska", - "languages.amh": "Amhariska", - "languages.ara": "Arabiska", - "languages.arg": "Aragonska", - "languages.arc": "Arameiska", - "languages.hye": "Armenska", - "languages.asm": "Assamesiska", - "languages.ava": "Avariska", - "languages.ave": "Avestiska", - "languages.aym": "Aymara", - "languages.aze": "Azerbajdzjanska", - "languages.bam": "Bambara", - "languages.bak": "Basjkiriska", - "languages.eus": "Baskiska", - "languages.bel": "Vitrysska", - "languages.ben": "Bengali", - "languages.bih": "Bihariska", - "languages.bis": "Bislama", - "languages.bos": "Bosniska", - "languages.bre": "Bretonska", - "languages.bul": "Bulgariska", - "languages.mya": "Burmesiska", - "languages.cat": "Katalanska", - "languages.cha": "Chamorro", - "languages.che": "Tjetjenska", - "languages.nya": "Chichewa", - "languages.zho": "Kinesiska", - "languages.chv": "Chuvash", - "languages.cor": "Korniska", - "languages.cos": "Korsikanska", - "languages.cre": "Cree", - "languages.hrv": "Kroatiska", - "languages.ces": "Tjeckiska", - "languages.dan": "Danska", - "languages.div": "Divehi", - "languages.nld": "Holländska", - "languages.dzo": "Dzongkha", - "languages.eng": "Engelska", - "languages.epo": "Esperanto", - "languages.est": "Estniska", - "languages.ewe": "Ewe", - "languages.fao": "Färöiska", - "languages.fij": "Fijianska", - "languages.fin": "Finska", - "languages.fra": "Franska", - "languages.ful": "Fula", - "languages.glg": "Galiciska", - "languages.kat": "Georgiska", - "languages.deu": "Tyska", - "languages.ell": "Grekiska", - "languages.egy": "Egyptiska (antik)", - "languages.grn": "Guaraní", - "languages.guj": "Gujarati", - "languages.hat": "Haitisk kreol", - "languages.hau": "Hausa", - "languages.heb": "Hebreiska", - "languages.her": "Herero", - "languages.hin": "Hindi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Ungerska", - "languages.ina": "Interlingua", - "languages.ind": "Indonesian", - "languages.ile": "Interlingue", - "languages.gle": "Iriska", - "languages.grc": "Grekisk, antik (till 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Isländska", - "languages.ita": "Italienska", - "languages.iku": "Inuktitut", - "languages.jpn": "Japanska", - "languages.jav": "Javanesiska", - "languages.kal": "Grönländska", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kashmiriska", - "languages.kaz": "Kazakiska", - "languages.khm": "Khmer", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kirgisiska", - "languages.kom": "Komi", - "languages.kon": "Kongo", - "languages.kor": "Koreanska", - "languages.kur": "Kurdiska", - "languages.kua": "Kwanyama", - "languages.lat": "Latin", - "languages.ltz": "Luxembourgiska", - "languages.lug": "Ganda", - "languages.lim": "Limburgiska", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Litauiska", - "languages.lub": "Luba-Katanga", - "languages.lav": "Lettiska", - "languages.glv": "Manx", - "languages.mkd": "Makedonska", - "languages.mlg": "Malagassiska", - "languages.msa": "Malay", - "languages.mal": "Malayalam", - "languages.mlt": "Maltesiska", - "languages.mri": "Maori", - "languages.mar": "Marathi", - "languages.mah": "Marshallesiska", - "languages.mon": "Mongoliska", - "languages.nau": "Nauriska", - "languages.nav": "Navajo", - "languages.nob": "Norska Bokmål", - "languages.nde": "Nordndebele", - "languages.nep": "Nepalesiska", - "languages.ndo": "Ndonga", - "languages.nno": "Nynorsk", - "languages.nor": "Norska", - "languages.iii": "Nuosu", - "languages.nbl": "Sydndebele", - "languages.oci": "Occitanska", - "languages.oji": "Ojibwe", - "languages.chu": "Kyrkslaviska", - "languages.orm": "Oromo", - "languages.ori": "Oriya", - "languages.oss": "Ossetiska", - "languages.pan": "Punjabiska", - "languages.pli": "Pali", - "languages.fas": "Persiska", - "languages.pol": "Polska", - "languages.pus": "Pashto", - "languages.por": "Portugisiska", - "languages.que": "Quechua", - "languages.roh": "Rätoromanska", - "languages.run": "Kirundi", - "languages.ron": "Rumänska", - "languages.rus": "Rysska", - "languages.sam": "Samarisk arameiska", - "languages.san": "Sanskrit", - "languages.srd": "Sardiska", - "languages.snd": "Sindhi", - "languages.sme": "Nordsamiska", - "languages.smo": "Samoanska", - "languages.sag": "Sango", - "languages.srp": "Serbiska", - "languages.gla": "Skotsk gaeliska", - "languages.sna": "Shona", - "languages.sin": "Sinhala", - "languages.slk": "Slovakiska", - "languages.slv": "Slovenska", - "languages.som": "Somaliska", - "languages.sot": "Sesotho", - "languages.spa": "Spanska", - "languages.sun": "Sundanesiska", - "languages.sux": "Sumeriska", - "languages.swa": "Swahili", - "languages.ssw": "Swati", - "languages.swe": "Svenska", - "languages.syc": "Klassisk syriska", - "languages.syr": "Syriska", - "languages.tam": "Tamil", - "languages.tel": "Telugu", - "languages.tgk": "Tajikiska", - "languages.tha": "Thailändska", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetanska", - "languages.tuk": "Turkmeniska", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tonga", - "languages.tur": "Turkiska", - "languages.tso": "Tsonga", - "languages.tat": "Tatariska", - "languages.twi": "Twi", - "languages.tah": "Tahitian", - "languages.uga": "Ugaritiska", - "languages.uig": "Uiguriska", - "languages.ukr": "Ukrainska", - "languages.urd": "Urdu", - "languages.uzb": "Uzbekiska", - "languages.ven": "Venda", - "languages.vie": "Vietnamesiska", - "languages.vol": "Volapük", - "languages.win": "Vallonska", - "languages.cym": "Walesiska", - "languages.wol": "Wolof", - "languages.fry": "Västfrisiska", - "languages.xho": "Xhosa", - "languages.yid": "Jiddish", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_tr.json b/COPS/cops-3.1.3/lang/Localization_tr.json deleted file mode 100644 index 73390cca..00000000 --- a/COPS/cops-3.1.3/lang/Localization_tr.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "COPS Hakkında", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "Alfabeye göre sıralanmış {0} Kitap", - "allbooks.alphabetical.none": "Alfabeye göre sıralanmış 0 Kitap", - "allbooks.alphabetical.one": "Alfabeye göre sıralanmış 1 Kitap", - "allbooks.title": "Bütün Kitaplar", - "authors.alphabetical.many": "Alfabeye göre sıralanmış {0} Yazar", - "authors.alphabetical.none": "Alfabeye göre sıralanmış 0 Yazar", - "authors.alphabetical.one": "Alfabeye göre sıralanmış 1Yazar", - "authors.title": "Yazarlar", - "author.title": "Author", - "authorword.many": "{0} Yazar", - "authorword.none": "0 Yazar", - "authorword.one": "1 Yazar", - "bookentry.author": "{1}'den {0}.", - "bookword.many": "{0} Kitap", - "bookword.none": "0 Kitap", - "bookword.one": "1 Kitap", - "bookword.title": "Kitaplar", - "cog.alternate": "Arama, sıralama ve filtreleme", - "content.series": "Seriler:", - "content.series.data": "{1} Serisinin {0}. Kitabı", - "content.summary": "Bilgi", - "customcolumn.boolean.no": "Hayır", - "customcolumn.boolean.unknown": "Ayarlanmamış", - "customcolumn.boolean.yes": "Evet", - "customcolumn.date.format": "Y-a-g", - "customcolumn.date.unknown": "Ayarlanmamış", - "customcolumn.description": "Özel Sütun '{0}'", - "customcolumn.description.bool": "Doğru/Yanlış değerin sıralaması", - "customcolumn.description.enum.many": "{0} değerin alfabetik sıralaması", - "customcolumn.description.enum.none": "Hiç bir değerin alfabetik sıralaması", - "customcolumn.description.enum.one": "1 değerin alfabetik sıralaması", - "customcolumn.description.rating": "Derecelendirme Listesi", - "customcolumn.description.series.many": "Alfabeye göre sıralanmış {0} Seri", - "customcolumn.description.series.none": "Alfabeye göre sıralanmış 0 Seri", - "customcolumn.description.series.one": "Alfabeye göre sıralanmış 1 Seri", - "customcolumn.enum.unknown": "Ayarlanmamış", - "customcolumn.float.unknown": "Ayarlanmamış", - "customcolumn.int.unknown": "Ayarlanmamış", - "customcolumn.rating.unknown": "Ayarlanmamış", - "customcolumn.stars.many": "{0} Yıldız", - "customcolumn.stars.none": "0 Yıldız", - "customcolumn.stars.one": "1 Yıldız", - "customize.email": "E-Mail Adresi (kitap gönderilebilmesi için)", - "customize.fancybox": "Lightbox kullan (Kitap bilgileri yeni sayfa açılmasına gerek kalmadan görüntülenir)", - "customize.filter": "Etiket Filtreleme'yi Etkinleştir", - "customize.ignored": "Yoksayılan Kategoriler", - "customize.paging": "Bir sayfada gösterilecek en fazla kitap sayısı (Sınırsız için -1)", - "customize.style": "Tema", - "customize.template": "Template", - "customize.title": "Görünüm Seçenekleri", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Tümünü Bırak", - "filters.title": "Filters", - "home.alternate": "Anasayfa", - "i18n.coversection": "Kapak", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Dil", - "languages.alphabetical.many": "Alfabeye göre sıralanmış {0} Dil", - "languages.alphabetical.none": "Alfabeye göre sıralanmış 0 Dil", - "languages.alphabetical.one": "Alfabeye göre sıralanmış 1 Dil", - "languages.title": "Diller", - "links.title": "Bağlantı", - "mail.messagenotsent": "Mesaj gönderilemedi.", - "mail.messagesent": "Mesaj gönderildi.", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "Sonraki", - "paging.previous.alternate": "Önceki", - "permalink.alternate": "Kalıcı Bağlantı", - "pubdate.title": "Published", - "publisher.name": "Yayınevi", - "publishers.alphabetical.many": "Alfabeye göre sıralanmış {0} Yayınevi", - "publishers.alphabetical.none": "Alfabeye göre sıralanmış 0 Yayınevi", - "publishers.alphabetical.one": "Alfabeye göre sıralanmış 1 Yayınevi", - "publishers.title": "Yayınevleri", - "publisherword.many": "{0} Yayınevi", - "publisherword.none": "0 Yayınevi", - "publisherword.one": "1 Yayınevi", - "ratings.many": "{0} Derecelendirme", - "ratings.none": "0 Derecelendirme", - "ratings.one": "1 Derecelendirme", - "ratings.title": "Derecelendirmeler", - "rating.title": "Rating", - "ratingword.many": "{0} Yıldız", - "ratingword.none": "0 Yıldız", - "ratingword.one": "1 Yıldız", - "recent.list": "Son Eklenen {0} Kitap", - "recent.title": "Son Eklenenler", - "search.alternate": "Arama", - "search.result": "*{0}* için arama sonuçları", - "search.result.author": "*{0}* için yazarlarda arama sonuçları", - "search.result.book": "*{0}* için kitaplarda arama sonuçları", - "search.result.publisher": "*{0}* için yayınevlerinde arama sonuçları", - "search.result.series": "*{0}* için serilerde arama sonuçları", - "search.result.tag": "*{0}* için etiketlerde arama sonuçları", - "search.sortorder.asc": "Artan", - "search.sortorder.desc": "Azalan", - "series.alphabetical.many": "Alfabeye göre sıralanmış {0} Seri", - "series.alphabetical.none": "Alfabeye göre sıralanmış 0 Seri", - "series.alphabetical.one": "Alfabeye göre sıralanmış 1 Seri", - "series.title": "Seriler", - "seriesword.many": "{0} Seri", - "seriesword.none": "0 Seri", - "seriesword.one": "1 Seri", - "sort.alternate": "Sıralama", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "Diğer Kitaplar", - "splitByLetter.letter": "{1} ile başlayan {0}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "Alfabeye göre sıralanmış {0} Etiket", - "tags.alphabetical.none": "Alfabeye göre sıralanmış 0 Etiket", - "tags.alphabetical.one": "Alfabeye göre sıralanmış 1 Etiket", - "tags.title": "Etiketler", - "tagword.many": "{0} Etiket", - "tagword.none": "0 Etiket", - "tagword.one": "1 Etiket", - "tagword.title": "Etiketler", - "title.title": "Title", - "languages.abk": "Abhazya Dili", - "languages.aaf": "Afar Dili", - "languages.afr": "Afrikanca", - "languages.aka": "Akanca (Afrika dili)", - "languages.sqi": "Arnavutça", - "languages.amh": "Etiyopyaca", - "languages.ara": "Arapça", - "languages.arg": "Aragonca (İspanya)", - "languages.arc": "Aramaic", - "languages.hye": "Ermenice", - "languages.asm": "Assamese (Hindistan)", - "languages.ava": "Avarca", - "languages.ave": "Avestan (Eski İran)", - "languages.aym": "Aymara (Güney Amerika)", - "languages.aze": "Azerice", - "languages.bam": "Bambara (Mali)", - "languages.bak": "Başkırca", - "languages.eus": "Baskça", - "languages.bel": "Beyaz Rusça", - "languages.ben": "Bengalce", - "languages.bih": "Bihari", - "languages.bis": "Bislama (Vanuatu; Kuzey Pasifik)", - "languages.bos": "Boşnakça", - "languages.bre": "Bretonca", - "languages.bul": "Bulgarca", - "languages.mya": "Burmaca", - "languages.cat": "Katalanca", - "languages.cha": "Chamorro Dili (Guam adaları)", - "languages.che": "Çeçence", - "languages.nya": "Chichewa Dili", - "languages.zho": "Çince", - "languages.chv": "Çuvaş (Türkçe)", - "languages.cor": "Cornish (Kelt)", - "languages.cos": "Korsikaca", - "languages.cre": "Cree (Kuzey Amerika yerlileri)", - "languages.hrv": "Hırvatça", - "languages.ces": "Çekçe", - "languages.dan": "Danca", - "languages.div": "Divehi dili", - "languages.nld": "Hollandaca", - "languages.dzo": "Dzongkha (Butan)", - "languages.eng": "İngilizce", - "languages.epo": "Esperanto Dili", - "languages.est": "Estonca", - "languages.ewe": "Ewe Dili (Afrika)", - "languages.fao": "Faroece", - "languages.fij": "Fiji dili", - "languages.fin": "Fince", - "languages.fra": "Fransızca", - "languages.ful": "Fulah (Afrika)", - "languages.glg": "Galce", - "languages.kat": "Gürcüce", - "languages.deu": "Almanca", - "languages.ell": "Yunanca", - "languages.egy": "Egyptian (Ancient)", - "languages.grn": "Guarani (Paraguay)", - "languages.guj": "Gucaratça", - "languages.hat": "Haiti Dili", - "languages.hau": "Hausa Dili", - "languages.heb": "İbranice", - "languages.her": "Herero Dili", - "languages.hin": "Hintçe", - "languages.hmo": "Hiri Motu Dili", - "languages.hun": "Macarca", - "languages.ina": "Interlingua (Uluslararası Yardımcı Dil Kurumu)", - "languages.ind": "Endonezyaca", - "languages.ile": "Interlingue Dili", - "languages.gle": "İrlandaca", - "languages.grc": "Greek, Ancient (to 1453)", - "languages.ibo": "Igbo Dili", - "languages.ipk": "Inupiak Dili", - "languages.ido": "Ido Dili", - "languages.isl": "İzlandaca", - "languages.ita": "İtalyanca", - "languages.iku": "İnuitçe", - "languages.jpn": "Japonca", - "languages.jav": "Cava Dili", - "languages.kal": "Kalaallisut Dili", - "languages.kan": "Kannada Dili", - "languages.kau": "Kanuri Dili", - "languages.kas": "Keşmirce", - "languages.kaz": "Kazakça", - "languages.khm": "Khmer Dili", - "languages.kik": "Kikuyu Dili", - "languages.kin": "Kinyarwanda Dili", - "languages.kir": "Kırgızca", - "languages.kom": "Komi Dili", - "languages.kon": "Kongo Dili", - "languages.kor": "Korece", - "languages.kur": "Kürtçe", - "languages.kua": "Kwanyama Dili", - "languages.lat": "Latince", - "languages.ltz": "Lüksemburg Dili", - "languages.lug": "Ganda Dili", - "languages.lim": "Liburg Dili", - "languages.lin": "Lingala Dili", - "languages.lao": "Lao Dili", - "languages.lit": "Litvanca", - "languages.lub": "Luba-Katanga Dili", - "languages.lav": "Letonca", - "languages.glv": "Manx Dili (Galler)", - "languages.mkd": "Makedonca", - "languages.mlg": "Madagaskar Dili", - "languages.msa": "Malay Dili", - "languages.mal": "Malayalam Dili", - "languages.mlt": "Malta Dili", - "languages.mri": "Maorice", - "languages.mar": "Marathi Dili", - "languages.mah": "Marshall Dili", - "languages.mon": "Moğolca", - "languages.nau": "Nauru Dili", - "languages.nav": "Navajo Dili", - "languages.nob": "Norveççe Bokmal", - "languages.nde": "Ndebele; Kuzey", - "languages.nep": "Nepal Dili", - "languages.ndo": "Ndonga Dili", - "languages.nno": "Norveççe Nynorsk", - "languages.nor": "Norveçce", - "languages.iii": "Nuosu Dili", - "languages.nbl": "Ndebele; Güney", - "languages.oci": "Oksitanca", - "languages.oji": "Ojibwe Dili", - "languages.chu": "Slav; Eski", - "languages.orm": "Oromo Dili", - "languages.ori": "Oriya Dili", - "languages.oss": "Osetya Dili", - "languages.pan": "Pencabi Dili", - "languages.pli": "Pali Dili", - "languages.fas": "Farsça", - "languages.pol": "Lehçe", - "languages.pus": "Peştuca", - "languages.por": "Portekizce", - "languages.que": "Quechua Dili", - "languages.roh": "Romanca", - "languages.run": "Kirundi Dili", - "languages.ron": "Rumence", - "languages.rus": "Rusça", - "languages.sam": "Samaritan Aramaic", - "languages.san": "Sanskritçe", - "languages.srd": "Sardinya Dili", - "languages.snd": "Sindhi Dili", - "languages.sme": "Sami; Kuzeyli", - "languages.smo": "Samoa Dili", - "languages.sag": "Sangho Dili", - "languages.srp": "Sırpça", - "languages.gla": "Galce; İskoçyalı", - "languages.sna": "Shona Dili", - "languages.sin": "Sinhala Dili", - "languages.slk": "Slovakça", - "languages.slv": "Slovence", - "languages.som": "Somali Dili", - "languages.sot": "Güney Sotho Dili", - "languages.spa": "İspanyolca", - "languages.sun": "Sudan Dili", - "languages.sux": "Sumerian", - "languages.swa": "Svahili dili", - "languages.ssw": "Siswati Dili", - "languages.swe": "İsveççe", - "languages.syc": "Classical Syriac", - "languages.syr": "Syriac", - "languages.tam": "Tamil Dili", - "languages.tel": "Telugu Dili", - "languages.tgk": "Tacikçe", - "languages.tha": "Taylandça", - "languages.tir": "Tigrinya Dili", - "languages.bod": "Tibetçe", - "languages.tuk": "Türkmence", - "languages.tgl": "Tagalog Dili", - "languages.tsn": "Tsvana Dili", - "languages.ton": "Tonga Dili", - "languages.tur": "Türkçe", - "languages.tso": "Tsonga Dili", - "languages.tat": "Tatarca", - "languages.twi": "Twi Dili", - "languages.tah": "Tahitice", - "languages.uga": "Ugaritic", - "languages.uig": "Uygurca", - "languages.ukr": "Ukraynaca", - "languages.urd": "Urduca", - "languages.uzb": "Özbekçe", - "languages.ven": "Venda Dili", - "languages.vie": "Vietnam Dili", - "languages.vol": "Volapük Dili", - "languages.win": "Valon Dili", - "languages.cym": "Galce", - "languages.wol": "Volof Dili", - "languages.fry": "Batı Frizce", - "languages.xho": "Zosa dili", - "languages.yid": "Yidiş Dili", - "languages.yor": "Yoruba Dili", - "languages.zha": "Zhuang Dili", - "languages.zul": "Zulu Dili", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_uk.json b/COPS/cops-3.1.3/lang/Localization_uk.json deleted file mode 100644 index 5af37cd8..00000000 --- a/COPS/cops-3.1.3/lang/Localization_uk.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "Про COPS", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "Алфавітний покажчик {0} книг(и)", - "allbooks.alphabetical.none": "Назви не вказані", - "allbooks.alphabetical.one": "Єдина книга", - "allbooks.title": "Усі книги", - "authors.alphabetical.many": "Алфавітний покажчик {0} авторів(а)", - "authors.alphabetical.none": "Автори не вказані", - "authors.alphabetical.one": "Єдиний автор", - "authors.title": "Автори", - "author.title": "Author", - "authorword.many": "{0} авторів(а)", - "authorword.none": "Немає авторів(а)", - "authorword.one": "1 автор", - "bookentry.author": "{0} з {1}", - "bookword.many": "{0} книг(и)", - "bookword.none": "Немає книг(и)", - "bookword.one": "1 книга", - "bookword.title": "Книги", - "cog.alternate": "Пошук, сортування та фільтри", - "content.series": "Серії:", - "content.series.data": "Книга {0} з серії {1}", - "content.summary": "Короткий зміст", - "customcolumn.boolean.no": "Ні", - "customcolumn.boolean.unknown": "Не встановлено", - "customcolumn.boolean.yes": "Так", - "customcolumn.date.format": "Y-m-d", - "customcolumn.date.unknown": "Не встановлено", - "customcolumn.description": "Custom column '{0}'", - "customcolumn.description.bool": "Index of a boolean value", - "customcolumn.description.enum.many": "Alphabetical index of the {0} values", - "customcolumn.description.enum.none": "Alphabetical index of absolutely no values", - "customcolumn.description.enum.one": "Alphabetical index of one value", - "customcolumn.description.rating": "Index of ratings", - "customcolumn.description.series.many": "Алфавітний покажчик {0} серій(ї)", - "customcolumn.description.series.none": "Серії не вказано", - "customcolumn.description.series.one": "Єдина серія", - "customcolumn.enum.unknown": "Не встановлено", - "customcolumn.float.unknown": "Не встановлено", - "customcolumn.int.unknown": "Не встановлено", - "customcolumn.rating.unknown": "Не встановлено", - "customcolumn.stars.many": "{0} Stars", - "customcolumn.stars.none": "No Stars", - "customcolumn.stars.one": "1 Star", - "customize.email": "Вкажіть Ваш email (для відправки книг електронною поштою)", - "customize.fancybox": "Відкривати картку книги у спливаючому вікні", - "customize.filter": "Увімкнути фільтрацію за жанром", - "customize.ignored": "Виключити категорії", - "customize.paging": "Максимальна кількість книжок на сторінці (-1 - не обмежувати)", - "customize.style": "Тема", - "customize.template": "Template", - "customize.title": "Налаштування зовнішнього вигляду COPS", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "Очистити все", - "filters.title": "Filters", - "home.alternate": "Додому", - "i18n.coversection": "Обкладинка", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "Мова", - "languages.alphabetical.many": "Алфавітний покажчик {0} мов(и)", - "languages.alphabetical.none": "Мови не вказані", - "languages.alphabetical.one": "Єдина мова", - "languages.title": "Мови", - "links.title": "Посилання", - "mail.messagenotsent": "Повідомлення не може бути відправлено", - "mail.messagesent": "Повідомлення відправлено", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "Наступний", - "paging.previous.alternate": "Попередній", - "permalink.alternate": "Постійне посилання", - "pubdate.title": "Published", - "publisher.name": "Видавництво", - "publishers.alphabetical.many": "Алфавітний покажчик of the {0} видавництв(а)", - "publishers.alphabetical.none": "Видавництва не вказані", - "publishers.alphabetical.one": "Єдине видавництво", - "publishers.title": "Видавництва", - "publisherword.many": "{0} видавництв(а)", - "publisherword.none": "Немає видавництв(а)", - "publisherword.one": "1 видавництво", - "ratings.many": "{0} оцінок(ка)", - "ratings.none": "Немає оцінок", - "ratings.one": "1 оцінка", - "ratings.title": "Оцінки", - "rating.title": "Rating", - "ratingword.many": "{0} зірка(ок)", - "ratingword.none": "Немає зірок", - "ratingword.one": "1 зірка", - "recent.list": "{0} нещодавно доданих книжок", - "recent.title": "Останні надходження", - "search.alternate": "Пошук", - "search.result": "Результат пошуку *{0}*", - "search.result.author": "Результат пошуку *{0}* серед авторів", - "search.result.book": "Результат пошуку *{0}* серед книжок", - "search.result.publisher": "Результат пошуку *{0}* серед видавництв", - "search.result.series": "Результат пошуку *{0}* серед серій", - "search.result.tag": "Результат пошуку *{0}* серед жанрів", - "search.sortorder.asc": "Висх.", - "search.sortorder.desc": "Спад.", - "series.alphabetical.many": "Алфавітний покажчик {0} серій(ї)", - "series.alphabetical.none": "Серії не вказано", - "series.alphabetical.one": "Єдина серія", - "series.title": "Серії", - "seriesword.many": "{0} серій(я)", - "seriesword.none": "Немає серій", - "seriesword.one": "1 серія", - "sort.alternate": "Сортування", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "Книги за назвою", - "splitByLetter.letter": "{0} починається з {1}", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "Алфавітний покажчик {0} жанрів(а)", - "tags.alphabetical.none": "Жанри не вказано", - "tags.alphabetical.one": "Єдиний жанр", - "tags.title": "Жанри", - "tagword.many": "{0} жанрів", - "tagword.none": "Немає жанрів", - "tagword.one": "1 жанр", - "tagword.title": "Жанри", - "title.title": "Title", - "languages.abk": "Abkhaz", - "languages.aaf": "Afar", - "languages.afr": "Afrikaans", - "languages.aka": "Akan", - "languages.sqi": "Albanian", - "languages.amh": "Amharic", - "languages.ara": "Arabic", - "languages.arg": "Aragonese", - "languages.arc": "Aramaic", - "languages.hye": "Armenian", - "languages.asm": "Assamese", - "languages.ava": "Avaric", - "languages.ave": "Avestan", - "languages.aym": "Aymara", - "languages.aze": "Azerbaijani", - "languages.bam": "Bambara", - "languages.bak": "Bashkir", - "languages.eus": "Basque", - "languages.bel": "Belarusian", - "languages.ben": "Bengali", - "languages.bih": "Bihari", - "languages.bis": "Bislama", - "languages.bos": "Bosnian", - "languages.bre": "Breton", - "languages.bul": "Bulgarian", - "languages.mya": "Burmese", - "languages.cat": "Catalan", - "languages.cha": "Chamorro", - "languages.che": "Chechen", - "languages.nya": "Chichewa", - "languages.zho": "Chinese", - "languages.chv": "Chuvash", - "languages.cor": "Cornish", - "languages.cos": "Corsican", - "languages.cre": "Cree", - "languages.hrv": "Croatian", - "languages.ces": "Czech", - "languages.dan": "Danish", - "languages.div": "Divehi", - "languages.nld": "Dutch", - "languages.dzo": "Dzongkha", - "languages.eng": "English", - "languages.epo": "Esperanto", - "languages.est": "Estonian", - "languages.ewe": "Ewe", - "languages.fao": "Faroese", - "languages.fij": "Fijian", - "languages.fin": "Finnish", - "languages.fra": "French", - "languages.ful": "Fula", - "languages.glg": "Galician", - "languages.kat": "Georgian", - "languages.deu": "German", - "languages.ell": "Greek", - "languages.egy": "Egyptian (Ancient)", - "languages.grn": "Guaraní", - "languages.guj": "Gujarati", - "languages.hat": "Haitian", - "languages.hau": "Hausa", - "languages.heb": "Hebrew", - "languages.her": "Herero", - "languages.hin": "Hindi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Hungarian", - "languages.ina": "Interlingua", - "languages.ind": "Indonesian", - "languages.ile": "Interlingue", - "languages.gle": "Irish", - "languages.grc": "Greek, Ancient (to 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Icelandic", - "languages.ita": "Italian", - "languages.iku": "Inuktitut", - "languages.jpn": "Japanese", - "languages.jav": "Javanese", - "languages.kal": "Kalaallisut", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kashmiri", - "languages.kaz": "Kazakh", - "languages.khm": "Khmer", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kyrgyz", - "languages.kom": "Komi", - "languages.kon": "Kongo", - "languages.kor": "Korean", - "languages.kur": "Kurdish", - "languages.kua": "Kwanyama", - "languages.lat": "Latin", - "languages.ltz": "Luxembourgish", - "languages.lug": "Ganda", - "languages.lim": "Limburgish", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Lithuanian", - "languages.lub": "Luba-Katanga", - "languages.lav": "Latvian", - "languages.glv": "Manx", - "languages.mkd": "Macedonian", - "languages.mlg": "Malagasy", - "languages.msa": "Malay", - "languages.mal": "Malayalam", - "languages.mlt": "Maltese", - "languages.mri": "Māori", - "languages.mar": "Marathi", - "languages.mah": "Marshallese", - "languages.mon": "Mongolian", - "languages.nau": "Nauru", - "languages.nav": "Navajo", - "languages.nob": "Norwegian Bokmål", - "languages.nde": "North Ndebele", - "languages.nep": "Nepali", - "languages.ndo": "Ndonga", - "languages.nno": "Norwegian Nynorsk", - "languages.nor": "Norwegian", - "languages.iii": "Nuosu", - "languages.nbl": "South Ndebele", - "languages.oci": "Occitan", - "languages.oji": "Ojibwe", - "languages.chu": "Old Church Slavonic", - "languages.orm": "Oromo", - "languages.ori": "Oriya", - "languages.oss": "Ossetian", - "languages.pan": "Panjabi", - "languages.pli": "Pāli", - "languages.fas": "Persian", - "languages.pol": "Polish", - "languages.pus": "Pashto", - "languages.por": "Portuguese", - "languages.que": "Quechua", - "languages.roh": "Romansh", - "languages.run": "Kirundi", - "languages.ron": "Romanian", - "languages.rus": "Russian", - "languages.sam": "Samaritan Aramaic", - "languages.san": "Sanskrit", - "languages.srd": "Sardinian", - "languages.snd": "Sindhi", - "languages.sme": "Northern Sami", - "languages.smo": "Samoan", - "languages.sag": "Sango", - "languages.srp": "Serbian", - "languages.gla": "Scottish Gaelic", - "languages.sna": "Shona", - "languages.sin": "Sinhala", - "languages.slk": "Slovak", - "languages.slv": "Slovene", - "languages.som": "Somali", - "languages.sot": "Southern Sotho", - "languages.spa": "Spanish", - "languages.sun": "Sundanese", - "languages.sux": "Sumerian", - "languages.swa": "Swahili", - "languages.ssw": "Swati", - "languages.swe": "Swedish", - "languages.syc": "Classical Syriac", - "languages.syr": "Syriac", - "languages.tam": "Tamil", - "languages.tel": "Telugu", - "languages.tgk": "Tajik", - "languages.tha": "Thai", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetan Standard", - "languages.tuk": "Turkmen", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tonga", - "languages.tur": "Turkish", - "languages.tso": "Tsonga", - "languages.tat": "Tatar", - "languages.twi": "Twi", - "languages.tah": "Tahitian", - "languages.uga": "Ugaritic", - "languages.uig": "Uighur", - "languages.ukr": "Українська", - "languages.urd": "Urdu", - "languages.uzb": "Uzbek", - "languages.ven": "Venda", - "languages.vie": "Vietnamese", - "languages.vol": "Volapük", - "languages.win": "Walloon", - "languages.cym": "Welsh", - "languages.wol": "Wolof", - "languages.fry": "Western Frisian", - "languages.xho": "Xhosa", - "languages.yid": "Yiddish", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_zh_CN.json b/COPS/cops-3.1.3/lang/Localization_zh_CN.json deleted file mode 100644 index b0385d2f..00000000 --- a/COPS/cops-3.1.3/lang/Localization_zh_CN.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "关于COPS", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "{0} 本书籍的字母索引", - "allbooks.alphabetical.none": "无书籍", - "allbooks.alphabetical.one": "1 本书籍", - "allbooks.title": "所有书籍", - "authors.alphabetical.many": "{0} 位作者的字母索引", - "authors.alphabetical.none": "无作者", - "authors.alphabetical.one": "1 位作者", - "authors.title": "作者", - "author.title": "Author", - "authorword.many": "{0} 位作者", - "authorword.none": "未知", - "authorword.one": "1 位作者", - "bookentry.author": "{0} 由作者 {1}", - "bookword.many": "{0} 本书籍", - "bookword.none": "无书籍", - "bookword.one": "1 本书籍", - "bookword.title": "书名", - "cog.alternate": "搜索, 分类和过滤", - "content.series": "系列:", - "content.series.data": "系列 {1} 的第 {0} 本", - "content.summary": "概要", - "customcolumn.boolean.no": "否", - "customcolumn.boolean.unknown": "未设置", - "customcolumn.boolean.yes": "是", - "customcolumn.date.format": "年-月-日", - "customcolumn.date.unknown": "未设置", - "customcolumn.description": "自定义栏目 '{0}'", - "customcolumn.description.bool": "按布尔值索引", - "customcolumn.description.enum.many": "按 {0} 的字母索引", - "customcolumn.description.enum.none": "没有内容", - "customcolumn.description.enum.one": "按属性的字母索引", - "customcolumn.description.rating": "按评分索引", - "customcolumn.description.series.many": "{0} 个系列的字母索引", - "customcolumn.description.series.none": "无系列", - "customcolumn.description.series.one": "1 个系列", - "customcolumn.enum.unknown": "未设置", - "customcolumn.float.unknown": "未设置", - "customcolumn.int.unknown": "未设置", - "customcolumn.rating.unknown": "未设置", - "customcolumn.stars.many": "{0} 星", - "customcolumn.stars.none": "无评星", - "customcolumn.stars.one": "1 个评星", - "customize.email": "设置您的电子邮件(以允许发送邮件)", - "customize.fancybox": "使用灯箱", - "customize.filter": "打开标签过滤", - "customize.ignored": "忽略的分类", - "customize.paging": "页内最大书籍数(-1表示禁用)", - "customize.style": "主题", - "customize.template": "Template", - "customize.title": "自定义界面", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "全不选", - "filters.title": "Filters", - "home.alternate": "首页", - "i18n.coversection": "封面", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "语言", - "languages.alphabetical.many": "{0} 语言的字母索引", - "languages.alphabetical.none": "无语言", - "languages.alphabetical.one": "1 种语言", - "languages.title": "语言", - "links.title": "友情链接", - "mail.messagenotsent": "信息未发送。", - "mail.messagesent": "信息已发送。", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "下一页", - "paging.previous.alternate": "上一页", - "permalink.alternate": "永久链接", - "pubdate.title": "Published", - "publisher.name": "出版社", - "publishers.alphabetical.many": "{0} 个出版社的字母索引", - "publishers.alphabetical.none": "无出版社", - "publishers.alphabetical.one": "单个出版社的字母索引", - "publishers.title": "出版社", - "publisherword.many": "{0} 个出版社", - "publisherword.none": "无出版社", - "publisherword.one": "1 个出版社", - "ratings.many": "{0} 个评价", - "ratings.none": "未评价", - "ratings.one": "1 个评价", - "ratings.title": "评价", - "rating.title": "Rating", - "ratingword.many": "{0} 颗星", - "ratingword.none": "未评星", - "ratingword.one": "1 颗星", - "recent.list": "{0} 本最近添加的书", - "recent.title": "最近添加", - "search.alternate": "搜索", - "search.result": "*{0}* 的搜索结果", - "search.result.author": "作者中 *{0}* 的搜索结果", - "search.result.book": "书籍中 *{0}* 的搜索结果", - "search.result.publisher": "*{0}* 在出版社中的搜索结果", - "search.result.series": "系列中 *{0}* 的搜索结果", - "search.result.tag": "标签中 *{0}* 的搜索结果", - "search.sortorder.asc": "升序", - "search.sortorder.desc": "降序", - "series.alphabetical.many": "{0} 个系列的字母索引", - "series.alphabetical.none": "无系列", - "series.alphabetical.one": "1 个系列", - "series.title": "系列", - "seriesword.many": "{0} 系列", - "seriesword.none": "无系列", - "seriesword.one": "1 个系列", - "sort.alternate": "排序", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "其他书籍", - "splitByLetter.letter": "{0} 以 {1} 开头", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "{0} 个标签的字母索引", - "tags.alphabetical.none": "无标签", - "tags.alphabetical.one": "1 个标签", - "tags.title": "标签", - "tagword.many": "{0} 标签", - "tagword.none": "无标签", - "tagword.one": "1 个标签", - "tagword.title": "标签", - "title.title": "Title", - "languages.abk": "阿布哈兹语", - "languages.aaf": "阿法尔语", - "languages.afr": "Afrikaans", - "languages.aka": "Akan", - "languages.sqi": "Albanian", - "languages.amh": "Amharic", - "languages.ara": "Arabic", - "languages.arg": "Aragonese", - "languages.arc": "Aramaic", - "languages.hye": "Armenian", - "languages.asm": "Assamese", - "languages.ava": "Avaric", - "languages.ave": "Avestan", - "languages.aym": "Aymara", - "languages.aze": "Azerbaijani", - "languages.bam": "Bambara", - "languages.bak": "Bashkir", - "languages.eus": "Basque", - "languages.bel": "Belarusian", - "languages.ben": "Bengali", - "languages.bih": "Bihari", - "languages.bis": "Bislama", - "languages.bos": "Bosnian", - "languages.bre": "Breton", - "languages.bul": "Bulgarian", - "languages.mya": "Burmese", - "languages.cat": "Catalan", - "languages.cha": "Chamorro", - "languages.che": "Chechen", - "languages.nya": "Chichewa", - "languages.zho": "简体中文", - "languages.chv": "Chuvash", - "languages.cor": "Cornish", - "languages.cos": "Corsican", - "languages.cre": "Cree", - "languages.hrv": "Croatian", - "languages.ces": "Czech", - "languages.dan": "Danish", - "languages.div": "Divehi", - "languages.nld": "Dutch", - "languages.dzo": "Dzongkha", - "languages.eng": "英语", - "languages.epo": "Esperanto", - "languages.est": "Estonian", - "languages.ewe": "Ewe", - "languages.fao": "Faroese", - "languages.fij": "Fijian", - "languages.fin": "Finnish", - "languages.fra": "法语", - "languages.ful": "Fula", - "languages.glg": "Galician", - "languages.kat": "Georgian", - "languages.deu": "German", - "languages.ell": "Greek", - "languages.egy": "Egyptian (Ancient)", - "languages.grn": "Guaraní", - "languages.guj": "Gujarati", - "languages.hat": "Haitian", - "languages.hau": "Hausa", - "languages.heb": "Hebrew", - "languages.her": "Herero", - "languages.hin": "Hindi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Hungarian", - "languages.ina": "Interlingua", - "languages.ind": "Indonesian", - "languages.ile": "Interlingue", - "languages.gle": "Irish", - "languages.grc": "Greek, Ancient (to 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Icelandic", - "languages.ita": "Italian", - "languages.iku": "Inuktitut", - "languages.jpn": "日语", - "languages.jav": "Javanese", - "languages.kal": "Kalaallisut", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kashmiri", - "languages.kaz": "Kazakh", - "languages.khm": "Khmer", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kyrgyz", - "languages.kom": "Komi", - "languages.kon": "Kongo", - "languages.kor": "Korean", - "languages.kur": "Kurdish", - "languages.kua": "Kwanyama", - "languages.lat": "Latin", - "languages.ltz": "Luxembourgish", - "languages.lug": "Ganda", - "languages.lim": "Limburgish", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Lithuanian", - "languages.lub": "Luba-Katanga", - "languages.lav": "Latvian", - "languages.glv": "Manx", - "languages.mkd": "Macedonian", - "languages.mlg": "Malagasy", - "languages.msa": "Malay", - "languages.mal": "Malayalam", - "languages.mlt": "Maltese", - "languages.mri": "Māori", - "languages.mar": "Marathi", - "languages.mah": "Marshallese", - "languages.mon": "Mongolian", - "languages.nau": "Nauru", - "languages.nav": "Navajo", - "languages.nob": "Norwegian Bokmål", - "languages.nde": "North Ndebele", - "languages.nep": "Nepali", - "languages.ndo": "Ndonga", - "languages.nno": "Norwegian Nynorsk", - "languages.nor": "Norwegian", - "languages.iii": "Nuosu", - "languages.nbl": "South Ndebele", - "languages.oci": "Occitan", - "languages.oji": "Ojibwe", - "languages.chu": "Old Church Slavonic", - "languages.orm": "Oromo", - "languages.ori": "Oriya", - "languages.oss": "Ossetian", - "languages.pan": "Panjabi", - "languages.pli": "Pāli", - "languages.fas": "Persian", - "languages.pol": "Polish", - "languages.pus": "Pashto", - "languages.por": "Portuguese", - "languages.que": "Quechua", - "languages.roh": "Romansh", - "languages.run": "Kirundi", - "languages.ron": "Romanian", - "languages.rus": "Russian", - "languages.sam": "Samaritan Aramaic", - "languages.san": "Sanskrit", - "languages.srd": "Sardinian", - "languages.snd": "Sindhi", - "languages.sme": "Northern Sami", - "languages.smo": "Samoan", - "languages.sag": "Sango", - "languages.srp": "Serbian", - "languages.gla": "Scottish Gaelic", - "languages.sna": "Shona", - "languages.sin": "Sinhala", - "languages.slk": "Slovak", - "languages.slv": "Slovene", - "languages.som": "Somali", - "languages.sot": "Southern Sotho", - "languages.spa": "Spanish", - "languages.sun": "Sundanese", - "languages.sux": "Sumerian", - "languages.swa": "Swahili", - "languages.ssw": "Swati", - "languages.swe": "Swedish", - "languages.syc": "Classical Syriac", - "languages.syr": "Syriac", - "languages.tam": "Tamil", - "languages.tel": "Telugu", - "languages.tgk": "Tajik", - "languages.tha": "Thai", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetan Standard", - "languages.tuk": "Turkmen", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tonga", - "languages.tur": "Turkish", - "languages.tso": "Tsonga", - "languages.tat": "Tatar", - "languages.twi": "Twi", - "languages.tah": "Tahitian", - "languages.uga": "Ugaritic", - "languages.uig": "Uighur", - "languages.ukr": "Ukrainian", - "languages.urd": "Urdu", - "languages.uzb": "Uzbek", - "languages.ven": "Venda", - "languages.vie": "Vietnamese", - "languages.vol": "Volapük", - "languages.win": "Walloon", - "languages.cym": "Welsh", - "languages.wol": "Wolof", - "languages.fry": "Western Frisian", - "languages.xho": "Xhosa", - "languages.yid": "Yiddish", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/lang/Localization_zh_TW.json b/COPS/cops-3.1.3/lang/Localization_zh_TW.json deleted file mode 100644 index bae82398..00000000 --- a/COPS/cops-3.1.3/lang/Localization_zh_TW.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "about.title": "关于COPS", - "addeddate.title": "Added", - "allbooks.alphabetical.many": "{0} 本书籍的字母索引", - "allbooks.alphabetical.none": "无书籍", - "allbooks.alphabetical.one": "1 本书籍", - "allbooks.title": "所有书籍", - "authors.alphabetical.many": "{0} 位作者的字母索引", - "authors.alphabetical.none": "无作者", - "authors.alphabetical.one": "1 位作者", - "authors.title": "作者", - "author.title": "Author", - "authorword.many": "{0} 位作者", - "authorword.none": "未知", - "authorword.one": "1 位作者", - "bookentry.author": "{0} 由作者 {1}", - "bookword.many": "{0} 本书籍", - "bookword.none": "无书籍", - "bookword.one": "1 本书籍", - "bookword.title": "书名", - "cog.alternate": "搜索, 分类和过滤", - "content.series": "系列:", - "content.series.data": "系列 {1} 的第 {0} 本", - "content.summary": "概要", - "customcolumn.boolean.no": "否", - "customcolumn.boolean.unknown": "未设置", - "customcolumn.boolean.yes": "是", - "customcolumn.date.format": "Y-m-d", - "customcolumn.date.unknown": "未设置", - "customcolumn.description": "Custom column '{0}'", - "customcolumn.description.bool": "Index of a boolean value", - "customcolumn.description.enum.many": "Alphabetical index of the {0} values", - "customcolumn.description.enum.none": "Alphabetical index of absolutely no values", - "customcolumn.description.enum.one": "Alphabetical index of one value", - "customcolumn.description.rating": "Index of ratings", - "customcolumn.description.series.many": "{0} 个系列的字母索引", - "customcolumn.description.series.none": "无系列", - "customcolumn.description.series.one": "1 个系列", - "customcolumn.enum.unknown": "未设置", - "customcolumn.float.unknown": "未设置", - "customcolumn.int.unknown": "未设置", - "customcolumn.rating.unknown": "未设置", - "customcolumn.stars.many": "{0} Stars", - "customcolumn.stars.none": "No Stars", - "customcolumn.stars.one": "1 Star", - "customize.email": "设置您的电子邮件(以允许发送邮件)", - "customize.fancybox": "使用灯箱", - "customize.filter": "打开标签过滤", - "customize.ignored": "Ignored categories", - "customize.paging": "页内最大书籍数(-1表示禁用)", - "customize.style": "主题", - "customize.template": "Template", - "customize.title": "自定义界面", - "default.template": "Default COPS template", - "downloadall.title": "Download all", - "downloadall.tooltip": "Download a zip file containing all books on this page in this format", - "extra.content": "Description", - "extra.link": "Link", - "extra.title": "Extra Information", - "filter.clearall": "全部清除", - "filters.title": "Filters", - "home.alternate": "首页", - "i18n.coversection": "封面", - "identifiers.title": "Identifiers", - "identifierword.many": "{0} identifiers", - "identifierword.none": "No identifier", - "identifierword.one": "1 identifier", - "language.title": "语言", - "languages.alphabetical.many": "{0} 语言的字母索引", - "languages.alphabetical.none": "无语言", - "languages.alphabetical.one": "1 种语言", - "languages.title": "语言", - "links.title": "網站連結", - "mail.messagenotsent": "信息未发送。", - "mail.messagesent": "信息已发送。", - "paging.first.alternate": "First", - "paging.last.alternate": "Last", - "paging.next.alternate": "下一页", - "paging.previous.alternate": "上一页", - "permalink.alternate": "永久链接", - "pubdate.title": "Published", - "publisher.name": "Publisher", - "publishers.alphabetical.many": "Alphabetical index of the {0} publishers", - "publishers.alphabetical.none": "Alphabetical index of absolutely no publishers", - "publishers.alphabetical.one": "Alphabetical index of the single publisher", - "publishers.title": "Publishers", - "publisherword.many": "{0} publishers", - "publisherword.none": "No publishers", - "publisherword.one": "1 publisher", - "ratings.many": "{0} ratings", - "ratings.none": "no ratings", - "ratings.one": "1 rating", - "ratings.title": "Ratings", - "rating.title": "Rating", - "ratingword.many": "{0} stars", - "ratingword.none": "No star", - "ratingword.one": "1 star", - "recent.list": "{0} 本最近添加的书", - "recent.title": "最近添加", - "search.alternate": "搜索", - "search.result": "*{0}* 的搜索结果", - "search.result.author": "作者中 *{0}* 的搜索结果", - "search.result.book": "书籍中 *{0}* 的搜索结果", - "search.result.publisher": "Search result for *{0}* in publishers", - "search.result.series": "系列中 *{0}* 的搜索结果", - "search.result.tag": "标签中 *{0}* 的搜索结果", - "search.sortorder.asc": "升序", - "search.sortorder.desc": "降序", - "series.alphabetical.many": "{0} 个系列的字母索引", - "series.alphabetical.none": "无系列", - "series.alphabetical.one": "1 个系列", - "series.title": "系列", - "seriesword.many": "{0} 系列", - "seriesword.none": "无系列", - "seriesword.one": "1 个系列", - "sort.alternate": "排序", - "sort.count": "Count", - "sort.names": "Names", - "sort.titles": "Titles", - "sortby.title": "Sort by", - "splitByLetter.book.other": "其他书籍", - "splitByLetter.letter": "{0} 以 {1} 开头", - "splitByRange.range": "{0} in range {1}", - "splitByYear.year": "{0} published in {1}", - "tags.alphabetical.many": "{0} 个标签的字母索引", - "tags.alphabetical.none": "无标签", - "tags.alphabetical.one": "1 个标签", - "tags.title": "标签", - "tagword.many": "{0} 标签", - "tagword.none": "无标签", - "tagword.one": "1 个标签", - "tagword.title": "标签", - "title.title": "Title", - "languages.abk": "Abkhaz", - "languages.aaf": "Afar", - "languages.afr": "Afrikaans", - "languages.aka": "Akan", - "languages.sqi": "Albanian", - "languages.amh": "Amharic", - "languages.ara": "Arabic", - "languages.arg": "Aragonese", - "languages.arc": "Aramaic", - "languages.hye": "Armenian", - "languages.asm": "Assamese", - "languages.ava": "Avaric", - "languages.ave": "Avestan", - "languages.aym": "Aymara", - "languages.aze": "Azerbaijani", - "languages.bam": "Bambara", - "languages.bak": "Bashkir", - "languages.eus": "Basque", - "languages.bel": "Belarusian", - "languages.ben": "Bengali", - "languages.bih": "Bihari", - "languages.bis": "Bislama", - "languages.bos": "Bosnian", - "languages.bre": "Breton", - "languages.bul": "Bulgarian", - "languages.mya": "Burmese", - "languages.cat": "Catalan", - "languages.cha": "Chamorro", - "languages.che": "Chechen", - "languages.nya": "Chichewa", - "languages.zho": "简体中文", - "languages.chv": "Chuvash", - "languages.cor": "Cornish", - "languages.cos": "Corsican", - "languages.cre": "Cree", - "languages.hrv": "Croatian", - "languages.ces": "Czech", - "languages.dan": "Danish", - "languages.div": "Divehi", - "languages.nld": "Dutch", - "languages.dzo": "Dzongkha", - "languages.eng": "英语", - "languages.epo": "Esperanto", - "languages.est": "Estonian", - "languages.ewe": "Ewe", - "languages.fao": "Faroese", - "languages.fij": "Fijian", - "languages.fin": "Finnish", - "languages.fra": "法语", - "languages.ful": "Fula", - "languages.glg": "Galician", - "languages.kat": "Georgian", - "languages.deu": "German", - "languages.ell": "Greek", - "languages.egy": "Egyptian (Ancient)", - "languages.grn": "Guaraní", - "languages.guj": "Gujarati", - "languages.hat": "Haitian", - "languages.hau": "Hausa", - "languages.heb": "Hebrew", - "languages.her": "Herero", - "languages.hin": "Hindi", - "languages.hmo": "Hiri Motu", - "languages.hun": "Hungarian", - "languages.ina": "Interlingua", - "languages.ind": "Indonesian", - "languages.ile": "Interlingue", - "languages.gle": "Irish", - "languages.grc": "Greek, Ancient (to 1453)", - "languages.ibo": "Igbo", - "languages.ipk": "Inupiaq", - "languages.ido": "Ido", - "languages.isl": "Icelandic", - "languages.ita": "Italian", - "languages.iku": "Inuktitut", - "languages.jpn": "日语", - "languages.jav": "Javanese", - "languages.kal": "Kalaallisut", - "languages.kan": "Kannada", - "languages.kau": "Kanuri", - "languages.kas": "Kashmiri", - "languages.kaz": "Kazakh", - "languages.khm": "Khmer", - "languages.kik": "Kikuyu", - "languages.kin": "Kinyarwanda", - "languages.kir": "Kyrgyz", - "languages.kom": "Komi", - "languages.kon": "Kongo", - "languages.kor": "Korean", - "languages.kur": "Kurdish", - "languages.kua": "Kwanyama", - "languages.lat": "Latin", - "languages.ltz": "Luxembourgish", - "languages.lug": "Ganda", - "languages.lim": "Limburgish", - "languages.lin": "Lingala", - "languages.lao": "Lao", - "languages.lit": "Lithuanian", - "languages.lub": "Luba-Katanga", - "languages.lav": "Latvian", - "languages.glv": "Manx", - "languages.mkd": "Macedonian", - "languages.mlg": "Malagasy", - "languages.msa": "Malay", - "languages.mal": "Malayalam", - "languages.mlt": "Maltese", - "languages.mri": "Māori", - "languages.mar": "Marathi", - "languages.mah": "Marshallese", - "languages.mon": "Mongolian", - "languages.nau": "Nauru", - "languages.nav": "Navajo", - "languages.nob": "Norwegian Bokmål", - "languages.nde": "North Ndebele", - "languages.nep": "Nepali", - "languages.ndo": "Ndonga", - "languages.nno": "Norwegian Nynorsk", - "languages.nor": "Norwegian", - "languages.iii": "Nuosu", - "languages.nbl": "South Ndebele", - "languages.oci": "Occitan", - "languages.oji": "Ojibwe", - "languages.chu": "Old Church Slavonic", - "languages.orm": "Oromo", - "languages.ori": "Oriya", - "languages.oss": "Ossetian", - "languages.pan": "Panjabi", - "languages.pli": "Pāli", - "languages.fas": "Persian", - "languages.pol": "Polish", - "languages.pus": "Pashto", - "languages.por": "Portuguese", - "languages.que": "Quechua", - "languages.roh": "Romansh", - "languages.run": "Kirundi", - "languages.ron": "Romanian", - "languages.rus": "Russian", - "languages.sam": "Samaritan Aramaic", - "languages.san": "Sanskrit", - "languages.srd": "Sardinian", - "languages.snd": "Sindhi", - "languages.sme": "Northern Sami", - "languages.smo": "Samoan", - "languages.sag": "Sango", - "languages.srp": "Serbian", - "languages.gla": "Scottish Gaelic", - "languages.sna": "Shona", - "languages.sin": "Sinhala", - "languages.slk": "Slovak", - "languages.slv": "Slovene", - "languages.som": "Somali", - "languages.sot": "Southern Sotho", - "languages.spa": "Spanish", - "languages.sun": "Sundanese", - "languages.sux": "Sumerian", - "languages.swa": "Swahili", - "languages.ssw": "Swati", - "languages.swe": "Swedish", - "languages.syc": "Classical Syriac", - "languages.syr": "Syriac", - "languages.tam": "Tamil", - "languages.tel": "Telugu", - "languages.tgk": "Tajik", - "languages.tha": "Thai", - "languages.tir": "Tigrinya", - "languages.bod": "Tibetan Standard", - "languages.tuk": "Turkmen", - "languages.tgl": "Tagalog", - "languages.tsn": "Tswana", - "languages.ton": "Tonga", - "languages.tur": "Turkish", - "languages.tso": "Tsonga", - "languages.tat": "Tatar", - "languages.twi": "Twi", - "languages.tah": "Tahitian", - "languages.uga": "Ugaritic", - "languages.uig": "Uighur", - "languages.ukr": "Ukrainian", - "languages.urd": "Urdu", - "languages.uzb": "Uzbek", - "languages.ven": "Venda", - "languages.vie": "Vietnamese", - "languages.vol": "Volapük", - "languages.win": "Walloon", - "languages.cym": "Welsh", - "languages.wol": "Wolof", - "languages.fry": "Western Frisian", - "languages.xho": "Xhosa", - "languages.yid": "Yiddish", - "languages.yor": "Yoruba", - "languages.zha": "Zhuang", - "languages.zul": "Zulu", - "DO_NOT_TRANSLATE": "end" -} diff --git a/COPS/cops-3.1.3/loader.php b/COPS/cops-3.1.3/loader.php deleted file mode 100644 index db0482a3..00000000 --- a/COPS/cops-3.1.3/loader.php +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - COPS - - - - - -
    -
    - - - -
    -
    - - diff --git a/COPS/cops-3.1.3/mike.php b/COPS/cops-3.1.3/mike.php deleted file mode 100644 index 83f15493..00000000 --- a/COPS/cops-3.1.3/mike.php +++ /dev/null @@ -1,3 +0,0 @@ - - * @author mikespub - * @deprecated 3.1.0 use index.php/opds instead - */ - -if (!class_exists('\Kiwilan\Opds\OpdsResponse')) { - echo 'This endpoint is an example for development only'; - return; -} - -$link = str_replace('opds.php', 'index.php/opds', $_SERVER['REQUEST_URI'] ?? ''); -header('Location: ' . $link); diff --git a/COPS/cops-3.1.3/package.json b/COPS/cops-3.1.3/package.json deleted file mode 100644 index ad4bdb07..00000000 --- a/COPS/cops-3.1.3/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "seblucas-cops", - "packageManager": "yarn@4.4.1", - "dependencies": { - "@mikespub/epubjs-reader": "^2024.4.23", - "bootstrap": "^3.4.1", - "corejs-typeahead": "^1.3.4", - "datatables.net": "^1.13.11", - "datatables.net-bs5": "^1.13.11", - "dot": "^1.1.3", - "graphql-playground-react": "^1.7.28", - "jquery": "^3.7.1", - "js-cookie": "^2.2.1", - "lru-fast": "^0.2.2", - "magnific-popup": "^1.2.0", - "normalize.css": "^8.0.1", - "swagger-ui-dist": "^5.17.14", - "twig": "^1.17.1" - }, - "license": "GPL-2.0-or-later" -} diff --git a/COPS/cops-3.1.3/phpstan-baseline.neon b/COPS/cops-3.1.3/phpstan-baseline.neon deleted file mode 100644 index ae97eae0..00000000 --- a/COPS/cops-3.1.3/phpstan-baseline.neon +++ /dev/null @@ -1,41 +0,0 @@ -parameters: - ignoreErrors: - - - message: "#^Static method SebLucas\\\\Cops\\\\Calibre\\\\Annotation\\:\\:forgetAboutConvertAnnotations\\(\\) is unused\\.$#" - count: 1 - path: src/Calibre/Annotation.php - - - - message: "#^Property SebLucas\\\\Cops\\\\Calibre\\\\CustomColumn\\:\\:\\$value \\(string\\) on left side of \\?\\? is not nullable\\.$#" - count: 1 - path: src/Calibre/CustomColumn.php - - - - message: "#^Call to an undefined method DOMNode\\:\\:getAttribute\\(\\)\\.$#" - count: 1 - path: src/Calibre/Metadata.php - - - - message: "#^Call to an undefined method DOMNode\\:\\:getElementsByTagName\\(\\)\\.$#" - count: 1 - path: src/Calibre/Metadata.php - - - - message: "#^Anonymous function has an unused use \\$request\\.$#" - count: 1 - path: src/Handlers/GraphQLHandler.php - - - - message: "#^Negated boolean expression is always false\\.$#" - count: 1 - path: src/Output/Format.php - - - - message: "#^Call to an undefined method SebLucas\\\\Cops\\\\Pages\\\\Page\\:\\:getContent\\(\\)\\.$#" - count: 1 - path: src/Output/JsonRenderer.php - - - - message: "#^Comparison operation \"\\>\" between 0 and 0 is always false\\.$#" - count: 1 - path: src/Output/JsonRenderer.php diff --git a/COPS/cops-3.1.3/phpstan.neon.dist b/COPS/cops-3.1.3/phpstan.neon.dist deleted file mode 100644 index d5ff2758..00000000 --- a/COPS/cops-3.1.3/phpstan.neon.dist +++ /dev/null @@ -1,15 +0,0 @@ -# baseline re-generated with level 4 to keep some issues visible on higher levels -# at the time this file was updated there are 2 errors reported for levels 4 to 6 -includes: - #- phpstan-baseline.neon - -parameters: - level: 6 - paths: - - . - bootstrapFiles: - - vendor/autoload.php - excludePaths: - - vendor/* - - tests/WebDriverTestCase.php - - tests/WebDriverTest.php diff --git a/COPS/cops-3.1.3/phpunit.xml.dist b/COPS/cops-3.1.3/phpunit.xml.dist deleted file mode 100644 index 8ecd24bf..00000000 --- a/COPS/cops-3.1.3/phpunit.xml.dist +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - ./tests/ - ./tests/WebDriverTest.php - - - - - ./ - - - ./resources - ./tests - ./vendor - ./config - - - diff --git a/COPS/cops-3.1.3/rector.php b/COPS/cops-3.1.3/rector.php deleted file mode 100644 index 879f6ebb..00000000 --- a/COPS/cops-3.1.3/rector.php +++ /dev/null @@ -1,40 +0,0 @@ -paths([ - //__DIR__ . '/test', - //__DIR__ . '/resources', - //__DIR__ . '/lib', - __DIR__, - ]); - - // register a single rule - //$rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class); - - $rectorConfig->skip([ - __DIR__ . '/vendor', - ClosureToArrowFunctionRector::class, - MixedTypeRector::class, - ClassPropertyAssignToConstructorPromotionRector::class, - ]); - - // define sets of rules - $rectorConfig->sets([ - LevelSetList::UP_TO_PHP_81, - //DowngradeLevelSetList::DOWN_TO_PHP_80, - //DowngradeLevelSetList::DOWN_TO_PHP_74, - PHPUnitSetList::PHPUNIT_100, - ]); -}; diff --git a/COPS/cops-3.1.3/resources/dot-php/LICENSE b/COPS/cops-3.1.3/resources/dot-php/LICENSE deleted file mode 100644 index 52df22e7..00000000 --- a/COPS/cops-3.1.3/resources/dot-php/LICENSE +++ /dev/null @@ -1,339 +0,0 @@ -GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - PHP rendering engine for doT.js (The fastest + concise javascript template engine for nodejs and browsers) - Copyright (C) 2013 Sébastien Lucas - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - {signature of Ty Coon}, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/COPS/cops-3.1.3/resources/dot-php/README.md b/COPS/cops-3.1.3/resources/dot-php/README.md deleted file mode 100644 index a31fe87b..00000000 --- a/COPS/cops-3.1.3/resources/dot-php/README.md +++ /dev/null @@ -1,41 +0,0 @@ -doT-php -======= - -PHP rendering engine for [doT.js (The fastest + concise javascript template engine for nodejs and browsers)](https://github.com/olado/doT). - - -How to use it -------------- - -```php -// Load the library -require_once('resources/doT-php/doT.php'); - -// Load the template -$page = file_get_contents('templates/page.html'); - -// instanciate the object -$template = new doT(); - -// Compile your templace in a PHP function ($dot) -$dot = $template->template($page); - -// the data is simple PHP array -$data = array('title' => 'My custom title'); - -// Write the HTML -echo $dot($data); -``` - - -Warning -------- - -It's far from complete. I needed it just to provide a server side rendering engine -for another project ([COPS](https://github.com/seblucas/cops)). - -So the code provided works perfectly for the templates of COPS and was never tested -elsewhere, doT's unit test were also never tested. - -That being said, You can fork, enhance it and send me some pull request, I'll -happily merge them. diff --git a/COPS/cops-3.1.3/resources/dot-php/composer.json b/COPS/cops-3.1.3/resources/dot-php/composer.json deleted file mode 100644 index 30afa926..00000000 --- a/COPS/cops-3.1.3/resources/dot-php/composer.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "seblucas/dot-php", - "type": "library", - "description": "PHP rendering engine for doT.js (The fastest + concise javascript template engine for nodejs and browsers)", - "keywords": ["doT", "template", "engine", "rendering"], - "homepage": "https://github.com/seblucas/doT-php", - "license": "GPL-2.0-or-later", - "authors": [ - { - "name": "Sébastien Lucas", - "email": "sebastien@slucas.fr", - "homepage": "http://www.slucas.fr/", - "role": "Developer" - } - ], - "require": { - "php": ">=5.3.0" - }, - "autoload": { - "classmap": ["doT.php"] - } -} diff --git a/COPS/cops-3.1.3/resources/dot-php/doT.php b/COPS/cops-3.1.3/resources/dot-php/doT.php deleted file mode 100644 index b856cdda..00000000 --- a/COPS/cops-3.1.3/resources/dot-php/doT.php +++ /dev/null @@ -1,146 +0,0 @@ - - */ - -namespace SebLucas\Template; - -class doT -{ - public string $functionBody; - /** @var callable */ - protected $functionCode; - /** @var array */ - public $def; - - /** - * Summary of resolveDefs - * @param ?string $block - * @return ?string - */ - public function resolveDefs($block) - { - $me = $this; - return preg_replace_callback("/\{\{#([\s\S]+?)\}\}/", function ($m) use ($me) { - $d = $m[1]; - $d = substr($d, 4); - if (!array_key_exists($d, $me->def)) { - return ""; - } - if (preg_match("/\{\{#([\s\S]+?)\}\}/", (string) $me->def [$d])) { - //return $me->resolveDefs($me->def [$d], $me->def); - return $me->resolveDefs($me->def [$d]); - } else { - return $me->def [$d]; - } - }, $block); - } - - /** - * Summary of handleDotNotation - * @param string $string - * @return ?string - */ - public function handleDotNotation($string) - { - $out = preg_replace("/(\w+)\.(.*?)([\s,\)])/", "\$$1[\"$2\"]$3", $string); - $out = preg_replace("/(\w+)\.([\w\.]*?)$/", "\$$1[\"$2\"] ", $out); - $out = preg_replace("/\./", '"]["', $out); - - // Special hideous case : shouldn't be committed - $out = preg_replace("/^i /", ' $i ', $out); - return $out; - } - - /** - * Summary of template - * @param string $string - * @param ?array $def - * @return \Closure - */ - public function template($string, $def) - { - $me = $this; - - $func = $string; - - // deps - if (empty($def)) { - $func = preg_replace("/\{\{#([\s\S]+?)\}\}/", "", $func); - } else { - $this->def = $def; - $func = $this->resolveDefs($func); - } - - // single quotes can mess up serverside rendering for client-side javascript, e.g. in header template: - // ["'", '\/'], - "encode" => ['~QUOTE~', '~SLASH~'], - ]; - $func = str_replace($replace["unsafe"], $replace["encode"], $func); - - // interpolate - $func = preg_replace_callback("/\{\{=([\s\S]+?)\}\}/", function ($m) use ($me) { - return "' . " . $me->handleDotNotation($m[1]) . " . '"; - }, $func); - // Conditional - $func = preg_replace_callback("/\{\{\?(\?)?\s*([\s\S]*?)\s*\}\}/", function ($m) use ($me) { - $elsecase = $m[1]; - $code = $m[2]; - if ($elsecase) { - if ($code) { - return "';} else if (" . $me->handleDotNotation($code) . ") { $" . "out.='"; - } else { - return "';} else { $" . "out.='"; - } - } else { - if ($code) { - return "'; if (" . $me->handleDotNotation($code) . ") { $" . "out.='"; - } else { - return "';} $" . "out.='"; - } - } - }, $func); - // Iterate - $func = preg_replace_callback("/\{\{~\s*(?:\}\}|([\s\S]+?)\s*\:\s*([\w$]+)\s*(?:\:\s*([\w$]+))?\s*\}\})/", function ($m) use ($me) { - if (count($m) > 1) { - $iterate = $m[1]; - $vname = $m[2]; - $iname = $m[3]; - $iterate = $me->handleDotNotation($iterate); - return "'; for (\$$iname = 0; \$$iname < count($iterate); \$$iname++) { \$$vname = $iterate [\$$iname]; \$out.='"; - } else { - return "';} $" . "out.='"; - } - }, $func); - $func = '$out = \'' . $func . '\'; return $out;'; - - $this->functionBody = $func; - - return function ($it) use ($func, $replace) { - try { - return str_replace($replace["encode"], $replace["unsafe"], eval($func)); - } catch (\Throwable $e) { - return $e->getMessage() . ' in ' . $func; - } - }; - } - - /** - * Summary of execute - * @param mixed $data - * @return mixed - */ - public function execute($data) - { - try { - return ($this->functionCode)($data); - } catch (\Throwable $e) { - return $e->getMessage(); - } - } -} diff --git a/COPS/cops-3.1.3/resources/monocle/README.md b/COPS/cops-3.1.3/resources/monocle/README.md deleted file mode 100644 index 34a3771d..00000000 --- a/COPS/cops-3.1.3/resources/monocle/README.md +++ /dev/null @@ -1,150 +0,0 @@ -# Monocle - -A silky, tactile browser-based ebook reader. - -Initial development by Joseph Pearson of Inventive Labs. Released under the -MIT license. - -____________________________________________________________________________ -THIS PROJECT IS NOW OVER EIGHT YEARS OLD. -IT HAS NOT BEEN ACTIVELY MAINTAINED SINCE 2015. -You are welcome to explore and learn from the code, but it is no longer the -best approach for modern browsers and devices, and it is not recommended for -new projects or production applications. -____________________________________________________________________________ - - -## Getting Monocle - -There's a few different ways to get Monocle. The easiest way to explore -it is from the test site, which is always running the latest `master`: - -http://test.monoclejs.com/test - -To grab the code for your own use, see: - -https://github.com/joseph/Monocle/wiki/Getting-Monocle-running - -The scripts and stylesheets are separated into: - -* `monocore` - the essential Monocle functionality -* `monoctrl` - the optional basic controls for page numbers, font-sizing, etc - - -## Integrating Monocle - -Here's the simplest thing that could possibly work. - - - - - - - - - - -
    -

    Hello world.

    -
    - - - - - - -In this example, we initialise the reader with the contents of the div -itself. In theory there's no limit on the size of the contents of that div. - -A more advanced scenario involves feeding Monocle a "book data object", from -which it can lazily load the contents of the book as the user requests it. - - -## Connecting Monocle to your book content - -For a non-trivial Monocle implementation, your task is to connect the -Monocle Reader to your book's HTML content and structure. You create -something called "the book data object" to do this. - -The book data object is really pretty simple. You'll find the specification -and some examples in the [Monocle Wiki page on the book data object](https://github.com/joseph/Monocle/wiki/Book-data-object). - -For more advanced uses and customisations of Monocle, you should definitely -read the [Monocle Wiki](https://github.com/joseph/Monocle/wiki). - - -## Browser support - -At this time, Monocle aims for full support of all browsers with a -W3C-compliant CSS column module implementation. That is Gecko, WebKit and -Opera at this point. Please encourage your browser-maker to work on -implementing these standards in particular: - -* CSS Multi-Column Layout -* W3C DOM Level 2 Event Model -* CSS 2D Transforms (better: 3D Transforms, even better: hardware acceleration) - -Monocle has a particular focus on mobile devices. Monocle supports: - -* iOS 4.2+ -* Android 2.2+ -* Kindle 3 - -All these mobile platforms implement columned iframes differently, so support -may be imperfect in places, but we're working on it. Patches that improve or -broaden Monocle's browser support are very welcome (but please provide tests). - -Inventive Labs would like to thank Ebooq for providing a device to assist with -Android testing. - - -## Future directions - -Monocle has a small set of big goals: - -* Faster, more responsive page flipping -* Wider browser support (and better tests, automated as far as possible) -* Tracking spec developments in EPUB and Zhook, supporting where appropriate - -We'd also like to provide more implementation showcases in the tests, and -offer more developer documentation in the wiki. - -If you can help out with any of these things, fork away (or create an issue -on GitHub). - - -## History - -3.2.0 - A new event management subsystem, called Gala, replacing the old - Monocle.Events. Gala unifies touch and mouse event registration - a lot better. It also works as a standalone library, if you need that - - there are no dependencies on other parts of Monocle. - -3.1.0 - Numerous stability fixes, plus improvements for Android and Opera, - including minor API changes to flippers and slow-browser detection. - -3.0.1 - Bugfixes for component loading, cancelling magic panel contacts. - -3.0.0 - Magic panel, IE10 support, iOS6 support, better Android support, - selection events, billboard feature, Monocle.Formatting to clean up - Reader, removing deprecated flippers, Stencil refactor, component - weights (for more accurate component percentages), and many bug - fixes. See https://github.com/joseph/Monocle/compare/v2.3.1...v3.0.0 - -2.3.1 - Fix for serious Firefox 12 bug in paginating content. - -2.3.0 - Smoother transitions and animations in more browsers. - -2.2.1 - Slider fixes for better iOS performance. - -2.2.0 - Speed, compatibility improvements (esp iOS5, Android, Kindle3). - -2.1.0 - Source file reorganisation, Sprockets 2, distributables, wiki. - -2.0.0 - Complete rewrite to sandbox content in iframes (the Componentry branch). - -1.0.1 - Scrolling flipper, more tests, work on sandboxing in iframe (Framer). - -1.0.0 - Initial release. diff --git a/COPS/cops-3.1.3/resources/monocle/scripts/monocore.js b/COPS/cops-3.1.3/resources/monocle/scripts/monocore.js deleted file mode 100644 index ae8b6453..00000000 --- a/COPS/cops-3.1.3/resources/monocle/scripts/monocore.js +++ /dev/null @@ -1,5641 +0,0 @@ -/*! - * Monocle - A silky, tactile browser-based ebook JavaScript library. - * - * Copyright 2012, Joseph Pearson - * Licensed under the MIT license. - */ - - -Monocle = { - VERSION: "3.2.0" -}; - - -Monocle.Dimensions = {}; -Monocle.Controls = {}; -Monocle.Flippers = {}; -Monocle.Panels = {}; -// A class that tests the browser environment for required capabilities and -// known bugs (for which we have workarounds). -// -Monocle.Env = function () { - - var API = { constructor: Monocle.Env } - var k = API.constants = API.constructor; - var p = API.properties = { - // Assign to a function before running survey in order to get - // results as they come in. The function should take two arguments: - // testName and value. - resultCallback: null - } - - // These are private variables so they don't clutter up properties. - var css = Monocle.Browser.css; - var activeTestName = null; - var frameLoadCallback = null; - var testFrame = null; - var testFrameCntr = null; - var testFrameSize = 100; - var surveyCallback = null; - - - function survey(cb) { - surveyCallback = cb; - runNextTest(); - } - - - function runNextTest() { - var test = envTests.shift(); - if (!test) { return completed(); } - activeTestName = test[0]; - try { test[1](); } catch (e) { result(e); } - } - - - // Each test should call this to say "I'm finished, run the next test." - // - function result(val) { - API[activeTestName] = val; - if (p.resultCallback) { p.resultCallback(activeTestName, val); } - runNextTest(); - return val; - } - - - // Invoked after all tests have run. - // - function completed() { - // Remove the test frame after a slight delay (otherwise Gecko spins). - Monocle.defer(removeTestFrame); - - if (typeof surveyCallback == "function") { - fn = surveyCallback; - surveyCallback = null; - fn(API); - } - } - - - // A bit of sugar for simplifying a detection pattern: does this - // function exist? - // - // Pass a string snippet of JavaScript to be evaluated. - // - function testForFunction(str) { - return function () { result(typeof eval(str) == "function"); } - } - - - // A bit of sugar to indicate that the detection function for this test - // hasn't been written yet... - // - // Pass the value you want assigned for the test until it is implemented. - // - function testNotYetImplemented(rslt) { - return function () { result(rslt); } - } - - - // Loads (or reloads) a hidden iframe so that we can test browser features. - // - // cb is the callback that is fired when the test frame's content is loaded. - // - // src is optional, in which case it defaults to 4. If provided, it can be - // a number (specifying the number of pages of default content), or a string, - // which will be loaded as a URL. - // - function loadTestFrame(cb, src) { - if (!testFrame) { testFrame = createTestFrame(); } - frameLoadCallback = cb; - - src = src || 4; - - if (typeof src == "number") { - var pgs = []; - for (var i = 1, ii = src; i <= ii; ++i) { - pgs.push("
    Page "+i+"
    "); - } - var divStyle = [ - "display:inline-block", - "line-height:"+testFrameSize+"px", - "width:"+testFrameSize+"px" - ].join(";"); - src = "javascript:'"+ - ''+ - ''+ - ''+pgs.join("")+''+ - "'"; - } - - testFrame.src = src; - } - - - // Creates the hidden test frame and returns it. - // - function createTestFrame() { - testFrameCntr = document.createElement('div'); - testFrameCntr.style.cssText = [ - "width:"+testFrameSize+"px", - "height:"+testFrameSize+"px", - "overflow:hidden", - "position:absolute", - "visibility:hidden" - ].join(";"); - document.body.appendChild(testFrameCntr); - - var fr = document.createElement('iframe'); - testFrameCntr.appendChild(fr); - fr.setAttribute("scrolling", "no"); - fr.style.cssText = [ - "width:100%", - "height:100%", - "border:none", - "background:#900" - ].join(";"); - fr.addEventListener( - "load", - function () { - if (!fr.contentDocument || !fr.contentDocument.body) { return; } - var bd = fr.contentDocument.body; - bd.style.cssText = ([ - "margin:0", - "padding:0", - "position:absolute", - "height:100%", - "width:100%", - "-webkit-column-width:"+testFrameSize+"px", - "-webkit-column-gap:0", - "-webkit-column-fill:auto", - "-moz-column-width:"+testFrameSize+"px", - "-moz-column-gap:0", - "-moz-column-fill:auto", - "-o-column-width:"+testFrameSize+"px", - "-o-column-gap:0", - "-o-column-fill:auto", - "column-width:"+testFrameSize+"px", - "column-gap:0", - "column-fill:auto" - ].join(";")); - if (bd.scrollHeight > testFrameSize) { - bd.style.cssText += ["min-width:200%", "overflow:hidden"].join(";"); - if (bd.scrollHeight <= testFrameSize) { - bd.className = "column-force"; - } else { - bd.className = "column-failed "+bd.scrollHeight; - } - } - frameLoadCallback(fr); - }, - false - ); - return fr; - } - - - function removeTestFrame() { - if (testFrameCntr && testFrameCntr.parentNode) { - testFrameCntr.parentNode.removeChild(testFrameCntr); - } - } - - - function columnedWidth(fr) { - var bd = fr.contentDocument.body; - var de = fr.contentDocument.documentElement; - return Math.max(bd.scrollWidth, de.scrollWidth); - } - - - var envTests = [ - - // TEST FOR REQUIRED CAPABILITIES - - ["supportsW3CEvents", testForFunction("window.addEventListener")], - ["supportsCustomEvents", testForFunction("document.createEvent")], - ["supportsColumns", function () { - result(css.supportsPropertyWithAnyPrefix('column-width')); - }], - ["supportsTransform", function () { - result(css.supportsProperty([ - 'transformProperty', - 'WebkitTransform', - 'MozTransform', - 'OTransform', - 'msTransform' - ])); - }], - - - // TEST FOR OPTIONAL CAPABILITIES - - // Does it do CSS transitions? - ["supportsTransition", function () { - result(css.supportsPropertyWithAnyPrefix('transition')) - }], - - // Can we find nodes in a document with an XPath? - // - ["supportsXPath", testForFunction("document.evaluate")], - - // Can we find nodes in a document natively with a CSS selector? - // - ["supportsQuerySelector", testForFunction("document.querySelector")], - - // Can we do 3d transforms? - // - ["supportsTransform3d", function () { - result( - css.supportsMediaQueryProperty('transform-3d') && - css.supportsProperty([ - 'perspectiveProperty', - 'WebkitPerspective', - 'MozPerspective', - 'OPerspective', - 'msPerspective' - ]) && - !Monocle.Browser.renders.slow // Some older browsers can't be trusted. - ); - }], - - - // Commonly-used browser functionality - ["supportsOfflineCache", function () { - result(typeof window.applicationCache != 'undefined'); - }], - - ["supportsLocalStorage", function () { - // NB: Some duplicitous early Android browsers claim to have - // localStorage, but calls to getItem() fail. - result( - typeof window.localStorage != "undefined" && - typeof window.localStorage.getItem == "function" - ) - }], - - - // CHECK OUT OUR CONTEXT - - // Does the device have a MobileSafari-style touch interface? - // - ["touch", function () { - result( - ('ontouchstart' in window) || - css.supportsMediaQueryProperty('touch-enabled') - ); - }], - - // Is the Reader embedded, or in the top-level window? - // - ["embedded", function () { result(top != self) }], - - - // TEST FOR CERTAIN RENDERING OR INTERACTION BUGS - - // iOS (at least up to version 4.1) makes a complete hash of touch events - // when an iframe is overlapped by other elements. It's a dog's breakfast. - // See test/bugs/ios-frame-touch-bug for details. - // - ["brokenIframeTouchModel", function () { - result(Monocle.Browser.iOSVersionBelow("4.2")); - }], - - // Webkit-based browsers put floated elements in the wrong spot when - // columns are used -- they appear way down where they would be if there - // were no columns. Presumably the float positions are calculated before - // the columns. A bug has been lodged, and it's fixed in recent WebKits. - // - ["floatsIgnoreColumns", function () { - if (!Monocle.Browser.is.WebKit) { return result(false); } - match = navigator.userAgent.match(/AppleWebKit\/([\d\.]+)/); - if (!match) { return result(false); } - return result(match[1] < "534.30"); - }], - - // The latest engines all agree that if a body is translated leftwards, - // its scrollWidth is shortened. But some older WebKits (notably iOS4) - // do not subtract translateX values from scrollWidth. In this case, - // we should not add the translate back when calculating the width. - // - ["widthsIgnoreTranslate", function () { - loadTestFrame(function (fr) { - var firstWidth = columnedWidth(fr); - var s = fr.contentDocument.body.style; - var props = css.toDOMProps("transform"); - for (var i = 0, ii = props.length; i < ii; ++i) { - s[props[i]] = "translateX(-600px)"; - } - var secondWidth = columnedWidth(fr); - for (i = 0, ii = props.length; i < ii; ++i) { - s[props[i]] = "none"; - } - result(secondWidth == firstWidth); - }); - }], - - // On Android browsers, if the component iframe has a relative width (ie, - // 100%), the width of the entire browser will keep expanding and expanding - // to fit the width of the body of the iframe (which, with columns, is - // massive). So, 100% is treated as "of the body content" rather than "of - // the parent dimensions". In this scenario, we need to give the component - // iframe a fixed width in pixels. - // - // In iOS, the frame is clipped by overflow:hidden, so this doesn't seem to - // be a problem. - // - ["relativeIframeExpands", function () { - result(navigator.userAgent.indexOf("Android 2") >= 0); - }], - - // iOS3 will pause JavaScript execution if it gets a style-change + a - // scroll change on a component body. Weirdly, this seems to break GBCR - // in iOS4. - // - ["scrollToApplyStyle", function () { - result(Monocle.Browser.iOSVersionBelow("4")); - }], - - - // TEST FOR OTHER QUIRKY BROWSER BEHAVIOUR - - // Older versions of WebKit (iOS3, Kindle3) need a min-width set on the - // body of the iframe at 200%. This forces columns. But when this - // min-width is set, it's more difficult to recognise 1 page components, - // so we generally don't want to force it unless we have to. - // - ["forceColumns", function () { - loadTestFrame(function (fr) { - var bd = fr.contentDocument.body; - result(bd.className ? true : false); - }); - }], - - // A component iframe's body is absolutely positioned. This means that - // the documentElement should have a height of 0, since it contains nothing - // other than an absolutely positioned element. - // - // But for some browsers (Gecko and Opera), the documentElement is as - // wide as the full columned content, and the body is only as wide as - // the iframe element (ie, the first column). - // - // It gets weirder. Gecko sometimes behaves like WebKit (not clipping the - // body) IF the component has been loaded via HTML/JS/Nodes, not URL. Still - // can't reproduce outside Monocle. - // - // FIXME: If we can figure out a reliable behaviour for Gecko, we should - // use it to precalculate the workaround. At the moment, this test isn't - // used, but it belongs in src/dimensions/columns.js#columnedDimensions(). - // - // ["iframeBodyWidthClipped", function () { - // loadTestFrame(function (fr) { - // var doc = fr.contentDocument; - // result( - // doc.body.scrollWidth <= testFrameSize && - // doc.documentElement.scrollWidth > testFrameSize - // ); - // }) - // }], - - // Finding the page that a given HTML node is on is typically done by - // calculating the offset of its rectange from the body's rectangle. - // - // But if this information isn't provided by the browser, we need to use - // node.scrollIntoView and check the scrollOffset. Basically iOS3 is the - // only target platform that doesn't give us the rectangle info. - // - ["findNodesByScrolling", function () { - result(typeof document.body.getBoundingClientRect !== "function"); - }], - - // In MobileSafari browsers, iframes are rendered at the width and height - // of their content, rather than having scrollbars. So in that case, it's - // the containing element (the "sheaf") that must be scrolled, not the - // iframe body. - // - ["sheafIsScroller", function () { - loadTestFrame(function (fr) { - result(fr.parentNode.scrollWidth > testFrameSize); - }); - }], - - // For some reason, iOS MobileSafari sometimes loses track of a page after - // slideOut -- it thinks it has an x-translation of 0, rather than -768 or - // whatever. So the page gets "stuck" there, until it is given a non-zero - // x-translation. The workaround is to set a non-zero duration on the jumpIn, - // which seems to force WebKit to recalculate the x of the page. Weird, yeah. - // - ["stickySlideOut", function () { - result(Monocle.Browser.is.MobileSafari); - }], - - - // Chrome and Firefox incorrectly clip text when the dimensions of - // a page are not an integer. IE10 clips text when the page dimensions - // are rounded. - // - ['roundPageDimensions', function () { - result(!Monocle.Browser.is.IE); - }], - - - - // In IE10, the element of the iframe's document has scrollbars, - // unless you set its style.overflow to 'hidden'. - // - ['documentElementHasScrollbars', function () { - result(Monocle.Browser.is.IE); - }], - - - // Older versions of iOS (<6) would render blank pages if they were - // off the screen when their layout/position was updated. - // - ['offscreenRenderingClipped', function () { - result(Monocle.Browser.iOSVersionBelow('6')); - }], - - - // Gecko is better at loading content with document.write than with - // javascript: URLs. With the latter, it tends to put cruft in history, - // and gets confused by . - ['loadHTMLWithDocWrite', function () { - result(Monocle.Browser.is.Gecko || Monocle.Browser.is.Opera); - }] - - ]; - - - function isCompatible() { - return ( - API.supportsW3CEvents && - API.supportsCustomEvents && - API.supportsColumns && - API.supportsTransform && - !API.brokenIframeTouchModel - ); - } - - - API.survey = survey; - API.isCompatible = isCompatible; - - return API; -} -; -// A class for manipulating CSS properties in a browser-engine-aware way. -// -Monocle.CSS = function () { - - var API = { constructor: Monocle.CSS } - var k = API.constants = API.constructor; - var p = API.properties = { - guineapig: document.createElement('div') - } - - - // Returns engine-specific properties, - // - // eg: - // - // toCSSProps('transform') - // - // ... in WebKit, this will return: - // - // ['transform', '-webkit-transform'] - // - function toCSSProps(prop) { - var props = [prop]; - var eng = k.engines.indexOf(Monocle.Browser.engine); - if (eng) { - var pf = k.prefixes[eng]; - if (pf) { - props.push(pf+prop); - } - } - return props; - } - - - // Returns an engine-specific CSS string. - // - // eg: - // - // toCSSDeclaration('column-width', '300px') - // - // ... in Mozilla, this will return: - // - // "column-width: 300px; -moz-column-width: 300px;" - // - function toCSSDeclaration(prop, val) { - var props = toCSSProps(prop); - for (var i = 0, ii = props.length; i < ii; ++i) { - props[i] += ": "+val+";"; - } - return props.join(""); - } - - - // Returns an array of DOM properties specific to this engine. - // - // eg: - // - // toDOMProps('column-width') - // - // ... in Opera, this will return: - // - // [columnWidth, OColumnWidth] - // - function toDOMProps(prop) { - var parts = prop.split('-'); - for (var i = parts.length; i > 0; --i) { - parts[i] = capStr(parts[i]); - } - - var props = [parts.join('')]; - var eng = k.engines.indexOf(Monocle.Browser.engine); - if (eng) { - var pf = k.domprefixes[eng]; - if (pf) { - parts[0] = capStr(parts[0]); - props.push(pf+parts.join('')); - } - } - return props; - } - - - // Is this exact property (or any in this array of properties) supported - // by this engine? - // - function supportsProperty(props) { - for (var i in props) { - if (p.guineapig.style[props[i]] !== undefined) { return true; } - } - return false; - } // Thanks modernizr! - - - - // Is this property (or a prefixed variant) supported by this engine? - // - function supportsPropertyWithAnyPrefix(prop) { - return supportsProperty(toDOMProps(prop)); - } - - - function supportsMediaQuery(query) { - var gpid = "monocle_guineapig"; - p.guineapig.id = gpid; - var st = document.createElement('style'); - st.textContent = query+'{#'+gpid+'{height:3px}}'; - (document.head || document.getElementsByTagName('head')[0]).appendChild(st); - document.documentElement.appendChild(p.guineapig); - - var result = p.guineapig.offsetHeight === 3; - - st.parentNode.removeChild(st); - p.guineapig.parentNode.removeChild(p.guineapig); - - return result; - } // Thanks modernizr! - - - function supportsMediaQueryProperty(prop) { - return supportsMediaQuery( - '@media (' + k.prefixes.join(prop+'),(') + 'monocle__)' - ); - } - - - function capStr(wd) { - return wd ? wd.charAt(0).toUpperCase() + wd.substr(1) : ""; - } - - - API.toCSSProps = toCSSProps; - API.toCSSDeclaration = toCSSDeclaration; - API.toDOMProps = toDOMProps; - API.supportsProperty = supportsProperty; - API.supportsPropertyWithAnyPrefix = supportsPropertyWithAnyPrefix; - API.supportsMediaQuery = supportsMediaQuery; - API.supportsMediaQueryProperty = supportsMediaQueryProperty; - - return API; -} - - -Monocle.CSS.engines = ["W3C", "WebKit", "Gecko", "Opera", "IE", "Konqueror"]; -Monocle.CSS.prefixes = ["", "-webkit-", "-moz-", "-o-", "-ms-", "-khtml-"]; -Monocle.CSS.domprefixes = ["", "Webkit", "Moz", "O", "ms", "Khtml"]; -// STUBS - simple debug functions and polyfills to normalise client -// execution environments. - - -// A little console stub if not initialized in a console-equipped browser. -// -if (typeof window.console == "undefined") { - window.console = { messages: [] } - window.console.log = function (msg) { - this.messages.push(msg); - } - window.console.warn = window.console.log; -} - - -// A simple version of console.dir that works on iOS. -// -window.console.compatDir = function (obj) { - var stringify = function (o) { - var parts = []; - for (x in o) { - parts.push(x + ": " + o[x]); - } - return parts.join(";\n"); - } - - var out = stringify(obj); - window.console.log(out); - return out; -} - - -// This is called by Monocle methods and practices that are no longer -// recommended and will soon be removed. -// -window.console.deprecation = function (msg) { - console.warn("[DEPRECATION]: "+msg); - if (typeof console.trace == "function") { - console.trace(); - } -} - - -// A convenient alias for setTimeout that assumes 0 if no timeout is specified. -// -Monocle.defer = function (fn, time) { - if (typeof fn == "function") { - return setTimeout(fn, time || 0); - } -} -; -Monocle.Browser = {}; - -// Compare the user-agent string to a string or regex pattern. -// -Monocle.Browser.uaMatch = function (test) { - var ua = navigator.userAgent; - if (typeof test == "string") { return ua.indexOf(test) >= 0; } - return !!ua.match(test); -} - - -// Detect the browser engine and set boolean flags for reference. -// -Monocle.Browser.is = { - IE: !!(window.attachEvent && !Monocle.Browser.uaMatch('Opera')), - Opera: Monocle.Browser.uaMatch('Opera'), - WebKit: Monocle.Browser.uaMatch(/Apple\s?WebKit/), - Gecko: Monocle.Browser.uaMatch('Gecko') && !Monocle.Browser.uaMatch('KHTML'), - MobileSafari: Monocle.Browser.uaMatch(/OS \d_.*AppleWebKit.*Mobile/) -} - - -// Set the browser engine string. -// -if (Monocle.Browser.is.IE) { - Monocle.Browser.engine = "IE"; -} else if (Monocle.Browser.is.Opera) { - Monocle.Browser.engine = "Opera"; -} else if (Monocle.Browser.is.WebKit) { - Monocle.Browser.engine = "WebKit"; -} else if (Monocle.Browser.is.Gecko) { - Monocle.Browser.engine = "Gecko"; -} else { - console.warn("Unknown engine; assuming W3C compliant."); - Monocle.Browser.engine = "W3C"; -} - - -// Detect the client platform (typically device/operating system). -// -Monocle.Browser.on = { - iPhone: Monocle.Browser.is.MobileSafari && screen.width == 320, - iPad: Monocle.Browser.is.MobileSafari && screen.width == 768, - UIWebView: ( - Monocle.Browser.is.MobileSafari && - !Monocle.Browser.uaMatch('Safari') && - !navigator.standalone - ), - BlackBerry: Monocle.Browser.uaMatch('BlackBerry'), - Android: ( - Monocle.Browser.uaMatch('Android') || - Monocle.Browser.uaMatch(/Linux;.*EBRD/) // Sony Readers - ), - MacOSX: ( - Monocle.Browser.uaMatch('Mac OS X') && - !Monocle.Browser.is.MobileSafari - ), - Kindle3: Monocle.Browser.uaMatch(/Kindle\/3/) -} - - -// It is only because MobileSafari is responsible for so much anguish that -// we special-case it here. Not a badge of honour. -// -if (Monocle.Browser.is.MobileSafari) { - (function () { - var ver = navigator.userAgent.match(/ OS ([\d_]+)/); - if (ver) { - Monocle.Browser.iOSVersion = ver[1].replace(/_/g, '.'); - } else { - console.warn("Unknown MobileSafari user agent: "+navigator.userAgent); - } - })(); -} -Monocle.Browser.iOSVersionBelow = function (strOrNum) { - return !!Monocle.Browser.iOSVersion && Monocle.Browser.iOSVersion < strOrNum; -} - - -// Some browser environments are too slow or too problematic for -// special animation effects. -// -// FIXME: These tests are too opinionated. Replace with more targeted tests. -// -Monocle.Browser.renders = (function () { - var ua = navigator.userAgent; - var caps = {}; - caps.eInk = Monocle.Browser.on.Kindle3; - caps.slow = ( - caps.eInk || - (Monocle.Browser.on.Android && !ua.match(/Chrome/)) || - Monocle.Browser.on.Blackberry || - ua.match(/NintendoBrowser/) - ); - return caps; -})(); - - -// A helper class for sniffing CSS features and creating CSS rules -// appropriate to the current rendering engine. -// -Monocle.Browser.css = new Monocle.CSS(); - - -// During Reader initialization, this method is called to create the -// "environment", which tests for the existence of various browser -// features and bugs, then invokes the callback to continue initialization. -// -// If the survey has already been conducted and the env exists, calls -// callback immediately. -// -Monocle.Browser.survey = function (callback) { - if (!Monocle.Browser.env) { - Monocle.Browser.env = new Monocle.Env(); - Monocle.Browser.env.survey(callback); - } else if (typeof callback == "function") { - callback(); - } -} -; -Gala = {} - - -// Register an event listener. -// -Gala.listen = function (elem, evtType, fn, useCapture) { - elem = Gala.$(elem); - if (elem.addEventListener) { - elem.addEventListener(evtType, fn, useCapture || false); - } else if (elem.attachEvent) { - if (evtType.indexOf(':') < 1) { - elem.attachEvent('on'+evtType, fn); - } else { - var h = (Gala.IE_REGISTRATIONS[elem] = Gala.IE_REGISTRATIONS[elem] || {}); - var a = (h[evtType] = h[evtType] || []); - a.push(fn); - } - } -} - - -// Remove an event listener. -// -Gala.deafen = function (elem, evtType, fn, useCapture) { - elem = Gala.$(elem); - if (elem.removeEventListener) { - elem.removeEventListener(evtType, fn, useCapture || false); - } else if (elem.detachEvent) { - if (evtType.indexOf(':') < 1) { - elem.detachEvent('on'+evtType, fn); - } else { - var h = (Gala.IE_REGISTRATIONS[elem] = Gala.IE_REGISTRATIONS[elem] || {}); - var a = (h[evtType] = h[evtType] || []); - for (var i = 0, ii = a.length; i < ii; ++i) { - if (a[i] == fn) { a.splice(i, 1); } - } - } - } -} - - -// Fire an event on the element. -// -// The data supplied to this function will be available in the event object in -// the 'm' property -- eg, alert(evt.m) --> 'foo' -// -Gala.dispatch = function (elem, evtType, data, cancelable) { - elem = Gala.$(elem); - if (elem.dispatchEvent) { - var evt = document.createEvent('Events'); - evt.initEvent(evtType, false, cancelable || false); - evt.m = data; - return elem.dispatchEvent(evt); - } else if (elem.attachEvent && evtType.indexOf(':') >= 0) { - if (!Gala.IE_REGISTRATIONS[elem]) { return true; } - var evtHandlers = Gala.IE_REGISTRATIONS[elem][evtType]; - if (!evtHandlers || evtHandlers.length < 1) { return true; } - var evt = { - type: evtType, - currentTarget: elem, - target: elem, - m: data, - defaultPrevented: false, - preventDefault: function () { evt.defaultPrevented = true; } - } - var q, processQueue = Gala.IE_INVOCATION_QUEUE.length == 0; - for (var i = 0, ii = evtHandlers.length; i < ii; ++i) { - q = { elem: elem, evtType: evtType, handler: evtHandlers[i], evt: evt } - Gala.IE_INVOCATION_QUEUE.push(q); - } - if (processQueue) { - while (q = Gala.IE_INVOCATION_QUEUE.shift()) { - //console.log("IE EVT on %s: '%s' with data: %s", q.elem, q.evtType, q.evt.m); - q.handler(q.evt); - } - } - return !(cancelable && evt.defaultPrevented); - } else { - console.warn('[GALA] Cannot dispatch non-namespaced events: '+evtType); - return true; - } -} - - -// Prevents the browser-default action on an event and stops it from -// propagating up the DOM tree. -// -Gala.stop = function (evt) { - evt = evt || window.event; - if (evt.preventDefault) { evt.preventDefault(); } - if (evt.stopPropagation) { evt.stopPropagation(); } - evt.returnValue = false; - evt.cancelBubble = true; - return false; -} - - -// Add a group of listeners, which is just a hash of { evtType: callback, ... } -// -Gala.listenGroup = function (elem, listeners, useCapture) { - for (evtType in listeners) { - Gala.listen(elem, evtType, listeners[evtType], useCapture || false); - } -} - - -// Remove a group of listeners. -// -Gala.deafenGroup = function (elem, listeners, useCapture) { - for (evtType in listeners) { - Gala.deafen(elem, evtType, listeners[evtType], useCapture || false); - } -} - - -// Replace a group of listeners with another group, re-using the same -// 'listeners' object -- a common pattern. -// -Gala.replaceGroup = function (elem, listeners, newListeners, useCapture) { - Gala.deafenGroup(elem, listeners, useCapture || false); - for (evtType in listeners) { delete listeners[evtType]; } - for (evtType in newListeners) { listeners[evtType] = newListeners[evtType]; } - Gala.listenGroup(elem, listeners, useCapture || false); - return listeners; -} - - -// Listen for a tap or a click event. -// -// Returns a 'listener' object that can be passed to Gala.deafenGroup(). -// -// If 'tapClass' is undefined, it defaults to 'tapping'. If it is a blank -// string, no class is assigned. -// -Gala.onTap = function (elem, fn, tapClass) { - elem = Gala.$(elem); - if (typeof tapClass == 'undefined') { tapClass = Gala.TAPPING_CLASS; } - var tapping = false; - var fns = { - start: function (evt) { - tapping = true; - if (tapClass) { elem.classList.add(tapClass); } - }, - move: function (evt) { - if (!tapping) { return; } - tapping = false; - if (tapClass) { elem.classList.remove(tapClass); } - }, - end: function (evt) { - if (!tapping) { return; } - fns.move(evt); - evt.currentTarget = evt.currentTarget || evt.srcElement; - fn(evt); - }, - noop: function (evt) {} - } - var noopOnClick = function (listeners) { - Gala.listen(elem, 'click', listeners.click = fns.noop); - } - Gala.listen(window, 'gala:contact:cancel', fns.move); - return Gala.onContact(elem, fns, false, noopOnClick); -} - - -// Register a series of functions to listen for the start, move, end -// events of a mouse or touch interaction. -// -// 'fns' argument is an object like: -// -// { -// 'start': function () { ... }, -// 'move': function () { ... }, -// 'end': function () { ... }, -// 'cancel': function () { ... } -// } -// -// All of the functions in this object are optional. -// -// Returns an object that can later be passed to Gala.deafenGroup. -// -Gala.onContact = function (elem, fns, useCapture, initCallback) { - elem = Gala.$(elem); - var listeners = null; - var inited = false; - - // If we see a touchstart event, register all these listeners. - var touchListeners = function () { - var l = {} - if (fns.start) { - l.touchstart = function (evt) { - if (evt.touches.length <= 1) { fns.start(evt); } - } - } - if (fns.move) { - l.touchmove = function (evt) { - if (evt.touches.length <= 1) { fns.move(evt); } - } - } - if (fns.end) { - l.touchend = function (evt) { - if (evt.touches.length <= 1) { fns.end(evt); } - } - } - if (fns.cancel) { - l.touchcancel = fns.cancel; - } - return l; - } - - // Whereas if we see a mousedown event, register all these listeners. - var mouseListeners = function () { - var l = {}; - if (fns.start) { - l.mousedown = function (evt) { if (evt.button < 2) { fns.start(evt); } } - } - if (fns.move) { - l.mousemove = fns.move; - } - if (fns.end) { - l.mouseup = function (evt) { if (evt.button < 2) { fns.end(evt); } } - } - // if (fns.cancel) { - // l.mouseout = function (evt) { - // obj = evt.relatedTarget || evt.fromElement; - // while (obj && (obj = obj.parentNode)) { if (obj == elem) { return; } } - // fns.cancel(evt); - // } - // } - return l; - } - - if (typeof Gala.CONTACT_MODE == 'undefined') { - var contactInit = function (evt, newListeners, mode) { - if (inited) { return; } - Gala.CONTACT_MODE = Gala.CONTACT_MODE || mode; - if (Gala.CONTACT_MODE != mode) { return; } - Gala.replaceGroup(elem, listeners, newListeners, useCapture); - if (typeof initCallback == 'function') { initCallback(listeners); } - if (listeners[evt.type]) { listeners[evt.type](evt); } - inited = true; - } - var touchInit = function (evt) { - contactInit(evt, touchListeners(), 'touch'); - } - var mouseInit = function (evt) { - contactInit(evt, mouseListeners(), 'mouse'); - } - listeners = { - 'touchstart': touchInit, - 'touchmove': touchInit, - 'touchend': touchInit, - 'touchcancel': touchInit, - 'mousedown': mouseInit, - 'mousemove': mouseInit, - 'mouseup': mouseInit, - 'mouseout': mouseInit - } - } else if (Gala.CONTACT_MODE == 'touch') { - listeners = touchListeners(); - } else if (Gala.CONTACT_MODE == 'mouse') { - listeners = mouseListeners(); - } - - Gala.listenGroup(elem, listeners); - if (typeof initCallback == 'function') { initCallback(listeners); } - return listeners; -} - - -// The Gala.Cursor object provides more detail coordinates for the contact -// event, and normalizes differences between touch and mouse coordinates. -// -// If you have a contact event listener, you can get the coordinates for it -// with: -// -// var cursor = new Gala.Cursor(evt); -// -Gala.Cursor = function (evt) { - var API = { constructor: Gala.Cursor } - - - function initialize() { - var ci = - evt.type.indexOf('mouse') == 0 ? evt : - ['touchstart', 'touchmove'].indexOf(evt.type) >= 0 ? evt.targetTouches[0] : - ['touchend', 'touchcancel'].indexOf(evt.type) >= 0 ? evt.changedTouches[0] : - null; - - // Basic coordinates (provided by the event). - API.pageX = ci.pageX; - API.pageY = ci.pageY; - API.clientX = ci.clientX; - API.clientY = ci.clientY; - API.screenX = ci.screenX; - API.screenY = ci.screenY; - - // Coordinates relative to the target element for the event. - var tgt = API.target = evt.target || evt.srcElement; - while (tgt.nodeType != 1 && tgt.parentNode) { tgt = tgt.parentNode; } - assignOffsetFor(tgt, 'offset'); - - // Coordinates relative to the element that the event was registered on. - var registrant = evt.currentTarget; - if (registrant && typeof registrant.offsetLeft != 'undefined') { - assignOffsetFor(registrant, 'registrant'); - } - } - - - function assignOffsetFor(elem, attr) { - var r; - if (elem.getBoundingClientRect) { - var er = elem.getBoundingClientRect(); - var dr = document.documentElement.getBoundingClientRect(); - r = { left: er.left - dr.left, top: er.top - dr.top } - } else { - r = { left: elem.offsetLeft, top: elem.offsetTop } - while (elem = elem.offsetParent) { - if (elem.offsetLeft || elem.offsetTop) { - r.left += elem.offsetLeft; - r.top += elem.offsetTop; - } - } - } - API[attr+'X'] = API.pageX - r.left; - API[attr+'Y'] = API.pageY - r.top; - } - - - initialize(); - - return API; -} - - -// A little utility to dereference ids into elements. You've seen this before. -// -Gala.$ = function (elem) { - if (typeof elem == 'string') { elem = document.getElementById(elem); } - return elem; -} - - - -// CONSTANTS -// -Gala.TAPPING_CLASS = 'tapping'; -Gala.IE_REGISTRATIONS = {} -Gala.IE_INVOCATION_QUEUE = [] -; -// A shortcut for creating a bookdata object from a 'data' hash. -// -// eg: -// -// Monocle.bookData({ components: ['intro.html', 'ch1.html', 'ch2.html'] }); -// -// All keys in the 'data' hash are optional: -// -// components: must be an array of component urls -// chapters: must be an array of nested chapters (the usual bookdata structure) -// metadata: must be a hash of key/values -// getComponentFn: override the default way to fetch components via id -// -Monocle.bookData = function (data) { - return { - getComponents: function () { - return data.components || ['anonymous']; - }, - getContents: function () { - return data.chapters || []; - }, - getComponent: data.getComponent || function (id) { - return { url: id } - }, - getMetaData: function (key) { - return (data.metadata || {})[key]; - }, - data: data - } -} - - -// A shortcut for creating a bookdata object from an array of element ids. -// -// eg: -// -// Monocle.bookDataFromIds(['part1', 'part2']); -// -Monocle.bookDataFromIds = function (elementIds) { - return Monocle.bookData({ - components: elementIds, - getComponent: function (cmptId) { - return { nodes: [document.getElementById(cmptId)] } - } - }); -} - - -// A shortcut for creating a bookdata object from an array of nodes. -// -// eg: -// -// Monocle.bookDataFromNodes([document.getElementById('content')]); -// -Monocle.bookDataFromNodes = function (nodes) { - return Monocle.bookData({ - getComponent: function (n) { return { 'nodes': nodes }; } - }); -} -; -Monocle.Factory = function (element, label, index, reader) { - - var API = { constructor: Monocle.Factory }; - var k = API.constants = API.constructor; - var p = API.properties = { - element: element, - label: label, - index: index, - reader: reader, - prefix: reader.properties.classPrefix || '' - } - - - // If index is null, uses the first available slot. If index is not null and - // the slot is not free, throws an error. - // - function initialize() { - if (!p.label) { return; } - // Append the element to the reader's graph of DOM elements. - var node = p.reader.properties.graph; - node[p.label] = node[p.label] || []; - if (typeof p.index == 'undefined' && node[p.label][p.index]) { - throw('Element already exists in graph: '+p.label+'['+p.index+']'); - } else { - p.index = p.index || node[p.label].length; - } - node[p.label][p.index] = p.element; - - // Add the label as a class name. - addClass(p.label); - } - - - // Finds an element that has been created in the context of the current - // reader, with the given label. If oIndex is not provided, returns first. - // If oIndex is provided (eg, n), returns the nth element with the label. - // - function find(oLabel, oIndex) { - if (!p.reader.properties.graph[oLabel]) { - return null; - } - return p.reader.properties.graph[oLabel][oIndex || 0]; - } - - - // Takes an elements and assimilates it into the reader -- essentially - // giving it a "dom" object of it's own. It will then be accessible via find. - // - // Note that (as per comments for initialize), if oIndex is provided and - // there is no free slot in the array for this label at that index, an - // error will be thrown. - // - function claim(oElement, oLabel, oIndex) { - return oElement.dom = new Monocle.Factory( - oElement, - oLabel, - oIndex, - p.reader - ); - } - - - // Create an element with the given label. - // - // The last argument (whether third or fourth) is the options hash. Your - // options are: - // - // class - the classname for the element. Must only be one name. - // html - the innerHTML for the element. - // text - the innerText for the element (an alternative to html, simpler). - // - // Returns the created element. - // - function make(tagName, oLabel, index_or_options, or_options) { - var oIndex, options; - if (arguments.length == 1) { - oLabel = null, - oIndex = 0; - options = {}; - } else if (arguments.length == 2) { - oIndex = 0; - options = {}; - } else if (arguments.length == 4) { - oIndex = arguments[2]; - options = arguments[3]; - } else if (arguments.length == 3) { - var lastArg = arguments[arguments.length - 1]; - if (typeof lastArg == "number") { - oIndex = lastArg; - options = {}; - } else { - oIndex = 0; - options = lastArg; - } - } - - var oElement = document.createElement(tagName); - claim(oElement, oLabel, oIndex); - if (options['class']) { - oElement.className += " "+p.prefix+options['class']; - } - if (options['html']) { - oElement.innerHTML = options['html']; - } - if (options['text']) { - oElement.appendChild(document.createTextNode(options['text'])); - } - - return oElement; - } - - - // Creates an element by passing all the given arguments to make. Then - // appends the element as a child of the current element. - // - function append(tagName, oLabel, index_or_options, or_options) { - var oElement = make.apply(this, arguments); - p.element.appendChild(oElement); - return oElement; - } - - - // Returns an array of [label, index, reader] for the given element. - // A simple way to introspect the arguments required for #find, for eg. - // - function address() { - return [p.label, p.index, p.reader]; - } - - - // Apply a set of style rules (hash or string) to the current element. - // See Monocle.Styles.applyRules for more info. - // - function setStyles(rules) { - return Monocle.Styles.applyRules(p.element, rules); - } - - - function setBetaStyle(property, value) { - return Monocle.Styles.affix(p.element, property, value); - } - - - // ClassName manipulation functions - with thanks to prototype.js! - - // Returns true if one of the current element's classnames matches name -- - // classPrefix aware (so don't concate the prefix onto it). - // - function hasClass(name) { - name = p.prefix + name; - var klass = p.element.className; - if (!klass) { return false; } - if (klass == name) { return true; } - return new RegExp("(^|\\s)"+name+"(\\s|$)").test(klass); - } - - - // Adds name to the classnames of the current element (prepending the - // reader's classPrefix first). - // - function addClass(name) { - if (hasClass(name)) { return; } - var gap = p.element.className ? ' ' : ''; - return p.element.className += gap+p.prefix+name; - } - - - // Removes (classPrefix+)name from the classnames of the current element. - // - function removeClass(name) { - var reName = new RegExp("(^|\\s+)"+p.prefix+name+"(\\s+|$)"); - var reTrim = /^\s+|\s+$/g; - var klass = p.element.className; - p.element.className = klass.replace(reName, ' ').replace(reTrim, ''); - return p.element.className; - } - - - API.find = find; - API.claim = claim; - API.make = make; - API.append = append; - API.address = address; - - API.setStyles = setStyles; - API.setBetaStyle = setBetaStyle; - API.hasClass = hasClass; - API.addClass = addClass; - API.removeClass = removeClass; - - initialize(); - - return API; -} -; -Monocle.Events = {}; - - -Monocle.Events.wrapper = function (fn) { - return function (evt) { evt.m = new Gala.Cursor(evt); fn(evt); } -} - - -Monocle.Events.listen = Gala.listen; - - -Monocle.Events.deafen = Gala.deafen; - - -Monocle.Events.dispatch = Gala.dispatch; - - -Monocle.Events.listenForTap = function (elem, fn, tapClass) { - return Gala.onTap(elem, Monocle.Events.wrapper(fn), tapClass); -} - - -Monocle.Events.deafenForTap = Gala.deafenGroup; - - -Monocle.Events.listenForContact = function (elem, fns, options) { - options = options || { useCapture: false }; - var wrappers = {}; - for (evtType in fns) { - wrappers[evtType] = Monocle.Events.wrapper(fns[evtType]); - } - return Gala.onContact(elem, wrappers, options.useCapture); -} - - -Monocle.Events.deafenForContact = Gala.deafenGroup; - - -// Listen for the next transition-end event on the given element, call -// the function, then deafen. -// -// Returns a function that can be used to cancel the listen early. -// -Monocle.Events.afterTransition = function (elem, fn) { - var evtName = "transitionend"; - if (Monocle.Browser.is.WebKit) { - evtName = 'webkitTransitionEnd'; - } else if (Monocle.Browser.is.Opera) { - evtName = 'oTransitionEnd'; - } - var l = null, cancel = null; - l = function () { fn(); cancel(); } - cancel = function () { Monocle.Events.deafen(elem, evtName, l); } - Monocle.Events.listen(elem, evtName, l); - return cancel; -} -; -Monocle.Styles = { - - // Takes a hash and returns a string. - rulesToString: function (rules) { - if (typeof rules != 'string') { - var parts = []; - for (var declaration in rules) { - parts.push(declaration+": "+rules[declaration]+";") - } - rules = parts.join(" "); - } - return rules; - }, - - - // Takes a hash or string of CSS property assignments and applies them - // to the element. - // - applyRules: function (elem, rules) { - rules = Monocle.Styles.rulesToString(rules); - elem.style.cssText += ';'+rules; - return elem.style.cssText; - }, - - - // Generates cross-browser properties for a given property. - // ie, affix(, 'transition', 'linear 100ms') would apply that value - // to webkitTransition for WebKit browsers, and to MozTransition for Gecko. - // - affix: function (elem, property, value) { - var target = elem.style ? elem.style : elem; - var props = Monocle.Browser.css.toDOMProps(property); - while (props.length) { target[props.shift()] = value; } - }, - - - setX: function (elem, x) { - var s = elem.style; - if (typeof x == "number") { x += "px"; } - var val = Monocle.Browser.env.supportsTransform3d ? - 'translate3d('+x+', 0, 0)' : - 'translateX('+x+')'; - val = (x == '0px') ? 'none' : val; - s.webkitTransform = s.MozTransform = s.OTransform = s.transform = val; - return x; - }, - - - setY: function (elem, y) { - var s = elem.style; - if (typeof y == "number") { y += "px"; } - var val = Monocle.Browser.env.supportsTransform3d ? - 'translate3d(0, '+y+', 0)' : - 'translateY('+y+')'; - val = (y == '0px') ? 'none' : val; - s.webkitTransform = s.MozTransform = s.OTransform = s.transform = val; - return y; - }, - - - getX: function (elem) { - var currStyle = document.defaultView.getComputedStyle(elem, null); - var re = /matrix\([^,]+,[^,]+,[^,]+,[^,]+,\s*([^,]+),[^\)]+\)/; - var props = Monocle.Browser.css.toDOMProps('transform'); - var matrix = null; - while (props.length && !matrix) { - matrix = currStyle[props.shift()]; - } - return parseInt(matrix.match(re)[1]); - }, - - - transitionFor: function (elem, prop, duration, timing, delay) { - var tProps = Monocle.Browser.css.toDOMProps('transition'); - var pProps = Monocle.Browser.css.toCSSProps(prop); - timing = timing || "linear"; - delay = (delay || 0)+"ms"; - for (var i = 0, ii = tProps.length; i < ii; ++i) { - var t = "none"; - if (duration) { - t = [pProps[i], duration+"ms", timing, delay].join(" "); - } - elem.style[tProps[i]] = t; - } - } - -} - - -// These rule definitions are more or less compulsory for Monocle to behave -// as expected. Which is why they appear here and not in the stylesheet. -// Adjust them if you know what you're doing. -// -Monocle.Styles.container = { - "position": "absolute", - "overflow": "hidden", - "top": "0", - "left": "0", - "bottom": "0", - "right": "0" -} - -Monocle.Styles.page = { - "position": "absolute", - "z-index": "1", - "-webkit-user-select": "none", - "-moz-user-select": "none", - "-ms-user-select": "none", - "user-select": "none", - "-webkit-transform": "translate3d(0,0,0)", - "visibility": "visible" - - /* - "background": "white", - "top": "0", - "left": "0", - "bottom": "0", - "right": "0" - */ -} - -Monocle.Styles.sheaf = { - "position": "absolute", - "overflow": "hidden" - - /* - "top": "0", - "left": "0", - "bottom": "0", - "right": "0" - */ -} - -Monocle.Styles.component = { - "width": "100%", - "height": "100%", - "border": "none", - "-webkit-user-select": "none", - "-moz-user-select": "none", - "-ms-user-select": "none", - "user-select": "none" -} - -Monocle.Styles.control = { - "z-index": "100", - "cursor": "pointer" -} - -Monocle.Styles.overlay = { - "position": "absolute", - "display": "none", - "width": "100%", - "height": "100%", - "z-index": "1000" -} -; -Monocle.Formatting = function (reader, optStyles, optScale) { - var API = { constructor: Monocle.Formatting }; - var k = API.constants = API.constructor; - var p = API.properties = { - reader: reader, - - // An array of style rules that are automatically applied to every page. - stylesheets: [], - - // A multiplier on the default font-size of each element in every - // component. If null, the multiplier is not applied (or it is removed). - fontScale: null - } - - - function initialize() { - p.fontScale = optScale; - clampStylesheets(optStyles); - p.reader.listen('monocle:componentmodify', persistOnComponentChange); - } - - - // Clamp page frames to a set of styles that reduce Monocle breakage. - // - function clampStylesheets(implStyles) { - var defCSS = k.DEFAULT_STYLE_RULES; - if (Monocle.Browser.env.floatsIgnoreColumns) { - defCSS.push("html#RS\\:monocle * { float: none !important; }"); - } - p.defaultStyles = addPageStyles(defCSS, false); - if (implStyles) { - p.initialStyles = addPageStyles(implStyles, false); - } - } - - - function persistOnComponentChange(evt) { - var doc = evt.m['document']; - doc.documentElement.id = p.reader.properties.systemId; - adjustFontScaleForDoc(doc, p.fontScale); - for (var i = 0; i < p.stylesheets.length; ++i) { - if (p.stylesheets[i]) { - addPageStylesheet(doc, i); - } - } - } - - - /* PAGE STYLESHEETS */ - - // API for adding a new stylesheet to all components. styleRules should be - // a string of CSS rules. restorePlace defaults to true. - // - // Returns a sheet index value that can be used with updatePageStyles - // and removePageStyles. - // - function addPageStyles(styleRules, restorePlace) { - return changingStylesheet(function () { - p.stylesheets.push(styleRules); - var sheetIndex = p.stylesheets.length - 1; - - var i = 0, cmpt = null; - while (cmpt = p.reader.dom.find('component', i++)) { - addPageStylesheet(cmpt.contentDocument, sheetIndex); - } - return sheetIndex; - }, restorePlace); - } - - - // API for updating the styleRules in an existing page stylesheet across - // all components. Takes a sheet index value obtained via addPageStyles. - // - function updatePageStyles(sheetIndex, styleRules, restorePlace) { - return changingStylesheet(function () { - p.stylesheets[sheetIndex] = styleRules; - if (typeof styleRules.join == "function") { - styleRules = styleRules.join("\n"); - } - - var i = 0, cmpt = null; - while (cmpt = p.reader.dom.find('component', i++)) { - var doc = cmpt.contentDocument; - var styleTag = doc.getElementById('monStylesheet'+sheetIndex); - if (!styleTag) { - console.warn('No such stylesheet: ' + sheetIndex); - return; - } - if (styleTag.styleSheet) { - styleTag.styleSheet.cssText = styleRules; - } else { - styleTag.replaceChild( - doc.createTextNode(styleRules), - styleTag.firstChild - ); - } - } - }, restorePlace); - } - - - // API for removing a page stylesheet from all components. Takes a sheet - // index value obtained via addPageStyles. - // - function removePageStyles(sheetIndex, restorePlace) { - return changingStylesheet(function () { - p.stylesheets[sheetIndex] = null; - var i = 0, cmpt = null; - while (cmpt = p.reader.dom.find('component', i++)) { - var doc = cmpt.contentDocument; - var styleTag = doc.getElementById('monStylesheet'+sheetIndex); - styleTag.parentNode.removeChild(styleTag); - } - }, restorePlace); - } - - - // Wraps all API-based stylesheet changes (add, update, remove) in a - // brace of custom events (stylesheetchanging/stylesheetchange), and - // recalculates component dimensions if specified (default to true). - // - function changingStylesheet(callback, restorePlace) { - restorePlace = (restorePlace === false) ? false : true; - if (restorePlace) { - dispatchChanging(); - } - var result = callback(); - if (restorePlace) { - p.reader.recalculateDimensions(true); - Monocle.defer(dispatchChange); - } else { - p.reader.recalculateDimensions(false); - } - return result; - } - - - function dispatchChanging() { - p.reader.dispatchEvent("monocle:stylesheetchanging", {}); - } - - - function dispatchChange() { - p.reader.dispatchEvent("monocle:stylesheetchange", {}); - } - - - // Private method for adding a stylesheet to a component. Used by - // addPageStyles. - // - function addPageStylesheet(doc, sheetIndex) { - var styleRules = p.stylesheets[sheetIndex]; - - if (!styleRules) { - return; - } - - if (!doc || !doc.documentElement) { - return; - } - - var head = doc.getElementsByTagName('head')[0]; - if (!head) { - head = doc.createElement('head'); - doc.documentElement.appendChild(head); - } - - if (typeof styleRules.join == "function") { - styleRules = styleRules.join("\n"); - } - - var styleTag = doc.createElement('style'); - styleTag.type = 'text/css'; - styleTag.id = "monStylesheet"+sheetIndex; - if (styleTag.styleSheet) { - styleTag.styleSheet.cssText = styleRules; - } else { - styleTag.appendChild(doc.createTextNode(styleRules)); - } - - head.appendChild(styleTag); - - return styleTag; - } - - - /* FONT SCALING */ - - function setFontScale(scale, restorePlace) { - p.fontScale = scale; - if (restorePlace) { - dispatchChanging(); - } - var i = 0, cmpt = null; - while (cmpt = p.reader.dom.find('component', i++)) { - adjustFontScaleForDoc(cmpt.contentDocument, scale); - } - if (restorePlace) { - p.reader.recalculateDimensions(true); - dispatchChange(); - } else { - p.reader.recalculateDimensions(false); - } - } - - - function adjustFontScaleForDoc(doc, scale) { - var elems = doc.getElementsByTagName('*'); - if (scale) { - scale = parseFloat(scale); - if (!doc.body.pfsSwept) { - sweepElements(doc, elems); - } - - // Iterate over each element, applying scale to the original - // font-size. If a proportional font sizing is already applied to - // the element, update existing cssText, otherwise append new cssText. - // - for (var j = 0, jj = elems.length; j < jj; ++j) { - var newFs = fsProperty(elems[j].pfsOriginal, scale); - if (elems[j].pfsApplied) { - replaceFontSizeInStyle(elems[j], newFs); - } else { - elems[j].style.cssText += newFs; - } - elems[j].pfsApplied = scale; - } - } else if (doc.body.pfsSwept) { - // Iterate over each element, removing proportional font-sizing flag - // and property from cssText. - for (var j = 0, jj = elems.length; j < jj; ++j) { - if (elems[j].pfsApplied) { - var oprop = elems[j].pfsOriginalProp; - var opropDec = oprop ? 'font-size: '+oprop+' ! important;' : ''; - replaceFontSizeInStyle(elems[j], opropDec); - elems[j].pfsApplied = null; - } - } - - // Establish new baselines in case classes have changed. - sweepElements(doc, elems); - } - } - - - function sweepElements(doc, elems) { - // Iterate over each element, looking at its font size and storing - // the original value against the element. - for (var i = 0, ii = elems.length; i < ii; ++i) { - var currStyle = doc.defaultView.getComputedStyle(elems[i], null); - var fs = parseFloat(currStyle.getPropertyValue('font-size')); - elems[i].pfsOriginal = fs; - elems[i].pfsOriginalProp = elems[i].style.fontSize; - } - doc.body.pfsSwept = true; - } - - - function fsProperty(orig, scale) { - return 'font-size: '+(orig*scale)+'px ! important;'; - } - - - function replaceFontSizeInStyle(elem, newProp) { - var lastFs = /font-size:[^;]/ - elem.style.cssText = elem.style.cssText.replace(lastFs, newProp); - } - - - API.addPageStyles = addPageStyles; - API.updatePageStyles = updatePageStyles; - API.removePageStyles = removePageStyles; - API.setFontScale = setFontScale; - - initialize(); - - return API; -} - - - -Monocle.Formatting.DEFAULT_STYLE_RULES = [ - "html#RS\\:monocle * {" + - "-webkit-font-smoothing: subpixel-antialiased;" + - "text-rendering: auto !important;" + - "word-wrap: break-word !important;" + - "overflow: visible !important;" + - "}", - "html#RS\\:monocle body {" + - "margin: 0 !important;"+ - "border: none !important;" + - "padding: 0 !important;" + - "width: 100% !important;" + - "position: absolute !important;" + - "-webkit-text-size-adjust: none;" + - "}", - "html#RS\\:monocle body * {" + - "max-width: 100% !important;" + - "}", - "html#RS\\:monocle img, html#RS\\:monocle video, html#RS\\:monocle object, html#RS\\:monocle svg {" + - "max-height: 95% !important;" + - "height: auto !important;" + - "}" -] -; -// READER -// -// -// The full DOM hierarchy created by Reader is: -// -// box -// -> container -// -> pages (the number of page elements is determined by the flipper) -// -> sheaf (basically just sets the margins) -// -> component (an iframe created by the current component) -// -> body (the document.body of the iframe) -// -> page controls -// -> standard controls -// -> overlay -// -> modal/popover controls -// -// -// Options: -// -// flipper: The class of page flipper to use. -// -// panels: The class of panels to use -// -// stylesheet: A string of CSS rules to apply to the contents of each -// component loaded into the reader. -// -// fontScale: a float to multiply against the default font-size of each -// element in each component. -// -// place: A book locus for the page to open to when the reader is -// initialized. (See comments at Book#pageNumberAt for more about -// the locus option). -// -// systemId: the id for root elements of components, defaults to "RS:monocle" -// -Monocle.Reader = function (node, bookData, options, onLoadCallback) { - - var API = { constructor: Monocle.Reader } - var k = API.constants = API.constructor; - var p = API.properties = { - // Initialization-completed flag. - initialized: false, - - // The active book. - book: null, - - // DOM graph of factory-generated objects. - graph: {}, - - // Id applied to the HTML element of each component, can be used to scope - // CSS rules. - systemId: (options ? options.systemId : null) || k.DEFAULT_SYSTEM_ID, - - // Prefix for classnames for any created element. - classPrefix: k.DEFAULT_CLASS_PREFIX, - - // Registered control objects (see addControl). Hashes of the form: - // { - // control: , - // elements: , - // controlType: - // } - controls: [], - - // After the reader has been resized, this resettable timer must expire - // the place is restored. - resizeTimer: null - } - - var dom; - - - // Inspects the browser environment and kicks off preparing the container. - // - function initialize() { - options = options || {} - - Monocle.Browser.survey(prepareBox); - } - - - // Sets up the container and internal elements. - // - function prepareBox() { - var box = node; - if (typeof box == "string") { box = document.getElementById(box); } - dom = API.dom = box.dom = new Monocle.Factory(box, 'box', 0, API); - - API.billboard = new Monocle.Billboard(API); - - if (!Monocle.Browser.env.isCompatible()) { - if (dispatchEvent("monocle:incompatible", {}, true)) { - fatalSystemMessage(k.COMPATIBILITY_INFO); - } - return; - } - - dispatchEvent("monocle:initializing", API); - - bookData = bookData || Monocle.bookDataFromNodes([box.cloneNode(true)]); - var bk = new Monocle.Book(bookData, options.preloadWindow || 1); - - box.innerHTML = ""; - - // Make sure the box div is absolutely or relatively positioned. - positionBox(); - - // Attach the page-flipping gadget. - attachFlipper(options.flipper); - - // Create the essential DOM elements. - createReaderElements(); - - // Create the selection object. - API.selection = new Monocle.Selection(API); - - // Create the formatting object. - API.formatting = new Monocle.Formatting( - API, - options.stylesheet, - options.fontScale - ); - - primeFrames(options.primeURL, function () { - // Make the reader elements look pretty. - applyStyles(); - - p.flipper.listenForInteraction(options.panels); - - setBook(bk, options.place, function () { - if (onLoadCallback) { onLoadCallback(API); } - dispatchEvent("monocle:loaded", API); - }); - }); - } - - - function positionBox() { - var currPosVal; - var box = dom.find('box'); - if (document.defaultView) { - var currStyle = document.defaultView.getComputedStyle(box, null); - currPosVal = currStyle.getPropertyValue('position'); - } else if (box.currentStyle) { - currPosVal = box.currentStyle.position - } - if (["absolute", "relative"].indexOf(currPosVal) == -1) { - box.style.position = "relative"; - } - } - - - function attachFlipper(flipperClass) { - if (!flipperClass) { - if (Monocle.Browser.renders.slow) { - flipperClass = Monocle.Flippers.Instant; - } else { - flipperClass = Monocle.Flippers.Slider; - } - } - - p.flipper = new flipperClass(API, null, p.readerOptions); - } - - - function createReaderElements() { - var cntr = dom.append('div', 'container'); - for (var i = 0; i < p.flipper.pageCount; ++i) { - var page = cntr.dom.append('div', 'page', i); - page.style.visibility = "hidden"; - page.m = { reader: API, pageIndex: i, place: null } - page.m.sheafDiv = page.dom.append('div', 'sheaf', i); - page.m.activeFrame = page.m.sheafDiv.dom.append('iframe', 'component', i); - page.m.activeFrame.m = { 'pageDiv': page }; - page.m.activeFrame.setAttribute('frameBorder', 0); - page.m.activeFrame.setAttribute('scrolling', 'no'); - p.flipper.addPage(page); - } - dom.append('div', 'overlay'); - dispatchEvent("monocle:loading", API); - } - - - // Opens the frame to a particular URL (usually 'about:blank'). - // - function primeFrames(url, callback) { - url = url || (Monocle.Browser.on.UIWebView ? "blank.html" : "about:blank"); - - var pageCount = 0; - - var cb = function (evt) { - var frame = evt.target || evt.srcElement; - Monocle.Events.deafen(frame, 'load', cb); - dispatchEvent( - 'monocle:frameprimed', - { frame: frame, pageIndex: pageCount } - ); - if ((pageCount += 1) == p.flipper.pageCount) { - Monocle.defer(callback); - } - } - - forEachPage(function (page) { - Monocle.Events.listen(page.m.activeFrame, 'load', cb); - page.m.activeFrame.src = url; - }); - } - - - function applyStyles() { - dom.find('container').dom.setStyles(Monocle.Styles.container); - forEachPage(function (page, i) { - page.dom.setStyles(Monocle.Styles.page); - dom.find('sheaf', i).dom.setStyles(Monocle.Styles.sheaf); - var cmpt = dom.find('component', i) - cmpt.dom.setStyles(Monocle.Styles.component); - }); - lockFrameWidths(); - dom.find('overlay').dom.setStyles(Monocle.Styles.overlay); - dispatchEvent('monocle:styles'); - } - - - function lockingFrameWidths() { - if (!Monocle.Browser.env.relativeIframeExpands) { return; } - for (var i = 0, cmpt; cmpt = dom.find('component', i); ++i) { - cmpt.style.display = "none"; - } - } - - - function lockFrameWidths() { - if (!Monocle.Browser.env.relativeIframeExpands) { return; } - for (var i = 0, cmpt; cmpt = dom.find('component', i); ++i) { - cmpt.style.width = cmpt.parentNode.offsetWidth+"px"; - cmpt.style.display = "block"; - } - } - - - // Apply the book, move to a particular place or just the first page, wait - // for everything to complete, then fire the callback. - // - function setBook(bk, place, callback) { - p.book = bk; - var pageCount = 0; - if (typeof callback == 'function') { - var watchers = { - 'monocle:componentchange': function (evt) { - dispatchEvent('monocle:firstcomponentchange', evt.m); - return (pageCount += 1) == p.flipper.pageCount; - }, - 'monocle:componentfailed': function (evt) { - fatalSystemMessage(k.LOAD_FAILURE_INFO); - return true; - }, - 'monocle:turn': function (evt) { - deafen('monocle:componentfailed', listener); - callback(); - return true; - } - } - var listener = function (evt) { - if (watchers[evt.type](evt)) { deafen(evt.type, listener); } - } - for (evtType in watchers) { listen(evtType, listener) } - } - p.flipper.moveTo(place || { page: 1 }, initialized); - } - - - function getBook() { - return p.book; - } - - - function initialized() { - p.initialized = true; - } - - - // Attempts to restore the place we were up to in the book before the - // reader was resized. - // - // The delay ensures that if we get multiple calls to this function in - // a short period, we don't do lots of expensive recalculations. - // - function resized() { - if (!p.initialized) { - console.warn('Attempt to resize book before initialization.'); - } - lockingFrameWidths(); - if (!dispatchEvent("monocle:resizing", {}, true)) { - return; - } - clearTimeout(p.resizeTimer); - p.resizeTimer = Monocle.defer(performResize, k.RESIZE_DELAY); - } - - - function performResize() { - lockFrameWidths(); - recalculateDimensions(true, afterResized); - } - - - function afterResized() { - dispatchEvent('monocle:resize'); - } - - - function recalculateDimensions(andRestorePlace, callback) { - if (!p.book) { return; } - dispatchEvent("monocle:recalculating"); - - var place, locus; - if (andRestorePlace !== false) { - var place = getPlace(); - var locus = { percent: place ? place.percentageThrough() : 0 }; - } - - forEachPage(function (pageDiv) { - pageDiv.m.activeFrame.m.component.updateDimensions(pageDiv); - }); - - var cb = function () { - dispatchEvent("monocle:recalculated"); - Monocle.defer(callback); - } - Monocle.defer(function () { locus ? p.flipper.moveTo(locus, cb) : cb; }); - } - - - // Returns the current page number in the book. - // - // The pageDiv argument is optional - typically defaults to whatever the - // flipper thinks is the "active" page. - // - function pageNumber(pageDiv) { - var place = getPlace(pageDiv); - return place ? (place.pageNumber() || 1) : 1; - } - - - // Returns the current "place" in the book -- ie, the page number, chapter - // title, etc. - // - // The pageDiv argument is optional - typically defaults to whatever the - // flipper thinks is the "active" page. - // - function getPlace(pageDiv) { - if (!p.initialized) { - console.warn('Attempt to access place before initialization.'); - } - return p.flipper.getPlace(pageDiv); - } - - - // Moves the current page as specified by the locus. See - // Monocle.Book#pageNumberAt for documentation on the locus argument. - // - // The callback argument is optional. - // - function moveTo(locus, callback) { - if (!p.initialized) { - console.warn('Attempt to move place before initialization.'); - } - if (!p.book.isValidLocus(locus)) { - dispatchEvent( - "monocle:notfound", - { href: locus ? locus.componentId : "anonymous" } - ); - return false; - } - var fn = callback; - if (!locus.direction) { - dispatchEvent('monocle:jumping', { locus: locus }); - fn = function () { - dispatchEvent('monocle:jump', { locus: locus }); - if (callback) { callback(); } - } - } - p.flipper.moveTo(locus, fn); - return true; - } - - - // Moves to the relevant element in the relevant component. - // - function skipToChapter(src) { - var locus = p.book.locusOfChapter(src); - return moveTo(locus); - } - - - // Valid types: - // - standard (an overlay above the pages) - // - page (within the page) - // - modal (overlay where click-away does nothing, for a single control) - // - hud (overlay that multiple controls can share) - // - popover (overlay where click-away removes the ctrl elements) - // - invisible - // - // Options: - // - hidden -- creates and hides the ctrl elements; - // use showControl to show them - // - container -- specify an existing DOM element to contain the control. - // - function addControl(ctrl, cType, options) { - for (var i = 0; i < p.controls.length; ++i) { - if (p.controls[i].control == ctrl) { - console.warn("Already added control: %o", ctrl); - return; - } - } - - options = options || {}; - - var ctrlData = { control: ctrl, elements: [], controlType: cType } - p.controls.push(ctrlData); - - var addControlTo = function (cntr) { - if (cntr == 'container') { - cntr = options.container || dom.find('container'); - if (typeof cntr == 'string') { cntr = document.getElementById(cntr); } - if (!cntr.dom) { dom.claim(cntr, 'controlContainer'); } - } else if (cntr == 'overlay') { - cntr = dom.find('overlay'); - } - if (typeof ctrl.createControlElements != 'function') { return; } - var ctrlElem = ctrl.createControlElements(cntr); - if (!ctrlElem) { return; } - cntr.appendChild(ctrlElem); - ctrlData.elements.push(ctrlElem); - Monocle.Styles.applyRules(ctrlElem, Monocle.Styles.control); - return ctrlElem; - } - - if (!cType || cType == 'standard' || cType == 'invisible') { - addControlTo('container'); - } else if (cType == 'page') { - forEachPage(addControlTo); - } else if (cType == 'modal' || cType == 'popover' || cType == 'hud') { - addControlTo('overlay'); - ctrlData.usesOverlay = true; - } else if (cType == 'invisible') { - addControlTo('container'); - } else { - console.warn('Unknown control type: ' + cType); - } - - if (options.hidden) { - hideControl(ctrl); - } else { - showControl(ctrl); - } - - if (typeof ctrl.assignToReader == 'function') { - ctrl.assignToReader(API); - } - - return ctrl; - } - - - function dataForControl(ctrl) { - for (var i = 0; i < p.controls.length; ++i) { - if (p.controls[i].control == ctrl) { - return p.controls[i]; - } - } - } - - - function hideControl(ctrl) { - var controlData = dataForControl(ctrl); - if (!controlData) { - console.warn("No data for control: " + ctrl); - return; - } - if (controlData.hidden) { - return; - } - for (var i = 0; i < controlData.elements.length; ++i) { - controlData.elements[i].style.display = "none"; - } - if (controlData.usesOverlay) { - var overlay = dom.find('overlay'); - overlay.style.display = "none"; - Monocle.Events.deafenForContact(overlay, overlay.listeners); - if (controlData.controlType != 'hud') { - dispatchEvent('monocle:modal:off'); - } - } - controlData.hidden = true; - if (ctrl.properties) { - ctrl.properties.hidden = true; - } - dispatchEvent('monocle:controlhide', { control: ctrl }, false); - } - - - function showControl(ctrl) { - var controlData = dataForControl(ctrl); - if (!controlData) { - console.warn("No data for control: " + ctrl); - return false; - } - - if (showingControl(ctrl)) { - return false; - } - - var overlay = dom.find('overlay'); - if (controlData.usesOverlay && controlData.controlType != "hud") { - for (var i = 0, ii = p.controls.length; i < ii; ++i) { - if (p.controls[i].usesOverlay && !p.controls[i].hidden) { - return false; - } - } - overlay.style.display = "block"; - dispatchEvent('monocle:modal:on'); - } - - for (var i = 0; i < controlData.elements.length; ++i) { - controlData.elements[i].style.display = "block"; - } - - if (controlData.controlType == "popover") { - var onControl = function (evt) { - var obj = evt.target; - do { - if (obj == controlData.elements[0]) { return true; } - } while (obj && (obj = obj.parentNode)); - return false; - } - overlay.listeners = Monocle.Events.listenForContact( - overlay, - { - start: function (evt) { if (!onControl(evt)) { hideControl(ctrl); } }, - move: function (evt) { if (!onControl(evt)) { evt.preventDefault(); } } - } - ); - } - controlData.hidden = false; - if (ctrl.properties) { - ctrl.properties.hidden = false; - } - dispatchEvent('monocle:controlshow', { control: ctrl }, false); - return true; - } - - - function showingControl(ctrl) { - var controlData = dataForControl(ctrl); - return controlData.hidden == false; - } - - - function dispatchEvent(evtType, data, cancelable) { - return Monocle.Events.dispatch(dom.find('box'), evtType, data, cancelable); - } - - - function listen(evtType, fn, useCapture) { - Monocle.Events.listen(dom.find('box'), evtType, fn, useCapture); - } - - - function deafen(evtType, fn) { - Monocle.Events.deafen(dom.find('box'), evtType, fn); - } - - - function visiblePages() { - return p.flipper.visiblePages ? - p.flipper.visiblePages() : - [dom.find('page')]; - } - - - function forEachPage(callback) { - for (var i = 0, ii = p.flipper.pageCount; i < ii; ++i) { - var page = dom.find('page', i); - callback(page, i); - } - } - - - /* The Reader PageStyles API is deprecated - it has moved to Formatting */ - - function addPageStyles(styleRules, restorePlace) { - console.deprecation("Use reader.formatting.addPageStyles instead."); - return API.formatting.addPageStyles(styleRules, restorePlace); - } - - - function updatePageStyles(sheetIndex, styleRules, restorePlace) { - console.deprecation("Use reader.formatting.updatePageStyles instead."); - return API.formatting.updatePageStyles(sheetIndex, styleRules, restorePlace); - } - - - function removePageStyles(sheetIndex, restorePlace) { - console.deprecation("Use reader.formatting.removePageStyles instead."); - return API.formatting.removePageStyles(sheetIndex, restorePlace); - } - - - function fatalSystemMessage(msg) { - var info = dom.make('div', 'book_fatality', { html: msg }); - var box = dom.find('box'); - var bbOrigin = [box.offsetWidth / 2, box.offsetHeight / 2]; - API.billboard.show(info, { closeButton: false, from: bbOrigin }); - } - - - API.getBook = getBook; - API.getPlace = getPlace; - API.moveTo = moveTo; - API.skipToChapter = skipToChapter; - API.resized = resized; - API.recalculateDimensions = recalculateDimensions; - API.addControl = addControl; - API.hideControl = hideControl; - API.showControl = showControl; - API.showingControl = showingControl; - API.dispatchEvent = dispatchEvent; - API.listen = listen; - API.deafen = deafen; - API.visiblePages = visiblePages; - - // Deprecated! - API.addPageStyles = addPageStyles; - API.updatePageStyles = updatePageStyles; - API.removePageStyles = removePageStyles; - - initialize(); - - return API; -} - - -Monocle.Reader.RESIZE_DELAY = Monocle.Browser.renders.slow ? 500 : 100; -Monocle.Reader.DEFAULT_SYSTEM_ID = 'RS:monocle' -Monocle.Reader.DEFAULT_CLASS_PREFIX = 'monelem_' -Monocle.Reader.DEFAULT_STYLE_RULES = Monocle.Formatting.DEFAULT_STYLE_RULES; -Monocle.Reader.COMPATIBILITY_INFO = - "

    Incompatible browser

    "+ - "

    Unfortunately, your browser isn't able to display this book. "+ - "If possible, try again in another browser or on another device.

    "; -Monocle.Reader.LOAD_FAILURE_INFO = - "

    Book could not be loaded

    "+ - "

    Sorry, parts of the book could not be retrieved.
    "+ - "Please check your connection and refresh to try again.

    "; -/* BOOK */ - -/* The Book handles movement through the content by the reader page elements. - * - * It's responsible for instantiating components as they are required, - * and for calculating which component and page number to move to (based on - * requests from the Reader). - * - */ - -Monocle.Book = function (dataSource, preloadWindow) { - - var API = { constructor: Monocle.Book } - var k = API.constants = API.constructor; - var p = API.properties = { - dataSource: dataSource, - preloadWindow: preloadWindow, - cmptLoadQueue: {}, - components: [], - chapters: {} // flat arrays of chapters per component - } - - - function initialize() { - p.componentIds = dataSource.getComponents(); - p.contents = dataSource.getContents(); - p.lastCIndex = p.componentIds.length - 1; - } - - - // Adjusts the given locus object to provide the page number within the - // current component. - // - // If the locus implies movement to another component, the locus - // 'componentId' property will be updated to point to this component, and - // the 'load' property will be set to true, which should be taken as a - // sign to call loadPageAt with a callback. - // - // The locus argument is an object that has one of the following properties: - // - // - page: positive integer. Counting up from the start of component. - // - pagesBack: negative integer. Counting back from the end of component. - // - percent: float indicating percentage through the component - // - direction: integer relative to the current page number for this pageDiv - // - position: string, one of "start" or "end", moves to corresponding point - // in the given component - // - anchor: an element id within the component - // - xpath: the node at this XPath within the component - // - selector: the first node at this CSS selector within the component - // - // The locus object can also specify a componentId. If it is not provided - // we default to the currently active component, and if that doesn't exist, - // we default to the very first component. - // - // The locus result will be an object with the following properties: - // - // - load: boolean, true if loading component required, false otherwise - // - componentId: component to load (current componentId if load is false) - // - if load is false: - // - page - // - if load is true: - // - one of page / pagesBack / percent / direction / position / anchor - // - function pageNumberAt(pageDiv, locus) { - locus.load = false; - var currComponent = pageDiv.m.activeFrame ? - pageDiv.m.activeFrame.m.component : - null; - var component = null; - var cIndex = p.componentIds.indexOf(locus.componentId); - if (cIndex < 0 && !currComponent) { - // No specified component, no current component. Load first component. - locus.load = true; - locus.componentId = p.componentIds[0]; - return locus; - } else if ( - cIndex < 0 && - locus.componentId && - currComponent.properties.id != locus.componentId - ) { - // Invalid component, say not found. - pageDiv.m.reader.dispatchEvent( - "monocle:notfound", - { href: locus.componentId } - ); - return null; - } else if (cIndex < 0) { - // No specified (or invalid) component, use current component. - component = currComponent; - locus.componentId = pageDiv.m.activeFrame.m.component.properties.id; - cIndex = p.componentIds.indexOf(locus.componentId); - } else if (!p.components[cIndex] || p.components[cIndex] != currComponent) { - // Specified component differs from current component. Load specified. - locus.load = true; - return locus; - } else { - component = currComponent; - } - - // If we're here, then the locus is based on the current component. - var result = { load: false, componentId: locus.componentId, page: 1 } - - // Get the current last page. - lastPageNum = component.lastPageNumber(); - - // Deduce the page number for the given locus. - if (typeof(locus.page) == "number") { - result.page = locus.page; - } else if (typeof(locus.pagesBack) == "number") { - result.page = lastPageNum + locus.pagesBack; - } else if (typeof(locus.percent) == "number") { - var place = new Monocle.Place(); - place.setPlace(component, 1); - result.page = place.pageAtPercentageThrough(locus.percent); - } else if (typeof(locus.direction) == "number") { - if (!pageDiv.m.place) { - console.warn("Can't move in a direction if pageDiv has no place."); - } - result.page = pageDiv.m.place.pageNumber(); - result.page += locus.direction; - } else if (typeof(locus.anchor) == "string") { - result.page = component.pageForChapter(locus.anchor, pageDiv); - } else if (typeof(locus.xpath) == "string") { - result.page = component.pageForXPath(locus.xpath, pageDiv); - } else if (typeof(locus.selector) == "string") { - result.page = component.pageForSelector(locus.selector, pageDiv); - } else if (typeof(locus.position) == "string") { - if (locus.position == "start") { - result.page = 1; - } else if (locus.position == "end") { - result.page = lastPageNum['new']; - } - } else { - console.warn("Unrecognised locus: " + locus); - } - - if (result.page < 1) { - if (cIndex == 0) { - // On first page of book. - result.page = 1; - result.boundarystart = true; - } else { - // Moving backwards from current component. - result.load = true; - result.componentId = p.componentIds[cIndex - 1]; - result.pagesBack = result.page; - result.page = null; - } - } else if (result.page > lastPageNum) { - if (cIndex == p.lastCIndex) { - // On last page of book. - result.page = lastPageNum; - result.boundaryend = true; - } else { - // Moving forwards from current component. - result.load = true; - result.componentId = p.componentIds[cIndex + 1]; - result.page -= lastPageNum; - } - } - - return result; - } - - - // Same as pageNumberAt, but if a load is not flagged, this will - // automatically update the pageDiv's place to the given pageNumber. - // - // If you call this (ie, from a flipper), you are effectively entering into - // a contract to move the frame offset to the given page returned in the - // locus if load is false. - // - function setPageAt(pageDiv, locus) { - locus = pageNumberAt(pageDiv, locus); - if (locus && !locus.load) { - var evtData = { locus: locus, page: pageDiv } - if (locus.boundarystart) { - pageDiv.m.reader.dispatchEvent('monocle:boundarystart', evtData); - } else if (locus.boundaryend) { - pageDiv.m.reader.dispatchEvent('monocle:boundaryend', evtData); - } else { - var component = p.components[p.componentIds.indexOf(locus.componentId)]; - pageDiv.m.place = pageDiv.m.place || new Monocle.Place(); - pageDiv.m.place.setPlace(component, locus.page); - - var evtData = { - page: pageDiv, - locus: locus, - pageNumber: pageDiv.m.place.pageNumber(), - componentId: locus.componentId - } - pageDiv.m.reader.dispatchEvent("monocle:pagechange", evtData); - } - } - return locus; - } - - - // Will load the given component into the pageDiv's frame, then invoke the - // callback with resulting locus (provided by pageNumberAt). - // - // If the resulting page number is outside the bounds of the new component, - // (ie, pageNumberAt again requests a load), this will recurse into further - // components until non-loading locus is returned by pageNumberAt. Then the - // callback will fire with that locus. - // - // As with setPageAt, if you call this you're obliged to move the frame - // offset to the given page in the locus passed to the callback. - // - function loadPageAt(pageDiv, locus, onLoad, onFail) { - var cIndex = p.componentIds.indexOf(locus.componentId); - if (!locus.load || cIndex < 0) { - locus = pageNumberAt(pageDiv, locus); - } - - if (!locus) { - return onFail ? onFail() : null; - } - - if (!locus.load) { - return onLoad(locus); - } - - var findPageNumber = function () { - locus = setPageAt(pageDiv, locus); - if (!locus) { - return onFail ? onFail() : null; - } else if (locus.load) { - loadPageAt(pageDiv, locus, onLoad, onFail) - } else { - onLoad(locus); - } - } - - var applyComponent = function (component) { - component.applyTo(pageDiv, findPageNumber); - for (var l = 1; l <= p.preloadWindow; ++l) { - deferredPreloadComponent(cIndex+l, l*k.PRELOAD_INTERVAL); - } - } - - loadComponent(cIndex, applyComponent, onFail, pageDiv); - } - - - // If your flipper doesn't care whether a component needs to be - // loaded before the page can be set, you can use this shortcut. - // - function setOrLoadPageAt(pageDiv, locus, onLoad, onFail) { - locus = setPageAt(pageDiv, locus); - if (!locus) { - if (onFail) { onFail(); } - } else if (locus.load) { - loadPageAt(pageDiv, locus, onLoad, onFail); - } else { - onLoad(locus); - } - } - - - // Fetches the component source from the dataSource. - // - // 'index' is the index of the component in the - // dataSource.getComponents array. - // - // 'onLoad' is invoked when the source is received. - // - // 'onFail' is optional, and is invoked if the source could not be fetched. - // - // 'pageDiv' is optional, and simply allows firing events on - // the reader object that has requested this component, ONLY if - // the source has not already been received. - // - function loadComponent(index, onLoad, onFail, pageDiv) { - if (p.components[index]) { - return onLoad(p.components[index]); - } - - var cmptId = p.components[index]; - var evtData = { 'page': pageDiv, 'component': cmptId, 'index': index }; - pageDiv.m.reader.dispatchEvent('monocle:componentloading', evtData); - - var onCmptLoad = function (cmpt) { - evtData['component'] = cmpt; - pageDiv.m.reader.dispatchEvent('monocle:componentloaded', evtData); - onLoad(cmpt); - } - - var onCmptFail = function (cmptId) { - console.warn("Failed to load component: "+cmptId); - pageDiv.m.reader.dispatchEvent('monocle:componentfailed', evtData); - if (onFail) { onFail(); } - } - - _loadComponent(index, onCmptLoad, onCmptFail); - } - - - function preloadComponent(index) { - if (p.components[index]) { return; } - var cmptId = p.componentIds[index]; - if (!cmptId) { return; } - if (p.cmptLoadQueue[cmptId]) { return; } - _loadComponent(index); - } - - - function deferredPreloadComponent(index, delay) { - Monocle.defer(function () { preloadComponent(index); }, delay); - } - - - function _loadComponent(index, successCallback, failureCallback) { - var cmptId = p.componentIds[index]; - var queueItem = { success: successCallback, failure: failureCallback }; - if (p.cmptLoadQueue[cmptId]) { - return p.cmptLoadQueue[cmptId] = queueItem; - } else { - p.cmptLoadQueue[cmptId] = queueItem; - } - - var onCmptFail = function () { - fireLoadQueue(cmptId, 'failure', cmptId); - } - - var onCmptLoad = function (cmptSource) { - if (cmptSource === false) { return onCmptFail(); } - p.components[index] = new Monocle.Component( - API, - cmptId, - index, - chaptersForComponent(cmptId), - cmptSource - ); - fireLoadQueue(cmptId, 'success', p.components[index]); - } - - var cmptSource = p.dataSource.getComponent(cmptId, onCmptLoad); - if (cmptSource && !p.components[index]) { - onCmptLoad(cmptSource); - } else if (cmptSource === false) { - onCmptFail(); - } - } - - - function fireLoadQueue(cmptId, cbName, args) { - if (typeof p.cmptLoadQueue[cmptId][cbName] == 'function') { - p.cmptLoadQueue[cmptId][cbName](args); - } - p.cmptLoadQueue[cmptId] = null; - } - - - // Returns an array of chapter objects that are found in the given component. - // - // A chapter object has this format: - // - // { - // title: "Chapter 1", - // fragment: null - // } - // - // The fragment property of a chapter object is either null (the chapter - // starts at the head of the component) or the fragment part of the URL - // (eg, "foo" in "index.html#foo"). - // - function chaptersForComponent(cmptId) { - if (p.chapters[cmptId]) { - return p.chapters[cmptId]; - } - p.chapters[cmptId] = []; - var matcher = new RegExp('^'+decodeURIComponent(cmptId)+"(\#(.+)|$)"); - var matches; - var recurser = function (chp) { - if (matches = decodeURIComponent(chp.src).match(matcher)) { - p.chapters[cmptId].push({ - title: chp.title, - fragment: matches[2] || null - }); - } - if (chp.children) { - for (var i = 0; i < chp.children.length; ++i) { - recurser(chp.children[i]); - } - } - } - - for (var i = 0; i < p.contents.length; ++i) { - recurser(p.contents[i]); - } - return p.chapters[cmptId]; - } - - - // Returns a locus for the chapter that has the URL given in the - // 'src' argument. - // - // See the comments at pageNumberAt for an explanation of locus objects. - // - function locusOfChapter(src) { - var matcher = new RegExp('^(.+?)(#(.*))?$'); - var matches = src.match(matcher); - if (!matches) { return null; } - var cmptId = componentIdMatching(matches[1]); - if (!cmptId) { return null; } - var locus = { componentId: cmptId } - matches[3] ? locus.anchor = matches[3] : locus.position = "start"; - return locus; - } - - - function isValidLocus(locus) { - if (!locus) { return false; } - if (locus.componentId && !componentIdMatching(locus.componentId)) { - return false; - } - return true; - } - - - function componentIdMatching(str) { - str = decodeURIComponent(str); - for (var i = 0, ii = p.componentIds.length; i < ii; ++i) { - if (decodeURIComponent(p.componentIds[i]) == str) { return str; } - } - return null; - } - - - function componentWeights() { - if (!p.weights) { - p.weights = dataSource.getMetaData('componentWeights') || []; - if (!p.weights.length) { - var cmptSize = 1.0 / p.componentIds.length; - for (var i = 0, ii = p.componentIds.length; i < ii; ++i) { - p.weights.push(cmptSize); - } - } - } - return p.weights; - } - - - API.getMetaData = dataSource.getMetaData; - API.pageNumberAt = pageNumberAt; - API.setPageAt = setPageAt; - API.loadPageAt = loadPageAt; - API.setOrLoadPageAt = setOrLoadPageAt; - API.chaptersForComponent = chaptersForComponent; - API.locusOfChapter = locusOfChapter; - API.isValidLocus = isValidLocus; - API.componentWeights = componentWeights; - - initialize(); - - return API; -} - - -// Legacy function. Deprecated. -// -Monocle.Book.fromNodes = function (nodes) { - console.deprecation("Book.fromNodes() will soon be removed."); - return new Monocle.Book(Monocle.bookDataFromNodes(nodes)); -} - -Monocle.Book.PRELOAD_INTERVAL = 1000; -// PLACE - -Monocle.Place = function () { - - var API = { constructor: Monocle.Place } - var k = API.constants = API.constructor; - var p = API.properties = { - component: null, - percent: null - } - - - function setPlace(cmpt, pageN) { - p.component = cmpt; - p.percent = pageN / cmpt.lastPageNumber(); - p.chapter = null; - } - - - function setPercentageThrough(cmpt, percent) { - p.component = cmpt; - p.percent = percent; - p.chapter = null; - } - - - function componentId() { - return p.component.properties.id; - } - - - // How far we are through the component at the "top of the page". - // - // 0 - start of book. 1.0 - end of book. - // - function percentAtTopOfPage() { - if (k.PAGE_ANCHOR == 'bottom') { - return p.percent - 1.0 / p.component.lastPageNumber(); - } else { - return p.percent; - } - } - - - function percentOnPage() { - return percentAtTopOfPage() + k.PAGE_ANCHOR_OFFSET / pagesInComponent(); - } - - - // How far we are through the component at the "bottom of the page". - // - function percentAtBottomOfPage() { - if (k.PAGE_ANCHOR == 'bottom') { - return p.percent; - } else { - return p.percent + 1.0 / p.component.lastPageNumber(); - } - } - - - // The page number at a given point (0: start, 1: end) within the component. - // - function pageAtPercentageThrough(percent) { - var pages = pagesInComponent(); - if (typeof percent != 'number') { percent = 0; } - return Math.max(Math.round(pages * percent), 1); - } - - - // The page number of this point within the component. - // - function pageNumber() { - return pageAtPercentageThrough(p.percent); - } - - - function pagesInComponent() { - return p.component.lastPageNumber(); - } - - - function chapterInfo() { - if (p.chapter) { - return p.chapter; - } - return p.chapter = p.component.chapterForPage(pageNumber()+1); - } - - - function chapterTitle() { - var chp = chapterInfo(); - return chp ? chp.title : null; - } - - - function chapterSrc() { - var src = componentId(); - var cinfo = chapterInfo(); - if (cinfo && cinfo.fragment) { - src += "#" + cinfo.fragment; - } - return src; - } - - - function getLocus(options) { - options = options || {}; - var locus = { - page: pageNumber(), - componentId: componentId() - } - if (options.direction) { - locus.page += options.direction; - } else { - locus.percent = percentAtBottomOfPage(); - } - return locus; - } - - - // Returns how far this place is in the entire book (0 - start, 1.0 - end). - // - function percentageOfBook() { - var book = p.component.properties.book; - var componentIds = book.properties.componentIds; - var weights = book.componentWeights(); - var cmptIndex = p.component.properties.index; - var pc = weights[cmptIndex] * p.percent; - for (var i = 0, ii = cmptIndex; i < ii; ++i) { pc += weights[i]; } - - // Note: This is a decent estimation of current page number and total - // number of pages, but it's very approximate. Could be improved by storing - // the page counts of all components accessed (since the dimensions of the - // reader last changed), and averaging the result across them. (You - // probably want to ignore calcs for components < 2 or 3 pages long, too. - // The bigger the component, the more accurate the calculation.) - // - // var bkPages = p.component.lastPageNumber() / weights[cmptIndex]; - // console.log('Page: '+ Math.floor(pc*bkPages)+ ' of '+ Math.floor(bkPages)); - - return pc; - } - - - function onFirstPageOfBook() { - return p.component.properties.index == 0 && pageNumber() == 1; - } - - - function onLastPageOfBook() { - return ( - p.component.properties.index == - p.component.properties.book.properties.lastCIndex && - pageNumber() == p.component.lastPageNumber() - ); - } - - - API.setPlace = setPlace; - API.setPercentageThrough = setPercentageThrough; - API.componentId = componentId; - API.percentAtTopOfPage = percentAtTopOfPage; - API.percentOnPage = percentOnPage; - API.percentAtBottomOfPage = percentAtBottomOfPage; - API.pageAtPercentageThrough = pageAtPercentageThrough; - API.pageNumber = pageNumber; - API.pagesInComponent = pagesInComponent; - API.chapterInfo = chapterInfo; - API.chapterTitle = chapterTitle; - API.chapterSrc = chapterSrc; - API.getLocus = getLocus; - API.percentageOfBook = percentageOfBook; - API.onFirstPageOfBook = onFirstPageOfBook; - API.onLastPageOfBook = onLastPageOfBook; - - API.percentageThrough = k.PAGE_ANCHOR == 'bottom' ? percentAtBottomOfPage : - k.PAGE_ANCHOR == 'offset' ? percentOnPage : - percentAtTopOfPage; - - return API; -} - - -// Can set this to 'top', 'offset' or 'bottom'. Old Monocle behaviour is 'bottom'. -// -Monocle.Place.PAGE_ANCHOR = 'offset'; -Monocle.Place.PAGE_ANCHOR_OFFSET = 0.1; - - -Monocle.Place.FromPageNumber = function (component, pageNumber) { - var place = new Monocle.Place(); - place.setPlace(component, pageNumber); - return place; -} - - -Monocle.Place.FromPercentageThrough = function (component, percent) { - var place = new Monocle.Place(); - place.setPercentageThrough(component, percent); - return place; -} - - -// We can't create a place from a percentage of the book, because the -// component may not have been loaded yet. But we can get a locus. -// -Monocle.Place.percentOfBookToLocus = function (reader, percent) { - var book = reader.getBook(); - var componentIds = book.properties.componentIds; - var weights = book.componentWeights(); - var cmptIndex = 0, cmptWeight = 0; - percent = Math.min(percent, 0.99999); - while (percent >= 0) { - cmptWeight = weights[cmptIndex]; - percent -= weights[cmptIndex]; - if (percent >= 0) { - cmptIndex += 1; - if (cmptIndex >= weights.length) { - console.error('Unable to calculate locus from percentage: '+percent); - return; - } - } - } - var cmptPercent = (percent + cmptWeight) / cmptWeight; - return { componentId: componentIds[cmptIndex], percent: cmptPercent } -} -; -/* COMPONENT */ - -// See the properties declaration for details of constructor arguments. -// -Monocle.Component = function (book, id, index, chapters, source) { - - var API = { constructor: Monocle.Component } - var k = API.constants = API.constructor; - var p = API.properties = { - // a back-reference to the public API of the book that owns this component - book: book, - - // the string that represents this component in the book's component array - id: id, - - // the position in the book's components array of this component - index: index, - - // The chapters argument is an array of objects that list the chapters that - // can be found in this component. A chapter object is defined as: - // - // { - // title: str, - // fragment: str, // optional anchor id - // percent: n // how far into the component the chapter begins - // } - // - // NOTE: the percent property is calculated by the component - you only need - // to pass in the title and the optional id string. - // - chapters: chapters, - - // the frame provided by dataSource.getComponent() for this component - source: source - } - - - // Makes this component the active component for the pageDiv. There are - // several strategies for this (see loadFrame). - // - // When the component has been loaded into the pageDiv's frame, the callback - // will be invoked with the pageDiv and this component as arguments. - // - function applyTo(pageDiv, callback) { - prepareSource(pageDiv.m.reader); - - var evtData = { 'page': pageDiv, 'source': p.source }; - pageDiv.m.reader.dispatchEvent('monocle:componentchanging', evtData); - - var onLoaded = function () { - setupFrame( - pageDiv, - pageDiv.m.activeFrame, - function () { callback(pageDiv, API) } - ); - } - - Monocle.defer(function () { loadFrame(pageDiv, onLoaded); }); - } - - - // Loads this component into the given frame, using one of the following - // strategies: - // - // * HTML - a HTML string - // * URL - a URL string - // * Nodes - an array of DOM body nodes (NB: no way to populate head) - // * Document - a DOM DocumentElement object - // - function loadFrame(pageDiv, callback) { - var frame = pageDiv.m.activeFrame; - - // We own this frame now. - frame.m.component = API; - - // Hide the frame while we're changing it. - frame.style.visibility = "hidden"; - - frame.whenDocumentReady = function () { - var doc = frame.contentDocument; - var evtData = { 'page': pageDiv, 'document': doc, 'component': API }; - pageDiv.m.reader.dispatchEvent('monocle:componentmodify', evtData); - frame.whenDocumentReady = null; - } - - if (p.source.html) { - return loadFrameFromHTML(p.source.html || p.source, frame, callback); - } else if (p.source.url) { - return loadFrameFromURL(p.source.url, frame, callback); - } else if (p.source.doc) { - return loadFrameFromDocument(p.source.doc, frame, callback); - } - } - - - // LOAD STRATEGY: HTML - // Loads a HTML string into the given frame, invokes the callback once loaded. - // - function loadFrameFromHTML(src, frame, callback) { - var fn = function () { - Monocle.Events.deafen(frame, 'load', fn); - frame.whenDocumentReady(); - Monocle.defer(callback); - } - Monocle.Events.listen(frame, 'load', fn); - if (Monocle.Browser.env.loadHTMLWithDocWrite) { - frame.contentDocument.open('text/html', 'replace'); - frame.contentDocument.write(src); - frame.contentDocument.close(); - } else { - frame.contentWindow['monCmptData'] = src; - frame.src = "javascript:window['monCmptData'];" - } - } - - - // LOAD STRATEGY: URL - // Loads the URL into the given frame, invokes callback once loaded. - // - function loadFrameFromURL(url, frame, callback) { - // If it's a relative path, we need to make it absolute. - if (!url.match(/^\//)) { - url = absoluteURL(url); - } - var onDocumentReady = function () { - Monocle.Events.deafen(frame, 'load', onDocumentReady); - frame.whenDocumentReady(); - } - var onDocumentLoad = function () { - Monocle.Events.deafen(frame, 'load', onDocumentLoad); - Monocle.defer(callback); - } - Monocle.Events.listen(frame, 'load', onDocumentReady); - Monocle.Events.listen(frame, 'load', onDocumentLoad); - frame.contentWindow.location.replace(url); - } - - - // LOAD STRATEGY: DOCUMENT - // Replaces the DocumentElement of the given frame with the given srcDoc. - // Invokes the callback when loaded. - // - function loadFrameFromDocument(srcDoc, frame, callback) { - var doc = frame.contentDocument; - - // WebKit has an interesting quirk. The tag must exist in the - // document being replaced, not the new document. - if (Monocle.Browser.is.WebKit) { - var srcBase = srcDoc.querySelector('base'); - if (srcBase) { - var head = doc.querySelector('head'); - if (!head) { - try { - head = doc.createElement('head'); - prependChild(doc.documentElement, head); - } catch (e) { - head = doc.body; - } - } - var base = doc.createElement('base'); - base.setAttribute('href', srcBase.href); - head.appendChild(base); - } - } - - doc.replaceChild( - doc.importNode(srcDoc.documentElement, true), - doc.documentElement - ); - - // NB: It's a significant problem with this load strategy that there's - // no indication when it is complete. - Monocle.defer(callback); - } - - - // Once a frame is loaded with this component, call this method to style - // and measure its contents. - // - function setupFrame(pageDiv, frame, callback) { - updateDimensions(pageDiv, function () { - frame.style.visibility = "visible"; - - // Find the place of any chapters in the component. - locateChapters(pageDiv); - - // Nothing can prevent iframe scrolling on Android, so we have to undo it. - if (Monocle.Browser.on.Android) { - Monocle.Events.listen(frame.contentWindow, 'scroll', function () { - frame.contentWindow.scrollTo(0,0); - }); - } - - // Announce that the component has changed. - var doc = frame.contentDocument; - var evtData = { 'page': pageDiv, 'document': doc, 'component': API }; - pageDiv.m.reader.dispatchEvent('monocle:componentchange', evtData); - - callback(); - }); - } - - - // Checks whether the pageDiv dimensions have changed. If they have, - // remeasures dimensions and returns true. Otherwise returns false. - // - function updateDimensions(pageDiv, callback) { - pageDiv.m.dimensions.update(function (pageLength) { - p.pageLength = pageLength; - if (typeof callback == "function") { callback() }; - }); - } - - - // Iterates over all the chapters that are within this component - // (according to the array we were provided on initialization) and finds - // their location (in percentage terms) within the text. - // - // Stores this percentage with the chapter object in the chapters array. - // - function locateChapters(pageDiv) { - if (p.chapters[0] && typeof p.chapters[0].percent == "number") { - return; - } - var doc = pageDiv.m.activeFrame.contentDocument; - for (var i = 0; i < p.chapters.length; ++i) { - var chp = p.chapters[i]; - chp.percent = 0; - if (chp.fragment) { - var node = doc.getElementById(chp.fragment); - chp.percent = pageDiv.m.dimensions.percentageThroughOfNode(node); - } - } - return p.chapters; - } - - - // For a given page number within the component, return the chapter that - // starts on or most-recently-before this page. - // - // Useful, for example, in displaying the current chapter title as a - // running head on the page. - // - function chapterForPage(pageN) { - var cand = null; - var percent = (pageN - 1) / p.pageLength; - for (var i = 0; i < p.chapters.length; ++i) { - if (percent >= p.chapters[i].percent) { - cand = p.chapters[i]; - } else { - return cand; - } - } - return cand; - } - - - // For a given chapter fragment (the bit after the hash - // in eg, "index.html#foo"), return the page number on which - // the chapter starts. If the fragment is null or blank, will - // return the first page of the component. - // - function pageForChapter(fragment, pageDiv) { - if (!fragment) { - return 1; - } - for (var i = 0; i < p.chapters.length; ++i) { - if (p.chapters[i].fragment == fragment) { - return percentToPageNumber(p.chapters[i].percent); - } - } - var doc = pageDiv.m.activeFrame.contentDocument; - var node = doc.getElementById(fragment); - var percent = pageDiv.m.dimensions.percentageThroughOfNode(node); - return percentToPageNumber(percent); - } - - - function pageForXPath(xpath, pageDiv) { - var doc = pageDiv.m.activeFrame.contentDocument; - var percent = 0; - if (Monocle.Browser.env.supportsXPath) { - var node = doc.evaluate(xpath, doc, null, 9, null).singleNodeValue; - if (node) { - percent = pageDiv.m.dimensions.percentageThroughOfNode(node); - } - } else { - console.warn("XPath not supported in this client."); - } - return percentToPageNumber(percent); - } - - - function pageForSelector(selector, pageDiv) { - var doc = pageDiv.m.activeFrame.contentDocument; - var percent = 0; - if (Monocle.Browser.env.supportsQuerySelector) { - var node = doc.querySelector(selector); - if (node) { - percent = pageDiv.m.dimensions.percentageThroughOfNode(node); - } - } else { - console.warn("querySelector not supported in this client."); - } - return percentToPageNumber(percent); - } - - - function percentToPageNumber(pc) { - return Math.floor(pc * p.pageLength) + 1; - } - - - // A public getter for p.pageLength. - // - function lastPageNumber() { - return p.pageLength; - } - - - function prepareSource(reader) { - if (p.sourcePrepared) { return; } - p.sourcePrepared = true; - - if (typeof p.source == "string") { - p.source = { html: p.source }; - } - - // If supplied as escaped javascript, unescape it to HTML by evalling it. - if (p.source.javascript) { - console.deprecation( - "Loading a component by 'javascript' is deprecated. " + - "Use { 'html': src } -- no need to escape or clean the string." - ); - var src = p.source.javascript; - src = src.replace(/\\n/g, "\n"); - src = src.replace(/\\r/g, "\r"); - src = src.replace(/\\'/g, "'"); - p.source = { html: src }; - } - - // If supplied as DOM nodes, convert to HTML by concatenating outerHTMLs. - if (p.source.nodes) { - var srcs = []; - for (var i = 0, ii = p.source.nodes.length; i < ii; ++i) { - var node = p.source.nodes[i]; - if (node.outerHTML) { - srcs.push(node.outerHTML); - } else { - var div = document.createElement('div'); - div.appendChild(node.cloneNode(true)); - srcs.push(div.innerHTML); - delete(div); - } - } - p.source = { html: srcs.join('') }; - } - - if (p.source.html && !p.source.html.match(new RegExp("", "im"))) { - var baseURI = computeBaseURI(reader); - if (baseURI) { - p.source.html = p.source.html.replace( - new RegExp("(]*>)", "im"), - '$1' - ); - } - } - - if (p.source.doc && !p.source.doc.querySelector('base')) { - var srcHead = p.source.doc.querySelector('head') || p.source.doc.body; - var baseURI = computeBaseURI(reader); - if (srcHead && baseURI) { - var srcBase = p.source.doc.createElement('base'); - srcBase.setAttribute('href', baseURI); - prependChild(srcHead, srcBase); - } - } - } - - - function computeBaseURI(reader) { - var evtData = { cmptId: p.id, cmptURI: absoluteURL(p.id) } - if (reader.dispatchEvent('monocle:component:baseuri', evtData, true)) { - return evtData.cmptURI; - } - } - - - function absoluteURL(url) { - var link = document.createElement('a'); - link.setAttribute('href', url); - result = link.href; - delete(link); - return result; - } - - - function prependChild(pr, el) { - pr.firstChild ? pr.insertBefore(el, pr.firstChild) : pr.appendChild(el); - } - - - API.applyTo = applyTo; - API.updateDimensions = updateDimensions; - API.chapterForPage = chapterForPage; - API.pageForChapter = pageForChapter; - API.pageForXPath = pageForXPath; - API.pageForSelector = pageForSelector; - API.lastPageNumber = lastPageNumber; - - return API; -} -; -Monocle.Selection = function (reader) { - var API = { constructor: Monocle.Selection }; - var k = API.constants = API.constructor; - var p = API.properties = { - reader: reader, - lastSelection: [] - }; - - - function initialize() { - if (k.SELECTION_POLLING_INTERVAL) { - setInterval(pollSelection, k.SELECTION_POLLING_INTERVAL); - } - } - - - function pollSelection() { - var index = 0, frame = null; - while (frame = reader.dom.find('component', index++)) { - if (frame.contentWindow) { - pollSelectionOnWindow(frame.contentWindow, index); - } - } - } - - - function pollSelectionOnWindow(win, index) { - var sel = win.getSelection(); - var lm = p.lastSelection[index] || {}; - var nm = p.lastSelection[index] = { - selected: anythingSelected(win), - range: sel.rangeCount ? sel.getRangeAt(0) : null, - string: sel.toString() - }; - if (nm.selected) { - nm.rangeStartContainer = nm.range.startContainer; - nm.rangeEndContainer = nm.range.endContainer; - nm.rangeStartOffset = nm.range.startOffset; - nm.rangeEndOffset = nm.range.endOffset; - if (!sameRange(nm, lm)) { - p.reader.dispatchEvent('monocle:selection', nm); - } - } else if (lm.selected) { - p.reader.dispatchEvent('monocle:deselection', lm); - } - } - - - function sameRange(m1, m2) { - return ( - m1.rangeStartContainer == m2.rangeStartContainer && - m1.rangeEndContainer == m2.rangeEndContainer && - m1.rangeStartOffset == m2.rangeStartOffset && - m1.rangeEndOffset == m2.rangeEndOffset - ); - } - - - // Given a window object, remove any user selections within. Trivial in - // most browsers, but involving major mojo on iOS. - // - function deselect() { - var index = 0, frame = null; - while (frame = reader.dom.find('component', index++)) { - deselectOnWindow(frame.contentWindow); - } - } - - - function deselectOnWindow(win) { - win = win || window; - if (!anythingSelected(win)) { return; } - - if (Monocle.Browser.iOSVersion && !Monocle.Browser.iOSVersionBelow(5)) { - preservingScale(function () { - preservingScrollPosition(function () { - var inp = document.createElement('input'); - inp.style.cssText = [ - 'position: absolute', - 'top: 0', - 'left: 0', - 'width: 0', - 'height: 0' - ].join(';'); - document.body.appendChild(inp); - inp.focus(); - document.body.removeChild(inp); - }) - }); - } - - var sel = win.getSelection(); - sel.removeAllRanges(); - win.document.body.scrollLeft = 0; - win.document.body.scrollTop = 0; - } - - - function preservingScrollPosition(fn) { - var sx = window.scrollX, sy = window.scrollY; - fn(); - window.scrollTo(sx, sy); - } - - - function preservingScale(fn) { - var head = document.querySelector('head'); - var ovp = head.querySelector('meta[name=viewport]'); - var createViewportMeta = function (content) { - var elem = document.createElement('meta'); - elem.setAttribute('name', 'viewport'); - elem.setAttribute('content', content); - head.appendChild(elem); - return elem; - } - - if (ovp) { - var ovpcontent = ovp.getAttribute('content'); - var re = /user-scalable\s*=\s*([^,$\s])*/; - var result = ovpcontent.match(re); - if (result && ['no', '0'].indexOf(result[1]) >= 0) { - fn(); - } else { - var nvpcontent = ovpcontent.replace(re, ''); - nvpcontent += nvpcontent ? ', ' : ''; - nvpcontent += 'user-scalable=no'; - head.removeChild(ovp); - var nvp = createViewportMeta(nvpcontent); - fn(); - head.removeChild(nvp); - head.appendChild(ovp); - } - } else { - var nvp = createViewportMeta('user-scalable=no'); - fn(); - nvp.setAttribute('content', 'user-scalable=yes'); - } - } - - - function anythingSelected(win) { - return !win.getSelection().isCollapsed; - } - - - API.deselect = deselect; - - - initialize(); - - return API; -} - - -Monocle.Selection.SELECTION_POLLING_INTERVAL = 250; -Monocle.Billboard = function (reader) { - var API = { constructor: Monocle.Billboard }; - var k = API.constants = API.constructor; - var p = API.properties = { - reader: reader, - cntr: null - }; - - - function show(urlOrElement, options) { - p.reader.dispatchEvent('monocle:modal:on'); - if (p.cntr) { return console.warn("Modal billboard already showing."); } - - var options = options || {}; - var elem = urlOrElement; - p.cntr = reader.dom.append('div', k.CLS.cntr); - if (typeof urlOrElement == 'string') { - var url = urlOrElement; - p.inner = elem = p.cntr.dom.append('iframe', k.CLS.inner); - elem.setAttribute('src', url); - } else { - p.inner = p.cntr.dom.append('div', k.CLS.inner); - p.inner.appendChild(elem); - } - p.dims = [ - elem.naturalWidth || elem.offsetWidth, - elem.naturalHeight || elem.offsetHeight - ]; - if (options.closeButton != false) { - var cBtn = p.cntr.dom.append('div', k.CLS.closeButton); - Monocle.Events.listenForTap(cBtn, hide); - } - align(options.align || 'left top'); - p.reader.listen('monocle:resize', align); - - shrink(options.from); - Monocle.defer(grow); - } - - - function hide(evt) { - shrink(); - Monocle.Events.afterTransition(p.cntr, remove); - } - - - function grow() { - Monocle.Styles.transitionFor(p.cntr, 'transform', k.ANIM_MS, 'ease-in-out'); - Monocle.Styles.affix(p.cntr, 'transform', 'translate(0, 0) scale(1)'); - } - - - function shrink(from) { - p.from = from || p.from || [0,0]; - var translate = 'translate('+p.from[0]+'px, '+p.from[1]+'px)'; - var scale = 'scale(0)'; - if (typeof p.from[2] === 'number') { - scale = 'scaleX('+(p.from[2] / p.cntr.offsetWidth)+') '; - scale += 'scaleY('+(p.from[3] / p.cntr.offsetHeight)+')'; - } - Monocle.Styles.affix(p.cntr, 'transform', translate+' '+scale); - } - - - function remove () { - p.cntr.parentNode.removeChild(p.cntr); - p.cntr = p.inner = null; - p.reader.deafen('monocle:resize', align); - p.reader.dispatchEvent('monocle:modal:off'); - } - - - function align(loc) { - p.alignment = (typeof loc == 'string') ? loc : p.alignment; - if (!p.alignment) { return; } - if (p.dims[0] > p.inner.offsetWidth || p.dims[1] > p.inner.offsetHeight) { - p.cntr.dom.addClass(k.CLS.oversized); - } else { - p.cntr.dom.removeClass(k.CLS.oversized); - } - - var s = p.alignment.split(/\s+/); - var l = 0, t = 0; - var w = (p.inner.scrollWidth - p.inner.offsetWidth); - var h = (p.inner.scrollHeight - p.inner.offsetHeight); - if (s[0].match(/^\d+$/)) { - l = Math.max(0, parseInt(s[0]) - (p.inner.offsetWidth / 2)); - } else if (s[0] == 'center') { - l = w / 2; - } else if (s[0] == 'right') { - l = w; - } - if (s[1] && s[1].match(/^\d+$/)) { - t = Math.max(0, parseInt(s[1]) - (p.inner.offsetHeight / 2)); - } else if (!s[1] || s[1] == 'center') { - t = h / 2; - } else if (s[1] == 'bottom') { - t = h; - } - p.inner.scrollLeft = l; - p.inner.scrollTop = t; - } - - - API.show = show; - API.hide = hide; - API.align= align; - - return API; -} - - -Monocle.Billboard.CLS = { - cntr: 'billboard_container', - inner: 'billboard_inner', - closeButton: 'billboard_close', - oversized: 'billboard_oversized' -} - -Monocle.Billboard.ANIM_MS = 400; -// A panel is an invisible column of interactivity. When contact occurs -// (mousedown, touchstart), the panel expands to the full width of its -// container, to catch all interaction events and prevent them from hitting -// other things. -// -// Panels are used primarily to provide hit zones for page flipping -// interactions, but you can do whatever you like with them. -// -// After instantiating a panel and adding it to the reader as a control, -// you can call listenTo() with a hash of methods for any of 'start', 'move' -// 'end' and 'cancel'. -// -Monocle.Controls.Panel = function () { - - var API = { constructor: Monocle.Controls.Panel } - var k = API.constants = API.constructor; - var p = API.properties = { - evtCallbacks: {} - } - - function createControlElements(cntr) { - p.div = cntr.dom.make('div', k.CLS.panel); - p.div.dom.setStyles(k.DEFAULT_STYLES); - Monocle.Events.listenForContact( - p.div, - { - 'start': start, - 'move': move, - 'end': end, - 'cancel': cancel - }, - { useCapture: false } - ); - return p.div; - } - - - function setDirection(dir) { - p.direction = dir; - } - - - function listenTo(evtCallbacks) { - p.evtCallbacks = evtCallbacks; - } - - - function deafen() { - p.evtCallbacks = {} - } - - - function start(evt) { - p.contact = true; - evt.m.offsetX += p.div.offsetLeft; - evt.m.offsetY += p.div.offsetTop; - expand(); - invoke('start', evt); - } - - - function move(evt) { - if (!p.contact) { - return; - } - invoke('move', evt); - } - - - function end(evt) { - if (!p.contact) { - return; - } - Monocle.Events.deafenForContact(p.div, p.listeners); - contract(); - p.contact = false; - invoke('end', evt); - } - - - function cancel(evt) { - if (!p.contact) { - return; - } - Monocle.Events.deafenForContact(p.div, p.listeners); - contract(); - p.contact = false; - invoke('cancel', evt); - } - - - function invoke(evtType, evt) { - if (p.evtCallbacks[evtType]) { - p.evtCallbacks[evtType](p.direction, evt.m.offsetX, evt.m.offsetY, API); - } - evt.preventDefault(); - } - - - function expand() { - if (p.expanded) { - return; - } - p.div.dom.addClass(k.CLS.expanded); - p.expanded = true; - } - - - function contract(evt) { - if (!p.expanded) { - return; - } - p.div.dom.removeClass(k.CLS.expanded); - p.expanded = false; - } - - - API.createControlElements = createControlElements; - API.listenTo = listenTo; - API.deafen = deafen; - API.expand = expand; - API.contract = contract; - API.setDirection = setDirection; - - return API; -} - - -Monocle.Controls.Panel.CLS = { - panel: 'panel', - expanded: 'controls_panel_expanded' -} -Monocle.Controls.Panel.DEFAULT_STYLES = { - position: 'absolute', - height: '100%' -} -; -// The simplest page-flipping interaction system: contact to the left half of -// the reader turns back one page, contact to the right half turns forward -// one page. -// -Monocle.Panels.TwoPane = function (flipper, evtCallbacks) { - - var API = { constructor: Monocle.Panels.TwoPane } - var k = API.constants = API.constructor; - var p = API.properties = {} - - - function initialize() { - p.panels = { - forwards: new Monocle.Controls.Panel(), - backwards: new Monocle.Controls.Panel() - } - - for (dir in p.panels) { - flipper.properties.reader.addControl(p.panels[dir]); - p.panels[dir].listenTo(evtCallbacks); - p.panels[dir].setDirection(flipper.constants[dir.toUpperCase()]); - var style = { "width": k.WIDTH }; - style[(dir == "forwards" ? "right" : "left")] = 0; - p.panels[dir].properties.div.dom.setStyles(style); - } - } - - - initialize(); - - return API; -} - -Monocle.Panels.TwoPane.WIDTH = "50%"; -// A three-pane system of page interaction. The left 33% turns backwards, the -// right 33% turns forwards, and contact on the middle third causes the -// system to go into "interactive mode". In this mode, the page-flipping panels -// are only active in the margins, and all of the actual text content of the -// book is selectable. The user can exit "interactive mode" by hitting the little -// IMode icon in the lower right corner of the reader. -// -Monocle.Panels.IMode = function (flipper, evtCallbacks) { - - var API = { constructor: Monocle.Panels.IMode } - var k = API.constants = API.constructor; - var p = API.properties = {} - - - function initialize() { - p.flipper = flipper; - p.reader = flipper.properties.reader; - p.panels = { - forwards: new Monocle.Controls.Panel(), - backwards: new Monocle.Controls.Panel() - } - p.divs = {} - - for (dir in p.panels) { - p.reader.addControl(p.panels[dir]); - p.divs[dir] = p.panels[dir].properties.div; - p.panels[dir].listenTo(evtCallbacks); - p.panels[dir].setDirection(flipper.constants[dir.toUpperCase()]); - p.divs[dir].style.width = "33%"; - p.divs[dir].style[dir == "forwards" ? "right" : "left"] = 0; - } - - p.panels.central = new Monocle.Controls.Panel(); - p.reader.addControl(p.panels.central); - p.divs.central = p.panels.central.properties.div; - p.divs.central.dom.setStyles({ left: "33%", width: "34%" }); - menuCallbacks({ end: modeOn }); - - for (dir in p.panels) { - p.divs[dir].dom.addClass('panels_imode_panel'); - p.divs[dir].dom.addClass('panels_imode_'+dir+'Panel'); - } - - p.toggleIcon = { - createControlElements: function (cntr) { - var div = cntr.dom.make('div', 'panels_imode_toggleIcon'); - Monocle.Events.listenForTap(div, modeOff); - return div; - } - } - p.reader.addControl(p.toggleIcon, null, { hidden: true }); - } - - - function menuCallbacks(callbacks) { - p.menuCallbacks = callbacks; - p.panels.central.listenTo(p.menuCallbacks); - } - - - function toggle() { - p.interactive ? modeOff() : modeOn(); - } - - - function modeOn() { - if (p.interactive) { - return; - } - - p.panels.central.contract(); - - var page = p.reader.visiblePages()[0]; - var sheaf = page.m.sheafDiv; - var bw = sheaf.offsetLeft; - var fw = page.offsetWidth - (sheaf.offsetLeft + sheaf.offsetWidth); - bw = Math.floor(((bw - 2) / page.offsetWidth) * 10000 / 100 ) + "%"; - fw = Math.floor(((fw - 2) / page.offsetWidth) * 10000 / 100 ) + "%"; - - startCameo(function () { - p.divs.forwards.style.width = fw; - p.divs.backwards.style.width = bw; - Monocle.Styles.affix(p.divs.central, 'transform', 'translateY(-100%)'); - }); - - p.reader.showControl(p.toggleIcon); - - p.interactive = true; - } - - - function modeOff() { - if (!p.interactive) { - return; - } - - p.panels.central.contract(); - - p.reader.selection.deselect(); - - startCameo(function () { - p.divs.forwards.style.width = "33%"; - p.divs.backwards.style.width = "33%"; - Monocle.Styles.affix(p.divs.central, 'transform', 'translateY(0)'); - }); - - p.reader.hideControl(p.toggleIcon); - - p.interactive = false; - } - - - function startCameo(fn) { - // Set transitions on the panels. - var trn = Monocle.Panels.IMode.CAMEO_DURATION+"ms ease-in"; - Monocle.Styles.affix(p.divs.forwards, 'transition', "width "+trn); - Monocle.Styles.affix(p.divs.backwards, 'transition', "width "+trn); - Monocle.Styles.affix(p.divs.central, 'transition', "-webkit-transform "+trn); - - // Temporarily disable listeners. - for (var pan in p.panels) { - p.panels[pan].deafen(); - } - - // Set the panels to opaque. - for (var div in p.divs) { - p.divs[div].style.opacity = 1; - } - - if (typeof WebkitTransitionEvent != "undefined") { - p.cameoListener = Monocle.Events.listen( - p.divs.central, - 'webkitTransitionEnd', - endCameo - ); - } else { - setTimeout(endCameo, k.CAMEO_DURATION); - } - fn(); - } - - - function endCameo() { - setTimeout(function () { - // Remove panel transitions. - var trn = "opacity linear " + Monocle.Panels.IMode.LINGER_DURATION + "ms"; - Monocle.Styles.affix(p.divs.forwards, 'transition', trn); - Monocle.Styles.affix(p.divs.backwards, 'transition', trn); - Monocle.Styles.affix(p.divs.central, 'transition', trn); - - // Set the panels to transparent. - for (var div in p.divs) { - p.divs[div].style.opacity = 0; - } - - // Re-enable listeners. - p.panels.forwards.listenTo(evtCallbacks); - p.panels.backwards.listenTo(evtCallbacks); - p.panels.central.listenTo(p.menuCallbacks); - }, Monocle.Panels.IMode.LINGER_DURATION); - - - if (p.cameoListener) { - Monocle.Events.deafen(p.divs.central, 'webkitTransitionEnd', endCameo); - } - } - - - API.toggle = toggle; - API.modeOn = modeOn; - API.modeOff = modeOff; - API.menuCallbacks = menuCallbacks; - - initialize(); - - return API; -} - -Monocle.Panels.IMode.CAMEO_DURATION = 250; -Monocle.Panels.IMode.LINGER_DURATION = 250; -Monocle.Panels.eInk = function (flipper, evtCallbacks) { - - var API = { constructor: Monocle.Panels.eInk } - var k = API.constants = API.constructor; - var p = API.properties = { - flipper: flipper - } - - - function initialize() { - p.panel = new Monocle.Controls.Panel(); - p.reader = p.flipper.properties.reader; - p.reader.addControl(p.panel); - - p.panel.listenTo({ end: function (panel, x) { - if (x < p.panel.properties.div.offsetWidth / 2) { - p.panel.setDirection(flipper.constants.BACKWARDS); - } else { - p.panel.setDirection(flipper.constants.FORWARDS); - } - evtCallbacks.end(panel, x); - } }); - - var s = p.panel.properties.div.style; - p.reader.listen("monocle:componentchanging", function () { - s.opacity = 1; - Monocle.defer(function () { s.opacity = 0 }, 40); - }); - s.width = "100%"; - s.background = "#000"; - s.opacity = 0; - - if (k.LISTEN_FOR_KEYS) { - Monocle.Events.listen(window.top.document, 'keyup', handleKeyEvent); - } - } - - - function handleKeyEvent(evt) { - var eventCharCode = evt.charCode || evt.keyCode; - var dir = null; - if (eventCharCode == k.KEYS["PAGEUP"]) { - dir = flipper.constants.BACKWARDS; - } else if (eventCharCode == k.KEYS["PAGEDOWN"]) { - dir = flipper.constants.FORWARDS; - } - if (dir) { - flipper.moveTo({ direction: dir }); - evt.preventDefault(); - } - } - - - initialize(); - - return API; -} - - -Monocle.Panels.eInk.LISTEN_FOR_KEYS = true; -Monocle.Panels.eInk.KEYS = { "PAGEUP": 33, "PAGEDOWN": 34 }; -// Provides page-flipping panels only in the margins of the book. This is not -// entirely suited to small screens with razor-thin margins, but is an -// appropriate panel class for larger screens (like, say, an iPad). -// -// Since the flipper hit zones are only in the margins, the actual text content -// of the book is always selectable. -// -Monocle.Panels.Marginal = function (flipper, evtCallbacks) { - - var API = { constructor: Monocle.Panels.Marginal } - var k = API.constants = API.constructor; - var p = API.properties = {} - - - function initialize() { - p.panels = { - forwards: new Monocle.Controls.Panel(), - backwards: new Monocle.Controls.Panel() - } - - for (dir in p.panels) { - flipper.properties.reader.addControl(p.panels[dir]); - p.panels[dir].listenTo(evtCallbacks); - p.panels[dir].setDirection(flipper.constants[dir.toUpperCase()]); - with (p.panels[dir].properties.div.style) { - dir == "forwards" ? right = 0 : left = 0; - } - } - setWidths(); - } - - - function setWidths() { - var page = flipper.properties.reader.dom.find('page'); - var sheaf = page.m.sheafDiv; - var bw = sheaf.offsetLeft; - var fw = page.offsetWidth - (sheaf.offsetLeft + sheaf.offsetWidth); - bw = Math.floor(((bw - 2) / page.offsetWidth) * 10000 / 100) + "%"; - fw = Math.floor(((fw - 2) / page.offsetWidth) * 10000 / 100) + "%"; - p.panels.forwards.properties.div.style.width = fw; - p.panels.backwards.properties.div.style.width = bw; - } - - - API.setWidths = setWidths; - - initialize(); - - return API; -} -; -Monocle.Panels.Magic = function (flipper, evtCallbacks) { - - var API = { constructor: Monocle.Panels.Magic } - var k = API.constants = API.constructor; - var p = API.properties = { - flipper: flipper, - evtCallbacks: evtCallbacks, - parts: {}, - action: {}, - contacts: [], - startListeners: [], - disabled: false - } - - - function initialize() { - p.reader = flipper.properties.reader; - p.parts = { - reader: p.reader.dom.find('box'), - cmpts: [] - } - for (var i = 0; i < p.flipper.pageCount; ++i) { - p.parts.cmpts.push(p.reader.dom.find('component', i)); - } - initListeners(); - - p.reader.listen('monocle:componentmodify', initListeners); - p.reader.listen('monocle:magic:init', initListeners); - p.reader.listen('monocle:magic:halt', haltListeners); - p.reader.listen('monocle:modal:on', disable); - p.reader.listen('monocle:modal:off', enable); - Monocle.Events.listen(window, 'gala:contact:cancel', resetAction); - } - - - function initListeners(evt) { - //console.log('magic:init'); - stopListening(); - startListening(); - } - - - function haltListeners(evt) { - //console.log('magic:halt'); - stopListening(); - } - - - function disable(evt) { - //console.log('modal:on - halting magic'); - stopListening(); - p.disabled = true; - } - - - function enable(evt) { - //console.log('modal:off - initing magic'); - p.disabled = false; - startListening(); - } - - - function startListening() { - if (p.disabled || p.startListeners.length) { return; } - - p.startListeners.push([ - p.parts.reader, - Monocle.Events.listenForContact( - p.parts.reader, - { 'start': translatorFunction(p.parts.reader, readerContactStart) } - ) - ]); - - for (var i = 0, ii = p.parts.cmpts.length; i < ii; ++i) { - p.startListeners.push([ - p.parts.cmpts[i].contentDocument.defaultView, - Monocle.Events.listenForContact( - p.parts.cmpts[i].contentDocument.defaultView, - { 'start': translatorFunction(p.parts.cmpts[i], cmptContactStart) } - ) - ]); - } - } - - - function stopListening() { - if (p.disabled || !p.startListeners.length) { return; } - for (var j = 0, jj = p.startListeners.length; j < jj; ++j) { - Monocle.Events.deafenForContact( - p.startListeners[j][0], - p.startListeners[j][1] - ); - } - p.startListeners = []; - } - - - function listenForMoveAndEnd(fnMove, fnEnd) { - listenOnElem( - document.defaultView, - translatorFunction(document.documentElement, fnMove), - translatorFunction(document.documentElement, fnEnd) - ); - for (var i = 0, ii = p.parts.cmpts.length; i < ii; ++i) { - listenOnElem( - p.parts.cmpts[i].contentDocument.defaultView, - translatorFunction(p.parts.cmpts[i], fnMove), - translatorFunction(p.parts.cmpts[i], fnEnd) - ); - } - } - - - function listenOnElem(elem, fnMove, fnEnd) { - var contactListeners = Monocle.Events.listenForContact( - elem, - { - 'move': fnMove, - 'end': function (evt) { deafenContactListeners(); fnEnd(evt); } - } - ); - p.contacts.push([elem, contactListeners]); - } - - - function deafenContactListeners() { - for (var i = 0, ii = p.contacts.length; i < ii; ++i) { - Monocle.Events.deafenForContact(p.contacts[i][0], p.contacts[i][1]); - } - p.contacts = []; - } - - - function readerContactStart(evt) { - listenForMoveAndEnd(readerContactMove, readerContactEnd); - p.action.startX = evt.m.readerX; - p.action.startY = evt.m.readerY; - p.action.screenX = evt.m.screenX; - p.action.screenY = evt.m.screenY; - p.action.dir = evt.m.readerX > halfway() ? k.FORWARDS : k.BACKWARDS; - p.action.handled = !dispatch('monocle:magic:contact:start', evt); - if (!p.action.handled) { invoke('start', evt); } - } - - - function readerContactMove(evt) { - if (p.action.handled) { - dispatch('monocle:magic:contact:move', evt); - } else { - invoke('move', evt); - } - // Can't prevent mousemove, so has no effect there. Preventing default - // for touchmove will override scrolling, while still allowing selection. - evt.preventDefault(); - } - - - function readerContactEnd(evt) { - p.action.endX = evt.m.readerX; - p.action.endY = evt.m.readerY; - if (dispatch('monocle:magic:contact', evt)) { invoke('end', evt); } - p.action = {}; - } - - - function cmptContactStart(evt) { - if (actionIsCancelled(evt)) { return resetAction(); } - p.action.startX = evt.m.readerX; - p.action.startY = evt.m.readerY; - p.action.screenX = evt.m.screenX; - p.action.screenY = evt.m.screenY; - listenForMoveAndEnd(cmptContactMove, cmptContactEnd); - } - - - function cmptContactMove(evt) { - if (actionIsEmpty()) { return; } - if (actionIsCancelled(evt)) { return resetAction(); } - - // Can't prevent mousemove, so has no effect there. Preventing default - // for touchmove will override scrolling, while still allowing selection. - evt.preventDefault(); - } - - - function cmptContactEnd(evt) { - if (actionIsEmpty()) { return; } - if (actionIsCancelled(evt)) { return resetAction(); } - p.action.endX = evt.m.readerX; - p.action.endY = evt.m.readerY; - if (Math.abs(p.action.endX - p.action.startX) < k.LEEWAY) { - p.action.dir = p.action.startX > halfway() ? k.FORWARDS : k.BACKWARDS; - } else { - p.action.dir = p.action.startX > p.action.endX ? k.FORWARDS : k.BACKWARDS; - } - - if (dispatch('monocle:magic:contact', evt)) { - invoke('start', evt); - invoke('end', evt); - } - p.action = {}; - } - - - // Adds two new properties to evt.m: - // - readerX - // - readerY - // - // Calculated as the offset of the click from the top left of reader element. - // - // Then calls the passed function. - // - function translatorFunction(registrant, callback) { - return function (evt) { - translatingReaderOffset(registrant, evt, callback); - } - } - - - function translatingReaderOffset(registrant, evt, callback) { - if (typeof p.action.screenX != 'undefined') { - evt.m.readerX = p.action.startX + (evt.m.screenX - p.action.screenX); - evt.m.readerY = p.action.startY + (evt.m.screenY - p.action.screenY); - } else { - var dr = document.documentElement.getBoundingClientRect(); - var rr = p.parts.reader.getBoundingClientRect(); - rr = { left: rr.left - dr.left, top: rr.top - dr.top } - - if (evt.view == window) { - evt.m.readerX = Math.round(evt.m.pageX - rr.left); - evt.m.readerY = Math.round(evt.m.pageY - rr.top); - } else { - var er = registrant.getBoundingClientRect(); - er = { left: er.left - dr.left, top: er.top - dr.top } - evt.m.readerX = Math.round((er.left - rr.left) + evt.m.clientX); - evt.m.readerY = Math.round((er.top - rr.top) + evt.m.clientY); - } - } - - callback(evt); - } - - - function halfway() { - return p.parts.reader.offsetWidth / 2; - } - - - function resetAction() { - p.action = {}; - deafenContactListeners(); - } - - - function actionIsCancelled(evt) { - var win = evt.target.ownerDocument.defaultView; - return (evt.defaultPrevented || !win.getSelection().isCollapsed); - } - - - function actionIsEmpty() { - return typeof p.action.startX == 'undefined'; - } - - - // Returns true if the event WAS NOT cancelled. - function dispatch(evtName, trigger) { - var rr = p.parts.reader.getBoundingClientRect(); - var evtData = { - trigger: trigger, - start: { x: p.action.startX, y: p.action.startY }, - end: { x: p.action.endX, y: p.action.endY }, - max: { x: rr.right - rr.left, y: rr.bottom - rr.top } - } - return p.reader.dispatchEvent(evtName, evtData, true); - } - - - function invoke(evtType, evt) { - if (p.evtCallbacks[evtType]) { - p.evtCallbacks[evtType](p.action.dir, evt.m.readerX, evt.m.readerY, API); - } - } - - - API.enable = enable; - API.disable = disable; - - initialize(); - - return API; -} - - -Monocle.Panels.Magic.LEEWAY = 3; -Monocle.Panels.Magic.FORWARDS = 1; -Monocle.Panels.Magic.BACKWARDS = -1; -Monocle.Dimensions.Columns = function (pageDiv) { - - var API = { constructor: Monocle.Dimensions.Columns } - var k = API.constants = API.constructor; - var p = API.properties = { - page: pageDiv, - reader: pageDiv.m.reader, - length: 0, - width: 0 - } - - // Logically, forceColumn browsers can't have a gap, because that would - // make the minWidth > 200%. But how much greater? Not worth the effort. - k.GAP = Monocle.Browser.env.forceColumns ? 0 : 20; - - function update(callback) { - setColumnWidth(); - Monocle.defer(function () { - p.length = columnCount(); - if (Monocle.DEBUG) { - console.log( - 'page['+p.page.m.pageIndex+'] -> '+p.length+ - ' ('+p.page.m.activeFrame.m.component.properties.id+')' - ); - } - callback(p.length); - }); - } - - - function setColumnWidth() { - var pdims = pageDimensions(); - var ce = columnedElement(); - - p.width = pdims.width; - - var rules = Monocle.Styles.rulesToString(k.STYLE["columned"]); - rules += Monocle.Browser.css.toCSSDeclaration('column-width', pdims.col+'px'); - rules += Monocle.Browser.css.toCSSDeclaration('column-gap', k.GAP+'px'); - rules += Monocle.Browser.css.toCSSDeclaration('column-fill', 'auto'); - rules += Monocle.Browser.css.toCSSDeclaration('transform', 'none'); - - if (Monocle.Browser.env.forceColumns && ce.scrollHeight > pdims.height) { - rules += Monocle.Styles.rulesToString(k.STYLE['column-force']); - if (Monocle.DEBUG) { - console.warn("Force columns ("+ce.scrollHeight+" > "+pdims.height+")"); - } - } - - if (ce.style.cssText != rules) { - // Update offset because we're translating to zero. - p.page.m.offset = 0; - - // IE10 hack. - if (Monocle.Browser.env.documentElementHasScrollbars) { - ce.ownerDocument.documentElement.style.overflow = 'hidden'; - } - - // Apply body style changes. - ce.style.cssText = rules; - - if (Monocle.Browser.env.scrollToApplyStyle) { - ce.scrollLeft = 0; - } - } - } - - - // Returns the element to which columns CSS should be applied. - // - function columnedElement() { - return p.page.m.activeFrame.contentDocument.body; - } - - - // Returns the width of the offsettable area of the columned element. By - // definition, the number of pages is always this divided by the - // width of a single page (eg, the client area of the columned element). - // - function columnedWidth() { - var bd = columnedElement(); - var de = p.page.m.activeFrame.contentDocument.documentElement; - - var w = Math.max(bd.scrollWidth, de.scrollWidth); - - // Add one because the final column doesn't have right gutter. - // w += k.GAP; - - if (!Monocle.Browser.env.widthsIgnoreTranslate && p.page.m.offset) { - w += p.page.m.offset; - } - return w; - } - - - function pageDimensions() { - var elem = p.page.m.sheafDiv; - var w = elem.clientWidth; - if (elem.getBoundingClientRect) { w = elem.getBoundingClientRect().width; } - if (Monocle.Browser.env.roundPageDimensions) { w = Math.round(w); } - return { col: w, width: w + k.GAP, height: elem.clientHeight } - } - - - function columnCount() { - return Math.ceil(columnedWidth() / pageDimensions().width) - } - - - function locusToOffset(locus) { - return pageDimensions().width * (locus.page - 1); - } - - - // Moves the columned element to the offset implied by the locus. - // - // The 'transition' argument is optional, allowing the translation to be - // animated. If not given, no change is made to the columned element's - // transition property. - // - function translateToLocus(locus, transition) { - var offset = locusToOffset(locus); - p.page.m.offset = offset; - translateToOffset(offset, transition); - return offset; - } - - - function translateToOffset(offset, transition) { - var ce = columnedElement(); - if (transition) { - Monocle.Styles.affix(ce, "transition", transition); - } - // NB: can't use setX as it causes a flicker on iOS. - Monocle.Styles.affix(ce, "transform", "translateX(-"+offset+"px)"); - } - - - function percentageThroughOfNode(target) { - if (!target) { return 0; } - var doc = p.page.m.activeFrame.contentDocument; - var offset = 0; - if (Monocle.Browser.env.findNodesByScrolling) { - // First, remove translation... - translateToOffset(0); - - // Store scroll offsets for all windows. - var win = s = p.page.m.activeFrame.contentWindow; - var scrollers = [ - [win, win.scrollX, win.scrollY], - [window, window.scrollX, window.scrollY] - ]; - //while (s != s.parent) { scrollers.push([s, s.scrollX]); s = s.parent; } - - if (Monocle.Browser.env.sheafIsScroller) { - var scroller = p.page.m.sheafDiv; - var x = scroller.scrollLeft; - target.scrollIntoView(); - offset = scroller.scrollLeft; - } else { - var scroller = win; - var x = scroller.scrollX; - target.scrollIntoView(); - offset = scroller.scrollX; - } - - // Restore scroll offsets for all windows. - while (s = scrollers.shift()) { - s[0].scrollTo(s[1], s[2]); - } - - // ... finally, replace translation. - translateToOffset(p.page.m.offset); - } else { - offset = target.getBoundingClientRect().left; - offset -= doc.body.getBoundingClientRect().left; - } - - // We know at least 1px will be visible, and offset should not be 0. - offset += 1; - - // Percent is the offset divided by the total width of the component. - var percent = offset / (p.length * p.width); - - // Page number would be offset divided by the width of a single page. - // var pageNum = Math.ceil(offset / pageDimensions().width); - - return percent; - } - - - API.update = update; - API.percentageThroughOfNode = percentageThroughOfNode; - - API.locusToOffset = locusToOffset; - API.translateToLocus = translateToLocus; - - return API; -} - - -Monocle.Dimensions.Columns.STYLE = { - // Most of these are already applied to body, but they're repeated here - // in case columnedElement() is ever anything other than body. - "columned": { - "margin": "0", - "padding": "0", - "height": "100%", - "width": "100%", - "position": "absolute" - }, - "column-force": { - "min-width": "200%", - "overflow": "hidden" - } -} -; -Monocle.Flippers.Slider = function (reader) { - - var API = { constructor: Monocle.Flippers.Slider } - var k = API.constants = API.constructor; - var p = API.properties = { - reader: reader, - pageCount: 2, - activeIndex: 1, - turnData: {}, - nextPageReady: true - } - - - function initialize() { - p.reader.listen("monocle:componentchanging", showWaitControl); - } - - - function addPage(pageDiv) { - pageDiv.m.dimensions = new Monocle.Dimensions.Columns(pageDiv); - - // BROWSERHACK: Firefox 4 is prone to beachballing on the first page turn - // unless a zeroed translateX has been applied to the page div. - Monocle.Styles.setX(pageDiv, 0); - } - - - function visiblePages() { - return [upperPage()]; - } - - - function listenForInteraction(panelClass) { - if (typeof panelClass != "function") { - panelClass = k.DEFAULT_PANELS_CLASS; - if (!panelClass) { - console.warn("Invalid panel class.") - } - } - p.panels = new panelClass( - API, - { - 'start': lift, - 'move': turning, - 'end': release, - 'cancel': release - } - ); - } - - - function getPlace(pageDiv) { - pageDiv = pageDiv || upperPage(); - return pageDiv.m ? pageDiv.m.place : null; - } - - - function moveTo(locus, callback) { - var cb = function () { - if (typeof callback == "function") { callback(); } - announceTurn(); - } - setPage(upperPage(), locus, function () { prepareNextPage(cb) }); - } - - - function setPage(pageDiv, locus, onLoad, onFail) { - p.reader.getBook().setOrLoadPageAt( - pageDiv, - locus, - function (locus) { - pageDiv.m.dimensions.translateToLocus(locus); - Monocle.defer(onLoad); - }, - onFail - ); - } - - - function upperPage() { - return p.reader.dom.find('page', p.activeIndex); - } - - - function lowerPage() { - return p.reader.dom.find('page', (p.activeIndex + 1) % 2); - } - - - function flipPages() { - upperPage().style.zIndex = 1; - lowerPage().style.zIndex = 2; - return p.activeIndex = (p.activeIndex + 1) % 2; - } - - - function lift(dir, boxPointX) { - if (p.turnData.lifting || p.turnData.releasing) { return; } - - p.reader.selection.deselect(); - - p.turnData.points = { - start: boxPointX, - min: boxPointX, - max: boxPointX - } - p.turnData.lifting = true; - - var place = getPlace(); - - if (dir == k.FORWARDS) { - if (place.onLastPageOfBook()) { - p.reader.dispatchEvent( - 'monocle:boundaryend', - { - locus: getPlace().getLocus({ direction : dir }), - page: upperPage() - } - ); - resetTurnData(); - return; - } - onGoingForward(boxPointX); - } else if (dir == k.BACKWARDS) { - if (place.onFirstPageOfBook()) { - p.reader.dispatchEvent( - 'monocle:boundarystart', - { - locus: getPlace().getLocus({ direction : dir }), - page: upperPage() - } - ); - resetTurnData(); - return; - } - onGoingBackward(boxPointX); - } else { - console.warn("Invalid direction: " + dir); - } - } - - - function turning(dir, boxPointX) { - if (!p.turnData.points) { return; } - if (p.turnData.lifting || p.turnData.releasing) { return; } - checkPoint(boxPointX); - slideToCursor(boxPointX, null, "0"); - } - - - function release(dir, boxPointX) { - if (!p.turnData.points) { - return; - } - if (p.turnData.lifting) { - p.turnData.releaseArgs = [dir, boxPointX]; - return; - } - if (p.turnData.releasing) { - return; - } - - checkPoint(boxPointX); - - p.turnData.releasing = true; - - if (dir == k.FORWARDS) { - if ( - p.turnData.points.tap || - p.turnData.points.start - boxPointX > 60 || - p.turnData.points.min >= boxPointX - ) { - // Completing forward turn - slideOut(afterGoingForward); - } else { - // Cancelling forward turn - slideIn(afterCancellingForward); - } - } else if (dir == k.BACKWARDS) { - if ( - p.turnData.points.tap || - boxPointX - p.turnData.points.start > 60 || - p.turnData.points.max <= boxPointX - ) { - // Completing backward turn - slideIn(afterGoingBackward); - } else { - // Cancelling backward turn - slideOut(afterCancellingBackward); - } - } else { - console.warn("Invalid direction: " + dir); - } - } - - - function checkPoint(boxPointX) { - p.turnData.points.min = Math.min(p.turnData.points.min, boxPointX); - p.turnData.points.max = Math.max(p.turnData.points.max, boxPointX); - p.turnData.points.tap = p.turnData.points.max - p.turnData.points.min < 10; - } - - - function onGoingForward(x) { - if (p.nextPageReady == false) { - prepareNextPage(function () { lifted(x); }, resetTurnData); - } else { - lifted(x); - } - } - - - function onGoingBackward(x) { - var lp = lowerPage(), up = upperPage(); - var onFail = function () { slideOut(afterCancellingBackward); } - - if (Monocle.Browser.env.offscreenRenderingClipped) { - // set lower to "the page before upper" - setPage( - lp, - getPlace(up).getLocus({ direction: k.BACKWARDS }), - function () { - // flip lower to upper, ready to slide in from left - flipPages(); - // move lower off the screen to the left - jumpOut(lp, function () { lifted(x); }); - }, - onFail - ); - } else { - jumpOut(lp, function () { - flipPages(); - setPage( - lp, - getPlace(up).getLocus({ direction: k.BACKWARDS }), - function () { lifted(x); }, - onFail - ); - }); - } - } - - - function afterGoingForward() { - var up = upperPage(), lp = lowerPage(); - flipPages(); - jumpIn(up, function () { prepareNextPage(announceTurn); }); - } - - - function afterGoingBackward() { - announceTurn(); - } - - - function afterCancellingForward() { - announceCancel(); - } - - - function afterCancellingBackward() { - flipPages(); // flip upper to lower - jumpIn(lowerPage(), function () { prepareNextPage(announceCancel); }); - } - - - // Prepares the lower page to show the next page after the current page, - // and calls onLoad when done. - // - // Note that if the next page is a new component, and it fails to load, - // onFail will be called. If onFail is not supplied, onLoad will be called. - // - function prepareNextPage(onLoad, onFail) { - setPage( - lowerPage(), - getPlace().getLocus({ direction: k.FORWARDS }), - onLoad, - function () { - onFail ? onFail() : onLoad(); - p.nextPageReady = false; - } - ); - } - - - function lifted(x) { - p.turnData.lifting = false; - p.reader.dispatchEvent('monocle:turning'); - var releaseArgs = p.turnData.releaseArgs; - if (releaseArgs) { - p.turnData.releaseArgs = null; - release(releaseArgs[0], releaseArgs[1]); - } else if (x) { - slideToCursor(x); - } - } - - - function announceTurn() { - p.nextPageReady = true; - p.reader.dispatchEvent('monocle:turn'); - resetTurnData(); - } - - - function announceCancel() { - p.reader.dispatchEvent('monocle:turn:cancel'); - resetTurnData(); - } - - - function resetTurnData() { - hideWaitControl(); - p.turnData = {}; - } - - - function setX(elem, x, options, callback) { - var duration, transition; - - if (!options.duration) { - duration = 0; - } else { - duration = parseInt(options.duration); - } - - if (Monocle.Browser.env.supportsTransition) { - Monocle.Styles.transitionFor( - elem, - 'transform', - duration, - options.timing, - options.delay - ); - - if (Monocle.Browser.env.supportsTransform3d) { - Monocle.Styles.affix(elem, 'transform', 'translate3d('+x+'px,0,0)'); - } else { - Monocle.Styles.affix(elem, 'transform', 'translateX('+x+'px)'); - } - - if (typeof callback == "function") { - if (duration && Monocle.Styles.getX(elem) != x) { - Monocle.Events.afterTransition(elem, callback); - } else { - Monocle.defer(callback); - } - } - } else { - // Old-school JS animation. - elem.currX = elem.currX || 0; - var completeTransition = function () { - elem.currX = x; - Monocle.Styles.setX(elem, x); - if (typeof callback == "function") { callback(); } - } - if (!duration) { - completeTransition(); - } else { - var stamp = (new Date()).getTime(); - var frameRate = 40; - var step = (x - elem.currX) * (frameRate / duration); - var stepFn = function () { - var destX = elem.currX + step; - var timeElapsed = ((new Date()).getTime() - stamp) >= duration; - var pastDest = (destX > x && elem.currX < x) || - (destX < x && elem.currX > x); - if (timeElapsed || pastDest) { - completeTransition(); - } else { - Monocle.Styles.setX(elem, destX); - elem.currX = destX; - setTimeout(stepFn, frameRate); - } - } - stepFn(); - } - } - } - - - function jumpIn(pageDiv, callback) { - opts = { duration: (Monocle.Browser.env.stickySlideOut ? 1 : 0) } - setX(pageDiv, 0, opts, callback); - } - - - function jumpOut(pageDiv, callback) { - setX(pageDiv, 0 - pageDiv.offsetWidth, { duration: 0 }, callback); - } - - - // NB: Slides are always done by the visible upper page. - - function slideIn(callback) { - setX(upperPage(), 0, slideOpts(), callback); - } - - - function slideOut(callback) { - setX(upperPage(), 0 - upperPage().offsetWidth, slideOpts(), callback); - } - - - function slideToCursor(cursorX, callback, duration) { - setX( - upperPage(), - Math.min(0, cursorX - upperPage().offsetWidth), - { duration: duration || k.FOLLOW_DURATION }, - callback - ); - } - - - function slideOpts() { - var opts = { timing: 'ease-in', duration: 320 } - var now = (new Date()).getTime(); - if (p.lastSlide && now - p.lastSlide < 1500) { opts.duration *= 0.5; } - p.lastSlide = now; - return opts; - } - - - function ensureWaitControl() { - if (p.waitControl) { return; } - p.waitControl = { - createControlElements: function (holder) { - return holder.dom.make('div', 'flippers_slider_wait'); - } - } - p.reader.addControl(p.waitControl, 'page'); - } - - - function showWaitControl() { - ensureWaitControl(); - p.reader.dom.find('flippers_slider_wait', 0).style.opacity = 1; - p.reader.dom.find('flippers_slider_wait', 1).style.opacity = 1; - } - - - function hideWaitControl() { - ensureWaitControl(); - p.reader.dom.find('flippers_slider_wait', 0).style.opacity = 0; - p.reader.dom.find('flippers_slider_wait', 1).style.opacity = 0; - } - - - // THIS IS THE CORE API THAT ALL FLIPPERS MUST PROVIDE. - API.pageCount = p.pageCount; - API.addPage = addPage; - API.getPlace = getPlace; - API.moveTo = moveTo; - API.listenForInteraction = listenForInteraction; - - // OPTIONAL API - WILL BE INVOKED (WHERE RELEVANT) IF PROVIDED. - API.visiblePages = visiblePages; - - initialize(); - - return API; -} - - -// Constants -Monocle.Flippers.Slider.DEFAULT_PANELS_CLASS = Monocle.Panels.TwoPane; -Monocle.Flippers.Slider.FORWARDS = 1; -Monocle.Flippers.Slider.BACKWARDS = -1; -Monocle.Flippers.Slider.FOLLOW_DURATION = 100; -Monocle.Flippers.Scroller = function (reader, setPageFn) { - - var API = { constructor: Monocle.Flippers.Scroller } - var k = API.constants = API.constructor; - var p = API.properties = { - pageCount: 1, - duration: 300 - } - - - function initialize() { - p.reader = reader; - p.setPageFn = setPageFn; - } - - - function addPage(pageDiv) { - pageDiv.m.dimensions = new Monocle.Dimensions.Columns(pageDiv); - } - - - function page() { - return p.reader.dom.find('page'); - } - - - function listenForInteraction(panelClass) { - if (typeof panelClass != "function") { - panelClass = k.DEFAULT_PANELS_CLASS; - } - p.panels = new panelClass( - API, - { - 'end': turn - } - ); - } - - - function turn(dir) { - if (p.turning) { return; } - p.reader.selection.deselect(); - moveTo({ page: getPlace().pageNumber() + dir}); - p.reader.dispatchEvent('monocle:turning'); - } - - - function getPlace() { - return page().m.place; - } - - - function moveTo(locus, callback) { - var fn = frameToLocus; - if (typeof callback == "function") { - fn = function (locus) { frameToLocus(locus); callback(locus); } - } - p.reader.getBook().setOrLoadPageAt(page(), locus, fn); - } - - - function frameToLocus(locus) { - if (locus.boundarystart || locus.boundaryend) { return; } - p.turning = true; - var dims = page().m.dimensions; - var fr = page().m.activeFrame; - var bdy = fr.contentDocument.body; - var anim = true; - if (p.activeComponent != fr.m.component) { - // No animation. - p.activeComponent = fr.m.component; - dims.translateToLocus(locus, "none"); - Monocle.defer(turned); - } else if (Monocle.Browser.env.supportsTransition) { - // Native animation. - dims.translateToLocus(locus, p.duration+"ms ease-in 0ms"); - Monocle.Events.afterTransition(bdy, turned); - } else { - // Old-school JS animation. - var x = dims.locusToOffset(locus); - var finalX = 0 - x; - var stamp = (new Date()).getTime(); - var frameRate = 40; - var currX = p.currX || 0; - var step = (finalX - currX) * (frameRate / p.duration); - var stepFn = function () { - var destX = currX + step; - if ( - (new Date()).getTime() - stamp > p.duration || - Math.abs(currX - finalX) <= Math.abs((currX + step) - finalX) - ) { - Monocle.Styles.setX(bdy, finalX); - turned(); - } else { - Monocle.Styles.setX(bdy, destX); - currX = destX; - setTimeout(stepFn, frameRate); - } - p.currX = destX; - } - stepFn(); - } - } - - - function turned() { - p.turning = false; - p.reader.dispatchEvent('monocle:turn'); - } - - - // THIS IS THE CORE API THAT ALL FLIPPERS MUST PROVIDE. - API.pageCount = p.pageCount; - API.addPage = addPage; - API.getPlace = getPlace; - API.moveTo = moveTo; - API.listenForInteraction = listenForInteraction; - - initialize(); - - return API; -} - -Monocle.Flippers.Scroller.speed = 200; // How long the animation takes -Monocle.Flippers.Scroller.rate = 20; // frame-rate of the animation -Monocle.Flippers.Scroller.FORWARDS = 1; -Monocle.Flippers.Scroller.BACKWARDS = -1; -Monocle.Flippers.Scroller.DEFAULT_PANELS_CLASS = Monocle.Panels.TwoPane; -Monocle.Flippers.Instant = function (reader) { - - var API = { constructor: Monocle.Flippers.Instant } - var k = API.constants = API.constructor; - var p = API.properties = { - pageCount: 1 - } - - - function initialize() { - p.reader = reader; - } - - - function addPage(pageDiv) { - pageDiv.m.dimensions = new Monocle.Dimensions.Columns(pageDiv); - } - - - function getPlace() { - return page().m.place; - } - - - function moveTo(locus, callback) { - var fn = frameToLocus; - if (typeof callback == "function") { - fn = function (locus) { frameToLocus(locus); callback(locus); } - } - p.reader.getBook().setOrLoadPageAt(page(), locus, fn); - } - - - function listenForInteraction(panelClass) { - if (typeof panelClass != "function") { - if (Monocle.Browser.on.Kindle3) { - panelClass = Monocle.Panels.eInk; - } - panelClass = panelClass || k.DEFAULT_PANELS_CLASS; - } - if (!panelClass) { throw("Panels not found."); } - p.panels = new panelClass(API, { 'end': turn }); - } - - - function page() { - return p.reader.dom.find('page'); - } - - - function turn(dir) { - p.reader.selection.deselect(); - moveTo({ page: getPlace().pageNumber() + dir}); - p.reader.dispatchEvent('monocle:turning'); - } - - - function frameToLocus(locus) { - page().m.dimensions.translateToLocus(locus); - Monocle.defer(function () { p.reader.dispatchEvent('monocle:turn'); }); - } - - - // THIS IS THE CORE API THAT ALL FLIPPERS MUST PROVIDE. - API.pageCount = p.pageCount; - API.addPage = addPage; - API.getPlace = getPlace; - API.moveTo = moveTo; - API.listenForInteraction = listenForInteraction; - - initialize(); - - return API; -} - -Monocle.Flippers.Instant.FORWARDS = 1; -Monocle.Flippers.Instant.BACKWARDS = -1; -Monocle.Flippers.Instant.DEFAULT_PANELS_CLASS = Monocle.Panels.TwoPane; - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/COPS/cops-3.1.3/resources/monocle/scripts/monoctrl.js b/COPS/cops-3.1.3/resources/monocle/scripts/monoctrl.js deleted file mode 100644 index 5e715526..00000000 --- a/COPS/cops-3.1.3/resources/monocle/scripts/monoctrl.js +++ /dev/null @@ -1,985 +0,0 @@ -Monocle.Controls.Contents = function (reader) { - - var API = { constructor: Monocle.Controls.Contents } - var k = API.constants = API.constructor; - var p = API.properties = { - reader: reader - } - - - function createControlElements() { - var div = reader.dom.make('div', 'controls_contents_container'); - contentsForBook(div, reader.getBook()); - return div; - } - - - function contentsForBook(div, book) { - while (div.hasChildNodes()) { - div.removeChild(div.firstChild); - } - var list = div.dom.append('ol', 'controls_contents_list'); - - var contents = book.properties.contents; - for (var i = 0; i < contents.length; ++i) { - chapterBuilder(list, contents[i], 0); - } - } - - - function chapterBuilder(list, chp, padLvl) { - var index = list.childNodes.length; - var li = list.dom.append('li', 'controls_contents_chapter', index); - var span = li.dom.append( - 'span', - 'controls_contents_chapterTitle', - index, - { html: chp.title } - ); - span.style.paddingLeft = padLvl + "em"; - - var invoked = function () { - p.reader.skipToChapter(chp.src); - p.reader.hideControl(API); - } - - Monocle.Events.listenForTap(li, invoked, 'controls_contents_chapter_active'); - - if (chp.children) { - for (var i = 0; i < chp.children.length; ++i) { - chapterBuilder(list, chp.children[i], padLvl + 1); - } - } - } - - - API.createControlElements = createControlElements; - - return API; -} -; -Monocle.Controls.Magnifier = function (reader) { - - var API = { constructor: Monocle.Controls.Magnifier } - var k = API.constants = API.constructor; - var p = API.properties = { - buttons: [], - magnified: false - } - - - function initialize() { - p.reader = reader; - } - - - function createControlElements(holder) { - var btn = holder.dom.make('div', 'controls_magnifier_button'); - btn.smallA = btn.dom.append('span', 'controls_magnifier_a', { text: 'A' }); - btn.largeA = btn.dom.append('span', 'controls_magnifier_A', { text: 'A' }); - p.buttons.push(btn); - Monocle.Events.listenForTap(btn, toggleMagnification); - return btn; - } - - - function toggleMagnification(evt) { - var opacities; - p.magnified = !p.magnified; - if (p.magnified) { - opacities = [0.3, 1]; - p.reader.formatting.setFontScale(k.MAGNIFICATION, true); - } else { - opacities = [1, 0.3]; - p.reader.formatting.setFontScale(null, true); - } - - for (var i = 0; i < p.buttons.length; i++) { - p.buttons[i].smallA.style.opacity = opacities[0]; - p.buttons[i].largeA.style.opacity = opacities[1]; - } - } - - API.createControlElements = createControlElements; - - initialize(); - - return API; -} - - -Monocle.Controls.Magnifier.MAGNIFICATION = 1.2; -// A panel is an invisible column of interactivity. When contact occurs -// (mousedown, touchstart), the panel expands to the full width of its -// container, to catch all interaction events and prevent them from hitting -// other things. -// -// Panels are used primarily to provide hit zones for page flipping -// interactions, but you can do whatever you like with them. -// -// After instantiating a panel and adding it to the reader as a control, -// you can call listenTo() with a hash of methods for any of 'start', 'move' -// 'end' and 'cancel'. -// -Monocle.Controls.Panel = function () { - - var API = { constructor: Monocle.Controls.Panel } - var k = API.constants = API.constructor; - var p = API.properties = { - evtCallbacks: {} - } - - function createControlElements(cntr) { - p.div = cntr.dom.make('div', k.CLS.panel); - p.div.dom.setStyles(k.DEFAULT_STYLES); - Monocle.Events.listenForContact( - p.div, - { - 'start': start, - 'move': move, - 'end': end, - 'cancel': cancel - }, - { useCapture: false } - ); - return p.div; - } - - - function setDirection(dir) { - p.direction = dir; - } - - - function listenTo(evtCallbacks) { - p.evtCallbacks = evtCallbacks; - } - - - function deafen() { - p.evtCallbacks = {} - } - - - function start(evt) { - p.contact = true; - evt.m.offsetX += p.div.offsetLeft; - evt.m.offsetY += p.div.offsetTop; - expand(); - invoke('start', evt); - } - - - function move(evt) { - if (!p.contact) { - return; - } - invoke('move', evt); - } - - - function end(evt) { - if (!p.contact) { - return; - } - Monocle.Events.deafenForContact(p.div, p.listeners); - contract(); - p.contact = false; - invoke('end', evt); - } - - - function cancel(evt) { - if (!p.contact) { - return; - } - Monocle.Events.deafenForContact(p.div, p.listeners); - contract(); - p.contact = false; - invoke('cancel', evt); - } - - - function invoke(evtType, evt) { - if (p.evtCallbacks[evtType]) { - p.evtCallbacks[evtType](p.direction, evt.m.offsetX, evt.m.offsetY, API); - } - evt.preventDefault(); - } - - - function expand() { - if (p.expanded) { - return; - } - p.div.dom.addClass(k.CLS.expanded); - p.expanded = true; - } - - - function contract(evt) { - if (!p.expanded) { - return; - } - p.div.dom.removeClass(k.CLS.expanded); - p.expanded = false; - } - - - API.createControlElements = createControlElements; - API.listenTo = listenTo; - API.deafen = deafen; - API.expand = expand; - API.contract = contract; - API.setDirection = setDirection; - - return API; -} - - -Monocle.Controls.Panel.CLS = { - panel: 'panel', - expanded: 'controls_panel_expanded' -} -Monocle.Controls.Panel.DEFAULT_STYLES = { - position: 'absolute', - height: '100%' -} -; -Monocle.Controls.PlaceSaver = function (bookId) { - - var API = { constructor: Monocle.Controls.PlaceSaver } - var k = API.constants = API.constructor; - var p = API.properties = {} - - - function initialize() { - applyToBook(bookId); - } - - - function assignToReader(reader) { - p.reader = reader; - p.reader.listen('monocle:turn', savePlaceToCookie); - } - - - function applyToBook(bookId) { - p.bkTitle = bookId.toLowerCase().replace(/[^a-z0-9]/g, ''); - p.prefix = k.COOKIE_NAMESPACE + p.bkTitle + "."; - } - - - function setCookie(key, value, days) { - var expires = ""; - if (days) { - var d = new Date(); - d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000)); - expires = "; expires="+d.toGMTString(); - } - var path = "; path=/"; - document.cookie = p.prefix + key + "=" + value + expires + path; - return value; - } - - - function getCookie(key) { - if (!document.cookie) { - return null; - } - var regex = new RegExp(p.prefix + key + "=(.+?)(;|$)"); - var matches = document.cookie.match(regex); - if (matches) { - return matches[1]; - } else { - return null; - } - } - - - function savePlaceToCookie() { - var place = p.reader.getPlace(); - setCookie( - "component", - encodeURIComponent(place.componentId()), - k.COOKIE_EXPIRES_IN_DAYS - ); - setCookie( - "percent", - place.percentageThrough(), - k.COOKIE_EXPIRES_IN_DAYS - ); - } - - - function savedPlace() { - var locus = { - componentId: getCookie('component'), - percent: getCookie('percent') - } - if (locus.componentId && locus.percent) { - locus.componentId = decodeURIComponent(locus.componentId); - locus.percent = parseFloat(locus.percent); - return locus; - } else { - return null; - } - } - - - function restorePlace() { - var locus = savedPlace(); - if (locus) { - p.reader.moveTo(locus); - } - } - - - API.assignToReader = assignToReader; - API.savedPlace = savedPlace; - API.restorePlace = restorePlace; - - initialize(); - - return API; -} - -Monocle.Controls.PlaceSaver.COOKIE_NAMESPACE = "monocle.controls.placesaver."; -Monocle.Controls.PlaceSaver.COOKIE_EXPIRES_IN_DAYS = 7; // Set to 0 for session-based expiry. -; -Monocle.Controls.Scrubber = function (reader) { - - var API = { constructor: Monocle.Controls.Scrubber } - var k = API.constants = API.constructor; - var p = API.properties = {} - - - function initialize() { - p.reader = reader; - p.reader.listen('monocle:turn', updateNeedles); - updateNeedles(); - } - - - function pixelToPlace(x, cntr) { - if (!p.componentIds) { - p.componentIds = p.reader.getBook().properties.componentIds; - p.componentWidth = 100 / p.componentIds.length; - } - var pc = (x / cntr.offsetWidth) * 100; - var cmpt = p.componentIds[Math.floor(pc / p.componentWidth)]; - var cmptPc = ((pc % p.componentWidth) / p.componentWidth); - return { componentId: cmpt, percentageThrough: cmptPc }; - } - - - function placeToPixel(place, cntr) { - if (!p.componentIds) { - p.componentIds = p.reader.getBook().properties.componentIds; - p.componentWidth = 100 / p.componentIds.length; - } - var componentIndex = p.componentIds.indexOf(place.componentId()); - var pc = p.componentWidth * componentIndex; - pc += place.percentageThrough() * p.componentWidth; - return Math.round((pc / 100) * cntr.offsetWidth); - } - - - function updateNeedles() { - if (p.hidden || !p.reader.dom.find(k.CLS.container)) { - return; - } - var place = p.reader.getPlace(); - var x = placeToPixel(place, p.reader.dom.find(k.CLS.container)); - var needle, i = 0; - for (var i = 0, needle; needle = p.reader.dom.find(k.CLS.needle, i); ++i) { - setX(needle, x - needle.offsetWidth / 2); - p.reader.dom.find(k.CLS.trail, i).style.width = x + "px"; - } - } - - - function setX(node, x) { - var cntr = p.reader.dom.find(k.CLS.container); - x = Math.min(cntr.offsetWidth - node.offsetWidth, x); - x = Math.max(x, 0); - Monocle.Styles.setX(node, x); - } - - - function createControlElements(holder) { - var cntr = holder.dom.make('div', k.CLS.container); - var track = cntr.dom.append('div', k.CLS.track); - var needleTrail = cntr.dom.append('div', k.CLS.trail); - var needle = cntr.dom.append('div', k.CLS.needle); - var bubble = cntr.dom.append('div', k.CLS.bubble); - - var cntrListeners, bodyListeners; - - var moveEvt = function (evt, x) { - evt.preventDefault(); - x = (typeof x == "number") ? x : evt.m.registrantX; - var place = pixelToPlace(x, cntr); - setX(needle, x - needle.offsetWidth / 2); - var book = p.reader.getBook(); - var chps = book.chaptersForComponent(place.componentId); - var cmptIndex = p.componentIds.indexOf(place.componentId); - var chp = chps[Math.floor(chps.length * place.percentageThrough)]; - if (cmptIndex > -1 && book.properties.components[cmptIndex]) { - var actualPlace = Monocle.Place.FromPercentageThrough( - book.properties.components[cmptIndex], - place.percentageThrough - ); - chp = actualPlace.chapterInfo() || chp; - } - - if (chp) { - bubble.innerHTML = chp.title; - } - setX(bubble, x - bubble.offsetWidth / 2); - - p.lastX = x; - return place; - } - - var endEvt = function (evt) { - var place = moveEvt(evt, p.lastX); - p.reader.moveTo({ - percent: place.percentageThrough, - componentId: place.componentId - }); - Monocle.Events.deafenForContact(cntr, cntrListeners); - Monocle.Events.deafenForContact(document.body, bodyListeners); - bubble.style.display = "none"; - } - - var startFn = function (evt) { - bubble.style.display = "block"; - moveEvt(evt); - cntrListeners = Monocle.Events.listenForContact( - cntr, - { move: moveEvt } - ); - bodyListeners = Monocle.Events.listenForContact( - document.body, - { end: endEvt } - ); - } - - Monocle.Events.listenForContact(cntr, { start: startFn }); - - return cntr; - } - - - API.createControlElements = createControlElements; - API.updateNeedles = updateNeedles; - - initialize(); - - return API; -} - -Monocle.Controls.Scrubber.CLS = { - container: 'controls_scrubber_container', - track: 'controls_scrubber_track', - needle: 'controls_scrubber_needle', - trail: 'controls_scrubber_trail', - bubble: 'controls_scrubber_bubble' -} -; -Monocle.Controls.Spinner = function (reader) { - - var API = { constructor: Monocle.Controls.Spinner } - var k = API.constants = API.constructor; - var p = API.properties = { - reader: reader, - divs: [], - repeaters: {}, - showForPages: [] - } - - - function createControlElements(cntr) { - var anim = cntr.dom.make('div', 'controls_spinner_anim'); - anim.dom.append('div', 'controls_spinner_inner'); - p.divs.push(anim); - return anim; - } - - - function registerSpinEvent(startEvtType, stopEvtType) { - var label = startEvtType; - p.reader.listen(startEvtType, function (evt) { spin(label, evt) }); - p.reader.listen(stopEvtType, function (evt) { spun(label, evt) }); - } - - - // Registers spin/spun event handlers for certain time-consuming events. - // - function listenForUsualDelays() { - registerSpinEvent('monocle:componentloading', 'monocle:componentloaded'); - registerSpinEvent('monocle:componentchanging', 'monocle:componentchange'); - registerSpinEvent('monocle:resizing', 'monocle:resize'); - registerSpinEvent('monocle:jumping', 'monocle:jump'); - registerSpinEvent('monocle:recalculating', 'monocle:recalculated'); - p.reader.listen('monocle:notfound', forceSpun); - p.reader.listen('monocle:componentfailed', forceSpun); - } - - - // Displays the spinner. Both arguments are optional. - // - function spin(label, evt) { - label = label || k.GENERIC_LABEL; - p.repeaters[label] = true; - p.reader.showControl(API); - - // If the delay is on a page other than the page we've been assigned to, - // don't show the animation. p.global ensures that if an event affects - // all pages, the animation is always shown, even if other events in this - // spin cycle are page-specific. - var page = (evt && evt.m && evt.m.page) ? evt.m.page : null; - if (page && p.divs.length > 1) { - p.showForPages[page.m.pageIndex] = true; - } else { - p.global = true; - p.reader.dispatchEvent('monocle:modal:on'); - } - for (var i = 0; i < p.divs.length; ++i) { - var show = (p.global || p.showForPages[i]) ? true : false; - p.divs[i].dom[show ? 'removeClass' : 'addClass']('dormant'); - } - } - - - // Stops displaying the spinner. Both arguments are optional. - // - function spun(label, evt) { - label = label || k.GENERIC_LABEL; - p.repeaters[label] = false; - for (var l in p.repeaters) { - if (p.repeaters[l]) { return; } - } - forceSpun(); - } - - - function forceSpun() { - if (p.global) { p.reader.dispatchEvent('monocle:modal:off'); } - p.global = false; - p.repeaters = {}; - p.showForPages = []; - for (var i = 0; i < p.divs.length; ++i) { - p.divs[i].dom.addClass('dormant'); - } - } - - - API.createControlElements = createControlElements; - API.registerSpinEvent = registerSpinEvent; - API.listenForUsualDelays = listenForUsualDelays; - API.spin = spin; - API.spun = spun; - API.forceSpun = forceSpun; - - return API; -} - -Monocle.Controls.Spinner.GENERIC_LABEL = "generic"; -Monocle.Controls.Stencil = function (reader, behaviorClasses) { - - var API = { constructor: Monocle.Controls.Stencil } - var k = API.constants = API.constructor; - var p = API.properties = { - reader: reader, - behaviors: [], - components: {}, - masks: [] - } - - - // Create the stencil container and listen for draw/update events. - // - function createControlElements(holder) { - behaviorClasses = behaviorClasses || k.DEFAULT_BEHAVIORS; - for (var i = 0, ii = behaviorClasses.length; i < ii; ++i) { - addBehavior(behaviorClasses[i]); - } - p.container = holder.dom.make('div', k.CLS.container); - p.reader.listen('monocle:turning', hide); - p.reader.listen('monocle:turn:cancel', show); - p.reader.listen('monocle:turn', update); - p.reader.listen('monocle:stylesheetchange', update); - p.reader.listen('monocle:resize', update); - update(); - return p.container; - } - - - // Pass this method an object that responds to 'findElements(doc)' with - // an array of DOM elements for that document, and to 'fitMask(elem, mask)'. - // - // After you have added all your behaviors this way, you would typically - // call update() to make them take effect immediately. - // - function addBehavior(bhvrClass) { - var bhvr = new bhvrClass(API); - if (typeof bhvr.findElements != 'function') { - console.warn('Missing "findElements" method for behavior: %o', bhvr); - } - if (typeof bhvr.fitMask != 'function') { - console.warn('Missing "fitMask" method for behavior: %o', bhvr); - } - p.behaviors.push(bhvr); - } - - - // Resets any pre-calculated rectangles for the active component, - // recalculates them, and forces masks to be "drawn" (moved into the new - // rectangular locations). - // - function update() { - var visPages = p.reader.visiblePages(); - if (!visPages || !visPages.length) { return; } - var pageDiv = visPages[0]; - var cmptId = pageComponentId(pageDiv); - if (!cmptId) { return; } - p.components[cmptId] = null; - calculateRectangles(pageDiv); - draw(); - } - - - function hide() { - p.container.style.display = 'none'; - } - - - function show() { - p.container.style.display = 'block'; - } - - - // Removes any existing masks. - function clear() { - while (p.container.childNodes.length) { - p.container.removeChild(p.container.lastChild); - } - } - - - // Aligns the stencil container to the shape of the page, then moves the - // masks to sit above any currently visible rectangles. - // - function draw() { - var pageDiv = p.reader.visiblePages()[0]; - var cmptId = pageComponentId(pageDiv); - if (!p.components[cmptId]) { - return; - } - - // Position the container. - alignToComponent(pageDiv); - - // Clear old masks. - clear(); - - // Layout the masks. - if (!p.disabled) { - show(); - var rects = p.components[cmptId]; - if (rects && rects.length) { - layoutRectangles(pageDiv, rects); - } - } - } - - - // Iterate over all the
    elements in the active component, and - // create an array of rectangular points corresponding to their positions. - // - function calculateRectangles(pageDiv) { - var cmptId = pageComponentId(pageDiv); - if (!p.components[cmptId]) { - p.components[cmptId] = []; - } else { - return; - } - - var doc = pageDiv.m.activeFrame.contentDocument; - var offset = getOffset(pageDiv); - - for (var b = 0, bb = p.behaviors.length; b < bb; ++b) { - var bhvr = p.behaviors[b]; - var elems = bhvr.findElements(doc); - for (var i = 0; i < elems.length; ++i) { - var elem = elems[i]; - if (elem.getClientRects) { - var r = elem.getClientRects(); - for (var j = 0; j < r.length; j++) { - p.components[cmptId].push({ - element: elem, - behavior: bhvr, - left: Math.ceil(r[j].left + offset.l), - top: Math.ceil(r[j].top), - width: Math.floor(r[j].width), - height: Math.floor(r[j].height) - }); - } - } - } - } - - return p.components[cmptId]; - } - - - // Update location of visible rectangles - creating as required. - // - function layoutRectangles(pageDiv, rects) { - var offset = getOffset(pageDiv); - var visRects = []; - for (var i = 0; i < rects.length; ++i) { - if (rectVisible(rects[i], offset.l, offset.l + offset.w)) { - visRects.push(rects[i]); - } - } - - for (i = 0; i < visRects.length; ++i) { - var r = visRects[i]; - var cr = { - left: r.left - offset.l, - top: r.top, - width: r.width, - height: r.height - }; - var mask = createMask(r.element, r.behavior); - mask.dom.setStyles({ - display: 'block', - left: cr.left+"px", - top: cr.top+"px", - width: cr.width+"px", - height: cr.height+"px", - position: 'absolute' - }); - mask.stencilRect = cr; - } - } - - - // Find the offset position in pixels from the left of the current page. - // - function getOffset(pageDiv) { - return { - l: pageDiv.m.offset || 0, - w: pageDiv.m.dimensions.properties.width - }; - } - - - // Is this area presently on the screen? - // - function rectVisible(rect, l, r) { - return rect.left >= l && rect.left < r; - } - - - // Returns the active component id for the given page, or the current - // page if no argument passed in. - // - function pageComponentId(pageDiv) { - pageDiv = pageDiv || p.reader.visiblePages()[0]; - if (!pageDiv.m.activeFrame.m.component) { return; } - return pageDiv.m.activeFrame.m.component.properties.id; - } - - - // Positions the stencil container over the active frame. - // - function alignToComponent(pageDiv) { - cmpt = pageDiv.m.activeFrame.parentNode; - p.container.dom.setStyles({ - left: cmpt.offsetLeft+"px", - top: cmpt.offsetTop+"px" - }); - } - - - function createMask(element, bhvr) { - var mask = p.container.dom.append(bhvr.maskTagName || 'div', k.CLS.mask); - Monocle.Events.listenForContact(mask, { - start: function () { p.reader.dispatchEvent('monocle:magic:halt'); }, - move: function (evt) { evt.preventDefault(); }, - end: function () { p.reader.dispatchEvent('monocle:magic:init'); } - }); - bhvr.fitMask(element, mask); - return mask; - } - - - // Make the active masks visible (by giving them a class -- override style - // in monoctrl.css). - // - function toggleHighlights() { - var cls = k.CLS.highlights; - if (p.container.dom.hasClass(cls)) { - p.container.dom.removeClass(cls); - } else { - p.container.dom.addClass(cls); - } - } - - - function disable() { - p.disabled = true; - draw(); - } - - - function enable() { - p.disabled = false; - draw(); - } - - - function filterElement(elem, behavior) { - if (typeof behavior.filterElement == 'function') { - return behavior.filterElement(elem); - } - return elem; - } - - - function maskAssigned(elem, mask, behavior) { - if (typeof behavior.maskAssigned == 'function') { - return behavior.maskAssigned(elem, mask); - } - return false; - } - - - API.createControlElements = createControlElements; - API.addBehavior = addBehavior; - API.draw = draw; - API.update = update; - API.toggleHighlights = toggleHighlights; - - return API; -} - - -Monocle.Controls.Stencil.CLS = { - container: 'controls_stencil_container', - mask: 'controls_stencil_mask', - highlights: 'controls_stencil_highlighted' -} - - - -Monocle.Controls.Stencil.Links = function (stencil) { - var API = { constructor: Monocle.Controls.Stencil.Links } - - // Optionally specify the HTML tagname of the mask. - API.maskTagName = 'a'; - - // Returns an array of all the elements in the given doc that should - // be covered with a stencil mask for interactivity. - // - // (Hint: doc.querySelectorAll() is your friend.) - // - API.findElements = function (doc) { - return doc.querySelectorAll('a[href]'); - } - - - // Return an element. It should usually be a child of the container element, - // with a className of the given maskClass. You set up the interactivity of - // the mask element here. - // - API.fitMask = function (link, mask) { - var hrefObject = deconstructHref(link); - - if (hrefObject.internal) { - mask.setAttribute('href', 'javascript:"Skip to chapter"'); - mask.onclick = function (evt) { - stencil.properties.reader.skipToChapter(hrefObject.internal); - evt.preventDefault(); - return false; - } - } else { - mask.setAttribute('href', hrefObject.external); - mask.setAttribute('target', '_blank'); - mask.onclick = function (evt) { return true; } - } - - link.onclick = function (evt) { - evt.preventDefault(); - return false; - } - } - - - // Returns an object with either: - // - // - an 'external' property -- an absolute URL with a protocol, - // host & etc, which should be treated as an external resource (eg, - // open in new window) - // - // OR - // - // - an 'internal' property -- a relative URL (with optional hash anchor), - // that is treated as a link to component in the book - // - // A weird but useful property of tags is that while - // link.getAttribute('href') will return the actual string value of the - // attribute (eg, 'foo.html'), link.href will return the absolute URL (eg, - // 'http://example.com/monocles/foo.html'). - // - function deconstructHref(elem) { - var loc = document.location; - var origin = loc.protocol+'//'+loc.host; - var href = elem.href; - var path = href.substring(origin.length); - var ext = { external: href }; - - // Anchor tags with 'target' attributes are always external URLs. - if (elem.getAttribute('target')) { - return ext; - } - // URLs with a different protocol or domain are always external. - //console.log("Domain test: %s <=> %s", origin, href); - if (href.indexOf(origin) != 0) { - return ext; - } - - // If it is in a sub-path of the current path, it's internal. - var topPath = loc.pathname.replace(/[^\/]*\.[^\/]+$/,''); - if (topPath[topPath.length - 1] != '/') { - topPath += '/'; - } - //console.log("Sub-path test: %s <=> %s", topPath, path); - if (path.indexOf(topPath) == 0) { - return { internal: path.substring(topPath.length) } - } - - // If it's a root-relative URL and it's in our list of component ids, - // it's internal. - var cmptIds = stencil.properties.reader.getBook().properties.componentIds; - for (var i = 0, ii = cmptIds.length; i < ii; ++i) { - //console.log("Component test: %s <=> %s", cmptIds[i], path); - if (path.indexOf(cmptIds[i]) == 0) { - return { internal: path } - } - } - - // Otherwise it's external. - return ext; - } - - - return API; -} - - -Monocle.Controls.Stencil.DEFAULT_BEHAVIORS = [Monocle.Controls.Stencil.Links]; diff --git a/COPS/cops-3.1.3/resources/monocle/styles/monocore.css b/COPS/cops-3.1.3/resources/monocle/styles/monocore.css deleted file mode 100644 index 02b49517..00000000 --- a/COPS/cops-3.1.3/resources/monocle/styles/monocore.css +++ /dev/null @@ -1,195 +0,0 @@ -/*=========================================================================== - -This is a base-level Monocle stylesheet. It assumes no class-prefix has been -given to the Reader during initialisation - if one has, you can copy and -modify this stylesheet accordingly. - ----------------------------------------------------------------------------*/ - -/* The reader object that holds pretty much everything. - * (A direct child of the element passed to reader initialisation). */ - -div.monelem_container { - background-color: black; -} - - -/* The div that mimics a leaf of paper in a book. */ -div.monelem_page { - background: white; - top: 0; - left: 0; - bottom: 3px; - right: 5px; - border-right: 1px solid #999; -} - - -/* The div within the page that determines page margins. */ -div.monelem_sheaf { - top: 1em; - left: 1em; - bottom: 1em; - right: 1em; -} - - -/* The iframe within the page that loads the content of the book. */ -div.monelem_component { -} - - -/* A panel that sits above the entire reader object, holding controls. */ -div.monelem_overlay { -} - - -/* A full-size panel to display an announcement (iframe or div) */ -div.monelem_billboard_container { - background: #FFF; - position: absolute; - top: 0; - left: 0; - height: 100%; - width: 100%; - z-index: 2000; - -webkit-transform: scale(0); - -moz-transform: scale(0); - transform: scale(0); - -webkit-transform-origin: -0 -0; - -moz-transform-origin: -0 -0; - transform-origin: -0 -0; -} - -.monelem_billboard_inner { - height: 100%; - width: 100%; - border: none; - overflow: auto; - /*-webkit-overflow-scrolling: touch;*/ /* This is sexy, but crashy. */ -} - -div.monelem_billboard_inner { - min-width: 100%; - min-height: 100%; - text-align: center; - vertical-align: middle; - display: -webkit-box; - -webkit-box-pack: center; - -webkit-box-align: center; -} - - -div.monelem_billboard_close { - position: absolute; - top: 0; - right: 0; - width: 50px; - height: 30px; - color: white; - background: #C00; - cursor: pointer; - border-bottom-left-radius: 4px; - text-shadow: 1px 1px 1px #900; - font: 9pt Helvetica Neue, Helvetica, sans-serif; -} - -div.monelem_billboard_close:after { - display: block; - content: 'Close'; - width: 100%; - line-height: 30px; - text-align: center; -} - -div.monelem_book_fatality { - font-family: Helvetica Neue, Helvetica, sans-serif; - margin: 0 auto; - max-width: 75%; -} - -div.monelem_book_fatality p { - line-height: 1.4; -} - - -/*=========================================================================== - PANELS ----------------------------------------------------------------------------*/ - - -.monelem_panels_imode_panel { - background: rgba(255,255,255,0.7); - opacity: 0; -} - -.monelem_panels_imode_backwardsPanel { - -webkit-box-shadow: 1px 1px 3px #777; - -moz-box-shadow: 1px 1px 3px #777; - box-shadow: 1px 1px 3px #777; -} - -.monelem_panels_imode_forwardsPanel { - -webkit-box-shadow: -1px 1px 3px #777; - -moz-box-shadow: -1px 1px 3px #777; - box-shadow: -1px 1px 3px #777; -} - -.monelem_panels_imode_centralPanel { -} - -.monelem_panels_imode_toggleIcon { - position: absolute; - right: 0; - bottom: 0; - width: 50px; - height: 50px; - background-repeat: no-repeat; - background-position: center center; -} - -/* If you modify this you could significantly change the way panels work. */ -div.monelem_controls_panel_expanded { - left: 0 !important; - width: 100% !important; - z-index: 1001 !important; -} - -/*=========================================================================== - Flippers ----------------------------------------------------------------------------*/ - -div.monelem_flippers_slider_wait { - position: absolute; - right: 0px; - top: 0px; - width: 92px; - height: 112px; - background-repeat: no-repeat; - -webkit-background-size: 100%; - -moz-background-size: 100%; - background-size: 100%; -} - -@media screen and (max-width: 640px) { - div.monelem_flippers_slider_wait { - width: 61px; - height: 75px; - } -} - - -/*=========================================================================== - DATA URIs - - These are data-uri packed images, inlined for loading speed and simplicity. - Placed at the end of this file because they're visually noisy... ----------------------------------------------------------------------------*/ - -div.monelem_panels_imode_toggleIcon { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB8AAAAaCAYAAABPY4eKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1%2B%2FAAAABV0RVh0Q3JlYXRpb24gVGltZQAzMC82LzEwBMfmVwAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNXG14zYAAANYSURBVEiJtdZbiNVVFMfxj8cx85JkIGlqSESgOGA9WIQgGmTRUyRaYFJDnUWYGV2eyiCpkIbEKJI1UqYvUkmFDxFBgpghonajSDCM7hcxLSnt4ulh%2F2c4HufMTOH8Xs75%2F%2Ffa67v3%2Bu%2B91hphGJWZNUzCXJyKiHd6xxqNhhGDTB6NOViAyzARY3EaP%2BNL7MCBiPi9Ze4leBlTsR9jcCnuiYgDbeGZeV4F7EINe7EP3%2BJ49W4GrsZ8NPAGXouIk5k5F93YFhHPVT5H4kbcjaX1ev3kWfDMPB9P4ko8ERE7BopONWcOVmMc1uBRrG8Oc5Ptq1hdr9cPdrQMTMUWfBQRCweD9ioiPsQtmbkeu7G8P3ClsZSI98EzcxqeUsLXM1RwZs7ErRiJKXgQN2Tmzoj4qsV2Hn7BYcq369UaHIqI5yPizyGCx2MPfsRVOBoR6%2FA%2BNmXmqCbbm%2FAiMiJO9cEzcwEuwLODwMZk5oXVLYA6PouIF%2FC6cvBgI37D0mreStyJroh4r9df785XYGtEHG8Hfnjb1w08Xu2qq3regtOZuaka2whV5NZieWY%2BhkV4ICJ2N%2FusZeYMJQm8NdCuuxdPH4HENGzsXjx9REQcqRxvR2dEfNBrHxF7lHywGPXW7085cEvwZkScHAheaRz%2BwngcqyAnlEPan%2Fbh5oj4rr%2FBDlyOXUMA%2Fx%2F9oFytM5SZs3t6epbWlOtxeJjg%2BzEmMye3vF%2BCYx2YhdFnTTs3OoQT2JqZ3TiC2zETyzrwrnIwhkMTqwVsxW24GLsiYmWj0dCBo2gNy7nSRfgpIjZjM6WU1ut1lHt%2BGLOHCd6J79sN1pSkMSUzJwwD%2FBoD5I9aRHyiFIVFQ3D2j1KR%2Fh7MMDPnY1JE7GwLr3434N5BnI3GFRiFzuai0Ub34aWBDGr0pcKPM%2FPpqovpT11KoVinNAvXt1lkLTNXKFesXU1HUz3HI0plWqW0QGcoIjYoERpMy7AS17b2da06o43KzLF4RanRzwwx3%2FfOHYW7lL5ubUR83p9do9Ho%2B99fDzcZDynfdxPejog%2FBoCOxHW4AxOwKiK%2BaGc%2FILzJ6ULcXznciwM4qFSzCUob3Km0UCeU3W5v5%2B8%2FwZsWMQvzlN1Nq8C%2F4ht8qkRm72B%2B%2BoP%2FC0sEOftJmUbfAAAAAElFTkSuQmCC); -} - -div.monelem_flippers_slider_wait { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFwAAABwCAMAAACkX%2BcnAAAB0VBMVEUAAACDg4OEhISFhYWGhoaHh4eIiIiJiIiJiYmKioqLi4uMjIyNjY2Ojo6Pj4%2BQkJCRkZGSkpKTk5OUlJSVlZWWlpaXl5eYmJiZmZmampqbm5ucnJycnJ2dnZ2dnZ6dnZ%2Benp6enp%2Bfn5%2Bfn6CgoKCgoKGhoKChoaGioqKjo6OkpKSlpaWmpaWmpqaoqKiqqqqrq6usrKytra2urq6wsLCxsbGzs7O0tLS0tLW1tbW1tba1tbe2tri4uLi4uLm4uLq6ury7u7y8vLy8vL28vL%2B9vb2%2Bvr6%2Bvr%2B%2Fv7%2B%2Fv8HAwMDAwMLAwMPBwcPCwsPExMTExMXFxcXGxsbHx8fIyMjJycrOztDOztHPz9DPz9HR0dTS0tTT09TT09XU1NbU1NfV1dfW1tjW1tnX19fX19rY2Nra2tva2tzd3eDe3t7f39%2Fh4eHi4uLl5enn5%2Bnp6ezp6e3q6u3q6u7r6%2B7r6%2B%2Fs7O%2Fs7PDt7fDt7fHu7vHu7vLv7%2B%2Fv7%2FLv7%2FPw8PDw8PPw8PTx8fTx8fXy8vXy8vbz8%2Fbz8%2Ff09Pf09Pj19fj19fn29vn39%2Fn39%2Fr4%2BPr4%2BPv5%2Bfv6%2Bvv6%2Bvz7%2B%2Fz7%2B%2F38%2FP39%2Ff39%2Ff7%2B%2Fv7%2B%2Fv%2F%2F%2F%2F%2BHSJEZAAAAAXRSTlMAQObYZgAAA5dJREFUaN61lk1uE0EQhd%2BrsQlREAgkFkQKLJByteQU3IIdd2OBYIFASFmAFLurWPT0uOfXme6aWUXy6PNL9XPXR3z6DSI93wQ0GkHjzweapM%2B%2Btn8SMAERPzKQQKN7IDRhD2APgkbumucvXp24T3s%2BH47H7%2F9U1AxmpvaDzV5IUMBfD0CbQXYPly93K%2BEiwneqphpMVc3e7p492zciQhGKNN2bX%2F42shJOEQFIQgAKgfgdpvFz7d58%2FPO4Fn5PiggBAUkAYhoUMJipwU5vhsfjWjhESMTsBChQVVMDYICadfjD4VAAFyGYZVcN7Vzar4iP6frkd5RuLjG7WlCFwdSy4ICtPlBAKJLNhYBq6HKf8IHrx4J7IQX5maqFLHeC3yrWwyEiFACSzlTVVFNuzQZTAG%2BrLoQwVT1kubvGF4wlVj2vi2isuvWrbiXJIUISYKwL5qpuWgbvXQHxSCeqbiXwvOrpClC1QdXViuAQUnpXgE1U%2FSb%2BUwVVF7JfdTWN2G4uFyiaeZz6oOpB1drzTF0sSw6ySdc5Y%2FZe1SPeCpPfS6p6yq4arK16V5eyAwWEp6oTEKpqewXEygBW9iMabzsAZjqoOkuTL227tjJvSg8UaG%2FGhW33obSK8d4dVj1eAV3VrXQsuBtXvd12XdWteCxg2nbobbuU2xQsHst42zHe6lllypOnbcdUeZ62HUzNoOXJz4vdpZXDz4rde5TDz4rdsQ6%2BLHZNxVjOip3VJD8ndjVtOSt2rEp%2BRuxCHXxZ7G6tCr4sdhUX1xPETmvhC2KndWNZFjtUjmVR7KRyLItiF2qTL4ndtdXCF8Tuqhq%2BIHaonfmi2Ek1fEHsQjV8YdtVt2VR7DzgM2J36QCfFbsbB%2Fi82MEBPit2HvBZsfMYy6zYuSSfq7oLfE7sLpzgk2J37QKfETt1gc%2BJnQ98Rux84NNiJ07wSbELTvBpsXOCT4rdRz%2F4WOzMCz4pdl7wKbGDG3xC7NzGMiV2jvCx2PnNfELsbvzgY7FrHOFjsXOEj7YdHeFjsfOF96sePOFjsXOED8XutSt8sO2uXOFDsfOFD6ruCx9U3Rc%2BEDt3eC52zvC%2B2DnD%2B2LnDe9V3RveEzt3eC527vBc7NzhudhtAe%2BuAH94VnV%2FeCZ2G8BzscMmUxdgi5lnYrcF%2FCR2wCZHSvftP9x2m8DTttsEnsRuK7hs8%2FPPxG4beCt2G8HbbbcNPG67reAUEfwHRePBMkvuZ4wAAAAASUVORK5CYII%3D); -} diff --git a/COPS/cops-3.1.3/resources/monocle/styles/monoctrl.css b/COPS/cops-3.1.3/resources/monocle/styles/monoctrl.css deleted file mode 100644 index 89e8ab68..00000000 --- a/COPS/cops-3.1.3/resources/monocle/styles/monoctrl.css +++ /dev/null @@ -1,169 +0,0 @@ -/*=========================================================================== - CONTROLS - - The standard Monocle stylesheet for the optional Monocle controls. See - comments for monocore.css, which apply here too. ----------------------------------------------------------------------------*/ - -/* Contents */ - -div.monelem_controls_contents_container { - position: absolute; - width: 75%; - height: 75%; - left: 12.5%; - top: 12.5%; - background: #EEE; - border: 2px solid #F7F7F7; - border-radius: 9px; - overflow-y: auto; - -webkit-overflow-scrolling: touch; - -moz-border-radius: 9px; - -webkit-border-radius: 9px; - box-shadow: 1px 2px 6px rgba(0,0,0,0.5); - -moz-box-shadow: 1px 2px 6px rgba(0,0,0,0.5); - -webkit-box-shadow: 1px 2px 6px rgba(0,0,0,0.5); -} - -ol.monelem_controls_contents_list { - margin: 6px; - padding: 0; -} - -li.monelem_controls_contents_chapter { - list-style: none; - line-height: 220%; - padding-left: 1em; - padding-right: 2em; - border-bottom: 2px groove #FEFEFE; - cursor: pointer; -} - -li.monelem_controls_contents_chapter_active { - background: #999; - color: white; -} - -/* Magnifier */ - -.monelem_controls_magnifier_button { - cursor: pointer; - color: #555; - position: absolute; - top: 2px; - right: 10px; - padding: 0 2px; -} - -.monelem_controls_magnifier_a { - font-size: 11px; -} - -.monelem_controls_magnifier_A { - font-size: 18px; - opacity: 0.3; -} - - -/* Spinner */ - -.monelem_controls_spinner_anim { - position: absolute; - width: 100%; - height: 100%; - background-color: white; - background-repeat: no-repeat; - background-position: center center; -} -.monelem_controls_spinner_anim.monelem_dormant { - width: 0; - height: 0; -} - - -/* Scrubber */ - -div.monelem_controls_scrubber_container { - position: absolute; - left: 1em; - right: 1em; - bottom: 4px; - height: 30px; - background: rgba(255,255,255,0.8); -} - -div.monelem_controls_scrubber_track { - margin-top: 10px; - height: 5px; - border: 1px solid #999; - cursor: pointer; -} - -div.monelem_controls_scrubber_needle { - position: absolute; - width: 14px; - height: 14px; - top: 5px; - background: #CCC; - border: 1px solid #999; - border-radius: 8px; - -moz-border-radius: 8px; - -webkit-border-radius: 8px; -} - -div.monelem_controls_scrubber_trail { - position: absolute; - background: #DDD; - top: 11px; - left: 1px; - height: 5px; -} - -div.monelem_controls_scrubber_bubble { - display: none; - position: absolute; - padding: 1em; - min-width: 20%; - max-width: 30%; - bottom: 2.5em; - background: rgba(0, 0, 0, 0.9); - color: #CCC; - font: bold 12px Lucida Grande, Tahoma, Helvetica, Arial, sans-serif; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - border-radius: 10px; - -moz-border-radius: 10px; - -webkit-border-radius: 10px; -} - - -/* Stencil */ -div.monelem_controls_stencil_container { - position: absolute; - top: 0; - left: 0; - width: 0; - height: 0; -} - -.monelem_controls_stencil_mask { - display: block; - position: absolute; -} - -div.monelem_controls_stencil_highlighted .monelem_controls_stencil_mask { - background: rgba(0,0,255,0.15); -} - - -/*=========================================================================== - DATA URIs - - These are data-uri packed images, inlined for loading speed and simplicity. - Placed at the end of this file because they're visually noisy... ----------------------------------------------------------------------------*/ - -div.monelem_controls_spinner_anim { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAA0CAMAAAANBM47AAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAsSAAALEgHS3X78AAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M1cbXjNgAAABV0RVh0Q3JlYXRpb24gVGltZQAxNy81LzEwnOhoKAAAAE5QTFRFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxKKmWQAAABp0Uk5TAAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBl0wLilAAAC8klEQVQYGZXBB2LjOAADQFCimtVFEoD//9HLbrJxipzoZoBToYptUwV8V/Xrsc8RP6i7aduPXHI69mWIAR9UY6Is5rnCuTBsWXeLkijbTFOLf7okW6R8zxEnwphskfIrifJdW4u/RtlpbGLsdjoHfDNkSZTSNg192w3jchSJEtcawCRzDvgjLPINX1SbSSvNXcC7eNuLXpQuTFbp8CZkH/isyS68H0PAF+0iUzxoNni33HPAR51UxDHgRLObslLEw3TPFT7oKPqIeOImURs+WJ0CHlqKXgLOxL4NgyRqxbuqeMNDXURPOBNWSokquRRP+GeVOzwcLlpwJmx3WVJuY2ZRi1ezfOBhdNGGU52ZhrloBzqSucKLerdLxLtIKlc4Nd9LA6wuNTC5aAbQZzs3eFhE9Tg3mw2wqkQgHCZrTJK3iIcoasMTvXX0E30EAK2k+Wbrho8mky2eCLslSz3+2ERKucVHIZsbnqp2WWXEX60ossMnrakeP+jGocabg9SGzyaXHHDRpOIO/zRjDWCTNlzVsLjFm4bODapE33BZoke8mVy8oqXY4rLNXvFmEnXDKJYaly3SjlchkSOwiCngstFMeDXLE4CVygGX3e6FawUgzFIKANbiHHDZ7U4qL7c5SWzxYqFywGXjvVD3F3Zu8ccs5gqXzeYx7CTTWOOvnmTEZZu0ItSxrvAmZrrHZYme8dkhLbiqLkUDPlvMA1cNIiM+613Y4KJNSviiprTgmrrQM75arVzhkllUxFetqBlXVEXa8d0hMeKCxVSH73rRG37XidpxZlXRiN9UhYUtztRFVI+fhUPFE851KlSHn4TNxTueGU2yx3PVbipVeGpxIaeAJ2IynRv8YHEp3iNOjRRdGvxotGjONb7pD7M4RfyiK6ZclhYf1bdDprRW+FW9SZSUlqGtq1BVTTftRaKce1zS7bIpWyW/oK0i38tU4apupWyRsijKVhoj/o+6W45cJEoqaR+bgP8txH5a1nUZ2gq/+Q/51T5MhuG3fQAAAABJRU5ErkJggg==); -} diff --git a/COPS/cops-3.1.3/resources/simonpioli/sortelements/README.md b/COPS/cops-3.1.3/resources/simonpioli/sortelements/README.md deleted file mode 100644 index 44b12424..00000000 --- a/COPS/cops-3.1.3/resources/simonpioli/sortelements/README.md +++ /dev/null @@ -1,35 +0,0 @@ -sort ---- - -The sort plugin is a very basic low-level element sorting function that allows you to sort DOM elements with a custom comparator (similar to `Array.prototype.sort`). - -Assuming the following markup: - -
      -
    • Banana
    • -
    • Carrot
    • -
    • Apple
    • -
    - -You could sort the items alphabetically like so: - - $('li').sortElements(function(a, b){ - return $(a).text() > $(b).text() ? 1 : -1; - }); - -That would result in: - -
      -
    • Apple
    • -
    • Banana
    • -
    • Carrot
    • -
    - -It also let's you specify what element will be sorted. The current collection's elements will be those referred to as `a` and `b` on each call of the comparator, but you might not want those elements to be the ones to move. E.g. you might want it to be a parent. For example, when sorting a table column, you would sort by the `` elements, but the elements you actually want to move within the DOM are the `` (each ``'s parent): - - $('td').sortElements(myComparator, function(){ - // Return a reference to the desired element: - return this.parentNode; - }); - -See more info here: [http://james.padolsey.com/javascript/sorting-elements-with-jquery/](http://james.padolsey.com/javascript/sorting-elements-with-jquery/). \ No newline at end of file diff --git a/COPS/cops-3.1.3/resources/simonpioli/sortelements/jquery.sortElements.js b/COPS/cops-3.1.3/resources/simonpioli/sortelements/jquery.sortElements.js deleted file mode 100644 index 1cd6bf87..00000000 --- a/COPS/cops-3.1.3/resources/simonpioli/sortelements/jquery.sortElements.js +++ /dev/null @@ -1,69 +0,0 @@ -/** -* jQuery.fn.sortElements -* -------------- -* @author James Padolsey (http://james.padolsey.com) -* @version 0.11 -* @updated 18-MAR-2010 -* -------------- -* @param Function comparator: -* Exactly the same behaviour as [1,2,3].sort(comparator) -* -* @param Function getSortable -* A function that should return the element that is -* to be sorted. The comparator will run on the -* current collection, but you may want the actual -* resulting sort to occur on a parent or another -* associated element. -* -* E.g. $('td').sortElements(comparator, function(){ -* return this.parentNode; -* }) -* -* The 's parent () will be sorted instead -* of the itself. -*/ -jQuery.fn.sortElements = (function(){ - - var sort = [].sort; - - return function(comparator, getSortable) { - - getSortable = getSortable || function(){return this;}; - - var placements = this.map(function(){ - - var sortElement = getSortable.call(this), - parentNode = sortElement.parentNode, - - // Since the element itself will change position, we have - // to have some way of storing it's original position in - // the DOM. The easiest way is to have a 'flag' node: - nextSibling = parentNode.insertBefore( - document.createTextNode(''), - sortElement.nextSibling - ); - - return function() { - - if (parentNode === this) { - throw new Error( - "You can't sort elements if any one is a descendant of another." - ); - } - - // Insert before flag: - parentNode.insertBefore(this, nextSibling); - // Remove flag: - parentNode.removeChild(nextSibling); - - }; - - }); - - return sort.call(this, comparator).each(function(i){ - placements[i].call(getSortable.call(this)); - }); - - }; - -})(); \ No newline at end of file diff --git a/COPS/cops-3.1.3/restapi.php b/COPS/cops-3.1.3/restapi.php deleted file mode 100644 index 4fb73874..00000000 --- a/COPS/cops-3.1.3/restapi.php +++ /dev/null @@ -1,13 +0,0 @@ - - * @author mikespub - * @deprecated 3.1.0 use index.php/restapi instead - */ - -$link = str_replace('restapi.php', 'index.php/restapi', $_SERVER['REQUEST_URI'] ?? ''); -header('Location: ' . $link); diff --git a/COPS/cops-3.1.3/router.php b/COPS/cops-3.1.3/router.php deleted file mode 100644 index 5bd97fa0..00000000 --- a/COPS/cops-3.1.3/router.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @author mikespub - */ - -if (php_sapi_name() !== 'cli-server') { - echo 'This router is for the php development server only'; - return; -} - -// check if the requested path actually exists -$path = parse_url((string) $_SERVER['REQUEST_URI'], PHP_URL_PATH); -if (!empty($path) && file_exists(__DIR__ . $path) && !is_dir(__DIR__ . $path)) { - return false; -} -// route to the right PHP endpoint if needed -$script = urldecode((string) $_SERVER['SCRIPT_NAME']); -if (str_contains($path, $script . '/') && file_exists(__DIR__ . $script)) { - return false; -} - -// set environment vars for the front controller -$_SERVER['SCRIPT_NAME'] = '/index.php'; -$_SERVER['PATH_INFO'] ??= parse_url((string) $_SERVER['REQUEST_URI'], PHP_URL_PATH); - -// use index.php as front controller -include __DIR__ . '/index.php'; diff --git a/COPS/cops-3.1.3/schema.graphql b/COPS/cops-3.1.3/schema.graphql deleted file mode 100644 index a8be025d..00000000 --- a/COPS/cops-3.1.3/schema.graphql +++ /dev/null @@ -1,269 +0,0 @@ -""" -Adapted from https://github.com/mikespub-org/acdibble-tuql -Goal: create GraphQL interface to Calibre database (maybe) -""" -type Query { - authors( - limit: Int - order: String - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - offset: Int - ): [Entry] - author( - id: ID - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - ): Entry - books( - limit: Int - order: String - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - offset: Int - ): [EntryBook] - book( - id: ID - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - ): EntryBook - customColumns( - limit: Int - order: String - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - offset: Int - ): [Entry] - customColumn( - id: ID - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - ): Entry - datas( - bookId: ID - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - ): [Data] - data( - id: ID - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - ): Data - feeds( - limit: Int - order: String - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - offset: Int - ): [Entry] - feed( - id: ID - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - ): Entry - identifiers( - limit: Int - order: String - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - offset: Int - ): [Entry] - identifier( - id: ID - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - ): Entry - languages( - limit: Int - order: String - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - offset: Int - ): [Entry] - language( - id: ID - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - ): Entry - preferences( - limit: Int - order: String - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - offset: Int - ): [Entry] - preference( - id: ID - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - ): Entry - publishers( - limit: Int - order: String - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - offset: Int - ): [Entry] - publisher( - id: ID - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - ): Entry - ratings( - limit: Int - order: String - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - offset: Int - ): [Entry] - rating( - id: ID - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - ): Entry - series( - limit: Int - order: String - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - offset: Int - ): [Entry] - serie( - id: ID - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - ): Entry - tags( - limit: Int - order: String - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - offset: Int - ): [Entry] - tag( - id: ID - - """ - A JSON object conforming the the shape specified in http://docs.sequelizejs.com/en/latest/docs/querying/ - """ - where: SequelizeJSON - ): Entry -} - -"""The `JSON` scalar type represents raw JSON as values.""" -scalar SequelizeJSON - -type Entry { - id: ID! - title: String! - content: String - contentType: String - linkArray: [Link] - className: String - numberOfElement: String - books: [EntryBook] -} - -type EntryBook { - id: ID! - title: String! - content: String - contentType: String - linkArray: [Link] - className: String - numberOfElement: String - path: String - authors: [Entry] - customColumns: [Entry] - datas: [Data] - identifiers: [Entry] - languages: String - publisher: Entry - rating: String - serie: Entry - tags: [Entry] -} - -type Link { - href: String! - type: String! - rel: String - title: String -} - -type Data { - id: ID! - book: EntryBook - format: String - uncompressedSize: Int - name: String -} diff --git a/COPS/cops-3.1.3/sendtomail.php b/COPS/cops-3.1.3/sendtomail.php deleted file mode 100644 index bf4b2b0c..00000000 --- a/COPS/cops-3.1.3/sendtomail.php +++ /dev/null @@ -1,13 +0,0 @@ - - * @author mikespub - * @deprecated 3.1.0 use index.php/mail instead - */ - -$link = str_replace('sendtomail.php', 'index.php/mail', $_SERVER['REQUEST_URI'] ?? ''); -header('Location: ' . $link); diff --git a/COPS/cops-3.1.3/src/Calibre/Annotation.php b/COPS/cops-3.1.3/src/Calibre/Annotation.php deleted file mode 100644 index 8316a865..00000000 --- a/COPS/cops-3.1.3/src/Calibre/Annotation.php +++ /dev/null @@ -1,211 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Pages\PageId; -use JsonException; - -class Annotation extends Base -{ - public const PAGE_ID = PageId::ALL_ANNOTATIONS_ID; - public const PAGE_ALL = PageId::ALL_ANNOTATIONS; - public const PAGE_BOOK = PageId::ANNOTATIONS_BOOK; - public const PAGE_DETAIL = PageId::ANNOTATION_DETAIL; - public const SQL_TABLE = "annotations"; - public const SQL_LINK_TABLE = "annotations"; - public const SQL_LINK_COLUMN = "id"; - public const SQL_SORT = "id"; - public const SQL_COLUMNS = "id, book, format, user_type, user, timestamp, annot_id, annot_type, annot_data"; - public const SQL_ALL_ROWS = "select {0} from annotations where 1=1 {1}"; - - public int $book; - public string $format; - public string $userType; - public string $user; - public float $timestamp; - public string $type; - /** @var array */ - public array $data; - - /** - * Summary of __construct - * @param object $post - * @param ?int $database - */ - public function __construct($post, $database = null) - { - $this->id = $post->id; - $this->book = $post->book; - $this->format = $post->format; - $this->userType = $post->user_type; - $this->user = $post->user; - $this->timestamp = $post->timestamp; - $this->name = $post->annot_id; - $this->type = $post->annot_type; - try { - $this->data = json_decode($post->annot_data, true, 512, JSON_THROW_ON_ERROR); - } catch (JsonException) { - $this->data = [ $post->annot_data ]; - } - $this->databaseId = $database; - } - - /** - * Summary of getUri - * @param array $params - * @return string - */ - public function getUri($params = []) - { - // @todo let restapi build route url, or change route to use page here? - if (Config::get('use_route_urls')) { - return Route::link($this->handler) . '/annotations/' . $this->book . '/' . $this->id; - } - $params['bookId'] = $this->book; - $params['id'] = $this->id; - // we need databaseId here because we use Route::link with $handler - $params['db'] = $this->getDatabaseId(); - return Route::link($this->handler, static::PAGE_DETAIL, $params); - } - - /** - * Summary of getTitle - * @return string - */ - public function getTitle() - { - return '(' . strval($this->book) . ') ' . ucfirst($this->type) . ' ' . $this->name; - } - - /** Use inherited class methods to query static SQL_TABLE for this class */ - - /** - * Summary of getCountByBookId - * @param ?int $database - * @return array - */ - public static function getCountByBookId($database = null) - { - $entries = []; - $query = 'select book, count(*) as count from annotations group by book order by book'; - $result = Database::query($query, [], $database); - while ($post = $result->fetchObject()) { - $entries[$post->book] = $post->count; - } - return $entries; - } - - /** - * Summary of getInstancesByBookId - * @param int $bookId - * @param ?int $database - * @return array - */ - public static function getInstancesByBookId($bookId, $database = null) - { - // @todo filter by format, user, annotType etc. - $query = 'select ' . static::getInstanceColumns($database) . ' -from annotations -where book = ?'; - $result = Database::query($query, [$bookId], $database); - $annotationArray = []; - while ($post = $result->fetchObject()) { - array_push($annotationArray, new Annotation($post, $database)); - } - return $annotationArray; - } - - /** - * Forget about converting annotations - * - * Epub CFIs are *not* compatible between Calibre, Kobo, epub.js, readium.js etc. - * See https://github.com/futurepress/epub.js/issues/1358 for comments and links - * - * @return void - */ - private static function forgetAboutConvertAnnotations() - { - /** - From Calibre annotations: - { - "id": 2, - "book": 17, - "format": "EPUB", - "userType": "local", - "user": "viewer", - "timestamp": 1710158035.583, - "type": "highlight", - "data": { - "end_cfi": "/2/4/2/2/6/1:24", - "highlighted_text": "Charles Lutwidge Dodgson", - "notes": "Full author name", - "spine_index": 2, - "spine_name": "OPS/about.xml", - "start_cfi": "/2/4/2/2/6/1:0", - "style": { - "kind": "color", - "type": "builtin", - "which": "yellow" - }, - "timestamp": "2024-03-11T11:53:55.583Z", - "toc_family_titles": [ - "About" - ], - "type": "highlight", - "uuid": "5HHGuoCOtpA-umaIbBuc0Q" - } - } - From epub.js local storage in Chrome: - { - "restore": true, - "bookPath": "/cops/zipfs.php/0/20/", - "flow": "paginated", - "history": true, - "reload": false, - "bookmarks": [ - "epubcfi(/6/8!/4/2/2[chapter_458]/2/2/2/1:0)", - "epubcfi(/6/10!/4/2/2[chapter_460]/4/26/1:372)" - ], - "annotations": [ - { - "cfi": "epubcfi(/6/6!/4/2/2/2,/1:0,/1:13)", - "date": "2024-03-13T10:11:48.731Z", - "text": "About author", - "uuid": "60c92408-81b9-47d9-f705-66f26317f2ee" - }, - { - "cfi": "epubcfi(/6/6!/4/2/2/6,/1:0,/1:24)", - "date": "2024-03-13T10:19:09.443Z", - "text": "Actual person", - "uuid": "71aad015-28f9-4088-abce-48762492b52e" - }, - { - "cfi": "epubcfi(/6/6!/4/2/2/6,/1:93,/1:106)", - "date": "2024-03-13T10:19:31.777Z", - "text": "Pen name", - "uuid": "66f559ae-f8a5-4b39-b3cc-673a08d67f00" - } - ], - "sectionId": "level1-about", - "spread": { - "mod": "auto", - "min": 800 - }, - "styles": { - "fontSize": 100 - }, - "pagination": false, - "language": "en", - "previousLocationCfi": "epubcfi(/6/6!/4/2/2/2/1:0)" - } - */ - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/Author.php b/COPS/cops-3.1.3/src/Calibre/Author.php deleted file mode 100644 index 68cf4b9f..00000000 --- a/COPS/cops-3.1.3/src/Calibre/Author.php +++ /dev/null @@ -1,88 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Pages\PageId; - -class Author extends Base -{ - public const PAGE_ID = PageId::ALL_AUTHORS_ID; - public const PAGE_ALL = PageId::ALL_AUTHORS; - public const PAGE_LETTER = PageId::AUTHORS_FIRST_LETTER; - public const PAGE_DETAIL = PageId::AUTHOR_DETAIL; - public const SQL_TABLE = "authors"; - public const SQL_LINK_TABLE = "books_authors_link"; - public const SQL_LINK_COLUMN = "author"; - public const SQL_SORT = "sort"; - public const SQL_COLUMNS = "authors.id as id, authors.name as name, authors.sort as sort, authors.link as link"; - public const SQL_ROWS_BY_FIRST_LETTER = "select {0} from authors, books_authors_link where author = authors.id and upper (authors.sort) like ? {1} group by authors.id, authors.name, authors.sort order by sort"; - public const SQL_ROWS_FOR_SEARCH = "select {0} from authors, books_authors_link where author = authors.id and (upper (authors.sort) like ? or upper (authors.name) like ?) {1} group by authors.id, authors.name, authors.sort order by sort"; - public const SQL_ALL_ROWS = "select {0} from authors, books_authors_link where author = authors.id {1} group by authors.id, authors.name, authors.sort order by sort"; - public const SQL_BOOKLIST = 'select {0} from books_authors_link, books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - left outer join books_series_link on books_series_link.book = books.id - where books_authors_link.book = books.id and author = ? {1} order by series desc, series_index asc, pubdate asc'; - public const URL_PARAM = "a"; - - /** @var string */ - public $sort; - - /** - * Summary of __construct - * @param object $post - * @param ?int $database - */ - public function __construct($post, $database = null) - { - $this->id = $post->id; - $this->name = str_replace("|", ",", $post->name); - $this->sort = $post->sort; - $this->link = property_exists($post, 'link') ? $post->link : null; - $this->databaseId = $database; - } - - /** - * Summary of getTitle - * @return string - */ - public function getTitle() - { - return $this->name; - } - - /** - * Summary of getParentTitle - * @return string - */ - public function getParentTitle() - { - return localize("authors.title"); - } - - /** Use inherited class methods to query static SQL_TABLE for this class */ - - /** - * Summary of getInstancesByBookId - * @param int $bookId - * @param ?int $database - * @return array - */ - public static function getInstancesByBookId($bookId, $database = null) - { - $query = 'select ' . static::getInstanceColumns($database) . ' -from authors, books_authors_link -where author = authors.id -and book = ? order by books_authors_link.id'; - $result = Database::query($query, [$bookId], $database); - $authorArray = []; - while ($post = $result->fetchObject()) { - array_push($authorArray, new Author($post, $database)); - } - return $authorArray; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/Base.php b/COPS/cops-3.1.3/src/Calibre/Base.php deleted file mode 100644 index 38ad0078..00000000 --- a/COPS/cops-3.1.3/src/Calibre/Base.php +++ /dev/null @@ -1,576 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Request; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Model\Entry; -use SebLucas\Cops\Model\EntryBook; -use SebLucas\Cops\Model\LinkFeed; -use SebLucas\Cops\Model\LinkNavigation; -use SebLucas\Cops\Pages\PageId; -use SebLucas\Cops\Pages\Page; - -abstract class Base -{ - public const PAGE_ID = PageId::ALL_BASES_ID; - public const PAGE_ALL = 0; - public const PAGE_DETAIL = 0; - public const PAGE_LETTER = 0; - public const SQL_TABLE = "bases"; - public const SQL_LINK_TABLE = "books_bases_link"; - public const SQL_LINK_COLUMN = "base"; - public const SQL_SORT = "sort"; - public const SQL_COLUMNS = "bases.id as id, bases.name as name, bases.sort as sort, bases.link as link"; - public const SQL_ALL_ROWS = "select {0} from bases, books_bases_link where base = bases.id {1} group by bases.id, bases.name, bases.sort order by sort"; - public const SQL_ROWS_FOR_SEARCH = "select {0} from bases, books_bases_link where base = bases.id and (upper (bases.sort) like ? or upper (bases.name) like ?) {1} group by bases.id, bases.name, bases.sort order by sort"; - public const SQL_ROWS_BY_FIRST_LETTER = "select {0} from bases, books_bases_link where base = bases.id and upper (bases.sort) like ? {1} group by bases.id, bases.name, bases.sort order by sort"; - public const SQL_BOOKLIST = 'select {0} from books_bases_link, books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where books_bases_link.book = books.id and base = ? {1} order by books.sort'; - public const COMPATIBILITY_XML_ALDIKO = "aldiko"; - public const URL_PARAM = "b"; - - /** @var ?int */ - public $id; - /** @var ?string */ - public $name; - /** @var ?string */ - public $link; - public bool $limitSelf = true; - /** @var ?int */ - protected $databaseId = null; - /** @var ?int */ - protected $filterLimit = null; - /** @var array */ - protected $filterParams = []; - protected string $handler = ''; - - /** - * Summary of __construct - * @param object $post - * @param ?int $database - */ - public function __construct($post, $database = null) - { - $this->id = $post->id; - $this->name = $post->name; - $this->link = property_exists($post, 'link') ? $post->link : null; - $this->databaseId = $database; - } - - /** - * Summary of getDatabaseId - * @return ?int - */ - public function getDatabaseId() - { - return $this->databaseId; - } - - /** - * Summary of getUri - * @param array $params - * @return string - */ - public function getUri($params = []) - { - $params['id'] = $this->id; - // we need databaseId here because we use Route::link with $handler - $params['db'] = $this->getDatabaseId(); - if (Config::get('use_route_urls')) { - $params['title'] = $this->getTitle(); - } - return Route::link($this->handler, static::PAGE_DETAIL, $params); - } - - /** - * Summary of getParentUri - * @param array $params - * @return string - */ - public function getParentUri($params = []) - { - // we need databaseId here because we use Route::link with $handler - $params['db'] = $this->getDatabaseId(); - return Route::link($this->handler, static::PAGE_ALL, $params); - } - - /** - * Summary of getEntryId - * @return string - */ - public function getEntryId() - { - return static::PAGE_ID . ":" . $this->id; - } - - /** - * Summary of getEntryIdByLetter - * @param string $startingLetter - * @return string - */ - public static function getEntryIdByLetter($startingLetter) - { - return static::PAGE_ID . ":letter:" . $startingLetter; - } - - /** - * Summary of getTitle - * @return string - */ - public function getTitle() - { - return $this->name; - } - - /** - * Summary of getContent - * @param int $count - * @return string - */ - public function getContent($count = 0) - { - return str_format(localize("bookword", $count), $count); - } - - /** - * Summary of getContentType - * @return string - */ - public function getContentType() - { - return "text"; - } - - /** - * Summary of getLinkArray - * @param array $params - * @return array - */ - public function getLinkArray($params = []) - { - // remove for Filter::getEntryArray() - see filterTest - unset($params[static::URL_PARAM]); - return [ new LinkFeed($this->getUri($params), "subsection") ]; - } - - /** - * Summary of setHandler - * @param string $handler - * @return void - */ - public function setHandler($handler) - { - $this->handler = $handler; - } - - /** - * Summary of getHandler - * @return string - */ - public function getHandler() - { - return $this->handler; - } - - /** - * Summary of getClassName - * @param ?string $className - * @return string - */ - public function getClassName($className = null) - { - $className ??= static::class; - $classParts = explode('\\', $className); - return end($classParts); - } - - /** - * Summary of getEntry - * @param int $count - * @param array $params - * @return Entry - */ - public function getEntry($count = 0, $params = []) - { - $entry = new Entry( - $this->getTitle(), - $this->getEntryId(), - $this->getContent($count), - $this->getContentType(), - $this->getLinkArray($params), - $this->getDatabaseId(), - $this->getClassName(), - $count - ); - $entry->instance = $this; - return $entry; - } - - /** - * Summary of getParentTitle - * @return string - */ - public function getParentTitle() - { - return localize("title.title"); - } - - /** - * Summary of getPage - * @param int $count - * @param array $params - * @todo investigate potential use as alternative to getEntry() - * @return Page - */ - public function getPage($count = 0, $params = []) - { - $params['id'] = $this->id; - // we need databaseId here because we use Route::link with $handler - $params['db'] = $this->getDatabaseId(); - if (Config::get('use_route_urls')) { - $params['title'] = $this->getTitle(); - } - $request = Request::build($params, $this->handler); - $page = PageId::getPage(static::PAGE_DETAIL, $request, $this); - if (!empty($count)) { - $page->totalNumber = $count; - } - return $page; - } - - /** Use inherited class methods to get entries from by instance (linked via books) */ - - /** - * Get the query to find all books with this value - * the returning array has two values: - * - first the query (string) - * - second an array of all PreparedStatement parameters - * @return array{0: string, 1: array} - */ - public function getQuery() - { - return [ static::SQL_BOOKLIST, [ $this->id ]]; - } - - /** - * Summary of getLinkTable - * @return string - */ - public function getLinkTable() - { - return static::SQL_LINK_TABLE; - } - - /** - * Summary of getLinkColumn - * @return string - */ - public function getLinkColumn() - { - return static::SQL_LINK_COLUMN; - } - - /** - * Summary of getBooks - * @param int $n - * @param ?string $sort - * @return array - */ - public function getBooks($n = 1, $sort = null) - { - // @todo see if we want to do something special for books, and deal with static:: inheritance - //return $this->getEntriesByInstance(Book::class, $n, $sort, $this->databaseId); - $booklist = new BookList(null, $this->databaseId); - $booklist->orderBy = $sort; - [$entryArray, ] = $booklist->getBooksByInstance($this, $n); - return $entryArray; - } - - /** - * Summary of getEntriesByInstance - * @param class-string $className - * @param int $n - * @param ?string $sort - * @param ?int $database - * @param ?int $numberPerPage - * @return array - */ - public function getEntriesByInstance($className, $n = 1, $sort = null, $database = null, $numberPerPage = null) - { - $database ??= $this->databaseId; - $numberPerPage ??= $this->filterLimit; - // @todo get rid of extraParams in JsonRenderer and OpdsRenderer as filters should be included in navlink now - $params = $this->getExtraParams(); - $request = Request::build($params, $this->handler); - $baselist = new BaseList($className, $request, $database, $numberPerPage); - $baselist->orderBy = $sort; - return $baselist->getEntriesByInstance($this, $n, $this->filterParams); - } - - /** - * Summary of getAuthors - * @param int $n - * @param ?string $sort - * @return array - */ - public function getAuthors($n = 1, $sort = null) - { - return $this->getEntriesByInstance(Author::class, $n, $sort); - } - - /** - * Summary of getLanguages - * @param int $n - * @param ?string $sort - * @return array - */ - public function getLanguages($n = 1, $sort = null) - { - return $this->getEntriesByInstance(Language::class, $n, $sort); - } - - /** - * Summary of getPublishers - * @param int $n - * @param ?string $sort - * @return array - */ - public function getPublishers($n = 1, $sort = null) - { - return $this->getEntriesByInstance(Publisher::class, $n, $sort); - } - - /** - * Summary of getRatings - * @param int $n - * @param ?string $sort - * @return array - */ - public function getRatings($n = 1, $sort = null) - { - return $this->getEntriesByInstance(Rating::class, $n, $sort); - } - - /** - * Summary of getSeries - * @param int $n - * @param ?string $sort - * @return array - */ - public function getSeries($n = 1, $sort = null) - { - return $this->getEntriesByInstance(Serie::class, $n, $sort); - } - - /** - * Summary of getTags - * @param int $n - * @param ?string $sort - * @return array - */ - public function getTags($n = 1, $sort = null) - { - return $this->getEntriesByInstance(Tag::class, $n, $sort); - } - - /** - * Summary of getIdentifiers - * @param int $n - * @param ?string $sort - * @return array - */ - public function getIdentifiers($n = 1, $sort = null) - { - return $this->getEntriesByInstance(Identifier::class, $n, $sort); - } - - /** - * Summary of getCustomValues - * @param CustomColumnType $customType - * @return array - */ - public function getCustomValues($customType) - { - // we'd need to apply getEntriesById from $instance on $customType instance here - too messy - return []; - } - - /** - * Summary of setFilterLimit - * @param ?int $filterLimit - * @return void - */ - public function setFilterLimit($filterLimit) - { - $this->filterLimit = $filterLimit; - } - - /** - * Summary of getFilterLimit - * @return ?int - */ - public function getFilterLimit() - { - if (empty($this->filterLimit) || $this->filterLimit < 1) { - return 999999; - } - return $this->filterLimit; - } - - /** - * Summary of setFilterParams if we want to filter by virtual library etc. - * @see Page::getFilters() - * @param array $filterParams - * @return void - */ - public function setFilterParams($filterParams) - { - $this->filterParams = $filterParams; - } - - /** - * Summary of getFilterParams - * @return array - */ - public function getFilterParams() - { - return $this->filterParams; - } - - /** - * Summary of getExtraParams if we want to add extra params to entry links etc. - * @return array - */ - public function getExtraParams() - { - return array_merge([static::URL_PARAM => $this->id], $this->filterParams); - } - - /** - * Summary of getNote - * @return Note|null - */ - public function getNote() - { - $className = static::class; - $tableName = $className::SQL_TABLE; - return Note::getInstanceByTypeId($tableName, $this->id, $this->databaseId); - } - - /** Generic methods inherited by Author, Language, Publisher, Rating, Series, Tag classes */ - - /** - * Summary of getInstanceById - * @param string|int|null $id - * @param ?int $database - * @return object - */ - public static function getInstanceById($id, $database = null) - { - $className = static::class; - if (isset($id)) { - $query = 'select ' . static::getInstanceColumns($database) . ' from ' . $className::SQL_TABLE . ' where id = ?'; - $result = Database::query($query, [$id], $database); - if ($post = $result->fetchObject()) { - return new $className($post, $database); - } - } - $default = static::getDefaultName(); - // use id = 0 to support route urls - return new $className((object) ['id' => 0, 'name' => $default, 'sort' => $default], $database); - } - - /** - * Summary of getInstanceByName - * @param string $name - * @param ?int $database - * @return object|null - */ - public static function getInstanceByName($name, $database = null) - { - $className = static::class; - $query = 'select ' . static::getInstanceColumns($database) . ' from ' . $className::SQL_TABLE . ' where name = ?'; - $result = Database::query($query, [$name], $database); - if ($post = $result->fetchObject()) { - return new $className($post, $database); - } - return null; - } - - /** - * Summary of getInstanceColumns - * @param ?int $database - * @return string - */ - public static function getInstanceColumns($database = null) - { - $className = static::class; - // add link field for database user_version 26 = Calibre version 6.15.0 and later (Apr 7, 2023) - if (in_array($className::SQL_TABLE, ['languages', 'publishers', 'ratings', 'series', 'tags']) && Database::getUserVersion($database) > 25) { - return $className::SQL_COLUMNS . ', ' . $className::SQL_TABLE . '.link as link'; - } - return $className::SQL_COLUMNS; - } - - /** - * Summary of getDefaultName - * @return ?string - */ - public static function getDefaultName() - { - return null; - } - - /** - * Summary of getCount - * @param ?int $database - * @param ?string $handler - * @return ?Entry - */ - public static function getCount($database = null, $handler = null) - { - $count = Database::querySingle('select count(*) from ' . static::SQL_TABLE, $database); - return static::getCountEntry($count, $database, null, $handler); - } - - /** - * Summary of getCountEntry - * @param int $count - * @param ?int $database - * @param ?string $numberOfString - * @param ?string $handler - * @param array $params - * @return ?Entry - */ - public static function getCountEntry($count, $database = null, $numberOfString = null, $handler = null, $params = []) - { - if ($count == 0) { - return null; - } - if (!$numberOfString) { - $numberOfString = static::SQL_TABLE . ".alphabetical"; - } - $params["db"] ??= $database; - $href = Route::link($handler, static::PAGE_ALL, $params); - $entry = new Entry( - localize(static::SQL_TABLE . ".title"), - static::PAGE_ID, - str_format(localize($numberOfString, $count), $count), - "text", - // issue #26 for koreader: section is not supported - [ new LinkNavigation($href, "subsection") ], - $database, - "", - $count - ); - return $entry; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/BaseList.php b/COPS/cops-3.1.3/src/Calibre/BaseList.php deleted file mode 100644 index ecce38dd..00000000 --- a/COPS/cops-3.1.3/src/Calibre/BaseList.php +++ /dev/null @@ -1,635 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Input\Request; -use SebLucas\Cops\Model\Entry; -use SebLucas\Cops\Model\LinkFeed; -use SebLucas\Cops\Model\LinkNavigation; - -class BaseList -{ - public Request $request; - public string $className; - /** @var ?int */ - protected $databaseId = null; - /** @var ?int */ - protected $numberPerPage = null; - /** @var array */ - //protected $ignoredCategories = []; - /** @var ?string */ - public $orderBy = null; - protected string $handler = ''; - - /** - * @param class-string $className - * @param ?Request $request - * @param ?int $database - * @param ?int $numberPerPage - */ - public function __construct($className, $request, $database = null, $numberPerPage = null) - { - $this->className = $className; - $this->request = $request ?? new Request(); - $this->databaseId = $database ?? $this->request->database(); - $this->numberPerPage = $numberPerPage ?? $this->request->option("max_item_per_page"); - //$this->ignoredCategories = $this->request->option('ignored_categories'); - $this->setOrderBy(); - // get handler based on $this->request - $this->handler = $this->request->getHandler(); - } - - /** - * Summary of setOrderBy - * @return void - */ - protected function setOrderBy() - { - $this->orderBy = $this->request->getSorted($this->getSort()); - //$this->orderBy ??= $this->request->option('sort'); - } - - /** - * Summary of getOrderBy - * @return ?string - */ - protected function getOrderBy() - { - return match ($this->orderBy) { - 'title' => 'sort', - 'count' => 'count desc, name', - default => $this->orderBy, - }; - } - - /** - * Summary of getDatabaseId - * @return ?int - */ - public function getDatabaseId() - { - return $this->databaseId; - } - - /** Use inherited class methods to get entries from by instance (linked via books) */ - - /** - * Summary of getTable - * @return string - */ - public function getTable() - { - return $this->className::SQL_TABLE; - } - - /** - * Summary of getSort - * @return string - */ - public function getSort() - { - return $this->className::SQL_SORT; - } - - /** - * Summary of getCountColumns - * @return string - */ - public function getCountColumns() - { - return $this->className::SQL_COLUMNS . ", count(*) as count"; - } - - /** - * Summary of getLinkTable - * @return string - */ - public function getLinkTable() - { - return $this->className::SQL_LINK_TABLE; - } - - /** - * Summary of getLinkColumn - * @return string - */ - public function getLinkColumn() - { - return $this->className::SQL_LINK_COLUMN; - } - - /** Generic methods inherited by Author, Language, Publisher, Rating, Series, Tag classes */ - - /** - * Summary of getInstanceById - * @param ?int $id - * @return mixed - */ - public function getInstanceById($id) - { - return $this->className::getInstanceById($id, $this->databaseId); - } - - /** - * Summary of getWithoutEntry - * @return ?Entry - */ - public function getWithoutEntry() - { - $count = $this->countWithoutEntries(); - $instance = $this->getInstanceById(null); - $instance->setHandler($this->handler); - return $instance->getEntry($count); - } - - /** - * Summary of getEntryCount - * @return ?Entry - */ - public function getEntryCount() - { - return $this->className::getCount($this->databaseId); - } - - /** - * Summary of countRequestEntries - * @return int - */ - public function countRequestEntries() - { - if ($this->request->hasFilter()) { - return $this->countEntriesByFilter(); - } - return $this->countAllEntries(); - } - - /** - * Summary of countAllEntries - * @return int - */ - public function countAllEntries() - { - return Database::querySingle('select count(*) from ' . $this->getTable(), $this->databaseId); - } - - /** - * Summary of countDistinctEntries - * @param ?string $column - * @return int - */ - public function countDistinctEntries($column = null) - { - $column ??= $this->getSort(); - return Database::querySingle('select count(distinct ' . $column . ') from ' . $this->getTable(), $this->databaseId); - } - - /** - * Summary of countEntriesByFirstLetter - * @param string $letter - * @return int - */ - public function countEntriesByFirstLetter($letter) - { - $filterString = 'upper(' . $this->getTable() . '.' . $this->getSort() . ') like ?'; - $param = $letter . "%"; - $filter = new Filter($this->request, [], $this->getLinkTable(), $this->databaseId); - $filter->addFilter($filterString, $param); - return $this->countFilteredEntries($filter); - } - - /** - * Summary of countEntriesByFilter - * @return int - */ - public function countEntriesByFilter() - { - $filter = new Filter($this->request, [], $this->getLinkTable(), $this->databaseId); - return $this->countFilteredEntries($filter); - } - - /** - * Summary of countEntriesByInstance - * @param Base|Category $instance - * @param array $filterParams if we want to filter by virtual library etc. - * @return int - */ - public function countEntriesByInstance($instance, $filterParams = []) - { - $filter = new Filter($filterParams, [], $this->getLinkTable(), $this->databaseId); - $filter->addInstanceFilter($instance); - return $this->countFilteredEntries($filter); - } - - /** - * Summary of countFilteredEntries - * @param Filter $filter - * @return int - */ - public function countFilteredEntries($filter) - { - // select {0} from series, books_series_link where series.id = books_series_link.series {1} - $query = 'select {0} from ' . $this->getTable() . ', ' . $this->getLinkTable() . ' where ' . $this->getTable() . '.id = ' . $this->getLinkTable() . '.' . $this->getLinkColumn() . ' {1}'; - // count(distinct series.id) - $columns = 'count(distinct ' . $this->getTable() . '.id)'; - // and (exists (select null from books_authors_link, books where books_series_link.book = books.id and books_authors_link.book = books.id and books_authors_link.author = ?)) - $filterString = $filter->getFilterString(); - // [1] - $params = $filter->getQueryParams(); - return Database::countFilter($query, $columns, $filterString, $params, $this->databaseId); - } - - /** - * Summary of countWithoutEntries - * @return int - */ - public function countWithoutEntries() - { - // @todo see BookList::getBooksWithoutCustom() to support CustomColumn - if (!in_array($this->className, [Rating::class, Serie::class, Tag::class, Identifier::class])) { - return 0; - } - $query = $this->className::SQL_BOOKLIST_NULL; - $columns = 'count(distinct books.id)'; - return Database::countFilter($query, $columns, "", [], $this->databaseId); - } - - /** - * Summary of getRequestEntries - * @param int $n - * @return array - */ - public function getRequestEntries($n = 1) - { - if ($this->request->hasFilter()) { - return $this->getEntriesByFilter($n); - } - return $this->getAllEntries($n); - } - - /** - * Summary of getAllEntries = same as getAll() in child class - * @param int $n - * @return array - */ - public function getAllEntries($n = 1) - { - $query = $this->className::SQL_ALL_ROWS; - if (!empty($this->orderBy) && $this->orderBy != $this->getSort() && str_contains($this->getCountColumns(), ' as ' . $this->orderBy)) { - if (str_contains($query, 'order by')) { - $query = preg_replace('/\s+order\s+by\s+[\w.]+(\s+(asc|desc)|)\s*/i', ' order by ' . $this->getOrderBy() . ' ', $query); - } else { - $query .= ' order by ' . $this->getOrderBy() . ' '; - } - } - $columns = $this->getCountColumns(); - return $this->getEntryArrayWithBookNumber($query, $columns, "", [], $n); - } - - /** - * Summary of getAllEntriesByQuery - * @param string $find - * @param int $n - * @param int $repeat for SCOPE_AUTHOR we need to repeat the query x 2 because Author checks both name and sort fields - * @return array - */ - public function getAllEntriesByQuery($find, $n = 1, $repeat = 1) - { - $query = $this->className::SQL_ROWS_FOR_SEARCH; - $columns = $this->getCountColumns(); - // Author has 2 params, the rest 1 - $params = array_fill(0, $repeat, '%' . $find . '%'); - if ($this->request->hasFilter()) { - $filter = new Filter($this->request, $params, $this->getLinkTable(), $this->databaseId); - $filterString = $filter->getFilterString(); - $params = $filter->getQueryParams(); - return $this->getEntryArrayWithBookNumber($query, $columns, $filterString, $params, $n); - } - return $this->getEntryArrayWithBookNumber($query, $columns, "", $params, $n); - } - - /** - * Summary of getCountByFirstLetter - * @return array - */ - public function getCountByFirstLetter() - { - // substr(upper(authors.sort), 1, 1) - $groupField = 'substr(upper(' . $this->getTable() . '.' . $this->getSort() . '), 1, 1)'; - return $this->getCountByGroup($groupField, $this->className::PAGE_LETTER, 'letter'); - } - - /** - * Summary of getCountByGroup - * @param string $groupField - * @param string $page - * @param string $label - * @return array - */ - public function getCountByGroup($groupField, $page, $label) - { - $filter = new Filter($this->request, [], $this->getLinkTable(), $this->databaseId); - $filterString = $filter->getFilterString(); - $params = $filter->getQueryParams(); - - if (!in_array($this->orderBy, ['groupid', 'count'])) { - $this->orderBy = 'groupid'; - } - $sortBy = $this->getOrderBy(); - // select {0} from authors, books_authors_link where authors.id = books_authors_link.author {1} - $query = 'select {0} from ' . $this->getTable() . ', ' . $this->getLinkTable() . ' where ' . $this->getTable() . '.id = ' . $this->getLinkTable() . '.' . $this->getLinkColumn() . ' {1}'; - // group by groupid - $query .= ' group by groupid'; - // order by $sortBy - $query .= ' order by ' . $sortBy; - // $groupField as groupid, count(distinct authors.id) as count - $columns = $groupField . ' as groupid, count(distinct ' . $this->getTable() . '.id) as count'; - $result = Database::queryFilter($query, $columns, $filterString, $params, -1, $this->databaseId); - - $entryArray = []; - $params = $this->request->getFilterParams(); - $params["db"] ??= $this->databaseId; - while ($post = $result->fetchObject()) { - $params["id"] = $post->groupid; - $href = Route::link($this->handler, $page, $params); - array_push($entryArray, new Entry( - $post->groupid, - $this->className::PAGE_ID . ':' . $label . ':' . $post->groupid, - str_format(localize('bookword', $post->count), $post->count), - 'text', - [ new LinkNavigation($href, "subsection") ], - $this->databaseId, - ucfirst($label), - $post->count - )); - } - return $entryArray; - } - - /** - * Summary of getEntriesByFirstLetter - * @param string $letter - * @param int $n - * @return array - */ - public function getEntriesByFirstLetter($letter, $n = 1) - { - $query = $this->className::SQL_ROWS_BY_FIRST_LETTER; - $columns = $this->getCountColumns(); - $filter = new Filter($this->request, [$letter . "%"], $this->getLinkTable(), $this->databaseId); - $filterString = $filter->getFilterString(); - $params = $filter->getQueryParams(); - return $this->getEntryArrayWithBookNumber($query, $columns, $filterString, $params, $n); - } - - /** - * Summary of getEntriesByFilter - * @param int $n - * @return array - */ - public function getEntriesByFilter($n = 1) - { - $filter = new Filter($this->request, [], $this->getLinkTable(), $this->databaseId); - return $this->getFilteredEntries($filter, $n); - } - - /** - * Summary of getEntriesByInstance - * @param Base|Category $instance - * @param int $n - * @param array $filterParams if we want to filter by virtual library etc. - * @return array - */ - public function getEntriesByInstance($instance, $n = 1, $filterParams = []) - { - $filter = new Filter($filterParams, [], $this->getLinkTable(), $this->databaseId); - $filter->addInstanceFilter($instance); - $entries = $this->getFilteredEntries($filter, $n); - $limit = $instance->getFilterLimit(); - // are we at the filter limit for this instance? - if ($n == 1 && count($entries) < $limit) { - return $entries; - } - // if so, let's see how many entries we're missing - $total = $this->countEntriesByInstance($instance, $filterParams); - $count = $total - count($entries); - if ($count < 1) { - return $entries; - } - // @todo let the caller know there are more entries available - // @todo we can't use facetGroups here, or OPDS reader thinks we're drilling down :-() - $className = $instance->getClassName($this->className); - $title = strtolower($className); - $title = localize($title . 's.title'); - if ($n > 1) { - $paging = '&filter=1'; - if ($n > 2) { - $paging .= '&g[' . $this->className::URL_PARAM . ']=' . strval($n - 1); - } - $entry = new Entry( - localize("paging.previous.alternate") . " " . $title, - $instance->getEntryId() . ':filter:', - $instance->getContent($count), - "text", - [ new LinkFeed($instance->getUri() . $paging) ], - $this->databaseId, - $className, - $count - ); - array_push($entries, $entry); - } - if ($n < ceil($total / $limit)) { - $paging = '&filter=1'; - $paging .= '&g[' . $this->className::URL_PARAM . ']=' . strval($n + 1); - $entry = new Entry( - localize("paging.next.alternate") . " " . $title, - $instance->getEntryId() . ':filter:', - $instance->getContent($count), - "text", - [ new LinkFeed($instance->getUri() . $paging) ], - $this->databaseId, - $className, - $count - ); - array_push($entries, $entry); - } - return $entries; - } - - /** - * Summary of getEntriesByCustomValueId - * @param CustomColumnType $customType - * @param mixed $valueId - * @param int $n - * @return array - */ - public function getEntriesByCustomValueId($customType, $valueId, $n = 1) - { - $filter = new Filter([], [], $this->getLinkTable(), $this->databaseId); - $filter->addCustomIdFilter($customType, $valueId); - return $this->getFilteredEntries($filter, $n); - } - - /** - * Summary of getFilteredEntries - * @param Filter $filter - * @param int $n - * @return array - */ - public function getFilteredEntries($filter, $n = 1) - { - $query = $this->className::SQL_ALL_ROWS; - if (!empty($this->orderBy) && $this->orderBy != $this->getSort() && str_contains($this->getCountColumns(), ' as ' . $this->orderBy)) { - if (str_contains($query, 'order by')) { - $query = preg_replace('/\s+order\s+by\s+[\w.]+(\s+(asc|desc)|)\s*/i', ' order by ' . $this->getOrderBy() . ' ', $query); - } else { - $query .= ' order by ' . $this->getOrderBy() . ' '; - } - } - $columns = $this->getCountColumns(); - $filterString = $filter->getFilterString(); - $params = $filter->getQueryParams(); - return $this->getEntryArrayWithBookNumber($query, $columns, $filterString, $params, $n); - } - - /** - * Summary of getEntryArrayWithBookNumber - * @param string $query - * @param string $columns - * @param string $filter - * @param array $params - * @param int $n - * @return array - */ - public function getEntryArrayWithBookNumber($query, $columns, $filter, $params, $n) - { - $result = Database::queryFilter($query, $columns, $filter, $params, $n, $this->databaseId, $this->numberPerPage); - $entryArray = []; - $params = []; - if ($this->request->hasFilter()) { - $params = $this->request->getFilterParams(); - //$params["db"] ??= $this->databaseId; - } - while ($post = $result->fetchObject()) { - /** @var Author|Tag|Serie|Publisher|Language|Rating|Book $instance */ - if ($this->className == Book::class) { - $post->count = 1; - } - - $instance = new $this->className($post, $this->databaseId); - $instance->setHandler($this->handler); - array_push($entryArray, $instance->getEntry($post->count, $params)); - } - return $entryArray; - } - - /** - * Summary of hasChildCategories - * @return bool - */ - public function hasChildCategories() - { - if (empty(Config::get('calibre_categories_using_hierarchy')) || !in_array($this->className::CATEGORY, Config::get('calibre_categories_using_hierarchy'))) { - return false; - } - return true; - } - - /** - * Use the Calibre tag browser view to retrieve all tags or series with count - * Format: tag_browser_tags(id,name,count,avg_rating,sort) - * @param int $n - * @return array - */ - public function browseAllEntries($n = 1) - { - if (!$this->hasChildCategories()) { - return []; - } - $tableName = 'tag_browser_' . $this->className::CATEGORY; - $queryFormat = "SELECT id, name, count FROM {0} ORDER BY {1}"; - if (!in_array($this->orderBy, ['id', 'name', 'count', 'sort'])) { - $this->orderBy = "sort"; - } - $query = str_format($queryFormat, $tableName, $this->getOrderBy()); - - $result = Database::queryFilter($query, "", "", [], $n, $this->databaseId, $this->numberPerPage); - $entryArray = []; - while ($post = $result->fetchObject()) { - $instance = new $this->className($post, $this->databaseId); - $instance->setHandler($this->handler); - array_push($entryArray, $instance->getEntry($post->count)); - } - return $entryArray; - } - - /** - * Summary of getInstanceIdsByBookIds - * @param array $bookIds - * @return array> - */ - public function getInstanceIdsByBookIds($bookIds) - { - if (count($bookIds) < 1) { - return []; - } - $queryFormat = 'SELECT book, {1} as instanceId FROM {0} WHERE book IN (' . str_repeat('?,', count($bookIds) - 1) . '?)'; - $query = str_format($queryFormat, $this->getLinkTable(), $this->getLinkColumn()); - $result = Database::query($query, $bookIds, $this->databaseId); - - $instanceIds = []; - while ($post = $result->fetchObject()) { - $instanceIds[$post->book] ??= []; - array_push($instanceIds[$post->book], $post->instanceId); - } - return $instanceIds; - } - - /** - * Summary of getInstancesByIds - * @param array> $instanceIds - * @return array - */ - public function getInstancesByIds($instanceIds) - { - $uniqueIds = static::getUniqueInstanceIds($instanceIds); - if (count($uniqueIds) < 1) { - return []; - } - $query = 'select ' . $this->className::SQL_COLUMNS . ' from ' . $this->className::SQL_TABLE . ' where id IN (' . str_repeat('?,', count($uniqueIds) - 1) . '?)'; - $result = Database::query($query, $uniqueIds, $this->databaseId); - $instances = []; - while ($post = $result->fetchObject()) { - if ($this->className == Data::class) { - // we don't have the book available here, set later - $instances[$post->id] = new $this->className($post); - } else { - $instances[$post->id] = new $this->className($post, $this->databaseId); - $instances[$post->id]->setHandler($this->handler); - } - } - return $instances; - } - - /** - * Summary of getUniqueInstanceIds - * @param array> $instanceIds - * @return array - */ - public static function getUniqueInstanceIds($instanceIds) - { - $uniqueIds = []; - foreach ($instanceIds as $bookId => $instanceIdList) { - $uniqueIds = array_values(array_unique(array_merge($uniqueIds, $instanceIdList))); - } - return $uniqueIds; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/Book.php b/COPS/cops-3.1.3/src/Calibre/Book.php deleted file mode 100644 index b3317ed2..00000000 --- a/COPS/cops-3.1.3/src/Calibre/Book.php +++ /dev/null @@ -1,879 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Model\EntryBook; -use SebLucas\Cops\Model\LinkEntry; -use SebLucas\Cops\Model\LinkFeed; -use SebLucas\Cops\Output\FileResponse; -use SebLucas\Cops\Output\Format; -use SebLucas\Cops\Output\Response; -use SebLucas\Cops\Pages\PageId; -use SebLucas\EPubMeta\EPub; -use SebLucas\EPubMeta\Tools\ZipEdit; -use Exception; - -//class Book extends Base -class Book -{ - public const PAGE_ID = PageId::ALL_BOOKS_ID; - public const PAGE_ALL = PageId::ALL_BOOKS; - public const PAGE_LETTER = PageId::ALL_BOOKS_LETTER; - public const PAGE_YEAR = PageId::ALL_BOOKS_YEAR; - public const PAGE_DETAIL = PageId::BOOK_DETAIL; - public const SQL_TABLE = "books"; - public const SQL_LINK_TABLE = "books"; - public const SQL_LINK_COLUMN = "id"; - public const SQL_SORT = "sort"; - public const SQL_COLUMNS = 'books.id as id, books.title as title, text as comment, path, timestamp, pubdate, series_index, uuid, has_cover, ratings.rating'; - public const SQL_ALL_ROWS = BookList::SQL_BOOKS_ALL; - - public const SQL_BOOKS_LEFT_JOIN = 'left outer join comments on comments.book = books.id - left outer join books_ratings_link on books_ratings_link.book = books.id - left outer join ratings on books_ratings_link.rating = ratings.id '; - - public const BAD_SEARCH = 'QQQQQ'; - public const DATA_DIR_NAME = 'data'; - - /** @var int */ - public $id; - /** @var string */ - public $title; - /** @var mixed */ - public $timestamp; - /** @var mixed */ - public $pubdate; - /** @var string */ - public $path; - /** @var string */ - public $uuid; - /** @var bool */ - public $hasCover; - /** @var string */ - public $relativePath; - /** @var ?float */ - public $seriesIndex; - /** @var string */ - public $comment; - /** @var ?int */ - public $rating; - /** @var ?int */ - protected $databaseId = null; - /** @var ?array */ - public $datas = null; - /** @var ?array */ - public $extraFiles = null; - /** @var ?array */ - public $authors = null; - /** @var Publisher|false|null */ - public $publisher = null; - /** @var Serie|false|null */ - public $serie = null; - /** @var ?array */ - public $tags = null; - /** @var ?array */ - public $identifiers = null; - /** @var ?string */ - public $languages = null; - /** @var ?array */ - public $annotations = null; - /** @var array */ - public $format = []; - /** @var ?string */ - protected $coverFileName = null; - public bool $updateForKepub = false; - protected string $handler = ''; - - /** - * Summary of __construct - * @param object $line - * @param ?int $database - */ - public function __construct($line, $database = null) - { - $this->id = $line->id; - $this->title = $line->title; - $this->timestamp = strtotime($line->timestamp); - $this->pubdate = $line->pubdate; - //$this->path = Database::getDbDirectory() . $line->path; - //$this->relativePath = $line->path; - // -DC- Init relative or full path - if (!empty(Config::get('calibre_external_storage'))) { - $this->path = Config::get('calibre_external_storage') . str_replace('%2F', '/', rawurlencode($line->path)); - } else { - $this->path = $line->path; - if (!is_dir($this->path)) { - $this->path = Database::getDbDirectory($database) . $line->path; - } - } - $this->seriesIndex = $line->series_index; - $this->comment = $line->comment ?? ''; - $this->uuid = $line->uuid; - $this->hasCover = $line->has_cover; - $this->rating = $line->rating; - $this->databaseId = $database; - // do this at the end when all properties are set - if ($this->hasCover) { - $this->coverFileName = Cover::findCoverFileName($this, $line); - if (empty($this->coverFileName)) { - $this->hasCover = false; - } - } - } - - /** - * Summary of getDatabaseId - * @return ?int - */ - public function getDatabaseId() - { - return $this->databaseId; - } - - /** - * Summary of getCoverFileName - * @return ?string - */ - public function getCoverFileName() - { - if ($this->hasCover) { - return $this->coverFileName; - } - return null; - } - - /** - * Summary of getEntryId - * @return string - */ - public function getEntryId() - { - return PageId::ALL_BOOKS_UUID . ':' . $this->uuid; - } - - /** - * Summary of getEntryIdByLetter - * @param string $startingLetter - * @return string - */ - public static function getEntryIdByLetter($startingLetter) - { - return static::PAGE_ID . ':letter:' . $startingLetter; - } - - /** - * Summary of getEntryIdByYear - * @param string|int $year - * @return string - */ - public static function getEntryIdByYear($year) - { - return static::PAGE_ID . ':year:' . $year; - } - - /** - * Summary of getUri - * @param array $params - * @return string - */ - public function getUri($params = []) - { - $params['id'] = $this->id; - // we need databaseId here because we use Route::link with $handler - $params['db'] = $this->databaseId; - if (Config::get('use_route_urls')) { - $params['author'] = $this->getAuthorsName(); - $params['title'] = $this->getTitle(); - } - return Route::link($this->handler, static::PAGE_DETAIL, $params); - } - - /** - * Summary of getDetailUrl - * @param string|null $handler - * @param array $params - * @return string - */ - public function getDetailUrl($handler = null, $params = []) - { - $handler ??= $this->handler; - $params['id'] = $this->id; - // we need databaseId here because we use Route::link with $handler - $params['db'] = $this->databaseId; - if (Config::get('use_route_urls')) { - $params['author'] = $this->getAuthorsName(); - $params['title'] = $this->getTitle(); - } - return Route::link($handler, static::PAGE_DETAIL, $params); - } - - /** - * Summary of getTitle - * @return string - */ - public function getTitle() - { - return $this->title; - } - - /* Other class (author, series, tag, ...) initialization and accessors */ - - /** - * @param int $n - * @param ?string $sort - * @return ?array - */ - public function getAuthors($n = -1, $sort = null) - { - if (is_null($this->authors)) { - $this->authors = Author::getInstancesByBookId($this->id, $this->databaseId); - } - return $this->authors; - } - - /** - * Summary of getAuthorsName - * @return string - */ - public function getAuthorsName() - { - return implode(', ', array_map(function ($author) { - return $author->name; - }, $this->getAuthors())); - } - - /** - * Summary of getAuthorsSort - * @return string - */ - public function getAuthorsSort() - { - return implode(', ', array_map(function ($author) { - return $author->sort; - }, $this->getAuthors())); - } - - /** - * Summary of getPublisher - * @return Publisher|false - */ - public function getPublisher() - { - if (is_null($this->publisher)) { - $this->publisher = Publisher::getInstanceByBookId($this->id, $this->databaseId); - } - return $this->publisher; - } - - /** - * @return Serie|false - */ - public function getSerie() - { - if (is_null($this->serie)) { - $this->serie = Serie::getInstanceByBookId($this->id, $this->databaseId); - } - return $this->serie; - } - - /** - * @param int $n - * @param ?string $sort - * @return string - */ - public function getLanguages($n = -1, $sort = null) - { - if (is_null($this->languages)) { - $this->languages = Language::getLanguagesByBookId($this->id, $this->databaseId); - } - return $this->languages; - } - - /** - * @param int $n - * @param ?string $sort - * @return array - */ - public function getTags($n = -1, $sort = null) - { - if (is_null($this->tags)) { - $this->tags = Tag::getInstancesByBookId($this->id, $this->databaseId); - } - return $this->tags; - } - - /** - * Summary of getTagsName - * @return string - */ - public function getTagsName() - { - return implode(', ', array_map(function ($tag) { - return $tag->name; - }, $this->getTags())); - } - - /** - * @return array - */ - public function getIdentifiers() - { - if (is_null($this->identifiers)) { - $this->identifiers = Identifier::getInstancesByBookId($this->id, $this->databaseId); - } - return $this->identifiers; - } - - /** - * @return array - */ - public function getAnnotations() - { - if (is_null($this->annotations)) { - $this->annotations = Annotation::getInstancesByBookId($this->id, $this->databaseId); - } - return $this->annotations; - } - - /** - * @param string $source from metadata.opf file (default) - * @return Metadata|false - */ - public function getMetadata($source = 'file') - { - $file = realpath($this->path . '/metadata.opf'); - if (empty($file) || !file_exists($file)) { - return false; - } - $content = file_get_contents($file); - return Metadata::parseData($content); - } - - /** - * @return array - */ - public function getDatas() - { - if (is_null($this->datas)) { - $this->datas = static::getDataByBook($this); - } - return $this->datas; - } - - /** - * Get extra data files associated with this book - * @see https://manual.calibre-ebook.com/metadata.html#data-files - * @return array - */ - public function getExtraFiles() - { - if (is_null($this->extraFiles)) { - $this->extraFiles = []; - $dataPath = $this->path . '/' . static::DATA_DIR_NAME . '/'; - if (empty(Config::get('calibre_external_storage')) && is_dir($dataPath)) { - $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dataPath)); - foreach ($iterator as $file) { - if ($file->isDir()) { - continue; - } - if (!str_starts_with((string) $file->getPathname(), $dataPath)) { - continue; - } - array_push($this->extraFiles, substr((string) $file->getPathname(), strlen($dataPath))); - } - } - } - return $this->extraFiles; - } - - /** - * Summary of getExtraFileLink - * @param string $fileName - * @return LinkEntry - */ - public function getExtraFileLink($fileName) - { - $filePath = $this->path . '/' . static::DATA_DIR_NAME . '/' . $fileName; - $mimetype = Response::getMimeType($filePath) ?? 'application/octet-stream'; - if (Database::useAbsolutePath($this->databaseId)) { - $params = ['id' => $this->id, 'db' => $this->databaseId]; - if (Config::get('use_route_urls') && is_null($params['db'])) { - $params['db'] = 0; - } - $params['file'] = $fileName; - $url = Route::link("fetch", null, $params); - } else { - $url = Route::path(str_replace('%2F', '/', rawurlencode($filePath))); - } - $linkEntry = new LinkEntry( - $url, - $mimetype, - 'related', - $fileName - ); - $linkEntry->addFileInfo($filePath); - return $linkEntry; - } - - /** - * Summary of GetMostInterestingDataToSendToKindle - * @return ?Data - */ - public function GetMostInterestingDataToSendToKindle() - { - $bestFormatForKindle = ['PDF', 'AZW3', 'MOBI', 'EPUB']; - $bestRank = -1; - $bestData = null; - foreach ($this->getDatas() as $data) { - $key = array_search($data->format, $bestFormatForKindle); - if ($key !== false && $key > $bestRank) { - $bestRank = $key; - $bestData = $data; - } - } - return $bestData; - } - - /** - * Summary of getDataById - * @param int $idData - * @return Data|false - */ - public function getDataById($idData) - { - $reduced = array_filter($this->getDatas(), function ($data) use ($idData) { - return $data->id == $idData; - }); - return reset($reduced); - } - - /** - * Summary of getRating - * @return string - */ - public function getRating() - { - if (is_null($this->rating) || $this->rating == 0) { - return ''; - } - $retour = ''; - for ($i = 0; $i < $this->rating / 2; $i++) { - $retour .= '★'; // full star - } - for ($i = 0; $i < 5 - $this->rating / 2; $i++) { - $retour .= '☆'; // empty star - } - return $retour; - } - - /** - * Summary of getPubDate - * @return string - */ - public function getPubDate() - { - if (empty($this->pubdate)) { - return ''; - } - $dateY = (int) substr((string) $this->pubdate, 0, 4); - if ($dateY > 102) { - return str_pad(strval($dateY), 4, '0', STR_PAD_LEFT); - } - return ''; - } - - /** - * Summary of getComment - * @param bool $withSerie - * @return string - */ - public function getComment($withSerie = true) - { - $addition = ''; - $se = $this->getSerie(); - if (!empty($se) && $withSerie) { - $addition = $addition . '' . localize('content.series') . '' . str_format(localize('content.series.data'), $this->seriesIndex, htmlspecialchars($se->name)) . "
    \n"; - } - //if (preg_match('/<\/(div|p|a|span)>/', $this->comment)) { - return $addition . Format::html2xhtml($this->comment); - //} else { - // return $addition . htmlspecialchars($this->comment); - //} - } - - /** - * Summary of getDataFormat - * @param string $format - * @return Data|false - */ - public function getDataFormat($format) - { - $reduced = array_filter($this->getDatas(), function ($data) use ($format) { - return $data->format == $format; - }); - return reset($reduced); - } - - /** - * @checkme always returns absolute path for single DB in PHP app here - cfr. internal dir for X-Accel-Redirect with Nginx - * @param string $extension - * @param int $idData - * @param bool $encoded url encode filename - * @return string|false|null string for file path, false for missing cover, null for missing data - */ - public function getFilePath($extension, $idData = null, $encoded = false) - { - if ($extension == "jpg" || $extension == "png") { - return $this->getCoverFilePath($extension); - } - $data = $this->getDataById($idData); - if (!$data) { - return null; - } - $file = $data->name . "." . strtolower($data->format); - if ($encoded) { - return $this->path . '/' . rawurlencode($file); - } - return $this->path . '/' . $file; - } - - /** - * @checkme always returns absolute path for single DB in PHP app here - cfr. internal dir for X-Accel-Redirect with Nginx - * @param string $extension - * @return string|false string for file path, false for missing cover - */ - public function getCoverFilePath($extension) - { - if (empty($this->coverFileName)) { - return $this->path . '/cover.' . $extension; - } else { - $ext = strtolower(pathinfo($this->coverFileName, PATHINFO_EXTENSION)); - if ($ext == $extension) { - return $this->coverFileName; - } - } - return false; - } - - /** - * Summary of sendUpdatedEpub - * @param int $idData - * @param FileResponse $response - * @return FileResponse - */ - public function sendUpdatedEpub($idData, $response) - { - $data = $this->getDataById($idData); - - // if we want to update metadata and then use kepubify, we need to save the updated Epub first - if ($this->updateForKepub && !empty(Config::get('kepubify_path'))) { - // make a temp copy for the updated Epub file - $tmpfile = FileResponse::getTempFile('epub'); - if (!copy($data->getLocalPath(), $tmpfile)) { - // this will call exit() - Response::sendError(null, 'Error: unable to copy epub file'); - } - $filePath = $tmpfile; - } else { - $filePath = $data->getLocalPath(); - } - - try { - $epub = new EPub($filePath, ZipEdit::class); - - $epub->setTitle($this->title); - $authorArray = []; - foreach ($this->getAuthors() as $author) { - $authorArray[$author->sort] = $author->name; - } - $epub->setAuthors($authorArray); - $epub->setLanguage($this->getLanguages()); - $epub->setDescription($this->getComment(false)); - $epub->setSubjects($this->getTagsName()); - // -DC- Use cover file name - // $epub->Cover2($this->getCoverFilePath('jpg'), 'image/jpeg'); - $epub->setCoverFile($this->coverFileName, 'image/jpeg'); - $epub->setCalibre($this->uuid); - $se = $this->getSerie(); - if (!empty($se)) { - $epub->setSeries($se->name); - $epub->setSeriesIndex(strval($this->seriesIndex)); - } - $filename = $data->getUpdatedFilenameEpub(); - // @checkme this is set in fetch.php now - if ($this->updateForKepub) { - $filename = $data->getUpdatedFilenameKepub(); - // @todo no cache control here!? - $response->setHeaders($data->getMimeType(), null, basename($filename)); - // save updated Epub file and convert to kepub - if (!empty(Config::get('kepubify_path'))) { - $epub->save(); - - // run kepubify on updated Epub file and send converted tmpfile - $result = $this->runKepubify($filePath, $response); - if (empty($result)) { - // this will call exit() - Response::sendError(null, 'Error: failed to convert epub file'); - } - return $result; - } - $epub->updateForKepub(); - } - // @todo no cache control here!? - //$response->setHeaders($data->getMimeType(), null, basename($filename)); - $sendHeaders = headers_sent() ? false : true; - $epub->download($filename, $sendHeaders); - return $response; - } catch (Exception $e) { - // this will call exit() - Response::sendError(null, 'Exception: ' . $e->getMessage()); - } - } - - /** - * Summary of runKepubify - * @param string $filepath - * @param ?FileResponse $response - * @return FileResponse|string|null - */ - public function runKepubify($filepath, $response = null) - { - if (empty(Config::get('kepubify_path'))) { - return null; - } - $tmpfile = FileResponse::getTempFile('kepub.epub'); - $cmd = escapeshellarg((string) Config::get('kepubify_path')); - $cmd .= ' -o ' . escapeshellarg($tmpfile); - $cmd .= ' ' . escapeshellarg($filepath); - exec($cmd, $output, $return); - if ($return == 0 && file_exists($tmpfile)) { - if (!empty($response)) { - return $response->sendFile($tmpfile, true); - } - return $tmpfile; - } - return null; - } - - /** - * The values of all the specified columns - * - * @param string[] $columns - * @param bool $asArray - * @return array - */ - public function getCustomColumnValues($columns, $asArray = false) - { - $result = []; - $database = $this->databaseId; - - $columns = CustomColumnType::checkCustomColumnList($columns, $database); - - foreach ($columns as $lookup) { - $col = CustomColumnType::createByLookup($lookup, $database); - if (!is_null($col)) { - $cust = $col->getCustomByBook($this); - if ($asArray) { - array_push($result, $cust->toArray()); - } else { - array_push($result, $cust); - } - } - } - - return $result; - } - - /** - * Summary of getLinkArray - * @param array $params @todo is this useful here? - * @return array - */ - public function getLinkArray($params = []) - { - $database = $this->databaseId; - $linkArray = []; - - $cover = new Cover($this); - $coverLink = $cover->getCoverLink(); - if ($coverLink) { - array_push($linkArray, $coverLink); - } - // @todo set height for thumbnail here depending on opds vs. html - $thumb = 'html'; - $thumbnailLink = $cover->getThumbnailLink($thumb); - if ($thumbnailLink) { - array_push($linkArray, $thumbnailLink); - } - - foreach ($this->getDatas() as $data) { - if ($data->isKnownType()) { - $linkEntry = $data->getDataLink(LinkEntry::OPDS_ACQUISITION_TYPE, $data->format); - if (empty(Config::get('calibre_external_storage'))) { - $linkEntry->addFileInfo($data->getLocalPath()); - } - array_push($linkArray, $linkEntry); - } - } - - // don't use collection here, or OPDS reader will group all entries together - messes up recent books - foreach ($this->getAuthors() as $author) { - /** @var Author $author */ - $author->setHandler($this->handler); - array_push( - $linkArray, - new LinkFeed( - $author->getUri(), - 'related', - str_format(localize('bookentry.author'), localize('splitByLetter.book.other'), $author->name) - ) - ); - } - - // don't use collection here, or OPDS reader will group all entries together - messes up recent books - $serie = $this->getSerie(); - if (!empty($serie)) { - $serie->setHandler($this->handler); - array_push( - $linkArray, - new LinkFeed( - $serie->getUri(), - 'related', - str_format(localize('content.series.data'), $this->seriesIndex, $serie->name) - ) - ); - } - - return $linkArray; - } - - /** - * Summary of setHandler - * @param string $handler - * @return void - */ - public function setHandler($handler) - { - $this->handler = $handler; - } - - /** - * Summary of getHandler - * @return string - */ - public function getHandler() - { - return $this->handler; - } - - /** - * Summary of getEntry - * @param int $count - * @param array $params - * @return EntryBook - */ - public function getEntry($count = 0, $params = []) - { - return new EntryBook( - $this->getTitle(), - $this->getEntryId(), - $this->getComment(), - 'text/html', - $this->getLinkArray($params), - $this - ); - } - - /* End of other class (author, series, tag, ...) initialization and accessors */ - - // -DC- Get customisable book columns - /** - * Summary of getBookColumns - * @return string - */ - public static function getBookColumns() - { - $res = static::SQL_COLUMNS; - if (!empty(Config::get('calibre_database_field_cover'))) { - $res = str_replace('has_cover,', 'has_cover, ' . Config::get('calibre_database_field_cover') . ',', $res); - } - - return $res; - } - - /** - * Summary of getBookById - * @param int $bookId - * @param ?int $database - * @return ?Book - */ - public static function getBookById($bookId, $database = null) - { - $query = 'select ' . static::getBookColumns() . ' -from books ' . static::SQL_BOOKS_LEFT_JOIN . ' -where books.id = ?'; - $result = Database::query($query, [$bookId], $database); - while ($post = $result->fetchObject()) { - $book = new Book($post, $database); - return $book; - } - return null; - } - - /** - * Summary of getBookByDataId - * @param int $dataId - * @param ?int $database - * @return ?Book - */ - public static function getBookByDataId($dataId, $database = null) - { - $query = 'select ' . static::getBookColumns() . ', data.name, data.format -from data, books ' . static::SQL_BOOKS_LEFT_JOIN . ' -where data.book = books.id and data.id = ?'; - $result = Database::query($query, [$dataId], $database); - while ($post = $result->fetchObject()) { - $book = new Book($post, $database); - $data = new Data($post, $book); - $data->id = $dataId; - $book->datas = [$data]; - return $book; - } - return null; - } - - /** - * Summary of getDataByBook - * @param Book $book - * @return array - */ - public static function getDataByBook($book) - { - $out = []; - - $sql = 'select id, format, name from data where book = ?'; - - $ignored_formats = Config::get('ignored_formats'); - if (count($ignored_formats) > 0) { - $sql .= " and format not in ('" - . implode("','", $ignored_formats) - . "')"; - } - - $database = $book->getDatabaseId(); - $result = Database::query($sql, [$book->id], $database); - - while ($post = $result->fetchObject()) { - array_push($out, new Data($post, $book)); - } - return $out; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/BookList.php b/COPS/cops-3.1.3/src/Calibre/BookList.php deleted file mode 100644 index b3b287d8..00000000 --- a/COPS/cops-3.1.3/src/Calibre/BookList.php +++ /dev/null @@ -1,622 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Input\Request; -use SebLucas\Cops\Model\Entry; -use SebLucas\Cops\Model\EntryBook; -use SebLucas\Cops\Model\LinkFeed; -use SebLucas\Cops\Model\LinkNavigation; -use SebLucas\Cops\Pages\PageId; -use SebLucas\Cops\Pages\PageQueryResult; -use Exception; - -class BookList -{ - public const SQL_BOOKS_ALL = 'select {0} from books ' . Book::SQL_BOOKS_LEFT_JOIN . ' where 1=1 {1} order by books.sort '; - public const SQL_BOOKS_BY_FIRST_LETTER = 'select {0} from books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where upper (books.sort) like ? {1} order by books.sort'; - public const SQL_BOOKS_BY_PUB_YEAR = 'select {0} from books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where substr(date(books.pubdate), 1, 4) = ? {1} order by books.sort'; - public const SQL_BOOKS_QUERY = 'select {0} from books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where ( - exists (select null from authors, books_authors_link where book = books.id and author = authors.id and authors.name like ?) or - exists (select null from tags, books_tags_link where book = books.id and tag = tags.id and tags.name like ?) or - exists (select null from series, books_series_link on book = books.id and books_series_link.series = series.id and series.name like ?) or - exists (select null from publishers, books_publishers_link where book = books.id and books_publishers_link.publisher = publishers.id and publishers.name like ?) or - title like ?) {1} order by books.sort'; - public const SQL_BOOKS_RECENT = 'select {0} from books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where 1=1 {1} order by books.timestamp desc limit '; - public const URL_PARAM_FIRST = "f"; - public const URL_PARAM_YEAR = "y"; - - public const BAD_SEARCH = 'QQQQQ'; - public const BATCH_QUERY = false; - - public Request $request; - /** @var ?int */ - protected $databaseId = null; - /** @var ?int */ - protected $numberPerPage = null; - /** @var array */ - //protected $ignoredCategories = []; - /** @var ?string */ - public $orderBy = null; - /** @var array */ - public $bookList = []; - protected string $handler = ''; - - /** - * @param ?Request $request - * @param ?int $database - * @param ?int $numberPerPage - */ - public function __construct($request, $database = null, $numberPerPage = null) - { - $this->request = $request ?? new Request(); - $this->databaseId = $database ?? $this->request->database(); - $this->numberPerPage = $numberPerPage ?? $this->request->option("max_item_per_page"); - //$this->ignoredCategories = $this->request->option('ignored_categories'); - $this->setOrderBy(); - // get handler based on $this->request - $this->handler = $this->request->getHandler(); - } - - /** - * Summary of setOrderBy - * @return void - */ - protected function setOrderBy() - { - $this->orderBy = $this->request->getSorted(); - //$this->orderBy ??= $this->request->option('sort'); - } - - /** - * Summary of getOrderBy - * @return ?string - */ - protected function getOrderBy() - { - return match ($this->orderBy) { - 'title asc', 'title' => 'books.sort asc', - 'title desc' => 'books.sort desc', - 'author asc', 'author' => 'books.author_sort asc', - 'author desc' => 'books.author_sort desc', - 'pubdate desc', 'pubdate' => 'books.pubdate desc', - 'pubdate asc' => 'books.pubdate asc', - 'rating desc', 'rating' => 'ratings.rating desc', - 'rating asc' => 'ratings.rating asc', - 'timestamp desc', 'timestamp' => 'books.timestamp desc', - 'timestamp asc' => 'books.timestamp asc', - 'count desc', 'count' => 'count desc', - 'count asc' => 'count asc', - default => $this->orderBy, - }; - } - - /** - * Summary of getBookCount - * @return int - */ - public function getBookCount() - { - if ($this->request->hasFilter()) { - return $this->getFilterBookCount(); - } - return Database::querySingle('select count(*) from books', $this->databaseId); - } - - /** - * Summary of getFilterBookCount - * @return int - */ - public function getFilterBookCount() - { - $filter = new Filter($this->request, [], "books", $this->databaseId); - $filterString = $filter->getFilterString(); - $params = $filter->getQueryParams(); - return Database::countFilter(static::SQL_BOOKS_ALL, 'count(*)', $filterString, $params, $this->databaseId); - } - - /** - * Summary of getCount - * @return array - */ - public function getCount() - { - $nBooks = $this->getBookCount(); - $result = []; - $params = $this->request->getFilterParams(); - $params["db"] ??= $this->databaseId; - $href = Route::link($this->handler, Book::PAGE_ALL, $params); - // issue #26 for koreader: section is not supported - if (!empty(Config::get('titles_split_first_letter'))) { - $linkArray = [ new LinkNavigation($href, "subsection") ]; - } elseif (!empty(Config::get('titles_split_publication_year'))) { - $linkArray = [ new LinkNavigation($href, "subsection") ]; - } else { - $linkArray = [ new LinkFeed($href, null) ]; - } - $entry = new Entry( - localize('allbooks.title'), - Book::PAGE_ID, - str_format(localize('allbooks.alphabetical', $nBooks), $nBooks), - 'text', - $linkArray, - $this->databaseId, - '', - $nBooks - ); - array_push($result, $entry); - if (Config::get('recentbooks_limit') > 0) { - $href = Route::link($this->handler, PageId::ALL_RECENT_BOOKS, $params); - $count = ($nBooks > Config::get('recentbooks_limit')) ? Config::get('recentbooks_limit') : $nBooks; - $entry = new Entry( - localize('recent.title'), - PageId::ALL_RECENT_BOOKS_ID, - str_format(localize('recent.list'), $count), - 'text', - [ new LinkFeed($href, 'http://opds-spec.org/sort/new')], - $this->databaseId, - '', - $count - ); - array_push($result, $entry); - } - return $result; - } - - /** - * Summary of getBooksByInstance - * @param Base|Author|Identifier|Language|Publisher|Rating|Serie|Tag|CustomColumn $instance - * @param int $n - * @return array{0: EntryBook[], 1: integer} - */ - public function getBooksByInstance($instance, $n) - { - if (empty($instance->id) && in_array($instance::class, [Rating::class, Serie::class, Tag::class, Identifier::class])) { - return $this->getBooksWithoutInstance($instance, $n); - } - [$query, $params] = $instance->getQuery(); - return $this->getEntryArray($query, $params, $n); - } - - /** - * Summary of getBooksByInstanceOrChildren - * @param Category $instance - * @param int $n - * @return array{0: EntryBook[], 1: integer} - */ - public function getBooksByInstanceOrChildren($instance, $n) - { - [$query, $params] = $instance->getQuery(); - $children = $instance->getChildCategories(); - if (!empty($children)) { - $childIds = []; - foreach ($children as $child) { - array_push($childIds, $child->id); - } - $params = array_merge($params, $childIds); - $query = str_replace(' = ? ', ' IN (' . str_repeat('?,', count($params) - 1) . '?)', $query); - // use distinct here in case books belong to several child categories - $query = str_ireplace('select ', 'select distinct ', $query); - } - return $this->getEntryArray($query, $params, $n); - } - - /** - * Summary of getBooksWithoutInstance - * @param mixed $instance - * @param int $n - * @return array{0: EntryBook[], 1: integer} - */ - public function getBooksWithoutInstance($instance, $n) - { - // in_array("series", Config::get('show_not_set_filter')) - if ($instance instanceof CustomColumn) { - return $this->getBooksWithoutCustom($instance->customColumnType, $n); - } - return $this->getEntryArray($instance::SQL_BOOKLIST_NULL, [], $n); - } - - /** - * Summary of getBooksByCustomYear - * @param CustomColumnTypeDate $columnType - * @param string|int $year - * @param int $n - * @return array{0: EntryBook[], 1: integer} - */ - public function getBooksByCustomYear($columnType, $year, $n) - { - [$query, $params] = $columnType->getQueryByYear($year); - - return $this->getEntryArray($query, $params, $n); - } - - /** - * Summary of getBooksByCustomRange - * @param CustomColumnTypeInteger $columnType - * @param string $range - * @param int $n - * @return array{0: EntryBook[], 1: integer} - */ - public function getBooksByCustomRange($columnType, $range, $n) - { - [$query, $params] = $columnType->getQueryByRange($range); - - return $this->getEntryArray($query, $params, $n); - } - - /** - * Summary of getBooksWithoutCustom - * @param CustomColumnType $columnType - * @param int $n - * @return array{0: EntryBook[], 1: integer} - */ - public function getBooksWithoutCustom($columnType, $n) - { - // use null here to reduce conflict with bool and int custom columns - [$query, $params] = $columnType->getQuery(null); - return $this->getEntryArray($query, $params, $n); - } - - /** - * Summary of getBooksByQueryScope - * @param array $queryScope - * @param int $n - * @param array $ignoredCategories - * @return array{0: EntryBook[], 1: integer} - */ - public function getBooksByQueryScope($queryScope, $n, $ignoredCategories = []) - { - $i = 0; - $critArray = []; - foreach ([PageQueryResult::SCOPE_AUTHOR, - PageQueryResult::SCOPE_TAG, - PageQueryResult::SCOPE_SERIES, - PageQueryResult::SCOPE_PUBLISHER, - PageQueryResult::SCOPE_BOOK] as $key) { - if (in_array($key, $ignoredCategories) || - (!array_key_exists($key, $queryScope) && !array_key_exists('all', $queryScope))) { - $critArray[$i] = static::BAD_SEARCH; - } else { - if (array_key_exists($key, $queryScope)) { - $critArray[$i] = $queryScope[$key]; - } else { - $critArray[$i] = $queryScope["all"]; - } - } - $i++; - } - return $this->getEntryArray(static::SQL_BOOKS_QUERY, $critArray, $n); - } - - /** - * Summary of getAllBooks - * @param int $n - * @return array{0: EntryBook[], 1: integer} - */ - public function getAllBooks($n = 1) - { - [$entryArray, $totalNumber] = $this->getEntryArray(static::SQL_BOOKS_ALL, [], $n); - return [$entryArray, $totalNumber]; - } - - /** - * Summary of getCountByFirstLetter - * @return array - */ - public function getCountByFirstLetter() - { - return $this->getCountByGroup('substr(upper(books.sort), 1, 1)', Book::PAGE_LETTER, 'letter'); - } - - /** - * Summary of getCountByPubYear - * @return array - */ - public function getCountByPubYear() - { - return $this->getCountByGroup('substr(date(books.pubdate), 1, 4)', Book::PAGE_YEAR, 'year'); - } - - /** - * Summary of getCountByGroup - * @param string $groupField - * @param string $page - * @param string $label - * @return array - */ - public function getCountByGroup($groupField, $page, $label) - { - $filter = new Filter($this->request, [], "books", $this->databaseId); - $filterString = $filter->getFilterString(); - $params = $filter->getQueryParams(); - - // check orderBy to sort by count - if (!in_array($this->orderBy, ['groupid', 'count'])) { - $this->orderBy = 'groupid'; - } - $sortBy = $this->getOrderBy(); - $result = Database::queryFilter('select {0} -from books -where 1=1 {1} -group by groupid -order by ' . $sortBy, $groupField . ' as groupid, count(*) as count', $filterString, $params, -1, $this->databaseId); - - $entryArray = []; - while ($post = $result->fetchObject()) { - $params = ['id' => $post->groupid, 'db' => $this->databaseId]; - $href = Route::link($this->handler, $page, $params); - array_push($entryArray, new Entry( - $post->groupid, - Book::PAGE_ID . ':' . $label . ':' . $post->groupid, - str_format(localize('bookword', $post->count), $post->count), - 'text', - [ new LinkFeed($href, "subsection") ], - $this->databaseId, - ucfirst($label), - $post->count - )); - } - return $entryArray; - } - - /** - * Summary of getBooksByFirstLetter - * @param string $letter - * @param int $n - * @return array{0: EntryBook[], 1: integer} - */ - public function getBooksByFirstLetter($letter, $n) - { - return $this->getEntryArray(static::SQL_BOOKS_BY_FIRST_LETTER, [$letter . '%'], $n); - } - - /** - * Summary of getBooksByPubYear - * @param string|int $year - * @param int $n - * @return array{0: EntryBook[], 1: integer} - */ - public function getBooksByPubYear($year, $n) - { - return $this->getEntryArray(static::SQL_BOOKS_BY_PUB_YEAR, [$year], $n); - } - - /** - * Summary of getAllRecentBooks - * @return array - */ - public function getAllRecentBooks() - { - [$entryArray, ] = $this->getEntryArray(static::SQL_BOOKS_RECENT . Config::get('recentbooks_limit'), [], -1); - return $entryArray; - } - - /** - * Summary of getEntryArray - * @param string $query - * @param array $params - * @param int $n - * @return array{0: EntryBook[], 1: integer} - */ - public function getEntryArray($query, $params, $n) - { - $filter = new Filter($this->request, $params, "books", $this->databaseId); - $filterString = $filter->getFilterString(); - $params = $filter->getQueryParams(); - - if (isset($this->orderBy) && $this->orderBy !== Book::SQL_SORT) { - if (str_contains($query, 'order by')) { - $query = preg_replace('/\s+order\s+by\s+[\w.]+(\s+(asc|desc)|)\s*/i', ' order by ' . $this->getOrderBy() . ' ', $query); - } else { - $query .= ' order by ' . $this->getOrderBy() . ' '; - } - } - - /** @var integer $totalNumber */ - /** @var \PDOStatement $result */ - [$totalNumber, $result] = Database::queryTotal($query, Book::getBookColumns(), $filterString, $params, $n, $this->databaseId, $this->numberPerPage); - - if (static::BATCH_QUERY) { - return $this->batchQuery($totalNumber, $result); - } - $entryArray = []; - while ($post = $result->fetchObject()) { - $book = new Book($post, $this->databaseId); - $book->setHandler($this->handler); - array_push($entryArray, $book->getEntry()); - } - return [$entryArray, $totalNumber]; - } - - /** - * Summary of batchQuery - * @param int $totalNumber - * @param \PDOStatement $result - * @throws \Exception - * @return array{0: EntryBook[], 1: integer} - */ - public function batchQuery($totalNumber, $result) - { - $this->bookList = []; - while ($post = $result->fetchObject()) { - $book = new Book($post, $this->databaseId); - $book->setHandler($this->handler); - $this->bookList[$book->id] = $book; - } - $entryArray = []; - if (count($this->bookList) < 1) { - return [$entryArray, $totalNumber]; - } - $this->setAuthors(); - $this->setSerie(); - $this->setPublisher(); - $this->setTags(); - $this->setLanguages(); - $this->setDatas(); - foreach ($this->bookList as $bookId => $book) { - array_push($entryArray, $book->getEntry()); - } - $this->bookList = []; - return [$entryArray, $totalNumber]; - } - - /** - * Summary of setAuthors - * @throws \Exception - * @return void - */ - public function setAuthors() - { - $bookIds = array_keys($this->bookList); - $baselist = new BaseList(Author::class, $this->request, $this->databaseId); - $authorIds = $baselist->getInstanceIdsByBookIds($bookIds); - $authors = $baselist->getInstancesByIds($authorIds); - foreach ($bookIds as $bookId) { - $this->bookList[$bookId]->authors = []; - $authorIds[$bookId] ??= []; - foreach ($authorIds[$bookId] as $authorId) { - if (!array_key_exists($authorId, $authors)) { - throw new Exception('Unknown author ' . $authorId . ' in ' . var_export($authors, true)); - } - array_push($this->bookList[$bookId]->authors, $authors[$authorId]); - } - } - } - - /** - * Summary of setSerie - * @throws \Exception - * @return void - */ - public function setSerie() - { - $bookIds = array_keys($this->bookList); - $baselist = new BaseList(Serie::class, $this->request, $this->databaseId); - $seriesIds = $baselist->getInstanceIdsByBookIds($bookIds); - $series = $baselist->getInstancesByIds($seriesIds); - foreach ($bookIds as $bookId) { - $this->bookList[$bookId]->serie = false; - $seriesIds[$bookId] ??= []; - foreach ($seriesIds[$bookId] as $seriesId) { - if (!array_key_exists($seriesId, $series)) { - throw new Exception('Unknown series ' . $seriesId . ' in ' . var_export($series, true)); - } - $this->bookList[$bookId]->serie = $series[$seriesId]; - break; - } - } - } - - /** - * Summary of setPublisher - * @throws \Exception - * @return void - */ - public function setPublisher() - { - $bookIds = array_keys($this->bookList); - $baselist = new BaseList(Publisher::class, $this->request, $this->databaseId); - $publisherIds = $baselist->getInstanceIdsByBookIds($bookIds); - $publishers = $baselist->getInstancesByIds($publisherIds); - foreach ($bookIds as $bookId) { - $this->bookList[$bookId]->publisher = false; - $publisherIds[$bookId] ??= []; - foreach ($publisherIds[$bookId] as $publisherId) { - if (!array_key_exists($publisherId, $publishers)) { - throw new Exception('Unknown publisher ' . $publisherId . ' in ' . var_export($publishers, true)); - } - $this->bookList[$bookId]->publisher = $publishers[$publisherId]; - break; - } - } - } - - /** - * Summary of setTags - * @throws \Exception - * @return void - */ - public function setTags() - { - $bookIds = array_keys($this->bookList); - $baselist = new BaseList(Tag::class, $this->request, $this->databaseId); - $tagIds = $baselist->getInstanceIdsByBookIds($bookIds); - $tags = $baselist->getInstancesByIds($tagIds); - foreach ($bookIds as $bookId) { - $this->bookList[$bookId]->tags = []; - $tagIds[$bookId] ??= []; - foreach ($tagIds[$bookId] as $tagId) { - if (!array_key_exists($tagId, $tags)) { - throw new Exception('Unknown tag ' . $tagId . ' in ' . var_export($tags, true)); - } - array_push($this->bookList[$bookId]->tags, $tags[$tagId]); - } - } - } - - /** - * Summary of setLanguages - * @throws \Exception - * @return void - */ - public function setLanguages() - { - $bookIds = array_keys($this->bookList); - $baselist = new BaseList(Language::class, $this->request, $this->databaseId); - $languageIds = $baselist->getInstanceIdsByBookIds($bookIds); - $languages = $baselist->getInstancesByIds($languageIds); - foreach ($bookIds as $bookId) { - $langCodes = []; - $languageIds[$bookId] ??= []; - foreach ($languageIds[$bookId] as $languageId) { - if (!array_key_exists($languageId, $languages)) { - throw new Exception('Unknown language ' . $languageId . ' in ' . var_export($languages, true)); - } - array_push($langCodes, $languages[$languageId]->getTitle()); - } - $this->bookList[$bookId]->languages = implode(', ', $langCodes); - } - } - - /** - * Summary of setDatas - * @throws \Exception - * @return void - */ - public function setDatas() - { - $bookIds = array_keys($this->bookList); - $baselist = new BaseList(Data::class, $this->request, $this->databaseId); - $dataIds = $baselist->getInstanceIdsByBookIds($bookIds); - $datas = $baselist->getInstancesByIds($dataIds); - $ignored_formats = Config::get('ignored_formats'); - foreach ($bookIds as $bookId) { - $this->bookList[$bookId]->datas = []; - $dataIds[$bookId] ??= []; - foreach ($dataIds[$bookId] as $dataId) { - if (!array_key_exists($dataId, $datas)) { - throw new Exception('Unknown data ' . $dataId . ' in ' . var_export($datas, true)); - } - if (!empty($ignored_formats) && in_array($datas[$dataId]->format, $ignored_formats)) { - continue; - } - // we need to set the book here, since we didn't do it above - $datas[$dataId]->setBook($this->bookList[$bookId]); - array_push($this->bookList[$bookId]->datas, $datas[$dataId]); - } - } - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/Category.php b/COPS/cops-3.1.3/src/Calibre/Category.php deleted file mode 100644 index 49a81606..00000000 --- a/COPS/cops-3.1.3/src/Calibre/Category.php +++ /dev/null @@ -1,181 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Model\Entry; - -abstract class Category extends Base -{ - public const CATEGORY = "categories"; - /** @var ?int */ - public $count; - /** @var ?array */ - protected $children = null; - /** @var Category|false|null */ - protected $parent = null; - - /** - * Summary of hasChildCategories - * @return bool - */ - public function hasChildCategories() - { - if (empty(Config::get('calibre_categories_using_hierarchy')) || !in_array(static::CATEGORY, Config::get('calibre_categories_using_hierarchy'))) { - return false; - } - return true; - } - - /** - * Get child instances for hierarchical tags or custom columns - * @return array - */ - public function getChildCategories() - { - if (!is_null($this->children)) { - return $this->children; - } - // Fiction -> Fiction.% matching Fiction.Historical and Fiction.Romance - $find = $this->getTitle() . '.%'; - $this->children = $this->getRelatedCategories($find); - return $this->children; - } - - /** - * Get child entries for hierarchical tags or custom columns - * @param int|bool|null $expand include all child categories at all levels or only direct children - * @return array - */ - public function getChildEntries($expand = false) - { - $entryArray = []; - foreach ($this->getChildCategories() as $child) { - // check if this is an immediate child or not, like Fiction matches Fiction.Historical but not Fiction.Historical.Romance - if (empty($expand) && !preg_match('/^' . $this->getTitle() . '\.[^.]+$/', $child->getTitle())) { - continue; - } - array_push($entryArray, $child->getEntry($child->count)); - } - return $entryArray; - } - - /** - * Get sibling entries for hierarchical tags or custom columns - * @return array - */ - public function getSiblingEntries() - { - // Fiction.Historical -> Fiction.% matching Fiction.Historical and Fiction.Romance - $parentName = static::findParentName($this->getTitle()); - if (empty($parentName)) { - return []; - } - // pattern match here - $find = $parentName . '.%'; - $siblings = $this->getRelatedCategories($find); - $entryArray = []; - foreach ($siblings as $sibling) { - array_push($entryArray, $sibling->getEntry($sibling->count)); - } - return $entryArray; - } - - /** - * Find parent name of hierarchical name - * @param string $name - * @return string - */ - protected static function findParentName($name) - { - $parts = explode('.', $name); - $child = array_pop($parts); - if (empty($parts)) { - return ''; - } - $parent = implode('.', $parts); - return $parent; - } - - /** - * Get parent instance for hierarchical tags or custom columns - * @return Category|false - */ - public function getParentCategory() - { - if (!is_null($this->parent)) { - return $this->parent; - } - $this->parent = false; - // Fiction.Historical -> Fiction - $parentName = static::findParentName($this->getTitle()); - if (empty($parentName)) { - return $this->parent; - } - // exact match here - $find = $parentName; - $parents = $this->getRelatedCategories($find); - if (count($parents) == 1) { - $this->parent = $parents[0]; - } - return $this->parent; - } - - /** - * Get parent entry for hierarchical tags or custom columns - * @return ?Entry - */ - public function getParentEntry() - { - $parent = $this->getParentCategory(); - if (!empty($parent)) { - return $parent->getEntry($parent->count); - } - return null; - } - - /** - * Find related categories for hierarchical tags or series - @todo needs title_sort function in sqlite for series - * Format: tag_browser_tags(id,name,count,avg_rating,sort) - * @param string|array $find pattern match or exact match for name, or array of child ids - * @return array - */ - public function getRelatedCategories($find) - { - if (!$this->hasChildCategories()) { - return []; - } - $className = static::class; - $tableName = 'tag_browser_' . static::CATEGORY; - if (is_array($find)) { - $queryFormat = "SELECT id, name, count FROM {0} WHERE id IN (" . str_repeat("?,", count($find) - 1) . "?) ORDER BY sort"; - $params = $find; - } elseif (!str_contains($find, '%')) { - $queryFormat = "SELECT id, name, count FROM {0} WHERE name = ? ORDER BY sort"; - $params = [$find]; - } else { - $queryFormat = "SELECT id, name, count FROM {0} WHERE name LIKE ? ORDER BY sort"; - $params = [$find]; - } - $query = str_format($queryFormat, $tableName); - $result = Database::query($query, $params, $this->databaseId); - - $instances = []; - while ($post = $result->fetchObject()) { - /** @var Category $instance */ - $instance = new $className($post, $this->databaseId); - $instance->count = $post->count; - array_push($instances, $instance); - } - return $instances; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/Cover.php b/COPS/cops-3.1.3/src/Calibre/Cover.php deleted file mode 100644 index c438a055..00000000 --- a/COPS/cops-3.1.3/src/Calibre/Cover.php +++ /dev/null @@ -1,437 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Request; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Model\LinkEntry; -use SebLucas\Cops\Output\FileResponse; - -class Cover -{ - public static string $handler = "fetch"; - /** @var Book */ - public $book; - /** @var ?int */ - protected $databaseId; - /** @var ?string */ - public $coverFileName = null; - /** @var ?FileResponse */ - protected $response = null; - - /** - * Summary of __construct - * @param Book $book - * @param ?int $database - */ - public function __construct($book, $database = null) - { - $this->book = $book; - if ($book->hasCover) { - $this->coverFileName = $book->getCoverFileName(); - } - $this->databaseId = $database ?? $book->getDatabaseId(); - } - - /** - * Summary of checkDatabaseFieldCover - * @param string $fileName - * @return ?string - */ - public function checkDatabaseFieldCover($fileName) - { - $imgDirectory = Database::getImgDirectory($this->databaseId); - $this->coverFileName = $fileName; - if (!file_exists($this->coverFileName)) { - $this->coverFileName = null; - } - if (empty($this->coverFileName)) { - $this->coverFileName = sprintf('%s%s', $imgDirectory, $fileName); - if (!file_exists($this->coverFileName)) { - $this->coverFileName = null; - } - } - if (empty($this->coverFileName)) { - // Try with the epub file name - $data = $this->book->getDataFormat('EPUB'); - if ($data) { - // this won't work for Calibre directories due to missing (book->id) in path here - $this->coverFileName = sprintf('%s%s/%s', $imgDirectory, $data->name, $fileName); - if (!file_exists($this->coverFileName)) { - $this->coverFileName = null; - } - if (empty($this->coverFileName)) { - $this->coverFileName = sprintf('%s%s.jpg', $imgDirectory, $data->name); - if (!file_exists($this->coverFileName)) { - $this->coverFileName = null; - } - } - } - } - return $this->coverFileName; - } - - /** - * Summary of checkCoverFilePath - * @return ?string - */ - public function checkCoverFilePath() - { - $cover = $this->book->getCoverFilePath("jpg"); - if (!empty($cover) && !empty(Config::get('calibre_external_storage'))) { - $this->coverFileName = $cover; - return $this->coverFileName; - } - if ($cover === false || !file_exists($cover)) { - $cover = $this->book->getCoverFilePath("png"); - } - if ($cover === false || !file_exists($cover)) { - $this->coverFileName = null; - } else { - $this->coverFileName = $cover; - } - return $this->coverFileName; - } - - /** - * Summary of getThumbnailCachePath - * @param ?int $width - * @param ?int $height - * @param string $type - * @return ?string - */ - public function getThumbnailCachePath($width, $height, $type = 'jpg') - { - // moved some of the thumbnail cache from fetch.php to Cover - //by default, we don't cache - $cachePath = null; - if (empty(Config::get('thumbnail_cache_directory'))) { - return $cachePath; - } - - $uuid = $this->book->uuid; - $database = $this->databaseId; - - $cachePath = Config::get('thumbnail_cache_directory'); - //if multiple databases, add a subfolder with the database ID - $cachePath .= !is_null($database) ? 'db-' . $database . DIRECTORY_SEPARATOR : ''; - //when there are lots of thumbnails, it's better to save files in subfolders, so if the book's uuid is - //"01234567-89ab-cdef-0123-456789abcdef", we will save the thumbnail in .../0/12/34567-89ab-cdef-0123-456789abcdef-... - $cachePath .= substr($uuid, 0, 1) . DIRECTORY_SEPARATOR . substr($uuid, 1, 2) . DIRECTORY_SEPARATOR; - //check if cache folder exists or create it - if (file_exists($cachePath) || mkdir($cachePath, 0o700, true)) { - //we name the thumbnail from the book's uuid and it's dimensions (width and/or height) - $thumbnailCacheName = substr($uuid, 3) . '-' . strval($width) . 'x' . strval($height) . '.' . $type; - $cachePath = $cachePath . $thumbnailCacheName; - } else { - //error creating the folder, so we don't cache - $cachePath = null; - } - - return $cachePath; - } - - /** - * Summary of getThumbnail - * @param ?int $width - * @param ?int $height - * @param ?string $outputfile - * @param string $inType - * @return bool - */ - public function getThumbnail($width, $height, $outputfile = null, $inType = 'jpg') - { - if (is_null($width) && is_null($height)) { - return false; - } - if (empty($this->coverFileName) || !is_file($this->coverFileName) || !is_readable($this->coverFileName)) { - return false; - } - // @todo support creating (and caching) thumbnails for external cover images someday - - // -DC- Use cover file name - //$file = $this->getCoverFilePath('jpg'); - $file = $this->coverFileName; - // get image size - if ($size = GetImageSize($file)) { - $w = $size[0]; - $h = $size[1]; - //set new size - if (!is_null($width)) { - $nw = $width; - if ($nw >= $w) { - return false; - } - $nh = intval(($nw * $h) / $w); - } else { - $nh = $height; - if ($nh >= $h) { - return false; - } - $nw = intval(($nh * $w) / $h); - } - } else { - return false; - } - - // Draw the image - if ($inType == 'png') { - $src_img = imagecreatefrompng($file); - } else { - $src_img = imagecreatefromjpeg($file); - } - $dst_img = imagecreatetruecolor($nw, $nh); - if (!imagecopyresampled($dst_img, $src_img, 0, 0, 0, 0, $nw, $nh, $w, $h)) { - return false; - } - //if we don't cache the thumbnail, this already returns the image data - if (is_null($outputfile)) { - $mimetype = ($inType == 'png') ? 'image/png' : 'image/jpeg'; - // use cache control here - $this->response->setHeaders($mimetype, 0); - $this->response->sendHeaders(); - } - if ($inType == 'png') { - if (!imagepng($dst_img, $outputfile, 9)) { - return false; - } - } else { - if (!imagejpeg($dst_img, $outputfile, 80)) { - return false; - } - } - imagedestroy($src_img); - imagedestroy($dst_img); - - return true; - } - - /** - * Summary of sendThumbnail - * @param Request $request - * @param FileResponse $response - * @return FileResponse - */ - public function sendThumbnail($request, $response) - { - $type = $request->get('type', 'jpg'); - $width = $request->get('width'); - $height = $request->get('height'); - $thumb = $request->get('thumb'); - if (!empty($thumb) && empty($height)) { - $height = match ($thumb) { - "opds2" => intval(Config::get('opds_thumbnail_height')) * 2, - "opds" => intval(Config::get('opds_thumbnail_height')), - "html2" => intval(Config::get('html_thumbnail_height')) * 2, - "html" => intval(Config::get('html_thumbnail_height')), - default => intval($thumb), - }; - } - $mime = ($type == 'jpg') ? 'image/jpeg' : 'image/png'; - $file = $this->coverFileName; - - $cachePath = $this->getThumbnailCachePath($width, $height, $type); - - if ($cachePath !== null && file_exists($cachePath)) { - //return the already cached thumbnail - $response->setHeaders($mime, 0); - return $response->sendFile($cachePath, true); - } - - $this->response = $response; - if ($this->getThumbnail($width, $height, $cachePath, $type)) { - //if we don't cache the thumbnail, imagejpeg() in $cover->getThumbnail() already return the image data - if ($cachePath === null) { - // The cover had to be resized - return $this->response; - } - //return the just cached thumbnail - $response->setHeaders($mime, 0); - return $response->sendFile($cachePath, true); - } - - $response->setHeaders($mime, 0); - return $response->sendFile($file); - } - - /** - * Summary of getCoverUri - * @return ?string - */ - public function getCoverUri() - { - $link = $this->getCoverLink(); - if ($link) { - return $link->hrefXhtml(); - } - return null; - } - - /** - * Summary of getCoverLink - * @return ?LinkEntry - */ - public function getCoverLink() - { - if ($this->coverFileName) { - // -DC- Use cover file name - //array_push($linkArray, Data::getLink($this, 'jpg', 'image/jpeg', LinkEntry::OPDS_IMAGE_TYPE, 'cover.jpg', NULL)); - $ext = strtolower(pathinfo($this->coverFileName, PATHINFO_EXTENSION)); - $mime = ($ext == 'jpg') ? 'image/jpeg' : 'image/png'; - if (!empty(Config::get('calibre_external_storage')) && str_starts_with($this->coverFileName, (string) Config::get('calibre_external_storage'))) { - return new LinkEntry( - $this->coverFileName, - $mime, - LinkEntry::OPDS_IMAGE_TYPE - ); - } - $file = 'cover.' . $ext; - // moved image-specific code from Data to Cover - if (!Database::useAbsolutePath($this->databaseId)) { - return new LinkEntry( - Route::path(str_replace('%2F', '/', rawurlencode($this->book->path . "/" . $file))), - $mime, - LinkEntry::OPDS_IMAGE_TYPE - ); - } - $params = ['id' => $this->book->id, 'db' => $this->databaseId]; - if (Config::get('use_route_urls') && is_null($params['db'])) { - $params['db'] = 0; - } - if ($ext != 'jpg') { - $params['type'] = $ext; - } - return new LinkEntry( - Route::link(static::$handler, null, $params), - $mime, - LinkEntry::OPDS_IMAGE_TYPE - ); - } - - return null; - } - - /** - * Summary of getThumbnailUri - * @param string $thumb - * @param bool $useDefault - * @return ?string - */ - public function getThumbnailUri($thumb, $useDefault = true) - { - $link = $this->getThumbnailLink($thumb, $useDefault); - if ($link) { - return $link->hrefXhtml(); - } - return null; - } - - /** - * Summary of getThumbnailLink - * @param string $thumb - * @param bool $useDefault - * @return ?LinkEntry - */ - public function getThumbnailLink($thumb, $useDefault = true) - { - if (Config::get('thumbnail_handling') != "1" && - !empty(Config::get('thumbnail_handling'))) { - $fileName = Config::get('thumbnail_handling'); - $ext = strtolower(pathinfo((string) $fileName, PATHINFO_EXTENSION)); - $mime = ($ext == 'jpg') ? 'image/jpeg' : 'image/png'; - return new LinkEntry( - Route::path($fileName), - $mime, - LinkEntry::OPDS_THUMBNAIL_TYPE - ); - } - - if ($this->coverFileName) { - // -DC- Use cover file name - //array_push($linkArray, Data::getLink($this, 'jpg', 'image/jpeg', LinkEntry::OPDS_THUMBNAIL_TYPE, 'cover.jpg', NULL)); - $ext = strtolower(pathinfo($this->coverFileName, PATHINFO_EXTENSION)); - $mime = ($ext == 'jpg') ? 'image/jpeg' : 'image/png'; - // @todo support creating (and caching) thumbnails for external cover images someday - if (!empty(Config::get('calibre_external_storage')) && str_starts_with($this->coverFileName, (string) Config::get('calibre_external_storage'))) { - return new LinkEntry( - $this->coverFileName, - $mime, - LinkEntry::OPDS_THUMBNAIL_TYPE - ); - } - //$file = 'cover.' . $ext; - // moved image-specific code from Data to Cover - $params = ['id' => $this->book->id, 'db' => $this->databaseId]; - if (Config::get('use_route_urls') && is_null($params['db'])) { - $params['db'] = 0; - } - if ($ext != 'jpg') { - $params['type'] = $ext; - } - if (Config::get('thumbnail_handling') != "1") { - $params['thumb'] = $thumb; - } - return new LinkEntry( - Route::link(static::$handler, null, $params), - $mime, - LinkEntry::OPDS_THUMBNAIL_TYPE - ); - } - - if ($useDefault) { - return $this->getDefaultLink(); - } - return null; - } - - /** - * Summary of getDefaultLink - * @return ?LinkEntry - */ - public function getDefaultLink() - { - if (!empty(Config::get('thumbnail_default'))) { - $ext = strtolower(pathinfo((string) Config::get('thumbnail_default'), PATHINFO_EXTENSION)); - $mime = ($ext == 'jpg') ? 'image/jpeg' : 'image/png'; - return new LinkEntry( - Route::path(Config::get('thumbnail_default')), - $mime, - LinkEntry::OPDS_THUMBNAIL_TYPE - ); - } - return null; - } - - /** - * Summary of findCoverFileName - * @param Book $book - * @param object $line - * @return ?string - */ - public static function findCoverFileName($book, $line) - { - // -DC- Use cover file name - //if (!file_exists($this->getCoverFilePath('jpg'))) { - // // double check - // $this->hasCover = 0; - //} - $coverFileName = null; - $cover = new Cover($book); - if (!empty(Config::get('calibre_database_field_cover'))) { - $coverFileName = $cover->checkDatabaseFieldCover($line->cover); - } - // Else try with default cover file name - if (empty($coverFileName)) { - $coverFileName = $cover->checkCoverFilePath(); - } - return $coverFileName; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/CustomColumn.php b/COPS/cops-3.1.3/src/Calibre/CustomColumn.php deleted file mode 100644 index dc5945a8..00000000 --- a/COPS/cops-3.1.3/src/Calibre/CustomColumn.php +++ /dev/null @@ -1,216 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Model\Entry; -use SebLucas\Cops\Pages\PageId; - -/** - * A CustomColumn with an value - */ -class CustomColumn extends Category -{ - public const PAGE_ID = PageId::ALL_CUSTOMS_ID; - public const PAGE_ALL = PageId::ALL_CUSTOMS; - public const PAGE_DETAIL = PageId::CUSTOM_DETAIL; - public const URL_PARAM = "c"; - - /** @var string the (string) representation of the value */ - public $value; - /** @var CustomColumnType the custom column that contains the value */ - public $customColumnType; - /** @var string the value encoded for HTML displaying */ - public $htmlvalue; - - /** - * CustomColumn constructor. - * - * @param integer|string|null $id id of the chosen value - * @param string $value string representation of the value - * @param CustomColumnType $customColumnType the CustomColumn this value lives in - */ - public function __construct($id, $value, $customColumnType) - { - $this->id = $id; - $this->value = $value; - $this->customColumnType = $customColumnType; - $this->htmlvalue = $this->customColumnType->encodeHTMLValue($this->value ?? ''); - $this->databaseId = $this->customColumnType->getDatabaseId(); - $this->handler = $this->customColumnType->getHandler(); - } - - /** - * Summary of getCustomId - * @return int - */ - public function getCustomId() - { - return $this->customColumnType->customId; - } - - /** - * Get the URI to show all books with this value - * - * @param array $params - * @return string - */ - public function getUri($params = []) - { - $params['custom'] = $this->getCustomId(); - $params['id'] = $this->id; - // we need databaseId here because we use Route::link with $handler - $params['db'] = $this->getDatabaseId(); - return Route::link($this->handler, static::PAGE_DETAIL, $params); - } - - /** - * Summary of getParentUri - * @param array $params - * @return string - */ - public function getParentUri($params = []) - { - return $this->customColumnType->getUri($params); - } - - /** - * Get the EntryID to show all books with this value - * - * @return string - */ - public function getEntryId() - { - return static::PAGE_ID . ":" . strval($this->getCustomId()) . ":" . $this->id; - } - - /** - * Summary of getTitle - * @return string - */ - public function getTitle() - { - return strval($this->value); - } - - /** - * Summary of getParentTitle - * @return string - */ - public function getParentTitle() - { - return $this->customColumnType->getTitle(); - } - - /** - * Summary of getClassName - * @param ?string $className - * @return string - */ - public function getClassName($className = null) - { - return $this->customColumnType->getTitle(); - } - - /** - * Summary of getCustomCount - * @return Entry - */ - public function getCustomCount() - { - [$query, $params] = $this->getQuery(); - $columns = 'count(*)'; - $count = Database::countFilter($query, $columns, "", $params, $this->databaseId); - return $this->getEntry($count); - } - - /** - * Get the query to find all books with this value - * the returning array has two values: - * - first the query (string) - * - second an array of all PreparedStatement parameters - * - * @return array{0: string, 1: array} - */ - public function getQuery() - { - return $this->customColumnType->getQuery($this->id); - } - - /** - * Summary of getFilter - * @param ?string $parentTable - * @return array{0: string, 1: array} - */ - public function getFilter($parentTable = null) - { - return $this->customColumnType->getFilter($this->id, $parentTable); - } - - /** - * Return the value of this column as an HTML snippet - * - * @return string - */ - public function getHTMLEncodedValue() - { - return $this->htmlvalue; - } - - /** - * Summary of hasChildCategories - * @return bool - */ - public function hasChildCategories() - { - return $this->customColumnType->hasChildCategories(); - } - - /** - * Find related categories for hierarchical custom columns - * Format: tag_browser_custom_column_2(id,value,count,avg_rating,sort) - * @param string|array $find - * @return array - */ - public function getRelatedCategories($find) - { - return $this->customColumnType->getRelatedCategories($find); - } - - /** - * Create an CustomColumn by CustomColumnID and ValueID - * - * @param int $customId the id of the customColumn - * @param string|int $id the id of the chosen value - * @param ?int $database - * @return ?CustomColumn - */ - public static function createCustom($customId, $id, $database = null) - { - $columnType = CustomColumnType::createByCustomID($customId, $database); - - return $columnType->getCustom($id); - } - - /** - * Return this object as an array - * - * @return array - */ - public function toArray() - { - return [ - 'valueID' => $this->id, - 'value' => $this->value, - 'customColumnType' => $this->customColumnType->toArray(), - 'htmlvalue' => $this->htmlvalue, - ]; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/CustomColumnType.php b/COPS/cops-3.1.3/src/Calibre/CustomColumnType.php deleted file mode 100644 index ad132225..00000000 --- a/COPS/cops-3.1.3/src/Calibre/CustomColumnType.php +++ /dev/null @@ -1,572 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Model\Entry; -use SebLucas\Cops\Model\LinkNavigation; -use SebLucas\Cops\Pages\PageId; -use Exception; - -/** - * A single calibre custom column - */ -abstract class CustomColumnType -{ - public const PAGE_ID = PageId::ALL_CUSTOMS_ID; - public const PAGE_ALL = PageId::ALL_CUSTOMS; - public const PAGE_DETAIL = PageId::CUSTOM_DETAIL; - public const SQL_TABLE = "custom_columns"; - public const SQL_BOOKLIST_LINK = 'select {0} from {2}, books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where {2}.book = books.id and {2}.{3} = ? {1} order by books.sort'; - public const SQL_BOOKLIST_ID = 'select {0} from {2}, books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where {2}.book = books.id and {2}.id = ? {1} order by books.sort'; - public const SQL_BOOKLIST_VALUE = 'select {0} from {2}, books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where {2}.book = books.id and {2}.value = ? {1} order by books.sort'; - public const SQL_BOOKLIST_RANGE = 'select {0} from {2}, books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where {2}.book = books.id and {2}.value >= ? and {2}.value <= ? {1} order by {2}.value'; - public const SQL_BOOKLIST_NULL = 'select {0} from books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where books.id not in (select book from {2}) {1} order by books.sort'; - public const ALL_WILDCARD = ["*"]; - - public const TYPE_TEXT = "text"; // type 1 + 2 (calibre) - public const TYPE_CSV = "csv"; // type 2 (internal) - public const TYPE_COMMENT = "comments"; // type 3 - public const TYPE_SERIES = "series"; // type 4 - public const TYPE_ENUM = "enumeration"; // type 5 - public const TYPE_DATE = "datetime"; // type 6 - public const TYPE_FLOAT = "float"; // type 7 - public const TYPE_INT = "int"; // type 8 - public const TYPE_RATING = "rating"; // type 9 - public const TYPE_BOOL = "bool"; // type 10 - public const TYPE_COMPOSITE = "composite"; // type 11 + 12 - - /** @var array */ - protected static $customColumnCacheID = []; - - /** @var array */ - protected static $customColumnCacheLookup = []; - - /** @var integer the id of this column */ - public $customId; - /** @var string name/title of this column */ - public $columnTitle; - /** @var string the datatype of this column (one of the TYPE_* constant values) */ - public $datatype; - /** @var null|Entry[] */ - protected $customValues = null; - /** @var ?int */ - protected $databaseId = null; - /** @var ?int */ - protected $numberPerPage = -1; - /** @var array */ - protected $displaySettings = []; - protected string $handler = ''; - - /** - * Summary of __construct - * @param int $customId - * @param string $datatype - * @param ?int $database - * @param array $displaySettings - */ - protected function __construct($customId, $datatype, $database = null, $displaySettings = []) - { - $this->columnTitle = static::getTitleByCustomID($customId, $database); - $this->customId = $customId; - $this->datatype = $datatype; - $this->customValues = null; - $this->databaseId = $database; - $this->numberPerPage = Config::get('max_item_per_page'); - $this->displaySettings = $displaySettings; - } - - /** - * Summary of getDatabaseId - * @return mixed - */ - public function getDatabaseId() - { - return $this->databaseId; - } - - /** - * Get the name of the sqlite table for this column - * - * @return string - */ - protected function getTableName() - { - return "custom_column_{$this->customId}"; - } - - /** - * The URI to show all the values of this column - * - * @param array $params - * @return string - */ - public function getUri($params = []) - { - $params['custom'] = $this->customId; - // we need databaseId here because we use Route::link with $handler - $params['db'] = $this->getDatabaseId(); - return Route::link($this->handler, static::PAGE_ALL, $params); - } - - /** - * The EntryID to show all the values of this column - * - * @return string - */ - public function getEntryId() - { - return static::PAGE_ID . ":" . $this->customId; - } - - /** - * The title of this column - * - * @return string - */ - public function getTitle() - { - return $this->columnTitle; - } - - /** - * Summary of getContentType - * @return mixed|string - */ - public function getContentType() - { - // @checkme convert "csv" back to "text" here? - return $this->datatype; - } - - /** - * Summary of getLinkArray - * @param array $params - * @return array - */ - public function getLinkArray($params = []) - { - // issue #26 for koreader: section is not supported - return [ new LinkNavigation($this->getUri($params), "subsection") ]; - } - - /** - * Summary of setHandler - * @param string $handler - * @return void - */ - public function setHandler($handler) - { - $this->handler = $handler; - } - - /** - * Summary of getHandler - * @return string - */ - public function getHandler() - { - return $this->handler; - } - - /** - * The description used in the index page - * - * @param int $count - * @return string - */ - public function getContent($count = 0) - { - $desc = $this->getDatabaseDescription(); - if ($desc === null || empty($desc)) { - $desc = str_format(localize("customcolumn.description"), $this->getTitle()); - } - return $desc; - } - - /** - * The description of this column as it is definied in the database - * - * @return ?string - */ - public function getDatabaseDescription() - { - $query = 'SELECT display FROM custom_columns WHERE id = ?'; - $result = Database::query($query, [$this->customId], $this->databaseId); - if ($post = $result->fetchObject()) { - $json = json_decode($post->display); - return (isset($json->description) && !empty($json->description)) ? $json->description : null; - } - return null; - } - - /** - * Get the Entry for this column - * This is used in the initializeContent method to display e.g. the index page - * - * @param array $params - * @return Entry - */ - public function getCount($params = []) - { - // @todo do we want to filter by virtual library etc. here? - $pcount = $this->getDistinctValueCount(); - $ptitle = $this->getTitle(); - $pid = $this->getEntryId(); - $pcontent = $this->getContent($pcount); - // @checkme convert "csv" back to "text" here? - $pcontentType = $this->getContentType(); - $database = $this->getDatabaseId(); - $plinkArray = $this->getLinkArray($params); - $pclass = ""; - - return new Entry($ptitle, $pid, $pcontent, $pcontentType, $plinkArray, $database, $pclass, $pcount); - } - - /** - * Return an entry array for all possible (in the DB used) values of this column - * These are the values used in the PageAllCustoms() page - * - * @param int $n - * @param ?string $sort - * @return array - */ - public function getAllCustomValues($n = -1, $sort = null) - { - // lazy loading - if ($this->customValues == null) { - $this->customValues = $this->getAllCustomValuesFromDatabase($n, $sort); - } - - return $this->customValues; - } - - /** - * Summary of getPaginatedResult - * @param string $query - * @param array $params - * @param int $n - * @return \PDOStatement - */ - public function getPaginatedResult($query, $params = [], $n = 1) - { - if ($this->numberPerPage != -1 && $n != -1) { - $query .= " LIMIT ?, ?"; - array_push($params, ($n - 1) * $this->numberPerPage, $this->numberPerPage); - } - $result = Database::query($query, $params, $this->databaseId); - - return $result; - } - - /** - * Get the amount of distinct values for this column - * - * @return int - */ - public function getDistinctValueCount() - { - $queryFormat = "SELECT COUNT(DISTINCT value) AS count FROM {0}"; - $query = str_format($queryFormat, $this->getTableName()); - // @todo do we want to filter by virtual library etc. here? - return Database::querySingle($query, $this->databaseId); - } - - /** - * Use the Calibre tag browser view to retrieve all custom values with count - * Format: tag_browser_custom_column_2(id,value,count,avg_rating,sort) - * @param int $n - * @param ?string $sort - * @return array - */ - public function browseAllCustomValues($n = -1, $sort = null) - { - if (!$this->hasChildCategories()) { - return []; - } - $tableName = 'tag_browser_' . $this->getTableName(); - $queryFormat = "SELECT id, value, count FROM {0} ORDER BY {1}"; - if (!in_array($sort, ['id', 'value', 'count', 'sort'])) { - $sort = "sort"; - } - if ($sort == 'count') { - $sort .= ' desc, value'; - } - $query = str_format($queryFormat, $tableName, $sort); - - $result = $this->getPaginatedResult($query, [], $n); - $entryArray = []; - while ($post = $result->fetchObject()) { - $customcolumn = new CustomColumn($post->id, $post->value, $this); - array_push($entryArray, $customcolumn->getEntry($post->count)); - } - return $entryArray; - } - - /** - * Summary of hasChildCategories - * @return bool - */ - public function hasChildCategories() - { - // @todo this only works with column titles/names, not the lookup names used elsewhere - if (empty(Config::get('calibre_categories_using_hierarchy')) || !in_array($this->columnTitle, Config::get('calibre_categories_using_hierarchy'))) { - return false; - } - return true; - } - - /** - * Find related categories for hierarchical custom columns - * Format: tag_browser_custom_column_2(id,value,count,avg_rating,sort) - * @param string|array $find pattern match or exact match for name, or array of child ids - * @return array - */ - public function getRelatedCategories($find) - { - if (!$this->hasChildCategories()) { - return []; - } - $tableName = 'tag_browser_' . $this->getTableName(); - if (is_array($find)) { - $queryFormat = "SELECT id, value, count FROM {0} WHERE id IN (" . str_repeat("?,", count($find) - 1) . "?) ORDER BY sort"; - $params = $find; - } elseif (!str_contains($find, '%')) { - $queryFormat = "SELECT id, value, count FROM {0} WHERE value = ? ORDER BY sort"; - $params = [$find]; - } else { - $queryFormat = "SELECT id, value, count FROM {0} WHERE value LIKE ? ORDER BY sort"; - $params = [$find]; - } - $query = str_format($queryFormat, $tableName); - $result = Database::query($query, $params, $this->databaseId); - - $instances = []; - while ($post = $result->fetchObject()) { - $customcolumn = new CustomColumn($post->id, $post->value, $this); - $customcolumn->count = $post->count; - array_push($instances, $customcolumn); - } - return $instances; - } - - /** - * Encode a value of this column ready to be displayed in an HTML document - * - * @param integer|string $value - * @return string - */ - public function encodeHTMLValue($value) - { - return htmlspecialchars($value); - } - - /** - * Return this object as an array - * - * @return array - */ - public function toArray() - { - return [ - 'customId' => $this->customId, - 'columnTitle' => $this->columnTitle, - 'datatype' => $this->datatype, - 'displaySettings' => $this->displaySettings, - //'customValues' => $this->customValues, - ]; - } - - /** - * Get the datatype & display-settings of a CustomColumn by its customID - * - * @param int $customId - * @param ?int $database - * @return array - */ - protected static function getDatatypeAndDisplaySettingsByCustomID($customId, $database = null) - { - $query = 'SELECT datatype, is_multiple, display FROM custom_columns WHERE id = ?'; - $result = Database::query($query, [$customId], $database); - if ($post = $result->fetchObject()) { - - $settings = $post->display ? json_decode($post->display, true) : []; - - // handle case where we have several values, e.g. array of text for type 2 (csv) - if ($post->datatype === "text" && $post->is_multiple === 1) { - return ["csv", $settings]; - } - return [$post->datatype, $settings]; - } - return [null, []]; - } - - /** - * Create a CustomColumnType by CustomID - * - * @param int $customId the id of the custom column - * @param ?int $database - * @return ?CustomColumnType - * @throws Exception If the $customId is not found or the datatype is unknown - */ - public static function createByCustomID($customId, $database = null) - { - // Reuse already created CustomColumns for performance - if (array_key_exists($customId, static::$customColumnCacheID)) { - return static::$customColumnCacheID[$customId]; - } - - [$datatype, $displaySettings] = static::getDatatypeAndDisplaySettingsByCustomID($customId, $database); - - static::$customColumnCacheID[$customId] = match ($datatype) { - static::TYPE_TEXT => new CustomColumnTypeText($customId, static::TYPE_TEXT, $database, $displaySettings), - static::TYPE_CSV => new CustomColumnTypeText($customId, static::TYPE_CSV, $database, $displaySettings), - static::TYPE_SERIES => new CustomColumnTypeSeries($customId, $database, $displaySettings), - static::TYPE_ENUM => new CustomColumnTypeEnumeration($customId, $database, $displaySettings), - static::TYPE_COMMENT => new CustomColumnTypeComment($customId, $database, $displaySettings), - static::TYPE_DATE => new CustomColumnTypeDate($customId, $database, $displaySettings), - static::TYPE_FLOAT => new CustomColumnTypeFloat($customId, $database, $displaySettings), - static::TYPE_INT => new CustomColumnTypeInteger($customId, static::TYPE_INT, $database, $displaySettings), - static::TYPE_RATING => new CustomColumnTypeRating($customId, $database, $displaySettings), - static::TYPE_BOOL => new CustomColumnTypeBool($customId, $database, $displaySettings), - static::TYPE_COMPOSITE => null, - default => throw new Exception("Unkown column type: " . $datatype), - }; - return static::$customColumnCacheID[$customId]; - } - - /** - * Create a CustomColumnType by its lookup name - * - * @param string $lookup the lookup-name of the custom column - * @param ?int $database - * @return ?CustomColumnType - */ - public static function createByLookup($lookup, $database = null) - { - // Reuse already created CustomColumns for performance - if (array_key_exists($lookup, static::$customColumnCacheLookup)) { - return static::$customColumnCacheLookup[$lookup]; - } - - $query = 'SELECT id FROM custom_columns WHERE label = ?'; - $result = Database::query($query, [$lookup], $database); - if ($post = $result->fetchObject()) { - return static::$customColumnCacheLookup[$lookup] = static::createByCustomID($post->id, $database); - } - return static::$customColumnCacheLookup[$lookup] = null; - } - - /** - * Get the title of a CustomColumn by its customID - * - * @param int $customId - * @param ?int $database - * @return string - */ - protected static function getTitleByCustomID($customId, $database = null) - { - $query = 'SELECT name FROM custom_columns WHERE id = ?'; - $result = Database::query($query, [$customId], $database); - if ($post = $result->fetchObject()) { - return $post->name; - } - return ""; - } - - /** - * Check the list of custom columns requested (and expand the wildcard if needed) - * - * @param array $columnList - * @param ?int $database - * @return array - */ - public static function checkCustomColumnList($columnList, $database = null) - { - if ($columnList === static::ALL_WILDCARD) { - $columnList = array_keys(static::getAllCustomColumns($database)); - } - return $columnList; - } - - /** - * Get all defined custom columns from the database - * - * @param ?int $database - * @return array> - */ - public static function getAllCustomColumns($database = null) - { - $query = 'SELECT id, label, name, datatype, display, is_multiple, normalized FROM custom_columns'; - $result = Database::query($query, [], $database); - $columns = []; - while ($post = $result->fetchObject()) { - $columns[$post->label] = (array) $post; - } - return $columns; - } - - /** - * Get the query to find all books with a specific value of this column - * the returning array has two values: - * - first the query (string) - * - second an array of all PreparedStatement parameters - * - * @param string|integer|null $id the id of the searched value - * @return ?array{0: string, 1: array} - */ - abstract public function getQuery($id); - - /** - * Summary of getFilter - * @param string|int|null $id - * @param ?string $parentTable - * @return ?array{0: string, 1: array} - */ - abstract public function getFilter($id, $parentTable = null); - - /** - * Get a CustomColumn for a specified (by ID) value - * - * @param string|int|null $id the id of the searched value - * @return ?CustomColumn - */ - abstract public function getCustom($id); - - /** - * Return an entry array for all possible (in the DB used) values of this column by querying the database - * - * @param int $n - * @param ?string $sort - * @return ?array - */ - abstract protected function getAllCustomValuesFromDatabase($n = -1, $sort = null); - - /** - * Find the value of this column for a specific book - * - * @param Book $book - * @return CustomColumn - */ - abstract public function getCustomByBook($book); - - /** - * Is this column searchable by value - * only searchable columns can be displayed on the index page - * - * @return bool - */ - abstract public function isSearchable(); -} diff --git a/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeBool.php b/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeBool.php deleted file mode 100644 index aea2d3ae..00000000 --- a/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeBool.php +++ /dev/null @@ -1,162 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Model\Entry; - -class CustomColumnTypeBool extends CustomColumnType -{ - public const SQL_BOOKLIST_TRUE = 'select {0} from {2}, books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where {2}.book = books.id and {2}.value = 1 {1} order by books.sort'; - public const SQL_BOOKLIST_FALSE = 'select {0} from {2}, books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where {2}.book = books.id and {2}.value = 0 {1} order by books.sort'; - - // PHP pre 5.6 does not support const arrays - /** @var array */ - protected $BOOLEAN_NAMES = [ - -1 => "customcolumn.boolean.unknown", // localize("customcolumn.boolean.unknown") - 0 => "customcolumn.boolean.no", // localize("customcolumn.boolean.no") - +1 => "customcolumn.boolean.yes", // localize("customcolumn.boolean.yes") - ]; - - /** - * Summary of __construct - * @param int $customId - * @param ?int $database - * @param array $displaySettings - */ - protected function __construct($customId, $database = null, $displaySettings = []) - { - parent::__construct($customId, static::TYPE_BOOL, $database, $displaySettings); - } - - /** - * Summary of getQuery - * @param string|int|null $id - * @return ?array{0: string, 1: array} - */ - public function getQuery($id) - { - if ($id == -1 || $id === '') { - $query = str_format(static::SQL_BOOKLIST_NULL, "{0}", "{1}", $this->getTableName()); - return [$query, []]; - } elseif ($id == 0) { - $query = str_format(static::SQL_BOOKLIST_FALSE, "{0}", "{1}", $this->getTableName()); - return [$query, []]; - } elseif ($id == 1) { - $query = str_format(static::SQL_BOOKLIST_TRUE, "{0}", "{1}", $this->getTableName()); - return [$query, []]; - } else { - return null; - } - } - - /** - * Summary of getFilter - * @param string|int|null $id - * @param ?string $parentTable - * @return ?array{0: string, 1: array} - */ - public function getFilter($id, $parentTable = null) - { - $linkTable = $this->getTableName(); - $linkColumn = "value"; - // @todo support $parentTable if relevant - if ($id == -1 || $id === '') { - // @todo is this the right way when filtering? - $filter = "not exists (select null from {$linkTable} where {$linkTable}.book = books.id)"; - return [$filter, []]; - } elseif ($id == 0) { - $filter = "exists (select null from {$linkTable} where {$linkTable}.book = books.id and {$linkTable}.{$linkColumn} = 0)"; - return [$filter, []]; - } elseif ($id == 1) { - $filter = "exists (select null from {$linkTable} where {$linkTable}.book = books.id and {$linkTable}.{$linkColumn} = 1)"; - return [$filter, []]; - } else { - return ["", []]; - } - } - - /** - * Summary of getCustom - * @param string|int|null $id - * @return CustomColumn - */ - public function getCustom($id) - { - return new CustomColumn($id, localize($this->BOOLEAN_NAMES[$id]), $this); - } - - /** - * Summary of getAllCustomValuesFromDatabase - * @param int $n - * @param ?string $sort - * @return array - */ - protected function getAllCustomValuesFromDatabase($n = -1, $sort = null) - { - $queryFormat = "SELECT coalesce({0}.value, -1) AS id, count(*) AS count FROM books LEFT JOIN {0} ON books.id = {0}.book GROUP BY {0}.value ORDER BY {0}.value"; - $query = str_format($queryFormat, $this->getTableName()); - $result = Database::query($query, [], $this->databaseId); - - $entryArray = []; - while ($post = $result->fetchObject()) { - $name = localize($this->BOOLEAN_NAMES[$post->id]); - $customcolumn = new CustomColumn($post->id, $name, $this); - array_push($entryArray, $customcolumn->getEntry($post->count)); - } - return $entryArray; - } - - /** - * Summary of getDistinctValueCount - * @return int - */ - public function getDistinctValueCount() - { - return count($this->BOOLEAN_NAMES); - } - - /** - * Summary of getContent - * @param int $count - * @return string - */ - public function getContent($count = 0) - { - return localize("customcolumn.description.bool"); - } - - /** - * Summary of getCustomByBook - * @param Book $book - * @return CustomColumn - */ - public function getCustomByBook($book) - { - $queryFormat = "SELECT {0}.value AS boolvalue FROM {0} WHERE {0}.book = ?"; - $query = str_format($queryFormat, $this->getTableName()); - - $result = Database::query($query, [$book->id], $this->databaseId); - if ($post = $result->fetchObject()) { - return new CustomColumn($post->boolvalue, localize($this->BOOLEAN_NAMES[$post->boolvalue]), $this); - } else { - return new CustomColumn(-1, localize($this->BOOLEAN_NAMES[-1]), $this); - } - } - - /** - * Summary of isSearchable - * @return bool - */ - public function isSearchable() - { - return true; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeComment.php b/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeComment.php deleted file mode 100644 index 69229d40..00000000 --- a/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeComment.php +++ /dev/null @@ -1,125 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Model\Entry; - -class CustomColumnTypeComment extends CustomColumnType -{ - /** - * Summary of __construct - * @param int $customId - * @param ?int $database - * @param array $displaySettings - */ - protected function __construct($customId, $database = null, $displaySettings = []) - { - parent::__construct($customId, static::TYPE_COMMENT, $database, $displaySettings); - } - - /** - * Summary of getQuery - * @param string|int|null $id - * @return ?array{0: string, 1: array} - */ - public function getQuery($id) - { - if (empty($id) && in_array("custom", Config::get('show_not_set_filter'))) { - $query = str_format(static::SQL_BOOKLIST_NULL, "{0}", "{1}", $this->getTableName()); - return [$query, []]; - } - $query = str_format(static::SQL_BOOKLIST_ID, "{0}", "{1}", $this->getTableName()); - return [$query, [$id]]; - } - - /** - * Summary of getFilter - * @param string|int|null $id - * @param ?string $parentTable - * @return ?array{0: string, 1: array} - */ - public function getFilter($id, $parentTable = null) - { - $linkTable = $this->getTableName(); - $linkColumn = "id"; - if (!empty($parentTable) && $parentTable != "books") { - $filter = "exists (select null from {$linkTable}, books where {$parentTable}.book = books.id and {$linkTable}.book = books.id and {$linkTable}.{$linkColumn} = ?)"; - } else { - $filter = "exists (select null from {$linkTable} where {$linkTable}.book = books.id and {$linkTable}.{$linkColumn} = ?)"; - } - return [$filter, [$id]]; - } - - /** - * Summary of getCustom - * @param string|int|null $id - * @return CustomColumn - */ - public function getCustom($id) - { - return new CustomColumn($id, $id, $this); - } - - /** - * Summary of encodeHTMLValue - * @param string $value - * @return string - */ - public function encodeHTMLValue($value) - { - return "
    " . $value . "
    "; // no htmlspecialchars, this is already HTML - } - - /** - * Summary of getAllCustomValuesFromDatabase - * @param int $n - * @param ?string $sort - * @return null - */ - protected function getAllCustomValuesFromDatabase($n = -1, $sort = null) - { - return null; - } - - /** - * Summary of getDistinctValueCount - * @return int - */ - public function getDistinctValueCount() - { - return 0; - } - - /** - * Summary of getCustomByBook - * @param Book $book - * @return CustomColumn - */ - public function getCustomByBook($book) - { - $queryFormat = "SELECT {0}.id AS id, {0}.value AS value FROM {0} WHERE {0}.book = ?"; - $query = str_format($queryFormat, $this->getTableName()); - - $result = Database::query($query, [$book->id], $this->databaseId); - if ($post = $result->fetchObject()) { - return new CustomColumn($post->id, $post->value, $this); - } - return new CustomColumn(null, localize("customcolumn.float.unknown"), $this); - } - - /** - * Summary of isSearchable - * @return bool - */ - public function isSearchable() - { - return false; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeDate.php b/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeDate.php deleted file mode 100644 index 8b304c50..00000000 --- a/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeDate.php +++ /dev/null @@ -1,241 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Model\Entry; -use SebLucas\Cops\Model\LinkNavigation; -use DateTime; -use UnexpectedValueException; - -class CustomColumnTypeDate extends CustomColumnType -{ - public const SQL_BOOKLIST = 'select {0} from {2}, books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where {2}.book = books.id and date({2}.value) = ? {1} order by books.sort'; - public const SQL_BOOKLIST_YEAR = 'select {0} from {2}, books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where {2}.book = books.id and substr(date({2}.value), 1, 4) = ? {1} order by {2}.value'; - public const GET_PATTERN = '/^(\d+)$/'; - - /** - * Summary of __construct - * @param int $customId - * @param ?int $database - * @param array $displaySettings - */ - protected function __construct($customId, $database = null, $displaySettings = []) - { - parent::__construct($customId, static::TYPE_DATE, $database, $displaySettings); - } - - /** - * Summary of getQuery - * @param string|int|null $id - * @return ?array{0: string, 1: array} - */ - public function getQuery($id) - { - if (empty($id) && in_array("custom", Config::get('show_not_set_filter'))) { - $query = str_format(static::SQL_BOOKLIST_NULL, "{0}", "{1}", $this->getTableName()); - return [$query, []]; - } - $date = new DateTime($id); - $query = str_format(static::SQL_BOOKLIST, "{0}", "{1}", $this->getTableName()); - return [$query, [$date->format("Y-m-d")]]; - } - - /** - * Summary of getQueryByYear - * @param mixed $year - * @throws \UnexpectedValueException - * @return ?array{0: string, 1: array} - */ - public function getQueryByYear($year) - { - if (!preg_match(static::GET_PATTERN, (string) $year)) { - throw new UnexpectedValueException(); - } - $query = str_format(static::SQL_BOOKLIST_YEAR, "{0}", "{1}", $this->getTableName()); - return [$query, [$year]]; - } - - /** - * Summary of getFilter - * @param string|int|null $id - * @param ?string $parentTable - * @return ?array{0: string, 1: array} - */ - public function getFilter($id, $parentTable = null) - { - $date = new DateTime($id); - $linkTable = $this->getTableName(); - $linkColumn = "value"; - if (!empty($parentTable) && $parentTable != "books") { - $filter = "exists (select null from {$linkTable}, books where {$parentTable}.book = books.id and {$linkTable}.book = books.id and {$linkTable}.{$linkColumn} = ?)"; - } else { - $filter = "exists (select null from {$linkTable} where {$linkTable}.book = books.id and date({$linkTable}.{$linkColumn}) = ?)"; - } - return [$filter, [$date->format("Y-m-d")]]; - } - - /** - * Summary of getCustom - * @param string|int|null $id - * @return CustomColumn - */ - public function getCustom($id) - { - if (empty($id)) { - return new CustomColumn(null, localize("customcolumn.date.unknown"), $this); - } - $date = new DateTime($id); - - return new CustomColumn($id, $date->format(localize("customcolumn.date.format")), $this); - } - - /** - * Summary of getAllCustomValuesFromDatabase - * @param int $n - * @param ?string $sort - * @return array - */ - protected function getAllCustomValuesFromDatabase($n = -1, $sort = null) - { - $queryFormat = "SELECT date(value) AS datevalue, count(*) AS count FROM {0} GROUP BY datevalue"; - if (!empty($sort) && $sort == 'count') { - $queryFormat .= ' ORDER BY count desc, datevalue'; - } else { - $queryFormat .= ' ORDER BY datevalue'; - } - $query = str_format($queryFormat, $this->getTableName()); - - $result = $this->getPaginatedResult($query, [], $n); - $entryArray = []; - while ($post = $result->fetchObject()) { - $date = new DateTime($post->datevalue); - $id = $date->format("Y-m-d"); - $name = $date->format(localize("customcolumn.date.format")); - - $customcolumn = new CustomColumn($id, $name, $this); - array_push($entryArray, $customcolumn->getEntry($post->count)); - } - - return $entryArray; - } - - /** - * Summary of getDistinctValueCount - * @return mixed - */ - public function getDistinctValueCount() - { - $queryFormat = "SELECT COUNT(DISTINCT date(value)) AS count FROM {0}"; - $query = str_format($queryFormat, $this->getTableName()); - return Database::querySingle($query, $this->databaseId); - } - - /** - * Summary of getCountByYear - * @param mixed $page can be $columnType::PAGE_ALL or $columnType::PAGE_DETAIL - * @param ?string $sort - * @return array - */ - public function getCountByYear($page, $sort = null) - { - $queryFormat = "SELECT substr(date(value), 1, 4) AS groupid, count(*) AS count FROM {0} GROUP BY groupid"; - if (!empty($sort) && $sort == 'count') { - $queryFormat .= ' ORDER BY count desc, groupid'; - } else { - $queryFormat .= ' ORDER BY groupid'; - } - $query = str_format($queryFormat, $this->getTableName()); - $result = Database::query($query, [], $this->databaseId); - - $entryArray = []; - $label = 'year'; - while ($post = $result->fetchObject()) { - $params = ['custom' => $this->customId, 'year' => $post->groupid, 'db' => $this->databaseId]; - $href = Route::link($this->handler, $page, $params); - array_push($entryArray, new Entry( - $post->groupid, - $this->getEntryId() . ':' . $label . ':' . $post->groupid, - str_format(localize('bookword', $post->count), $post->count), - 'text', - [ new LinkNavigation($href, null, null) ], - $this->databaseId, - ucfirst($label), - $post->count - )); - } - - return $entryArray; - } - - /** - * Summary of getCustomValuesByYear - * @param mixed $year - * @param ?string $sort - * @return array - */ - public function getCustomValuesByYear($year, $sort = null) - { - if (!preg_match(static::GET_PATTERN, (string) $year)) { - throw new UnexpectedValueException(); - } - $queryFormat = "SELECT date(value) AS datevalue, count(*) AS count FROM {0} WHERE substr(date(value), 1, 4) = ? GROUP BY datevalue"; - if (!empty($sort) && $sort == 'count') { - $queryFormat .= ' ORDER BY count desc, datevalue'; - } else { - $queryFormat .= ' ORDER BY datevalue'; - } - $query = str_format($queryFormat, $this->getTableName()); - $params = [ $year ]; - $result = Database::query($query, $params, $this->databaseId); - - $entryArray = []; - while ($post = $result->fetchObject()) { - $date = new DateTime($post->datevalue); - $id = $date->format("Y-m-d"); - $name = $date->format(localize("customcolumn.date.format")); - - $customcolumn = new CustomColumn($id, $name, $this); - array_push($entryArray, $customcolumn->getEntry($post->count)); - } - - return $entryArray; - } - - /** - * Summary of getCustomByBook - * @param Book $book - * @return CustomColumn - */ - public function getCustomByBook($book) - { - $queryFormat = "SELECT date({0}.value) AS datevalue FROM {0} WHERE {0}.book = ?"; - $query = str_format($queryFormat, $this->getTableName()); - - $result = Database::query($query, [$book->id], $this->databaseId); - if ($post = $result->fetchObject()) { - $date = new DateTime($post->datevalue); - - return new CustomColumn($date->format("Y-m-d"), $date->format(localize("customcolumn.date.format")), $this); - } - return new CustomColumn(null, localize("customcolumn.date.unknown"), $this); - } - - /** - * Summary of isSearchable - * @return bool - */ - public function isSearchable() - { - return true; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeEnumeration.php b/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeEnumeration.php deleted file mode 100644 index 09d3e2c4..00000000 --- a/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeEnumeration.php +++ /dev/null @@ -1,151 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Model\Entry; - -class CustomColumnTypeEnumeration extends CustomColumnType -{ - /** - * Summary of __construct - * @param int $customId - * @param ?int $database - * @param array $displaySettings - */ - protected function __construct($customId, $database = null, $displaySettings = []) - { - parent::__construct($customId, static::TYPE_ENUM, $database, $displaySettings); - } - - /** - * Get the name of the linking sqlite table for this column - * (or NULL if there is no linktable) - * - * @return string - */ - protected function getTableLinkName() - { - return "books_custom_column_{$this->customId}_link"; - } - - /** - * Get the name of the linking column in the linktable - * - * @return string - */ - protected function getTableLinkColumn() - { - return "value"; - } - - /** - * Summary of getQuery - * @param string|int|null $id - * @return ?array{0: string, 1: array} - */ - public function getQuery($id) - { - if (empty($id) && in_array("custom", Config::get('show_not_set_filter'))) { - $query = str_format(static::SQL_BOOKLIST_NULL, "{0}", "{1}", $this->getTableLinkName()); - return [$query, []]; - } - $query = str_format(static::SQL_BOOKLIST_LINK, "{0}", "{1}", $this->getTableLinkName(), $this->getTableLinkColumn()); - return [$query, [$id]]; - } - - /** - * Summary of getFilter - * @param string|int|null $id - * @param ?string $parentTable - * @return ?array{0: string, 1: array} - */ - public function getFilter($id, $parentTable = null) - { - $linkTable = $this->getTableLinkName(); - $linkColumn = $this->getTableLinkColumn(); - if (!empty($parentTable) && $parentTable != "books") { - $filter = "exists (select null from {$linkTable}, books where {$parentTable}.book = books.id and {$linkTable}.book = books.id and {$linkTable}.{$linkColumn} = ?)"; - } else { - $filter = "exists (select null from {$linkTable} where {$linkTable}.book = books.id and {$linkTable}.{$linkColumn} = ?)"; - } - return [$filter, [$id]]; - } - - /** - * Summary of getCustom - * @param string|int|null $id - * @return CustomColumn - */ - public function getCustom($id) - { - $query = str_format("SELECT id, value AS name FROM {0} WHERE id = ?", $this->getTableName()); - $result = Database::query($query, [$id], $this->databaseId); - if ($post = $result->fetchObject()) { - return new CustomColumn($id, $post->name, $this); - } - return new CustomColumn(null, localize("customcolumn.enum.unknown"), $this); - } - - /** - * Summary of getAllCustomValuesFromDatabase - * @param int $n - * @param ?string $sort - * @return array - */ - protected function getAllCustomValuesFromDatabase($n = -1, $sort = null) - { - $queryFormat = "SELECT {0}.id AS id, {0}.value AS name, count(*) AS count FROM {0}, {1} WHERE {0}.id = {1}.{2} GROUP BY {0}.id, {0}.value ORDER BY {0}.value"; - $query = str_format($queryFormat, $this->getTableName(), $this->getTableLinkName(), $this->getTableLinkColumn()); - - $result = $this->getPaginatedResult($query, [], $n); - $entryArray = []; - while ($post = $result->fetchObject()) { - $customcolumn = new CustomColumn($post->id, $post->name, $this); - array_push($entryArray, $customcolumn->getEntry($post->count)); - } - return $entryArray; - } - - /** - * Summary of getContent - * @param int $count - * @return string - */ - public function getContent($count = 0) - { - return str_format(localize("customcolumn.description.enum", $count), $count); - } - - /** - * Summary of getCustomByBook - * @param Book $book - * @return CustomColumn - */ - public function getCustomByBook($book) - { - $queryFormat = "SELECT {0}.id AS id, {0}.{2} AS name FROM {0}, {1} WHERE {0}.id = {1}.{2} AND {1}.book = ?"; - $query = str_format($queryFormat, $this->getTableName(), $this->getTableLinkName(), $this->getTableLinkColumn()); - - $result = Database::query($query, [$book->id], $this->databaseId); - if ($post = $result->fetchObject()) { - return new CustomColumn($post->id, $post->name, $this); - } - return new CustomColumn(null, localize("customcolumn.enum.unknown"), $this); - } - - /** - * Summary of isSearchable - * @return bool - */ - public function isSearchable() - { - return true; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeFloat.php b/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeFloat.php deleted file mode 100644 index a2ab69e3..00000000 --- a/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeFloat.php +++ /dev/null @@ -1,137 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Model\Entry; -use UnexpectedValueException; - -class CustomColumnTypeFloat extends CustomColumnType -{ - public const GET_PATTERN = '/^(-?[0-9.]+)-(-?[0-9.]+)$/'; - - /** - * Summary of __construct - * @param int $customId - * @param ?int $database - * @param array $displaySettings - */ - protected function __construct($customId, $database = null, $displaySettings = []) - { - parent::__construct($customId, static::TYPE_FLOAT, $database, $displaySettings); - } - - /** - * Summary of getQuery - * @param string|int|null $id - * @return ?array{0: string, 1: array} - */ - public function getQuery($id) - { - if (empty($id) && strval($id) !== '0.0' && in_array("custom", Config::get('show_not_set_filter'))) { - $query = str_format(static::SQL_BOOKLIST_NULL, "{0}", "{1}", $this->getTableName()); - return [$query, []]; - } - $query = str_format(static::SQL_BOOKLIST_VALUE, "{0}", "{1}", $this->getTableName()); - return [$query, [$id]]; - } - - /** - * Summary of getQueryByRange - * @param string $range - * @throws \UnexpectedValueException - * @return ?array{0: string, 1: array} - */ - public function getQueryByRange($range) - { - $matches = []; - if (!preg_match(static::GET_PATTERN, $range, $matches)) { - throw new UnexpectedValueException(); - } - $lower = $matches[1]; - $upper = $matches[2]; - $query = str_format(static::SQL_BOOKLIST_RANGE, "{0}", "{1}", $this->getTableName()); - return [$query, [$lower, $upper]]; - } - - /** - * Summary of getFilter - * @param string|int|null $id - * @param ?string $parentTable - * @return ?array{0: string, 1: array} - */ - public function getFilter($id, $parentTable = null) - { - $linkTable = $this->getTableName(); - $linkColumn = "value"; - if (!empty($parentTable) && $parentTable != "books") { - $filter = "exists (select null from {$linkTable}, books where {$parentTable}.book = books.id and {$linkTable}.book = books.id and {$linkTable}.{$linkColumn} = ?)"; - } else { - $filter = "exists (select null from {$linkTable} where {$linkTable}.book = books.id and {$linkTable}.{$linkColumn} = ?)"; - } - return [$filter, [$id]]; - } - - /** - * Summary of getCustom - * @param string|int|null $id - * @return CustomColumn - */ - public function getCustom($id) - { - return new CustomColumn($id, $id, $this); - } - - /** - * Summary of getAllCustomValuesFromDatabase - * @param int $n - * @param ?string $sort - * @return array - */ - protected function getAllCustomValuesFromDatabase($n = -1, $sort = null) - { - $queryFormat = "SELECT value AS id, count(*) AS count FROM {0} GROUP BY value"; - $query = str_format($queryFormat, $this->getTableName()); - - $result = $this->getPaginatedResult($query, [], $n); - $entryArray = []; - while ($post = $result->fetchObject()) { - $name = $post->id; - $customcolumn = new CustomColumn($post->id, $name, $this); - array_push($entryArray, $customcolumn->getEntry($post->count)); - } - return $entryArray; - } - - /** - * Summary of getCustomByBook - * @param Book $book - * @return CustomColumn - */ - public function getCustomByBook($book) - { - $queryFormat = "SELECT {0}.value AS value FROM {0} WHERE {0}.book = ?"; - $query = str_format($queryFormat, $this->getTableName()); - - $result = Database::query($query, [$book->id], $this->databaseId); - if ($post = $result->fetchObject()) { - return new CustomColumn($post->value, $post->value, $this); - } - return new CustomColumn(null, localize("customcolumn.float.unknown"), $this); - } - - /** - * Summary of isSearchable - * @return bool - */ - public function isSearchable() - { - return true; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeInteger.php b/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeInteger.php deleted file mode 100644 index 7e0ae8f2..00000000 --- a/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeInteger.php +++ /dev/null @@ -1,231 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Model\Entry; -use SebLucas\Cops\Model\LinkNavigation; -use UnexpectedValueException; - -class CustomColumnTypeInteger extends CustomColumnType -{ - public const GET_PATTERN = '/^(-?[0-9]+)-(-?[0-9]+)$/'; - - /** - * Summary of __construct - * @param int $customId - * @param string $datatype - * @param ?int $database - * @param array $displaySettings - * @throws \UnexpectedValueException - */ - protected function __construct($customId, $datatype = self::TYPE_INT, $database = null, $displaySettings = []) - { - match ($datatype) { - static::TYPE_INT => parent::__construct($customId, static::TYPE_INT, $database, $displaySettings), - static::TYPE_FLOAT => parent::__construct($customId, static::TYPE_FLOAT, $database, $displaySettings), - default => throw new UnexpectedValueException(), - }; - } - - /** - * Summary of getQuery - * @param string|int|null $id - * @return ?array{0: string, 1: array} - */ - public function getQuery($id) - { - if (empty($id) && strval($id) !== '0' && in_array("custom", Config::get('show_not_set_filter'))) { - $query = str_format(static::SQL_BOOKLIST_NULL, "{0}", "{1}", $this->getTableName()); - return [$query, []]; - } - $query = str_format(static::SQL_BOOKLIST_VALUE, "{0}", "{1}", $this->getTableName()); - return [$query, [$id]]; - } - - /** - * Summary of getQueryByRange - * @param string $range - * @throws \UnexpectedValueException - * @return ?array{0: string, 1: array} - */ - public function getQueryByRange($range) - { - $matches = []; - if (!preg_match(static::GET_PATTERN, $range, $matches)) { - throw new UnexpectedValueException(); - } - $lower = $matches[1]; - $upper = $matches[2]; - $query = str_format(static::SQL_BOOKLIST_RANGE, "{0}", "{1}", $this->getTableName()); - return [$query, [$lower, $upper]]; - } - - /** - * Summary of getFilter - * @param string|int|null $id - * @param ?string $parentTable - * @return ?array{0: string, 1: array} - */ - public function getFilter($id, $parentTable = null) - { - $linkTable = $this->getTableName(); - $linkColumn = "value"; - if (!empty($parentTable) && $parentTable != "books") { - $filter = "exists (select null from {$linkTable}, books where {$parentTable}.book = books.id and {$linkTable}.book = books.id and {$linkTable}.{$linkColumn} = ?)"; - } else { - $filter = "exists (select null from {$linkTable} where {$linkTable}.book = books.id and {$linkTable}.{$linkColumn} = ?)"; - } - return [$filter, [$id]]; - } - - /** - * Summary of getCustom - * @param string|int|null $id - * @return CustomColumn - */ - public function getCustom($id) - { - return new CustomColumn($id, $id, $this); - } - - /** - * Summary of getAllCustomValuesFromDatabase - * @param int $n - * @param ?string $sort - * @return array - */ - protected function getAllCustomValuesFromDatabase($n = -1, $sort = null) - { - $queryFormat = "SELECT value AS id, count(*) AS count FROM {0} GROUP BY value"; - if (!empty($sort) && $sort == 'count') { - $queryFormat .= ' ORDER BY count desc, value'; - } else { - $queryFormat .= ' ORDER BY value'; - } - $query = str_format($queryFormat, $this->getTableName()); - - $result = $this->getPaginatedResult($query, [], $n); - $entryArray = []; - while ($post = $result->fetchObject()) { - $name = $post->id; - $customcolumn = new CustomColumn($post->id, $name, $this); - array_push($entryArray, $customcolumn->getEntry($post->count)); - } - return $entryArray; - } - - /** - * Summary of getCountByRange - * @param mixed $page can be $columnType::PAGE_ALL or $columnType::PAGE_DETAIL - * @param ?string $sort - * @return array - */ - public function getCountByRange($page, $sort = null) - { - $numtiles = Config::get('custom_integer_split_range'); - if ($numtiles <= 1) { - $numtiles = Config::get('max_item_per_page'); - } - if ($numtiles < 1) { - $numtiles = 1; - } - // Equal height distribution using NTILE() has problem with overlapping range - //$queryFormat = "SELECT groupid, MIN(value) AS min_value, MAX(value) AS max_value, COUNT(*) AS count FROM (SELECT value, NTILE({$numtiles}) OVER (ORDER BY value) AS groupid FROM {0}) x GROUP BY groupid"; - // Semi-equal height distribution using CUME_DIST() - $queryFormat = "SELECT CAST(ROUND(dist * ({$numtiles} - 1), 0) AS INTEGER) AS groupid, MIN(value) AS min_value, MAX(value) AS max_value, COUNT(*) AS count FROM (SELECT value, CUME_DIST() OVER (ORDER BY value) dist FROM {0}) GROUP BY groupid"; - if (!empty($sort) && $sort == 'count') { - $queryFormat .= ' ORDER BY count desc, groupid'; - } else { - $queryFormat .= ' ORDER BY groupid'; - } - $query = str_format($queryFormat, $this->getTableName()); - $result = Database::query($query, [], $this->databaseId); - - $entryArray = []; - $label = 'range'; - while ($post = $result->fetchObject()) { - $range = $post->min_value . "-" . $post->max_value; - $params = ['custom' => $this->customId, 'range' => $range, 'db' => $this->databaseId]; - $href = Route::link($this->handler, $page, $params); - array_push($entryArray, new Entry( - $range, - $this->getEntryId() . ':' . $label . ':' . $range, - str_format(localize('bookword', $post->count), $post->count), - 'text', - [ new LinkNavigation($href, null, null) ], - $this->databaseId, - ucfirst($label), - $post->count - )); - } - - return $entryArray; - } - - /** - * Summary of getCustomValuesByRange - * @param string $range - * @param ?string $sort - * @return array - */ - public function getCustomValuesByRange($range, $sort = null) - { - $matches = []; - if (!preg_match(static::GET_PATTERN, $range, $matches)) { - throw new UnexpectedValueException(); - } - $lower = $matches[1]; - $upper = $matches[2]; - $queryFormat = "SELECT value AS id, count(*) AS count FROM {0} WHERE value >= ? AND value <= ? GROUP BY value"; - if (!empty($sort) && $sort == 'count') { - $queryFormat .= ' ORDER BY count desc, value'; - } else { - $queryFormat .= ' ORDER BY value'; - } - $query = str_format($queryFormat, $this->getTableName()); - $result = Database::query($query, [$lower, $upper], $this->databaseId); - - $entryArray = []; - while ($post = $result->fetchObject()) { - $name = $post->id; - $customcolumn = new CustomColumn($post->id, $name, $this); - array_push($entryArray, $customcolumn->getEntry($post->count)); - } - - return $entryArray; - } - - /** - * Summary of getCustomByBook - * @param Book $book - * @return CustomColumn - */ - public function getCustomByBook($book) - { - $queryFormat = "SELECT {0}.value AS value FROM {0} WHERE {0}.book = ?"; - $query = str_format($queryFormat, $this->getTableName()); - - $result = Database::query($query, [$book->id], $this->databaseId); - if ($post = $result->fetchObject()) { - return new CustomColumn($post->value, $post->value, $this); - } - return new CustomColumn(null, localize("customcolumn.int.unknown"), $this); - } - - /** - * Summary of isSearchable - * @return bool - */ - public function isSearchable() - { - return true; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeRating.php b/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeRating.php deleted file mode 100644 index 82e40986..00000000 --- a/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeRating.php +++ /dev/null @@ -1,169 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Model\Entry; - -class CustomColumnTypeRating extends CustomColumnType -{ - public const SQL_BOOKLIST = 'select {0} from books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - left join {2} on {2}.book = books.id - left join {3} on {3}.id = {2}.{4} - where {3}.value = ? order by books.sort'; - public const SQL_BOOKLIST_NULL = 'select {0} from books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - left join {2} on {2}.book = books.id - left join {3} on {3}.id = {2}.{4} - where ((books.id not in (select {2}.book from {2})) or ({3}.value = 0)) {1} order by books.sort'; - - /** - * Summary of __construct - * @param int $customId - * @param ?int $database - * @param array $displaySettings - */ - protected function __construct($customId, $database = null, $displaySettings = []) - { - parent::__construct($customId, static::TYPE_RATING, $database, $displaySettings); - } - - /** - * Get the name of the linking sqlite table for this column - * (or NULL if there is no linktable) - * - * @return string - */ - protected function getTableLinkName() - { - return "books_custom_column_{$this->customId}_link"; - } - - /** - * Get the name of the linking column in the linktable - * - * @return string - */ - protected function getTableLinkColumn() - { - return "value"; - } - - /** - * Summary of getQuery - * @param string|int|null $id - * @return ?array{0: string, 1: array} - */ - public function getQuery($id) - { - if (empty($id)) { - $query = str_format(static::SQL_BOOKLIST_NULL, "{0}", "{1}", $this->getTableLinkName(), $this->getTableName(), $this->getTableLinkColumn()); - return [$query, []]; - } else { - $query = str_format(static::SQL_BOOKLIST, "{0}", "{1}", $this->getTableLinkName(), $this->getTableName(), $this->getTableLinkColumn()); - return [$query, [$id]]; - } - } - - /** - * Summary of getFilter - * @param string|int|null $id - * @param ?string $parentTable - * @return ?array{0: string, 1: array} - */ - public function getFilter($id, $parentTable = null) - { - // @todo do we want to filter on ratings Id or Value here - return ["", []]; - } - - /** - * Summary of getCustom - * @param string|int|null $id - * @return CustomColumn - */ - public function getCustom($id) - { - return new CustomColumn($id, str_format(localize("customcolumn.stars", $id / 2), $id / 2), $this); - } - - /** - * Summary of getAllCustomValuesFromDatabase - * @param int $n - * @param ?string $sort - * @return array - */ - protected function getAllCustomValuesFromDatabase($n = -1, $sort = null) - { - $queryFormat = "SELECT coalesce({0}.value, 0) AS value, count(*) AS count FROM books LEFT JOIN {1} ON books.id = {1}.book LEFT JOIN {0} ON {0}.id = {1}.value GROUP BY coalesce({0}.value, -1)"; - $query = str_format($queryFormat, $this->getTableName(), $this->getTableLinkName()); - $result = Database::query($query, [], $this->databaseId); - - $countArray = [0 => 0, 2 => 0, 4 => 0, 6 => 0, 8 => 0, 10 => 0]; - while ($row = $result->fetchObject()) { - $countArray[$row->value] = $row->count; - } - - $entryArray = []; - - // @todo align with other custom columns - for ($i = 0; $i <= 5; $i++) { - $id = $i * 2; - $count = $countArray[$id]; - $name = str_format(localize("customcolumn.stars", $i), $i); - $customcolumn = new CustomColumn($id, $name, $this); - array_push($entryArray, $customcolumn->getEntry($count)); - } - - return $entryArray; - } - - /** - * Summary of getDistinctValueCount - * @return int - */ - public function getDistinctValueCount() - { - return count($this->getAllCustomValues()); - } - - /** - * Summary of getContent - * @param int $count - * @return string - */ - public function getContent($count = 0) - { - return localize("customcolumn.description.rating"); - } - - /** - * Summary of getCustomByBook - * @param mixed $book - * @return CustomColumn - */ - public function getCustomByBook($book) - { - $queryFormat = "SELECT {0}.value AS value FROM {0}, {1} WHERE {0}.id = {1}.{2} AND {1}.book = ?"; - $query = str_format($queryFormat, $this->getTableName(), $this->getTableLinkName(), $this->getTableLinkColumn()); - - $result = Database::query($query, [$book->id], $this->databaseId); - if ($post = $result->fetchObject()) { - return new CustomColumn($post->value, str_format(localize("customcolumn.stars", $post->value / 2), $post->value / 2), $this); - } - return new CustomColumn(null, localize("customcolumn.rating.unknown"), $this); - } - - /** - * Summary of isSearchable - * @return bool - */ - public function isSearchable() - { - return true; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeSeries.php b/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeSeries.php deleted file mode 100644 index ca7e54b7..00000000 --- a/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeSeries.php +++ /dev/null @@ -1,151 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Model\Entry; - -class CustomColumnTypeSeries extends CustomColumnType -{ - /** - * Summary of __construct - * @param int $customId - * @param ?int $database - * @param array $displaySettings - */ - protected function __construct($customId, $database = null, $displaySettings = []) - { - parent::__construct($customId, static::TYPE_SERIES, $database, $displaySettings); - } - - /** - * Get the name of the linking sqlite table for this column - * (or NULL if there is no linktable) - * - * @return string - */ - protected function getTableLinkName() - { - return "books_custom_column_{$this->customId}_link"; - } - - /** - * Get the name of the linking column in the linktable - * - * @return string - */ - protected function getTableLinkColumn() - { - return "value"; - } - - /** - * Summary of getQuery - * @param string|int|null $id - * @return ?array{0: string, 1: array} - */ - public function getQuery($id) - { - if (empty($id) && in_array("custom", Config::get('show_not_set_filter'))) { - $query = str_format(static::SQL_BOOKLIST_NULL, "{0}", "{1}", $this->getTableLinkName()); - return [$query, []]; - } - $query = str_format(static::SQL_BOOKLIST_LINK, "{0}", "{1}", $this->getTableLinkName(), $this->getTableLinkColumn()); - return [$query, [$id]]; - } - - /** - * Summary of getFilter - * @param string|int|null $id - * @param ?string $parentTable - * @return ?array{0: string, 1: array} - */ - public function getFilter($id, $parentTable = null) - { - $linkTable = $this->getTableLinkName(); - $linkColumn = $this->getTableLinkColumn(); - if (!empty($parentTable) && $parentTable != "books") { - $filter = "exists (select null from {$linkTable}, books where {$parentTable}.book = books.id and {$linkTable}.book = books.id and {$linkTable}.{$linkColumn} = ?)"; - } else { - $filter = "exists (select null from {$linkTable} where {$linkTable}.book = books.id and {$linkTable}.{$linkColumn} = ?)"; - } - return [$filter, [$id]]; - } - - /** - * Summary of getCustom - * @param string|int|null $id - * @return CustomColumn - */ - public function getCustom($id) - { - $query = str_format("SELECT id, value AS name FROM {0} WHERE id = ?", $this->getTableName()); - $result = Database::query($query, [$id], $this->databaseId); - if ($post = $result->fetchObject()) { - return new CustomColumn($id, $post->name, $this); - } - return new CustomColumn(null, localize("customcolumn.boolean.unknown"), $this); - } - - /** - * Summary of getAllCustomValuesFromDatabase - * @param int $n - * @param ?string $sort - * @return array - */ - protected function getAllCustomValuesFromDatabase($n = -1, $sort = null) - { - $queryFormat = "SELECT {0}.id AS id, {0}.value AS name, count(*) AS count FROM {0}, {1} WHERE {0}.id = {1}.{2} GROUP BY {0}.id, {0}.value ORDER BY {0}.value"; - $query = str_format($queryFormat, $this->getTableName(), $this->getTableLinkName(), $this->getTableLinkColumn()); - - $result = $this->getPaginatedResult($query, [], $n); - $entryArray = []; - while ($post = $result->fetchObject()) { - $customcolumn = new CustomColumn($post->id, $post->name, $this); - array_push($entryArray, $customcolumn->getEntry($post->count)); - } - return $entryArray; - } - - /** - * Summary of getContent - * @param int $count - * @return string - */ - public function getContent($count = 0) - { - return str_format(localize("customcolumn.description.series", $count), $count); - } - - /** - * Summary of getCustomByBook - * @param mixed $book - * @return CustomColumn - */ - public function getCustomByBook($book) - { - $queryFormat = "SELECT {0}.id AS id, {0}.{2} AS value, {1}.{2} AS name, {1}.extra AS extra FROM {0}, {1} WHERE {0}.id = {1}.{2} AND {1}.book = ?"; - $query = str_format($queryFormat, $this->getTableName(), $this->getTableLinkName(), $this->getTableLinkColumn()); - - $result = Database::query($query, [$book->id], $this->databaseId); - if ($post = $result->fetchObject()) { - return new CustomColumn($post->id, $post->value . " [" . $post->extra . "]", $this); - } - return new CustomColumn(null, "", $this); - } - - /** - * Summary of isSearchable - * @return bool - */ - public function isSearchable() - { - return true; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeText.php b/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeText.php deleted file mode 100644 index 89c0cdc8..00000000 --- a/COPS/cops-3.1.3/src/Calibre/CustomColumnTypeText.php +++ /dev/null @@ -1,177 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Model\Entry; -use UnexpectedValueException; - -class CustomColumnTypeText extends CustomColumnType -{ - /** - * Summary of __construct - * @param int $customId - * @param string $datatype - * @param ?int $database - * @param array $displaySettings - * @return void - * @throws \UnexpectedValueException - */ - protected function __construct($customId, $datatype = self::TYPE_TEXT, $database = null, $displaySettings = []) - { - switch ($datatype) { - case static::TYPE_TEXT: - parent::__construct($customId, static::TYPE_TEXT, $database, $displaySettings); - return; - case static::TYPE_CSV: - parent::__construct($customId, static::TYPE_CSV, $database, $displaySettings); - return; - case static::TYPE_ENUM: - parent::__construct($customId, static::TYPE_ENUM, $database, $displaySettings); - return; - case static::TYPE_SERIES: - parent::__construct($customId, static::TYPE_SERIES, $database, $displaySettings); - return; - default: - throw new UnexpectedValueException(); - } - } - - /** - * Get the name of the linking sqlite table for this column - * (or NULL if there is no linktable) - * - * @return string - */ - protected function getTableLinkName() - { - return "books_custom_column_{$this->customId}_link"; - } - - /** - * Get the name of the linking column in the linktable - * - * @return string - */ - protected function getTableLinkColumn() - { - return "value"; - } - - /** - * Summary of getQuery - * @param string|int|null $id - * @return ?array{0: string, 1: array} - */ - public function getQuery($id) - { - if (empty($id) && in_array("custom", Config::get('show_not_set_filter'))) { - $query = str_format(static::SQL_BOOKLIST_NULL, "{0}", "{1}", $this->getTableLinkName()); - return [$query, []]; - } - $query = str_format(static::SQL_BOOKLIST_LINK, "{0}", "{1}", $this->getTableLinkName(), $this->getTableLinkColumn()); - return [$query, [$id]]; - } - - /** - * Summary of getFilter - * @param string|int|null $id - * @param ?string $parentTable - * @return ?array{0: string, 1: array} - */ - public function getFilter($id, $parentTable = null) - { - $linkTable = $this->getTableLinkName(); - $linkColumn = $this->getTableLinkColumn(); - if (!empty($parentTable) && $parentTable != "books") { - $filter = "exists (select null from {$linkTable}, books where {$parentTable}.book = books.id and {$linkTable}.book = books.id and {$linkTable}.{$linkColumn} = ?)"; - } else { - $filter = "exists (select null from {$linkTable} where {$linkTable}.book = books.id and {$linkTable}.{$linkColumn} = ?)"; - } - return [$filter, [$id]]; - } - - /** - * Summary of getCustom - * @param string|int|null $id - * @return CustomColumn - */ - public function getCustom($id) - { - $query = str_format("SELECT id, value AS name FROM {0} WHERE id = ?", $this->getTableName()); - $result = Database::query($query, [$id], $this->databaseId); - if ($post = $result->fetchObject()) { - return new CustomColumn($id, $post->name, $this); - } - return new CustomColumn(null, localize("customcolumn.boolean.unknown"), $this); - } - - /** - * Summary of getAllCustomValuesFromDatabase - * @param int $n - * @param ?string $sort - * @return array - */ - protected function getAllCustomValuesFromDatabase($n = -1, $sort = null) - { - $queryFormat = "SELECT {0}.id AS id, {0}.value AS name, count(*) AS count FROM {0}, {1} WHERE {0}.id = {1}.{2} GROUP BY {0}.id, {0}.value ORDER BY {0}.value"; - $query = str_format($queryFormat, $this->getTableName(), $this->getTableLinkName(), $this->getTableLinkColumn()); - - $result = $this->getPaginatedResult($query, [], $n); - $entryArray = []; - while ($post = $result->fetchObject()) { - $customcolumn = new CustomColumn($post->id, $post->name, $this); - array_push($entryArray, $customcolumn->getEntry($post->count)); - } - return $entryArray; - } - - /** - * Summary of getCustomByBook - * @param mixed $book - * @throws \UnexpectedValueException - * @return CustomColumn - */ - public function getCustomByBook($book) - { - $queryFormat = match ($this->datatype) { - static::TYPE_TEXT => "SELECT {0}.id AS id, {0}.{2} AS name FROM {0}, {1} WHERE {0}.id = {1}.{2} AND {1}.book = ? ORDER BY {0}.value", - static::TYPE_CSV => "SELECT {0}.id AS id, {0}.{2} AS name FROM {0}, {1} WHERE {0}.id = {1}.{2} AND {1}.book = ? ORDER BY {0}.value", - static::TYPE_ENUM => "SELECT {0}.id AS id, {0}.{2} AS name FROM {0}, {1} WHERE {0}.id = {1}.{2} AND {1}.book = ?", - static::TYPE_SERIES => "SELECT {0}.id AS id, {1}.{2} AS name, {1}.extra AS extra FROM {0}, {1} WHERE {0}.id = {1}.{2} AND {1}.book = ?", - default => throw new UnexpectedValueException(), - }; - $query = str_format($queryFormat, $this->getTableName(), $this->getTableLinkName(), $this->getTableLinkColumn()); - - $result = Database::query($query, [$book->id], $this->databaseId); - // handle case where we have several values, e.g. array of text for type 2 (csv) - if ($this->datatype === static::TYPE_CSV) { - $idArray = []; - $nameArray = []; - while ($post = $result->fetchObject()) { - array_push($idArray, $post->id); - array_push($nameArray, $post->name); - } - return new CustomColumn(implode(",", $idArray), implode(",", $nameArray), $this); - } - if ($post = $result->fetchObject()) { - return new CustomColumn($post->id, $post->name, $this); - } - return new CustomColumn(null, "", $this); - } - - /** - * Summary of isSearchable - * @return bool - */ - public function isSearchable() - { - return true; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/Data.php b/COPS/cops-3.1.3/src/Calibre/Data.php deleted file mode 100644 index a7e3f3f3..00000000 --- a/COPS/cops-3.1.3/src/Calibre/Data.php +++ /dev/null @@ -1,326 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Model\LinkEntry; -use SebLucas\Cops\Output\Response; - -class Data -{ - public const SQL_TABLE = "data"; - public const SQL_COLUMNS = "id, name, format"; - public const SQL_LINK_TABLE = "data"; - public const SQL_LINK_COLUMN = "id"; - public const SQL_SORT = "name"; - public static string $handler = "fetch"; - /** @var int */ - public $id; - public string $name; - public string $format; - public string $realFormat; - public string $extension; - /** @var ?Book */ - public $book; - /** @var ?int */ - protected $databaseId; - public bool $updateForKepub = false; - - /** @var array */ - public static $mimetypes = [ - 'aac' => 'audio/aac', - 'azw' => 'application/x-mobipocket-ebook', - 'azw1' => 'application/x-topaz-ebook', - 'azw2' => 'application/x-kindle-application', - 'azw3' => 'application/x-mobi8-ebook', - 'cbz' => 'application/x-cbz', - 'cbr' => 'application/x-cbr', - 'css' => 'text/css', - 'djv' => 'image/vnd.djvu', - 'djvu' => 'image/vnd.djvu', - 'doc' => 'application/msword', - 'epub' => 'application/epub+zip', - 'fb2' => 'text/fb2+xml', - 'gif' => 'image/gif', - 'ibooks' => 'application/x-ibooks+zip', - 'jpeg' => 'image/jpeg', - 'jpg' => 'image/jpeg', - 'kepub' => 'application/epub+zip', - 'kobo' => 'application/x-koboreader-ebook', - 'm4a' => 'audio/mp4', - 'm4b' => 'audio/mp4', - 'mobi' => 'application/x-mobipocket-ebook', - 'mp3' => 'audio/mpeg', - 'lit' => 'application/x-ms-reader', - 'lrs' => 'text/x-sony-bbeb+xml', - 'lrf' => 'application/x-sony-bbeb', - 'lrx' => 'application/x-sony-bbeb', - 'ncx' => 'application/x-dtbncx+xml', - 'opf' => 'application/oebps-package+xml', - 'otf' => 'font/otf', - 'pdb' => 'application/vnd.palm', - 'pdf' => 'application/pdf', - 'png' => 'image/png', - 'prc' => 'application/x-mobipocket-ebook', - 'rtf' => 'application/rtf', - 'svg' => 'image/svg+xml', - 'ttf' => 'font/ttf', - 'tpz' => 'application/x-topaz-ebook', - 'txt' => 'text/plain', - 'wav' => 'audio/wav', - 'webp' => 'image/webp', - 'wmf' => 'image/wmf', - 'woff' => 'font/woff', - 'woff2' => 'font/woff2', - 'xhtml' => 'application/xhtml+xml', - 'xml' => 'application/xhtml+xml', - 'xpgt' => 'application/adobe-page-template+xml', - 'zip' => 'application/zip', - ]; - - /** - * Summary of __construct - * @param object $post - * @param ?Book $book - */ - public function __construct($post, $book = null) - { - $this->id = $post->id; - $this->name = $post->name; - $this->format = $post->format; - $this->realFormat = str_replace("ORIGINAL_", "", $post->format); - $this->extension = strtolower($this->realFormat); - $this->setBook($book); - } - - /** - * Summary of setBook - * @param ?Book $book - * @return void - */ - public function setBook($book) - { - $this->book = $book; - $this->databaseId = ($nullsafeVariable1 = $book) ? $nullsafeVariable1->getDatabaseId() : null; - // this is set on book in JsonRenderer now - if (!is_null($book) && $book->updateForKepub && $this->isEpubValidOnKobo()) { - $this->updateForKepub = true; - } - } - - /** - * Summary of isKnownType - * @return bool - */ - public function isKnownType() - { - return array_key_exists($this->extension, static::$mimetypes); - } - - /** - * Summary of getMimeType - * @return string - */ - public function getMimeType() - { - if ($this->isKnownType()) { - return static::$mimetypes[$this->extension]; - } - $default = "application/octet-stream"; - return Response::getMimeType($this->getLocalPath()) ?? $default; - } - - /** - * Summary of isEpubValidOnKobo - * @return bool - */ - public function isEpubValidOnKobo() - { - return $this->format == "EPUB" || $this->format == "KEPUB"; - } - - /** - * Summary of getFilename - * @return string - */ - public function getFilename() - { - return $this->name . "." . strtolower($this->format); - } - - /** - * Summary of getUpdatedFilename - * @return string - */ - public function getUpdatedFilename() - { - return $this->book->getAuthorsSort() . " - " . $this->book->title; - } - - /** - * Summary of getUpdatedFilenameEpub - * @return string - */ - public function getUpdatedFilenameEpub() - { - return $this->getUpdatedFilename() . ".epub"; - } - - /** - * Summary of getUpdatedFilenameKepub - * @return string - */ - public function getUpdatedFilenameKepub() - { - $str = $this->getUpdatedFilename() . ".kepub.epub"; - return str_replace( - [':', '#', '&'], - ['-', '-', ' '], - $str - ); - } - - /** - * Summary of getDataLink - * @param string $rel - * @param ?string $title - * @param bool $view - * @return LinkEntry - */ - public function getDataLink($rel, $title = null, $view = false) - { - if ($rel == LinkEntry::OPDS_ACQUISITION_TYPE && Config::get('use_url_rewriting') == "1") { - return $this->getHtmlLinkWithRewriting($title, $view); - } - - return static::getLink($this->book, $this->extension, $this->getMimeType(), $rel, $this->getFilename(), $this->id, $title, $view); - } - - /** - * Summary of getHtmlLink - * @return string - */ - public function getHtmlLink() - { - return $this->getDataLink(LinkEntry::OPDS_ACQUISITION_TYPE)->href; - } - - /** - * Summary of getViewHtmlLink - * @return string - */ - public function getViewHtmlLink() - { - return $this->getDataLink(LinkEntry::OPDS_ACQUISITION_TYPE, null, true)->href; - } - - /** - * Summary of getLocalPath - * @return string - */ - public function getLocalPath() - { - return $this->book->path . "/" . $this->getFilename(); - } - - /** - * Summary of getHtmlLinkWithRewriting - * @param ?string $title - * @param bool $view - * @deprecated 3.1.0 use route urls instead - * @return LinkEntry - */ - public function getHtmlLinkWithRewriting($title = null, $view = false) - { - $database = ""; - if (!is_null($this->databaseId)) { - $database = $this->databaseId . "/"; - } - - $prefix = "download"; - if ($view) { - $prefix = "view"; - } - $href = $prefix . "/" . $this->id . "/" . $database; - - // this is set on book in JsonRenderer now - if ($this->updateForKepub) { - $href .= rawurlencode($this->getUpdatedFilenameKepub()); - } else { - $href .= rawurlencode($this->getFilename()); - } - return new LinkEntry( - Route::path($href), - $this->getMimeType(), - LinkEntry::OPDS_ACQUISITION_TYPE, - $title - ); - } - - /** - * Summary of getDataByBook - * @param mixed $book - * @return array - */ - public static function getDataByBook($book) - { - return Book::getDataByBook($book); - } - - /** - * Summary of getLink - * @param Book $book - * @param string $type - * @param string $mime - * @param string $rel - * @param string $filename - * @param ?int $idData - * @param ?string $title - * @param bool $view - * @return LinkEntry - */ - public static function getLink($book, $type, $mime, $rel, $filename, $idData, $title = null, $view = false) - { - if (!empty(Config::get('calibre_external_storage')) && str_starts_with($book->path, (string) Config::get('calibre_external_storage'))) { - return new LinkEntry( - $book->path . "/" . rawurlencode($filename), - $mime, - $rel, - $title - ); - } - // moved image-specific code from Data to Cover - if (Database::useAbsolutePath($book->getDatabaseId()) || - ($type == "epub" && Config::get('update_epub-metadata'))) { - $params = ['db' => $book->getDatabaseId()]; - if (Config::get('use_route_urls') && is_null($params['db'])) { - $params['db'] = 0; - } - $params['type'] = $type; - $params['data'] = $idData; - if ($view) { - $params['view'] = 1; - } - return new LinkEntry( - Route::link(static::$handler, null, $params), - $mime, - $rel, - $title - ); - } - - return new LinkEntry( - Route::path(str_replace('%2F', '/', rawurlencode($book->path . "/" . $filename))), - $mime, - $rel, - $title - ); - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/Database.php b/COPS/cops-3.1.3/src/Calibre/Database.php deleted file mode 100644 index a8836a97..00000000 --- a/COPS/cops-3.1.3/src/Calibre/Database.php +++ /dev/null @@ -1,440 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Language\Translation; -use SebLucas\Cops\Output\Response; -use Exception; -use PDO; - -class Database -{ - public const KEEP_STATS = false; - public const CALIBRE_DB_NAME = 'metadata.db'; - public const NOTES_DIR_NAME = '.calnotes'; - public const NOTES_DB_NAME = 'notes.db'; - /** @var ?PDO */ - protected static $db = null; - protected static ?string $dbFileName = null; - /** @var ?PDO */ - protected static $notesDb = null; - protected static int $count = 0; - /** @var array */ - protected static $queries = []; - - /** - * Summary of getDbStatistics - * @return array - */ - public static function getDbStatistics() - { - return ['count' => static::$count, 'queries' => static::$queries]; - } - - /** - * Summary of isMultipleDatabaseEnabled - * @return bool - */ - public static function isMultipleDatabaseEnabled() - { - return is_array(Config::get('calibre_directory')); - } - - /** - * Summary of useAbsolutePath - * @param ?int $database - * @return bool - */ - public static function useAbsolutePath($database) - { - $path = static::getDbDirectory($database); - return preg_match('/^\//', $path) || // Linux / - preg_match('/^\w\:/', $path); // Windows X: - } - - /** - * Summary of noDatabaseSelected - * @param ?int $database - * @return bool - */ - public static function noDatabaseSelected($database) - { - return static::isMultipleDatabaseEnabled() && is_null($database); - } - - /** - * Summary of getDbList - * @return array - */ - public static function getDbList() - { - if (static::isMultipleDatabaseEnabled()) { - return Config::get('calibre_directory'); - } else { - return ["" => Config::get('calibre_directory')]; - } - } - - /** - * Summary of getDbNameList - * @return array - */ - public static function getDbNameList() - { - if (static::isMultipleDatabaseEnabled()) { - return array_keys(Config::get('calibre_directory')); - } else { - return [""]; - } - } - - /** - * Summary of getDbName - * @param ?int $database - * @return string - */ - public static function getDbName($database) - { - if (static::isMultipleDatabaseEnabled()) { - if (is_null($database)) { - $database = 0; - } - $array = array_keys(Config::get('calibre_directory')); - return $array[$database]; - } - return ""; - } - - /** - * Summary of getDbDirectory - * @param ?int $database - * @return string - */ - public static function getDbDirectory($database) - { - if (static::isMultipleDatabaseEnabled()) { - if (is_null($database)) { - $database = 0; - } - $array = array_values(Config::get('calibre_directory')); - return $array[$database]; - } - return Config::get('calibre_directory'); - } - - // -DC- Add image directory - /** - * Summary of getImgDirectory - * @param ?int $database - * @return string - */ - public static function getImgDirectory($database) - { - if (static::isMultipleDatabaseEnabled()) { - if (is_null($database)) { - $database = 0; - } - $array = array_values(Config::get('image_directory')); - return $array[$database]; - } - return Config::get('image_directory'); - } - - /** - * Summary of getDbFileName - * @param ?int $database - * @return string - */ - public static function getDbFileName($database) - { - return static::getDbDirectory($database) . 'metadata.db'; - } - - /** - * Summary of error - * @param ?int $database - * @throws \Exception - * @return never - */ - protected static function error($database) - { - if (php_sapi_name() != "cli") { - Response::redirect(Route::link("check") . "?err=1"); - } - throw new Exception("Database <{$database}> not found."); - } - - /** - * Summary of getDb - * @param ?int $database - * @return \PDO - */ - public static function getDb($database = null) - { - if (static::KEEP_STATS) { - static::$count += 1; - } - if (is_null(static::$db)) { - try { - if (is_readable(static::getDbFileName($database))) { - static::$db = new PDO('sqlite:' . static::getDbFileName($database)); - if (Translation::useNormAndUp()) { - static::$db->sqliteCreateFunction('normAndUp', function ($s) { - return Translation::normAndUp($s); - }, 1); - } - static::$dbFileName = static::getDbFileName($database); - } else { - static::error($database); - } - } catch (Exception) { - static::error($database); - } - } - return static::$db; - } - - /** - * Summary of checkDatabaseAvailability - * @param ?int $database - * @return bool - */ - public static function checkDatabaseAvailability($database) - { - if (static::noDatabaseSelected($database)) { - for ($i = 0; $i < count(static::getDbList()); $i++) { - static::getDb($i); - static::clearDb(); - } - } else { - static::getDb($database); - } - return true; - } - - /** - * Summary of clearDb - * @return void - */ - public static function clearDb() - { - static::$db = null; - static::$notesDb = null; - } - - /** - * Summary of querySingle - * @param string $query - * @param ?int $database - * @return mixed - */ - public static function querySingle($query, $database = null) - { - if (static::KEEP_STATS) { - array_push(static::$queries, $query); - } - return static::getDb($database)->query($query)->fetchColumn(); - } - - - /** - * Summary of query - * @param string $query - * @param array $params - * @param ?int $database - * @return \PDOStatement - */ - public static function query($query, $params = [], $database = null) - { - if (static::KEEP_STATS) { - array_push(static::$queries, $query); - } - if (count($params) > 0) { - $result = static::getDb($database)->prepare($query); - $result->execute($params); - } else { - $result = static::getDb($database)->query($query); - } - return $result; - } - - /** - * Summary of queryTotal - * @param string $query - * @param string $columns - * @param string $filter - * @param array $params - * @param int $n - * @param ?int $database - * @param ?int $numberPerPage - * @return array{0: integer, 1: \PDOStatement} - */ - public static function queryTotal($query, $columns, $filter, $params, $n, $database = null, $numberPerPage = null) - { - if (static::KEEP_STATS) { - array_push(static::$queries, $query); - } - $totalResult = -1; - - if (Translation::useNormAndUp()) { - $query = preg_replace("/upper/", "normAndUp", $query); - $columns = preg_replace("/upper/", "normAndUp", $columns); - } - - if (is_null($numberPerPage)) { - $numberPerPage = Config::get('max_item_per_page'); - } - - if ($numberPerPage != -1 && $n != -1) { - // First check total number of results - $totalResult = static::countFilter($query, 'count(*)', $filter, $params, $database); - - // Next modify the query and params - $query .= " limit ?, ?"; - array_push($params, ($n - 1) * $numberPerPage, $numberPerPage); - } - $result = static::getDb($database)->prepare(str_format($query, $columns, $filter)); - $result->execute($params); - return [$totalResult, $result]; - } - - /** - * Summary of queryFilter - * @param string $query - * @param string $columns - * @param string $filter - * @param array $params - * @param int $n - * @param ?int $database - * @param ?int $numberPerPage - * @return \PDOStatement - */ - public static function queryFilter($query, $columns, $filter, $params, $n, $database = null, $numberPerPage = null) - { - if (static::KEEP_STATS) { - array_push(static::$queries, $query); - } - if (Translation::useNormAndUp()) { - $query = preg_replace("/upper/", "normAndUp", $query); - $columns = preg_replace("/upper/", "normAndUp", $columns); - } - - if (is_null($numberPerPage)) { - $numberPerPage = Config::get('max_item_per_page'); - } - - if ($numberPerPage != -1 && $n != -1) { - // Next modify the query and params - $query .= " limit ?, ?"; - array_push($params, ($n - 1) * $numberPerPage, $numberPerPage); - } - - $result = static::getDb($database)->prepare(str_format($query, $columns, $filter)); - $result->execute($params); - return $result; - } - - /** - * Summary of countFilter - * @param string $query - * @param string $columns - * @param string $filter - * @param array $params - * @param ?int $database - * @return integer - */ - public static function countFilter($query, $columns = 'count(*)', $filter = '', $params = [], $database = null) - { - if (static::KEEP_STATS) { - array_push(static::$queries, $query); - } - // assuming order by ... is at the end of the query here - $query = preg_replace('/\s+order\s+by\s+[\w.]+(\s+(asc|desc)|).*$/i', '', $query); - $result = static::getDb($database)->prepare(str_format($query, $columns, $filter)); - $result->execute($params); - $totalResult = $result->fetchColumn(); - return $totalResult; - } - - /** - * Summary of getDbSchema - * @param ?int $database - * @param ?string $type get table or view entries - * @return array - */ - public static function getDbSchema($database = null, $type = null) - { - $query = 'SELECT type, name, tbl_name, rootpage, sql FROM sqlite_schema'; - $params = []; - if (!empty($type)) { - $query .= ' WHERE type = ?'; - $params[] = $type; - } - $entries = []; - $result = static::query($query, $params, $database); - while ($post = $result->fetchObject()) { - $entry = (array) $post; - array_push($entries, $entry); - } - return $entries; - } - - /** - * Summary of getTableInfo - * @param ?int $database - * @param string $name table or view name - * @return array - */ - public static function getTableInfo($database = null, $name = 'books') - { - $query = "PRAGMA table_info({$name})"; - $params = []; - $result = static::query($query, $params, $database); - $entries = []; - while ($post = $result->fetchObject()) { - $entry = (array) $post; - array_push($entries, $entry); - } - return $entries; - } - - /** - * Summary of getUserVersion - * @param ?int $database - * @return int - */ - public static function getUserVersion($database = null) - { - $query = "PRAGMA user_version"; - $result = static::querySingle($query, $database); - return $result; - } - - /** - * Summary of getNotesDb - * @param ?int $database - * @return PDO|null - */ - public static function getNotesDb($database = null) - { - if (!is_null(static::$notesDb)) { - return static::$notesDb; - } - static::getDb($database); - // calibre_dir/.calnotes/notes.db - $dbFileName = dirname((string) static::$dbFileName) . '/' . static::NOTES_DIR_NAME . '/' . static::NOTES_DB_NAME; - if (!file_exists($dbFileName) || !is_readable($dbFileName)) { - return null; - } - static::$notesDb = new PDO('sqlite:' . $dbFileName); - return static::$notesDb; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/Filter.php b/COPS/cops-3.1.3/src/Calibre/Filter.php deleted file mode 100644 index b4546795..00000000 --- a/COPS/cops-3.1.3/src/Calibre/Filter.php +++ /dev/null @@ -1,491 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Request; -use SebLucas\Cops\Model\Entry; -use SebLucas\Cops\Pages\PageId; -use UnexpectedValueException; - -class Filter -{ - public const PAGE_ID = PageId::FILTER_ID; - public const PAGE_DETAIL = PageId::FILTER; - public const URL_PARAMS = [ - Author::URL_PARAM => Author::class, - Language::URL_PARAM => Language::class, - Publisher::URL_PARAM => Publisher::class, - Rating::URL_PARAM => Rating::class, - Serie::URL_PARAM => Serie::class, - Tag::URL_PARAM => Tag::class, - Identifier::URL_PARAM => Identifier::class, - CustomColumn::URL_PARAM => CustomColumn::class, - BookList::URL_PARAM_FIRST => BookList::class, - BookList::URL_PARAM_YEAR => BookList::class, - VirtualLibrary::URL_PARAM => VirtualLibrary::class, - ]; - public const SEARCH_FIELDS = [ - 'authors' => Author::class, - //'formats' => Format::class, - 'languages' => Language::class, - 'publishers' => Publisher::class, - 'ratings' => Rating::class, - 'series' => Serie::class, - 'tags' => Tag::class, - ]; - - protected Request $request; - /** @var array */ - protected $params = []; - protected string $parentTable = "books"; - protected string $queryString = ""; - /** @var ?int */ - protected $databaseId; - - /** - * Summary of __construct - * @param Request|array $request current request or urlParams array - * @param array $params initial query params - * @param string $parent optional parent link table if we need to link books, e.g. books_series_link - * @param ?int $database current database in multiple database setup - */ - public function __construct($request, array $params = [], string $parent = "books", $database = null) - { - if (is_array($request)) { - $request = Request::build($request); - } - $this->request = $request; - $this->params = $params; - $this->parentTable = $parent; - $this->queryString = ""; - $this->databaseId = $database; - - $this->checkForFilters(); - } - - /** - * Summary of getFilterString - * @return string filters to append to query string - */ - public function getFilterString() - { - return $this->queryString; - } - - /** - * Summary of getQueryParams - * @return array updated query params including filters - */ - public function getQueryParams() - { - return $this->params; - } - - /** - * Summary of checkForFilters - * @return void - */ - public function checkForFilters() - { - if (empty($this->request->urlParams)) { - return; - } - - // See $config['cops_books_filter'] - $tagName = $this->request->get('tag', null); - if (!empty($tagName)) { - $this->addTagNameFilter($tagName); - } - - // See $config['cops_calibre_virtual_libraries'] - $libraryId = $this->request->get(VirtualLibrary::URL_PARAM, null); - if (!empty($libraryId)) { - $this->addVirtualLibraryFilter($libraryId); - } - - $authorId = $this->request->get(Author::URL_PARAM, null, '/^!?\d+$/'); - if (!empty($authorId)) { - $this->addAuthorIdFilter($authorId); - } - - $languageId = $this->request->get(Language::URL_PARAM, null, '/^!?\d+$/'); - if (!empty($languageId)) { - $this->addLanguageIdFilter($languageId); - } - - $publisherId = $this->request->get(Publisher::URL_PARAM, null, '/^!?\d+$/'); - if (!empty($publisherId)) { - $this->addPublisherIdFilter($publisherId); - } - - $ratingId = $this->request->get(Rating::URL_PARAM, null, '/^!?\d+$/'); - if (!empty($ratingId)) { - $this->addRatingIdFilter($ratingId); - } - - $seriesId = $this->request->get(Serie::URL_PARAM, null, '/^!?\d+$/'); - if (!empty($seriesId)) { - $this->addSeriesIdFilter($seriesId); - } - - $tagId = $this->request->get(Tag::URL_PARAM, null, '/^!?\d+$/'); - if (!empty($tagId)) { - $this->addTagIdFilter($tagId); - } - - $identifierType = $this->request->get(Identifier::URL_PARAM, null, '/^!?\w+$/'); - if (!empty($identifierType)) { - $this->addIdentifierTypeFilter($identifierType); - } - - $letter = $this->request->get(BookList::URL_PARAM_FIRST, null, '/^\w$/'); - if (!empty($letter)) { - $this->addFirstLetterFilter($letter); - } - - $year = $this->request->get(BookList::URL_PARAM_YEAR, null, '/^\d+$/'); - if (!empty($year)) { - $this->addPubYearFilter($year); - } - - // URL format: ...&c[2]=3&c[3]=other to filter on column 2 = 3 and column 3 = other - $customIdArray = $this->request->get(CustomColumn::URL_PARAM, null); - if (!empty($customIdArray) && is_array($customIdArray)) { - $this->addCustomIdArrayFilters($customIdArray); - } - } - - /** - * Summary of addFilter - * @param string $filter - * @param mixed $param - * @return void - */ - public function addFilter($filter, $param) - { - $this->queryString .= ' and (' . $filter . ')'; - array_push($this->params, $param); - } - - /** - * Summary of addTagNameFilter - * @param string $tagName - * @return void - */ - public function addTagNameFilter($tagName) - { - $exists = true; - if (preg_match("/^!(.*)$/", $tagName, $matches)) { - $exists = false; - $tagName = $matches[1]; - } - - $filter = 'exists (select null from books_tags_link, tags where books_tags_link.book = books.id and books_tags_link.tag = tags.id and tags.name = ?)'; - - if (!$exists) { - $filter = 'not ' . $filter; - } - - $this->addFilter($filter, $tagName); - } - - /** - * Summary of addVirtualLibraryFilter - * @param string|int $libraryId - * @throws \UnexpectedValueException - * @return void - */ - public function addVirtualLibraryFilter($libraryId) - { - // URL format: ...&vl=2.Short_Stories_in_English - if (str_contains($libraryId, '.')) { - [$libraryId, $slug] = explode('.', $libraryId); - } - /** @var VirtualLibrary $instance */ - $instance = VirtualLibrary::getInstanceById($libraryId); - if (empty($instance->id)) { - return; - } - - $search = $instance->value; - $replace = $search; - $params = []; - $matches = []; - // See https://github.com/seblucas/cops/pull/233 by @Broele - preg_match_all('/(?P#?\w+)\:(?P\w+|"(?P[^"]*)")/', $search, $matches, PREG_SET_ORDER); - foreach ($matches as $match) { - // get search field - if (!array_key_exists($match['attr'], static::SEARCH_FIELDS)) { - $match['attr'] .= 's'; - if (!array_key_exists($match['attr'], static::SEARCH_FIELDS)) { - throw new UnexpectedValueException('Unsupported search field: ' . $match['attr']); - } - } - // find exact match - if (isset($match['quoted']) && str_starts_with($match['quoted'], '=')) { - $value = substr($match['quoted'], 1); - $className = static::SEARCH_FIELDS[$match['attr']]; - $instance = $className::getInstanceByName($value, $this->databaseId); - $filterString = $this->getLinkedIdFilter($instance->getLinkTable(), $instance->getLinkColumn(), $instance->limitSelf); - $replace = str_replace($match[0], $filterString, $replace); - array_push($params, $instance->id); - } else { - throw new UnexpectedValueException('Unsupported search criteria: ' . $match['attr'] . '=' . $match['value']); - } - } - - if (!empty($replace)) { - $this->queryString .= ' and (' . $replace . ')'; - foreach ($params as $param) { - array_push($this->params, $param); - } - } - } - - /** - * Summary of addInstanceFilter - * @param Base|Author|Language|Publisher|Rating|Serie|Tag|CustomColumn $instance - * @return void - */ - public function addInstanceFilter($instance) - { - if ($instance instanceof CustomColumn) { - $this->addCustomIdFilter($instance->customColumnType, $instance->id); - return; - } - $this->addLinkedIdFilter($instance->id, $instance->getLinkTable(), $instance->getLinkColumn(), $instance->limitSelf); - } - - /** - * Summary of addAuthorIdFilter - * @param string|int $authorId - * @return void - */ - public function addAuthorIdFilter($authorId) - { - $this->addLinkedIdFilter($authorId, Author::SQL_LINK_TABLE, Author::SQL_LINK_COLUMN); - } - - /** - * Summary of addLanguageIdFilter - * @param string|int $languageId - * @return void - */ - public function addLanguageIdFilter($languageId) - { - $this->addLinkedIdFilter($languageId, Language::SQL_LINK_TABLE, Language::SQL_LINK_COLUMN); - } - - /** - * Summary of addPublisherIdFilter - * @param string|int $publisherId - * @return void - */ - public function addPublisherIdFilter($publisherId) - { - $this->addLinkedIdFilter($publisherId, Publisher::SQL_LINK_TABLE, Publisher::SQL_LINK_COLUMN); - } - - /** - * Summary of addRatingIdFilter - * @param string|int $ratingId - * @return void - */ - public function addRatingIdFilter($ratingId) - { - $this->addLinkedIdFilter($ratingId, Rating::SQL_LINK_TABLE, Rating::SQL_LINK_COLUMN); - } - - /** - * Summary of addSeriesIdFilter - * @param string|int $seriesId - * @return void - */ - public function addSeriesIdFilter($seriesId) - { - $this->addLinkedIdFilter($seriesId, Serie::SQL_LINK_TABLE, Serie::SQL_LINK_COLUMN); - } - - /** - * Summary of addTagIdFilter - * @param string|int $tagId - * @return void - */ - public function addTagIdFilter($tagId) - { - $this->addLinkedIdFilter($tagId, Tag::SQL_LINK_TABLE, Tag::SQL_LINK_COLUMN); - } - - /** - * Summary of addIdentifierTypeFilter - * @param string $identifierType - * @return void - */ - public function addIdentifierTypeFilter($identifierType) - { - $this->addLinkedIdFilter($identifierType, Identifier::SQL_LINK_TABLE, Identifier::SQL_LINK_COLUMN); - } - - /** - * Summary of addFirstLetterFilter - * @param mixed $letter - * @return void - */ - public function addFirstLetterFilter($letter) - { - $filter = 'substr(upper(books.sort), 1, 1) = ?'; - $this->addFilter($filter, $letter); - } - - /** - * Summary of addPubYearFilter - * @param mixed $year - * @return void - */ - public function addPubYearFilter($year) - { - $filter = 'substr(date(books.pubdate), 1, 4) = ?'; - $this->addFilter($filter, $year); - } - - /** - * Summary of addCustomIdArrayFilters - * @param array $customIdArray - * @return void - */ - public function addCustomIdArrayFilters($customIdArray) - { - foreach ($customIdArray as $customId => $valueId) { - if (!preg_match('/^\d+$/', $customId)) { - continue; - } - $customType = CustomColumnType::createByCustomID($customId, $this->databaseId); - $this->addCustomIdFilter($customType, $valueId); - } - } - - /** - * Summary of addCustomIdFilter - * @param CustomColumnType $customType - * @param mixed $valueId - * @return void - */ - public function addCustomIdFilter($customType, $valueId) - { - [$filter, $params] = $customType->getFilter($valueId, $this->parentTable); - if (!empty($filter)) { - $this->queryString .= ' and (' . $filter . ')'; - foreach ($params as $param) { - array_push($this->params, $param); - } - } - } - - /** - * Summary of addLinkedIdFilter - * @param string|int $linkId - * @param string $linkTable - * @param string $linkColumn - * @param bool $limitSelf if filtering on the same table as the parent, limit results to self (or not for tags) - * @return void - */ - public function addLinkedIdFilter($linkId, $linkTable, $linkColumn, $limitSelf = true) - { - $exists = true; - $matches = []; - if (preg_match("/^!(.*)$/", $linkId, $matches)) { - $exists = false; - $linkId = $matches[1]; - } - - $filter = $this->getLinkedIdFilter($linkTable, $linkColumn, $limitSelf); - - if (!$exists) { - $filter = 'not ' . $filter; - } - - $this->addFilter($filter, $linkId); - } - - /** - * Summary of getLinkedIdFilter - * @param string $linkTable - * @param string $linkColumn - * @param bool $limitSelf if filtering on the same table as the parent, limit results to self (or not for tags) - * @return string - */ - public function getLinkedIdFilter($linkTable, $linkColumn, $limitSelf = true) - { - if ($this->parentTable == $linkTable) { - if ($limitSelf) { - $filter = "{$linkTable}.{$linkColumn} = ?"; - } else { - // find other tags/identifiers applied to books where this tag/identifier applies - $filter = "exists (select null from {$linkTable} as filterself, books where {$this->parentTable}.book = books.id and {$this->parentTable}.{$linkColumn} != filterself.{$linkColumn} and filterself.book = books.id and filterself.{$linkColumn} = ?)"; - } - } elseif ($this->parentTable == "books") { - $filter = "exists (select null from {$linkTable} where {$linkTable}.book = books.id and {$linkTable}.{$linkColumn} = ?)"; - } else { - $filter = "exists (select null from {$linkTable}, books where {$this->parentTable}.book = books.id and {$linkTable}.book = books.id and {$linkTable}.{$linkColumn} = ?)"; - } - - return $filter; - } - - /** - * Summary of getEntryArray - * @param Request $request - * @param ?int $database - * @return array - */ - public static function getEntryArray($request, $database = null) - { - $handler = $request->getHandler(); - $libraryId = $request->getVirtualLibrary(); - $entryArray = []; - foreach (static::URL_PARAMS as $paramName => $className) { - if ($className == VirtualLibrary::class) { - continue; - } - $paramValue = $request->get($paramName, null); - if (!isset($paramValue)) { - continue; - } - // @todo do we want to filter by virtual library etc. here? - if ($className == BookList::class) { - $booklist = new BookList(Request::build([$paramName => $paramValue], $handler), $database); - $groupFunc = ($paramName == 'f') ? 'getCountByFirstLetter' : 'getCountByPubYear'; - $entryArray = array_merge($entryArray, $booklist->$groupFunc()); - continue; - } - if ($className == CustomColumn::class) { - foreach ($paramValue as $customId => $valueId) { - $custom = CustomColumn::createCustom($customId, $valueId, $database); - $custom->setHandler($handler); - $entryArray = array_merge($entryArray, [ $custom->getCustomCount() ]); - } - continue; - } - // remove negative flag for filter entry here - if (preg_match('/^!\d+$/', (string) $paramValue)) { - $paramValue = substr((string) $paramValue, 1); - } - if (!empty($libraryId)) { - $req = Request::build([$paramName => $paramValue, VirtualLibrary::URL_PARAM => $libraryId], $handler); - } else { - $req = Request::build([$paramName => $paramValue], $handler); - } - $baselist = new BaseList($className, $req, $database); - $entries = $baselist->getEntriesByFilter(); - $entryArray = array_merge($entryArray, $entries); - } - return $entryArray; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/Identifier.php b/COPS/cops-3.1.3/src/Calibre/Identifier.php deleted file mode 100644 index 732287fc..00000000 --- a/COPS/cops-3.1.3/src/Calibre/Identifier.php +++ /dev/null @@ -1,191 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Pages\PageId; - -class Identifier extends Base -{ - public const PAGE_ID = PageId::ALL_IDENTIFIERS_ID; - public const PAGE_ALL = PageId::ALL_IDENTIFIERS; - public const PAGE_DETAIL = PageId::IDENTIFIER_DETAIL; - public const SQL_TABLE = "identifiers"; - public const SQL_LINK_TABLE = "identifiers"; - public const SQL_LINK_COLUMN = "type"; - public const SQL_SORT = "type"; - public const SQL_COLUMNS = "identifiers.type as id, identifiers.type as type, '' as val"; - public const SQL_ALL_ROWS = "select {0} from identifiers where 1=1 {1} group by identifiers.type order by identifiers.type"; - public const SQL_ROWS_FOR_SEARCH = ""; // "select {0} from tags, books_tags_link where tags.id = tag and upper (tags.name) like ? {1} group by tags.id, tags.name order by tags.name"; - public const SQL_BOOKLIST = 'select {0} from identifiers, books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where identifiers.book = books.id and identifiers.type = ? {1} order by books.sort'; - public const SQL_BOOKLIST_NULL = 'select {0} from books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where books.id not in (select book from identifiers) {1} order by books.sort'; - public const URL_PARAM = "i"; - - /** @var ?int */ - public $id; - /** @var string */ - public $type; - public string $formattedType; - /** @var string */ - public $val; - public string $uri; - /** @var ?int */ - protected $databaseId; - - /** - * Summary of __construct - * @param object $post - * @param ?int $database - */ - public function __construct($post, $database = null) - { - $this->id = $post->id; - $this->type = strtolower($post->type); - $this->val = $post->val; - $this->formatType(); - $this->databaseId = $database; - } - - /** - * Summary of formatType - * @return void - */ - public function formatType() - { - if ($this->type == 'amazon') { - $this->formattedType = "Amazon"; - $this->uri = sprintf("https://amazon.com/dp/%s", $this->val); - } elseif ($this->type == "asin") { - $this->formattedType = $this->type; - $this->uri = sprintf("https://amazon.com/dp/%s", $this->val); - } elseif (str_starts_with($this->type, "amazon_")) { - $this->formattedType = sprintf("Amazon.co.%s", substr($this->type, 7)); - $this->uri = sprintf("https://amazon.co.%s/dp/%s", substr($this->type, 7), $this->val); - } elseif ($this->type == "isbn") { - $this->formattedType = "ISBN"; - $this->uri = sprintf("https://www.worldcat.org/isbn/%s", $this->val); - } elseif ($this->type == "doi") { - $this->formattedType = "DOI"; - $this->uri = sprintf("https://dx.doi.org/%s", $this->val); - } elseif ($this->type == "douban") { - $this->formattedType = "Douban"; - $this->uri = sprintf("https://book.douban.com/subject/%s", $this->val); - } elseif ($this->type == "goodreads") { - $this->formattedType = "Goodreads"; - $this->uri = sprintf("https://www.goodreads.com/book/show/%s", $this->val); - } elseif ($this->type == "google") { - $this->formattedType = "Google Books"; - $this->uri = sprintf("https://books.google.com/books?id=%s", $this->val); - } elseif ($this->type == "kobo") { - $this->formattedType = "Kobo"; - $this->uri = sprintf("https://www.kobo.com/ebook/%s", $this->val); - } elseif ($this->type == "litres") { - $this->formattedType = "ЛитРес"; - $this->uri = sprintf("https://www.litres.ru/%s", $this->val); - } elseif ($this->type == "issn") { - $this->formattedType = "ISSN"; - $this->uri = sprintf("https://portal.issn.org/resource/ISSN/%s", $this->val); - } elseif ($this->type == "isfdb") { - $this->formattedType = "ISFDB"; - $this->uri = sprintf("http://www.isfdb.org/cgi-bin/pl.cgi?%s", $this->val); - } elseif ($this->type == "lubimyczytac") { - $this->formattedType = "Lubimyczytac"; - $this->uri = sprintf("https://lubimyczytac.pl/ksiazka/%s/ksiazka", $this->val); - } elseif ($this->type == "wd") { - $this->formattedType = "Wikidata"; - $this->uri = sprintf("https://www.wikidata.org/entity/%s", $this->val); - } elseif ($this->type == "ltid") { - $this->formattedType = "LibraryThing"; - $this->uri = sprintf("https://www.librarything.com/work/book/%s", $this->val); - } elseif ($this->type == "olid") { - $this->formattedType = "OpenLibrary"; - $this->uri = sprintf("https://openlibrary.org/works/%s", $this->val); - } elseif ($this->type == "url") { - $this->formattedType = $this->type; - $this->uri = $this->val; - } else { - $this->formattedType = $this->type; - $this->uri = ''; - } - } - - /** - * Summary of getTitle - * @return mixed - */ - public function getTitle() - { - return $this->formattedType; - } - - /** - * Summary of getParentTitle - * @return string - */ - public function getParentTitle() - { - return localize("identifiers.title"); - } - - /** - * Summary of getLink - * @return string - */ - public function getLink() - { - return $this->uri; - } - - /** - * Summary of getInstanceById - * @param string|int|null $id used for the type of identifier here - * @param ?int $database - * @return object - */ - public static function getInstanceById($id, $database = null) - { - if (isset($id)) { - return new Identifier((object) ['id' => $id, 'type' => $id, 'val' => ''], $database); - } - $default = static::getDefaultName(); - return new Identifier((object) ['id' => null, 'type' => $default, 'val' => ''], $database); - } - - /** - * Summary of getDefaultName - * @return string - */ - public static function getDefaultName() - { - return localize("identifierword.none"); - } - - /** - * Summary of getInstancesByBookId - * @param int $bookId - * @param ?int $database - * @return array - */ - public static function getInstancesByBookId($bookId, $database = null) - { - $identifiers = []; - - $query = 'select type, val, id - from identifiers - where book = ? - order by type'; - $result = Database::query($query, [$bookId], $database); - while ($post = $result->fetchObject()) { - array_push($identifiers, new Identifier($post, $database)); - } - return $identifiers; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/Language.php b/COPS/cops-3.1.3/src/Calibre/Language.php deleted file mode 100644 index ffa7e5b8..00000000 --- a/COPS/cops-3.1.3/src/Calibre/Language.php +++ /dev/null @@ -1,91 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Pages\PageId; - -class Language extends Base -{ - public const PAGE_ID = PageId::ALL_LANGUAGES_ID; - public const PAGE_ALL = PageId::ALL_LANGUAGES; - public const PAGE_DETAIL = PageId::LANGUAGE_DETAIL; - public const SQL_TABLE = "languages"; - public const SQL_LINK_TABLE = "books_languages_link"; - public const SQL_LINK_COLUMN = "lang_code"; - public const SQL_SORT = "lang_code"; - public const SQL_COLUMNS = "languages.id as id, languages.lang_code as name"; - public const SQL_ALL_ROWS = "select {0} from languages, books_languages_link where languages.id = books_languages_link.lang_code {1} group by languages.id, books_languages_link.lang_code order by languages.lang_code"; - public const SQL_BOOKLIST = 'select {0} from books_languages_link, books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where books_languages_link.book = books.id and lang_code = ? {1} order by books.sort'; - public const URL_PARAM = "l"; - - /** - * Summary of getTitle - * @return string - */ - public function getTitle() - { - return static::getLanguageString($this->name); - } - - /** - * Summary of getParentTitle - * @return string - */ - public function getParentTitle() - { - return localize("languages.title"); - } - - /** Use inherited class methods to query static SQL_TABLE for this class */ - - /** - * Summary of getLanguageString - * @param string $code - * @return string - */ - public static function getLanguageString($code) - { - $string = localize("languages." . $code); - if (preg_match("/^languages/", $string)) { - return $code; - } - return $string; - } - - /** - * Summary of getDefaultName - * @return string - */ - public static function getDefaultName() - { - return localize("language.title"); - } - - /** - * Summary of getLanguagesByBookId - * @param int $bookId - * @param ?int $database - * @return string - */ - public static function getLanguagesByBookId($bookId, $database = null) - { - $lang = []; - $query = 'select ' . static::getInstanceColumns($database) . ' - from books_languages_link, languages - where books_languages_link.lang_code = languages.id - and book = ? - order by item_order'; - $result = Database::query($query, [$bookId], $database); - while ($post = $result->fetchObject()) { - array_push($lang, static::getLanguageString($post->name)); - } - return implode(', ', $lang); - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/Metadata.php b/COPS/cops-3.1.3/src/Calibre/Metadata.php deleted file mode 100644 index 9192c85a..00000000 --- a/COPS/cops-3.1.3/src/Calibre/Metadata.php +++ /dev/null @@ -1,197 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Calibre; - -use DOMDocument; -use DOMNode; -use DOMText; -use JsonException; - -/** - * Calibre metadata.opf files are based on EPUB 2.0 , - * not EPUB 3.x - */ -class Metadata -{ - public string $uniqueIdentifier; - public string $version; - /** @var array */ - public array $metadata; - /** @var array */ - public array $guide; - - /** - * Summary of getElement - * @param string $element like dc:identifier - * @return array - */ - public function getElement($element) - { - $elements = []; - foreach ($this->metadata as $item) { - if (empty($item[$element])) { - continue; - } - $elements[] = $item[$element]; - } - return $elements; - } - - /** - * Summary of getIdentifiers - * @return array - */ - public function getIdentifiers() - { - return $this->getElement('dc:identifier'); - } - - /** - * Summary of getElementName - * @param string $element like meta - * @param string $name like calibre:annotation - * @return array - */ - public function getElementName($element, $name) - { - $elements = []; - foreach ($this->metadata as $item) { - if (empty($item[$element])) { - continue; - } - if (empty($item[$element]['name']) || $item[$element]['name'] != $name) { - continue; - } - $elements[] = $item[$element]['content']; - } - return $elements; - } - - /** - * Summary of getAnnotations - * @return array - */ - public function getAnnotations() - { - return $this->getElementName('meta', 'calibre:annotation'); - } - - /** - * Summary of getInstanceByBookId - * @param int $bookId - * @param ?int $database - * @return Metadata|false - */ - public static function getInstanceByBookId($bookId, $database = null) - { - $book = Book::getBookById($bookId, $database); - if (empty($book)) { - return false; - } - $file = realpath($book->path . '/metadata.opf'); - if (empty($file) || !file_exists($file)) { - return false; - } - $content = file_get_contents($file); - return static::parseData($content); - } - - /** - * @param string $data - * @return self - */ - public static function parseData($data) - { - $doc = new DOMDocument(); - $doc->loadXML($data); - $root = static::getNode($doc, 'package'); - - $package = new self(); - $package->uniqueIdentifier = static::getAttr($root, 'unique-identifier'); - $package->version = static::getAttr($root, 'version'); - $package->metadata = static::addNode(static::getNode($root, 'metadata')); - $package->guide = static::addNode(static::getNode($root, 'guide')); - return $package; - } - - /** - * @param DOMNode $node - * @param string $name - * @return mixed - */ - public static function getAttr($node, $name) - { - return $node->getAttribute($name); - } - - /** - * @param DOMNode $node - * @param string $name - * @return DOMNode - */ - public static function getNode($node, $name) - { - return $node->getElementsByTagName($name)->item(0); - } - - /** - * @param DOMNode $node - * @return string|array - */ - public static function addNode($node) - { - if (!$node->hasAttributes() && !$node->hasChildNodes()) { - return trim($node->nodeValue); - } - $children = null; - if ($node->hasChildNodes()) { - if ($node->childNodes->length == 1 && $node->firstChild instanceof DOMText) { - $children = trim((string) $node->firstChild->nodeValue); - } else { - $children = []; - foreach ($node->childNodes as $child) { - if ($child instanceof DOMText) { - continue; - } - $children[] = [$child->nodeName => self::addNode($child)]; - } - } - } - if (!$node->hasAttributes()) { - return $children; - } - $info = []; - foreach ($node->attributes as $attr) { - if ($node->nodeName == 'meta' && $attr->name == 'content' && !empty($attr->value)) { - try { - $info[$attr->name] = json_decode($attr->value, true, 512, JSON_THROW_ON_ERROR); - } catch (JsonException) { - $info[$attr->name] = $attr->value; - } - } elseif ($attr->name == 'value') { - $info['@value'] = $attr->value; - } else { - $info[$attr->name] = $attr->value; - } - } - //$value = trim($node->nodeValue); - //if ($value !== '') { - // $info['value'] = $value; - //} - if (!empty($children)) { - if (is_array($children)) { - $info['children'] = $children; - } else { - $info['value'] = $children; - } - } - return $info; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/Note.php b/COPS/cops-3.1.3/src/Calibre/Note.php deleted file mode 100644 index bcf853d9..00000000 --- a/COPS/cops-3.1.3/src/Calibre/Note.php +++ /dev/null @@ -1,176 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Pages\PageId; - -class Note -{ - public const PAGE_ID = PageId::ALL_NOTES_ID; - public const PAGE_ALL = PageId::ALL_NOTES; - public const PAGE_TYPE = PageId::ALL_NOTES_TYPE; - public const PAGE_DETAIL = PageId::NOTE_DETAIL; - public const ALLOWED_FIELDS = [ - 'authors' => Author::class, - //'languages' => Language::class, - 'publishers' => Publisher::class, - 'series' => Serie::class, - 'tags' => Tag::class, - ]; - public int $id; - public int $item; - public string $colname; - public string $doc; - public float $mtime; - public ?int $databaseId = null; - protected string $handler = ''; - - /** - * Summary of __construct - * @param object $post - * @param ?int $database - */ - public function __construct($post, $database = null) - { - $this->id = $post->id; - $this->item = $post->item; - $this->colname = $post->colname; - $this->doc = $post->doc; - $this->mtime = $post->mtime; - $this->databaseId = $database; - } - - /** - * Summary of getUri - * @param array $params - * @return string - */ - public function getUri($params = []) - { - // @todo get handler from somewhere - return Route::link($this->handler) . '/notes/' . $this->colname . '/' . $this->item; - } - - /** - * Summary of getTitle - * @return string|null - */ - public function getTitle() - { - // @todo get corresponding title from item instance - return ''; - } - - /** - * Summary of getResources - * @return array - */ - public function getResources() - { - $notesDb = Database::getNotesDb($this->databaseId); - if (is_null($notesDb)) { - return []; - } - $resources = []; - $query = 'select hash, name from resources, notes_resources_link where resources.hash = resource and note = ?'; - $params = [$this->id]; - $result = $notesDb->prepare($query); - $result->execute($params); - while ($post = $result->fetchObject()) { - $resources[$post->hash] = new Resource($post, $this->databaseId); - } - return $resources; - } - - /** - * Summary of getCountByType - * @param ?int $database - * @return array - */ - public static function getCountByType($database = null) - { - $notesDb = Database::getNotesDb($database); - if (is_null($notesDb)) { - return []; - } - $entries = []; - $query = 'select colname as type, count(*) as count from notes group by colname order by colname'; - $result = $notesDb->prepare($query); - $result->execute(); - while ($post = $result->fetchObject()) { - $entries[$post->type] = $post->count; - } - return $entries; - } - - /** - * Summary of getEntriesByType - * @param string $type - * @param ?int $database - * @return array - */ - public static function getEntriesByType($type, $database = null) - { - if (!array_key_exists($type, static::ALLOWED_FIELDS)) { - return []; - } - $notesDb = Database::getNotesDb($database); - if (is_null($notesDb)) { - return []; - } - $entries = []; - $query = 'select item, length(doc) as size, mtime from notes where colname = ? order by item'; - $params = [$type]; - $result = $notesDb->prepare($query); - $result->execute($params); - while ($post = $result->fetchObject()) { - $entries[$post->item] = (array) $post; - } - $itemIdList = array_keys($entries); - if (empty($itemIdList)) { - return $entries; - } - $query = "select id, name from {$type} where id in (" . str_repeat('?,', count($itemIdList) - 1) . '?)'; - $result = Database::query($query, $itemIdList, $database); - while ($post = $result->fetchObject()) { - if (array_key_exists($post->id, $entries)) { - $entries[$post->id]["title"] = $post->name; - } - } - return $entries; - } - - /** - * Summary of getInstanceByTypeId - * @param string $type - * @param int $id - * @param ?int $database - * @return self|null - */ - public static function getInstanceByTypeId($type, $id, $database = null) - { - if (!array_key_exists($type, static::ALLOWED_FIELDS)) { - return null; - } - $notesDb = Database::getNotesDb($database); - if (is_null($notesDb)) { - return null; - } - $query = 'select id, item, colname, doc, mtime from notes where item = ? and colname = ?'; - $params = [$id, $type]; - $result = $notesDb->prepare($query); - $result->execute($params); - if ($post = $result->fetchObject()) { - return new self($post, $database); - } - return null; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/Preference.php b/COPS/cops-3.1.3/src/Calibre/Preference.php deleted file mode 100644 index d711f2d8..00000000 --- a/COPS/cops-3.1.3/src/Calibre/Preference.php +++ /dev/null @@ -1,118 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Pages\PageId; -use JsonException; - -class Preference -{ - public const PAGE_ID = PageId::ALL_PREFERENCES_ID; - public const PAGE_ALL = PageId::ALL_PREFERENCES; - public const PAGE_DETAIL = PageId::PREFERENCE_DETAIL; - public const SQL_TABLE = "preferences"; - public const SQL_COLUMNS = "id, key, val"; - - public int $id; - public string $key; - public mixed $val; - public ?int $databaseId = null; - - /** - * Summary of __construct - * @param object $post - * @param ?int $database - */ - public function __construct($post, $database = null) - { - $this->id = $post->id; - $this->key = $post->key; - try { - $this->val = json_decode($post->val, true, 512, JSON_THROW_ON_ERROR); - } catch (JsonException) { - $this->val = $post->val; - } - $this->databaseId = $database; - } - - /** - * Summary of getInstances - * @param ?int $database - * @return array - */ - public static function getInstances($database = null) - { - $preferences = []; - $query = 'select ' . static::SQL_COLUMNS . ' from ' . static::SQL_TABLE . ' order by key'; - $result = Database::query($query, [], $database); - while ($post = $result->fetchObject()) { - $preferences[$post->key] = new self($post, $database); - } - return $preferences; - } - - /** - * Summary of getInstanceByKey - * @param string $key - * @param ?int $database - * @return self|null - */ - public static function getInstanceByKey($key, $database = null) - { - $query = 'select ' . static::SQL_COLUMNS . ' from ' . static::SQL_TABLE . ' where key = ?'; - $params = [$key]; - $result = Database::query($query, $params, $database); - if ($post = $result->fetchObject()) { - return new self($post, $database); - } - return null; - } - - /** - * Summary of getVirtualLibraries - * { - * "Both Authors": "authors:\"=Author Two\" and authors:\"=Author One\"", - * "Kindle 2": "tags:\"=Kindle_Mike\" or tags:\"=Kindle_Luca\"", - * "No Device": "not tags:\"=Kindle_Mike\" and not tags:\"=Kindle_Luca\" and not tags:\"=Kindle_Lydia\"" - * } - * See https://github.com/seblucas/cops/pull/233 - * @param ?int $database - * @return self|null - */ - public static function getVirtualLibraries($database = null) - { - return static::getInstanceByKey('virtual_libraries', $database); - } - - /** - * Summary of getUserCategories - * @param ?int $database - * @return self|null - */ - public static function getUserCategories($database = null) - { - // @todo investigate format - return static::getInstanceByKey('user_categories', $database); - } - - /** - * Summary of getSavedSearches - * { - * "Author One": "authors:one and not authors:two" - * } - * @param ?int $database - * @return self|null - */ - public static function getSavedSearches($database = null) - { - // @todo map search string from saved search to filters - return static::getInstanceByKey('saved_searches', $database); - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/Publisher.php b/COPS/cops-3.1.3/src/Calibre/Publisher.php deleted file mode 100644 index a9ae7dea..00000000 --- a/COPS/cops-3.1.3/src/Calibre/Publisher.php +++ /dev/null @@ -1,66 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Pages\PageId; - -class Publisher extends Base -{ - public const PAGE_ID = PageId::ALL_PUBLISHERS_ID; - public const PAGE_ALL = PageId::ALL_PUBLISHERS; - public const PAGE_DETAIL = PageId::PUBLISHER_DETAIL; - public const SQL_TABLE = "publishers"; - public const SQL_LINK_TABLE = "books_publishers_link"; - public const SQL_LINK_COLUMN = "publisher"; - public const SQL_SORT = "name"; - public const SQL_COLUMNS = "publishers.id as id, publishers.name as name"; - public const SQL_ALL_ROWS = "select {0} from publishers, books_publishers_link where publishers.id = publisher {1} group by publishers.id, publishers.name order by publishers.name"; - public const SQL_ROWS_FOR_SEARCH = "select {0} from publishers, books_publishers_link where publishers.id = publisher and upper (publishers.name) like ? {1} group by publishers.id, publishers.name order by publishers.name"; - public const SQL_BOOKLIST = 'select {0} from books_publishers_link, books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where books_publishers_link.book = books.id and publisher = ? {1} order by books.sort'; - public const URL_PARAM = "p"; - - /** - * Summary of getParentTitle - * @return string - */ - public function getParentTitle() - { - return localize("publishers.title"); - } - - /** Use inherited class methods to query static SQL_TABLE for this class */ - - /** - * Summary of getInstanceByBookId - * @param int $bookId - * @param ?int $database - * @return Publisher|false - */ - public static function getInstanceByBookId($bookId, $database = null) - { - $query = 'select ' . static::getInstanceColumns($database) . ' -from books_publishers_link, publishers -where publishers.id = publisher and book = ?'; - $result = Database::query($query, [$bookId], $database); - if ($post = $result->fetchObject()) { - return new Publisher($post, $database); - } - return false; - } - - /** - * Summary of getDefaultName - * @return string - */ - public static function getDefaultName() - { - return localize("publisherword.none"); - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/Rating.php b/COPS/cops-3.1.3/src/Calibre/Rating.php deleted file mode 100644 index 22e382b3..00000000 --- a/COPS/cops-3.1.3/src/Calibre/Rating.php +++ /dev/null @@ -1,72 +0,0 @@ -name) / 2), intval($this->name) / 2); - } - - /** - * Summary of getParentTitle - * @return string - */ - public function getParentTitle() - { - return localize("ratings.title"); - } - - /** Use inherited class methods to query static SQL_TABLE for this class */ - - /** - * Summary of getCount - * @param ?int $database - * @param ?string $handler - * @return ?Entry - */ - public static function getCount($database = null, $handler = null) - { - $count = Database::querySingle('select count(*) from ' . static::SQL_TABLE, $database); - // str_format (localize("ratings", count(array)) - return static::getCountEntry($count, $database, "ratings", $handler); - } - - /** - * Summary of getDefaultName - * @return int - */ - public static function getDefaultName() - { - return 0; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/Resource.php b/COPS/cops-3.1.3/src/Calibre/Resource.php deleted file mode 100644 index 145ff2e5..00000000 --- a/COPS/cops-3.1.3/src/Calibre/Resource.php +++ /dev/null @@ -1,138 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Output\FileResponse; - -class Resource -{ - // https://github.com/kovidgoyal/calibre/blob/master/src/calibre/gui2/dialogs/edit_category_notes.py - public const IMAGE_EXTENSIONS = [ - 'png' => 'image/png', - 'jpeg' => 'image/jpeg', - 'jpg' => 'image/jpeg', - 'gif' => 'image/gif', - 'svg' => 'image/svg+xml', - 'webp' => 'image/webp', - ]; - public const RESOURCE_URL_SCHEME = 'calres'; - public static string $handler = "calres"; - public string $hash; - public string $name; - public ?int $databaseId = null; - - /** - * Summary of __construct - * @param object $post - * @param ?int $database - */ - public function __construct($post, $database = null) - { - $this->hash = $post->hash; - $this->name = $post->name; - $this->databaseId = $database; - } - - /** - * Summary of getUri - * @param array $params - * @return string - */ - public function getUri($params = []) - { - $database = $this->databaseId ?? 0; - if (Config::get('use_route_urls')) { - [$alg, $digest] = explode(':', $this->hash); - $params['db'] = $database; - $params['alg'] = $alg; - $params['digest'] = $digest; - return Route::link(static::$handler, null, $params); - } - // @todo remove /handler once link() is fixed - $baseurl = Route::link(static::$handler) . '/' . static::$handler; - return $baseurl . '/' . $database . '/' . str_replace(':', '/', $this->hash); - } - - /** - * Summary of fixResourceLinks - * @param string $doc - * @param ?int $database - * @return string - */ - public static function fixResourceLinks($doc, $database = null) - { - $database ??= 0; - if (Config::get('use_route_urls')) { - // create link to resource with dummy alg & digest - $baseurl = Route::link(static::$handler, null, ['db' => $database, 'alg' => '{alg}', 'digest' => '{digest}']); - // remove dummy alg & digest - $baseurl = str_replace(['/{alg}', '/{digest}'], [], $baseurl); - return str_replace(static::RESOURCE_URL_SCHEME . '://', $baseurl . '/', $doc); - } - // @todo remove /handler once link() is fixed - $baseurl = Route::link(static::$handler) . '/' . static::$handler; - return str_replace(static::RESOURCE_URL_SCHEME . '://', $baseurl . '/' . $database . '/', $doc); - } - - /** - * Summary of getResourcePath - * @param string $hash - * @param ?int $database - * @return string|null - */ - public static function getResourcePath($hash, $database = null) - { - [$alg, $digest] = explode(':', $hash); - $resourcesDir = dirname(Database::getDbFileName($database)) . '/' . Database::NOTES_DIR_NAME . '/resources'; - $resourcePath = $resourcesDir . '/' . substr($digest, 0, 2) . '/' . $alg . '-' . $digest; - if (file_exists($resourcePath)) { - return $resourcePath; - } - return null; - } - - /** - * Summary of sendImageResource - * @param string $hash - * @param FileResponse $response - * @param ?string $name - * @param ?int $database - * @return FileResponse|null - */ - public static function sendImageResource($hash, $response, $name = null, $database = null) - { - $path = static::getResourcePath($hash, $database); - if (empty($path)) { - return null; - } - if (empty($name)) { - $content = file_get_contents($path . '.metadata'); - $info = json_decode($content, true); - $name = $info['name']; - } - $ext = strtolower(pathinfo((string) $name, PATHINFO_EXTENSION)); - if (!array_key_exists($ext, static::IMAGE_EXTENSIONS)) { - return null; - } - $mime = static::IMAGE_EXTENSIONS[$ext]; - - $response->setHeaders($mime, 0); - return $response->sendFile($path, true); - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/Serie.php b/COPS/cops-3.1.3/src/Calibre/Serie.php deleted file mode 100644 index 127c4705..00000000 --- a/COPS/cops-3.1.3/src/Calibre/Serie.php +++ /dev/null @@ -1,69 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Pages\PageId; - -class Serie extends Category -{ - public const PAGE_ID = PageId::ALL_SERIES_ID; - public const PAGE_ALL = PageId::ALL_SERIES; - public const PAGE_DETAIL = PageId::SERIE_DETAIL; - public const SQL_TABLE = "series"; - public const SQL_LINK_TABLE = "books_series_link"; - public const SQL_LINK_COLUMN = "series"; - public const SQL_SORT = "sort"; - public const SQL_COLUMNS = "series.id as id, series.name as name, series.sort as sort"; - public const SQL_ALL_ROWS = "select {0} from series, books_series_link where series.id = series {1} group by series.id, series.name, series.sort order by series.sort"; - public const SQL_ROWS_FOR_SEARCH = "select {0} from series, books_series_link where series.id = series and upper (series.name) like ? {1} group by series.id, series.name, series.sort order by series.sort"; - public const SQL_BOOKLIST = 'select {0} from books_series_link, books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where books_series_link.book = books.id and series = ? {1} order by series_index'; - public const SQL_BOOKLIST_NULL = 'select {0} from books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where books.id not in (select book from books_series_link) {1} order by books.sort'; - public const URL_PARAM = "s"; - public const CATEGORY = "series"; - - /** - * Summary of getParentTitle - * @return string - */ - public function getParentTitle() - { - return localize("series.title"); - } - - /** Use inherited class methods to query static SQL_TABLE for this class */ - - /** - * Summary of getInstanceByBookId - * @param int $bookId - * @param ?int $database - * @return Serie|false - */ - public static function getInstanceByBookId($bookId, $database = null) - { - $query = 'select ' . static::getInstanceColumns($database) . ' -from books_series_link, series -where series.id = series and book = ?'; - $result = Database::query($query, [$bookId], $database); - if ($post = $result->fetchObject()) { - return new Serie($post, $database); - } - return false; - } - - /** - * Summary of getDefaultName - * @return string - */ - public static function getDefaultName() - { - return localize("seriesword.none"); - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/Tag.php b/COPS/cops-3.1.3/src/Calibre/Tag.php deleted file mode 100644 index 82165ff6..00000000 --- a/COPS/cops-3.1.3/src/Calibre/Tag.php +++ /dev/null @@ -1,72 +0,0 @@ - - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Pages\PageId; - -class Tag extends Category -{ - public const PAGE_ID = PageId::ALL_TAGS_ID; - public const PAGE_ALL = PageId::ALL_TAGS; - public const PAGE_DETAIL = PageId::TAG_DETAIL; - public const SQL_TABLE = "tags"; - public const SQL_LINK_TABLE = "books_tags_link"; - public const SQL_LINK_COLUMN = "tag"; - public const SQL_SORT = "name"; - public const SQL_COLUMNS = "tags.id as id, tags.name as name"; - public const SQL_ALL_ROWS = "select {0} from tags, books_tags_link where tags.id = tag {1} group by tags.id, tags.name order by tags.name"; - public const SQL_ROWS_FOR_SEARCH = "select {0} from tags, books_tags_link where tags.id = tag and upper (tags.name) like ? {1} group by tags.id, tags.name order by tags.name"; - public const SQL_BOOKLIST = 'select {0} from books_tags_link, books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where books_tags_link.book = books.id and tag = ? {1} order by books.sort'; - public const SQL_BOOKLIST_NULL = 'select {0} from books ' . Book::SQL_BOOKS_LEFT_JOIN . ' - where books.id not in (select book from books_tags_link) {1} order by books.sort'; - public const URL_PARAM = "t"; - public const CATEGORY = "tags"; - - /** - * Summary of getParentTitle - * @return string - */ - public function getParentTitle() - { - return localize("tags.title"); - } - - /** Use inherited class methods to query static SQL_TABLE for this class */ - - /** - * Summary of getDefaultName - * @return string - */ - public static function getDefaultName() - { - return localize("tagword.none"); - } - - /** - * Summary of getInstancesByBookId - * @param int $bookId - * @param ?int $database - * @return array - */ - public static function getInstancesByBookId($bookId, $database = null) - { - $tags = []; - $query = 'select ' . static::getInstanceColumns($database) . ' - from books_tags_link, tags - where tag = tags.id - and book = ? - order by name'; - $result = Database::query($query, [$bookId], $database); - while ($post = $result->fetchObject()) { - array_push($tags, new Tag($post, $database)); - } - return $tags; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/User.php b/COPS/cops-3.1.3/src/Calibre/User.php deleted file mode 100644 index ac5826d8..00000000 --- a/COPS/cops-3.1.3/src/Calibre/User.php +++ /dev/null @@ -1,152 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Config; -use PDO; -use Exception; -use JsonException; - -/** - * Summary of User - */ -class User -{ - public const SQL_TABLE = "users"; - public const SQL_COLUMNS = "id, name, timestamp, session_data, restriction, readonly, misc_data"; - - public int $id; - public string $name; - public mixed $restriction; - public ?string $userDbFile = null; - - /** - * Summary of __construct - * @param object $post - * @param ?string $userDbFile - */ - public function __construct($post, $userDbFile = null) - { - $this->id = $post->id; - $this->name = $post->name; - // @todo use restriction etc. from Calibre user database - // ['library_restrictions' => []] - try { - $this->restriction = json_decode($post->restriction, true, 512, JSON_THROW_ON_ERROR); - } catch (JsonException) { - $this->restriction = $post->restriction; - } - $this->userDbFile = $userDbFile; - } - - /** - * Summary of getUserDb - * @param string|null $userDbFile - * @return \PDO - */ - public static function getUserDb($userDbFile = null) - { - $userDbFile ??= Config::get('calibre_user_database'); - if (!is_string($userDbFile) || !is_readable($userDbFile)) { - throw new Exception('Invalid users database ' . $userDbFile); - } - return new PDO('sqlite:' . $userDbFile); - } - - /** - * Summary of getInstanceByName - * @param string $name - * @param ?string $userDbFile - * @return self|null - */ - public static function getInstanceByName($name, $userDbFile = null) - { - try { - $db = static::getUserDb($userDbFile); - } catch (Exception $e) { - error_log($e->getMessage()); - return null; - } - $query = 'select ' . static::SQL_COLUMNS . ' from ' . static::SQL_TABLE . ' where name = ?'; - $params = [$name]; - $result = $db->prepare($query); - $result->execute($params); - if ($post = $result->fetchObject()) { - return new self($post, $userDbFile); - } - return null; - } - - /** - * Summary of verifyLogin - * @param array $serverVars - * @return bool - */ - public static function verifyLogin($serverVars = null) - { - $basicAuth = Config::get('basic_authentication'); - if (empty($basicAuth)) { - return true; - } - $serverVars ??= $_SERVER; - if (empty($serverVars['PHP_AUTH_USER']) || empty($serverVars['PHP_AUTH_PW'])) { - return false; - } - // array( "username" => "xxx", "password" => "secret") - if (is_array($basicAuth)) { - return static::checkBasicAuthArray($basicAuth, $serverVars); - } - // /config/.config/calibre/server-users.sqlite - if (is_string($basicAuth)) { - return static::checkBasicAuthDatabase($basicAuth, $serverVars); - } - return false; - } - - /** - * Summary of checkBasicAuthArray - * @param array $authArray - * @param array $serverVars - * @return bool - */ - public static function checkBasicAuthArray($authArray, $serverVars) - { - if (($serverVars['PHP_AUTH_USER'] != $authArray['username'] || - $serverVars['PHP_AUTH_PW'] != $authArray['password'])) { - return false; - } - return true; - } - - /** - * Summary of checkBasicAuthDatabase - * @param string $userDbFile - * @param array $serverVars - * @return bool - */ - public static function checkBasicAuthDatabase($userDbFile, $serverVars) - { - try { - $db = static::getUserDb($userDbFile); - } catch (Exception $e) { - error_log($e->getMessage()); - return false; - } - $query = 'select ' . static::SQL_COLUMNS . ' from ' . static::SQL_TABLE . ' where name = ? and pw = ?'; - $stmt = $db->prepare($query); - $params = [ $serverVars['PHP_AUTH_USER'], $serverVars['PHP_AUTH_PW'] ]; - $stmt->execute($params); - $result = $stmt->fetchObject(); - if (empty($result) || $result->name != $serverVars['PHP_AUTH_USER']) { - return false; - } - return true; - } -} diff --git a/COPS/cops-3.1.3/src/Calibre/VirtualLibrary.php b/COPS/cops-3.1.3/src/Calibre/VirtualLibrary.php deleted file mode 100644 index d31240b3..00000000 --- a/COPS/cops-3.1.3/src/Calibre/VirtualLibrary.php +++ /dev/null @@ -1,204 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Calibre; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Model\Entry; -use SebLucas\Cops\Pages\PageId; - -class VirtualLibrary extends Base -{ - public const PAGE_ID = PageId::ALL_LIBRARIES_ID; - public const PAGE_ALL = PageId::ALL_LIBRARIES; - public const PAGE_DETAIL = PageId::LIBRARY_DETAIL; - public const SQL_TABLE = "libraries"; - public const URL_PARAM = "vl"; - - /** @var array */ - protected static array $libraries = []; - public string $value; - - /** - * Summary of __construct - * @param object $post - * @param ?int $database - */ - public function __construct($post, $database = null) - { - $this->id = $post->id; - $this->name = $post->name; - $this->value = $post->value; - $this->databaseId = $database; - } - - /** - * Summary of getUri - * @param array $params - * @return string - */ - public function getUri($params = []) - { - // get home page from Config - $homepage = PageId::getHomePage(); - // we need databaseId here because we use Route::link with $handler - $params['db'] = $this->getDatabaseId(); - if (!empty($this->id)) { - // URL format: ...&vl=2.Short_Stories_in_English - $params[static::URL_PARAM] = static::formatParameter($this->id, $this->getTitle()); - } - return Route::link($this->handler, $homepage, $params); - } - - /** - * Summary of getParentTitle - * @return string - */ - public function getParentTitle() - { - return localize("libraries.title"); - } - - /** - * Summary of formatParameter - * @param string|int $id - * @param string $title - * @return string - */ - public static function formatParameter($id, $title) - { - // URL format: ...&vl=2.Short_Stories_in_English - return strval($id) . '.' . Route::slugify($title); - } - - /** - * Summary of getLibraries - * @param ?int $database - * @return array - */ - public static function getLibraries($database = null) - { - $db = $database ?? 0; - if (array_key_exists($db, self::$libraries)) { - return self::$libraries[$db]; - } - $preference = Preference::getVirtualLibraries($database); - self::$libraries[$db] = $preference->val ?? []; - return self::$libraries[$db]; - } - - /** - * Summary of countEntries - * @param ?int $database - * @return int - */ - public static function countEntries($database = null) - { - $libraries = self::getLibraries($database); - return count($libraries); - } - - /** - * Summary of getEntries - * @param ?int $database - * @param ?string $handler - * @return array - */ - public static function getEntries($database = null, $handler = null) - { - $libraries = self::getLibraries($database); - $entryArray = []; - $id = 1; - foreach ($libraries as $name => $value) { - // @todo get book count filtered by value - $post = (object) ['id' => $id, 'name' => $name, 'value' => $value, 'count' => 0]; - $instance = new self($post, $database); - $instance->setHandler($handler); - array_push($entryArray, $instance->getEntry($post->count)); - $id += 1; - } - return $entryArray; - } - - /** - * Summary of getWithoutEntry - * @param ?int $database - * @param ?string $handler - * @return ?Entry - */ - public static function getWithoutEntry($database = null, $handler = null) - { - $booklist = new BookList(null, $database); - $count = $booklist->getBookCount(); - $instance = self::getInstanceById(null, $database); - $instance->setHandler($handler); - return $instance->getEntry($count); - } - - /** - * Summary of getDefaultName - * @return ?string - */ - public static function getDefaultName() - { - return localize("libraries.none"); - } - - /** - * Summary of getCount - * @param ?int $database - * @param ?string $handler - * @return ?Entry - */ - public static function getCount($database = null, $handler = null) - { - $libraries = self::getLibraries($database); - $count = count($libraries); - return static::getCountEntry($count, $database, "libraries", $handler); - } - - /** - * Summary of getInstanceById - * @param string|int|null $id - * @param ?int $database - * @return object - */ - public static function getInstanceById($id, $database = null) - { - $libraries = self::getLibraries($database); - if (isset($id)) { - // id = key position in array + 1 - $id = intval($id) - 1; - $name = array_keys($libraries)[$id]; - return static::getInstanceByName($name); - } - $default = static::getDefaultName(); - $post = (object) ['id' => null, 'name' => $default, 'value' => '']; - return new self($post, $database); - } - - /** - * Summary of getInstanceByName - * @param string $name - * @param ?int $database - * @return self|null - */ - public static function getInstanceByName($name, $database = null) - { - $libraries = self::getLibraries($database); - if (!empty($libraries) && array_key_exists($name, $libraries)) { - // id = key position in array + 1 - $id = array_search($name, array_keys($libraries)) + 1; - $post = (object) ['id' => $id, 'name' => $name, 'value' => $libraries[$name]]; - return new self($post, $database); - } - return null; - } -} diff --git a/COPS/cops-3.1.3/src/Framework.php b/COPS/cops-3.1.3/src/Framework.php deleted file mode 100644 index ee5a0fe1..00000000 --- a/COPS/cops-3.1.3/src/Framework.php +++ /dev/null @@ -1,132 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops; - -/** - * Minimal Framework - */ -class Framework -{ - /** @var array */ - protected static $handlers = [ - "index" => Handlers\HtmlHandler::class, - "feed" => Handlers\FeedHandler::class, - "json" => Handlers\JsonHandler::class, - "fetch" => Handlers\FetchHandler::class, - "read" => Handlers\ReadHandler::class, - "epubfs" => Handlers\EpubFsHandler::class, - "restapi" => Handlers\RestApiHandler::class, - "check" => Handlers\CheckHandler::class, - "opds" => Handlers\OpdsHandler::class, - "loader" => Handlers\LoaderHandler::class, - "zipper" => Handlers\ZipperHandler::class, - "calres" => Handlers\CalResHandler::class, - "zipfs" => Handlers\ZipFsHandler::class, - "mail" => Handlers\MailHandler::class, - "graphql" => Handlers\GraphQLHandler::class, - ]; - /** @var array */ - protected static $middlewares = []; - - /** - * Single request runner with optional handler name - * @param string $name - * @return void - */ - public static function run($name = '') - { - $request = static::getRequest($name); - - // @todo route to the right handler if needed - if (empty($name)) { - $name = $request->getHandler(); - } elseif (Input\Config::get('use_route_urls')) { - $name = $request->getHandler($name); - } - // special case for json requests here - if ($name == 'index' && $request->isJson()) { - $name = 'json'; - } - $handler = Framework::getHandler($name); - if (empty(static::$middlewares)) { - $handler->handle($request); - return; - } - // @see https://www.php-fig.org/psr/psr-15/meta/#queue-based-request-handler - $queue = new Handlers\QueueBasedHandler($handler); - foreach (static::$middlewares as $middleware) { - $queue->add(new $middleware()); - } - $queue->handle($request); - } - - /** - * Get request instance - * @param string $name - * @param bool $parse - * @return Input\Request - */ - public static function getRequest($name = '', $parse = true) - { - // initialize routes if needed - static::init(); - // when using Apache .htaccess redirect - if (empty($_SERVER['PATH_INFO']) && !empty($_SERVER['REDIRECT_PATH_INFO'])) { - $_SERVER['PATH_INFO'] = $_SERVER['REDIRECT_PATH_INFO']; - } - // @deprecated 3.1.0 use index.php/$name instead - // fix PATH_INFO when accessed via traditional endpoint scripts - if (!empty($name) && Input\Route::addPrefix($name)) { - if (empty($_SERVER['PATH_INFO']) || $_SERVER['PATH_INFO'] == '/') { - $_SERVER['PATH_INFO'] = '/' . $name; - } elseif (!str_starts_with((string) $_SERVER['PATH_INFO'], '/' . $name . '/')) { - $_SERVER['PATH_INFO'] = '/' . $name . $_SERVER['PATH_INFO']; - // @todo force parsing route urls here? - Input\Config::set('use_route_urls', 1); - } - } - // @todo special case for restapi - return new Input\Request($parse); - } - - /** - * Initialize framework - * @return void - */ - public static function init() - { - static::addRoutes(); - } - - /** - * Add routes for all handlers - * @return void - */ - public static function addRoutes() - { - if (Input\Route::count() > 0) { - return; - } - foreach (static::$handlers as $name => $handler) { - Input\Route::addRoutes($handler::getRoutes()); - } - } - - /** - * Get handler instance based on name - * @param string $name - * @param mixed $args - * @return mixed - */ - public static function getHandler($name, ...$args) - { - return new static::$handlers[$name](...$args); - } -} diff --git a/COPS/cops-3.1.3/src/Handlers/BaseHandler.php b/COPS/cops-3.1.3/src/Handlers/BaseHandler.php deleted file mode 100644 index 57a29244..00000000 --- a/COPS/cops-3.1.3/src/Handlers/BaseHandler.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Handlers; - -use SebLucas\Cops\Input\Request; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Output\Response; - -/** - * Summary of BaseHandler - */ -abstract class BaseHandler -{ - public const PARAM = Route::HANDLER_PARAM; - public const HANDLER = ""; - - /** - * @return array - */ - public static function getRoutes() - { - return []; - } - - public function __construct() - { - // ... - } - - /** - * @param Request $request - * @return Response|void - */ - abstract public function handle($request); -} diff --git a/COPS/cops-3.1.3/src/Handlers/CalResHandler.php b/COPS/cops-3.1.3/src/Handlers/CalResHandler.php deleted file mode 100644 index 16c33668..00000000 --- a/COPS/cops-3.1.3/src/Handlers/CalResHandler.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Handlers; - -use SebLucas\Cops\Calibre\Resource; -use SebLucas\Cops\Output\FileResponse; -use SebLucas\Cops\Output\Response; - -/** - * Handle calres:// resources for Calibre notes - * URL format: index.php/calres/{db}/{alg}/{digest} with {hash} = {alg}:{digest} - */ -class CalResHandler extends BaseHandler -{ - public const HANDLER = "calres"; - - public static function getRoutes() - { - // extra routes supported by other endpoints (path starts with endpoint param) - return [ - "/calres/{db:\d+}/{alg}/{digest}" => [static::PARAM => static::HANDLER], - ]; - } - - public function handle($request) - { - $database = $request->getId('db'); - $alg = $request->get('alg'); - $digest = $request->get('digest'); - - $hash = $alg . ':' . $digest; - - // create empty file response to start with!? - $response = new FileResponse(); - - $result = Resource::sendImageResource($hash, $response, null, intval($database)); - if (is_null($result)) { - Response::notFound($request); - } - } -} diff --git a/COPS/cops-3.1.3/src/Handlers/CheckHandler.php b/COPS/cops-3.1.3/src/Handlers/CheckHandler.php deleted file mode 100644 index cbbcb165..00000000 --- a/COPS/cops-3.1.3/src/Handlers/CheckHandler.php +++ /dev/null @@ -1,344 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Handlers; - -use SebLucas\Cops\Calibre\Database; -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Request; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Output\Format; -use SebLucas\Cops\Output\Response; -use Exception; -use PDO; - -/** - * Summary of CheckHandler - */ -class CheckHandler extends BaseHandler -{ - public const HANDLER = "check"; - - public static function getRoutes() - { - return [ - "/check/{more:.*}" => [static::PARAM => static::HANDLER], - "/check" => [static::PARAM => static::HANDLER], - ]; - } - - public function handle($request) - { - $more = $request->get('more'); - if ($more) { - $this->handleMore($request); - return; - } - - try { - $this->checkConfig($request); - } catch (Exception $e) { - echo "

    Error in normal handling:

    "; - echo "

    " . $e->getMessage() . "


    "; - include 'checkconfig.php'; - } - } - - /** - * Summary of checkConfig - * @param Request $request - * @return void - */ - public function checkConfig($request) - { - $data = []; - $data['style'] = Route::path($request->style()); - $data['err'] = $request->get('err', -1); - $data['error'] = $this->getError($data['err']); - $data['phpversion'] = $this->getPhpVersion(); - foreach ($this->getExtensions() as $extension => $message) { - $data['extension_' . $extension] = $message; - } - $data['baseurl'] = $this->getBaseURL($request); - $data['render'] = $this->getRender($request); - $data['agent'] = $this->getAgent($request); - $data['full'] = $request->get('full'); - $data['databases'] = $this->getDatabases($data['full']); - - $template = dirname(__DIR__, 2) . '/templates/checkconfig.html'; - - $response = new Response('text/html;charset=utf-8'); - $response->sendData(Format::template($data, $template)); - } - - /** - * Summary of getMessage - * @param string $title - * @param string $message - * @return string - */ - public function getMessage($title, $message) - { - return ' -
    -

    ' . $title . '

    -

    ' . $message . '

    -
    '; - } - - /** - * Summary of getError - * @param mixed $err - * @return string - */ - public function getError($err) - { - switch ($err) { - case 1: - $title = 'You\'ve been redirected because COPS is not configured properly'; - $message = 'Database error'; - return $this->getMessage($title, $message); - } - return ''; - } - - /** - * Summary of getPhpVersion - * @return string - */ - public function getPhpVersion() - { - if (defined('PHP_VERSION_ID')) { - if (PHP_VERSION_ID >= 80200) { - return 'OK (' . PHP_VERSION . ')'; - } - return 'Please install PHP >= 8.2 (' . PHP_VERSION . ')'; - } - return 'Please install PHP >= 8.2'; - } - - /** - * Summary of getExtensions - * @return array - */ - public function getExtensions() - { - $extensions = []; - if (extension_loaded('gd') && function_exists('gd_info')) { - $extensions['gd'] = 'OK'; - } else { - $extensions['gd'] = 'Please install the php-gd extension and make sure it\'s enabled'; - } - if (extension_loaded('pdo_sqlite')) { - $extensions['sqlite'] = 'OK'; - } else { - $extensions['sqlite'] = 'Please install the php-sqlite / php-sqlite3 extension and make sure it\'s enabled'; - } - if (extension_loaded('libxml')) { - $extensions['libxml'] = 'OK'; - } else { - $extensions['libxml'] = 'Please make sure libxml is enabled'; - } - if (extension_loaded('dom')) { - $extensions['dom'] = 'OK'; - } else { - $extensions['dom'] = 'Please install the php-xml extension and make sure DOM is enabled'; - } - if (extension_loaded('xmlwriter')) { - $extensions['xmlwriter'] = 'OK'; - } else { - $extensions['xmlwriter'] = 'Please install the php-xml extension and make sure XMLWriter is enabled'; - } - if (extension_loaded('json')) { - $extensions['json'] = 'OK'; - } else { - $extensions['json'] = 'Please install the php-json extension and make sure it\'s enabled'; - } - if (extension_loaded('mbstring')) { - $extensions['mbstring'] = 'OK'; - } else { - $extensions['mbstring'] = 'Please install the php-mbstring extension and make sure it\'s enabled'; - } - if (extension_loaded('intl')) { - $extensions['intl'] = 'OK'; - } else { - $extensions['intl'] = 'Please install the php-intl extension and make sure it\'s enabled'; - } - if (class_exists('Normalizer', $autoload = false)) { - $extensions['Normalizer'] = 'OK'; - } else { - $extensions['Normalizer'] = 'Please make sure intl is enabled in your php.ini'; - } - if (extension_loaded('zlib')) { - $extensions['zlib'] = 'OK'; - } else { - $extensions['zlib'] = 'Please make sure zlib is enabled'; - } - return $extensions; - } - - /** - * Summary of getBaseURL - * @param Request $request - * @return string - */ - public function getBaseURL($request) - { - $base = dirname((string) $request->script()); - if (!str_ends_with($base, '/')) { - $base .= '/'; - } - $result = ''; - $result .= 'Base URL detected by the script: ' . $base . '
    '; - $result .= 'Full URL specified in $config[\'cops_full_url\']: ' . Config::get('full_url') . '
    '; - if (Route::hasTrustedProxies()) { - $result .= 'Trusted proxies configured: ' . Config::get('trusted_proxies') . '
    '; - $result .= 'Trusted headers configured: ' . json_encode(Config::get('trusted_headers')) . '
    '; - foreach (Config::get('trusted_headers') as $name) { - $header = 'HTTP_' . strtoupper(str_replace('-', '_', $name)); - $result .= $header . ': ' . ($request->server($header) ?? '') . '
    '; - } - $result .= 'Base URL via trusted proxies: ' . Route::base() . '
    '; - } - $result .= 'REMOTE_ADDR: ' . ($request->server('REMOTE_ADDR') ?? '') . '
    '; - $result .= '
    '; - $result .= 'SCRIPT_NAME: ' . ($request->server('SCRIPT_NAME') ?? '') . '
    '; - $result .= 'HTTP_HOST: ' . ($request->server('HTTP_HOST') ?? '') . '
    '; - $result .= 'SERVER_NAME: ' . ($request->server('SERVER_NAME') ?? '') . '
    '; - $result .= 'SERVER_ADDR: ' . ($request->server('SERVER_ADDR') ?? '') . '
    '; - $result .= 'SERVER_PORT: ' . ($request->server('SERVER_PORT') ?? '') . '
    '; - $result .= 'REQUEST_SCHEME: ' . ($request->server('REQUEST_SCHEME') ?? '') . '
    '; - $result .= 'REQUEST_URI: ' . ($request->server('REQUEST_URI') ?? '') . '
    '; - return $result; - } - - /** - * Summary of getRender - * @param Request $request - * @return string - */ - public function getRender($request) - { - if ($request->render()) { - return 'Server side rendering'; - } - return 'Client side rendering'; - } - - /** - * Summary of getAgent - * @param Request $request - * @return string - */ - public function getAgent($request) - { - return $request->agent(); - } - - /** - * Summary of getDatabases - * @param mixed $full - * @return string - */ - public function getDatabases($full) - { - $i = 0; - $result = ''; - foreach (Database::getDbList() as $name => $database) { - $title = 'Check if Calibre database path is not an URL'; - if (!preg_match('#^http#', $database)) { - $message = $name . ' OK'; - } else { - $message = $name . ' Calibre path has to be local (no URL allowed)'; - } - $result .= $this->getMessage($title, $message); - - $title = 'Check if Calibre database file exists and is readable'; - if (is_readable(Database::getDbFileName($i))) { - $message = $name . ' OK'; - } else { - $message = $name . ' File ' . Database::getDbFileName($i) . ' not found, -Please check -
    '; - } - $result .= $this->getMessage($title, $message); - - if (!is_readable(Database::getDbFileName($i))) { - $i++; - continue; - } - $title = 'Check if Calibre database file can be opened with PHP'; - try { - $db = new PDO('sqlite:' . Database::getDbFileName($i)); - $message = $name . ' OK'; - } catch (Exception $e) { - $message = $name . ' If the file is readable, check your php configuration. Exception detail : ' . $e; - } - $result .= $this->getMessage($title, $message); - - $title = 'Check if Calibre database file contains at least some of the needed tables'; - try { - $db = new PDO('sqlite:' . Database::getDbFileName($i)); - $count = $db->query('select count(*) FROM sqlite_master WHERE type="table" AND name in ("books", "authors", "tags", "series")')->fetchColumn(); - if ($count == 4) { - $message = $name . ' OK'; - } else { - $message = $name . ' Not all Calibre tables were found. Are you sure you\'re using the correct database.'; - } - } catch (Exception $e) { - $message = $name . ' If the file is readable, check your php configuration. Exception detail : ' . $e; - } - $result .= $this->getMessage($title, $message); - - if (!$full) { - $i++; - continue; - } - $title = 'Check if all Calibre books are found'; - $message = "This option has been disabled by default - uncomment if you are sure you want to do this..."; - /** - try { - $db = new PDO('sqlite:' . Database::getDbFileName($i)); - $result = $db->prepare('select books.path || "/" || data.name || "." || lower (format) as fullpath from data join books on data.book = books.id'); - $result->execute(); - while ($post = $result->fetchObject()) { - if (!is_file(Database::getDbDirectory($i) . $post->fullpath)) { - echo '

    ' . Database::getDbDirectory($i) . $post->fullpath . '

    '; - } - } - } catch (Exception $e) { - echo $name . ' If the file is readable, check your php configuration. Exception detail : ' . $e; - } - */ - $result .= $this->getMessage($title, $message); - $i++; - } - return $result; - } - - /** - * Summary of handleMore - * @param Request $request - * @return void - */ - public function handleMore($request) - { - $message = date(DATE_COOKIE) . "\n\n"; - $message .= var_export($request, true); - - $response = new Response('text/plain;charset=utf-8'); - $response->sendData($message); - } -} diff --git a/COPS/cops-3.1.3/src/Handlers/EpubFsHandler.php b/COPS/cops-3.1.3/src/Handlers/EpubFsHandler.php deleted file mode 100644 index 6a781b8b..00000000 --- a/COPS/cops-3.1.3/src/Handlers/EpubFsHandler.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Handlers; - -use SebLucas\Cops\Output\EPubReader; -use SebLucas\Cops\Output\Response; -use Exception; - -/** - * Handle Epub filesystem for monocle epub reader - * URL format: index.php/epubfs?data={idData}&comp={component} - */ -class EpubFsHandler extends BaseHandler -{ - public const HANDLER = "epubfs"; - - public static function getRoutes() - { - // support custom pattern for route placeholders - see nikic/fast-route - return [ - "/epubfs/{db:\d+}/{data:\d+}/{comp:.+}" => [static::PARAM => static::HANDLER], - ]; - } - - public function handle($request) - { - if (php_sapi_name() === 'cli' && $request->getHandler() !== 'phpunit') { - return; - } - - //$database = $request->getId('db'); - $idData = $request->getId('data'); - if (empty($idData)) { - // this will call exit() - Response::notFound($request); - } - $component = $request->get('comp', null); - if (empty($component)) { - // this will call exit() - Response::notFound($request); - } - $database = $request->database(); - - // create empty response to start with!? - $response = new Response(); - - $reader = new EPubReader($request, $response); - - try { - $reader->sendContent($idData, $component, $database); - - } catch (Exception $e) { - error_log($e); - Response::sendError($request, $e->getMessage()); - } - } -} diff --git a/COPS/cops-3.1.3/src/Handlers/FeedHandler.php b/COPS/cops-3.1.3/src/Handlers/FeedHandler.php deleted file mode 100644 index c55be787..00000000 --- a/COPS/cops-3.1.3/src/Handlers/FeedHandler.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Handlers; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Output\OpdsRenderer; -use SebLucas\Cops\Output\Response; -use SebLucas\Cops\Pages\PageId; - -/** - * Handle OPDS 1.2 feed - * URL format: index.php/feed?page={page}&query={query}&... - */ -class FeedHandler extends BaseHandler -{ - public const HANDLER = "feed"; - - public static function getRoutes() - { - return [ - "/feed/{page}/{id}" => [static::PARAM => static::HANDLER], - "/feed/{page}" => [static::PARAM => static::HANDLER], - "/feed" => [static::PARAM => static::HANDLER], - ]; - } - - public function handle($request) - { - $page = $request->get('page', PageId::INDEX); - $query = $request->get('query'); - if ($query) { - $page = PageId::OPENSEARCH_QUERY; - } - // @todo handle special case of OPDS not expecting filter while HTML does better - $request->set('filter', null); - - if (Config::get('fetch_protect') == '1') { - session_start(); - if (!isset($_SESSION['connected'])) { - $_SESSION['connected'] = 0; - } - } - - $response = new Response('application/xml;charset=utf-8'); - - $OPDSRender = new OpdsRenderer($request, $response); - - switch ($page) { - case PageId::OPENSEARCH : - case PageId::SEARCH : - $response->sendData($OPDSRender->getOpenSearch($request)); - return; - default: - $currentPage = PageId::getPage($page, $request); - $response->sendData($OPDSRender->render($currentPage, $request)); - return; - } - } -} diff --git a/COPS/cops-3.1.3/src/Handlers/FetchHandler.php b/COPS/cops-3.1.3/src/Handlers/FetchHandler.php deleted file mode 100644 index 7315a690..00000000 --- a/COPS/cops-3.1.3/src/Handlers/FetchHandler.php +++ /dev/null @@ -1,235 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Handlers; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Request; -use SebLucas\Cops\Calibre\Book; -use SebLucas\Cops\Calibre\Cover; -use SebLucas\Cops\Calibre\Data; -use SebLucas\Cops\Output\FileResponse; -use SebLucas\Cops\Output\Response; -use SebLucas\Cops\Output\Zipper; - -/** - * Fetch book covers or files - * URL format: index.php/fetch?id={bookId}&type={type}&data={idData}&view={viewOnly} - * or index.php/fetch?id={bookId}&thumb={thumb} for book cover thumbnails - * or index.php/fetch?id={bookId}&file={file} for extra data file for this book - */ -class FetchHandler extends BaseHandler -{ - public const HANDLER = "fetch"; - - public static function getRoutes() - { - // check if the path starts with the endpoint param or not here - return [ - // support custom pattern for route placeholders - see nikic/fast-route - "/files/{db:\d+}/{id:\d+}/{file:.+}" => [static::PARAM => static::HANDLER], - "/thumbs/{thumb}/{db:\d+}/{id:\d+}.jpg" => [static::PARAM => static::HANDLER], - "/covers/{db:\d+}/{id:\d+}.jpg" => [static::PARAM => static::HANDLER], - "/inline/{db:\d+}/{data:\d+}/{ignore}.{type}" => [static::PARAM => static::HANDLER, "view" => 1], - "/fetch/{db:\d+}/{data:\d+}/{ignore}.{type}" => [static::PARAM => static::HANDLER], - // @todo handle url rewriting if enabled separately - path parameters are different - "/view/{data}/{db}/{ignore}.{type}" => [static::PARAM => static::HANDLER, "view" => 1], - "/view/{data}/{ignore}.{type}" => [static::PARAM => static::HANDLER, "view" => 1], - "/download/{data}/{db}/{ignore}.{type}" => [static::PARAM => static::HANDLER], - "/download/{data}/{ignore}.{type}" => [static::PARAM => static::HANDLER], - ]; - } - - /** - * Summary of handle - * @param Request $request - * @return void - */ - public function handle($request) - { - if (Config::get('fetch_protect') == '1') { - session_start(); - if (!isset($_SESSION['connected'])) { - // this will call exit() - Response::notFound($request); - } - } - // clean output buffers before sending the ebook data do avoid high memory usage on big ebooks (ie. comic books) - if (ob_get_length() !== false && $request->getHandler() !== 'phpunit') { - ob_end_clean(); - } - - $bookId = $request->getId(); - $type = $request->get('type', 'jpg'); - $idData = $request->getId('data'); - $viewOnly = $request->get('view', false); - $database = $request->database(); - $file = $request->get('file'); - - if (is_null($bookId)) { - $book = Book::getBookByDataId($idData, $database); - } else { - $book = Book::getBookById($bookId, $database); - } - - if (!$book) { - // this will call exit() - Response::notFound($request); - } - - if (!empty($file)) { - $this->sendExtraFile($request, $book, $file); - return; - } - - // -DC- Add png type - if (in_array($type, ['jpg', 'png'])) { - $this->sendThumbnail($request, $book, $type); - return; - } - - if (!$viewOnly && $type == 'epub' && Config::get('update_epub-metadata')) { - $this->sendUpdatedEpub($request, $book, $idData); - return; - } - - $data = $book->getDataById($idData); - // absolute path for single DB in PHP app here - cfr. internal dir for X-Accel-Redirect with Nginx - $file = $book->getFilePath($type, $idData); - - if ($viewOnly) { - // disposition inline here - $response = new FileResponse($data->getMimeType(), 0, ''); - $response->sendFile($file); - return; - } - - if ($type == 'epub' && Config::get('provide_kepub') == '1' && preg_match('/Kobo/', $request->agent())) { - $this->sendConvertedKepub($book, $file, $data); - return; - } - - $response = new FileResponse($data->getMimeType(), 0, basename($file)); - $response->sendFile($file); - } - - /** - * Summary of sendExtraFile - * @param Request $request - * @param Book $book - * @param string $file - * @return FileResponse|Zipper - */ - public function sendExtraFile($request, $book, $file) - { - if ($file == 'zipped') { - // zip all extra files and send back - return $this->zipExtraFiles($request, $book); - } - $extraFiles = $book->getExtraFiles(); - if (!in_array($file, $extraFiles)) { - // this will call exit() - Response::notFound($request); - } - // send back extra file - $filepath = $book->path . '/' . Book::DATA_DIR_NAME . '/' . $file; - if (!file_exists($filepath)) { - // this will call exit() - Response::notFound($request); - } - $mimetype = Response::getMimeType($filepath); - $response = new FileResponse($mimetype, 0, basename($filepath)); - return $response->sendFile($filepath); - } - - /** - * Summary of zipExtraFiles - * @param Request $request - * @param Book $book - * @return Zipper - */ - public function zipExtraFiles($request, $book) - { - $zipper = new Zipper($request); - - if ($zipper->isValidForExtraFiles($book)) { - $sendHeaders = headers_sent() ? false : true; - // disable nginx buffering by default - if ($sendHeaders) { - header('X-Accel-Buffering: no'); - } - return $zipper->download(null, $sendHeaders); - } else { - Response::sendError($request, "Invalid zipped: " . $zipper->getMessage()); - } - } - - /** - * Summary of sendThumbnail - * @param Request $request - * @param Book $book - * @param string $type - * @return FileResponse - */ - public function sendThumbnail($request, $book, $type) - { - $file = $book->getCoverFilePath($type); - if (empty($file) || !file_exists($file)) { - // this will call exit() - Response::notFound($request); - } - $cover = new Cover($book); - // create empty file response to start with!? - $response = new FileResponse(); - return $cover->sendThumbnail($request, $response); - } - - /** - * Summary of sendUpdatedEpub - * @param Request $request - * @param Book $book - * @param mixed $idData - * @return FileResponse - */ - public function sendUpdatedEpub($request, $book, $idData) - { - // update epub metadata + provide kepub if needed (with update of opf properties for cover-image in EPub) - if (Config::get('provide_kepub') == '1' && preg_match('/Kobo/', $request->agent())) { - $book->updateForKepub = true; - } - // create empty response to start with!? - $response = new FileResponse(); - // this will also use kepubify_path internally if defined - return $book->sendUpdatedEpub($idData, $response); - } - - /** - * Summary of sendConvertedKepub - * @param Book $book - * @param string $file - * @param Data $data - * @return FileResponse - */ - public function sendConvertedKepub($book, $file, $data) - { - // run kepubify on original Epub file and send converted tmpfile - if (!empty(Config::get('kepubify_path'))) { - // @todo no cache control here!? - $response = new FileResponse($data->getMimeType(), null, basename($data->getUpdatedFilenameKepub())); - $result = $book->runKepubify($file, $response); - if (empty($result)) { - Response::sendError(null, 'Error: failed to convert epub file'); - } - return $result; - } - // provide kepub in name only (without update of opf properties for cover-image in Epub) - $response = new FileResponse($data->getMimeType(), 0, basename($data->getUpdatedFilenameKepub())); - return $response->sendFile($file); - } -} diff --git a/COPS/cops-3.1.3/src/Handlers/GraphQLHandler.php b/COPS/cops-3.1.3/src/Handlers/GraphQLHandler.php deleted file mode 100644 index c0640476..00000000 --- a/COPS/cops-3.1.3/src/Handlers/GraphQLHandler.php +++ /dev/null @@ -1,345 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Handlers; - -use SebLucas\Cops\Calibre\Author; -use SebLucas\Cops\Calibre\BaseList; -use SebLucas\Cops\Calibre\Book; -use SebLucas\Cops\Calibre\BookList; -use SebLucas\Cops\Calibre\Identifier; -use SebLucas\Cops\Calibre\Language; -use SebLucas\Cops\Calibre\Publisher; -use SebLucas\Cops\Calibre\Rating; -use SebLucas\Cops\Calibre\Serie; -use SebLucas\Cops\Calibre\Tag; -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Context; -use SebLucas\Cops\Input\Request; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Output\Format; -use SebLucas\Cops\Output\Response; -use GraphQL\GraphQL; -use GraphQL\Utils\BuildSchema; -use GraphQL\Language\AST\TypeDefinitionNode; -use GraphQL\Type\Definition\ResolveInfo; -use GraphQL\Executor\Executor; -use GraphQL\Error\DebugFlag; - -/** - * Summary of GraphQLHandler - */ -class GraphQLHandler extends BaseHandler -{ - public const HANDLER = "graphql"; - public const DEBUG = DebugFlag::INCLUDE_DEBUG_MESSAGE; - - public static function getRoutes() - { - return [ - "/graphql" => [static::PARAM => static::HANDLER], - ]; - } - - /** - * Summary of handle - * @param Request $request - * @return void - */ - public function handle($request) - { - if ($request->method() !== 'POST') { - $this->renderPlayground(); - return; - } - - // override splitting authors and books by first letter here? - Config::set('author_split_first_letter', '0'); - Config::set('titles_split_first_letter', '0'); - //Config::set('titles_split_publication_year', '0'); - // @todo override pagination - Config::set('max_item_per_page', 100); - - $result = $this->runQuery($request); - - $response = new Response('application/json;charset=utf-8'); - $response->sendData(json_encode($result)); - } - - /** - * Summary of runQuery - * @param Request $request - * @return array - */ - public function runQuery($request) - { - $input = json_decode((string) $request->content(), true); - - $schema = $this->getSchema($request); - - $queryString = $input['query']; - $rootValue = 'query'; - // @see https://github.com/webonyx/graphql-php/blob/master/examples/02-schema-definition-language/graphql.php - // use $rootValue to resolve query fields - //$rootValue = $this->getFieldResolvers($request); - $context = new Context($request); - $variableValues = $input['variables'] ?? null; - $operationName = $input['operationName'] ?? null; - //$fieldResolver = $this->getFieldResolver($request, $resolvers); - //$validationRules = []; - - $result = GraphQL::executeQuery( - $schema, - $queryString, - $rootValue, - $context, - $variableValues, - $operationName, - $fieldResolver = null, - $validationRules = null - ); - //$result = array_merge($result->toArray(), ['input' => $input]); - - return $result->toArray(static::DEBUG); - } - - /** - * Summary of getSchema - * @phpstan-import-type TypeConfigDecorator from \GraphQL\Utils\ASTDefinitionBuilder - * @param Request $request - * @return \GraphQL\Type\Schema - */ - public function getSchema($request) - { - $resolvers = $this->mapTypeFieldResolvers(); - - $typeConfigDecorator = function (array $typeConfig, TypeDefinitionNode $typeDefinitionNode) use ($resolvers, $request) { - $name = $typeConfig['name']; - // ... add missing options to $typeConfig based on type $name - if (empty($typeConfig['resolveField']) && !empty($resolvers[$name])) { - $typeConfig['resolveField'] = $resolvers[$name]($request); - } - return $typeConfig; - }; - - $contents = file_get_contents(dirname(__DIR__, 2) . '/schema.graphql'); - //$schema = BuildSchema::build($contents); - $schema = BuildSchema::build($contents, $typeConfigDecorator); - - return $schema; - } - - /** - * Summary of mapTypeFieldResolvers - * @return array - */ - public function mapTypeFieldResolvers() - { - return [ - 'Query' => $this->getQueryFieldResolver(...), - 'Entry' => $this->getEntryFieldResolver(...), - 'EntryBook' => $this->getEntryBookFieldResolver(...), - ]; - } - - /** - * Summary of getQueryFieldResolver - * @param Request $request - * @return callable - */ - public function getQueryFieldResolver($request) - { - $resolver = static function ($objectValue, array $args, $context, ResolveInfo $info) use ($request) { - $fieldName = $info->fieldName; - switch ($fieldName) { - case 'books': - $booklist = new BookList($request); - [$entryArray, $totalNumber] = $booklist->getAllBooks(); - return $entryArray; - case 'book': - $book = Book::getBookById($args['id'], $request->database()); - if (is_null($book)) { - return $book; - } - $book->setHandler("index"); - return $book->getEntry(); - case 'datas': - $book = Book::getBookById($args['bookId'], $request->database()); - if (is_null($book)) { - return $book; - } - $book->setHandler("index"); - return $book->getDatas(); - case 'data': - $book = Book::getBookByDataId($args['id'], $request->database()); - if (is_null($book)) { - return $book; - } - $data = $book->datas[0]; - return $data; - case 'authors': - $baselist = new BaseList(Author::class, $request); - $entryArray = $baselist->getRequestEntries(); - return $entryArray; - case 'author': - $instance = Author::getInstanceById($args['id'], $request->database()); - $instance->setHandler("index"); - return $instance->getEntry(); - case 'identifiers': - $baselist = new BaseList(Identifier::class, $request); - $entryArray = $baselist->getRequestEntries(); - return $entryArray; - case 'identifier': - $instance = Identifier::getInstanceById($args['id'], $request->database()); - $instance->setHandler("index"); - return $instance->getEntry(); - case 'languages': - $baselist = new BaseList(Language::class, $request); - $entryArray = $baselist->getRequestEntries(); - return $entryArray; - case 'language': - $instance = Language::getInstanceById($args['id'], $request->database()); - $instance->setHandler("index"); - return $instance->getEntry(); - case 'publishers': - $baselist = new BaseList(Publisher::class, $request); - $entryArray = $baselist->getRequestEntries(); - return $entryArray; - case 'publisher': - $instance = Publisher::getInstanceById($args['id'], $request->database()); - $instance->setHandler("index"); - return $instance->getEntry(); - case 'ratings': - $baselist = new BaseList(Rating::class, $request); - $entryArray = $baselist->getRequestEntries(); - return $entryArray; - case 'rating': - $instance = Rating::getInstanceById($args['id'], $request->database()); - $instance->setHandler("index"); - return $instance->getEntry(); - case 'series': - $baselist = new BaseList(Serie::class, $request); - $entryArray = $baselist->getRequestEntries(); - return $entryArray; - case 'serie': - $instance = Serie::getInstanceById($args['id'], $request->database()); - $instance->setHandler("index"); - return $instance->getEntry(); - case 'tags': - $baselist = new BaseList(Tag::class, $request); - $entryArray = $baselist->getRequestEntries(); - return $entryArray; - case 'tag': - $instance = Tag::getInstanceById($args['id'], $request->database()); - $instance->setHandler("index"); - return $instance->getEntry(); - } - return Executor::defaultFieldResolver($objectValue, $args, $context, $info); - }; - return $resolver; - } - - /** - * Summary of getEntryFieldResolver - * @param Request $request - * @return callable - */ - public function getEntryFieldResolver($request) - { - $resolver = static function ($objectValue, array $args, $context, ResolveInfo $info) use ($request) { - $fieldName = $info->fieldName; - switch ($fieldName) { - case 'books': - // @todo get books for parent instance(s) - $instance = $objectValue->instance; - $booklist = new BookList($request); - [$entryArray, $totalNumber] = $booklist->getBooksByInstance($instance, 1); - return $entryArray; - } - return Executor::defaultFieldResolver($objectValue, $args, $context, $info); - }; - return $resolver; - } - - /** - * Summary of getEntryBookFieldResolver - * @param Request $request - * @return callable - */ - public function getEntryBookFieldResolver($request) - { - $resolver = static function ($objectValue, array $args, $context, ResolveInfo $info) use ($request) { - $fieldName = $info->fieldName; - //if (is_object($objectValue) && isset($objectValue->{$fieldName})) { - // return $objectValue->{$fieldName}; - //} - // coming from Data - if ($objectValue instanceof Book) { - $objectValue = $objectValue->getEntry(); - } - /** @var Book $book */ - $book = $objectValue->book; - switch ($fieldName) { - case 'path': - return $book->path; - case 'authors': - $authors = $book->getAuthors(); - $entryArray = []; - foreach ($authors as $author) { - array_push($entryArray, $author->getEntry()); - } - return $entryArray; - case 'datas': - $datas = $book->getDatas(); - return $datas; - case 'identifiers': - $identifiers = $book->getIdentifiers(); - $entryArray = []; - foreach ($identifiers as $identifier) { - array_push($entryArray, $identifier->getEntry()); - } - return $entryArray; - case 'languages': - $languages = $book->getLanguages(); - return $languages; - case 'publisher': - $publisher = $book->getPublisher(); - return $publisher->getEntry(); - case 'rating': - $rating = $book->getRating(); - return $rating; - case 'serie': - $serie = $book->getSerie(); - return $serie->getEntry(); - case 'tags': - $tags = $book->getTags(); - $entryArray = []; - foreach ($tags as $tag) { - array_push($entryArray, $tag->getEntry()); - } - return $entryArray; - } - return Executor::defaultFieldResolver($objectValue, $args, $context, $info); - }; - return $resolver; - } - - /** - * Render GraphQL Playground - * @return void - */ - public function renderPlayground() - { - $data = ['link' => Route::link(static::HANDLER)]; - $template = dirname(__DIR__, 2) . '/templates/graphql.html'; - - $response = new Response('text/html;charset=utf-8'); - $response->sendData(Format::template($data, $template)); - } -} diff --git a/COPS/cops-3.1.3/src/Handlers/HtmlHandler.php b/COPS/cops-3.1.3/src/Handlers/HtmlHandler.php deleted file mode 100644 index 225723b1..00000000 --- a/COPS/cops-3.1.3/src/Handlers/HtmlHandler.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Handlers; - -use SebLucas\Cops\Calibre\Database; -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Output\HtmlRenderer; -use SebLucas\Cops\Output\Response; -use SebLucas\Cops\Pages\PageId; -use Throwable; - -/** - * HTML main handler - * URL format: index.php?page={page}&... - */ -class HtmlHandler extends PageHandler -{ - public const HANDLER = "index"; - - public static function getRoutes() - { - return parent::getRoutes(); - } - - public function handle($request) - { - // If we detect that an OPDS reader try to connect try to redirect to feed.php - if (preg_match('/(Librera|MantanoReader|FBReader|Stanza|Marvin|Aldiko|Moon\+ Reader|Chunky|AlReader|EBookDroid|BookReader|CoolReader|PageTurner|books\.ebook\.pdf\.reader|com\.hiwapps\.ebookreader|OpenBook)/', $request->agent())) { - Response::redirect(Route::link("feed", null, ["db" => $request->database()])); - return; - } - - $page = $request->get('page'); - $database = $request->database(); - - // Use the configured home page if needed - if (!isset($page)) { - $page = PageId::getHomePage(); - $request->set('page', $page); - } - - // Access the database ASAP to be sure it's readable, redirect if that's not the case. - // It has to be done before any header is sent. - Database::checkDatabaseAvailability($database); - - if (Config::get('fetch_protect') == '1') { - session_start(); - if (!isset($_SESSION['connected'])) { - $_SESSION['connected'] = 0; - } - } - - $response = new Response('text/html;charset=utf-8'); - - $html = new HtmlRenderer($request, $response); - - try { - $response->sendData($html->render($request)); - } catch (Throwable $e) { - error_log($e); - Response::sendError($request, $e->getMessage()); - } - } -} diff --git a/COPS/cops-3.1.3/src/Handlers/JsonHandler.php b/COPS/cops-3.1.3/src/Handlers/JsonHandler.php deleted file mode 100644 index 6f2fc61c..00000000 --- a/COPS/cops-3.1.3/src/Handlers/JsonHandler.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Handlers; - -use SebLucas\Cops\Output\JsonRenderer; -use SebLucas\Cops\Output\Response; -use Throwable; - -/** - * Handle JSON ajax requests - * URL format: index.php?page={page}&... - * with Accept: application/json or X-Requested-With: XMLHttpRequest - */ -class JsonHandler extends PageHandler -{ - public const HANDLER = "json"; - - public static function getRoutes() - { - // same routes as HtmlHandler - see util.js - //return parent::getRoutes(); - return []; - } - - public function handle($request) - { - $response = new Response('application/json;charset=utf-8'); - - $json = new JsonRenderer($request, $response); - - try { - $response->sendData(json_encode($json->getJson($request))); - } catch (Throwable $e) { - error_log($e); - Response::sendError($request, $e->getMessage()); - } - } -} diff --git a/COPS/cops-3.1.3/src/Handlers/LoaderHandler.php b/COPS/cops-3.1.3/src/Handlers/LoaderHandler.php deleted file mode 100644 index 7c2b9a72..00000000 --- a/COPS/cops-3.1.3/src/Handlers/LoaderHandler.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Handlers; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Output\Response; -use Marsender\EPubLoader\RequestHandler; -use Marsender\EPubLoader\App\ExtraActions; - -/** - * Summary of LoaderHandler - */ -class LoaderHandler extends BaseHandler -{ - public const HANDLER = "loader"; - - public static function getRoutes() - { - return [ - "/loader/{action}/{dbNum:\d+}/{authorId:\d+}" => [static::PARAM => static::HANDLER], - "/loader/{action}/{dbNum:\d+}" => [static::PARAM => static::HANDLER], - "/loader/{action}/" => [static::PARAM => static::HANDLER], - "/loader/{action}" => [static::PARAM => static::HANDLER], - "/loader" => [static::PARAM => static::HANDLER], - ]; - } - - public function handle($request) - { - // get the global config for epub-loader from config/loader.php - $gConfig = require dirname(__DIR__, 2) . '/config/loader.php'; - // adapt for use with COPS - $gConfig['endpoint'] = Route::link('loader'); - $gConfig['app_name'] = 'COPS Loader'; - $gConfig['version'] = Config::VERSION; - $gConfig['admin_email'] = ''; - $gConfig['create_db'] = false; - $gConfig['databases'] = []; - - // specify a cache directory for any Google or Wikidata lookup - $cacheDir = $gConfig['cache_dir'] ?? 'tests/cache'; - if (!is_dir($cacheDir) && !mkdir($cacheDir, 0o777, true)) { - echo 'Please make sure the cache directory can be created'; - return; - } - if (!is_writable($cacheDir)) { - echo 'Please make sure the cache directory is writeable'; - return; - } - - // get the current COPS calibre directories - $calibreDir = Config::get('calibre_directory'); - if (!is_array($calibreDir)) { - $calibreDir = ['COPS Database' => $calibreDir]; - } - foreach ($calibreDir as $name => $path) { - $gConfig['databases'][] = ['name' => $name, 'db_path' => rtrim((string) $path, '/'), 'epub_path' => '.']; - } - - $action = $request->get('action'); - $dbNum = $request->getId('dbNum'); - $itemId = $request->getId('authorId'); - - $urlParams = $request->urlParams; - - // you can define extra actions for your app - see example.php - $handler = new RequestHandler($gConfig, ExtraActions::class, $cacheDir); - $result = $handler->request($action, $dbNum, $urlParams); - - if (method_exists($handler, 'isDone')) { - if ($handler->isDone()) { - return; - } - } - - // handle the result yourself or let epub-loader generate the output - $result = array_merge($gConfig, $result); - //$templateDir = 'templates/twigged/loader'; // if you want to use custom templates - $templateDir = null; - $template = null; - - $response = new Response('text/html;charset=utf-8'); - $response->sendData($handler->output($result, $templateDir, $template)); - } -} diff --git a/COPS/cops-3.1.3/src/Handlers/MailHandler.php b/COPS/cops-3.1.3/src/Handlers/MailHandler.php deleted file mode 100644 index 6b933df1..00000000 --- a/COPS/cops-3.1.3/src/Handlers/MailHandler.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Handlers; - -use SebLucas\Cops\Output\Mail; -use SebLucas\Cops\Output\Response; - -/** - * Send books by email - * URL format: index.php/mail (POST data and email) - */ -class MailHandler extends BaseHandler -{ - public const HANDLER = "mail"; - - public static function getRoutes() - { - return [ - "/mail" => [static::PARAM => static::HANDLER], - ]; - } - - public function handle($request) - { - // set request handler to 'phpunit' to run preSend() but not actually Send() - $dryRun = ($request->getHandler() === 'phpunit') ? true : false; - - $mailer = new Mail(); - - if ($error = $mailer->checkConfiguration()) { - // this will call exit() - Response::sendError($request, $error); - } - - $idData = (int) $request->post("data"); - $emailDest = $request->post("email"); - if ($error = $mailer->checkRequest($idData, $emailDest)) { - // this will call exit() - Response::sendError($request, $error); - } - - if ($error = $mailer->sendMail($idData, $emailDest, $request, $dryRun)) { - $response = new Response('text/plain'); - $response->sendData(localize("mail.messagenotsent") . $error); - return; - } - - $response = new Response('text/plain'); - $response->sendData(localize("mail.messagesent")); - } -} diff --git a/COPS/cops-3.1.3/src/Handlers/OpdsHandler.php b/COPS/cops-3.1.3/src/Handlers/OpdsHandler.php deleted file mode 100644 index a334135a..00000000 --- a/COPS/cops-3.1.3/src/Handlers/OpdsHandler.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Handlers; - -use SebLucas\Cops\Input\Config; -//use SebLucas\Cops\Output\OpdsRenderer; -use SebLucas\Cops\Output\KiwilanOPDS as OpdsRenderer; -use SebLucas\Cops\Pages\PageId; - -/** - * Handle OPDS 2.0 feed (dev only) - * URL format: index.php/opds{/route}?query={query} etc. - */ -class OpdsHandler extends BaseHandler -{ - public const HANDLER = "opds"; - - public static function getRoutes() - { - return [ - "/opds/{page}/{id}" => [static::PARAM => static::HANDLER], - "/opds/{page}" => [static::PARAM => static::HANDLER], - "/opds" => [static::PARAM => static::HANDLER], - ]; - } - - public function handle($request) - { - $page = $request->get('page', PageId::INDEX); - $query = $request->get('query'); // 'q' by default for php-opds - if ($query) { - $page = PageId::OPENSEARCH_QUERY; - } - - if (Config::get('fetch_protect') == '1') { - session_start(); - if (!isset($_SESSION['connected'])) { - $_SESSION['connected'] = 0; - } - } - - $OPDSRender = new OpdsRenderer(); - - switch ($page) { - case PageId::OPENSEARCH : - case PageId::SEARCH : - $response = $OPDSRender->getOpenSearch($request); - break; - default: - $currentPage = PageId::getPage($page, $request); - $response = $OPDSRender->render($currentPage, $request); - } - - foreach ($response->getHeaders() as $type => $value) { - header($type . ': ' . $value); - } - http_response_code($response->getStatus()); - - echo $response->getContents(); - } -} diff --git a/COPS/cops-3.1.3/src/Handlers/PageHandler.php b/COPS/cops-3.1.3/src/Handlers/PageHandler.php deleted file mode 100644 index 2d38319f..00000000 --- a/COPS/cops-3.1.3/src/Handlers/PageHandler.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Handlers; - -use SebLucas\Cops\Pages\PageId; - -/** - * Generic page handler extended by HtmlHandler and JsonHandler - * URL format: ...?page={page}&... - */ -class PageHandler extends BaseHandler -{ - public static function getRoutes() - { - // Format: route => page, or route => [page => page, fixed => 1, ...] with fixed params - return [ - "/index" => PageId::INDEX, - "/authors/letter/{id}" => PageId::AUTHORS_FIRST_LETTER, - "/authors/letter" => ["page" => PageId::ALL_AUTHORS, "letter" => 1], - "/authors/{id}/{title}" => PageId::AUTHOR_DETAIL, - "/authors/{id}" => PageId::AUTHOR_DETAIL, - "/authors" => PageId::ALL_AUTHORS, - "/books/letter/{id}" => PageId::ALL_BOOKS_LETTER, - "/books/letter" => ["page" => PageId::ALL_BOOKS, "letter" => 1], - "/books/year/{id}" => PageId::ALL_BOOKS_YEAR, - "/books/year" => ["page" => PageId::ALL_BOOKS, "year" => 1], - "/books/{id}/{author}/{title}" => PageId::BOOK_DETAIL, - "/books/{id}" => PageId::BOOK_DETAIL, - "/books" => PageId::ALL_BOOKS, - "/series/{id}/{title}" => PageId::SERIE_DETAIL, - "/series/{id}" => PageId::SERIE_DETAIL, - "/series" => PageId::ALL_SERIES, - "/query/{query}/{scope}" => ["page" => PageId::OPENSEARCH_QUERY, "search" => 1], - "/query/{query}" => ["page" => PageId::OPENSEARCH_QUERY, "search" => 1], - "/search/{query}/{scope}" => PageId::OPENSEARCH_QUERY, - "/search/{query}" => PageId::OPENSEARCH_QUERY, - "/search" => PageId::OPENSEARCH, - "/recent" => PageId::ALL_RECENT_BOOKS, - "/tags/{id}/{title}" => PageId::TAG_DETAIL, - "/tags/{id}" => PageId::TAG_DETAIL, - "/tags" => PageId::ALL_TAGS, - "/custom/{custom}/{id}" => PageId::CUSTOM_DETAIL, - "/custom/{custom}" => PageId::ALL_CUSTOMS, - "/about" => PageId::ABOUT, - "/languages/{id}/{title}" => PageId::LANGUAGE_DETAIL, - "/languages/{id}" => PageId::LANGUAGE_DETAIL, - "/languages" => PageId::ALL_LANGUAGES, - "/customize" => PageId::CUSTOMIZE, - "/publishers/{id}/{title}" => PageId::PUBLISHER_DETAIL, - "/publishers/{id}" => PageId::PUBLISHER_DETAIL, - "/publishers" => PageId::ALL_PUBLISHERS, - "/ratings/{id}/{title}" => PageId::RATING_DETAIL, - "/ratings/{id}" => PageId::RATING_DETAIL, - "/ratings" => PageId::ALL_RATINGS, - "/identifiers/{id}/{title}" => PageId::IDENTIFIER_DETAIL, - "/identifiers/{id}" => PageId::IDENTIFIER_DETAIL, - "/identifiers" => PageId::ALL_IDENTIFIERS, - "/libraries" => PageId::ALL_LIBRARIES, - ]; - } - - public function handle($request) - { - // ... - } -} diff --git a/COPS/cops-3.1.3/src/Handlers/QueueBasedHandler.php b/COPS/cops-3.1.3/src/Handlers/QueueBasedHandler.php deleted file mode 100644 index 4dfa5241..00000000 --- a/COPS/cops-3.1.3/src/Handlers/QueueBasedHandler.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Handlers; - -use SebLucas\Cops\Input\Request; -use SebLucas\Cops\Output\Response; - -/** - * Basic middleware dispatcher (FIFO queue) - * This is mainly useful for request middleware, not response middleware, - * since most COPS request handlers already finish sending the response - * @see https://www.php-fig.org/psr/psr-15/meta/#queue-based-request-handler - */ -class QueueBasedHandler extends BaseHandler -{ - /** @var BaseHandler */ - protected $handler; - /** @var array */ - protected $queue = []; - - /** - * Set final request handler - * @param BaseHandler $handler - */ - public function __construct($handler) - { - $this->handler = $handler; - } - - /** - * Add middleware to queue (FIFO) - * @param mixed $middleware - * @return void - */ - public function add($middleware) - { - $this->queue[] = $middleware; - } - - /** - * Process next middleware in queue or call final handler - * @param Request $request - * @return Response - */ - public function handle($request) - { - if (empty($this->queue)) { - // @todo most handlers already finish sending response - return $this->handler->handle($request); - } - // @todo support other __invoke, callable etc. middleware - $middleware = array_shift($this->queue); - return $middleware->process($request, $this); - } -} diff --git a/COPS/cops-3.1.3/src/Handlers/ReadHandler.php b/COPS/cops-3.1.3/src/Handlers/ReadHandler.php deleted file mode 100644 index a73177f5..00000000 --- a/COPS/cops-3.1.3/src/Handlers/ReadHandler.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Handlers; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Output\EPubReader; -use SebLucas\Cops\Output\Response; -use Exception; - -/** - * Handle epub reader with monocle - * URL format: index.php/read?data={idData}&version={version} - */ -class ReadHandler extends BaseHandler -{ - public const HANDLER = "read"; - - public static function getRoutes() - { - return [ - "/read/{db:\d+}/{data:\d+}/{title}" => [static::PARAM => static::HANDLER], - "/read/{db:\d+}/{data:\d+}" => [static::PARAM => static::HANDLER], - ]; - } - - public function handle($request) - { - $idData = $request->getId('data'); - if (empty($idData)) { - // this will call exit() - Response::notFound($request); - } - $version = $request->get('version', Config::get('epub_reader', 'monocle')); - $database = $request->database(); - - $response = new Response('text/html;charset=utf-8'); - - $reader = new EPubReader($request, $response); - - try { - $response->sendData($reader->getReader($idData, $version, $database)); - } catch (Exception $e) { - error_log($e); - Response::sendError($request, $e->getMessage()); - } - } -} diff --git a/COPS/cops-3.1.3/src/Handlers/RestApiHandler.php b/COPS/cops-3.1.3/src/Handlers/RestApiHandler.php deleted file mode 100644 index c821a65a..00000000 --- a/COPS/cops-3.1.3/src/Handlers/RestApiHandler.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Handlers; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Output\Format; -use SebLucas\Cops\Output\Response; -use SebLucas\Cops\Output\RestApi; -use Exception; - -/** - * Handle REST API - * URL format: index.php/restapi{/route}?db={db} etc. - */ -class RestApiHandler extends BaseHandler -{ - public const HANDLER = "restapi"; - - public static function getRoutes() - { - // Note: this supports all other routes with /restapi prefix - // extra routes supported by REST API - return [ - // add default routes for handler to generate links - "/restapi/{route:.*}" => [static::PARAM => static::HANDLER], - "/restapi" => [static::PARAM => static::HANDLER], - "/custom" => [static::PARAM => static::HANDLER], - "/databases/{db}/{name}" => [static::PARAM => static::HANDLER], - "/databases/{db}" => [static::PARAM => static::HANDLER], - "/databases" => [static::PARAM => static::HANDLER], - "/openapi" => [static::PARAM => static::HANDLER], - "/routes" => [static::PARAM => static::HANDLER], - "/pages" => [static::PARAM => static::HANDLER], - "/notes/{type}/{id}/{title}" => [static::PARAM => static::HANDLER], - "/notes/{type}/{id}" => [static::PARAM => static::HANDLER], - "/notes/{type}" => [static::PARAM => static::HANDLER], - "/notes" => [static::PARAM => static::HANDLER], - "/preferences/{key}" => [static::PARAM => static::HANDLER], - "/preferences" => [static::PARAM => static::HANDLER], - "/annotations/{bookId}/{id}" => [static::PARAM => static::HANDLER], - "/annotations/{bookId}" => [static::PARAM => static::HANDLER], - "/annotations" => [static::PARAM => static::HANDLER], - "/metadata/{bookId}/{element}/{name}" => [static::PARAM => static::HANDLER], - "/metadata/{bookId}/{element}" => [static::PARAM => static::HANDLER], - "/metadata/{bookId}" => [static::PARAM => static::HANDLER], - "/user/details" => [static::PARAM => static::HANDLER], - "/user" => [static::PARAM => static::HANDLER], - ]; - } - - public function handle($request) - { - // override splitting authors and books by first letter here? - Config::set('author_split_first_letter', '0'); - Config::set('titles_split_first_letter', '0'); - //Config::set('titles_split_publication_year', '0'); - - $path = $request->path(); - if (empty($path) || $path == '/restapi/') { - $data = ['link' => Route::link(static::HANDLER, null, ['route' => 'openapi'])]; - $template = dirname(__DIR__, 2) . '/templates/restapi.html'; - - $response = new Response('text/html;charset=utf-8'); - $response->sendData(Format::template($data, $template)); - return; - } - - $response = new Response('application/json;charset=utf-8'); - - $apiHandler = new RestApi($request, $response); - - try { - $response->sendData($apiHandler->getOutput()); - } catch (Exception $e) { - $response->sendData(json_encode(["Exception" => $e->getMessage()])); - } - } -} diff --git a/COPS/cops-3.1.3/src/Handlers/ZipFsHandler.php b/COPS/cops-3.1.3/src/Handlers/ZipFsHandler.php deleted file mode 100644 index e145cca3..00000000 --- a/COPS/cops-3.1.3/src/Handlers/ZipFsHandler.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Handlers; - -use SebLucas\Cops\Output\EPubReader; -use SebLucas\Cops\Output\Response; -use Exception; - -/** - * Handle Epub filesystem for epubjs-reader - * URL format: index.php/zipfs/{db}/{data}/{comp} - */ -class ZipFsHandler extends BaseHandler -{ - public const HANDLER = "zipfs"; - - public static function getRoutes() - { - // support custom pattern for route placeholders - see nikic/fast-route - return [ - "/zipfs/{db:\d+}/{data:\d+}/{comp:.+}" => [static::PARAM => static::HANDLER], - ]; - } - - public function handle($request) - { - if (php_sapi_name() === 'cli' && $request->getHandler() !== 'phpunit') { - return; - } - - //$database = $request->getId('db'); - $idData = $request->getId('data'); - if (empty($idData)) { - // this will call exit() - Response::notFound($request); - } - $component = $request->get('comp'); - if (empty($component)) { - // this will call exit() - Response::notFound($request); - } - $database = $request->database(); - - // create empty response to start with!? - $response = new Response(); - - $reader = new EPubReader($request, $response); - - try { - $reader->sendZipContent($idData, $component, $database); - - } catch (Exception $e) { - error_log($e); - Response::sendError($request, $e->getMessage()); - } - } -} diff --git a/COPS/cops-3.1.3/src/Handlers/ZipperHandler.php b/COPS/cops-3.1.3/src/Handlers/ZipperHandler.php deleted file mode 100644 index 65a73adc..00000000 --- a/COPS/cops-3.1.3/src/Handlers/ZipperHandler.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Handlers; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Output\Response; -use SebLucas\Cops\Output\Zipper; - -/** - * Download all books for a page, series or author by format (epub, mobi, any, ...) - * URL format: index.php/zipper?page={page}&type={type}&id={id} - */ -class ZipperHandler extends BaseHandler -{ - public const HANDLER = "zipper"; - - public static function getRoutes() - { - // handle endpoint with page param - return [ - "/zipper/{page}/{type}/{id}" => [static::PARAM => static::HANDLER], - "/zipper/{page}/{type}" => [static::PARAM => static::HANDLER], - "/zipper/{page}" => [static::PARAM => static::HANDLER], - ]; - } - - public function handle($request) - { - if (empty(Config::get('download_page')) && - empty(Config::get('download_series')) && - empty(Config::get('download_author')) - ) { - // this will call exit() - Response::sendError($request, 'Downloads by page, series or author are disabled in config'); - } - if (Config::get('fetch_protect') == '1') { - session_start(); - if (!isset($_SESSION['connected'])) { - // this will call exit() - Response::notFound($request); - } - } - - $zipper = new Zipper($request); - - if ($zipper->isValidForDownload()) { - $sendHeaders = headers_sent() ? false : true; - // disable nginx buffering by default - if ($sendHeaders) { - header('X-Accel-Buffering: no'); - } - $zipper->download(null, $sendHeaders); - } else { - Response::sendError($request, "Invalid download: " . $zipper->getMessage()); - } - } -} diff --git a/COPS/cops-3.1.3/src/Input/Config.php b/COPS/cops-3.1.3/src/Input/Config.php deleted file mode 100644 index 75113ed1..00000000 --- a/COPS/cops-3.1.3/src/Input/Config.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Input; - -use Exception; - -/** - * Summary of Config - */ -class Config -{ - public const VERSION = '3.1.3'; - public const ENDPOINT = [ - "index" => "index.php", - "feed" => "feed.php", - "json" => "getJSON.php", - "fetch" => "fetch.php", - "read" => "epubreader.php", - "epubfs" => "epubfs.php", - "restapi" => "restapi.php", - "check" => "checkconfig.php", - "opds" => "opds.php", - "loader" => "loader.php", - "zipper" => "zipper.php", - "calres" => "calres.php", - "zipfs" => "zipfs.php", - "mail" => "sendtomail.php", - "graphql" => "graphql.php", - ]; - protected const PREFIX = 'cops_'; - - /** - * Summary of values - * @var array - */ - protected static $values = []; - - /** - * Summary of load - * @param array $values - * @return void - */ - public static function load($values) - { - // some phpunit tests re-load the config so we merge here - static::$values = array_merge(static::$values, $values); - } - - /** - * Summary of get - * @param string $name - * @param mixed $default - * @throws \Exception - * @return mixed - */ - public static function get($name, $default = null) - { - if (empty(static::$values)) { - throw new Exception('Config was not loaded correctly in config/config.php or config/test.php'); - } - if (array_key_exists(static::PREFIX . $name, static::$values)) { - return static::$values[static::PREFIX . $name]; - } - return static::$values[$name] ?? $default; - } - - /** - * Summary of set - * @param string $name - * @param mixed $value - * @return void - */ - public static function set($name, $value) - { - static::$values[static::PREFIX . $name] = $value; - } - - /** - * Summary of dump - * @return array - */ - public static function dump() - { - return static::$values; - } -} diff --git a/COPS/cops-3.1.3/src/Input/Context.php b/COPS/cops-3.1.3/src/Input/Context.php deleted file mode 100644 index 756da5f8..00000000 --- a/COPS/cops-3.1.3/src/Input/Context.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Input; - -/** - * Summary of Context - */ -class Context -{ - /** - * Summary of request - * @var Request - */ - protected Request $request; - - /** - * Summary of __construct - * @param Request $request - */ - public function __construct(Request $request) - { - $this->request = $request; - } - - /** - * Summary of getRequest - * @return Request - */ - public function getRequest() - { - return $this->request; - } -} diff --git a/COPS/cops-3.1.3/src/Input/Request.php b/COPS/cops-3.1.3/src/Input/Request.php deleted file mode 100644 index ed2c9482..00000000 --- a/COPS/cops-3.1.3/src/Input/Request.php +++ /dev/null @@ -1,578 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Input; - -use SebLucas\Cops\Calibre\Filter; -use SebLucas\Cops\Output\Response; - -/** - * Summary of Request - */ -class Request -{ - /** @var array */ - public $urlParams = []; - protected string $queryString = ''; - protected string $pathInfo = ''; - protected bool $parsed = true; - public ?string $content = null; - - /** - * Summary of __construct - * @param bool $parse - */ - public function __construct($parse = true) - { - $this->parseParams($parse); - } - - /** - * Summary of useServerSideRendering - * @return bool|int - */ - public function render() - { - return preg_match('/' . Config::get('server_side_render') . '/', $this->agent()); - } - - /** - * Summary of query - * @return string - */ - public function query() - { - return $this->queryString; - } - - /** - * Summary of method - * @return ?string - */ - public function method() - { - return $this->server('REQUEST_METHOD'); - } - - /** - * Summary of agent - * @return string - */ - public function agent() - { - return $this->server('HTTP_USER_AGENT') ?? ""; - } - - /** - * Summary of language - * @return ?string - */ - public function language() - { - return $this->server('HTTP_ACCEPT_LANGUAGE'); - } - - /** - * Summary of path - * @param string $default - * @return string - */ - public function path($default = '') - { - return $this->server('PATH_INFO') ?? $default; - } - - /** - * Summary of script - * @return ?string - */ - public function script() - { - return $this->server('SCRIPT_NAME'); - } - - /** - * Summary of uri - * @return ?string - */ - public function uri() - { - return $this->server('REQUEST_URI'); - } - - /** - * Summary of parseParams - * @param bool $parse - * @return void - */ - public function parseParams($parse = true) - { - $this->parsed = $parse; - $this->urlParams = []; - $this->queryString = ''; - if (!$this->parsed) { - return; - } - $path = $this->path(); - if (!empty(Config::get('use_route_urls'))) { - $params = Route::match($path); - if (is_null($params)) { - // this will call exit() - //Response::sendError($this, "Invalid request path '$path'"); - error_log("Invalid COPS request path '$path'"); - $params = []; - } - // JsonHandler uses same routes as HtmlHandler - see util.js - if (empty($params[Route::HANDLER_PARAM]) && $this->isAjax()) { - $params[Route::HANDLER_PARAM] = 'json'; - } - foreach ($params as $name => $value) { - $this->urlParams[$name] = $value; - } - //} elseif (empty($this->urlParams[Route::HANDLER_PARAM]) && $this->isAjax()) { - // $this->urlParams[Route::HANDLER_PARAM] = 'json'; - } - if (!empty($_GET)) { - foreach ($_GET as $name => $value) { - // remove ajax timestamp for jQuery cache = false - if ($name == '_') { - continue; - } - $this->urlParams[$name] = $_GET[$name]; - } - } - // get virtual library from option (see customize) - if (!isset($this->urlParams['vl']) && !empty($this->option('virtual_library'))) { - $this->urlParams['vl'] = $this->option('virtual_library'); - } - if (!empty(Config::get('calibre_user_database'))) { - $user = $this->getUserName(); - // @todo use restriction etc. from Calibre user database - } - $this->queryString = $_SERVER['QUERY_STRING'] ?? ''; - $this->pathInfo = $_SERVER['PATH_INFO'] ?? ''; - } - - /** - * Summary of hasFilter - * @return bool - */ - public function hasFilter() - { - // see list of acceptable filter params in Filter.php - $find = Filter::URL_PARAMS; - return !empty(array_intersect_key($find, $this->urlParams)); - } - - /** - * Summary of getFilterParams - * @return array - */ - public function getFilterParams() - { - // see list of acceptable filter params in Filter.php - $find = Filter::URL_PARAMS; - return array_intersect_key($this->urlParams, $find); - } - - /** - * Summary of get - * @param string $name - * @param mixed $default - * @param ?string $pattern - * @return mixed - */ - public function get($name, $default = null, $pattern = null) - { - if (!empty($this->urlParams) && isset($this->urlParams[$name]) && $this->urlParams[$name] != '') { - if (!isset($pattern) || preg_match($pattern, (string) $this->urlParams[$name])) { - return $this->urlParams[$name]; - } - } - return $default; - } - - /** - * Summary of set - * @param string $name - * @param mixed $value - * @return void - */ - public function set($name, $value) - { - $this->urlParams[$name] = $value; - $this->queryString = http_build_query($this->urlParams); - } - - /** - * Summary of post - * @param string $name - * @return mixed - */ - public function post($name) - { - return $_POST[$name] ?? null; - } - - /** - * Summary of request - * @param string $name - * @return mixed - */ - public function request($name) - { - return $_REQUEST[$name] ?? null; - } - - /** - * Summary of server - * @param string $name - * @return mixed - */ - public function server($name) - { - return $_SERVER[$name] ?? null; - } - - /** - * Summary of session - * @param string $name - * @return mixed - */ - public function session($name) - { - return $_SESSION[$name] ?? null; - } - - /** - * Summary of cookie - * @param string $name - * @return mixed - */ - public function cookie($name) - { - return $_COOKIE[$name] ?? null; - } - - /** - * Summary of files - * @param string $name - * @return mixed - */ - public function files($name) - { - return $_FILES[$name] ?? null; - } - - /** - * Summary of content - * @return mixed - */ - public function content() - { - if (!isset($this->content)) { - $this->content = file_get_contents('php://input'); - } - return $this->content; - } - - /** - * Summary of option - * @param string $option - * @return mixed - */ - public function option($option) - { - if (!is_null($this->cookie($option))) { - if (!is_null(Config::get($option)) && is_array(Config::get($option))) { - return explode(',', (string) $this->cookie($option)); - } elseif (!preg_match('/[^A-Za-z0-9\-_.@()]/', (string) $this->cookie($option))) { - return $this->cookie($option); - } - } - if (!is_null(Config::get($option))) { - return Config::get($option); - } - - return ''; - } - - /** - * Summary of style - * @return string - */ - public function style() - { - $style = $this->option('style'); - if (!preg_match('/[^A-Za-z0-9\-_]/', (string) $style)) { - return 'templates/' . $this->template() . '/styles/style-' . $this->option('style') . '.css'; - } - return 'templates/' . Config::get('template') . '/styles/style-' . Config::get('style') . '.css'; - } - - /** - * Summary of template - * @return string - */ - public function template() - { - $template = $this->option('template'); - if (!preg_match('/[^A-Za-z0-9\-_]/', (string) $template) && is_dir("templates/{$template}/")) { - return $template; - } - return Config::get('template'); - } - - /** - * Summary of getIntOrNull - * @param string $name - * @return ?int - */ - protected function getIntOrNull($name) - { - $value = $this->get($name, null, '/^\d+$/'); - if (!is_null($value)) { - return (int) $value; - } - return null; - } - - /** - * Summary of getId - * @param string $name - * @return ?int - */ - public function getId($name = 'id') - { - return $this->getIntOrNull($name); - } - - /** - * Summary of database - * @return ?int - */ - public function database() - { - return $this->getIntOrNull('db'); - } - - /** - * Summary of getVirtualLibrary - * @param bool $strip - * @return int|string|null - */ - public function getVirtualLibrary($strip = false) - { - $libraryId = $this->get('vl', null); - if (empty($libraryId)) { - return null; - } - // URL format: ...&vl=2.Short_Stories_in_English - if ($strip && str_contains((string) $libraryId, '.')) { - [$libraryId, $slug] = explode('.', (string) $libraryId); - } - return $libraryId; - } - - /** - * Summary of getUserName - * @param ?string $name - * @return string|null - */ - public function getUserName($name = null) - { - $http_auth_user = Config::get('http_auth_user', 'PHP_AUTH_USER'); - $name ??= $this->server($http_auth_user); - return $name; - } - - /** - * Summary of getSorted - * @param ?string $default - * @return ?string - */ - public function getSorted($default = null) - { - return $this->get('sort', $default, '/^\w+(\s+(asc|desc)|)$/i'); - // ?? $this->option('sort'); - } - - /** - * Summary of getCurrentUrl - * @param ?string $handler - * @return string - */ - public function getCurrentUrl($handler = null) - { - $handler ??= $this->getHandler(); - $pathInfo = $this->path(); - $queryString = $this->query(); - if (empty($queryString)) { - return Route::link($handler) . $pathInfo; - } - return Route::link($handler) . $pathInfo . '?' . $queryString; - } - - /** - * Summary of getEndpoint - * @param string $default - * @deprecated 3.1.0 use getHandler() instead - * @return string - */ - public function getEndpoint($default) - { - $script = explode("/", $this->script() ?? "/" . $default); - $link = array_pop($script); - // see former LinkNavigation - if (preg_match("/(bookdetail|getJSON).php/", $link)) { - return $default; - } - return $link; - } - - /** - * Summary of getHandler - * @param string $default - * @return string - */ - public function getHandler($default = 'index') - { - // we have a handler already - if (!empty($this->urlParams[Route::HANDLER_PARAM])) { - return $this->urlParams[Route::HANDLER_PARAM]; - } - // @deprecated 3.1.0 use index.php endpoint - // try to find handler via endpoint - $endpoint = $this->getEndpoint(Config::ENDPOINT[$default]); - if ($endpoint == Config::ENDPOINT['index']) { - return 'index'; - } - $flipped = array_flip(Config::ENDPOINT); - if (!empty($flipped[$endpoint])) { - return $flipped[$endpoint]; - } - // for phpunit tests - if ($endpoint == 'phpunit' || $endpoint == 'Standard input code') { - return $default; - } - // how did we end up here? - throw new \Exception('Unknown handler for endpoint ' . htmlspecialchars($endpoint)); - //return $default; - } - - /** - * Summary of getCleanParams - * @return array - */ - public function getCleanParams() - { - $params = $this->urlParams; - unset($params['title']); - unset($params['_']); - unset($params['n']); - unset($params['complete']); - //unset($params[Route::HANDLER_PARAM]); - return $params; - } - - /** - * Summary of getApiKey - * @return string - */ - public function getApiKey() - { - // If you send header X-Api-Key from your client, the web server will turn this into HTTP_X_API_KEY - // For Nginx proxy configurations you may need to add something like this: - // proxy_set_header X-Api-Key $http_x_api_key; - return $this->server('HTTP_X_API_KEY') ?? ''; - } - - /** - * Summary of hasValidApiKey - * @return bool - */ - public function hasValidApiKey() - { - if (empty(Config::get('api_key')) || Config::get('api_key') !== $this->getApiKey()) { - return false; - } - return true; - } - - /** - * Summary of isAjax - * @return bool - */ - public function isAjax() - { - // for jquery etc. if passed along by proxy - if ($this->server('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest') { - return true; - } - // for fetch etc. if Accept header is specified - if (str_contains($this->server('HTTP_ACCEPT') ?? '', 'application/json')) { - return true; - } - // @todo https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Mode - return false; - } - - /** - * Summary of isJson - * @return bool - */ - public function isJson() - { - // @deprecated 3.1.0 use index.php endpoint - // using actual getJSON.php endpoint, or - // set in parseParams() based on isAjax() - $handler = $this->getHandler(); - if ($handler == 'json') { - return true; - } - return false; - } - - /** - * Summary of isFeed - * @return bool - */ - public function isFeed() - { - // @deprecated 3.1.0 use index.php endpoint - // using actual feed.php or opds.php endpoint, or - // set in parseParams() based on Route::match() - $handler = $this->getHandler(); - if (in_array($handler, ['feed', 'opds'])) { - return true; - } - return false; - } - - /** - * Summary of build - * @param array $params ['db' => $db, 'page' => $pageId, 'id' => $id, 'query' => $query, 'n' => $n] - * @param string $handler - * @param ?array $server - * @param ?array $cookie - * @param ?array $config - * @return Request - */ - public static function build($params = [], $handler = '', $server = null, $cookie = null, $config = null) - { - // ['db' => $db, 'page' => $pageId, 'id' => $id, 'query' => $query, 'n' => $n] - if (!empty($handler)) { - $params[Route::HANDLER_PARAM] ??= $handler; - } - $request = new self(false); - $request->urlParams = $params; - $request->queryString = http_build_query($request->urlParams); - return $request; - } -} diff --git a/COPS/cops-3.1.3/src/Input/Route.php b/COPS/cops-3.1.3/src/Input/Route.php deleted file mode 100644 index 0040f768..00000000 --- a/COPS/cops-3.1.3/src/Input/Route.php +++ /dev/null @@ -1,685 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Input; - -use FastRoute\Dispatcher; -use FastRoute\RouteCollector; -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Language\Translation; - -use function FastRoute\simpleDispatcher; - -/** - * Summary of Route - */ -class Route -{ - public const HANDLER_PARAM = "_handler"; - public const SYMFONY_REQUEST = '\Symfony\Component\HttpFoundation\Request'; - - /** @var ?\Symfony\Component\HttpFoundation\Request */ - protected static $proxyRequest = null; - /** @var ?string */ - protected static $baseUrl = null; - /** @var array */ - protected static $routes = []; - /** @var string[] */ - protected static $skipPrefix = ['index', 'json', 'fetch', 'restapi', 'graphql', 'phpunit']; - /** @var Dispatcher|null */ - protected static $dispatcher = null; - /** @var array */ - protected static $pages = []; - // with use_url_rewriting = 1 - basic rewrites only - /** @var array */ - protected static $rewrites = [ - // Format: route => handler, or route => [handler, [fixed => 1, ...]] with fixed params - "/view/{data}/{db}/{ignore}.{type}" => ["fetch", ["view" => 1]], - "/view/{data}/{ignore}.{type}" => ["fetch", ["view" => 1]], - "/download/{data}/{db}/{ignore}.{type}" => ["fetch"], - "/download/{data}/{ignore}.{type}" => ["fetch"], - ]; - /** @var array */ - protected static $handlers = []; - - /** - * Match pathinfo against routes and return query params - * @param string $path - * @return ?array array of query params or null if not found - */ - public static function match($path) - { - if (empty($path) || $path == '/') { - return []; - } - - // match exact path - if (static::has($path)) { - return static::get($path); - } - - // match pattern - $fixed = []; - $params = []; - $method = 'GET'; - - $dispatcher = static::getSimpleDispatcher(); - $routeInfo = $dispatcher->dispatch($method, $path); - switch ($routeInfo[0]) { - case Dispatcher::NOT_FOUND: - // ... 404 Not Found - //http_response_code(404); - //throw new Exception("Invalid route " . htmlspecialchars($path)); - return null; - case Dispatcher::METHOD_NOT_ALLOWED: - //$allowedMethods = $routeInfo[1]; - // ... 405 Method Not Allowed - //header('Allow: ' . implode(', ', $allowedMethods)); - //http_response_code(405); - //throw new Exception("Invalid method " . htmlspecialchars($method) . " for route " . htmlspecialchars($path)); - return null; - case Dispatcher::FOUND: - $fixed = $routeInfo[1]; - $params = $routeInfo[2]; - } - // for normal routes, put fixed params at the start - $params = array_merge($fixed, $params); - unset($params['ignore']); - return $params; - } - - /** - * Check if static route exists - * @param string $route - * @return bool - */ - public static function has($route) - { - return array_key_exists($route, static::$routes); - } - - /** - * Get query params for static route - * @param string $route - * @return array - */ - public static function get($route) - { - $page = static::$routes[$route]; - if (is_array($page)) { - return $page; - } - return ["page" => $page]; - } - - /** - * Set route to page with optional static params - * @param string $route - * @param string $page - * @param array $params - * @return void - */ - public static function set($route, $page, $params = []) - { - if (empty($params)) { - static::$routes[$route] = $page; - return; - } - $params["page"] = $page; - static::$routes[$route] = $params; - } - - /** - * Add prefix for paths with this endpoint - * @param string $name - * @return bool - */ - public static function addPrefix($name) - { - return !in_array($name, static::$skipPrefix); - } - - /** - * Summary of getSimpleDispatcher - * @return Dispatcher - */ - public static function getSimpleDispatcher() - { - static::$dispatcher ??= simpleDispatcher(function (RouteCollector $r) { - static::addRouteCollection($r); - }); - return static::$dispatcher; - } - - /** - * Summary of addRouteCollection - * @param RouteCollector $r - * @return void - */ - public static function addRouteCollection($r) - { - foreach (static::getRoutes() as $route => $queryParams) { - $r->addRoute('GET', $route, $queryParams); - } - } - - /** - * Get routes and query params - * @return array> - */ - public static function getRoutes() - { - $routeMap = []; - foreach (array_keys(static::$routes) as $route) { - $routeMap[$route] = static::get($route); - } - return $routeMap; - } - - /** - * Add routes and query params - * @param array> $routes - * @return void - */ - public static function addRoutes($routes) - { - static::$routes = array_merge(static::$routes, $routes); - } - - /** - * Set routes - * @param array> $routes - * @return void - */ - public static function setRoutes($routes = []) - { - static::$routes = $routes; - } - - /** - * Count routes - * @return int - */ - public static function count() - { - return count(static::$routes); - } - - /** - * Get full URL path for relative path with optional params - * @param string $path relative to base dir - * @param array $params (optional) - * @return string - */ - public static function path($path = null, $params = []) - { - if (!empty($path) && str_starts_with($path, '/')) { - return $path . static::params($params); - } - return static::base() . $path . static::params($params); - } - - /** - * Get optional query string with ? - * @param array $params - * @param string $prefix - * @return string - */ - public static function params($params = [], $prefix = '') - { - $queryParams = array_filter($params, function ($val) { - if (empty($val) && strval($val) !== '0') { - return false; - } - return true; - }); - if (empty($queryParams)) { - return $prefix; - } - $separator = null; - $queryString = http_build_query($queryParams, '', $separator); - return $prefix . '?' . $queryString; - } - - /** - * Get full link for handler with page and params - * @param string|null $handler before going through Config::ENDPOINT - * @param string|int|null $page - * @param array $params - * @return string - */ - public static function link($handler = null, $page = null, $params = []) - { - $handler ??= 'index'; - // take into account handler when building page url, e.g. feed or zipper - if (Config::get('use_route_urls') && !in_array($handler, ['index', 'json', 'phpunit'])) { - $params[Route::HANDLER_PARAM] = $handler; - } else { - unset($params[Route::HANDLER_PARAM]); - } - // ?page=... or /route/... - $page = static::page($page, $params); - // same routes as HtmlHandler - see util.js - if ($handler == 'json') { - $handler = 'index'; - } - // endpoint.php or handler or empty - $endpoint = static::endpoint($handler); - if (empty($endpoint) && str_starts_with($page, '/')) { - // URL format: /base/route/... - return static::base() . substr($page, 1); - } - // URL format: /base/endpoint.php?page=... or /base/handler/route/... - return static::base() . $endpoint . $page; - } - - /** - * Get endpoint for handler - * @param string $handler - * @return string - */ - public static function endpoint($handler) - { - if (Config::get('front_controller')) { - // no endpoint prefix for supported handlers - return ''; - } - if (Config::get('use_route_urls')) { - // use default endpoint for supported handlers - return Config::ENDPOINT['index']; - } - // @deprecated 3.1.0 use index.php endpoint - if (array_key_exists($handler, Config::ENDPOINT)) { - // @todo special case for restapi - if (in_array($handler, ['restapi'])) { - return Config::ENDPOINT['index']; - } - $endpoint = Config::ENDPOINT[$handler]; - } elseif ($handler == 'phpunit') { - $endpoint = $handler; - } elseif (empty($handler)) { - $endpoint = 'empty!'; - } else { - throw new \Exception('Unknown handler ' . htmlspecialchars($handler)); - } - return $endpoint; - } - - /** - * Get uri for page with params - * @param string|int|null $page - * @param array $params - * @return string - */ - public static function page($page, $params = []) - { - $queryParams = array_filter($params, function ($val) { - if (empty($val) && strval($val) !== '0') { - return false; - } - return true; - }); - if (!empty($page)) { - $queryParams = array_merge(['page' => $page], $queryParams); - } - $prefix = ''; - if (count($queryParams) < 1) { - return $prefix; - } - return static::route($queryParams, $prefix); - } - - /** - * Get uri for query with params - * @param string|null $query - * @param array $params - * @return string - */ - public static function query($query, $params = []) - { - $prefix = ''; - $pos = strpos((string) $query, '?'); - if ($pos !== false) { - $prefix = substr((string) $query, 0, $pos); - $query = substr((string) $query, $pos + 1); - } - $queryParams = []; - if (!empty($query)) { - parse_str($query, $queryParams); - $params = array_merge($queryParams, $params); - } - $queryParams = array_filter($params, function ($val) { - if (empty($val) && strval($val) !== '0') { - return false; - } - return true; - }); - if (count($queryParams) < 1) { - return $prefix; - } - return static::route($queryParams, $prefix); - } - - /** - * Summary of route - * @param array $params - * @param string $prefix - * @return string - */ - public static function route($params, $prefix = '') - { - if (Config::get('use_route_urls')) { - $route = static::getPageRoute($params, $prefix); - if (!is_null($route)) { - return $route; - } - } - unset($params[Route::HANDLER_PARAM]); - if (empty($params)) { - return $prefix; - } - $separator = null; - $queryString = http_build_query($params, '', $separator); - return $prefix . '?' . $queryString; - } - - /** - * Summary of base - * @return string - */ - public static function base() - { - if (isset(static::$baseUrl)) { - return static::$baseUrl; - } - if (!empty(Config::get('full_url'))) { - $base = Config::get('full_url'); - } elseif (static::hasTrustedProxies()) { - // use scheme and host + base path here to apply potential forwarded values - $base = static::$proxyRequest->getSchemeAndHttpHost() . static::$proxyRequest->getBasePath(); - } else { - $base = dirname((string) $_SERVER['SCRIPT_NAME']); - } - if (!str_ends_with((string) $base, '/')) { - $base .= '/'; - } - static::setBaseUrl($base); - return $base; - } - - /** - * Summary of getPageRoute - * @param array $params - * @param string $prefix - * @return string|null - */ - public static function getPageRoute($params, $prefix = '') - { - if (!empty($params[self::HANDLER_PARAM])) { - // keep page param and use endpoint as key here - $page = $params[self::HANDLER_PARAM]; - } elseif (isset($params['page'])) { - $page = $params['page']; - unset($params['page']); - } else { - $page = ''; - } - $pages = static::getPages(); - $routes = $pages[$page] ?? []; - if (count($routes) < 1) { - return null; - } - return static::findMatchingRoute($routes, $params, $prefix); - } - - /** - * Summary of findMatchingRoute - * @param array $routes - * @param array $params - * @param string $prefix - * @return string|null - */ - public static function findMatchingRoute($routes, $params, $prefix = '') - { - // find matching route based on fixed and/or path params - e.g. authors letter - foreach ($routes as $route => $fixed) { - if (count($fixed) > count($params)) { - continue; - } - $subst = $params; - // check and remove fixed params (incl. endpoint or page) - foreach ($fixed as $key => $val) { - if (!isset($subst[$key]) || $subst[$key] != $val) { - continue 2; - } - unset($subst[$key]); - } - $found = []; - // check and replace path params + support custom patterns - see nikic/fast-route - if (preg_match_all("~\{(\w+(|:[^}]+))\}~", $route, $found)) { - if (in_array('ignore', $found[1])) { - $subst['ignore'] = 'ignore'; - } - if (count($found[1]) > count($subst)) { - continue; - } - foreach ($found[1] as $param) { - $pattern = ''; - if (str_contains($param, ':')) { - [$param, $pattern] = explode(':', $param); - } - if (!isset($subst[$param])) { - continue 2; - } - $value = $subst[$param]; - if (!empty($pattern) && !preg_match('/^' . $pattern . '$/', (string) $value)) { - continue 2; - } - if (in_array($param, ['title', 'author', 'ignore'])) { - $value = static::slugify($value); - } - if (!empty($pattern)) { - $route = str_replace('{' . $param . ':' . $pattern . '}', "$value", $route); - } else { - $route = str_replace('{' . $param . '}', "$value", $route); - } - unset($subst[$param]); - } - } - if (count($subst) > 0) { - $separator = null; - return $prefix . $route . '?' . http_build_query($subst, '', $separator); - } - return $prefix . $route; - } - return null; - } - - /** - * Get mapping of pages to routes with fixed params - * @return array> - */ - public static function getPages() - { - if (!empty(static::$pages)) { - return static::$pages; - } - static::$pages = []; - foreach (static::$routes as $route => $params) { - if (!is_array($params)) { - $page = $params; - $params = []; - } elseif (!empty($params[self::HANDLER_PARAM])) { - // keep page param and use endpoint as key here - $page = $params[self::HANDLER_PARAM]; - } else { - $page = $params["page"] ?? ''; - unset($params["page"]); - } - static::$pages[$page] ??= []; - static::$pages[$page][$route] = $params; - } - return static::$pages; - } - - /** - * Summary of slug - @todo check transliteration - * @param string $string - * @return string - */ - public static function slugify($string) - { - $string = str_replace([' ', '&', '"'], ['_', '-', ''], trim($string)); - - return Translation::normalizeUtf8String($string); - } - - /** - * Match rewrite rule for path and return endpoint with params - * @param string $path - * @return array - */ - public static function matchRewrite($path) - { - $dispatcher = simpleDispatcher(function (RouteCollector $r) { - static::addRewriteRules($r); - }); - - // match pattern - $handler = ''; - $params = []; - $method = 'GET'; - $routeInfo = $dispatcher->dispatch($method, $path); - - if ($routeInfo[0] !== Dispatcher::FOUND) { - return [$handler, $params]; - } - $map = $routeInfo[1]; - $params = $routeInfo[2]; - $handler = array_shift($map); - $fixed = array_shift($map) ?? []; - unset($params['ignore']); - - // for rewrite rules, put fixed params at the end - $params = array_merge($params, $fixed); - return [$handler, $params]; - } - - /** - * Summary of addRewriteRules - * @param RouteCollector $r - * @return void - */ - public static function addRewriteRules($r) - { - foreach (static::$rewrites as $route => $map) { - $r->addRoute('GET', $route, $map); - } - } - - /** - * Summary of getUrlRewrite - * @param string $handler - * @param array $params - * @return string|null - */ - public static function getUrlRewrite($handler, $params) - { - $handlers = static::getHandlers(); - $routes = $handlers[$handler] ?? []; - if (count($routes) < 1) { - return null; - } - return static::findMatchingRoute($routes, $params); - } - - /** - * Get mapping of handlers to rewrites with fixed params - * @return array> - */ - public static function getHandlers() - { - if (!empty(static::$handlers)) { - return static::$handlers; - } - static::$handlers = []; - foreach (static::$rewrites as $route => $map) { - if (!is_array($map)) { - $map = [ $map ]; - } - $handler = array_shift($map); - $fixed = array_shift($map) ?? []; - static::$handlers[$handler] ??= []; - static::$handlers[$handler][$route] = $fixed; - } - return static::$handlers; - } - - /** - * Summary of setBaseUrl - * @param ?string $base - * @return void - */ - public static function setBaseUrl($base) - { - static::$baseUrl = $base; - if (is_null($base)) { - static::$proxyRequest = null; - } - } - - /** - * Check if we have trusted proxies defined in config/local.php - * @see https://github.com/symfony/symfony/blob/7.1/src/Symfony/Component/HttpKernel/Kernel.php#L741 - * @return bool - */ - public static function hasTrustedProxies() - { - $class = static::SYMFONY_REQUEST; - if (!class_exists($class)) { - return false; - } - if (empty(Config::get('trusted_proxies')) || empty(Config::get('trusted_headers'))) { - return false; - } - if (!isset(static::$proxyRequest)) { - $proxies = Config::get('trusted_proxies'); - $headers = Config::get('trusted_headers'); - $class::setTrustedProxies(is_array($proxies) ? $proxies : array_map('trim', explode(',', (string) $proxies)), static::resolveTrustedHeaders($headers)); - static::$proxyRequest = $class::createFromGlobals(); - } - return true; - } - - /** - * Convert trusted headers into bit field of Request::HEADER_* - * @see https://github.com/symfony/symfony/blob/7.1/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php#L3054 - * @param string[] $headers - * @return int - */ - protected static function resolveTrustedHeaders(array $headers) - { - $class = static::SYMFONY_REQUEST; - $trustedHeaders = 0; - - foreach ($headers as $h) { - $trustedHeaders |= match ($h) { - 'forwarded' => $class::HEADER_FORWARDED, - 'x-forwarded-for' => $class::HEADER_X_FORWARDED_FOR, - 'x-forwarded-host' => $class::HEADER_X_FORWARDED_HOST, - 'x-forwarded-proto' => $class::HEADER_X_FORWARDED_PROTO, - 'x-forwarded-port' => $class::HEADER_X_FORWARDED_PORT, - 'x-forwarded-prefix' => $class::HEADER_X_FORWARDED_PREFIX, - default => 0, - }; - } - - return $trustedHeaders; - } -} diff --git a/COPS/cops-3.1.3/src/Language/Translation.php b/COPS/cops-3.1.3/src/Language/Translation.php deleted file mode 100644 index 0cc82da3..00000000 --- a/COPS/cops-3.1.3/src/Language/Translation.php +++ /dev/null @@ -1,205 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Language; - -use SebLucas\Cops\Input\Config; - -class Translation -{ - public const BASE_DIR = './lang'; - /** @var ?\Transliterator */ - protected static $transliterator; - /** @var ?string */ - protected $acceptLanguageHeader; - - /** - * Summary of __construct - * @param ?string $acceptLanguageHeader from $_SERVER['HTTP_ACCEPT_LANGUAGE'] - */ - public function __construct($acceptLanguageHeader = null) - { - $this->acceptLanguageHeader = $acceptLanguageHeader; - } - - /** - * Get all accepted languages from the browser and put them in a sorted array - * languages id are normalized : fr-fr -> fr_FR - * @param ?string $accept from $_SERVER['HTTP_ACCEPT_LANGUAGE'] - * @return array of languages - */ - public function getAcceptLanguages($accept) - { - $langs = []; - - if (empty($accept)) { - return $langs; - } - - // break up string into pieces (languages and q factors) - if (preg_match('/^(\w{2})-\w{2}$/', $accept, $matches)) { - // Special fix for IE11 which send fr-FR and nothing else - $accept = $accept . ',' . $matches[1] . ';q=0.8'; - } - preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $accept, $lang_parse); - - if (count($lang_parse[1])) { - $langs = []; - foreach ($lang_parse[1] as $lang) { - // Format the language code (not standard among browsers) - if (strlen($lang) == 5) { - $lang = str_replace('-', '_', $lang); - $splitted = preg_split('/_/', $lang); - $lang = $splitted[0] . '_' . strtoupper($splitted[1]); - } - array_push($langs, $lang); - } - // create a list like "en" => 0.8 - $langs = array_combine($langs, $lang_parse[4]); - - // set default to 1 for any without q factor - foreach ($langs as $lang => $val) { - if ($val === '') { - $langs[$lang] = 1; - } - } - - // sort list based on value - arsort($langs, SORT_NUMERIC); - } - - return $langs; - } - - /** - * Find the best translation file possible based on the accepted languages - * @return array of language and language file - */ - public function getLangAndTranslationFile() - { - $langs = []; - $lang = 'en'; - if (!empty(Config::get('language'))) { - $lang = Config::get('language'); - } elseif (!empty($this->acceptLanguageHeader)) { - $langs = $this->getAcceptLanguages($this->acceptLanguageHeader); - } - $lang_file = null; - foreach ($langs as $language => $val) { - $temp_file = static::BASE_DIR . '/Localization_' . $language . '.json'; - if (file_exists($temp_file)) { - $lang = $language; - $lang_file = $temp_file; - break; - } - } - if (empty($lang_file)) { - $lang_file = static::BASE_DIR . '/Localization_' . $lang . '.json'; - } - return [$lang, $lang_file]; - } - - /** - * This method is based on this page - * http://www.mind-it.info/2010/02/22/a-simple-approach-to-localization-in-php/ - * @param string $phrase - * @param int $count - * @param bool $reset - * @return string - */ - public function localize($phrase, $count = -1, $reset = false) - { - if ($count == 0) { - $phrase .= '.none'; - } - if ($count == 1) { - $phrase .= '.one'; - } - if ($count > 1) { - $phrase .= '.many'; - } - - /* Static keyword is used to ensure the file is loaded only once */ - static $translations = null; - if ($reset) { - $translations = null; - } - /* If no instance of $translations has occured load the language file */ - if (is_null($translations)) { - $lang_file_en = null; - [$lang, $lang_file] = $this->getLangAndTranslationFile(); - if ($lang != 'en') { - $lang_file_en = static::BASE_DIR . '/Localization_en.json'; - } - - $lang_file_content = file_get_contents($lang_file); - /* Load the language file as a JSON object and transform it into an associative array */ - $translations = json_decode($lang_file_content, true); - - /* Clean the array of all unfinished translations */ - foreach (array_keys($translations) as $key) { - if (preg_match('/^##TODO##/', $key)) { - unset($translations [$key]); - } - } - if (!is_null($lang_file_en)) { - $lang_file_content = file_get_contents($lang_file_en); - $translations_en = json_decode($lang_file_content, true); - $translations = array_merge($translations_en, $translations); - } - } - if (array_key_exists($phrase, $translations)) { - return $translations[$phrase]; - } - return $phrase; - } - - /** - * Summary of useNormAndUp - * @return bool - */ - public static function useNormAndUp() - { - return Config::get('normalized_search') == '1'; - } - - /** - * Summary of normalizeUtf8String - * @param string $s - * @return string - */ - public static function normalizeUtf8String($s) - { - //return Transliteration::process($s); - - // ASCII is always valid NFC! If we're only ever given plain ASCII, we can - // avoid the overhead of initializing the transliterator by skipping - // out early. - if (!preg_match('/[\x80-\xff]/', $s)) { - return $s; - } - - // see https://www.drupal.org/project/rename_admin_paths/issues/3275140 for different order - if (!isset(static::$transliterator)) { - //static::$transliterator = transliterator_create("Any-Latin; NFD; [:Nonspacing Mark:] Remove; NFC;"); - static::$transliterator = transliterator_create("Any-Latin; Latin-ASCII; NFD; [:Nonspacing Mark:] Remove; NFC;"); - } - return transliterator_transliterate(static::$transliterator, $s); - } - - /** - * Summary of normAndUp - * @param string $s - * @return string - */ - public static function normAndUp($s) - { - return mb_strtoupper(static::normalizeUtf8String($s), 'UTF-8'); - } -} diff --git a/COPS/cops-3.1.3/src/Model/Entry.php b/COPS/cops-3.1.3/src/Model/Entry.php deleted file mode 100644 index 73b33258..00000000 --- a/COPS/cops-3.1.3/src/Model/Entry.php +++ /dev/null @@ -1,192 +0,0 @@ - - */ - -namespace SebLucas\Cops\Model; - -use SebLucas\Cops\Calibre\Base; -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Pages\PageId; - -class Entry -{ - public string $title; - public string $id; - public string $content; - /** @var string|int */ - public $numberOfElement; - public string $contentType; - /** @var array */ - public $linkArray; - /** @var ?int */ - public $localUpdated; - public string $className; - /** @var ?int */ - protected static $updated = null; - /** @var ?int */ - protected $databaseId; - /** @var ?Base */ - public $instance; - - /** @var array */ - public static $icons = [ - PageId::ALL_AUTHORS_ID => 'images/author.png', - PageId::ALL_SERIES_ID => 'images/serie.png', - PageId::ALL_RECENT_BOOKS_ID => 'images/recent.png', - PageId::ALL_TAGS_ID => 'images/tag.png', - PageId::ALL_LANGUAGES_ID => 'images/language.png', - PageId::ALL_CUSTOMS_ID => 'images/custom.png', - PageId::ALL_RATING_ID => 'images/rating.png', - "cops:books$" => 'images/allbook.png', - "cops:books:letter" => 'images/allbook.png', - PageId::ALL_PUBLISHERS_ID => 'images/publisher.png', - ]; - - /** - * Summary of __construct - * @param string $title - * @param string $id - * @param string $content - * @param string $contentType - * @param array $linkArray - * @param string|int|null $database - * @param string $className - * @param string|int $count - */ - public function __construct($title, $id, $content, $contentType = "text", $linkArray = [], $database = null, $className = "", $count = 0) - { - $this->title = $title; - $this->id = $id; - $this->content = $content; - $this->contentType = $contentType; - $this->linkArray = $linkArray; - $this->className = $className; - $this->numberOfElement = $count; - - if (Config::get('show_icons') == 1) { - foreach (static::$icons as $reg => $image) { - if (preg_match("/" . $reg . "/", $id)) { - array_push($this->linkArray, new LinkEntry( - Route::path($image) . "?v=" . Config::VERSION, - "image/png", - LinkEntry::OPDS_THUMBNAIL_TYPE - )); - break; - } - } - } - - if (!is_null($database)) { - $this->id = str_replace("cops:", "cops:" . strval($database) . ":", $this->id); - } - } - - /** - * Summary of getUpdatedTime - * @return string - */ - public function getUpdatedTime() - { - if (!is_null($this->localUpdated)) { - return date(DATE_ATOM, $this->localUpdated); - } - if (is_null(static::$updated)) { - static::$updated = time(); - } - return date(DATE_ATOM, static::$updated); - } - - /** - * Summary of getNavLink - * @param array $extraParams - * @return string - */ - public function getNavLink($extraParams = []) - { - foreach ($this->linkArray as $link) { - /** @var $link LinkEntry|LinkFeed */ - - if (!($link instanceof LinkFeed)) { - continue; - } - - $uri = $link->hrefXhtml(); - if (empty($extraParams)) { - return $uri; - } - $query = parse_url($uri, PHP_URL_QUERY); - if (is_null($query)) { - return $uri . '?' . http_build_query($extraParams); - } - // replace current params with extraParams where needed - parse_str($query, $params); - $params = array_replace($params, $extraParams); - return str_replace('?' . $query, '?' . http_build_query($params), $uri); - } - return "#"; - } - - /** - * Summary of getRelation - * @return ?string - */ - public function getRelation() - { - foreach ($this->linkArray as $link) { - /** @var $link LinkEntry|LinkFeed */ - - if (!($link instanceof LinkFeed)) { - continue; - } - - return $link->rel; - } - return null; - } - - /** - * Summary of getThumbnail - * @return ?string - */ - public function getThumbnail() - { - foreach ($this->linkArray as $link) { - /** @var $link LinkFeed|LinkEntry */ - - if ($link->rel == LinkEntry::OPDS_THUMBNAIL_TYPE) { - return $link->hrefXhtml(); - } - } - return null; - } - - /** - * Summary of getImage - * @return ?string - */ - public function getImage() - { - foreach ($this->linkArray as $link) { - /** @var $link LinkFeed|LinkEntry */ - - if ($link->rel == LinkEntry::OPDS_IMAGE_TYPE) { - return $link->hrefXhtml(); - } - } - return null; - } - - /** - * Summary of isValidForOPDS - * @return bool - */ - public function isValidForOPDS() - { - return true; - } -} diff --git a/COPS/cops-3.1.3/src/Model/EntryBook.php b/COPS/cops-3.1.3/src/Model/EntryBook.php deleted file mode 100644 index 1dd1555b..00000000 --- a/COPS/cops-3.1.3/src/Model/EntryBook.php +++ /dev/null @@ -1,56 +0,0 @@ - - */ - -namespace SebLucas\Cops\Model; - -use SebLucas\Cops\Calibre\Book; - -class EntryBook extends Entry -{ - public Book $book; - - /** - * EntryBook constructor. - * @param string $title - * @param string $id - * @param string $content - * @param string $contentType - * @param array $linkArray - * @param Book $book - */ - public function __construct($title, $id, $content, $contentType, $linkArray, $book) - { - parent::__construct($title, $id, $content, $contentType, $linkArray, $book->getDatabaseId()); - $this->book = $book; - $this->localUpdated = $book->timestamp; - } - - /** - * Summary of hasAcquisitionLink - * @return bool - */ - public function hasAcquisitionLink() - { - foreach ($this->linkArray as $link) { - if ($link->rel == LinkEntry::OPDS_ACQUISITION_TYPE) { - return true; - } - } - return false; - } - - /** - * Summary of isValidForOPDS - * @return bool - */ - public function isValidForOPDS() - { - // check that we have at least 1 valid acquisition link for this book - see #28 - return $this->hasAcquisitionLink(); - } -} diff --git a/COPS/cops-3.1.3/src/Model/Link.php b/COPS/cops-3.1.3/src/Model/Link.php deleted file mode 100644 index 7d89d508..00000000 --- a/COPS/cops-3.1.3/src/Model/Link.php +++ /dev/null @@ -1,50 +0,0 @@ - - */ - -namespace SebLucas\Cops\Model; - -class Link -{ - //public const OPDS_THUMBNAIL_TYPE = "http://opds-spec.org/image/thumbnail"; - //public const OPDS_IMAGE_TYPE = "http://opds-spec.org/image"; - //public const OPDS_ACQUISITION_TYPE = "http://opds-spec.org/acquisition"; - //public const OPDS_NAVIGATION_FEED = "application/atom+xml;profile=opds-catalog;kind=navigation"; - //public const OPDS_ACQUISITION_FEED = "application/atom+xml;profile=opds-catalog;kind=acquisition"; - - public string $href; - public string $type; - /** @var ?string */ - public $rel; - /** @var ?string */ - public $title; - - /** - * Summary of __construct - * @param string $href uri including the endpoint for images, books etc. - * @param string $type link type in the OPDS catalog - * @param ?string $rel relation in the OPDS catalog - * @param ?string $title title in the OPDS catalog and elsewhere - */ - public function __construct($href, $type, $rel = null, $title = null) - { - $this->href = $href; - $this->type = $type; - $this->rel = $rel; - $this->title = $title; - } - - /** - * Summary of hrefXhtml - * @return string - */ - public function hrefXhtml() - { - // Link()->href includes the endpoint here - return $this->href; - } -} diff --git a/COPS/cops-3.1.3/src/Model/LinkEntry.php b/COPS/cops-3.1.3/src/Model/LinkEntry.php deleted file mode 100644 index a678a294..00000000 --- a/COPS/cops-3.1.3/src/Model/LinkEntry.php +++ /dev/null @@ -1,50 +0,0 @@ - - */ - -namespace SebLucas\Cops\Model; - -/** - * From https://specs.opds.io/opds-1.2#52-catalog-entry-relations - * OPDS Catalog Entry Documents SHOULD include links to related Resources. This specification - * defines new relations for linking from OPDS Catalog Entry Documents. They are defined in the - * Sections Acquisition Relations and Artwork Relations. - */ -class LinkEntry extends Link -{ - public const OPDS_THUMBNAIL_TYPE = "http://opds-spec.org/image/thumbnail"; - public const OPDS_IMAGE_TYPE = "http://opds-spec.org/image"; - public const OPDS_ACQUISITION_TYPE = "http://opds-spec.org/acquisition"; - /** @var ?string */ - public $length; - /** @var ?string */ - public $mtime; - - /** - * Summary of hrefXhtml - * @return string - */ - public function hrefXhtml() - { - // LinkEntry()->href includes the endpoint here - return $this->href; - } - - /** - * Summary of addFileInfo - * @param string $filepath - * @return void - */ - public function addFileInfo($filepath) - { - if (!file_exists($filepath)) { - return; - } - $this->length = (string) filesize($filepath); - $this->mtime = date(DATE_ATOM, filemtime($filepath)); - } -} diff --git a/COPS/cops-3.1.3/src/Model/LinkFacet.php b/COPS/cops-3.1.3/src/Model/LinkFacet.php deleted file mode 100644 index 1f3bcfc3..00000000 --- a/COPS/cops-3.1.3/src/Model/LinkFacet.php +++ /dev/null @@ -1,47 +0,0 @@ - - */ - -namespace SebLucas\Cops\Model; - -/** - * From https://specs.opds.io/opds-1.2#4-facets - * An Acquisition Feed MAY offer multiple links to reorder the Publications listed - * in the feed or limit them to a subset. This specification defines one new relation - * to identify such links as Facets: - * http://opds-spec.org/facet: An Acquisition Feed with a subset or an alternate order - * of the Publications listed. - * - * Links using this relation MUST only appear in Acquisition Feeds. - */ -class LinkFacet extends LinkFeed -{ - public const LINK_RELATION = "http://opds-spec.org/facet"; - - /** @var ?string */ - public $facetGroup; - public bool $activeFacet; - /** @var ?int */ - public $threadCount; - - /** - * Summary of __construct - * @param string $href ?queryString relative to current endpoint - * @param ?string $title title in the OPDS catalog - * @param ?string $facetGroup facetGroup this facet belongs to - * @param bool $activeFacet is the facet currently active - * @param ?int $threadCount number of items expected - * @param ?int $database current database in multiple database setup - */ - public function __construct($href, $title = null, $facetGroup = null, $activeFacet = false, $threadCount = null, $database = null) - { - parent::__construct($href, static::LINK_RELATION, $title, $database); - $this->facetGroup = $facetGroup; - $this->activeFacet = $activeFacet; - $this->threadCount = $threadCount; - } -} diff --git a/COPS/cops-3.1.3/src/Model/LinkFeed.php b/COPS/cops-3.1.3/src/Model/LinkFeed.php deleted file mode 100644 index 6cd68ebe..00000000 --- a/COPS/cops-3.1.3/src/Model/LinkFeed.php +++ /dev/null @@ -1,61 +0,0 @@ - - */ - -namespace SebLucas\Cops\Model; - -/** - * From https://specs.opds.io/opds-1.2#23-acquisition-feeds - * An Acquisition Feed is an OPDS Catalog Feed Document that collects OPDS Catalog Entries - * into a single, ordered set. The simplest complete OPDS Catalog would be a single Acquisition - * Feed listing all of the available OPDS Catalog Entries from that provider. In more complex - * OPDS Catalogs, Acquisition Feeds are used to present and organize sets of related OPDS - * Catalog Entries for browsing and discovery by clients and aggregators. - * - * Links to Acquisition Feeds MUST use the "type" attribute - * "application/atom+xml;profile=opds-catalog;kind=acquisition" - */ -class LinkFeed extends Link -{ - public const OPDS_NAVIGATION_FEED = "application/atom+xml;profile=opds-catalog;kind=navigation"; - public const OPDS_ACQUISITION_FEED = "application/atom+xml;profile=opds-catalog;kind=acquisition"; - - public const LINK_TYPE = self::OPDS_ACQUISITION_FEED; - - /** - * Summary of __construct - * @param string $href ?queryString relative to current endpoint - * @param ?string $rel relation in the OPDS catalog - * @param ?string $title title in the OPDS catalog and elsewhere - * @param ?int $database current database in multiple database setup - */ - public function __construct($href, $rel = null, $title = null, $database = null) - { - parent::__construct($href, static::LINK_TYPE, $rel, $title); - //$this->href = Route::query($this->href, ['db' => $database]); - if (!is_null($database)) { - if (str_contains($this->href, '?')) { - $this->href .= '&db=' . $database; - } else { - $this->href .= '?db=' . $database; - } - } - } - - /** - * Summary of hrefXhtml - * @return string - */ - public function hrefXhtml() - { - // LinkFeed()->href is relative to endpoint - // @todo take into account endpoint when building href, e.g. feed.php - //return Route::base() . $endpoint . $this->href; - // LinkFeed()->href includes the endpoint here - return $this->href; - } -} diff --git a/COPS/cops-3.1.3/src/Model/LinkNavigation.php b/COPS/cops-3.1.3/src/Model/LinkNavigation.php deleted file mode 100644 index 89c8e301..00000000 --- a/COPS/cops-3.1.3/src/Model/LinkNavigation.php +++ /dev/null @@ -1,24 +0,0 @@ - - */ - -namespace SebLucas\Cops\Model; - -/** - * From https://specs.opds.io/opds-1.2#22-navigation-feeds - * A Navigation Feed is an OPDS Catalog Feed Document whose Atom Entries serve to create - * a suggested hierarchy for presentation and browsing. A Navigation Feed MUST NOT contain - * OPDS Catalog Entries but instead contains Atom Entries that link to other Navigation or - * Acquisition Feeds or other Resources. - * - * Links to Navigation Feeds MUST use the "type" attribute - * "application/atom+xml;profile=opds-catalog;kind=navigation" - */ -class LinkNavigation extends LinkFeed -{ - public const LINK_TYPE = parent::OPDS_NAVIGATION_FEED; -} diff --git a/COPS/cops-3.1.3/src/Output/BaseRenderer.php b/COPS/cops-3.1.3/src/Output/BaseRenderer.php deleted file mode 100644 index fac70ebb..00000000 --- a/COPS/cops-3.1.3/src/Output/BaseRenderer.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Output; - -use SebLucas\Cops\Input\Request; - -/** - * Base Renderer - */ -abstract class BaseRenderer -{ - /** @var Request */ - protected $request; - /** @var Response */ - protected $response; - - /** - * Summary of __construct - * @param ?Request $request - * @param ?Response $response - */ - public function __construct($request = null, $response = null) - { - if (!empty($request)) { - $this->setRequest($request); - } - if (!empty($response)) { - $this->setResponse($response); - } - } - - /** - * Summary of setRequest - * @param Request $request - * @return void - */ - public function setRequest($request) - { - $this->request = $request; - } - - /** - * Summary of setResponse - * @param Response $response - * @return void - */ - public function setResponse($response) - { - $this->response = $response; - } -} diff --git a/COPS/cops-3.1.3/src/Output/DotPHPTemplate.php b/COPS/cops-3.1.3/src/Output/DotPHPTemplate.php deleted file mode 100644 index 3659509b..00000000 --- a/COPS/cops-3.1.3/src/Output/DotPHPTemplate.php +++ /dev/null @@ -1,98 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Output; - -use SebLucas\Template\doT; - -/** - * Use doT-php template engine - * @see resources/dot-php - */ -class DotPHPTemplate extends BaseRenderer -{ - /** - * Summary of getDotTemplate - * @param string $templateFile - * @return \Closure - */ - public function getDotTemplate($templateFile) - { - // production mode was required here for issue seblucas/cops#392 - error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT); - $headcontent = file_get_contents($templateFile); - $template = new doT(); - $dot = $template->template($headcontent, null); - - return $dot; - } - - /** - * Summary of serverSide - * @param ?array $data - * @param string $theme - * @return bool|string|null - */ - public function serverSide($data, $theme = 'default') - { - // Get the templates - $header = file_get_contents('templates/' . $theme . '/header.html'); - $footer = file_get_contents('templates/' . $theme . '/footer.html'); - $main = file_get_contents('templates/' . $theme . '/main.html'); - $bookdetail = file_get_contents('templates/' . $theme . '/bookdetail.html'); - $page = file_get_contents('templates/' . $theme . '/page.html'); - - // Generate the function for the template - $template = new doT(); - $dot = $template->template($page, ['bookdetail' => $bookdetail, - 'header' => $header, - 'footer' => $footer, - 'main' => $main]); - // If there is a syntax error in the function created - // $dot will be equal to FALSE - if (!$dot) { - return false; - } - // Execute the template - if (!empty($data)) { - return $dot($data); - } - - return null; - } - - /** - * Summary of renderPage - * @param array $data - * @param string $theme - * @param bool|int $serverSide - * @return string - */ - public function renderPage($data, $theme = 'default', $serverSide = false) - { - $dot = $this->getDotTemplate('templates/' . $theme . '/file.html'); - if ($serverSide) { - // Get the page data - $json = new JsonRenderer(); - $page_it = $json->getJson($this->request, true); - if ($data['title'] != $page_it['title']) { - $data['title'] .= ' - ' . $page_it['title']; - } - // insert 'page.html' template with data here - $output = $dot($data); - $output .= "\n"; - $output .= $this->serverSide($page_it, $theme); - $output .= "\n\n"; - return $output; - } - $output = $dot($data); - $output .= "\n\n\n"; - return $output; - } -} diff --git a/COPS/cops-3.1.3/src/Output/EPubReader.php b/COPS/cops-3.1.3/src/Output/EPubReader.php deleted file mode 100644 index ca835416..00000000 --- a/COPS/cops-3.1.3/src/Output/EPubReader.php +++ /dev/null @@ -1,305 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Output; - -use SebLucas\Cops\Calibre\Book; -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Output\Format; -use SebLucas\EPubMeta\EPub; -use ZipArchive; -use Exception; - -/** - * EPub Reader based on Monocle - */ -class EPubReader extends BaseRenderer -{ - public static string $handler = "epubfs"; - public static string $template = "templates/epubreader.html"; - public static string $epubClass = EPub::class; - - /** - * Summary of getComponentContent - * @param EPub $epub - * @param string $component - * @param array $params - * @return ?string - */ - public static function getComponentContent($epub, $component, $params = []) - { - $data = $epub->component($component); - $handler = "epubfs"; - - $callback = function ($m) use ($epub, $component, $params, $handler) { - $method = $m[1]; - $path = $m[2]; - $end = ''; - if (preg_match('/^src\s*:/', $method)) { - $end = ')'; - } - if (preg_match('/^#/', $path)) { - return $method . "'" . $path . "'" . $end; - } - $hash = ''; - if (preg_match('/^(.+)#(.+)$/', $path, $matches)) { - $path = $matches[1]; - $hash = '#' . $matches[2]; - } - $comp = $epub->getComponentName($component, $path); - if (!$comp) { - return $method . "'#'" . $end; - } - $params['comp'] = $comp; - $out = $method . "'" . Route::link($handler, null, $params) . $hash . "'" . $end; - if ($end) { - return $out; - } - return str_replace('&', '&', $out); - }; - - $data = preg_replace_callback("/(src=)[\"']([^:]*?)[\"']/", $callback, $data); - $data = preg_replace_callback("/(href=)[\"']([^:]*?)[\"']/", $callback, $data); - $data = preg_replace_callback("/(\@import\s+)[\"'](.*?)[\"'];/", $callback, $data); - $data = preg_replace_callback('/(src\s*:\s*url\()(.*?)\)/', $callback, $data); - - return $data; - } - - /** - * Summary of sendContent - * @param int $idData - * @param string $component - * @param ?int $database - * @return Response - */ - public function sendContent($idData, $component, $database = null) - { - $book = Book::getBookByDataId($idData, $database); - if (!$book) { - throw new Exception('Unknown data ' . $idData); - } - $params = ['data' => $idData, 'db' => $book->getDatabaseId()]; - - $epub = new static::$epubClass($book->getFilePath('EPUB', $idData)); - $epub->initSpineComponent(); - - $data = static::getComponentContent($epub, $component, $params); - - // get mimetype for $component from EPub manifest here - $mimetype = $epub->componentContentType($component); - - // use cache control here - $this->response->setHeaders($mimetype, 0); - return $this->response->sendData($data); - } - - /** - * Summary of getReader - * @param int $idData - * @param ?string $version - * @param ?int $database - * @return string - */ - public function getReader($idData, $version = null, $database = null) - { - $version ??= Config::get('epub_reader', 'monocle'); - if ($version == 'epubjs') { - return $this->getEpubjsReader($idData, $database); - } - $book = Book::getBookByDataId($idData, $database); - if (!$book) { - throw new Exception('Unknown data ' . $idData); - } - if (!empty(Config::get('calibre_external_storage')) && str_starts_with($book->path, (string) Config::get('calibre_external_storage'))) { - return 'The "monocle" epub reader does not work with calibre_external_storage - please use "epubjs" reader instead'; - } - - try { - $epub = new static::$epubClass($book->getFilePath('EPUB', $idData)); - $epub->initSpineComponent(); - } catch (Exception $e) { - return $e->getMessage(); - } - - $components = implode(', ', array_map(function ($comp) { - return "'" . $comp . "'"; - }, $epub->components())); - - $contents = implode(', ', array_map(function ($content) { - return static::addContentItem($content); - }, $epub->contents())); - - // URL format: index.php/epubfs/{db}/{data}/{comp} - let monocle reader retrieve individual components - $db = $book->getDatabaseId() ?? 0; - $params = ['db' => $db, 'data' => $idData, 'comp' => '~COMP~']; - $link = str_replace(urlencode('~COMP~'), '~COMP~', Route::link(static::$handler, null, $params)); - - $data = [ - 'title' => $book->title, - 'version' => Config::VERSION, - 'resources' => Route::path('resources'), - 'styles' => Route::path('styles'), - 'favicon' => Route::path(Config::get('icon')), - 'components' => $components, - 'contents' => $contents, - 'link' => $link, - ]; - - return Format::template($data, static::$template); - } - - /** - * Summary of addContentItem - * @param array $item - * @return string - */ - public static function addContentItem($item) - { - if (empty($item['children'])) { - return "{title: '" . addslashes((string) $item['title']) . "', src: '" . $item['src'] . "'}"; - } - foreach (array_keys($item['children']) as $idx) { - $item['children'][$idx] = static::addContentItem($item['children'][$idx]); - } - return "{title: '" . addslashes((string) $item['title']) . "', src: '" . $item['src'] . "', children: [" . implode(', ', $item['children']) . "]}"; - } - - /** - * Encode the component name (to replace / and -) - * @param mixed $src - * @return string - */ - public static function encode($src) - { - $encodeReplace = static::$epubClass::$encodeNameReplace; - return str_replace( - $encodeReplace[0], - $encodeReplace[1], - $src - ); - } - - /** - * Decode the component name (to replace / and -) - * @param mixed $src - * @return string - */ - public static function decode($src) - { - $decodeReplace = static::$epubClass::$decodeNameReplace; - return str_replace( - $decodeReplace[0], - $decodeReplace[1], - $src - ); - } - - /** - * Summary of getEpubjsReader - * @param int $idData - * @param ?int $database - * @return string - */ - public function getEpubjsReader($idData, $database = null) - { - $handler = "zipfs"; - $template = "templates/epubjs-reader.html"; - $book = Book::getBookByDataId($idData, $database); - if (!$book) { - throw new Exception('Unknown data ' . $idData); - } - if (!empty(Config::get('calibre_external_storage')) && str_starts_with($book->path, (string) Config::get('calibre_external_storage'))) { - // URL format: full url to external epub file here - let epubjs reader handle parsing etc. in browser - $link = $book->getFilePath('EPUB', $idData, true); - if (!$link) { - throw new Exception('Unknown link ' . $idData); - } - } else { - $epub = $book->getFilePath('EPUB', $idData); - if (!$epub || !file_exists($epub)) { - throw new Exception('Unknown file ' . $epub); - } - // URL format: index.php/zipfs/{db}/{data}/{comp} - let epubjs reader retrieve individual components - $db = $book->getDatabaseId() ?? 0; - if (Config::get('use_route_urls')) { - $link = Route::link($handler, null, ['db' => $db, 'data' => $idData, 'comp' => '{component}']); - $link = str_replace('{component}', '', $link); - } else { - // @todo remove /{$handler} once link() is fixed - $link = Route::link($handler) . "/{$handler}/{$db}/{$idData}/"; - } - } - // Configurable settings (javascript object as text) - $settings = Config::get('epubjs_reader_settings'); - - $dist = Route::path(dirname((string) Config::get('assets')) . '/mikespub/epubjs-reader/dist'); - $data = [ - 'title' => htmlspecialchars($book->title), - 'version' => Config::VERSION, - 'dist' => $dist, - 'link' => $link, - 'settings' => $settings, - ]; - - return Format::template($data, $template); - } - - /** - * Summary of getZipContent - * @param string $filePath - * @param string $component - * @return ?string - */ - public function getZipFileContent($filePath, $component) - { - $zip = new ZipArchive(); - $res = $zip->open($filePath, ZipArchive::RDONLY); - if ($res !== true) { - throw new Exception('Invalid file ' . $filePath); - } - $res = $zip->locateName($component); - if ($res === false) { - throw new Exception('Unknown component ' . $component); - } - $data = $zip->getFromName($component); - $zip->close(); - - return $data; - } - - /** - * Summary of sendZipContent - * @param int $idData - * @param string $component - * @param ?int $database - * @return Response - */ - public function sendZipContent($idData, $component, $database = null) - { - $book = Book::getBookByDataId($idData, $database); - if (!$book) { - throw new Exception('Unknown data ' . $idData); - } - $filePath = $book->getFilePath('EPUB', $idData); - if (!$filePath || !file_exists($filePath)) { - throw new Exception('Unknown file ' . $filePath); - } - - $data = $this->getZipFileContent($filePath, $component); - - // get mimetype based on $component name alone here - $mimetype = Response::getMimeType($component); - - // use cache control here - $this->response->setHeaders($mimetype, 0); - return $this->response->sendData($data); - } -} diff --git a/COPS/cops-3.1.3/src/Output/FileResponse.php b/COPS/cops-3.1.3/src/Output/FileResponse.php deleted file mode 100644 index cf03e530..00000000 --- a/COPS/cops-3.1.3/src/Output/FileResponse.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Output; - -use SebLucas\Cops\Input\Config; - -class FileResponse extends Response -{ - /** - * Summary of getTempFile - * @param string $extension - * @return string - */ - public static function getTempFile($extension = '') - { - $tmpdir = sys_get_temp_dir(); - $tmpfile = tempnam($tmpdir, 'COPS'); - if (empty($extension)) { - return $tmpfile; - } - rename($tmpfile, $tmpfile . '.' . $extension); - return $tmpfile . '.' . $extension; - } - - /** - * Summary of sendFile - * @param string $filepath actual filepath - * @param bool $istmpfile with true if this is a temp file, false otherwise - * @return static - */ - public function sendFile($filepath, $istmpfile = false) - { - // detect mimetype from filepath here if needed - if (empty($this->mimetype)) { - $this->mimetype = static::getMimeType($filepath); - } - - // @todo do we send cache control for tmpfile too? - $this->sendHeaders(); - - // @todo clean up nginx x_accel_redirect - // don't use x_accel_redirect if we deal with a tmpfile here - if (!empty($istmpfile) || empty(Config::get('x_accel_redirect'))) { - header('Content-Length: ' . filesize($filepath)); - readfile($filepath); - } else { - header(Config::get('x_accel_redirect') . ': ' . $filepath); - } - - return $this; - } -} diff --git a/COPS/cops-3.1.3/src/Output/Format.php b/COPS/cops-3.1.3/src/Output/Format.php deleted file mode 100644 index c3635802..00000000 --- a/COPS/cops-3.1.3/src/Output/Format.php +++ /dev/null @@ -1,156 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Output; - -use DOMDocument; - -class Format -{ - /** - * This method is a direct copy-paste from - * http://tmont.com/blargh/2010/1/string-format-in-php - * @param string $format - * @return string - */ - public static function str_format($format) - { - $args = func_get_args(); - $format = array_shift($args); - - preg_match_all('/(?=\{)\{(\d+)\}(?!\})/', (string) $format, $matches, PREG_OFFSET_CAPTURE); - $offset = 0; - foreach ($matches[1] as $data) { - $i = $data[0]; - $format = substr_replace($format, @$args[(int) $i], $offset + $data[1] - 1, 2 + strlen($i)); - $offset += strlen((string) @$args[(int) $i]) - 2 - strlen($i); - } - - return $format; - } - - /** - * Summary of template - * @param ?array $data - * @param string $template - * @return string - */ - public static function template($data, $template) - { - // replace {{=it.key}} (= doT syntax) and {{it.key}} (= twig syntax) with value - $pattern = []; - $replace = []; - foreach ($data as $key => $value) { - array_push($pattern, '/\{\{=?\s*it\.' . $key . '\s*\}\}/'); - array_push($replace, $value); - } - $filecontent = file_get_contents($template); - return preg_replace($pattern, $replace, $filecontent); - } - - /** - * Summary of xml2xhtml - * @param string $xml - * @return ?string - */ - public static function xml2xhtml($xml) - { - return preg_replace_callback('#<(\w+)([^>]*)\s*/>#s', function ($m) { - $xhtml_tags = ['br', 'hr', 'input', 'frame', 'img', 'area', 'link', 'col', 'base', 'basefont', 'param']; - if (in_array($m[1], $xhtml_tags)) { - return '<' . $m[1] . $m[2] . ' />'; - } else { - return '<' . $m[1] . $m[2] . '>'; - } - }, $xml); - } - - /** - * Summary of display_xml_error - * @param mixed $error - * @return string - */ - public static function display_xml_error($error) - { - $return = ''; - $return .= str_repeat('-', $error->column) . "^\n"; - - switch ($error->level) { - case LIBXML_ERR_WARNING: - $return .= 'Warning ' . $error->code . ': '; - break; - case LIBXML_ERR_ERROR: - $return .= 'Error ' . $error->code . ': '; - break; - case LIBXML_ERR_FATAL: - $return .= 'Fatal Error ' . $error->code . ': '; - break; - } - - $return .= trim($error->message) . - "\n Line: " . $error->line . - "\n Column: " . $error->column; - - if ($error->file) { - $return .= "\n File: " . $error->file; - } - - return "$return\n\n--------------------------------------------\n\n"; - } - - /** - * Summary of are_libxml_errors_ok - * @return bool - */ - public static function are_libxml_errors_ok() - { - $errors = libxml_get_errors(); - - foreach ($errors as $error) { - if ($error->code == 801) { - return false; - } - } - return true; - } - - /** - * Summary of html2xhtml - * @param string $html - * @return string - */ - public static function html2xhtml($html) - { - $doc = new DOMDocument(); - libxml_use_internal_errors(true); - - $doc->loadHTML('' . - $html . ''); // Load the HTML - $output = $doc->saveXML($doc->documentElement); // Transform to an Ansi xml stream - $output = static::xml2xhtml($output); - if (preg_match('#(.*)#ms', (string) $output, $matches)) { - $output = $matches [1]; // Remove - } - /* - // In case of error with summary, use it to debug - $errors = libxml_get_errors(); - - foreach ($errors as $error) { - $output .= static::display_xml_error($error); - } - */ - - if (!static::are_libxml_errors_ok()) { - $output = 'HTML code not valid.'; - } - - libxml_use_internal_errors(false); - return $output; - } -} diff --git a/COPS/cops-3.1.3/src/Output/HtmlRenderer.php b/COPS/cops-3.1.3/src/Output/HtmlRenderer.php deleted file mode 100644 index dae9883c..00000000 --- a/COPS/cops-3.1.3/src/Output/HtmlRenderer.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Output; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Request; -use SebLucas\Cops\Input\Route; - -class HtmlRenderer extends BaseRenderer -{ - public static string $handler = "index"; - - /** - * Summary of getTemplateData - * @param Request $request - * @return array - */ - public function getTemplateData($request) - { - $data = [ - 'title' => Config::get('title_default'), - 'version' => Config::VERSION, - 'opds_url' => Route::link("feed"), - 'customHeader' => '', - 'template' => $request->template(), - 'server_side_rendering' => $request->render(), - 'current_css' => Route::path($request->style()), - 'favico' => Route::path(Config::get('icon')), - 'assets' => Route::path(Config::get('assets')), - 'images' => Route::path('images'), - 'resources' => Route::path('resources'), - 'templates' => Route::path('templates'), - 'basedir' => Route::path('.'), - 'getjson_url' => JsonRenderer::getCurrentUrl($request), - ]; - if (preg_match('/Kindle/', $request->agent())) { - $data['customHeader'] = ''; - } - return $data; - } - - /** - * Summary of render - * @param Request $request - * @return string - */ - public function render($request) - { - $data = $this->getTemplateData($request); - if (in_array($request->template(), Config::get('twig_templates'))) { - $template = new TwigTemplate($request); - return $template->renderPage($data, $request->template(), $request->render()); - } - $template = new DotPHPTemplate($request); - return $template->renderPage($data, $request->template(), $request->render()); - } -} diff --git a/COPS/cops-3.1.3/src/Output/JsonRenderer.php b/COPS/cops-3.1.3/src/Output/JsonRenderer.php deleted file mode 100644 index 05a7e18a..00000000 --- a/COPS/cops-3.1.3/src/Output/JsonRenderer.php +++ /dev/null @@ -1,758 +0,0 @@ - - */ - -namespace SebLucas\Cops\Output; - -use SebLucas\Cops\Calibre\Database; -use SebLucas\Cops\Calibre\Book; -use SebLucas\Cops\Calibre\Cover; -use SebLucas\Cops\Calibre\Filter; -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Request; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Model\Entry; -use SebLucas\Cops\Model\EntryBook; -use SebLucas\Cops\Pages\PageId; -use SebLucas\Cops\Pages\Page; -use Exception; - -class JsonRenderer extends BaseRenderer -{ - /** @var Request */ - protected $request; - /** @var ?int */ - protected $database = null; - /** @var string */ - protected $handler; - /** @var int|string */ - protected $page; - /** @var array */ - protected $extraParams = []; - - /** - * Summary of getCurrentUrl - * @param Request $request - * @return string - */ - public static function getCurrentUrl($request) - { - /** - $pathInfo = $request->path(); - $queryString = $request->query(); - //return Route::link(static::$handler) . $pathInfo . Route::query($queryString, ['complete' => 1]); - $uri = $pathInfo . Route::query($queryString, ['complete' => 1]); - if (Config::get('front_controller')) { - if (str_starts_with($uri, '/')) { - return Route::base() . substr($uri, 1); - } - return Route::base() . $uri; - } - */ - $params = $request->urlParams; - $params['complete'] = 1; - return Route::link("json", null, $params); - } - - /** - * @param Book $book - * @return array - */ - public function getBookContentArray($book) - { - $handler = $book->getHandler(); - $i = 0; - $preferedData = []; - foreach (Config::get('prefered_format') as $format) { - if ($i == 2) { - break; - } - $data = $book->getDataFormat($format); - if ($data) { - $i++; - array_push($preferedData, [ - "name" => $format, - "url" => $data->getHtmlLink(), - "viewUrl" => $data->getViewHtmlLink(), - ]); - } - } - - $authors = []; - foreach ($book->getAuthors() as $author) { - $author->setHandler($handler); - array_push($authors, [ - "name" => $author->name, - "url" => $author->getUri(), - ]); - } - - $tags = []; - foreach ($book->getTags() as $tag) { - $tag->setHandler($handler); - array_push($tags, [ - "name" => $tag->name, - "url" => $tag->getUri(), - ]); - } - - $publisher = $book->getPublisher(); - if (empty($publisher)) { - $pn = ""; - $pu = ""; - } else { - $publisher->setHandler($handler); - $pn = $publisher->name; - $pu = $publisher->getUri(); - } - - $serie = $book->getSerie(); - if (empty($serie)) { - $sn = ""; - $scn = ""; - $su = ""; - } else { - $serie->setHandler($handler); - $sn = $serie->name; - $scn = str_format(localize("content.series.data"), $book->seriesIndex, $serie->name); - $su = $serie->getUri(); - } - $cc = $book->getCustomColumnValues(Config::get('calibre_custom_column_list'), true); - - return [ - "id" => $book->id, - "detailurl" => $book->getDetailUrl($handler), - "hasCover" => $book->hasCover, - "preferedData" => $preferedData, - "preferedCount" => count($preferedData), - "rating" => $book->getRating(), - "publisherName" => $pn, - "publisherurl" => $pu, - "pubDate" => $book->getPubDate(), - "languagesName" => $book->getLanguages(), - "authorsName" => $book->getAuthorsName(), - "authors" => $authors, - "tagsName" => $book->getTagsName(), - "tags" => $tags, - "seriesName" => $sn, - "seriesIndex" => $book->seriesIndex, - "seriesCompleteName" => $scn, - "seriesurl" => $su, - "customcolumns_list" => $cc, - ]; - } - - /** - * @param Book $book - * @return array - */ - public function getFullBookContentArray($book) - { - $handler = $book->getHandler(); - $out = $this->getBookContentArray($book); - $database = $book->getDatabaseId(); - - $cover = new Cover($book); - // set height for thumbnail here depending on opds vs. html (height x 2) - if (in_array($handler, ['feed', 'opds'])) { - $thumb = "opds2"; - } else { - $thumb = "html2"; - } - $out ["thumbnailurl"] = $cover->getThumbnailUri($thumb, false); - $out ["coverurl"] = $cover->getCoverUri() ?? $out ["thumbnailurl"]; - $out ["content"] = $book->getComment(false); - $out ["datas"] = []; - $dataKindle = $book->GetMostInterestingDataToSendToKindle(); - foreach ($book->getDatas() as $data) { - $tab = [ - "id" => $data->id, - "format" => $data->format, - "url" => $data->getHtmlLink(), - "viewUrl" => $data->getViewHtmlLink(), - "mail" => 0, - "readerUrl" => "", - ]; - if (!empty(Config::get('mail_configuration')) && !is_null($dataKindle) && $data->id == $dataKindle->id) { - $tab ["mail"] = 1; - } - if ($data->format == "EPUB") { - if (Config::get('use_route_urls')) { - $tab ["readerUrl"] = Route::link("read", null, ["data" => $data->id, "db" => ($database ?? 0), "title" => $book->getTitle()]); - } else { - $tab ["readerUrl"] = Route::link("read", null, ["data" => $data->id, "db" => ($database ?? 0)]); - } - } - array_push($out ["datas"], $tab); - } - $out ["extraFiles"] = []; - foreach ($book->getExtraFiles() as $fileName) { - $link = $book->getExtraFileLink($fileName); - array_push($out ["extraFiles"], [ - "name" => $link->title, - "url" => $link->hrefXhtml(), - "length" => $link->length, - "mtime" => $link->mtime, - ]); - } - if (count($out ["extraFiles"]) > 0) { - $url = Route::link("fetch", null, ["id" => $book->id, "db" => ($database ?? 0), "file" => "zipped"]); - array_unshift($out ["extraFiles"], [ - "name" => " * ", - "url" => $url, - ]); - } - $out ["authors"] = []; - foreach ($book->getAuthors() as $author) { - $author->setHandler($handler); - array_push($out ["authors"], [ - "name" => $author->name, - "url" => $author->getUri(), - ]); - } - $out ["tags"] = []; - foreach ($book->getTags() as $tag) { - $tag->setHandler($handler); - array_push($out ["tags"], [ - "name" => $tag->name, - "url" => $tag->getUri(), - ]); - } - - $out ["identifiers"] = []; - foreach ($book->getIdentifiers() as $ident) { - array_push($out ["identifiers"], [ - "name" => $ident->formattedType, - "url" => $ident->getLink(), - ]); - } - - $out ["customcolumns_preview"] = $book->getCustomColumnValues(Config::get('calibre_custom_column_preview'), true); - - return $out; - } - - /** - * Summary of getContentArray - * @param Entry|EntryBook|null $entry - * @param array $extraParams - * @return array|bool - */ - public function getContentArray($entry, $extraParams = []) - { - if (is_null($entry)) { - return false; - } - if ($entry instanceof EntryBook) { - $out = [ - "title" => $entry->title, - "book" => $this->getBookContentArray($entry->book), - "thumbnailurl" => $entry->getThumbnail(), - "coverurl" => $entry->getImage(), - ]; - $out ["coverurl"] ??= $out ["thumbnailurl"]; - return $out; - } - $label = match ($entry->className) { - 'Author' => localize("authors.title"), - 'Identifier' => localize("identifiers.title"), - 'Language' => localize("languages.title"), - 'Publisher' => localize("publishers.title"), - 'Rating' => localize("ratings.title"), - 'Serie' => localize("series.title"), - 'Tag' => localize("tags.title"), - default => $entry->className, - }; - return [ - "class" => $label, - "title" => $entry->title, - "content" => $entry->content, - "navlink" => $entry->getNavLink($extraParams), - "number" => $entry->numberOfElement, - ]; - } - - /** - * Summary of getContentArrayTypeahead - * @param Page $currentPage - * @return array - */ - public function getContentArrayTypeahead($currentPage) - { - $out = []; - foreach ($currentPage->entryArray as $entry) { - if ($entry instanceof EntryBook) { - array_push($out, [ - "class" => $entry->className, - "title" => $entry->title, - "navlink" => $entry->book->getDetailUrl(), - ]); - } else { - array_push($out, [ - "class" => $entry->className, - "title" => $entry->title, - "navlink" => $entry->getNavLink(), - ]); - } - } - return $out; - } - - /** - * Summary of getCompleteArray - * @return array - */ - public function getCompleteArray() - { - // check for it.c.config.ignored_categories.whatever in templates for category 'whatever' - $ignoredCategories = ['dummy']; - $ignoredCategories = array_merge($ignoredCategories, $this->request->option('ignored_categories')); - $ignoredCategories = array_flip($ignoredCategories); - - $complete = [ - "version" => Config::VERSION, - "i18n" => [ - "addedDateTitle" => localize("addeddate.title"), - "coverAlt" => localize("i18n.coversection"), - "authorsTitle" => localize("authors.title"), - "authorTitle" => localize("author.title"), - "allbooksTitle" => localize("allbooks.title"), - "bookwordTitle" => localize("bookword.title"), - "recentTitle" => localize("recent.title"), - "tagsTitle" => localize("tags.title"), - "tagwordTitle" => localize("tagword.title"), - "linksTitle" => localize("links.title"), - "seriesTitle" => localize("series.title"), - "defaultTemplate" => localize("default.template"), - "customizeTitle" => localize("customize.title"), - "aboutTitle" => localize("about.title"), - "firstAlt" => localize("paging.first.alternate"), - "previousAlt" => localize("paging.previous.alternate"), - "nextAlt" => localize("paging.next.alternate"), - "lastAlt" => localize("paging.last.alternate"), - "searchAlt" => localize("search.alternate"), - "sortAlt" => localize("sort.alternate"), - "sortByTitle" => localize("sortby.title"), - "homeAlt" => localize("home.alternate"), - "cogAlt" => localize("cog.alternate"), - "permalinkAlt" => localize("permalink.alternate"), - "publisherName" => localize("publisher.name"), - "pubdateTitle" => localize("pubdate.title"), - "languagesTitle" => localize("languages.title"), - "languageTitle" => localize("language.title"), - "contentTitle" => localize("content.summary"), - "filterClearAll" => localize("filter.clearall"), - "sortorderAsc" => localize("search.sortorder.asc"), - "sortorderDesc" => localize("search.sortorder.desc"), - "customizeEmail" => localize("customize.email"), - "ratingsTitle" => localize("ratings.title"), - "ratingTitle" => localize("rating.title"), - "librariesTitle" => localize("libraries.title"), - "libraryTitle" => localize("library.title"), - "linkTitle" => localize("extra.link"), - "filesTitle" => localize("extra.files"), - "titleTitle" => localize("title.title"), - "filtersTitle" => localize("filters.title"), - "downloadAllTitle" => localize("downloadall.title"), - "downloadAllTooltip" => localize("downloadall.tooltip"), - ], - "url" => [ - "detailUrl" => str_replace(['%7B', '%7D'], ['{', '}'], Route::link($this->handler, PageId::BOOK_DETAIL, ['id' => '{0}', 'db' => '{1}'])), - // route urls do not accept non-numeric id or db to find match here - "coverUrl" => str_replace(['0', '1'], ['{0}', '{1}'], Route::link("fetch", null, ['id' => '0', 'db' => '1'])), - "thumbnailUrl" => str_replace(['0', '1'], ['{0}', '{1}'], Route::link("fetch", null, ['thumb' => 'html', 'id' => '0', 'db' => '1'])), - ], - "config" => [ - "use_fancyapps" => Config::get('use_fancyapps'), - "max_item_per_page" => Config::get('max_item_per_page'), - "kindleHack" => "", - "server_side_rendering" => $this->request->render(), - "html_tag_filter" => Config::get('html_tag_filter'), - "ignored_categories" => $ignoredCategories, - ], - ]; - if (Config::get('thumbnail_handling') == "1") { - $complete["url"]["thumbnailUrl"] = $complete["url"]["coverUrl"]; - } elseif (!empty(Config::get('thumbnail_handling'))) { - $complete["url"]["thumbnailUrl"] = Config::get('thumbnail_handling'); - } - if (preg_match("/./", $this->request->agent())) { - $complete["config"]["kindleHack"] = 'style="text-decoration: none !important;"'; - } - return $complete; - } - - /** - * Summary of addPagination - * @param Page $currentPage - * @return array - */ - public function addPagination($currentPage) - { - $out = []; - if (!$currentPage->isPaginated()) { - $out ["isPaginated"] = 0; - return $out; - } - $prevLink = $currentPage->getPrevLink(); - $nextLink = $currentPage->getNextLink(); - $out ["isPaginated"] = 1; - $out ["firstLink"] = ""; - $out ["prevLink"] = ""; - if (!is_null($prevLink)) { - $out ["firstLink"] = $currentPage->getFirstLink()->hrefXhtml(); - $out ["prevLink"] = $prevLink->hrefXhtml(); - } - $out ["nextLink"] = ""; - $out ["lastLink"] = ""; - if (!is_null($nextLink)) { - $out ["nextLink"] = $nextLink->hrefXhtml(); - $out ["lastLink"] = $currentPage->getLastLink()->hrefXhtml(); - } - $out ["maxPage"] = $currentPage->getMaxPage(); - $out ["currentPage"] = $currentPage->n; - return $out; - } - - /** - * Summary of addSortFilter - * @param Page $currentPage - * @return array - */ - public function addSortFilter($currentPage) - { - $out = []; - $out ["sorted"] = $currentPage->sorted ?? ''; - $out ["sortedBy"] = explode(' ', $out ["sorted"])[0]; - $out ["sortedDir"] = ''; - if (!empty($out ["sortedBy"])) { - if (in_array($out ["sortedBy"], ['title', 'author', 'sort', 'name', 'type', 'lang_code', 'letter', 'year', 'range', 'value', 'groupid', 'series_index'])) { - // default ascending order for anything vaguely alphabetical or grouped - $out ["sortedDir"] = str_contains($out ["sorted"], 'desc') ? 'desc' : 'asc'; - } elseif (in_array($out ["sortedBy"], ['pubdate', 'rating', 'timestamp', 'count', 'series'])) { - // default descending order for anything vaguely numerical or recent - $out ["sortedDir"] = str_contains($out ["sorted"], 'asc') ? 'asc' : 'desc'; - } else { - // default descending order for anything else we forgot above :-) - $out ["sortedDir"] = str_contains($out ["sorted"], 'asc') ? 'asc' : 'desc'; - } - } - $out ["containsBook"] = 0; - $out ["filterurl"] = false; - if ($currentPage->containsBook()) { - $out ["containsBook"] = 1; - // support {{=str_format(it.sorturl, "pubdate")}} etc. in templates (use double quotes for sort field) - $params = $this->request->getCleanParams(); - $params['sort'] = '{0}'; - $out ["sorturl"] = str_replace('%7B0%7D', '{0}', Route::link($this->handler, null, $params)); - $out ["sortoptions"] = $currentPage->getSortOptions(); - if ($currentPage->canFilter()) { - $params = $this->request->getCleanParams(); - $params['filter'] = 1; - $out ["filterurl"] = Route::link($this->handler, null, $params); - } - } elseif ($currentPage->canFilter()) { - $params = $this->request->getCleanParams(); - $params['filter'] = null; - $out ["filterurl"] = Route::link($this->handler, null, $params); - } - return $out; - } - - /** - * Summary of getFiltersArray - * @return array|false - */ - public function getFiltersArray() - { - $filters = false; - if (!$this->request->hasFilter()) { - return $filters; - } - $filters = []; - foreach (Filter::getEntryArray($this->request, $this->database) as $entry) { - array_push($filters, $this->getContentArray($entry, ['filter' => 1])); - } - if (empty($filters)) { - $filters = false; - } - return $filters; - } - - /** - * Summary of getHomeUrl - * @param string $baseurl - * @return string - */ - public function getHomeUrl($baseurl) - { - $homepage = PageId::getHomePage(); - // multiple database setup - if ($this->page != PageId::INDEX && !is_null($this->database)) { - if ($homepage != PageId::INDEX) { - $homeurl = Route::link($this->handler, PageId::INDEX, ['db' => $this->database]); - } else { - $homeurl = Route::link($this->handler, null, ['db' => $this->database]); - } - } elseif ($homepage != PageId::INDEX) { - $homeurl = Route::link($this->handler, PageId::INDEX); - } else { - $homeurl = $baseurl; - } - return $homeurl; - } - - /** - * Summary of getParentLink - * @param Page $currentPage - * @param array|false $filters - * @param string $homeurl - * @return string - */ - public function getParentUrl($currentPage, $filters, $homeurl) - { - $parenturl = ""; - if (!empty($filters) && !empty($currentPage->currentUri)) { - // if filtered, use the unfiltered uri as parent first - $parenturl = $currentPage->currentUri; - } elseif (!empty($currentPage->parentUri)) { - // otherwise use the parent uri - $parenturl = $currentPage->parentUri; - } elseif ($this->page != PageId::INDEX) { - if ($this->request->hasFilter()) { - $filterParams = $this->request->getFilterParams(); - $filterParams["db"] = $this->database; - $parenturl = Route::link($this->handler, PageId::INDEX, $filterParams); - } else { - $parenturl = $homeurl; - } - } - return $parenturl; - } - - /** - * Summary of getHierarchy - * @param Page $currentPage - * @param array $extraParams - * @return array|false - */ - public function getHierarchy($currentPage, $extraParams) - { - $hierarchy = false; - if (!$currentPage->hierarchy) { - return $hierarchy; - } - $hierarchy = [ - "parent" => $this->getContentArray($currentPage->hierarchy['parent'], $extraParams), - "current" => $this->getContentArray($currentPage->hierarchy['current'], $extraParams), - "children" => [], - "hastree" => $this->request->get('tree', false), - ]; - foreach ($currentPage->hierarchy['children'] as $entry) { - array_push($hierarchy["children"], $this->getContentArray($entry, $extraParams)); - } - return $hierarchy; - } - - /** - * Summary of getSeries - * @param Page $currentPage - * @param array $extraParams - * @return array|false - */ - public function getSeries($currentPage, $extraParams) - { - $series = false; - if (empty($currentPage->extra['series'])) { - return $series; - } - $series = []; - foreach ($currentPage->extra['series'] as $entry) { - array_push($series, $this->getContentArray($entry, $extraParams)); - } - return $series; - } - - /** - * Summary of getDownloadLinks - * @param Page $currentPage - * @param ?int $qid - * @return array|false - */ - public function getDownloadLinks($currentPage, $qid) - { - // avoid messy Javascript issue with empty array being truthy or falsy - see #40 - $download = false; - if (!$currentPage->containsBook()) { - return $download; - } - // download per page - if (!empty(Config::get('download_page'))) { - $download = []; - foreach (Config::get('download_page') as $format) { - $params = $this->request->getCleanParams(); - $params['type'] = strtolower((string) $format); - $url = Route::link(Zipper::$handler, null, $params); - array_push($download, ['url' => $url, 'format' => $format]); - } - return $download; - } - if (empty($qid)) { - return $download; - } - // download per series - if ($this->page == PageId::SERIE_DETAIL && !empty(Config::get('download_series'))) { - $download = []; - foreach (Config::get('download_series') as $format) { - $params = []; - $params['series'] = $qid; - $params['type'] = strtolower((string) $format); - $params['db'] = $this->database; - $url = Route::link(Zipper::$handler, null, $params); - array_push($download, ['url' => $url, 'format' => $format]); - } - return $download; - } - // download per author - if ($this->page == PageId::AUTHOR_DETAIL && !empty(Config::get('download_author'))) { - $download = []; - foreach (Config::get('download_author') as $format) { - $params = []; - $params['author'] = $qid; - $params['type'] = strtolower((string) $format); - $params['db'] = $this->database; - $url = Route::link(Zipper::$handler, null, $params); - array_push($download, ['url' => $url, 'format' => $format]); - } - return $download; - } - return $download; - } - - /** - * Summary of getJson - * @param Request $request - * @param bool $complete - * @return array - */ - public function getJson($request, $complete = false) - { - // Use the configured home page if needed - $homepage = PageId::getHomePage(); - $page = $request->get("page", $homepage); - $search = $request->get("search"); - $qid = $request->getId(); - $database = $request->database(); - $libraryId = $request->getVirtualLibrary(); - - try { - $currentPage = PageId::getPage($page, $request); - } catch (Exception $e) { - // this will call exit() - Response::sendError($request, $e->getMessage()); - } - - // adapt handler based on $request e.g. for rest api - $handler = $request->getHandler(); - - if ($search) { - return $this->getContentArrayTypeahead($currentPage); - } - - $this->setRequest($request); - - $out = [ "title" => $currentPage->title]; - $out ["parentTitle"] = $currentPage->parentTitle; - if (!empty($out ["parentTitle"])) { - $out ["title"] = $out ["parentTitle"] . " > " . $out ["title"]; - } - $out ["baseurl"] = Route::link($handler); - $entries = []; - $extraParams = []; - $out ["isFilterPage"] = false; - if (!empty($request->get('filter')) && !empty($currentPage->filterParams)) { - // @todo get rid of extraParams as filters should be included in navlink now - $extraParams = $currentPage->filterParams; - $out ["isFilterPage"] = true; - } - foreach ($currentPage->entryArray as $entry) { - array_push($entries, $this->getContentArray($entry, $extraParams)); - } - if (!is_null($currentPage->book)) { - // setting this on Book gets cascaded down to Data if isEpubValidOnKobo() - if (Config::get('provide_kepub') == "1" && preg_match("/Kobo/", $request->agent())) { - $currentPage->book->updateForKepub = true; - } - $out ["book"] = $this->getFullBookContentArray($currentPage->book); - } elseif ($page == PageId::BOOK_DETAIL) { - $page = PageId::INDEX; - } - $this->page = $page; - - $out ["databaseId"] = $database ?? ""; - $out ["databaseName"] = Database::getDbName($database); - if ($out ["databaseId"] == "") { - $out ["databaseName"] = ""; - } - $out ["libraryId"] = $libraryId ?? ""; - $out ["libraryName"] = Config::get('title_default'); - $out ["fullTitle"] = $out ["title"]; - if ($out ["databaseId"] != "" && $out ["databaseName"] != $out ["fullTitle"]) { - $out ["fullTitle"] = $out ["databaseName"] . " > " . $out ["fullTitle"]; - } - $out ["page"] = $page; - $out ["multipleDatabase"] = Database::isMultipleDatabaseEnabled() ? 1 : 0; - $out ["entries"] = $entries; - $out ["entriesCount"] = count($entries); - $out = array_replace($out, $this->addPagination($currentPage)); - if (!is_null($request->get("complete")) || $complete) { - $out ["c"] = $this->getCompleteArray(); - } - - $out = array_replace($out, $this->addSortFilter($currentPage)); - $out["filters"] = $this->getFiltersArray(); - - $out["abouturl"] = Route::link($handler, PageId::ABOUT, ['db' => $database]); - $out["customizeurl"] = Route::link($handler, PageId::CUSTOMIZE, ['db' => $database]); - - if ($page == PageId::ABOUT) { - $out ["fullhtml"] = $currentPage->getContent(); - } - - $out ["homeurl"] = $this->getHomeUrl($out["baseurl"]); - $out ["parenturl"] = $this->getParentUrl($currentPage, $out["filters"], $out["homeurl"]); - $out ["hierarchy"] = $this->getHierarchy($currentPage, $extraParams); - $out ["extra"] = $currentPage->extra; - if (!empty($currentPage->extra['series'])) { - $out ["extra"]["series"] = $this->getSeries($currentPage, $extraParams); - } - $out ["assets"] = Route::path(Config::get('assets')); - $out ["download"] = $this->getDownloadLinks($currentPage, $qid); - - /** @phpstan-ignore-next-line */ - if (Database::KEEP_STATS) { - $out ["dbstats"] = Database::getDbStatistics(); - } - - return $out; - } - - /** - * Summary of setRequest - * @param Request $request - * @return void - */ - public function setRequest($request) - { - $this->request = $request; - $this->database = $request->database(); - $this->handler = $request->getHandler(); - // Use the configured home page if needed - $homepage = PageId::getHomePage(); - $this->page = $request->get("page", $homepage); - } -} diff --git a/COPS/cops-3.1.3/src/Output/KiwilanOPDS.php b/COPS/cops-3.1.3/src/Output/KiwilanOPDS.php deleted file mode 100644 index 816d0300..00000000 --- a/COPS/cops-3.1.3/src/Output/KiwilanOPDS.php +++ /dev/null @@ -1,237 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Output; - -use Kiwilan\Opds\Opds; -use Kiwilan\Opds\OpdsConfig; -use Kiwilan\Opds\OpdsResponse; -use Kiwilan\Opds\Engine\Paginate\OpdsPaginate; -use Kiwilan\Opds\Entries\OpdsEntryBook; -use Kiwilan\Opds\Entries\OpdsEntryBookAuthor; -use Kiwilan\Opds\Entries\OpdsEntryNavigation; -use Kiwilan\Opds\Enums\OpdsVersionEnum; -use SebLucas\Cops\Input\Config as CopsConfig; -use SebLucas\Cops\Input\Request as CopsRequest; -use SebLucas\Cops\Input\Route as CopsRoute; -use SebLucas\Cops\Model\Entry as CopsEntry; -use SebLucas\Cops\Model\EntryBook as CopsEntryBook; -use SebLucas\Cops\Pages\Page as CopsPage; -use DateTime; - -class KiwilanOPDS -{ - public static string $handler = "opds"; - public static OpdsVersionEnum $version = OpdsVersionEnum::v2Dot0; - /** @var ?DateTime */ - private $updated = null; - - /** - * Summary of getUpdatedTime - * @return DateTime - */ - private function getUpdatedTime() - { - if (is_null($this->updated)) { - $this->updated = new DateTime(); - } - return $this->updated; - } - - /** - * Summary of getOpdsConfig - * @return OpdsConfig - */ - private function getOpdsConfig() - { - return new OpdsConfig( - name: 'Calibre', // CopsConfig::get('title_default') - author: CopsConfig::get('author_name') ?: 'Sébastien Lucas', - authorUrl: CopsConfig::get('author_uri') ?: 'http://blog.slucas.fr', - iconUrl: CopsConfig::get('icon'), - startUrl: CopsRoute::link(self::$handler), - // @todo php-opds uses this to identify search (not page=9) and adds '?q=' without checking for existing ? params - //searchUrl: self::$endpoint . '?page=8', - searchUrl: CopsRoute::link(self::$handler) . '/search', - //searchQuery: 'query', // 'q' by default for php-opds - updated: $this->getUpdatedTime(), - maxItemsPerPage: CopsConfig::get('max_item_per_page'), - forceJson: true, - ); - } - - /** - * Summary of getOpdsEntryBook - * @param CopsEntryBook $entry - * @return OpdsEntryBook - */ - private function getOpdsEntryBook($entry) - { - $authors = []; - foreach ($entry->book->getAuthors() as $author) { - $author->setHandler($entry->book->getHandler()); - $opdsEntryAuthor = new OpdsEntryBookAuthor( - name: $author->name, - uri: $author->getUri(), - ); - array_push($authors, $opdsEntryAuthor); - } - $categories = []; - foreach ($entry->book->getTags() as $category) { - array_push($categories, $category->name); - } - $published = null; - if ($entry->book->getPubDate() != "") { - $published = new DateTime($entry->book->getPubDate()); - } - $download = null; - $data = $entry->book->getDataFormat('EPUB'); - if ($data) { - $download = $data->getHtmlLink(); - } - $serie = $entry->book->getSerie(); - if ($serie) { - $serie = $serie->name; - } - $publisher = $entry->book->getPublisher(); - if ($publisher) { - $publisher = $publisher->name; - } - $opdsEntry = new OpdsEntryBook( - id: $entry->id, - title: $entry->title, - route: $entry->getNavLink(), - summary: OpdsEntryNavigation::handleContent($entry->content), - content: $entry->content, - media: $entry->getImage(), - updated: new DateTime($entry->getUpdatedTime()), - download: $download, - mediaThumbnail: $entry->getThumbnail(), - categories: $categories, - authors: $authors, - published: $published, - // Element "volume" not allowed here; expected the element end-tag, element "author", "category", "contributor", "link", "rights" or "source" or an element from another namespace - volume: $entry->book->seriesIndex, // @todo support float 1.5 - serie: $serie, - language: $entry->book->getLanguages(), - //isbn: $entry->book->uuid, - identifier: $entry->id, - publisher: $publisher, - ); - - return $opdsEntry; - } - - /** - * Summary of getOpdsEntry - * @param CopsEntry $entry - * @return OpdsEntryNavigation - */ - private function getOpdsEntry($entry) - { - $opdsEntry = new OpdsEntryNavigation( - id: $entry->id, - title: $entry->title, - route: $entry->getNavLink(), - summary: $entry->content, - media: $entry->getThumbnail(), - relation: $entry->getRelation(), - //updated: $entry->getUpdatedTime(), - updated: $this->getUpdatedTime(), - ); - if ($entry->numberOfElement) { - $opdsEntry->properties([ "numberOfItems" => $entry->numberOfElement ]); - } - - return $opdsEntry; - } - - /** - * Summary of getOpenSearch - * @param CopsRequest $request - * @return OpdsResponse - */ - public function getOpenSearch($request) - { - $opds = Opds::make($this->getOpdsConfig()) - ->title('Search') - ->url(CopsRoute::link(self::$handler) . '/search') - ->isSearch() - ->feeds([]) - ->get(); - return $opds->getResponse(); - } - - /** - * Summary of render - * @param CopsPage $page - * @param CopsRequest $request - * @return OpdsResponse - */ - public function render($page, $request) - { - $title = $page->title; - $feeds = []; - foreach ($page->entryArray as $entry) { - if ($entry instanceof CopsEntryBook) { - array_push($feeds, $this->getOpdsEntryBook($entry)); - } else { - array_push($feeds, $this->getOpdsEntry($entry)); - } - } - // @todo check with pathInfo - $url = CopsRoute::link(static::$handler, null, $request->urlParams); - //$url = $request->getCurrentUrl(static::$handler); - if ($page->isPaginated()) { - $prevLink = $page->getPrevLink(); - if (!is_null($prevLink)) { - $first = $page->getFirstLink()->hrefXhtml(); - $previous = $prevLink->hrefXhtml(); - } else { - $first = null; - $previous = null; - } - $nextLink = $page->getNextLink(); - if (!is_null($nextLink)) { - $next = $nextLink->hrefXhtml(); - $last = $page->getLastLink()->hrefXhtml(); - } else { - $next = null; - $last = null; - } - //$out ["maxPage"] = $page->getMaxPage(); - //'numberOfItems' => $page->totalNumber, - //'itemsPerPage' => $page->getNumberPerPage(), - //'currentPage' => $page->n, - // 'opensearch:startIndex' => (($page->n - 1) * $page->getNumberPerPage() + 1) - - $opds = Opds::make($this->getOpdsConfig()) - ->title($title) - ->url($url) - ->feeds($feeds) - ->paginate(new OpdsPaginate( - currentPage: $page->n, - totalItems: $page->totalNumber, - firstUrl: $first, - lastUrl: $last, - previousUrl: $previous, - nextUrl: $next, - )) // will generate pagination based on `OpdsPaginate` object - ->get(); - - } else { - $opds = Opds::make($this->getOpdsConfig()) - ->title($title) - ->url($url) - ->feeds($feeds) - ->get(); - } - return $opds->getResponse(); - } -} diff --git a/COPS/cops-3.1.3/src/Output/Mail.php b/COPS/cops-3.1.3/src/Output/Mail.php deleted file mode 100644 index e1af409e..00000000 --- a/COPS/cops-3.1.3/src/Output/Mail.php +++ /dev/null @@ -1,136 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Output; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Request; -use PHPMailer\PHPMailer\PHPMailer; -use SebLucas\Cops\Calibre\Book; - -class Mail -{ - public static int $maxSize = 10 * 1024 * 1024; - - /** - * Summary of checkConfiguration - * @todo initialize & check in constructor - * @return bool|string - */ - public function checkConfiguration() - { - $mailConfig = Config::get('mail_configuration'); - - if (is_null($mailConfig) || - !is_array($mailConfig) || - empty($mailConfig["smtp.host"]) || - empty($mailConfig["address.from"])) { - return "NOK. bad configuration."; - } - return false; - } - - /** - * Summary of checkRequest - * @param mixed $idData - * @param string $emailDest - * @return bool|string - */ - public function checkRequest($idData, $emailDest) - { - if (empty($idData)) { - return 'No data sent.'; - } - if (empty($emailDest)) { - return 'No email sent.'; - } - # Validate emailDest - if (!filter_var($emailDest, FILTER_VALIDATE_EMAIL)) { - return 'No valid email. ' . $emailDest . " is an unsupported email address. Update the email address on the settings page."; - } - return false; - } - - /** - * Summary of sendMail - * @param mixed $idData - * @param string $emailDest - * @param Request $request - * @param bool $dryRun - * @return bool|string - */ - public function sendMail($idData, $emailDest, $request, $dryRun = false) - { - $book = Book::getBookByDataId($idData, $request->database()); - if (!$book) { - return 'No email sent. Unknown book data'; - } - $data = $book->getDataById($idData); - - if (!file_exists($data->getLocalPath())) { - return 'No email sent. Attachment not found'; - } - if (filesize($data->getLocalPath()) > static::$maxSize) { - return 'No email sent. Attachment too big'; - } - - $mailConfig = Config::get('mail_configuration'); - - $mail = new PHPMailer(); - - $mail->IsSMTP(); - $mail->Timeout = 30; // 30 seconds as some files can be big - $mail->Host = $mailConfig["smtp.host"]; - if (!empty($mailConfig["smtp.secure"])) { - $mail->SMTPSecure = $mailConfig["smtp.secure"]; - $mail->Port = 465; - } - $mail->SMTPAuth = !empty($mailConfig["smtp.username"]); - if (!empty($mailConfig["smtp.username"])) { - $mail->Username = $mailConfig["smtp.username"]; - } - if (!empty($mailConfig["smtp.password"])) { - $mail->Password = $mailConfig["smtp.password"]; - } - if (!empty($mailConfig["smtp.secure"])) { - $mail->SMTPSecure = $mailConfig["smtp.secure"]; - } - if (!empty($mailConfig["smtp.port"])) { - $mail->Port = $mailConfig["smtp.port"]; - } - - $mail->From = $mailConfig["address.from"]; - $mail->FromName = Config::get('title_default'); - - $mail->AddAddress($emailDest); - - $mail->AddAttachment($data->getLocalPath()); - - $mail->IsHTML(true); - $mail->CharSet = "UTF-8"; - $mail->Subject = 'Sent by COPS : '; - if (!empty($mailConfig["subject"])) { - $mail->Subject = $mailConfig["subject"]; - } - $mail->Subject .= $data->getUpdatedFilename(); - $mail->Body = "

    " . $book->title . "

    " . $book->getAuthorsName() . "

    " . $book->getComment(); - $mail->AltBody = "Sent by COPS"; - - if ($dryRun) { - if (!$mail->preSend()) { - return 'Mailer Error: ' . $mail->ErrorInfo; - } - return false; - } - if (!$mail->Send()) { - return 'Mailer Error: ' . $mail->ErrorInfo; - } - return false; - } -} diff --git a/COPS/cops-3.1.3/src/Output/OpdsRenderer.php b/COPS/cops-3.1.3/src/Output/OpdsRenderer.php deleted file mode 100644 index a959aaaa..00000000 --- a/COPS/cops-3.1.3/src/Output/OpdsRenderer.php +++ /dev/null @@ -1,498 +0,0 @@ - - */ - -namespace SebLucas\Cops\Output; - -use SebLucas\Cops\Calibre\Book; -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Request; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Model\Entry; -use SebLucas\Cops\Model\EntryBook; -use SebLucas\Cops\Model\LinkEntry; -use SebLucas\Cops\Model\LinkFacet; -use SebLucas\Cops\Model\LinkFeed; -use SebLucas\Cops\Model\LinkNavigation; -use SebLucas\Cops\Pages\PageId; -use SebLucas\Cops\Pages\Page; -use XMLWriter; - -class OpdsRenderer extends BaseRenderer -{ - public static string $handler = "feed"; - /** @var ?XMLWriter */ - protected $xmlStream = null; - /** @var ?int */ - protected $updated = null; - /** @var Request */ - protected $request; - - /** - * Summary of getUpdatedTime - * @return string - */ - protected function getUpdatedTime() - { - if (is_null($this->updated)) { - $this->updated = time(); - } - return date(DATE_ATOM, $this->updated); - } - - /** - * Summary of getXmlStream - * @return XMLWriter - */ - protected function getXmlStream() - { - if (is_null($this->xmlStream)) { - $this->xmlStream = new XMLWriter(); - $this->xmlStream->openMemory(); - $this->xmlStream->setIndent(true); - } - return $this->xmlStream; - } - - /** - * Summary of getOpenSearch - * @param Request $request - * @return string - */ - public function getOpenSearch($request) - { - $database = $request->database(); - $xml = new XMLWriter(); - $xml->openMemory(); - $xml->setIndent(true); - $xml->startDocument('1.0', 'UTF-8'); - $xml->startElement("OpenSearchDescription"); - $xml->writeAttribute("xmlns", "http://a9.com/-/spec/opensearch/1.1/"); - $xml->startElement("ShortName"); - $xml->text("My catalog"); - $xml->endElement(); - $xml->startElement("Description"); - $xml->text("Search for ebooks"); - $xml->endElement(); - $xml->startElement("InputEncoding"); - $xml->text("UTF-8"); - $xml->endElement(); - $xml->startElement("OutputEncoding"); - $xml->text("UTF-8"); - $xml->endElement(); - $xml->startElement("Image"); - $xml->writeAttribute("type", "image/x-icon"); - $xml->writeAttribute("width", "16"); - $xml->writeAttribute("height", "16"); - $xml->text(Config::get('icon')); - $xml->endElement(); - $xml->startElement("Url"); - $xml->writeAttribute("type", 'application/atom+xml'); - $params = ["query" => "{searchTerms}", "db" => $database]; - $url = Route::link(static::$handler, null, $params); - $url = str_replace("%7B", "{", $url); - $url = str_replace("%7D", "}", $url); - $xml->writeAttribute("template", $url); - $xml->endElement(); - $xml->startElement("Query"); - $xml->writeAttribute("role", "example"); - $xml->writeAttribute("searchTerms", "robot"); - $xml->endElement(); - $xml->endElement(); - $xml->endDocument(); - return $xml->outputMemory(true); - } - - /** - * Summary of startXmlDocument - * @param Page $page - * @param Request $request - * @return void - */ - protected function startXmlDocument($page, $request) - { - $database = $request->database(); - $this->getXmlStream()->startDocument('1.0', 'UTF-8'); - $this->getXmlStream()->startElement("feed"); - $this->getXmlStream()->writeAttribute("xmlns", "http://www.w3.org/2005/Atom"); - $this->getXmlStream()->writeAttribute("xmlns:xhtml", "http://www.w3.org/1999/xhtml"); - $this->getXmlStream()->writeAttribute("xmlns:opds", "http://opds-spec.org/2010/catalog"); - $this->getXmlStream()->writeAttribute("xmlns:opensearch", "http://a9.com/-/spec/opensearch/1.1/"); - $this->getXmlStream()->writeAttribute("xmlns:dcterms", "http://purl.org/dc/terms/"); - $this->getXmlStream()->writeAttribute("xmlns:thr", "http://purl.org/syndication/thread/1.0"); - $this->getXmlStream()->startElement("title"); - $this->getXmlStream()->text($page->title); - $this->getXmlStream()->endElement(); - if ($page->subtitle != "") { - $this->getXmlStream()->startElement("subtitle"); - $this->getXmlStream()->text($page->subtitle); - $this->getXmlStream()->endElement(); - } - $this->getXmlStream()->startElement("id"); - if ($page->idPage) { - $idPage = $page->idPage; - if (!is_null($request->database())) { - $idPage = str_replace("cops:", "cops:" . strval($request->database()) . ":", $idPage); - } - $this->getXmlStream()->text($idPage); - } else { - $this->getXmlStream()->text($request->uri()); - } - $this->getXmlStream()->endElement(); - $this->getXmlStream()->startElement("updated"); - $this->getXmlStream()->text($this->getUpdatedTime()); - $this->getXmlStream()->endElement(); - $this->getXmlStream()->startElement("icon"); - $this->getXmlStream()->text($page->favicon); - $this->getXmlStream()->endElement(); - $this->getXmlStream()->startElement("author"); - $this->getXmlStream()->startElement("name"); - $this->getXmlStream()->text($page->authorName); - $this->getXmlStream()->endElement(); - $this->getXmlStream()->startElement("uri"); - $this->getXmlStream()->text($page->authorUri); - $this->getXmlStream()->endElement(); - $this->getXmlStream()->startElement("email"); - $this->getXmlStream()->text($page->authorEmail); - $this->getXmlStream()->endElement(); - $this->getXmlStream()->endElement(); - $url = Route::link(static::$handler); - $link = new LinkNavigation($url, "start", "Home"); - $this->renderLink($link); - // @todo check with pathInfo - $url = Route::link(static::$handler, null, $request->urlParams); - //$url = $request->getCurrentUrl(static::$handler); - if ($page->containsBook()) { - $link = new LinkFeed($url, "self"); - } else { - $link = new LinkNavigation($url, "self"); - } - $this->renderLink($link); - $params = ["db" => $database]; - if (Config::get('generate_invalid_opds_stream') == 0 || preg_match("/(MantanoReader|FBReader)/", $request->agent())) { - // Good and compliant way of handling search - $url = Route::link(static::$handler, PageId::OPENSEARCH, $params); - $link = new LinkEntry( - $url, - "application/opensearchdescription+xml", - "search", - "Search here" - ); - } else { - // Bad way, will be removed when OPDS client are fixed - $params["query"] = "{searchTerms}"; - $url = Route::link(static::$handler, null, $params); - $url = str_replace("%7B", "{", $url); - $url = str_replace("%7D", "}", $url); - $link = new LinkEntry( - $url, - "application/atom+xml", - "search", - "Search here" - ); - } - $this->renderLink($link); - if ($page->containsBook() && !is_null(Config::get('books_filter')) && count(Config::get('books_filter')) > 0) { - $Urlfilter = $request->get("tag", ""); - foreach (Config::get('books_filter') as $lib => $filter) { - //$link = new LinkFacet(Route::query($request->query(), ["tag" => $filter]), $lib, localize("tagword.title"), $filter == $Urlfilter, null, $database); - $params = array_replace($request->urlParams, ["tag" => $filter]); - $url = Route::link(static::$handler, null, $params); - $link = new LinkFacet( - $url, - $lib, - localize("tagword.title"), - $filter == $Urlfilter, - null, - $database - ); - $this->renderLink($link); - } - } - } - - /** - * Summary of endXmlDocument - * @return string - */ - protected function endXmlDocument() - { - $this->getXmlStream()->endElement(); - $this->getXmlStream()->endDocument(); - return $this->getXmlStream()->outputMemory(true); - } - - /** - * Summary of renderLink - * @param LinkEntry|LinkFeed $link - * @param ?int $number - * @return void - */ - protected function renderLink($link, $number = null) - { - $this->getXmlStream()->startElement("link"); - $this->getXmlStream()->writeAttribute("href", $link->hrefXhtml()); - $this->getXmlStream()->writeAttribute("type", $link->type); - if (!is_null($link->rel)) { - $this->getXmlStream()->writeAttribute("rel", $link->rel); - } - if (!is_null($link->title)) { - $this->getXmlStream()->writeAttribute("title", $link->title); - } - if ($link instanceof LinkEntry) { - if (!empty($link->length)) { - $this->getXmlStream()->writeAttribute("length", $link->length); - } - if (!empty($link->mtime)) { - // this corresponds to "mtime" in Calibre content server (= non-standard) - $this->getXmlStream()->writeAttribute("dcterms:modified", $link->mtime); - } - } elseif ($link instanceof LinkFacet) { - if (!is_null($link->facetGroup)) { - $this->getXmlStream()->writeAttribute("opds:facetGroup", $link->facetGroup); - } - if ($link->activeFacet) { - $this->getXmlStream()->writeAttribute("opds:activeFacet", "true"); - } - if (!empty($link->threadCount)) { - $this->getXmlStream()->writeAttribute("thr:count", (string) $link->threadCount); - } - } elseif ($link instanceof LinkFeed && !empty($number)) { - $this->getXmlStream()->writeAttribute("thr:count", (string) $number); - } - $this->getXmlStream()->endElement(); - } - - /** - * Summary of getPublicationDate - * @param Book $book - * @return string - */ - protected function getPublicationDate($book) - { - $dateYmd = substr($book->pubdate, 0, 10); - $pubdate = \DateTime::createFromFormat('Y-m-d', $dateYmd); - if ($pubdate === false || - $pubdate->format("Y") == "0101" || - $pubdate->format("Y") == "0100") { - return ""; - } - return $pubdate->format("Y-m-d"); - } - - /** - * Summary of renderEntry - * @param Entry|EntryBook $entry - * @return void - */ - protected function renderEntry($entry) - { - $this->getXmlStream()->startElement("title"); - $this->getXmlStream()->text($entry->title); - $this->getXmlStream()->endElement(); - $this->getXmlStream()->startElement("updated"); - $this->getXmlStream()->text($this->getUpdatedTime()); - $this->getXmlStream()->endElement(); - $this->getXmlStream()->startElement("id"); - $this->getXmlStream()->text($entry->id); - $this->getXmlStream()->endElement(); - $this->getXmlStream()->startElement("content"); - $this->getXmlStream()->writeAttribute("type", $entry->contentType); - $this->getXmlStream()->text($entry->content); - $this->getXmlStream()->endElement(); - - if ($entry::class != EntryBook::class) { - foreach ($entry->linkArray as $link) { - $this->renderLink($link, $entry->numberOfElement); - } - return; - } - - foreach ($entry->linkArray as $link) { - $this->renderLink($link); - } - - foreach ($entry->book->getAuthors() as $author) { - $author->setHandler($entry->book->getHandler()); - $this->getXmlStream()->startElement("author"); - $this->getXmlStream()->startElement("name"); - $this->getXmlStream()->text($author->name); - $this->getXmlStream()->endElement(); - $this->getXmlStream()->startElement("uri"); - $this->getXmlStream()->text($author->getUri()); - $this->getXmlStream()->endElement(); - $this->getXmlStream()->endElement(); - } - foreach ($entry->book->getTags() as $category) { - $this->getXmlStream()->startElement("category"); - $this->getXmlStream()->writeAttribute("term", $category->name); - $this->getXmlStream()->writeAttribute("label", $category->name); - $this->getXmlStream()->endElement(); - } - if ($entry->book->getPubDate() != "") { - $this->getXmlStream()->startElement("dcterms:issued"); - $this->getXmlStream()->text($this->getPublicationDate($entry->book)); - $this->getXmlStream()->endElement(); - $this->getXmlStream()->startElement("published"); - $this->getXmlStream()->text($this->getPublicationDate($entry->book) . "T08:08:08Z"); - $this->getXmlStream()->endElement(); - } - - $lang = $entry->book->getLanguages(); - if (!empty($lang)) { - $this->getXmlStream()->startElement("dcterms:language"); - $this->getXmlStream()->text($lang); - $this->getXmlStream()->endElement(); - } - } - - /** - * Summary of addPagination - * @param Page $page - * @return void - */ - public function addPagination($page) - { - $this->getXmlStream()->startElement("opensearch:totalResults"); - $this->getXmlStream()->text((string) $page->totalNumber); - $this->getXmlStream()->endElement(); - $this->getXmlStream()->startElement("opensearch:itemsPerPage"); - $this->getXmlStream()->text(Config::get('max_item_per_page')); - $this->getXmlStream()->endElement(); - $this->getXmlStream()->startElement("opensearch:startIndex"); - $this->getXmlStream()->text((string) (($page->n - 1) * Config::get('max_item_per_page') + 1)); - $this->getXmlStream()->endElement(); - $prevLink = $page->getPrevLink(); - $nextLink = $page->getNextLink(); - if (!is_null($prevLink)) { - $this->renderLink($page->getFirstLink()); - $this->renderLink($prevLink); - } - if (!is_null($nextLink)) { - $this->renderLink($nextLink); - $this->renderLink($page->getLastLink()); - } - } - - /** - * Summary of addSort - * @param Page $page - * @param Request $request - * @return void - */ - public function addSort($page, $request) - { - if (!$page->containsBook() || empty(Config::get('opds_sort_links'))) { - return; - } - $params = $request->getCleanParams(); - $params['sort'] = null; - $sortUrl = Route::link(static::$handler, null, $params); - if (str_contains($sortUrl, '?')) { - $sortUrl .= "&sort={0}"; - } else { - $sortUrl .= "?sort={0}"; - } - $sortLabel = localize("sort.alternate"); - $sortParam = $request->get('sort'); - $sortOptions = $page->getSortOptions(); - // @todo we can't use really facetGroups here, or OPDS reader thinks we're drilling down :-() - foreach ($sortOptions as $field => $title) { - $url = str_format($sortUrl, $field); - $link = new LinkFacet( - $url, - $title, - $sortLabel, - $field == $sortParam, - null - ); - //$link = new LinkNavigation($url, 'http://opds-spec.org/sort/' . $field, $sortLabel . ' ' . $title); - //$link = new LinkFeed($url, 'http://opds-spec.org/sort/' . $field, $sortLabel . ' ' . $title); - $this->renderLink($link); - } - } - - /** - * Summary of addFilter - * @param Page $page - * @param Request $request - * @return void - */ - public function addFilter($page, $request) - { - if (!$page->containsBook()) { - return; - } - if (!$page->canFilter()) { - return; - } - //$params = $request->getCleanParams(); - //$params['filter'] = 1; - //$url = Route::link(static::$handler, null, $params); - //$filterLabel = localize("cog.alternate"); - //$title = localize("links.title"); - //$link = new LinkFacet($url, $title, $filterLabel, false, null, $database); - //$this->renderLink($link); - // Note: facets are only shown if there are books available, so we need to get a filter page here - $req = Request::build($request->urlParams, static::$handler); - $req->set('filter', 1); - $filterPage = PageId::getPage($request->get('page'), $req); - //$request->set('filter', null); - // @todo get rid of extraParams as filters should be included in navlink now - $extraParams = $filterPage->filterParams; - if ($request->get('sort')) { - $extraParams['sort'] = $request->get('sort'); - } - // @todo handle special case of OPDS not expecting filter while HTML does better - unset($extraParams['filter']); - $database = $request->database(); - foreach ($filterPage->entryArray as $entry) { - if (empty($entry->className)) { - continue; - } - $group = strtolower($entry->className); - $group = localize($group . 's.title'); - $url = $entry->getNavLink($extraParams); - $link = new LinkFacet( - $url, - $entry->title, - $group, - false, - $entry->numberOfElement, - $database - ); - $this->renderLink($link); - } - } - - /** - * Summary of render - * @param Page $page - * @param Request $request - * @return string - */ - public function render($page, $request) - { - $this->startXmlDocument($page, $request); - if ($page->isPaginated()) { - $this->addPagination($page); - // only show sorting when paginating - $this->addSort($page, $request); - } - // always show filters even when not paginating - $this->addFilter($page, $request); - foreach ($page->entryArray as $entry) { - if (!$entry->isValidForOPDS()) { - continue; - } - $this->getXmlStream()->startElement("entry"); - $this->renderEntry($entry); - $this->getXmlStream()->endElement(); - } - return $this->endXmlDocument(); - } -} diff --git a/COPS/cops-3.1.3/src/Output/Response.php b/COPS/cops-3.1.3/src/Output/Response.php deleted file mode 100644 index 7ab81e0f..00000000 --- a/COPS/cops-3.1.3/src/Output/Response.php +++ /dev/null @@ -1,167 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Output; - -use SebLucas\Cops\Calibre\Data; -use SebLucas\Cops\Input\Request; -use SebLucas\Cops\Input\Route; - -class Response -{ - protected int $status = 200; - protected ?string $mimetype; - protected ?int $expires; - protected ?string $filename; - - /** - * Summary of getMimeType - * @param string $filepath - * @return ?string mimetype for known extension or existing file, or null if undefined - */ - public static function getMimeType($filepath) - { - $extension = pathinfo($filepath, PATHINFO_EXTENSION); - if (array_key_exists($extension, Data::$mimetypes)) { - $mimetype = Data::$mimetypes[$extension]; - } elseif (file_exists($filepath)) { - $mimetype = mime_content_type($filepath); - if (!$mimetype) { - $mimetype = 'application/octet-stream'; - } - } else { - // undefined mimetype - do not set Content-Type - $mimetype = null; - } - return $mimetype; - } - - /** - * Summary of __construct - * @param ?string $mimetype with null = no mimetype, '...' = actual mimetype for Content-Type - * @param ?int $expires with null = no cache control, 0 = default expiration, > 0 actual expiration - * @param ?string $filename with null = no disposition, '' = inline, '...' = attachment filename - * @return void - */ - public function __construct($mimetype = null, $expires = null, $filename = null) - { - $this->setHeaders($mimetype, $expires, $filename); - } - - /** - * Summary of setHeaders - * @param ?string $mimetype with null = no mimetype, '...' = actual mimetype for Content-Type - * @param ?int $expires with null = no cache control, 0 = default expiration, > 0 actual expiration - * @param ?string $filename with null = no disposition, '' = inline, '...' = attachment filename - * @return void - */ - public function setHeaders($mimetype = null, $expires = null, $filename = null) - { - $this->mimetype = $mimetype; - $this->expires = $expires; - $this->filename = $filename; - } - - /** - * Summary of sendHeaders - * @return void - */ - public function sendHeaders() - { - if (headers_sent()) { - return; - } - - if (is_null($this->expires)) { - // no cache control - } elseif (empty($this->expires)) { - // use default expiration (14 days) - $this->expires = 60 * 60 * 24 * 14; - } - if (!empty($this->expires)) { - header('Pragma: public'); - header('Cache-Control: max-age=' . $this->expires); - header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $this->expires) . ' GMT'); - } - - if (!empty($this->mimetype)) { - header('Content-Type: ' . $this->mimetype); - } - - if (is_null($this->filename)) { - // no content disposition - } elseif (empty($this->filename)) { - header('Content-Disposition: inline'); - } else { - header('Content-Disposition: attachment; filename="' . basename($this->filename) . '"'); - } - } - - /** - * Summary of sendData - * @param string $data actual data - * @return static - */ - public function sendData($data) - { - $this->sendHeaders(); - - echo $data; - - return $this; - } - - /** - * Summary of notFound - * @param ?Request $request - * @return never - */ - public static function notFound($request = null): never - { - header(($_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.1') . ' 404 Not Found'); - header('Status: 404 Not Found'); - - $_SERVER['REDIRECT_STATUS'] = 404; - $data = ['link' => Route::link("index")]; - $template = 'templates/notfound.html'; - echo Format::template($data, $template); - exit; - } - - /** - * Summary of sendError - * @param ?Request $request - * @param string|null $error - * @param array $params - * @return never - */ - public static function sendError($request = null, $error = null, $params = ['page' => 'index', 'db' => 0, 'vl' => 0]): never - { - header(($_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.1') . ' 404 Not Found'); - header('Status: 404 Not Found'); - - $_SERVER['REDIRECT_STATUS'] = 404; - $data = ['link' => Route::link("index", null, $params)]; - $data['error'] = htmlspecialchars($error ?? 'Unknown Error'); - $template = 'templates/error.html'; - echo Format::template($data, $template); - exit; - } - - /** - * Summary of redirect - * @param string $location - * @return void - */ - public static function redirect($location) - { - header('Location: ' . $location); - //exit; - } -} diff --git a/COPS/cops-3.1.3/src/Output/RestApi.php b/COPS/cops-3.1.3/src/Output/RestApi.php deleted file mode 100644 index e47d291b..00000000 --- a/COPS/cops-3.1.3/src/Output/RestApi.php +++ /dev/null @@ -1,881 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Output; - -use SebLucas\Cops\Calibre\Annotation; -use SebLucas\Cops\Calibre\CustomColumnType; -use SebLucas\Cops\Calibre\Database; -use SebLucas\Cops\Calibre\Metadata; -use SebLucas\Cops\Calibre\Note; -use SebLucas\Cops\Calibre\Resource; -use SebLucas\Cops\Calibre\Preference; -use SebLucas\Cops\Calibre\User; -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Request; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Pages\PageId; -use SebLucas\Cops\Framework; -use Exception; - -/** - * Basic REST API routing to JSON Renderer - * Note: this supports all other routes with /restapi prefix - */ -class RestApi extends BaseRenderer -{ - public static string $handler = "restapi"; - public static int $numberPerPage = 100; - public static bool $doRunEndpoint = false; // @todo disabled for now - - /** - * Summary of extra - * @var array> - */ - public static $extra = [ - "/custom" => [self::class, 'getCustomColumns'], - "/databases" => [self::class, 'getDatabases'], - "/openapi" => [self::class, 'getOpenApi'], - "/routes" => [self::class, 'getRoutes'], - "/pages" => [self::class, 'getPages'], - "/notes" => [self::class, 'getNotes'], - "/preferences" => [self::class, 'getPreferences'], - "/annotations" => [self::class, 'getAnnotations'], - "/metadata" => [self::class, 'getMetadata'], - "/user" => [self::class, 'getUser'], - ]; - - public bool $isExtra = false; - - /** - * Summary of getPathInfo - * @return string - */ - public function getPathInfo() - { - $path = $this->request->path("/index"); - // Note: this supports all other routes with /restapi prefix - if (str_starts_with($path, '/restapi/')) { - $path = substr($path, strlen('/restapi')); - } - return $path; - } - - /** - * Summary of matchPathInfo - * @param string $path - * @throws Exception if the $path is not found in $routes or $extra - * @return ?array - */ - public function matchPathInfo($path) - { - if ($path == '/') { - return null; - } - - // handle extra functions - $root = '/' . explode('/', $path . '/')[1]; - if (array_key_exists($root, static::$extra)) { - $params = Route::match($path); - if (!empty($params['page']) && $params['page'] != PageId::REST_API) { - return $params; - } - $this->isExtra = true; - unset($params['page']); - if (!empty($params)) { - $this->setParams($params); - } - return call_user_func(static::$extra[$root], $this->request); - } - - // match path with routes - return Route::match($path); - } - - /** - * Summary of setParams - * @param array $params - * @return Request - */ - public function setParams($params) - { - foreach ($params as $param => $value) { - $this->request->set($param, $value); - } - return $this->request; - } - - /** - * Summary of getJson - * @return array - */ - public function getJson() - { - $json = new JsonRenderer(); - return $json->getJson($this->request); - } - - /** - * Summary of runEndpoint - * @param string $path - * @param array $params - * @param ?bool $run - * @return array|null - */ - public function runEndpoint($path, $params, $run = null) - { - if (empty($params[Route::HANDLER_PARAM]) || !array_key_exists($params[Route::HANDLER_PARAM], Config::ENDPOINT)) { - return ["error" => "Invalid endpoint"]; - } - if (!$this->request->hasValidApiKey()) { - return ["error" => "Invalid api key"]; - } - $name = $params[Route::HANDLER_PARAM]; - //$endpoint = Config::ENDPOINT[$name]; - // check if the path starts with the endpoint param here - //if (str_starts_with($path, '/' . $name)) { - // $parts = array_slice(explode('/', $path), 2); - // $path = '/' . implode('/', $parts); - //} - // run endpoint via handler now - $handler = Framework::getHandler($name); - unset($params[Route::HANDLER_PARAM]); - $run ??= static::$doRunEndpoint; - if ($run) { - $oldpath = $_SERVER['PATH_INFO'] ?? ''; - $oldparams = $_GET; - $_SERVER['PATH_INFO'] = $path; - $_GET = $params; - // @todo define when to parse request path or not - see calres, loader and zipfs - $request = Framework::getRequest($name); - $handler->handle($request); - //require dirname(__DIR__, 2) . '/' . $endpoint; - $_SERVER['PATH_INFO'] = $oldpath; - $_GET = $oldparams; - return null; - } - $result = [Route::HANDLER_PARAM => $name, "path" => $path, "params" => $params]; - return $result; - } - - /** - * Summary of getScriptName - * @param Request $request - * @deprecated 3.1.0 use index.php endpoint - * @return string - */ - public static function getScriptName($request) - { - return $request->getEndpoint(Config::ENDPOINT["restapi"]); - } - - /** - * Summary of getOutput - * @param mixed $result - * @return string - */ - public function getOutput($result = null) - { - if (!isset($result)) { - $path = $this->getPathInfo(); - $params = $this->matchPathInfo($path); - if (!isset($params)) { - Response::redirect(Route::link(static::$handler) . '/index'); - return ''; - } - if ($this->isExtra) { - $result = $params; - } elseif (empty($params[Route::HANDLER_PARAM]) || $params[Route::HANDLER_PARAM] == 'json') { - $this->setParams($params); - $result = $this->getJson(); - } else { - // extra routes supported by other endpoints - $result = $this->runEndpoint($path, $params); - if (is_null($result)) { - return ''; - } - } - } - $output = json_encode($result, JSON_UNESCAPED_SLASHES); - //$endpoint = static::getScriptName($this->request); - - return $output; - } - - /** - * Summary of getCustomColumns - * @param Request $request - * @return array - */ - public static function getCustomColumns($request) - { - $db = $request->database(); - $columns = CustomColumnType::getAllCustomColumns(); - $baseurl = Route::link(static::$handler); - $result = [ - "title" => "Custom Columns", - "baseurl" => $baseurl, - "entries" => [], - ]; - foreach ($columns as $title => $column) { - $column["navlink"] = "{$baseurl}/custom/{$column['id']}" . Route::params(["db" => $db]); - array_push($result["entries"], $column); - } - return $result; - } - - /** - * Summary of getDatabases - * @param Request $request - * @return array - */ - public static function getDatabases($request) - { - $db = $request->database(); - if (!is_null($db) && Database::checkDatabaseAvailability($db)) { - return static::getDatabase($db, $request); - } - $baseurl = Route::link(static::$handler); - $result = [ - "title" => "Databases", - "baseurl" => $baseurl, - "entries" => [], - ]; - $id = 0; - foreach (Database::getDbNameList() as $key) { - array_push($result["entries"], [ - "class" => "Database", - "title" => $key, - "id" => $id, - "navlink" => "{$baseurl}/databases/{$id}", - ]); - $id += 1; - } - return $result; - } - - /** - * Summary of getDatabase - * @param int $database - * @param Request $request - * @return array - */ - public static function getDatabase($database, $request) - { - if (!Database::isMultipleDatabaseEnabled() && $database != 0) { - return [ - "title" => "Database Invalid", - "entries" => [], - ]; - } - $name = $request->get('name', null, '/^\w+$/'); - if (!empty($name)) { - return static::getTable($database, $name, $request); - } - $title = "Database"; - $dbName = Database::getDbName($database); - if (!empty($dbName)) { - $title .= " $dbName"; - } - $baseurl = Route::link(static::$handler); - $type = $request->get('type', null, '/^\w+$/'); - if (in_array($type, ['table', 'view'])) { - $title .= " Type $type"; - $result = [ - "title" => $title, - "baseurl" => $baseurl, - "entries" => [], - ]; - $entries = Database::getDbSchema($database, $type); - foreach ($entries as $entry) { - $entry["navlink"] = "{$baseurl}/databases/{$database}/{$entry['tbl_name']}"; - unset($entry["sql"]); - array_push($result["entries"], $entry); - } - $result["version"] = Database::getUserVersion($database); - return $result; - } - $title .= " Types"; - $result = [ - "title" => $title, - "baseurl" => $baseurl, - "entries" => [], - ]; - $metadata = [ - "table" => "Tables", - "view" => "Views", - ]; - foreach ($metadata as $name => $title) { - array_push($result["entries"], [ - "class" => "Metadata", - "title" => $title, - "navlink" => "{$baseurl}/databases/{$database}?type={$name}", - ]); - } - $result["version"] = Database::getUserVersion($database); - return $result; - } - - /** - * Summary of getTable - * @param int $database - * @param string $name - * @param Request $request - * @return array - */ - public static function getTable($database, $name, $request) - { - $title = "Database"; - $dbName = Database::getDbName($database); - if (!empty($dbName)) { - $title .= " $dbName"; - } - $title .= " Table $name"; - $baseurl = Route::link(static::$handler); - $result = [ - "title" => $title, - "baseurl" => $baseurl, - "entries" => [], - ]; - if (!$request->hasValidApiKey()) { - $result["error"] = "Invalid api key"; - return $result; - } - $query = "SELECT COUNT(*) FROM {$name}"; - $count = Database::querySingle($query, $database); - $result["total"] = $count; - $result["limit"] = static::$numberPerPage; - $start = 0; - $n = (int) $request->get('n', 1, '/^\d+$/'); - if ($n > 0 && $n < ceil($count / static::$numberPerPage)) { - $start = ($n - 1) * static::$numberPerPage; - } - $result["offset"] = $start; - $query = "SELECT * FROM {$name} LIMIT ?, ?"; - $res = Database::query($query, [$start, static::$numberPerPage], $database); - while ($post = $res->fetchObject()) { - $entry = (array) $post; - $entry["navlink"] = "{$baseurl}/databases/{$database}/{$name}?id={$entry['id']}"; - array_push($result["entries"], $entry); - } - $result["columns"] = Database::getTableInfo($database, $name); - return $result; - } - - /** - * Summary of getOpenApi - * @param Request $request - * @return array - */ - public static function getOpenApi($request) - { - $result = [ - "openapi" => "3.0.3", - "info" => [ - "title" => "COPS REST API", - "version" => Config::VERSION, - ], - ]; - $result["servers"] = [ - ["url" => Route::link(static::$handler), "description" => "COPS REST API Endpoint"], - ]; - $result["components"] = [ - "securitySchemes" => [ - "ApiKeyAuth" => [ - "type" => "apiKey", - "in" => "header", - "name" => "X-API-KEY", - ], - "BasicAuth" => [ - "type" => "http", - "scheme" => "basic", - ], - ], - ]; - $result["components"]["parameters"] = [ - "dbParam" => [ - "name" => "db", - "in" => "query", - "required" => false, - "schema" => [ - "type" => "integer", - "minimum" => 0, - ], - ], - ]; - $result["paths"] = []; - foreach (Route::getRoutes() as $route => $queryParams) { - if (str_starts_with($route, '/restapi')) { - continue; - } - $params = []; - $found = []; - $queryString = http_build_query($queryParams); - // support custom pattern for route placeholders - see nikic/fast-route - if (preg_match_all("~\{(\w+(|:[^}]+))\}~", $route, $found)) { - foreach ($found[1] as $param) { - $schema = [ - "type" => "string", - ]; - if (str_contains($param, ':')) { - [$param, $pattern] = explode(':', $param); - $schema["pattern"] = '^' . $pattern . '$'; - $route = str_replace(':' . $pattern, '', $route); - } - if ($param !== 'ignore') { - $queryString .= "&{$param}=" . '{' . $param . '}'; - } - array_push($params, [ - "name" => $param, - "in" => "path", - "required" => true, - "schema" => $schema, - ]); - } - } - if (!empty($queryParams[Route::HANDLER_PARAM]) && $queryParams[Route::HANDLER_PARAM] == "restapi") { - $queryString = substr($route, 1); - } elseif (!empty($queryParams[Route::HANDLER_PARAM])) { - $testpoint = $queryParams[Route::HANDLER_PARAM]; - //$script = Config::ENDPOINT[$testpoint]; - $script = $testpoint; - $queryString = str_replace(Route::HANDLER_PARAM . '=' . $testpoint, $script, $queryString); - $queryString = str_replace($script . '&', $script . ' handler with ', $queryString); - } else { - $queryString = 'page handler with ' . $queryString; - } - $result["paths"][$route] = [ - "get" => [ - "summary" => "Route to " . $queryString, - "responses" => [ - "200" => [ - "description" => "Result of " . $queryString, - ], - ], - ], - ]; - if ($route == "/databases/{db}") { - array_push($params, [ - "name" => "type", - "in" => "query", - "schema" => [ - "type" => "string", - "enum" => ["table", "view"], - ], - ]); - } - if ( - !str_starts_with($route, "/databases") && - !in_array($route, ["/openapi", "/routes", "/pages", "/about"]) && - (empty($queryParams[Route::HANDLER_PARAM]) || - in_array($queryParams[Route::HANDLER_PARAM], ['restapi', 'zipper'])) - ) { - array_push($params, [ - '$ref' => "#/components/parameters/dbParam", - ]); - } - if (!empty($params)) { - $result["paths"][$route]["get"]["parameters"] = $params; - } - if ($route == "/databases/{db}/{name}") { - $result["paths"][$route]["get"]["summary"] .= " - with api key"; - $result["paths"][$route]["get"]["security"] = [ - ["ApiKeyAuth" => []], - ]; - } - if ($route == "/user" || $route == "/user/details") { - $result["paths"][$route]["get"]["summary"] .= " - with basic authentication"; - $result["paths"][$route]["get"]["security"] = [ - ["BasicAuth" => []], - ]; - } - if (!empty($queryParams[Route::HANDLER_PARAM]) && $queryParams[Route::HANDLER_PARAM] !== "restapi") { - $result["paths"][$route]["get"]["summary"] .= " - with api key"; - $result["paths"][$route]["get"]["security"] = [ - ["ApiKeyAuth" => []], - ]; - } - } - return $result; - } - - /** - * Summary of getRoutes - * @param Request $request - * @return array - */ - public static function getRoutes($request) - { - $baseurl = Route::link(static::$handler); - $result = [ - "title" => "Routes", - "baseurl" => $baseurl, - "entries" => [], - ]; - foreach (Route::getRoutes() as $route => $queryParams) { - array_push($result["entries"], [ - "route" => $route, - "params" => $queryParams, - ]); - } - return $result; - } - - /** - * Summary of getPages - * @param Request $request - * @return array - */ - public static function getPages($request) - { - $baseurl = Route::link(static::$handler); - $result = [ - "title" => "Pages", - "baseurl" => $baseurl, - "entries" => [], - ]; - foreach (Route::getPages() as $page => $routes) { - array_push($result["entries"], [ - "page" => $page, - "routes" => $routes, - ]); - } - return $result; - } - - /** - * Summary of getNotes - * @param Request $request - * @return array - */ - public static function getNotes($request) - { - $type = $request->get('type', null, '/^\w+$/'); - if (!empty($type)) { - return static::getNotesByType($type, $request); - } - $db = $request->database(); - $baseurl = Route::link(static::$handler); - $result = [ - "title" => "Notes", - "baseurl" => $baseurl, - "databaseId" => $db, - "entries" => [], - ]; - foreach (Note::getCountByType($db) as $type => $count) { - array_push($result["entries"], [ - "class" => "Notes Type", - "title" => $type, - "navlink" => "{$baseurl}/notes/{$type}" . Route::params(["db" => $db]), - "number" => $count, - ]); - } - return $result; - } - - /** - * Summary of getNotesByType - * @param string $type - * @param Request $request - * @return array - */ - public static function getNotesByType($type, $request) - { - $id = $request->getId('id'); - if (!empty($id)) { - return static::getNoteByTypeId($type, $id, $request); - } - $db = $request->database(); - $baseurl = Route::link(static::$handler); - $result = [ - "title" => "Notes for {$type}", - "baseurl" => $baseurl, - "databaseId" => $db, - "entries" => [], - ]; - // @todo get item from notes + corresponding title from instance - foreach (Note::getEntriesByType($type, $db) as $entry) { - if (!empty($entry["title"])) { - $title = Route::slugify($entry["title"]); - array_push($result["entries"], [ - "class" => "Notes", - "title" => $entry["title"], - "id" => $entry["item"], - "navlink" => "{$baseurl}/notes/{$type}/{$entry['item']}/{$title}" . Route::params(["db" => $db]), - "size" => $entry["size"], - "timestamp" => $entry["mtime"], - ]); - } else { - array_push($result["entries"], [ - "class" => "Notes", - "title" => $type, - "id" => $entry["item"], - "navlink" => "{$baseurl}/notes/{$type}/{$entry['item']}" . Route::params(["db" => $db]), - "size" => $entry["size"], - "timestamp" => $entry["mtime"], - ]); - } - } - return $result; - } - - /** - * Summary of getNoteByTypeId - * @param string $type - * @param int $id - * @param Request $request - * @return array - */ - public static function getNoteByTypeId($type, $id, $request) - { - $db = $request->database(); - $note = Note::getInstanceByTypeId($type, $id, $db); - if (empty($note)) { - return ["error" => "Invalid note type id"]; - } - $baseurl = Route::link(static::$handler); - $result = [ - "title" => "Note for {$type} #{$id}", - "baseurl" => $baseurl, - "databaseId" => $db, - ]; - $result = array_replace($result, (array) $note); - $result["size"] = strlen($result["doc"]); - $result["resources"] = []; - foreach ($note->getResources() as $hash => $resource) { - $path = Resource::getResourcePath($hash, $db); - $size = !empty($path) ? filesize($path) : 0; - $mtime = !empty($path) ? filemtime($path) : 0; - $link = $resource->getUri(); - $result["resources"][$hash] = [ - "hash" => $resource->hash, - "name" => $resource->name, - "url" => $link, - "size" => $size, - "mtime" => $mtime, - ]; - } - return $result; - } - - /** - * Summary of getPreferences - * @param Request $request - * @return array - */ - public static function getPreferences($request) - { - $key = $request->get('key', null, '/^[\w\s:]+$/'); - if (!empty($key)) { - return static::getPreferenceByKey($key, $request); - } - $db = $request->database(); - $baseurl = Route::link(static::$handler); - $result = [ - "title" => "Preferences", - "baseurl" => $baseurl, - "databaseId" => $db, - "entries" => [], - ]; - foreach (Preference::getInstances($db) as $key => $preference) { - if (is_array($preference->val)) { - $count = count($preference->val); - } elseif (is_string($preference->val)) { - $count = strlen($preference->val); - } elseif (!is_null($preference->val)) { - $count = 1; - } else { - $count = 0; - } - array_push($result["entries"], [ - "class" => "Preference", - "title" => $key, - "navlink" => "{$baseurl}/preferences/" . rawurlencode($key) . Route::params(["db" => $db]), - "number" => $count, - ]); - } - return $result; - } - - /** - * Summary of getPreferenceByKey - * @param string $key - * @param Request $request - * @return array - */ - public static function getPreferenceByKey($key, $request) - { - $db = $request->database(); - $preference = Preference::getInstanceByKey($key, $db); - if (empty($preference)) { - return ["error" => "Invalid preference key"]; - } - $baseurl = Route::link(static::$handler); - $result = [ - "title" => "Preference for {$key}", - "baseurl" => $baseurl, - "databaseId" => $db, - ]; - $result = array_replace($result, (array) $preference); - return $result; - } - - /** - * Summary of getAnnotations - * @param Request $request - * @return array - */ - public static function getAnnotations($request) - { - $bookId = $request->getId('bookId'); - if (!empty($bookId)) { - return static::getAnnotationsByBookId($bookId, $request); - } - $db = $request->database(); - $baseurl = Route::link(static::$handler); - $result = [ - "title" => "Annotations", - "baseurl" => $baseurl, - "databaseId" => $db, - "entries" => [], - ]; - foreach (Annotation::getCountByBookId($db) as $bookId => $count) { - array_push($result["entries"], [ - "class" => "Annotations", - "title" => "Annotations for {$bookId}", - "navlink" => "{$baseurl}/annotations/{$bookId}" . Route::params(["db" => $db]), - "number" => $count, - ]); - } - return $result; - } - - /** - * Summary of getAnnotationsByBookId - * @param int $bookId - * @param Request $request - * @return array - */ - public static function getAnnotationsByBookId($bookId, $request) - { - $id = $request->getId('id'); - if (!empty($id)) { - return static::getAnnotationById($bookId, $id, $request); - } - $db = $request->database(); - $baseurl = Route::link(static::$handler); - $result = [ - "title" => "Annotations for {$bookId}", - "baseurl" => $baseurl, - "databaseId" => $db, - "entries" => [], - ]; - // @todo get item from annotations + corresponding title from instance - foreach (Annotation::getInstancesByBookId($bookId, $db) as $instance) { - $instance->setHandler(static::$handler); - $entry = $instance->getEntry(); - array_push($result["entries"], [ - "class" => $entry->className, - "title" => $entry->title, - "navlink" => $entry->getNavLink(), - ]); - } - return $result; - } - - /** - * Summary of getAnnotationById - * @param int $bookId - * @param int $id - * @param Request $request - * @return array - */ - public static function getAnnotationById($bookId, $id, $request) - { - $db = $request->database(); - /** @var Annotation $annotation */ - $annotation = Annotation::getInstanceById($id, $db); - if (empty($annotation->id)) { - return ["error" => "Invalid annotation id"]; - } - $baseurl = Route::link(static::$handler); - $result = [ - "title" => $annotation->getTitle(), - "baseurl" => $baseurl, - "databaseId" => $db, - ]; - $result = array_replace($result, get_object_vars($annotation)); - return $result; - } - - /** - * Summary of getMetadata - * @param Request $request - * @return array - */ - public static function getMetadata($request) - { - $bookId = $request->getId('bookId'); - if (empty($bookId)) { - return ["error" => "Invalid book id"]; - } - $db = $request->database(); - $baseurl = Route::link(static::$handler); - $metadata = Metadata::getInstanceByBookId($bookId, $db); - if (empty($metadata)) { - $result["error"] = "Invalid metadata for book id"; - return $result; - } - $result = [ - "title" => "Metadata for {$bookId}", - "baseurl" => $baseurl, - "databaseId" => $db, - ]; - $element = $request->get('element'); - if (empty($element)) { - $result["entries"] = $metadata; - return $result; - } - $result["element"] = $element; - $name = $request->get('name'); - if (empty($name)) { - $result["entries"] = $metadata->getElement($element); - return $result; - } - $result["name"] = $name; - $result["entries"] = $metadata->getElementName($element, $name); - return $result; - } - - /** - * Summary of getUser - * @param Request $request - * @return array - */ - public static function getUser($request) - { - $username = $request->getUserName(); - if (empty($username)) { - return ["error" => "Invalid username"]; - } - $db = $request->database(); - $baseurl = Route::link(static::$handler); - $result = [ - "title" => "User", - "baseurl" => $baseurl, - "databaseId" => $db, - ]; - $result["username"] = $username; - if ($request->path() == "/user/details") { - $user = User::getInstanceByName($username); - $result = array_replace($result, (array) $user); - } - return $result; - } -} diff --git a/COPS/cops-3.1.3/src/Output/TwigTemplate.php b/COPS/cops-3.1.3/src/Output/TwigTemplate.php deleted file mode 100644 index 9ed3d167..00000000 --- a/COPS/cops-3.1.3/src/Output/TwigTemplate.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Output; - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Route; - -/** - * Use Twig template engine - * @see https://twig.symfony.com/ - */ -class TwigTemplate extends BaseRenderer -{ - /** - * Summary of getTwigEnvironment - * @param string|string[] $templateDir - * @return \Twig\Environment - */ - public function getTwigEnvironment($templateDir = 'templates/twigged') - { - $loader = new \Twig\Loader\FilesystemLoader($templateDir); - $twig = new \Twig\Environment($loader); - // add Twig functions for COPS templates - $function = new \Twig\TwigFunction('str_format', function ($format, ...$args) { - //return str_format($format, ...$args); - return Format::str_format($format, ...$args); - }); - $twig->addFunction($function); - $assets = Route::path(Config::get('assets')); - $function = new \Twig\TwigFunction('asset', function ($file) use ($assets) { - return $assets . '/' . $file . '?v=' . Config::VERSION; - }); - $twig->addFunction($function); - - return $twig; - } - - /** - * Summary of serverSide - not used here - * @param \Twig\Environment $twig - * @param ?array $data - * @param string $theme - * @return bool|string|null - */ - public function serverSide($twig, $data, $theme = 'twigged') - { - if (empty($twig)) { - return false; - } - if (empty($data)) { - return null; - } - return $twig->render('page.html', ['it' => $data]); - } - - /** - * Summary of renderPage - * @param array $data - * @param string $theme - * @param bool|int $serverSide - * @return string - */ - public function renderPage($data, $theme = 'twigged', $serverSide = false) - { - // support other Twig template directories too - $twig = $this->getTwigEnvironment('templates/' . $theme); - if ($serverSide) { - // Get the page data - $json = new JsonRenderer(); - $data['page_it'] = $json->getJson($this->request, true); - if ($data['title'] != $data['page_it']['title']) { - $data['title'] .= ' - ' . $data['page_it']['title']; - } - // twig template will automatically include 'page.html' if needed - } - return $twig->render('index.html', ['it' => $data]); - } -} diff --git a/COPS/cops-3.1.3/src/Output/Zipper.php b/COPS/cops-3.1.3/src/Output/Zipper.php deleted file mode 100644 index 58f66b73..00000000 --- a/COPS/cops-3.1.3/src/Output/Zipper.php +++ /dev/null @@ -1,302 +0,0 @@ - - * @author mikespub - */ - -namespace SebLucas\Cops\Output; - -use SebLucas\Cops\Calibre\Author; -use SebLucas\Cops\Calibre\Book; -use SebLucas\Cops\Calibre\Serie; -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Request; -use SebLucas\Cops\Model\EntryBook; -use SebLucas\Cops\Pages\PageId; -use SebLucas\Cops\Pages\Page; -use ZipStream\ZipStream; - -/** - * Zipper to download multiple books - */ -class Zipper -{ - public static string $handler = "zipper"; - - /** @var Request */ - protected $request; - /** @var ?int */ - protected $databaseId = null; - /** @var string */ - protected $format = 'EPUB'; - /** @var string */ - protected $fileName = 'download.epub.zip'; - /** @var array */ - protected $fileList = []; - /** @var ?string */ - protected $message = null; - - /** - * Summary of __construct - * @param Request $request - */ - public function __construct(Request $request) - { - $this->request = $request; - $this->databaseId = $this->request->database(); - $type = $this->request->get('type', 'any'); - $this->format = strtoupper((string) $type); - } - - /** - * Summary of isValidForDownload - * @return bool - */ - public function isValidForDownload() - { - $entries = $this->hasPage(); - if (!$entries) { - $entries = $this->hasSeries(); - if (!$entries) { - $entries = $this->hasAuthor(); - if (!$entries) { - return false; - } - } - } - return $this->checkFileList($entries); - } - - /** - * Summary of hasPage - * @return array|bool - */ - public function hasPage() - { - if (!in_array($this->format, Config::get('download_page'))) { - $this->message ??= 'Invalid format for page'; - return false; - } - $pageId = $this->request->get('page'); - if (empty($pageId)) { - $this->message ??= 'Invalid page id'; - return false; - } - /** @var Page $instance */ - $instance = PageId::getPage($pageId, $this->request); - if ($instance::class == Page::class) { - $this->message = 'Invalid page'; - return false; - } - if ($this->format == 'ANY') { - $this->fileName = $instance->title . '.zip'; - } else { - $this->fileName = $instance->title . '.' . strtolower($this->format) . '.zip'; - } - if (!empty($instance->parentTitle)) { - $this->fileName = $instance->parentTitle . ' - ' . $this->fileName; - } - if (!empty($instance->n) && $instance->n > 1) { - $this->fileName = str_replace('.zip', '.' . strval($instance->n) . '.zip', $this->fileName); - } - $entries = $instance->entryArray; - if (empty($entries)) { - $this->message = 'No books found for page'; - return false; - } - return $entries; - } - - /** - * Summary of hasSeries - * @return array|bool - */ - public function hasSeries() - { - if (!in_array($this->format, Config::get('download_series'))) { - $this->message ??= 'Invalid format for series'; - return false; - } - $seriesId = $this->request->getId('series'); - if (empty($seriesId)) { - $this->message ??= 'Invalid series id'; - return false; - } - /** @var Serie $instance */ - $instance = Serie::getInstanceById($seriesId, $this->databaseId); - if (empty($instance->id)) { - $this->message = 'Invalid series'; - return false; - } - if ($this->format == 'ANY') { - $this->fileName = $instance->name . '.zip'; - } else { - $this->fileName = $instance->name . '.' . strtolower($this->format) . '.zip'; - } - $entries = $instance->getBooks(); // -1 - if (empty($entries)) { - $this->message = 'No books found for series'; - return false; - } - return $entries; - } - - /** - * Summary of hasAuthor - * @return array|bool - */ - public function hasAuthor() - { - if (!in_array($this->format, Config::get('download_author'))) { - $this->message ??= 'Invalid format for author'; - return false; - } - $authorId = $this->request->getId('author'); - if (empty($authorId)) { - $this->message ??= 'Invalid author id'; - return false; - } - /** @var Author $instance */ - $instance = Author::getInstanceById($authorId, $this->databaseId); - if (empty($instance->id)) { - $this->message = 'Invalid author'; - return false; - } - if ($this->format == 'ANY') { - $this->fileName = $instance->name . '.zip'; - } else { - $this->fileName = $instance->name . '.' . strtolower($this->format) . '.zip'; - } - $entries = $instance->getBooks(); // -1 - if (empty($entries)) { - $this->message = 'No books found for author'; - return false; - } - return $entries; - } - - /** - * Summary of checkFileList - * @param array $entries - * @return bool - */ - public function checkFileList($entries) - { - if (count($entries) < 1) { - $this->message = 'No books found'; - return false; - } - $this->fileList = []; - if ($this->format == 'ANY') { - $checkFormats = Config::get('prefered_format'); - } else { - $checkFormats = [ $this->format ]; - } - // @todo use download_template to format name - //$template = Config::get('download_template'); - foreach ($entries as $entry) { - if ($entry::class != EntryBook::class) { - continue; - } - $data = false; - foreach ($checkFormats as $format) { - $data = $entry->book->getDataFormat($format); - if ($data) { - break; - } - } - if (!$data) { - continue; - } - $path = $data->getLocalPath(); - if (!file_exists($path)) { - continue; - } - //$name = basename($path); - // @todo use normalizeUtf8String() on author, series and title or not? - // Using {author} - {series} #{series_index} - {title} with .{format} - $author = $entry->book->getAuthorsName(); - $name = explode(', ', $author)[0]; - $serie = $entry->book->getSerie(); - if (!empty($serie)) { - $name .= ' - ' . $serie->name . ' #' . $entry->book->seriesIndex; - } - $name .= ' - ' . $entry->book->title; - $info = pathinfo($path); - $name .= '.' . $info['extension']; - // allow unicode characters here - $name = preg_replace('/[^\w\s\d\'\.\-\/_,#\[\]\(\)]/u', '', $name); - $this->fileList[$name] = $path; - } - if (count($this->fileList) < 1) { - $this->message = 'No files found'; - return false; - } - return true; - } - - /** - * Summary of isValidForExtraFiles - * @param Book $book - * @return bool - */ - public function isValidForExtraFiles($book) - { - $extraFiles = $book->getExtraFiles(); - if (empty($extraFiles)) { - $this->message = 'No files found for book'; - return false; - } - $this->fileName = 'data.zip'; - $this->fileList = []; - foreach ($extraFiles as $name) { - $path = $book->path . '/' . Book::DATA_DIR_NAME . '/' . $name; - if (!file_exists($path)) { - continue; - } - $this->fileList[$name] = $path; - } - if (count($this->fileList) < 1) { - $this->message = 'No files found for book'; - return false; - } - return true; - } - - /** - * Summary of download - * @param ?string $fileName - * @param bool $sendHeaders - * @return static - */ - public function download($fileName = null, $sendHeaders = true) - { - $fileName ??= $this->fileName; - - // keep it simple for now, and use the basic options - $zip = new ZipStream( - outputName: $fileName, - sendHttpHeaders: $sendHeaders, - ); - foreach ($this->fileList as $name => $path) { - $zip->addFileFromPath( - fileName: $name, - path: $path, - ); - } - $zip->finish(); - return $this; - } - - /** - * Summary of getMessage - * @return string - */ - public function getMessage() - { - return $this->message ?? 'Unknown error'; - } -} diff --git a/COPS/cops-3.1.3/src/Pages/Page.php b/COPS/cops-3.1.3/src/Pages/Page.php deleted file mode 100644 index b4ec27bd..00000000 --- a/COPS/cops-3.1.3/src/Pages/Page.php +++ /dev/null @@ -1,367 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\Base; -use SebLucas\Cops\Calibre\Book; -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Request; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Model\Entry; -use SebLucas\Cops\Model\EntryBook; -use SebLucas\Cops\Model\LinkNavigation; - -class Page -{ - public const PAGE_ID = "cops:catalog"; - - /** @var string */ - public $title; - public string $subtitle = ""; - public string $authorName = ""; - public string $authorUri = ""; - public string $authorEmail = ""; - public string $parentTitle = ""; - public string $currentUri = ""; - public string $parentUri = ""; - /** @var ?string */ - public $idPage; - /** @var string|int|null */ - public $idGet; - public string $favicon; - /** @var int */ - public $n; - /** @var ?Book */ - public $book; - /** @var int */ - public $totalNumber = -1; - /** @var ?string */ - public $sorted = "sort"; - /** @var array */ - public $filterParams = []; - /** @var array|false */ - public $hierarchy = false; - /** @var array|false */ - public $extra = false; - - /** @var Entry[] */ - public $entryArray = []; - - /** @var Request */ - protected $request = null; - protected string $className = Base::class; - /** @var int */ - protected $numberPerPage = -1; - /** @var array */ - protected $ignoredCategories = []; - /** @var ?int */ - protected $databaseId = null; - protected string $handler = ''; - - /** - * Summary of getPage - * @param string|int|null $pageId - * @param ?Request $request - * @return Page|PageAbout|PageAllAuthors|PageAllAuthorsLetter|PageAllBooks|PageAllBooksLetter|PageAllBooksYear|PageAllCustoms|PageAllIdentifiers|PageAllLanguages|PageAllPublishers|PageAllRating|PageAllSeries|PageAllTags|PageAuthorDetail|PageBookDetail|PageCustomDetail|PageCustomize|PageIdentifierDetail|PageLanguageDetail|PagePublisherDetail|PageQueryResult|PageRatingDetail|PageRecentBooks|PageSerieDetail|PageTagDetail - */ - public static function getPage($pageId, $request) - { - return PageId::getPage($pageId, $request); - } - - /** - * Summary of __construct - * @param ?Request $request - */ - public function __construct($request = null) - { - $this->setConfig(); - $this->setRequest($request); - - // move to constructor as this is always called directly after PageId::getPage() - $this->initializeContent(); - } - - /** - * Summary of setRequest - * @param ?Request $request - * @return void - */ - public function setRequest($request) - { - $this->request = $request ?? new Request(); - // this could be string for first letter, identifier or custom columns - override there - $this->idGet = $this->request->getId(); - $this->n = $this->request->get('n', 1, '/^\d+$/'); // use default here - $this->numberPerPage = $this->request->option("max_item_per_page"); - $this->ignoredCategories = $this->request->option('ignored_categories'); - $this->databaseId = $this->request->database(); - $this->handler = $this->request->getHandler(); - } - - /** - * Summary of setConfig - * @return void - */ - public function setConfig() - { - $this->favicon = Config::get('icon'); - $this->authorName = Config::get('author_name') ?: 'Sébastien Lucas'; - $this->authorUri = Config::get('author_uri') ?: 'http://blog.slucas.fr'; - $this->authorEmail = Config::get('author_email') ?: 'sebastien@slucas.fr'; - } - - /** - * Summary of getNumberPerPage - * @return int - */ - public function getNumberPerPage() - { - return $this->numberPerPage; - } - - /** - * Summary of getIgnoredCategories - * @return array - */ - public function getIgnoredCategories() - { - return $this->ignoredCategories; - } - - /** - * Summary of getDatabaseId - * @return ?int - */ - public function getDatabaseId() - { - return $this->databaseId; - } - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - $this->getEntries(); - $this->idPage = static::PAGE_ID; - $this->title = Config::get('title_default'); - $this->subtitle = Config::get('subtitle_default'); - } - - /** - * Summary of getEntries - * @return void - */ - public function getEntries() - { - $this->getExtra(); - } - - /** - * Summary of getExtra - * @return void - */ - public function getExtra() - { - $this->extra = false; - } - - /** - * Summary of isPaginated - * @return bool - */ - public function isPaginated() - { - return ($this->getNumberPerPage() != -1 && - $this->totalNumber != -1 && - $this->totalNumber > $this->getNumberPerPage()); - } - - /** - * Summary of getFirstLink - * @return ?LinkNavigation - */ - public function getFirstLink() - { - if ($this->n > 1) { - $params = $this->request->getCleanParams(); - return new LinkNavigation( - Route::link($this->handler, null, $params), - "first", - localize("paging.first.alternate") - ); - } - return null; - } - - /** - * Summary of getLastLink - * @return ?LinkNavigation - */ - public function getLastLink() - { - if ($this->n < $this->getMaxPage()) { - $params = $this->request->getCleanParams(); - $params['n'] = strval($this->getMaxPage()); - return new LinkNavigation( - Route::link($this->handler, null, $params), - "last", - localize("paging.last.alternate") - ); - } - return null; - } - - /** - * Summary of getNextLink - * @return ?LinkNavigation - */ - public function getNextLink() - { - if ($this->n < $this->getMaxPage()) { - $params = $this->request->getCleanParams(); - $params['n'] = strval($this->n + 1); - return new LinkNavigation( - Route::link($this->handler, null, $params), - "next", - localize("paging.next.alternate") - ); - } - return null; - } - - /** - * Summary of getPrevLink - * @return ?LinkNavigation - */ - public function getPrevLink() - { - if ($this->n > 1) { - $params = $this->request->getCleanParams(); - $params['n'] = strval($this->n - 1); - return new LinkNavigation( - Route::link($this->handler, null, $params), - "previous", - localize("paging.previous.alternate") - ); - } - return null; - } - - /** - * Summary of getMaxPage - * @return float - */ - public function getMaxPage() - { - return ceil($this->totalNumber / $this->numberPerPage); - } - - /** - * Summary of getSortOptions - * @return array - */ - public function getSortOptions() - { - if ($this->request->isFeed()) { - $sortLinks = Config::get('opds_sort_links'); - } else { - $sortLinks = Config::get('html_sort_links'); - } - $allowed = array_flip($sortLinks); - $sortOptions = [ - //'title' => localize("bookword.title"), - 'title' => localize("sort.titles"), - 'author' => localize("authors.title"), - 'pubdate' => localize("pubdate.title"), - 'rating' => localize("ratings.title"), - 'timestamp' => localize("recent.title"), - //'series' => localize("series.title"), - //'language' => localize("languages.title"), - //'publisher' => localize("publishers.title"), - ]; - return array_intersect_key($sortOptions, $allowed); - } - - /** - * Summary of addEntries - * @param array $entries - * @return void - */ - public function addEntries($entries) - { - $this->entryArray = array_merge($this->entryArray, $entries); - } - - /** - * Summary of addHeaderEntry - * @param string $title - * @param string $content - * @param ?string $href - * @param ?string $relation - * @return void - */ - public function addHeaderEntry($title, $content, $href = null, $relation = null) - { - array_push($this->entryArray, $this->getHeaderEntry($title, $content, $href, $relation)); - } - - /** - * Summary of getHeaderEntry - * @param string $title - * @param string $content - * @param ?string $href - * @param ?string $relation - * @return Entry - */ - public function getHeaderEntry($title, $content, $href = null, $relation = null) - { - if (empty($href)) { - $linkArray = []; - } else { - $linkArray = [ new LinkNavigation($href, $relation) ]; - } - return new Entry( - $title, - "", - $content, - "text", - $linkArray, - $this->getDatabaseId(), - "", - "" - ); - } - - /** - * Summary of containsBook - * @return bool - */ - public function containsBook() - { - if (count($this->entryArray) == 0) { - return false; - } - if ($this->entryArray [0]::class == EntryBook::class) { - return true; - } - return false; - } - - /** - * Summary of canFilter - * @return bool - */ - public function canFilter() - { - return false; - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageAbout.php b/COPS/cops-3.1.3/src/Pages/PageAbout.php deleted file mode 100644 index 5f115132..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageAbout.php +++ /dev/null @@ -1,35 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Input\Config; - -class PageAbout extends Page -{ - public const PAGE_ID = PageId::ABOUT_ID; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - $this->idPage = static::PAGE_ID; - $this->title = localize("about.title"); - } - - /** - * Summary of getContent - * @return string - */ - public function getContent() - { - return preg_replace("/\About COPS\<\/h1\>/", "

    About COPS " . Config::VERSION . "

    ", file_get_contents('templates/about.html')); - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageAllAuthors.php b/COPS/cops-3.1.3/src/Pages/PageAllAuthors.php deleted file mode 100644 index c64451f7..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageAllAuthors.php +++ /dev/null @@ -1,45 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\Author; -use SebLucas\Cops\Calibre\BaseList; - -class PageAllAuthors extends Page -{ - protected string $className = Author::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - $this->getEntries(); - $this->idPage = Author::PAGE_ID; - $this->title = localize("authors.title"); - } - - /** - * Summary of getEntries - * @return void - */ - public function getEntries() - { - $baselist = new BaseList($this->className, $this->request); - if ($this->request->option("author_split_first_letter") == 1 || $this->request->get('letter')) { - $this->entryArray = $baselist->getCountByFirstLetter(); - $this->sorted = $baselist->orderBy; - } else { - $this->entryArray = $baselist->getRequestEntries($this->n); - $this->totalNumber = $baselist->countRequestEntries(); - $this->sorted = $baselist->orderBy; - } - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageAllAuthorsLetter.php b/COPS/cops-3.1.3/src/Pages/PageAllAuthorsLetter.php deleted file mode 100644 index 1bf51299..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageAllAuthorsLetter.php +++ /dev/null @@ -1,50 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\Author; -use SebLucas\Cops\Calibre\BaseList; -use SebLucas\Cops\Input\Route; - -class PageAllAuthorsLetter extends Page -{ - protected string $className = Author::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - // this would be the first letter - override here - $this->idGet = $this->request->get('id', null, '/^\p{L}$/u'); - $this->getEntries(); - $this->idPage = Author::getEntryIdByLetter($this->idGet); - $count = $this->totalNumber; - if ($count == -1) { - $count = count($this->entryArray); - } - $this->title = str_format(localize("splitByLetter.letter"), str_format(localize("authorword", $count), $count), $this->idGet); - $this->parentTitle = ""; // localize("authors.title"); - $filterParams = $this->request->getFilterParams(); - $this->parentUri = Route::link($this->handler, Author::PAGE_ALL, $filterParams); - } - - /** - * Summary of getEntries - * @return void - */ - public function getEntries() - { - $baselist = new BaseList($this->className, $this->request); - $this->entryArray = $baselist->getEntriesByFirstLetter($this->idGet, $this->n); - $this->totalNumber = $baselist->countEntriesByFirstLetter($this->idGet); - $this->sorted = $baselist->orderBy; - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageAllBooks.php b/COPS/cops-3.1.3/src/Pages/PageAllBooks.php deleted file mode 100644 index ebeccde6..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageAllBooks.php +++ /dev/null @@ -1,47 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\Book; -use SebLucas\Cops\Calibre\BookList; - -class PageAllBooks extends Page -{ - protected string $className = Book::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - $this->getEntries(); - $this->idPage = Book::PAGE_ID; - $this->title = localize("allbooks.title"); - } - - /** - * Summary of getEntries - * @return void - */ - public function getEntries() - { - $booklist = new BookList($this->request); - if ($this->request->option("titles_split_first_letter") == 1 || $this->request->get('letter')) { - $this->entryArray = $booklist->getCountByFirstLetter(); - $this->sorted = $booklist->orderBy ?? "letter"; - } elseif (!empty($this->request->option("titles_split_publication_year")) || $this->request->get('year')) { - $this->entryArray = $booklist->getCountByPubYear(); - $this->sorted = $booklist->orderBy ?? "year"; - } else { - [$this->entryArray, $this->totalNumber] = $booklist->getAllBooks($this->n); - $this->sorted = $booklist->orderBy ?? Book::SQL_SORT; - } - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageAllBooksLetter.php b/COPS/cops-3.1.3/src/Pages/PageAllBooksLetter.php deleted file mode 100644 index 53295b07..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageAllBooksLetter.php +++ /dev/null @@ -1,49 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\Book; -use SebLucas\Cops\Calibre\BookList; -use SebLucas\Cops\Input\Route; - -class PageAllBooksLetter extends Page -{ - protected string $className = Book::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - // this would be the first letter - override here - $this->idGet = $this->request->get('id', null, '/^\p{L}$/u'); - $this->getEntries(); - $this->idPage = Book::getEntryIdByLetter($this->idGet); - $count = $this->totalNumber; - if ($count == -1) { - $count = count($this->entryArray); - } - $this->title = str_format(localize("splitByLetter.letter"), str_format(localize("bookword", $count), $count), $this->idGet); - $this->parentTitle = ""; // localize("allbooks.title"); - $filterParams = $this->request->getFilterParams(); - $this->parentUri = Route::link($this->handler, Book::PAGE_ALL, $filterParams); - } - - /** - * Summary of getEntries - * @return void - */ - public function getEntries() - { - $booklist = new BookList($this->request); - [$this->entryArray, $this->totalNumber] = $booklist->getBooksByFirstLetter($this->idGet, $this->n); - $this->sorted = $booklist->orderBy ?? Book::SQL_SORT; - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageAllBooksYear.php b/COPS/cops-3.1.3/src/Pages/PageAllBooksYear.php deleted file mode 100644 index d6c80261..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageAllBooksYear.php +++ /dev/null @@ -1,47 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\Book; -use SebLucas\Cops\Calibre\BookList; -use SebLucas\Cops\Input\Route; - -class PageAllBooksYear extends Page -{ - protected string $className = Book::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - $this->getEntries(); - $this->idPage = Book::getEntryIdByYear($this->idGet); - $count = $this->totalNumber; - if ($count == -1) { - $count = count($this->entryArray); - } - $this->title = str_format(localize("splitByYear.year"), str_format(localize("bookword", $count), $count), $this->idGet); - $this->parentTitle = ""; // localize("allbooks.title"); - $filterParams = $this->request->getFilterParams(); - $this->parentUri = Route::link($this->handler, Book::PAGE_ALL, $filterParams); - } - - /** - * Summary of getEntries - * @return void - */ - public function getEntries() - { - $booklist = new BookList($this->request); - [$this->entryArray, $this->totalNumber] = $booklist->getBooksByPubYear($this->idGet, $this->n); - $this->sorted = $booklist->orderBy ?? Book::SQL_SORT; - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageAllCustoms.php b/COPS/cops-3.1.3/src/Pages/PageAllCustoms.php deleted file mode 100644 index f475b7be..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageAllCustoms.php +++ /dev/null @@ -1,134 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\BookList; -use SebLucas\Cops\Calibre\CustomColumn; -use SebLucas\Cops\Calibre\CustomColumnType; -use SebLucas\Cops\Calibre\CustomColumnTypeDate; -use SebLucas\Cops\Calibre\CustomColumnTypeInteger; -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Model\Entry; - -class PageAllCustoms extends Page -{ - protected string $className = CustomColumnType::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - $customId = $this->request->get("custom", null); - $columnType = CustomColumnType::createByCustomID($customId, $this->getDatabaseId()); - $columnType->setHandler($this->handler); - - $this->idPage = $columnType->getEntryId(); - $this->title = $columnType->getTitle(); - $this->getCustomEntries($columnType); - if ((!$this->isPaginated() || $this->n == $this->getMaxPage()) && in_array("custom", Config::get('show_not_set_filter'))) { - $this->addCustomNotSetEntry($columnType); - } - } - - /** - * Summary of getCustomEntries - * @param CustomColumnType $columnType - * @return void - */ - public function getCustomEntries($columnType) - { - // @todo do we want to filter by virtual library etc. here? - if (Config::get('custom_date_split_year') == 1 && $columnType instanceof CustomColumnTypeDate) { - $this->getCustomEntriesByYear($columnType); - } elseif (Config::get('custom_integer_split_range') > 0 && $columnType instanceof CustomColumnTypeInteger) { - $this->getCustomEntriesByRange($columnType); - } elseif ($columnType->hasChildCategories()) { - $this->sorted = $this->request->getSorted("sort"); - // use tag_browser_custom_column_X view here, to get the full hierarchy? - $this->entryArray = $columnType->browseAllCustomValues($this->n, $this->sorted); - $this->totalNumber = $columnType->getDistinctValueCount(); - } else { - $this->sorted = $this->request->getSorted("value"); - $this->entryArray = $columnType->getAllCustomValues($this->n, $this->sorted); - $this->totalNumber = $columnType->getDistinctValueCount(); - } - } - - /** - * Summary of getCustomEntriesByYear - * @param CustomColumnTypeDate $columnType - * @return void - */ - public function getCustomEntriesByYear($columnType) - { - $year = $this->request->get("year", null, $columnType::GET_PATTERN); - if (empty($year)) { - // can be $columnType::PAGE_ALL or $columnType::PAGE_DETAIL - $this->sorted = $this->request->getSorted("year"); - $this->entryArray = $columnType->getCountByYear($columnType::PAGE_DETAIL, $this->sorted); - return; - } - // if we use $columnType::PAGE_ALL in PageAllCustoms, otherwise see PageCustomDetail - $this->sorted = $this->request->getSorted("value"); - $this->entryArray = $columnType->getCustomValuesByYear($year, $this->sorted); - $count = 0; - foreach ($this->entryArray as $entry) { - /** @var Entry $entry */ - $count += $entry->numberOfElement; - } - $this->title = str_format(localize("splitByYear.year"), str_format(localize("bookword", $count), $count), $year); - $this->parentTitle = $columnType->getTitle(); - $this->parentUri = $columnType->getUri(); - } - - /** - * Summary of getCustomEntriesByRange - * @param CustomColumnTypeInteger $columnType - * @return void - */ - public function getCustomEntriesByRange($columnType) - { - $range = $this->request->get("range", null, $columnType::GET_PATTERN); - if (empty($range)) { - // can be $columnType::PAGE_ALL or $columnType::PAGE_DETAIL - $this->sorted = $this->request->getSorted("range"); - $this->entryArray = $columnType->getCountByRange($columnType::PAGE_DETAIL, $this->sorted); - return; - } - // if we use $columnType::PAGE_ALL in PageAllCustoms, otherwise see PageCustomDetail - $this->sorted = $this->request->getSorted("value"); - $this->entryArray = $columnType->getCustomValuesByRange($range, $this->sorted); - $count = 0; - foreach ($this->entryArray as $entry) { - /** @var Entry $entry */ - $count += $entry->numberOfElement; - } - $this->title = str_format(localize("splitByRange.range"), str_format(localize("bookword", $count), $count), $range); - $this->parentTitle = $columnType->getTitle(); - $this->parentUri = $columnType->getUri(); - } - - /** - * Summary of addCustomNotSetEntry - * @param CustomColumnType $columnType - * @return void - */ - public function addCustomNotSetEntry($columnType) - { - $instance = new CustomColumn(null, localize("customcolumn.boolean.unknown"), $columnType); - $instance->setHandler($this->handler); - // @todo support countWithoutEntries() for CustomColumn - $booklist = new BookList($this->request); - $booklist->orderBy = null; - [$result,] = $booklist->getBooksWithoutCustom($columnType, -1); - array_push($this->entryArray, $instance->getEntry(count($result))); - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageAllIdentifiers.php b/COPS/cops-3.1.3/src/Pages/PageAllIdentifiers.php deleted file mode 100644 index e4e6590b..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageAllIdentifiers.php +++ /dev/null @@ -1,44 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\BaseList; -use SebLucas\Cops\Calibre\Identifier; -use SebLucas\Cops\Input\Config; - -class PageAllIdentifiers extends Page -{ - protected string $className = Identifier::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - $this->getEntries(); - $this->idPage = Identifier::PAGE_ID; - $this->title = localize("identifiers.title"); - } - - /** - * Summary of getEntries - * @return void - */ - public function getEntries() - { - $baselist = new BaseList($this->className, $this->request); - $this->entryArray = $baselist->getRequestEntries($this->n); - $this->totalNumber = $baselist->countDistinctEntries(); - $this->sorted = $baselist->orderBy; - if ((!$this->isPaginated() || $this->n == $this->getMaxPage()) && in_array("identifier", Config::get('show_not_set_filter'))) { - array_push($this->entryArray, $baselist->getWithoutEntry()); - } - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageAllLanguages.php b/COPS/cops-3.1.3/src/Pages/PageAllLanguages.php deleted file mode 100644 index 78e370d7..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageAllLanguages.php +++ /dev/null @@ -1,40 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\Language; -use SebLucas\Cops\Calibre\BaseList; - -class PageAllLanguages extends Page -{ - protected string $className = Language::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - $this->getEntries(); - $this->idPage = Language::PAGE_ID; - $this->title = localize("languages.title"); - } - - /** - * Summary of getEntries - * @return void - */ - public function getEntries() - { - $baselist = new BaseList($this->className, $this->request); - $this->entryArray = $baselist->getRequestEntries($this->n); - $this->totalNumber = $baselist->countRequestEntries(); - $this->sorted = $baselist->orderBy; - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageAllPublishers.php b/COPS/cops-3.1.3/src/Pages/PageAllPublishers.php deleted file mode 100644 index 0475f391..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageAllPublishers.php +++ /dev/null @@ -1,40 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\Publisher; -use SebLucas\Cops\Calibre\BaseList; - -class PageAllPublishers extends Page -{ - protected string $className = Publisher::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - $this->getEntries(); - $this->idPage = Publisher::PAGE_ID; - $this->title = localize("publishers.title"); - } - - /** - * Summary of getEntries - * @return void - */ - public function getEntries() - { - $baselist = new BaseList($this->className, $this->request); - $this->entryArray = $baselist->getRequestEntries($this->n); - $this->totalNumber = $baselist->countRequestEntries(); - $this->sorted = $baselist->orderBy; - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageAllRating.php b/COPS/cops-3.1.3/src/Pages/PageAllRating.php deleted file mode 100644 index 4e7d0da8..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageAllRating.php +++ /dev/null @@ -1,44 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\BaseList; -use SebLucas\Cops\Calibre\Rating; -use SebLucas\Cops\Input\Config; - -class PageAllRating extends Page -{ - protected string $className = Rating::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - $this->getEntries(); - $this->idPage = Rating::PAGE_ID; - $this->title = localize("ratings.title"); - } - - /** - * Summary of getEntries - * @return void - */ - public function getEntries() - { - $baselist = new BaseList($this->className, $this->request); - $this->entryArray = $baselist->getRequestEntries($this->n); - $this->totalNumber = $baselist->countRequestEntries(); - $this->sorted = $baselist->orderBy; - if ((!$this->isPaginated() || $this->n == $this->getMaxPage()) && in_array("rating", Config::get('show_not_set_filter'))) { - array_push($this->entryArray, $baselist->getWithoutEntry()); - } - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageAllSeries.php b/COPS/cops-3.1.3/src/Pages/PageAllSeries.php deleted file mode 100644 index 6abca1d3..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageAllSeries.php +++ /dev/null @@ -1,51 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\BaseList; -use SebLucas\Cops\Calibre\Serie; -use SebLucas\Cops\Input\Config; - -class PageAllSeries extends Page -{ - protected string $className = Serie::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - $this->getEntries(); - $this->idPage = Serie::PAGE_ID; - $this->title = localize("series.title"); - } - - /** - * Summary of getEntries - * @return void - */ - public function getEntries() - { - $baselist = new BaseList($this->className, $this->request); - // @todo needs title_sort function in sqlite for series - //if ($baselist->hasChildCategories()) { - // // use tag_browser_series view here, to get the full hierarchy? - // $this->entryArray = $baselist->browseAllEntries($this->n); - //} else { - // $this->entryArray = $baselist->getRequestEntries($this->n); - //} - $this->entryArray = $baselist->getRequestEntries($this->n); - $this->totalNumber = $baselist->countRequestEntries(); - $this->sorted = $baselist->orderBy; - if ((!$this->isPaginated() || $this->n == $this->getMaxPage()) && in_array("series", Config::get('show_not_set_filter'))) { - array_push($this->entryArray, $baselist->getWithoutEntry()); - } - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageAllTags.php b/COPS/cops-3.1.3/src/Pages/PageAllTags.php deleted file mode 100644 index 575c398a..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageAllTags.php +++ /dev/null @@ -1,50 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\BaseList; -use SebLucas\Cops\Calibre\Tag; -use SebLucas\Cops\Input\Config; - -class PageAllTags extends Page -{ - protected string $className = Tag::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - $this->getEntries(); - $this->idPage = Tag::PAGE_ID; - $this->title = localize("tags.title"); - } - - /** - * Summary of getEntries - * @return void - */ - public function getEntries() - { - $baselist = new BaseList($this->className, $this->request); - $this->sorted = $this->request->getSorted("sort"); - if ($baselist->hasChildCategories()) { - // use tag_browser_tags view here, to get the full hierarchy? - $this->entryArray = $baselist->browseAllEntries($this->n); - } else { - $this->entryArray = $baselist->getRequestEntries($this->n); - } - $this->totalNumber = $baselist->countRequestEntries(); - $this->sorted = $baselist->orderBy; - if ((!$this->isPaginated() || $this->n == $this->getMaxPage()) && in_array("tag", Config::get('show_not_set_filter'))) { - array_push($this->entryArray, $baselist->getWithoutEntry()); - } - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageAllVirtualLibraries.php b/COPS/cops-3.1.3/src/Pages/PageAllVirtualLibraries.php deleted file mode 100644 index e2f5f131..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageAllVirtualLibraries.php +++ /dev/null @@ -1,39 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\VirtualLibrary; - -class PageAllVirtualLibraries extends Page -{ - protected string $className = VirtualLibrary::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - $this->getEntries(); - $this->idPage = VirtualLibrary::PAGE_ID; - $this->title = localize("libraries.title"); - } - - /** - * Summary of getEntries - * @return void - */ - public function getEntries() - { - $this->entryArray = VirtualLibrary::getEntries($this->getDatabaseId(), $this->handler); - $this->totalNumber = VirtualLibrary::countEntries($this->getDatabaseId()); - $this->sorted = null; - array_push($this->entryArray, VirtualLibrary::getWithoutEntry($this->getDatabaseId(), $this->handler)); - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageAuthorDetail.php b/COPS/cops-3.1.3/src/Pages/PageAuthorDetail.php deleted file mode 100644 index 748ae956..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageAuthorDetail.php +++ /dev/null @@ -1,68 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\Author; -use SebLucas\Cops\Calibre\BookList; - -class PageAuthorDetail extends PageWithDetail -{ - protected string $className = Author::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - /** @var Author $instance */ - $instance = Author::getInstanceById($this->idGet, $this->getDatabaseId()); - $instance->setHandler($this->handler); - if ($this->request->get('filter')) { - $this->filterParams = [Author::URL_PARAM => $this->idGet]; - $this->getFilters($instance); - } else { - $this->getEntries($instance); - } - $this->setInstance($instance); - $this->title = $instance->name; // not by getTitle() = $instance->sort here - } - - /** - * Summary of getEntries - * @param Author $instance - * @return void - */ - public function getEntries($instance = null) - { - $booklist = new BookList($this->request); - [$this->entryArray, $this->totalNumber] = $booklist->getBooksByInstance($instance, $this->n); - $this->sorted = $booklist->orderBy ?? "series desc"; - $this->getExtra($instance); - // add author series as extra info - $this->addExtraSeries($instance); - } - - /** - * Summary of addSeries - * @param Author $instance - * @return void - */ - public function addExtraSeries($instance = null) - { - $series = $instance->getSeries(); - if (empty($series)) { - return; - } - if (empty($this->extra)) { - $this->extra = []; - } - $this->extra["series"] = $series; - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageBookDetail.php b/COPS/cops-3.1.3/src/Pages/PageBookDetail.php deleted file mode 100644 index 64a44f05..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageBookDetail.php +++ /dev/null @@ -1,34 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\Book; - -class PageBookDetail extends Page -{ - protected string $className = Book::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - $this->book = Book::getBookById($this->idGet, $this->getDatabaseId()); - if (is_null($this->book)) { - $this->idPage = PageId::ERROR_ID; - $this->title = 'Not Found'; - return; - } - $this->book->setHandler($this->handler); - $this->idPage = $this->book->getEntryId(); - $this->title = $this->book->getTitle(); - $this->currentUri = $this->book->getUri(); - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageCustomDetail.php b/COPS/cops-3.1.3/src/Pages/PageCustomDetail.php deleted file mode 100644 index ea8e4e97..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageCustomDetail.php +++ /dev/null @@ -1,98 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\BookList; -use SebLucas\Cops\Calibre\CustomColumn; -use SebLucas\Cops\Calibre\CustomColumnTypeBool; -use SebLucas\Cops\Calibre\CustomColumnTypeDate; -use SebLucas\Cops\Calibre\CustomColumnTypeInteger; - -class PageCustomDetail extends PageWithDetail -{ - protected string $className = CustomColumn::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - // this could be string for some custom columns - override here - $this->idGet = $this->request->get('id'); - $customId = $this->request->get("custom", null); - $instance = CustomColumn::createCustom($customId, $this->idGet, $this->getDatabaseId()); - $instance->setHandler($this->handler); - // $this->title may get updated below here - $this->setInstance($instance); - if ($this->request->get('filter')) { - $this->filterParams = [CustomColumn::URL_PARAM . '[' . $customId . ']' => $this->idGet]; - $this->getFilters($instance); - } elseif ($this->request->get('tree')) { - $this->getHierarchy($instance); - } else { - $this->getCustomEntries($instance); - } - if ($instance->hasChildCategories()) { - $this->hierarchy = [ - "parent" => $instance->getParentEntry(), - "current" => $instance->getEntry(), - "children" => $instance->getChildEntries($this->request->get('tree')), - ]; - } - } - - /** - * Summary of getHierarchy - * @param CustomColumn $instance - * @return void - */ - public function getHierarchy($instance) - { - $booklist = new BookList($this->request); - [$this->entryArray, $this->totalNumber] = $booklist->getBooksByInstanceOrChildren($instance, $this->n); - $this->sorted = $booklist->orderBy ?? "sort"; - } - - /** - * Summary of getCustomEntries - * @param CustomColumn $instance - * @return void - */ - public function getCustomEntries($instance) - { - $columnType = $instance->customColumnType; - $booklist = new BookList($this->request); - if (!empty($this->idGet) || $columnType instanceof CustomColumnTypeBool) { - [$this->entryArray, $this->totalNumber] = $booklist->getBooksByInstance($instance, $this->n); - $this->sorted = $booklist->orderBy ?? "sort"; - return; - } - if ($columnType instanceof CustomColumnTypeDate) { - // if we use $columnType::PAGE_DETAIL in PageAllCustoms, otherwise see PageAllCustoms - $year = $this->request->get("year", null, $columnType::GET_PATTERN); - if (!empty($year)) { - [$this->entryArray, $this->totalNumber] = $booklist->getBooksByCustomYear($columnType, $year, $this->n); - $this->title = $year; - $this->sorted = $booklist->orderBy ?? "value"; - return; - } - } - if ($columnType instanceof CustomColumnTypeInteger) { - // if we use $columnType::PAGE_DETAIL in PageAllCustoms, otherwise see PageAllCustoms - $range = $this->request->get("range", null, $columnType::GET_PATTERN); - if (!empty($range)) { - [$this->entryArray, $this->totalNumber] = $booklist->getBooksByCustomRange($columnType, $range, $this->n); - $this->title = $range; - $this->sorted = $booklist->orderBy ?? "value"; - return; - } - } - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageCustomize.php b/COPS/cops-3.1.3/src/Pages/PageCustomize.php deleted file mode 100644 index c22e98ef..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageCustomize.php +++ /dev/null @@ -1,210 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\VirtualLibrary; -use SebLucas\Cops\Model\Entry; - -class PageCustomize extends Page -{ - /** - * Summary of isChecked - * @param string $key - * @param mixed $testedValue - * @return string - */ - protected function isChecked($key, $testedValue = 1) - { - $value = $this->request->option($key); - if (is_array($value)) { - if (in_array($testedValue, $value)) { - return "checked='checked'"; - } - } else { - if ($value == $testedValue) { - return "checked='checked'"; - } - } - return ""; - } - - /** - * Summary of isSelected - * @param string $key - * @param mixed $value - * @return string - */ - protected function isSelected($key, $value) - { - if ($this->request->option($key) == $value) { - return "selected='selected'"; - } - return ""; - } - - /** - * Summary of getTemplateList - * @return array - */ - protected function getTemplateList() - { - $result = []; - foreach (glob("templates/*", GLOB_ONLYDIR) as $filename) { - if (preg_match('/templates\/(.*)/', $filename, $m)) { - array_push($result, $m [1]); - } - } - return $result; - } - - /** - * Summary of getStyleList - * @return array - */ - protected function getStyleList() - { - $result = []; - foreach (glob("templates/" . $this->request->template() . "/styles/style-*.css") as $filename) { - if (preg_match('/styles\/style-(.*?)\.css/', $filename, $m)) { - array_push($result, $m [1]); - } - } - return $result; - } - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - $this->getEntries(); - $this->title = localize("customize.title"); - } - - /** - * Summary of getEntries - * @return void - */ - public function getEntries() - { - $this->entryArray = []; - - $ignoredBaseArray = [PageQueryResult::SCOPE_AUTHOR, - PageQueryResult::SCOPE_TAG, - PageQueryResult::SCOPE_SERIES, - PageQueryResult::SCOPE_PUBLISHER, - PageQueryResult::SCOPE_RATING, - "language"]; - - $database = $this->getDatabaseId(); - - $title = localize("customize.template"); - $content = ""; - if ($this->useSelectTag()) { - $content .= "'; - } else { - foreach ($this-> getTemplateList() as $filename) { - $content .= "isChecked("template", $filename) . " />
    "; - } - } - $this->addHeaderEntry($title, $content); - - $title = localize("customize.style"); - $content = ""; - if ($this->useSelectTag()) { - $content .= ''; - } else { - foreach ($this-> getStyleList() as $filename) { - $content .= "isChecked("style", $filename) . " />
    "; - } - } - $this->addHeaderEntry($title, $content); - - if (!$this->request->render()) { - $title = localize("customize.fancybox"); - $content = 'isChecked("use_fancyapps") . ' />'; - $this->addHeaderEntry($title, $content); - } - - $title = localize("customize.paging"); - $content = ''; - $this->addHeaderEntry($title, $content); - - $title = localize("customize.email"); - $content = ''; - $this->addHeaderEntry($title, $content); - - $title = localize("customize.filter"); - $content = 'isChecked("html_tag_filter") . ' />'; - $this->addHeaderEntry($title, $content); - - $title = localize("customize.ignored"); - $content = ""; - foreach ($ignoredBaseArray as $key) { - $keyPlural = preg_replace('/(ss)$/', 's', $key . "s"); - $content .= 'isChecked("ignored_categories", $key) . ' > ' . localize("{$keyPlural}.title") . '
    '; - } - $this->addHeaderEntry($title, $content); - - $this->addVirtualLibraries($database); - } - - /** - * Summary of useSelectTag - * @return bool|int - */ - public function useSelectTag() - { - return !preg_match("/(Kobo|Kindle\/3.0|EBRD1101)/", $this->request->agent()); - } - - /** - * Summary of addVirtualLibraries - * @param int|null $database - * @return void - */ - public function addVirtualLibraries($database = null) - { - $libraries = VirtualLibrary::getLibraries($database); - if (empty($libraries)) { - return; - } - $title = localize("library.title"); - $content = ""; - $id = 1; - if ($this->useSelectTag()) { - $content .= "'; - } else { - $content .= "isChecked("virtual_library", "") . " />
    "; - foreach ($libraries as $name => $value) { - $value = VirtualLibrary::formatParameter($id, $name); - $content .= "isChecked("virtual_library", $value) . " />
    "; - $id += 1; - } - } - $this->addHeaderEntry($title, $content); - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageId.php b/COPS/cops-3.1.3/src/Pages/PageId.php deleted file mode 100644 index d1cb62b9..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageId.php +++ /dev/null @@ -1,138 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\Base; -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Request; - -class PageId -{ - public const INDEX = "index"; - public const ALL_AUTHORS = "1"; - public const AUTHORS_FIRST_LETTER = "2"; - public const AUTHOR_DETAIL = "3"; - public const ALL_BOOKS = "4"; - public const ALL_BOOKS_LETTER = "5"; - public const ALL_SERIES = "6"; - public const SERIE_DETAIL = "7"; - public const OPENSEARCH = "8"; - public const SEARCH = "search"; - public const OPENSEARCH_QUERY = "9"; - public const ALL_RECENT_BOOKS = "10"; - public const ALL_TAGS = "11"; - public const TAG_DETAIL = "12"; - public const BOOK_DETAIL = "13"; - public const ALL_CUSTOMS = "14"; - public const CUSTOM_DETAIL = "15"; - public const ABOUT = "16"; - public const ALL_LANGUAGES = "17"; - public const LANGUAGE_DETAIL = "18"; - public const CUSTOMIZE = "19"; - public const ALL_PUBLISHERS = "20"; - public const PUBLISHER_DETAIL = "21"; - public const ALL_RATINGS = "22"; - public const RATING_DETAIL = "23"; - public const ALL_IDENTIFIERS = "41"; - public const IDENTIFIER_DETAIL = "42"; - public const ALL_LIBRARIES = "43"; - public const LIBRARY_DETAIL = "44"; - public const ALL_NOTES = "45"; - public const ALL_NOTES_TYPE = "46"; - public const NOTE_DETAIL = "47"; - public const ALL_PREFERENCES = "48"; - public const PREFERENCE_DETAIL = "49"; - public const ALL_BOOKS_YEAR = "50"; - public const ALL_ANNOTATIONS = "61"; - public const ANNOTATIONS_BOOK = "62"; - public const ANNOTATION_DETAIL = "63"; - public const EPUBJS_ZIPFS = "95"; - public const CALIBRE_RESOURCE = "97"; - public const REST_API = "98"; - public const FILTER = "99"; - public const ERROR = "100"; - public const INDEX_ID = "cops:catalog"; - public const ABOUT_ID = "cops:about"; - public const FILTER_ID = "cops:filter"; - public const ERROR_ID = "cops:error"; - public const ALL_AUTHORS_ID = "cops:authors"; - public const ALL_BASES_ID = "cops:bases"; - public const ALL_BOOKS_UUID = 'urn:uuid'; - public const ALL_BOOKS_ID = 'cops:books'; - public const ALL_RECENT_BOOKS_ID = 'cops:recentbooks'; - public const ALL_CUSTOMS_ID = "cops:custom"; - public const ALL_LANGUAGES_ID = "cops:languages"; - public const ALL_PUBLISHERS_ID = "cops:publishers"; - public const ALL_RATING_ID = "cops:rating"; - public const ALL_SERIES_ID = "cops:series"; - public const ALL_TAGS_ID = "cops:tags"; - public const ALL_IDENTIFIERS_ID = "cops:identifiers"; - public const ALL_LIBRARIES_ID = "cops:libraries"; - public const ALL_NOTES_ID = "cops:notes"; - public const ALL_PREFERENCES_ID = "cops:preferences"; - public const ALL_ANNOTATIONS_ID = "cops:annotations"; - - /** - * Summary of getPage - * @param string|int|null $pageId - * @param ?Request $request - * @param ?Base $instance @todo investigate potential use as alternative to getEntry() - * @return Page|PageAbout|PageAllAuthors|PageAllAuthorsLetter|PageAllBooks|PageAllBooksLetter|PageAllBooksYear|PageAllCustoms|PageAllLanguages|PageAllPublishers|PageAllRating|PageAllSeries|PageAllTags|PageAuthorDetail|PageBookDetail|PageCustomDetail|PageCustomize|PageLanguageDetail|PagePublisherDetail|PageQueryResult|PageRatingDetail|PageRecentBooks|PageSerieDetail|PageTagDetail - */ - public static function getPage($pageId, $request, $instance = null) - { - // @see https://www.php.net/manual/en/control-structures.match.php - // Unlike switch, the comparison is an identity check (===) rather than a weak equality check (==) - return match ((string) $pageId) { - PageId::ALL_AUTHORS => new PageAllAuthors($request), - PageId::AUTHORS_FIRST_LETTER => new PageAllAuthorsLetter($request), - PageId::AUTHOR_DETAIL => new PageAuthorDetail($request, $instance), - PageId::ALL_TAGS => new PageAllTags($request), - PageId::TAG_DETAIL => new PageTagDetail($request, $instance), - PageId::ALL_LANGUAGES => new PageAllLanguages($request), - PageId::LANGUAGE_DETAIL => new PageLanguageDetail($request, $instance), - PageId::ALL_CUSTOMS => new PageAllCustoms($request), - PageId::CUSTOM_DETAIL => new PageCustomDetail($request, $instance), - PageId::ALL_RATINGS => new PageAllRating($request), - PageId::RATING_DETAIL => new PageRatingDetail($request, $instance), - PageId::ALL_SERIES => new PageAllSeries($request), - PageId::ALL_BOOKS => new PageAllBooks($request), - PageId::ALL_BOOKS_LETTER => new PageAllBooksLetter($request), - PageId::ALL_BOOKS_YEAR => new PageAllBooksYear($request), - PageId::ALL_RECENT_BOOKS => new PageRecentBooks($request), - PageId::SERIE_DETAIL => new PageSerieDetail($request, $instance), - PageId::OPENSEARCH_QUERY => new PageQueryResult($request), - // support ?query=... URL param by default for opensearch - PageId::OPENSEARCH => !empty($request->get('query')) ? new PageQueryResult($request) : new PageIndex($request), - PageId::BOOK_DETAIL => new PageBookDetail($request), - PageId::ALL_PUBLISHERS => new PageAllPublishers($request), - PageId::PUBLISHER_DETAIL => new PagePublisherDetail($request, $instance), - PageId::ALL_IDENTIFIERS => new PageAllIdentifiers($request), - PageId::IDENTIFIER_DETAIL => new PageIdentifierDetail($request, $instance), - PageId::ALL_LIBRARIES => new PageAllVirtualLibraries($request), - PageId::ABOUT => new PageAbout($request), - PageId::CUSTOMIZE => new PageCustomize($request), - default => new PageIndex($request), - }; - } - - /** - * Summary of getHomePage - * @return string|int - */ - public static function getHomePage() - { - // Use the configured home page if needed - $page = PageId::INDEX; - if (!empty(Config::get('home_page')) && defined('SebLucas\Cops\Pages\PageId::' . Config::get('home_page'))) { - $page = constant('SebLucas\Cops\Pages\PageId::' . Config::get('home_page')); - } - return $page; - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageIdentifierDetail.php b/COPS/cops-3.1.3/src/Pages/PageIdentifierDetail.php deleted file mode 100644 index 0eefdc3a..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageIdentifierDetail.php +++ /dev/null @@ -1,56 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\BookList; -use SebLucas\Cops\Calibre\Identifier; - -/** - * This shows the books with a particular identifier type, e.g. amazon, isbn, url, ... - */ -class PageIdentifierDetail extends PageWithDetail -{ - /** - * Summary of className - * @var string - */ - protected string $className = Identifier::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - // this would be the identifier - override here - $this->idGet = $this->request->get('id', null, '/^\w+$/'); - /** @var Identifier $instance */ - $instance = Identifier::getInstanceById($this->idGet, $this->getDatabaseId()); - $instance->setHandler($this->handler); - if ($this->request->get('filter')) { - $this->filterParams = [Identifier::URL_PARAM => $this->idGet]; - $this->getFilters($instance); - } else { - $this->getEntries($instance); - } - $this->setInstance($instance); - } - - /** - * Summary of getEntries - * @param Identifier $instance - * @return void - */ - public function getEntries($instance = null) - { - $booklist = new BookList($this->request); - [$this->entryArray, $this->totalNumber] = $booklist->getBooksByInstance($instance, $this->n); - $this->sorted = $booklist->orderBy ?? "sort"; - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageIndex.php b/COPS/cops-3.1.3/src/Pages/PageIndex.php deleted file mode 100644 index ce16dbf2..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageIndex.php +++ /dev/null @@ -1,227 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\Author; -use SebLucas\Cops\Calibre\BaseList; -use SebLucas\Cops\Calibre\BookList; -use SebLucas\Cops\Calibre\CustomColumnType; -use SebLucas\Cops\Calibre\Database; -use SebLucas\Cops\Calibre\Language; -use SebLucas\Cops\Calibre\Publisher; -use SebLucas\Cops\Calibre\Rating; -use SebLucas\Cops\Calibre\Serie; -use SebLucas\Cops\Calibre\Tag; -use SebLucas\Cops\Calibre\VirtualLibrary; -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Model\Entry; -use SebLucas\Cops\Model\LinkNavigation; - -class PageIndex extends Page -{ - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - $this->getEntries(); - $this->idPage = static::PAGE_ID; - $this->title = Config::get('title_default'); - $this->subtitle = Config::get('subtitle_default'); - } - - /** - * Summary of getEntries - * @return void - */ - public function getEntries() - { - if (Database::noDatabaseSelected($this->databaseId)) { - $this->getDatabaseEntries(); - } elseif ($this->request->hasFilter()) { - $this->getFilterCountEntries(); - } else { - $this->getTopCountEntries(); - } - $this->getExtra(); - } - - /** - * Summary of getDatabaseEntries - * @return void - */ - public function getDatabaseEntries() - { - $i = 0; - foreach (Database::getDbNameList() as $key) { - $booklist = new BookList($this->request, $i); - $nBooks = $booklist->getBookCount(); - $this->addDatabaseEntry($key, $i, $nBooks); - $i++; - Database::clearDb(); - } - } - - /** - * Summary of addDatabaseEntry - * @param string $name - * @param int $idx - * @param int $count - * @return void - */ - public function addDatabaseEntry($name, $idx, $count) - { - array_push($this->entryArray, $this->getDatabaseEntry($name, $idx, $count)); - } - - /** - * Summary of getDatabaseEntry - * @param string $name - * @param int $idx - * @param int $count - * @return Entry - */ - public function getDatabaseEntry($name, $idx, $count) - { - $url = Route::link($this->handler, null, ["db" => $idx]); - return new Entry( - $name, - "cops:{$idx}:catalog", - str_format(localize("bookword", $count), $count), - "text", - [ new LinkNavigation($url) ], - null, - "", - $count - ); - } - - /** - * Summary of getFilterCountEntries - * @return void - */ - public function getFilterCountEntries() - { - $this->filterParams = $this->request->getFilterParams(); - if (!in_array(PageQueryResult::SCOPE_AUTHOR, $this->ignoredCategories)) { - $this->addFilterCountEntry(Author::class); - } - if (!in_array(PageQueryResult::SCOPE_SERIES, $this->ignoredCategories)) { - $this->addFilterCountEntry(Serie::class); - } - if (!in_array(PageQueryResult::SCOPE_PUBLISHER, $this->ignoredCategories)) { - $this->addFilterCountEntry(Publisher::class); - } - if (!in_array(PageQueryResult::SCOPE_TAG, $this->ignoredCategories)) { - $this->addFilterCountEntry(Tag::class); - } - if (!in_array(PageQueryResult::SCOPE_RATING, $this->ignoredCategories)) { - $this->addFilterCountEntry(Rating::class, "ratings"); - } - if (!in_array(PageQueryResult::SCOPE_LANGUAGE, $this->ignoredCategories)) { - $this->addFilterCountEntry(Language::class); - } - // @todo apply filter? - // for multi-database setup, not all databases may have all custom columns - see issue #89 - $customColumnList = CustomColumnType::checkCustomColumnList(Config::get('calibre_custom_column'), $this->getDatabaseId()); - foreach ($customColumnList as $lookup) { - $customColumn = CustomColumnType::createByLookup($lookup, $this->getDatabaseId()); - if (!is_null($customColumn) && $customColumn->isSearchable()) { - $customColumn->setHandler($this->handler); - array_push($this->entryArray, $customColumn->getCount()); - } - } - if (!empty(Config::get('calibre_virtual_libraries')) && !in_array('libraries', $this->ignoredCategories)) { - $library = VirtualLibrary::getCount($this->databaseId, $this->handler); - if (!is_null($library)) { - array_push($this->entryArray, $library); - } - } - $booklist = new BookList($this->request); - $this->addEntries($booklist->getCount()); - - if (Database::isMultipleDatabaseEnabled()) { - $this->title = Database::getDbName($this->getDatabaseId()); - } - } - - /** - * Summary of addFilterCountEntry - * @param string $className - * @param ?string $numberOfString - * @return void - */ - public function addFilterCountEntry($className, $numberOfString = null) - { - $baselist = new BaseList($className, $this->request, $this->databaseId); - $count = $baselist->countRequestEntries(); - if ($count > 0) { - array_push($this->entryArray, $className::getCountEntry($count, $this->databaseId, $numberOfString, $this->handler, $this->filterParams)); - } - } - - /** - * Summary of getTopCountEntries - * @return void - */ - public function getTopCountEntries() - { - if (!in_array(PageQueryResult::SCOPE_AUTHOR, $this->ignoredCategories)) { - $this->addTopCountEntry(Author::class); - } - if (!in_array(PageQueryResult::SCOPE_SERIES, $this->ignoredCategories)) { - $this->addTopCountEntry(Serie::class); - } - if (!in_array(PageQueryResult::SCOPE_PUBLISHER, $this->ignoredCategories)) { - $this->addTopCountEntry(Publisher::class); - } - if (!in_array(PageQueryResult::SCOPE_TAG, $this->ignoredCategories)) { - $this->addTopCountEntry(className: Tag::class); - } - if (!in_array(PageQueryResult::SCOPE_RATING, $this->ignoredCategories)) { - $this->addTopCountEntry(className: Rating::class); - } - if (!in_array(PageQueryResult::SCOPE_LANGUAGE, $this->ignoredCategories)) { - $this->addTopCountEntry(Language::class); - } - // for multi-database setup, not all databases may have all custom columns - see issue #89 - $customColumnList = CustomColumnType::checkCustomColumnList(Config::get('calibre_custom_column'), $this->getDatabaseId()); - foreach ($customColumnList as $lookup) { - $customColumn = CustomColumnType::createByLookup($lookup, $this->getDatabaseId()); - if (!is_null($customColumn) && $customColumn->isSearchable()) { - $customColumn->setHandler($this->handler); - array_push($this->entryArray, $customColumn->getCount()); - } - } - if (!empty(Config::get('calibre_virtual_libraries')) && !in_array('libraries', $this->ignoredCategories)) { - $this->addTopCountEntry(VirtualLibrary::class); - } - $booklist = new BookList($this->request); - $this->addEntries($booklist->getCount()); - - if (Database::isMultipleDatabaseEnabled()) { - $this->title = Database::getDbName($this->getDatabaseId()); - } - } - - /** - * Summary of addTopCountEntry - * @param string $className - * @return void - */ - public function addTopCountEntry($className) - { - $entry = $className::getCount($this->databaseId, $this->handler); - if (!is_null($entry)) { - array_push($this->entryArray, $entry); - } - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageLanguageDetail.php b/COPS/cops-3.1.3/src/Pages/PageLanguageDetail.php deleted file mode 100644 index efbbf79f..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageLanguageDetail.php +++ /dev/null @@ -1,47 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\BookList; -use SebLucas\Cops\Calibre\Language; - -class PageLanguageDetail extends PageWithDetail -{ - protected string $className = Language::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - /** @var Language $instance */ - $instance = Language::getInstanceById($this->idGet, $this->getDatabaseId()); - $instance->setHandler($this->handler); - if ($this->request->get('filter')) { - $this->filterParams = [Language::URL_PARAM => $this->idGet]; - $this->getFilters($instance); - } else { - $this->getEntries($instance); - } - $this->setInstance($instance); - } - - /** - * Summary of getEntries - * @param Language $instance - * @return void - */ - public function getEntries($instance = null) - { - $booklist = new BookList($this->request); - [$this->entryArray, $this->totalNumber] = $booklist->getBooksByInstance($instance, $this->n); - $this->sorted = $booklist->orderBy ?? "sort"; - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PagePublisherDetail.php b/COPS/cops-3.1.3/src/Pages/PagePublisherDetail.php deleted file mode 100644 index d8a05b27..00000000 --- a/COPS/cops-3.1.3/src/Pages/PagePublisherDetail.php +++ /dev/null @@ -1,47 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\BookList; -use SebLucas\Cops\Calibre\Publisher; - -class PagePublisherDetail extends PageWithDetail -{ - protected string $className = Publisher::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - /** @var Publisher $instance */ - $instance = Publisher::getInstanceById($this->idGet, $this->getDatabaseId()); - $instance->setHandler($this->handler); - if ($this->request->get('filter')) { - $this->filterParams = [Publisher::URL_PARAM => $this->idGet]; - $this->getFilters($instance); - } else { - $this->getEntries($instance); - } - $this->setInstance($instance); - } - - /** - * Summary of getEntries - * @param Publisher $instance - * @return void - */ - public function getEntries($instance = null) - { - $booklist = new BookList($this->request); - [$this->entryArray, $this->totalNumber] = $booklist->getBooksByInstance($instance, $this->n); - $this->sorted = $booklist->orderBy ?? "sort"; - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageQueryResult.php b/COPS/cops-3.1.3/src/Pages/PageQueryResult.php deleted file mode 100644 index 462a9ef5..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageQueryResult.php +++ /dev/null @@ -1,309 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\Author; -use SebLucas\Cops\Calibre\BaseList; -use SebLucas\Cops\Calibre\BookList; -use SebLucas\Cops\Calibre\Database; -use SebLucas\Cops\Calibre\Publisher; -use SebLucas\Cops\Calibre\Serie; -use SebLucas\Cops\Calibre\Tag; -use SebLucas\Cops\Input\Request; -use SebLucas\Cops\Input\Route; -use SebLucas\Cops\Language\Translation; -use SebLucas\Cops\Model\Entry; -use SebLucas\Cops\Model\LinkNavigation; - -class PageQueryResult extends Page -{ - public const PAGE_ID = PageId::OPENSEARCH_QUERY; - public const SCOPE_TAG = "tag"; - public const SCOPE_RATING = "rating"; - public const SCOPE_SERIES = "series"; - public const SCOPE_AUTHOR = "author"; - public const SCOPE_BOOK = "book"; - public const SCOPE_PUBLISHER = "publisher"; - public const SCOPE_LANGUAGE = "language"; - - /** @var ?string */ - public $query; - - public function setRequest($request) - { - parent::setRequest($request); - $this->query = $this->request->get('query'); - } - - /** - * Summary of useTypeahead - * @return bool - */ - protected function useTypeahead() - { - return !is_null($this->request->get("search")); - } - - /** - * Summary of searchByScope - * @param string $scope - * @param bool $limit - * @param ?int $database - * @return array - */ - protected function searchByScope($scope, $limit = false, $database = null) - { - $n = $this->n; - $numberPerPage = null; - $queryNormedAndUp = trim((string) $this->query); - if (Translation::useNormAndUp()) { - $queryNormedAndUp = Translation::normAndUp($this->query); - } - if ($limit) { - $n = 1; - $numberPerPage = 5; - } - $libraryId = ""; - if (!Database::noDatabaseSelected($database)) { - $libraryId = $this->request->getVirtualLibrary(); - } - if (!empty($libraryId)) { - $req = Request::build(['vl' => $libraryId], $this->handler); - } else { - $req = Request::build([], $this->handler); - } - switch ($scope) { - case static::SCOPE_BOOK : - $booklist = new BookList($req, $database, $numberPerPage); - $array = $booklist->getBooksByFirstLetter('%' . $queryNormedAndUp, $n); - break; - case static::SCOPE_AUTHOR : - $baselist = new BaseList(Author::class, $req, $database, $numberPerPage); - // we need to repeat the query x 2 here because Author checks both name and sort fields - $array = $baselist->getAllEntriesByQuery($queryNormedAndUp, $n, 2); - break; - case static::SCOPE_SERIES : - $baselist = new BaseList(Serie::class, $req, $database, $numberPerPage); - $array = $baselist->getAllEntriesByQuery($queryNormedAndUp, $n); - break; - case static::SCOPE_TAG : - $baselist = new BaseList(Tag::class, $req, $database, $numberPerPage); - $array = $baselist->getAllEntriesByQuery($queryNormedAndUp, $n); - break; - case static::SCOPE_PUBLISHER : - $baselist = new BaseList(Publisher::class, $req, $database, $numberPerPage); - $array = $baselist->getAllEntriesByQuery($queryNormedAndUp, $n); - break; - default: - $booklist = new BookList($req, $database, $numberPerPage); - $array = $booklist->getBooksByQueryScope( - ["all" => "%" . $queryNormedAndUp . "%"], - $n - ); - } - - return $array; - } - - /** - * Summary of doSearchByCategory - * @param ?int $database - * @return void - */ - public function doSearchByCategory($database = null) - { - $pagequery = $this->idPage; - $dbArray = [""]; - $d = $database; - $query = $this->query; - $libraryId = ""; - // Special case when no databases were chosen, we search on all databases - if (Database::noDatabaseSelected($database)) { - $dbArray = Database::getDbNameList(); - $d = 0; - } else { - $libraryId = $this->request->getVirtualLibrary(); - } - foreach ($dbArray as $key) { - if (Database::noDatabaseSelected($database)) { - $url = Route::link($this->handler, null, ["db" => $d]); - array_push($this->entryArray, new Entry( - $key, - "db:query:{$d}", - " ", - "text", - [ new LinkNavigation($url) ], - null, - "tt-header" - )); - Database::getDb($d); - } - foreach ([PageQueryResult::SCOPE_BOOK, - PageQueryResult::SCOPE_AUTHOR, - PageQueryResult::SCOPE_SERIES, - PageQueryResult::SCOPE_TAG, - PageQueryResult::SCOPE_PUBLISHER] as $key) { - if (in_array($key, $this->getIgnoredCategories())) { - continue; - } - $array = $this->searchByScope($key, true, $database); - - $i = 0; - if (count($array) == 2 && is_array($array [0])) { - $total = $array [1]; - $array = $array [0]; - // show the number of entries here, not the number of books found - //$total = count($array); - } else { - $total = count($array); - } - if ($total > 0) { - // Comment to help the perl i18n script - // str_format (localize("bookword", count($array)) - // str_format (localize("authorword", count($array)) - // str_format (localize("seriesword", count($array)) - // str_format (localize("tagword", count($array)) - // str_format (localize("publisherword", count($array)) - $params = ['query' => $query, 'db' => $d, 'scope' => $key]; - if (!empty($libraryId)) { - $params['vl'] = $libraryId; - } - $url = Route::link($this->handler, $pagequery, $params); - array_push($this->entryArray, new Entry( - str_format(localize("search.result.{$key}"), $this->query), - "db:query:{$d}:{$key}", - str_format(localize("{$key}word", $total), $total), - "text", - [ new LinkNavigation($url) ], - $database, - Database::noDatabaseSelected($database) ? "" : "tt-header", - $total - )); - } - if (!Database::noDatabaseSelected($database) && $this->useTypeahead()) { - foreach ($array as $entry) { - array_push($this->entryArray, $entry); - $i++; - if ($i > 4) { - break; - }; - } - } - } - $d++; - if (Database::noDatabaseSelected($database)) { - Database::clearDb(); - } - } - } - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - $this->idPage = static::PAGE_ID; - $scope = $this->request->get("scope"); - if (empty($scope)) { - $this->title = str_format(localize("search.result"), $this->query); - } else { - // Comment to help the perl i18n script - // str_format (localize ("search.result.author"), $this->query) - // str_format (localize ("search.result.tag"), $this->query) - // str_format (localize ("search.result.series"), $this->query) - // str_format (localize ("search.result.book"), $this->query) - // str_format (localize ("search.result.publisher"), $this->query) - $this->title = str_format(localize("search.result.{$scope}"), $this->query); - } - $this->getEntries(); - } - - /** - * Summary of getEntries - * @return void - */ - public function getEntries() - { - $database = $this->getDatabaseId(); - // Special case when we are doing a search and no database is selected - if (Database::noDatabaseSelected($database) && !$this->useTypeahead()) { - $this->getDatabaseEntries(); - return; - } - - $scope = $this->request->get("scope"); - if (empty($scope)) { - $this->doSearchByCategory($database); - return; - } - - $array = $this->searchByScope($scope, false, $database); - if (count($array) == 2 && is_array($array [0])) { - [$this->entryArray, $this->totalNumber] = $array; - } else { - $this->entryArray = $array; - } - } - - /** - * Summary of getDatabaseEntries - * @return void - */ - public function getDatabaseEntries() - { - $ignoredCategories = $this->getIgnoredCategories(); - $query = $this->query; - $crit = "%" . $this->query . "%"; - $d = 0; - foreach (Database::getDbNameList() as $key) { - Database::clearDb(); - $booklist = new BookList($this->request, $d, 1); - [$array, $totalNumber] = $booklist->getBooksByQueryScope(["all" => $crit], 1, $ignoredCategories); - $this->addDatabaseEntry($key, $d, $totalNumber, $query); - $d++; - } - } - - /** - * Summary of addDatabaseEntry - * @param string $name - * @param int $idx - * @param int $count - * @param string $query - * @return void - */ - public function addDatabaseEntry($name, $idx, $count, $query) - { - array_push($this->entryArray, $this->getDatabaseEntry($name, $idx, $count, $query)); - } - - /** - * Summary of getDatabaseEntry - * @param string $name - * @param int $idx - * @param int $count - * @param string $query - * @return Entry - */ - public function getDatabaseEntry($name, $idx, $count, $query) - { - $url = Route::link($this->handler, $this->idPage, ['query' => $query, 'db' => $idx]); - return new Entry( - $name, - "db:query:{$idx}", - str_format(localize("bookword", $count), $count), - "text", - [ new LinkNavigation($url) ], - null, - "", - $count - ); - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageRatingDetail.php b/COPS/cops-3.1.3/src/Pages/PageRatingDetail.php deleted file mode 100644 index 75712c07..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageRatingDetail.php +++ /dev/null @@ -1,47 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\BookList; -use SebLucas\Cops\Calibre\Rating; - -class PageRatingDetail extends PageWithDetail -{ - protected string $className = Rating::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - /** @var Rating $instance */ - $instance = Rating::getInstanceById($this->idGet, $this->getDatabaseId()); - $instance->setHandler($this->handler); - if ($this->request->get('filter')) { - $this->filterParams = [Rating::URL_PARAM => $this->idGet]; - $this->getFilters($instance); - } else { - $this->getEntries($instance); - } - $this->setInstance($instance); - } - - /** - * Summary of getEntries - * @param Rating $instance - * @return void - */ - public function getEntries($instance = null) - { - $booklist = new BookList($this->request); - [$this->entryArray, $this->totalNumber] = $booklist->getBooksByInstance($instance, $this->n); - $this->sorted = $booklist->orderBy ?? "sort"; - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageRecentBooks.php b/COPS/cops-3.1.3/src/Pages/PageRecentBooks.php deleted file mode 100644 index 3bc33317..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageRecentBooks.php +++ /dev/null @@ -1,39 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\BookList; - -class PageRecentBooks extends Page -{ - public const PAGE_ID = PageId::ALL_RECENT_BOOKS_ID; - //protected string $className = Book::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - $this->getEntries(); - $this->idPage = static::PAGE_ID; - $this->title = localize("recent.title"); - } - - /** - * Summary of getEntries - * @return void - */ - public function getEntries() - { - $booklist = new BookList($this->request); - $this->entryArray = $booklist->getAllRecentBooks(); - $this->sorted = $booklist->orderBy ?? "timestamp desc"; - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageSerieDetail.php b/COPS/cops-3.1.3/src/Pages/PageSerieDetail.php deleted file mode 100644 index 92b7cfb1..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageSerieDetail.php +++ /dev/null @@ -1,69 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\BookList; -use SebLucas\Cops\Calibre\Serie; - -class PageSerieDetail extends PageWithDetail -{ - protected string $className = Serie::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - /** @var Serie $instance */ - $instance = Serie::getInstanceById($this->idGet, $this->getDatabaseId()); - $instance->setHandler($this->handler); - if ($this->request->get('filter')) { - $this->filterParams = [Serie::URL_PARAM => $this->idGet]; - $this->getFilters($instance); - // @todo needs title_sort function in sqlite for series - //} elseif ($this->request->get('tree')) { - // $this->getHierarchy($instance); - } else { - $this->getEntries($instance); - } - $this->setInstance($instance); - //if ($instance->hasChildCategories()) { - // $this->hierarchy = [ - // "parent" => $instance->getParentEntry(), - // "current" => $instance->getEntry(), - // "children" => $instance->getChildEntries($this->request->get('tree')), - // ]; - //} - } - - /** - * Summary of getHierarchy - * @param Serie $instance - * @return void - */ - public function getHierarchy($instance) - { - $booklist = new BookList($this->request); - [$this->entryArray, $this->totalNumber] = $booklist->getBooksByInstanceOrChildren($instance, $this->n); - $this->sorted = $booklist->orderBy ?? "sort"; - } - - /** - * Summary of getEntries - * @param ?Serie $instance - * @return void - */ - public function getEntries($instance = null) - { - $booklist = new BookList($this->request); - [$this->entryArray, $this->totalNumber] = $booklist->getBooksByInstance($instance, $this->n); - $this->sorted = $booklist->orderBy ?? "series_index"; - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageTagDetail.php b/COPS/cops-3.1.3/src/Pages/PageTagDetail.php deleted file mode 100644 index 5b774c86..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageTagDetail.php +++ /dev/null @@ -1,68 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\BookList; -use SebLucas\Cops\Calibre\Tag; - -class PageTagDetail extends PageWithDetail -{ - protected string $className = Tag::class; - - /** - * Summary of initializeContent - * @return void - */ - public function initializeContent() - { - /** @var Tag $instance */ - $instance = Tag::getInstanceById($this->idGet, $this->getDatabaseId()); - $instance->setHandler($this->handler); - if ($this->request->get('filter')) { - $this->filterParams = [Tag::URL_PARAM => $this->idGet]; - $this->getFilters($instance); - } elseif ($this->request->get('tree')) { - $this->getHierarchy($instance); - } else { - $this->getEntries($instance); - } - $this->setInstance($instance); - if ($instance->hasChildCategories()) { - $this->hierarchy = [ - "parent" => $instance->getParentEntry(), - "current" => $instance->getEntry(), - "children" => $instance->getChildEntries($this->request->get('tree')), - ]; - } - } - - /** - * Summary of getHierarchy - * @param Tag $instance - * @return void - */ - public function getHierarchy($instance) - { - $booklist = new BookList($this->request); - [$this->entryArray, $this->totalNumber] = $booklist->getBooksByInstanceOrChildren($instance, $this->n); - $this->sorted = $booklist->orderBy ?? "sort"; - } - - /** - * Summary of getEntries - * @param ?Tag $instance - * @return void - */ - public function getEntries($instance = null) - { - $booklist = new BookList($this->request); - [$this->entryArray, $this->totalNumber] = $booklist->getBooksByInstance($instance, $this->n); - $this->sorted = $booklist->orderBy ?? "sort"; - } -} diff --git a/COPS/cops-3.1.3/src/Pages/PageWithDetail.php b/COPS/cops-3.1.3/src/Pages/PageWithDetail.php deleted file mode 100644 index f30b16c1..00000000 --- a/COPS/cops-3.1.3/src/Pages/PageWithDetail.php +++ /dev/null @@ -1,217 +0,0 @@ - - */ - -namespace SebLucas\Cops\Pages; - -use SebLucas\Cops\Calibre\Author; -use SebLucas\Cops\Calibre\Base; -use SebLucas\Cops\Calibre\CustomColumn; -use SebLucas\Cops\Calibre\Identifier; -use SebLucas\Cops\Calibre\Language; -use SebLucas\Cops\Calibre\Publisher; -use SebLucas\Cops\Calibre\Rating; -use SebLucas\Cops\Calibre\Resource; -use SebLucas\Cops\Calibre\Serie; -use SebLucas\Cops\Calibre\Tag; -use SebLucas\Cops\Calibre\VirtualLibrary; -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Input\Request; -use SebLucas\Cops\Input\Route; - -class PageWithDetail extends Page -{ - /** - * Summary of __construct - * @param ?Request $request - * @param ?Base $instance @todo investigate potential use as alternative to getEntry() - */ - public function __construct($request = null, $instance = null) - { - $this->setConfig(); - $this->setRequest($request); - - // move to constructor as this is always called directly after PageId::getPage() - if (empty($instance)) { - $this->initializeContent(); - } else { - // do not call getEntries() here - $this->setInstance($instance); - } - } - - /** - * Summary of setInstance - * @param ?Base $instance - * @return void - */ - public function setInstance($instance) - { - $this->idPage = $instance->getEntryId(); - $this->title = $instance->getTitle(); - // this is the unfiltered uri here, used in JsonRenderer - @todo do we want to use request->urlParams? - $this->currentUri = $instance->getUri(); - $this->parentTitle = $instance->getParentTitle(); - $filterParams = $this->request->getFilterParams(); - $this->parentUri = $instance->getParentUri($filterParams); - } - - /** - * Summary of getFilters - * @param Author|Language|Publisher|Rating|Serie|Tag|Identifier|CustomColumn $instance - * @return void - */ - public function getFilters($instance) - { - if ($this->request->isFeed()) { - $filterLinks = Config::get('opds_filter_links'); - $instance->setFilterLimit(Config::get('opds_filter_limit')); - } else { - $filterLinks = Config::get('html_filter_links'); - $instance->setFilterLimit(Config::get('html_filter_limit')); - } - $this->entryArray = []; - if (empty($filterLinks)) { - return; - } - // we use g[a]=2 to indicate we want to paginate in facetgroup Authors - $paging = $this->request->get('g'); - if (!is_array($paging)) { - $paging = []; - } - // if we want to filter by virtual library etc. - $libraryId = $this->request->getVirtualLibrary(); - if (!empty($libraryId)) { - $instance->setFilterParams([VirtualLibrary::URL_PARAM => $libraryId]); - } - // @todo get rid of extraParams in JsonRenderer and OpdsRenderer as filters should be included in navlink now - $params = $instance->getExtraParams(); - $params['db'] = $this->getDatabaseId(); - $filtersTitle = localize("filters.title"); - if (!($instance instanceof Author) && in_array('author', $filterLinks)) { - $title = localize(phrase: "authors.title"); - $href = Route::link($this->handler, Author::PAGE_ALL, $params); - $relation = "authors"; - $this->addHeaderEntry($title, $filtersTitle, $href, $relation); - $paging['a'] ??= 1; - $this->addEntries($instance->getAuthors($paging['a'])); - } - if (!($instance instanceof Language) && in_array('language', $filterLinks)) { - $title = localize("languages.title"); - $href = Route::link($this->handler, Language::PAGE_ALL, $params); - $relation = "languages"; - $this->addHeaderEntry($title, $filtersTitle, $href, $relation); - $paging['l'] ??= 1; - $this->addEntries($instance->getLanguages($paging['l'])); - } - if (!($instance instanceof Publisher) && in_array('publisher', $filterLinks)) { - $title = localize("publishers.title"); - $href = Route::link($this->handler, Publisher::PAGE_ALL, $params); - $relation = "publishers"; - $this->addHeaderEntry($title, $filtersTitle, $href, $relation); - $paging['p'] ??= 1; - $this->addEntries($instance->getPublishers($paging['p'])); - } - if (!($instance instanceof Rating) && in_array('rating', $filterLinks)) { - $title = localize("ratings.title"); - $href = Route::link($this->handler, Rating::PAGE_ALL, $params); - $relation = "ratings"; - $this->addHeaderEntry($title, $filtersTitle, $href, $relation); - $paging['r'] ??= 1; - $this->addEntries($instance->getRatings($paging['r'])); - } - if (!($instance instanceof Serie) && in_array('series', $filterLinks)) { - $title = localize("series.title"); - $href = Route::link($this->handler, Serie::PAGE_ALL, $params); - $relation = "series"; - $this->addHeaderEntry($title, $filtersTitle, $href, $relation); - $paging['s'] ??= 1; - $this->addEntries($instance->getSeries($paging['s'])); - } - if (in_array('tag', $filterLinks)) { - $title = localize("tags.title"); - $href = Route::link($this->handler, Tag::PAGE_ALL, $params); - $relation = "tags"; - $this->addHeaderEntry($title, $filtersTitle, $href, $relation); - $paging['t'] ??= 1; - // special case if we want to find other tags applied to books where this tag applies - if ($instance instanceof Tag) { - $instance->limitSelf = false; - } - $this->addEntries($instance->getTags($paging['t'])); - } - if (in_array('identifier', $filterLinks)) { - $title = localize("identifiers.title"); - $href = Route::link($this->handler, Identifier::PAGE_ALL, $params); - $relation = "identifiers"; - $this->addHeaderEntry($title, $filtersTitle, $href, $relation); - $paging['i'] ??= 1; - // special case if we want to find other identifiers applied to books where this identifier applies - if ($instance instanceof Identifier) { - $instance->limitSelf = false; - } - $this->addEntries($instance->getIdentifiers($paging['i'])); - } - /** - // we'd need to apply getEntriesById from $instance on $customType instance here - too messy - if (!($instance instanceof CustomColumn) && in_array('custom', $filterLinks)) { - $columns = CustomColumnType::getAllCustomColumns($this->getDatabaseId()); - $paging['c'] ??= []; - foreach ($columns as $label => $column) { - $customType = CustomColumnType::createByCustomID($column["id"], $this->getDatabaseId()); - $title = $customType->getTitle(); - $href = $customType->getParentUri(); - $relation = $customType->getTitle(); - $this->addHeaderEntry($title, $filtersTitle, $href, $relation); - $paging['c'][$column['id']] ??= 1; - $entries = $instance->getCustomValues($customType); - // @todo - } - } - */ - } - - /** - * Summary of canFilter - * @return bool - */ - public function canFilter() - { - if ($this->request->isFeed()) { - $filterLinks = Config::get('opds_filter_links'); - } else { - $filterLinks = Config::get('html_filter_links'); - } - if (!empty($filterLinks)) { - return true; - } - return false; - } - - /** - * Summary of getExtra - * @param Base $instance - * @return void - */ - public function getExtra($instance = null) - { - if (!is_null($instance) && !empty($instance->id)) { - $content = null; - $note = $instance->getNote(); - if (!empty($note) && !empty($note->doc)) { - $content = Resource::fixResourceLinks($note->doc, $instance->getDatabaseId()); - } - if (!empty($instance->link) || !empty($content)) { - $this->extra = [ - "title" => localize("extra.title"), - "link" => $instance->link, - "content" => $content, - ]; - } - } - } -} diff --git a/COPS/cops-3.1.3/src/functions.php b/COPS/cops-3.1.3/src/functions.php deleted file mode 100644 index 71de023c..00000000 --- a/COPS/cops-3.1.3/src/functions.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @author mikespub - */ - -use SebLucas\Cops\Input\Config; -use SebLucas\Cops\Language\Translation; -use SebLucas\Cops\Output\Format; - -if (!function_exists('str_format')) { - /** - * Summary of str_format - * @param string $format - * @param array $args - * @return string - */ - function str_format($format, ...$args) - { - return Format::str_format($format, ...$args); - } -} - -if (!function_exists('localize')) { - $translator = new Translation($_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? null); - Config::set('_translator_', $translator); - - /** - * Summary of localize - * @param string $phrase - * @param int $count - * @param bool $reset - * @return string - */ - function localize($phrase, $count = -1, $reset = false) - { - return Config::get('_translator_')->localize($phrase, $count, $reset); - } -} diff --git a/COPS/cops-3.1.3/styles/cops-monocle.css b/COPS/cops-3.1.3/styles/cops-monocle.css deleted file mode 100644 index d9592c92..00000000 --- a/COPS/cops-3.1.3/styles/cops-monocle.css +++ /dev/null @@ -1,273 +0,0 @@ -body { - margin: 0; - padding: 0; - background: #000; - -webkit-user-select: none; - -webkit-text-size-adjust: none; -} - -#components { - display: none; -} - -#reader, #readerBg { - position: absolute; - width: 100%; - height: 100%; -} - -#reader div pre { - white-space: normal; - font: normal 100% serif; -} - -/* from smallest and outermost to largest and innermost */ -.dummyPage { - position: absolute; - left: 0; - top: 20px; - bottom: 20px; - right: 15px; - background-color: #FCF6F0; - -webkit-box-shadow: 2px 2px 4px #754; - -moz-box-shadow: 2px 2px 4px #754; - box-shadow: 2px 2px 4px #754; - -webkit-border-top-left-radius: 26px 6px; - -webkit-border-bottom-left-radius: 26px 6px; - -moz-border-top-left-radius: 26px 6px; - -moz-border-bottom-left-radius: 26px 6px; - border-top-left-radius: 26px 6px; - border-bottom-left-radius: 26px 6px; -} -.dummyPage + .dummyPage { - top: 16px; - bottom: 16px; - right: 16px; - -webkit-box-shadow: 1px 0 2px #A99; - -moz-box-shadow: 1px 0 2px #A99; - box-shadow: 1px 0 2px #A99; -} -.dummyPage + .dummyPage + .dummyPage { - top: 13px; - bottom: 13px; - right: 18px; - background-color: #FFF9F4; -} -.dummyPage + .dummyPage + .dummyPage + .dummyPage { - top: 10px; - bottom: 10px; - right: 21px; -} -.dummyPage + .dummyPage + .dummyPage + .dummyPage + .dummyPage { - top: 8px; - bottom: 8px; - right: 25px; -} -.jacket { - position: absolute; - top: 1px; - bottom: 1px; - right: 3px; - left: 65%; - -webkit-box-shadow: -3px 0 3px #311; - -moz-box-shadow: -3px 0 3px #311; - box-shadow: -3px 0 3px #311; - -webkit-border-top-right-radius: 3px; - -webkit-border-bottom-right-radius: 3px; - -moz-border-top-right-radius: 3px; - -moz-border-bottom-right-radius: 3px; - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; - background-color: #F7F7F7; - background: -webkit-linear-gradient(0deg, #DDD, #FFF); - background: -moz-linear-gradient(0deg , #DDD, #FFF); - background: linear-gradient(90deg, #DDD, #FFF); -} -.board { - position: absolute; - top: 1px; - bottom: 1px; - width: 90%; - background-color: #974; - border: 1px solid #852; -} - -.runner { - color: #542; - text-transform: uppercase; - font-size: 82%; -} - -.pageNumber, .bookTitle, .chapterTitle { - padding: 3% 2%; -} - -.bookTitle, .chapterTitle { - position: absolute; - top: 1%; - left: 6%; - cursor: pointer; - padding: 0; -} - -.chapterTitle { - top: auto; - bottom: 1%; - right: 20%; -} - -.pageNumber { - position: absolute; - bottom: 1%; - right: 8%; - padding-right: 0; -} - -#readerBg { - background-color: #000; -} - -#toc ul.root { - position: absolute; - top: 50px; - left: 8%; - max-height: 75%; - max-width: 80%; - background: #E0D3C0; - -webkit-box-shadow: 1px 2px 2px #652; - -moz-box-shadow: 1px 2px 2px #652; - -webkit-border-radius: 10px; - -moz-border-radius: 10px; - border-radius: 10px; - overflow-y: auto; - color: #432; - font: 11pt Georgia, serif; - text-shadow: 1px 1px #EEE6D0; - border: 1px solid #EED; - z-index: 9; -} - -.tocArrow { - position: absolute; - top: 40px; - left: 16%; - width: 20px; - height: 20px; - -webkit-transform: rotateZ(45deg); - background: #E0D3C0; - z-index: 8; -} - -#toc li { - list-style: none; - line-height: 220%; - padding-left: 1em; - padding-right: 2em; - border-bottom: 2px groove #FFF6E9; - cursor: pointer; -} - -#toc li span { - display: block; -} - -#toc ul li:last-child { - border-bottom: none; -} - -#toc ul { - margin: 0; - padding: 0; -} -#toc ul.root { - border-top: none; -} - - - -/* Overrides to core elements */ - -div.monelem_container { - background: none; - width: auto; -} - -div.monelem_page { - top: 6px; - bottom: 6px; - right: 4px; - border-color: #CBA; - outline: none; - -webkit-box-shadow: 1px 0 1px #CBA; - -moz-box-shadow: 1px 0 1px #CBA; - box-shadow: 1px 0 2px #CBA; - -webkit-border-top-left-radius: 26px 4px; - -webkit-border-bottom-left-radius: 26px 4px; - -moz-border-top-left-radius: 26px 4px; - -moz-border-bottom-left-radius: 26px 4px; - border-top-left-radius: 26px 4px; - border-bottom-left-radius: 26px 4px; - background-color: #FFFFFE; - background-image: -webkit-linear-gradient(0deg, #EDEAE8 0px, #FFFFFE 24px); - background-image: -moz-linear-gradient(0deg, #EDEAE8 0px, #FFFFFE 24px); - background-image: linear-gradient(90deg, #EDEAE8 0px, #FFFFFE 24px); -} - -div.monelem_sheaf { - left: 6%; - right: 8%; - top: 8%; - bottom: 8%; -} - - -/* Overriding magnifier button display */ - -div.monelem_controls_magnifier_button { - color: #632; - padding: 2%; - top: 1%; - right: 6%; -} - - -/* Overriding table of contents display */ - -div.monelem_controls_contents_container { - background: #E0D3C0; - border: 1px solid #EED; - font: 11pt Georgia, serif; - color: #432; - text-shadow: 1px 1px #FFF6E0; -} - -div.monelem_controls_contents_chapter { - border-bottom: 2px groove #FFF6E9; -} - -li.monelem_controls_contents_chapter_active { - text-shadow: -1px -1px #876; - background: #BA9; -} - - -/* Overriding the scrubber display */ -div.monelem_controls_scrubber_container { - left: 5.5%; - right: 9%; - bottom: 2%; - background: #FFFEFC; -} - -div.monelem_controls_scrubber_track { - border-color: #432; -} - -div.monelem_controls_scrubber_needle { - border-color: #432; - background: #E0D3C0; -} - -div.monelem_controls_scrubber_trail { - background: #E0D3C0; -} diff --git a/COPS/cops-3.1.3/styles/cops-monocle.js b/COPS/cops-3.1.3/styles/cops-monocle.js deleted file mode 100644 index 20af0f9d..00000000 --- a/COPS/cops-3.1.3/styles/cops-monocle.js +++ /dev/null @@ -1,184 +0,0 @@ -/** global: Monocle */ -Monocle.DEBUG = true; - -(function () { - - /** global: Monocle */ - Monocle.Styles.container.right = "24px"; - - // Initialize the reader element. - /** global: Monocle */ - Monocle.Events.listen( - window, - 'load', - function () { - var readerOptions = {}; - - /* PLACE SAVER */ - var bkTitle = bookData.getMetaData('title'); - var placeSaver = new Monocle.Controls.PlaceSaver(bkTitle); - readerOptions.place = placeSaver.savedPlace(); - readerOptions.panels = Monocle.Panels.Marginal; - readerOptions.stylesheet = "body { " + - "color: #210;" + - "font-family: Palatino, Georgia, serif;" + - "}"; - - /* Initialize the reader */ - window.reader = Monocle.Reader( - 'reader', - bookData, - readerOptions, - function(reader) { - reader.addControl(placeSaver, 'invisible'); - - /* SPINNER */ - /** global: Monocle */ - var spinner = Monocle.Controls.Spinner(reader); - reader.addControl(spinner, 'page', { hidden: true }); - spinner.listenForUsualDelays('reader'); - - /* Because the 'reader' element changes size on window resize, - * we should notify it of this event. */ - /** global: Monocle */ - Monocle.Events.listen( - window, - 'resize', - function () { window.reader.resized() } - ); - - /** global: Monocle */ - Monocle.Events.listen(window.top.document, 'keyup', function(evt) { - var eventCharCode = evt.charCode || evt.keyCode; - var dir = null; - var flipper = reader.Flipper; - if (eventCharCode == 33 || eventCharCode == 37) { // Page down or Left arrow - dir = -1; - } else if (eventCharCode == 34 || eventCharCode == 39 ) { // Page down or Right arrow - dir = 1; - } - if (dir) { - reader.moveTo({ direction: dir }); - evt.preventDefault(); - } - }); - - /* MAGNIFIER CONTROL */ - /** global: Monocle */ - var magnifier = new Monocle.Controls.Magnifier(reader); - reader.addControl(magnifier, 'page'); - - /* BOOK TITLE RUNNING HEAD */ - var bookTitle = {} - /** global: Monocle */ - bookTitle.contentsMenu = Monocle.Controls.Contents(reader); - reader.addControl(bookTitle.contentsMenu, 'popover', { hidden: true }); - bookTitle.createControlElements = function () { - var cntr = document.createElement('div'); - cntr.className = "bookTitle"; - var runner = document.createElement('div'); - runner.className = "runner"; - runner.innerHTML = reader.getBook().getMetaData('title'); - cntr.appendChild(runner); - - /** global: Monocle */ - Monocle.Events.listenForContact( - cntr, - { - start: function (evt) { - if (evt.preventDefault) { - evt.stopPropagation(); - evt.preventDefault(); - } else { - evt.returnValue = false; - } - reader.showControl(bookTitle.contentsMenu); - } - } - ); - - return cntr; - } - reader.addControl(bookTitle, 'page'); - - - /* CHAPTER TITLE RUNNING HEAD */ - var chapterTitle = { - runners: [], - createControlElements: function (page) { - var cntr = document.createElement('div'); - cntr.className = "chapterTitle"; - var runner = document.createElement('div'); - runner.className = "runner"; - cntr.appendChild(runner); - this.runners.push(runner); - this.update(page); - return cntr; - }, - update: function (page) { - var place = reader.getPlace(page); - if (place) { - this.runners[page.m.pageIndex].innerHTML = place.chapterTitle(); - } - } - } - reader.addControl(chapterTitle, 'page'); - reader.listen( - 'monocle:pagechange', - function (evt) { chapterTitle.update(evt.m.page); } - ); - - - /* PAGE NUMBER RUNNING HEAD */ - var pageNumber = { - runners: [], - createControlElements: function (page) { - var cntr = document.createElement('div'); - cntr.className = "pageNumber"; - var runner = document.createElement('div'); - runner.className = "runner"; - cntr.appendChild(runner); - this.runners.push(runner); - this.update(page, page.m.place.pageNumber()); - return cntr; - }, - update: function (page, pageNumber) { - if (pageNumber) { - this.runners[page.m.pageIndex].innerHTML = pageNumber; - } - } - } - reader.addControl(pageNumber, 'page'); - reader.listen( - 'monocle:pagechange', - function (evt) { - pageNumber.update(evt.m.page, evt.m.pageNumber); - } - ); - - /* Scrubber */ - /** global: Monocle */ - var scrubber = new Monocle.Controls.Scrubber(reader); - reader.addControl(scrubber, 'popover', { hidden: true }); - var showFn = function (evt) { - evt.stopPropagation(); - reader.showControl(scrubber); - scrubber.updateNeedles(); - } - for (var i = 0; i < chapterTitle.runners.length; ++i) { - /** global: Monocle */ - Monocle.Events.listenForContact( - chapterTitle.runners[i].parentNode, - { start: showFn } - ); - /** global: Monocle */ - Monocle.Events.listenForContact( - pageNumber.runners[i].parentNode, - { start: showFn } - ); - } - } - ); - } - ); -})(); diff --git a/COPS/cops-3.1.3/templates/about.html b/COPS/cops-3.1.3/templates/about.html deleted file mode 100644 index 10da9aaa..00000000 --- a/COPS/cops-3.1.3/templates/about.html +++ /dev/null @@ -1,26 +0,0 @@ -
    -

    About COPS

    -

    This Fork

    -

    See CHANGELOG on Github for details: https://github.com/mikespub-org/seblucas-cops

    - -

    Authors

    -

    COPS is developed and maintained by Sébastien Lucas.

    - -

    See full history on Github to check all authors.

    - -

    COPS use some external libraries, check README for the details.

    -

    Copyright

    -

    This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation.

    - -

    The complete content of license is provided in file COPYING within distribution and also available online.

    -

    Contact

    -

    For more info please visit COPS Home Page

    - -

    You can also check COPS's topic on MobileRead forum.

    - -

    DISCLAIMER : COPS is an open source software free to install everywhere. So if you have questions about any books available with any installation of COPS, please ask the owner of the website and not COPS's maintainer.

    -

    Thanks

    -

    Thanks a lot to Kovid Goyal for Calibre.

    - -

    And many thanks to all those who helped test COPS.

    -
    diff --git a/COPS/cops-3.1.3/templates/bootstrap/bookdetail.html b/COPS/cops-3.1.3/templates/bootstrap/bookdetail.html deleted file mode 100644 index 65dd2fb0..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap/bookdetail.html +++ /dev/null @@ -1,84 +0,0 @@ -
    -
    - {{? it.book.hasCover == 1}} - - {{=it.c.i18n.coverAlt}} - - {{?}} -
    -
    -

    - {{=htmlspecialchars (it.title)}} -

    -

    {{=it.c.i18n.authorsTitle}}: - {{~it.book.authors:author:i}} - {{? i > 0}}, {{?}}{{=htmlspecialchars (author.name)}} - {{~}} -

    - {{? it.book.tagsName != ""}} -

    {{=it.c.i18n.tagsTitle}}: - {{~it.book.tags:tag:i}} - {{? i > 0}}, {{?}}{{=htmlspecialchars (tag.name)}} - {{~}} -

    - {{?}} - {{? it.book.rating != ""}} -

    {{=it.c.i18n.ratingTitle}} : {{=it.book.rating}}

    - {{?}} - {{? it.book.seriesName != ""}} -

    {{=it.c.i18n.seriesTitle}} : {{=htmlspecialchars (it.book.seriesCompleteName)}}

    - {{?}} -
    -
    -
    - {{~it.book.datas:data:i}} - {{=data.format}} - - {{? data.mail == 1}} - - - {{?}} - {{? data.readerUrl != ""}} - - - {{?}} -
    - {{~}} -
    -
    -
    - -
    -
    - {{? it.book.publisherName != ""}} -

    -

    {{=it.c.i18n.publisherName}}:

    {{=htmlspecialchars (it.book.publisherName)}} -

    - {{?}} - {{? it.book.pubDate != ""}} -

    -

    {{=it.c.i18n.pubdateTitle}}:

    {{=it.book.pubDate}} -

    - {{?}} - {{? it.book.languagesName != ""}} -

    -

    {{=it.c.i18n.languagesTitle}}:

    {{=it.book.languagesName}} -

    - {{?}} - {{~it.book.customcolumns_preview :column:column_index}} -

    -

    {{=column.customColumnType.columnTitle}}:

    {{=column.htmlvalue}} -

    - {{~}} - {{? it.book.extraFiles != ""}} -

    -

    {{=it.c.i18n.filesTitle}}:

    {{~it.book.extraFiles:extraFile:i}}{{=htmlspecialchars (extraFile.name)}} {{~}} -

    - {{?}} - {{? it.book.content != ""}} -
    -

    {{=it.c.i18n.contentTitle}}

    -
    {{=it.book.content}}
    - {{?}} -
    -
    diff --git a/COPS/cops-3.1.3/templates/bootstrap/file.html b/COPS/cops-3.1.3/templates/bootstrap/file.html deleted file mode 100644 index c29f7cf5..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap/file.html +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - - - - - - - - - - {{=it.title}} - - - - -{{? it.server_side_rendering == 0}} - - - - -{{?}} - - - - - - - - - - - - - - - - - -{{? it.server_side_rendering == 0}} - -{{?}} - diff --git a/COPS/cops-3.1.3/templates/bootstrap/footer.html b/COPS/cops-3.1.3/templates/bootstrap/footer.html deleted file mode 100644 index e69de29b..00000000 diff --git a/COPS/cops-3.1.3/templates/bootstrap/header.html b/COPS/cops-3.1.3/templates/bootstrap/header.html deleted file mode 100644 index 7d6e3cc8..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap/header.html +++ /dev/null @@ -1,43 +0,0 @@ - diff --git a/COPS/cops-3.1.3/templates/bootstrap/main.html b/COPS/cops-3.1.3/templates/bootstrap/main.html deleted file mode 100644 index 1c9b5744..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap/main.html +++ /dev/null @@ -1,83 +0,0 @@ -
    -{{? it.page == 13 || it.page == 16}} - {{? it.page == 13}} - {{#def.bookdetail}} - {{??}} - {{= it.fullhtml}} - {{?}} -{{??}} -
    -
      -
    -
    -
    -{{~it.entries:entry:i}} - {{? it.containsBook == 0}} -
    -
    - {{? it.page == 19}} -
    - {{=htmlspecialchars (entry.title)}} -
    -
    - {{=entry.content}} -
    - {{??}} - -
    - {{=entry.number}} -
    - {{?}} -
    -
    - {{??}} -
    -
    - -
    -
    - {{? entry.thumbnailurl }} - - {{=it.c.i18n.coverAlt}} - - {{?}} -
    -
    {{=htmlspecialchars (entry.book.authorsName)}}
    - {{? entry.book.tagsName != ""}}
    {{=htmlspecialchars (entry.book.tagsName)}}
    {{?}} - {{? entry.book.seriesName != ""}}
    {{=htmlspecialchars (entry.book.seriesName)}} ({{=entry.book.seriesIndex}})
    {{?}} - {{~entry.book.customcolumns_list :column:column_index}} -
    {{=column.customColumnType.columnTitle}} : {{=column.htmlvalue}}
    - {{~}} - {{~entry.book.preferedData:data:j}} -
    - {{~}} -
    - {{~entry.book.preferedData:data:j}} -

    - {{=data.name}} - -

    - {{~}} -
    -
    -
    -
    - {{?}} -{{~}} -
    -{{?}} -{{? it.isPaginated == 1}} - -{{?}} -
    -
    diff --git a/COPS/cops-3.1.3/templates/bootstrap/page.html b/COPS/cops-3.1.3/templates/bootstrap/page.html deleted file mode 100644 index 88139c88..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap/page.html +++ /dev/null @@ -1,3 +0,0 @@ -{{#def.header}} -{{#def.main}} -{{#def.footer}} diff --git a/COPS/cops-3.1.3/templates/bootstrap/scripts/cops.js b/COPS/cops-3.1.3/templates/bootstrap/scripts/cops.js deleted file mode 100644 index 3383895c..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap/scripts/cops.js +++ /dev/null @@ -1,4 +0,0 @@ -function postRefresh() -{ - $('[data-toggle="tooltip"]').tooltip(); -} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/bootstrap/styles/style-base.css b/COPS/cops-3.1.3/templates/bootstrap/styles/style-base.css deleted file mode 100644 index 4823668e..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap/styles/style-base.css +++ /dev/null @@ -1,3 +0,0 @@ -.panel-body { padding: 5px; } - -.bottomright {position:absolute; bottom:0; margin-bottom:25px; right: 20px;} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/bootstrap/styles/style-default.css b/COPS/cops-3.1.3/templates/bootstrap/styles/style-default.css deleted file mode 100644 index 4823668e..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap/styles/style-default.css +++ /dev/null @@ -1,3 +0,0 @@ -.panel-body { padding: 5px; } - -.bottomright {position:absolute; bottom:0; margin-bottom:25px; right: 20px;} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/bootstrap/suggestion.html b/COPS/cops-3.1.3/templates/bootstrap/suggestion.html deleted file mode 100644 index 1107dade..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap/suggestion.html +++ /dev/null @@ -1 +0,0 @@ -

    {{=it.title}}

    \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/bootstrap2/bookdetail.html b/COPS/cops-3.1.3/templates/bootstrap2/bookdetail.html deleted file mode 100644 index db857422..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap2/bookdetail.html +++ /dev/null @@ -1,101 +0,0 @@ -
    -
    -
    - {{? it.book.hasCover == 1}} -
    - - {{=it.c.i18n.coverAlt}} - - {{?}} -
    -
    - -
    - {{~it.book.datas:data:i}} -
    - {{=data.format}} - {{? data.mail == 1}} - - - {{?}} - {{? data.readerUrl != ""}} - - - {{?}} -
    - {{~}} -
    - - -
    -

    {{=htmlspecialchars (it.title)}}

    -

    {{~it.book.authors:author:i}}{{? i > 0}}, {{?}}{{=htmlspecialchars (author.name)}}{{~}}

    - {{? it.book.seriesName != ""}} -

    {{=htmlspecialchars (it.book.seriesName)}} ({{=it.book.seriesIndex}})

    - {{?}} -
    - - -
    - - {{? it.book.languagesName != ""}} -

    - {{=it.c.i18n.languagesTitle}}: {{=it.book.languagesName}} -

    - {{?}} - - {{? it.book.identifiers != ""}} -
    -

    - - {{~it.book.identifiers:id:i}}{{=htmlspecialchars (id.name)}} {{~}} -

    -
    - {{?}} - - {{? it.book.tagsName != ""}} -
    - - {{~it.book.tags:tag:i}}{{=htmlspecialchars (tag.name)}} {{~}} -
    - {{?}} - - {{? it.book.rating != ""}} -

    -

    {{=it.c.i18n.ratingTitle}}: {{=it.book.rating}}

    -

    - {{?}} - {{? it.book.publisherName != ""}} -

    -

    {{=it.c.i18n.publisherName}}: {{=htmlspecialchars (it.book.publisherName)}}

    -

    - {{?}} - {{? it.book.pubDate != ""}} -

    -

    {{=it.c.i18n.pubdateTitle}}: {{=it.book.pubDate}}

    -

    - {{?}} - {{~it.book.customcolumns_preview :column:column_index}} -

    -

    {{=column.customColumnType.columnTitle}}: {{=column.htmlvalue}}

    -

    - {{~}} - {{? it.book.extraFiles != ""}} -

    -

    {{=it.c.i18n.filesTitle}}: {{~it.book.extraFiles:extraFile:i}}{{=htmlspecialchars (extraFile.name)}} {{~}}

    -

    - {{?}} - -
    - -
    - -
    -
    - {{? it.book.content != ""}} -
    -

    {{=it.c.i18n.contentTitle}}

    -
    {{=it.book.content}}
    - {{?}} -
    -
    diff --git a/COPS/cops-3.1.3/templates/bootstrap2/file.html b/COPS/cops-3.1.3/templates/bootstrap2/file.html deleted file mode 100644 index b46e51d4..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap2/file.html +++ /dev/null @@ -1,211 +0,0 @@ - - - - - - - - - - - - - - - {{=it.title}} - - - - -{{? it.server_side_rendering == 0}} - - - - -{{?}} - - - - - - - - - - - - - - - - - - -{{? it.server_side_rendering == 0}} - -{{?}} - diff --git a/COPS/cops-3.1.3/templates/bootstrap2/footer.html b/COPS/cops-3.1.3/templates/bootstrap2/footer.html deleted file mode 100644 index e69de29b..00000000 diff --git a/COPS/cops-3.1.3/templates/bootstrap2/header.html b/COPS/cops-3.1.3/templates/bootstrap2/header.html deleted file mode 100644 index 318ce00a..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap2/header.html +++ /dev/null @@ -1,103 +0,0 @@ - diff --git a/COPS/cops-3.1.3/templates/bootstrap2/main.html b/COPS/cops-3.1.3/templates/bootstrap2/main.html deleted file mode 100644 index 29b4b9fc..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap2/main.html +++ /dev/null @@ -1,176 +0,0 @@ -
    -{{? it.page == 13 || it.page == 16}} - {{? it.page == 13}} - {{#def.bookdetail}} - {{??}} - {{= it.fullhtml}} - {{?}} -{{??}} -
    - - {{? it.filters}} - - {{?}} -
    - -{{? it.containsBook == 0}} -
    -
    - {{~it.entries:entry:idx}} -
    -
    - {{? it.page == 19}} -
    - {{=htmlspecialchars (entry.title)}} -
    -
    - {{=entry.content}} -
    - {{??}} - {{? entry.class == "" && entry.number == ""}} - - - {{??}} - -
    - {{=htmlspecialchars (entry.title)}} - {{=entry.number}} -
    -
    - {{?}} - {{?}} -
    -
    - {{~}} -
    -
    -{{??}} -
    - {{~it.entries:entry:idx}} -
    -
    - {{? entry.thumbnailurl }} - - {{=it.c.i18n.coverAlt}} - - {{?}} -
    -
    -

    {{=htmlspecialchars (entry.title)}}

    -
    {{=htmlspecialchars (entry.book.authorsName)}}
    - {{? entry.book.seriesName != ""}}
    {{=htmlspecialchars (entry.book.seriesName)}} ({{=entry.book.seriesIndex}})
    {{?}} - - {{~entry.book.customcolumns_list :column:column_index}} -
    {{=column.customColumnType.columnTitle}} : {{=column.htmlvalue}}
    - {{~}} -
    -
    -
    - - {{? entry.book.preferedCount > 1}}
    {{?}} - {{~entry.book.preferedData:data:i}} - {{? i == 0}} - {{=data.name}} - {{? entry.book.preferedCount > 1}} - - {{? entry.book.preferedCount > 1}}{{?}} - {{?}} - {{~}} - {{? entry.book.preferedCount > 1}}
    {{?}} -
    -
    - {{~}} -
    -{{?}} -{{?}} -{{? it.isPaginated == 1}} - -{{?}} -
    -
    -{{? it.extra }} -{{? it.extra.series }} -
    -
    -
    -
    -
    - {{=it.c.i18n.seriesTitle}} -
    -
    -
      - {{~it.extra.series:series:idx}} -
    • {{=series.title}} ({{=series.number}})
    • - {{~}} -
    -
    -
    -
    -
    -
    -{{?}} -{{? it.extra.title }} -
    -
    -
    -
    -
    - {{=it.extra.title}} -
    -
    - {{? it.extra.link }} -

    {{=it.c.i18n.linkTitle}}: {{=it.extra.link}}

    - {{?}} - {{? it.extra.content }} - {{=it.extra.content}} - {{?}} -
    -
    -
    -
    -
    -{{?}} -{{?}} diff --git a/COPS/cops-3.1.3/templates/bootstrap2/page.html b/COPS/cops-3.1.3/templates/bootstrap2/page.html deleted file mode 100644 index 88139c88..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap2/page.html +++ /dev/null @@ -1,3 +0,0 @@ -{{#def.header}} -{{#def.main}} -{{#def.footer}} diff --git a/COPS/cops-3.1.3/templates/bootstrap2/scripts/cops.js b/COPS/cops-3.1.3/templates/bootstrap2/scripts/cops.js deleted file mode 100644 index 2647a549..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap2/scripts/cops.js +++ /dev/null @@ -1,7 +0,0 @@ -function postRefresh() -{ - $('[data-toggle="tooltip"]').tooltip(); - hash = window.location.hash.replace("#", ""); - var elmnt = document.getElementById(hash); - if (elmnt) elmnt.scrollIntoView(); -} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/bootstrap2/styles/style-base.css b/COPS/cops-3.1.3/templates/bootstrap2/styles/style-base.css deleted file mode 100644 index 4823668e..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap2/styles/style-base.css +++ /dev/null @@ -1,3 +0,0 @@ -.panel-body { padding: 5px; } - -.bottomright {position:absolute; bottom:0; margin-bottom:25px; right: 20px;} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/bootstrap2/styles/style-default.css b/COPS/cops-3.1.3/templates/bootstrap2/styles/style-default.css deleted file mode 100644 index 4823668e..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap2/styles/style-default.css +++ /dev/null @@ -1,3 +0,0 @@ -.panel-body { padding: 5px; } - -.bottomright {position:absolute; bottom:0; margin-bottom:25px; right: 20px;} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/bootstrap2/styles/style-kindle.css b/COPS/cops-3.1.3/templates/bootstrap2/styles/style-kindle.css deleted file mode 100644 index 76e60a3a..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap2/styles/style-kindle.css +++ /dev/null @@ -1,139 +0,0 @@ -/* Override fonts, sizes and colours for Kindle eInk readers */ - -body { - font-family: "Amazon Ember", Helvetica, Futura, Caecilia, Georgia, Palatino, sans-serif; - font-size: 25px; - background-color: white; -} - -.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { - color:black; -} - -a, a:hover { - color:black; - text-decoration: underline; -} - -.navbar-static-top { - padding-top: 5px; - padding-left:15px; -} - -.navbar-brand { - font-size: 2em; - line-height: 1.2em; - margin-bottom: 10px; - float:none; - font-weight: bold; - padding: 0px; -} - -.navbar > div { - background-color: white; - border-bottom: solid 1px black; - color: black; -} - -.navbar-inverse .navbar-brand, .navbar-inverse .navbar-nav>li>a, span.glyphicon.glyphicon-tags { - color: black; -} - -.navbar-inverse, .container-fluid { - background-color: white; - border:none; -} - -.panel-default>.panel-heading { - color: black; - background-color: transparent; - font-weight: bold; -} - -.panel-body{ - font-weight: normal; - color: black; -} - -.panel-body label { - font-weight: normal; -} - -/* Navbar collapse button */ -.navbar-inverse .navbar-toggle:focus, .navbar-inverse .navbar-toggle:hover { - background-color: black; - color:white; -} - -.navbar-toggle { - height: 50px; - width: 50px; - padding: 12px 6px; -} -.navbar-toggle .icon-bar { - width: 80%; - margin: auto; -} - -.navbar-inverse .navbar-nav>li>a:focus, .navbar-inverse .navbar-nav>li>a:hover, .navbar-inverse .navbar-brand:focus, .navbar-inverse .navbar-brand:hover { - color:black; - background-color: transparent; - text-decoration: underline; -} - -.navbar-inverse .navbar-form { - border: none; -} - -.meta .title { - font-size: 1.8em; -} - -.meta .author { - font-size: 1.5em; - font-weight: bold; -} - -.btn-sm { - font-size: 0.6em; -} - -.form-control { - font-size: 1.1em; - line-height: 1.2em; -} - -input[type="checkbox"], input[type="radio"] { - height: 25px; - width: 25px; - margin-right: 5px; -} - -input#email, input#max_item_per_page, select#style, select#template { /* prevents overlap */ - width: 100%; -} - -.btn-success,.btn-success:hover, .btn-info,.btn-info:hover, .btn-primary, .btn-primary:hover, .navbar-toggle { - background-color: black; - border-color: black; - text-decoration: none; -} - -#queryInput.form-control, #searchButton { - height: 45px; -} - -#searchButton { - width: 50px; - padding-left:16px; - padding-top: 10px; - font-size: 18px; -} - -.book-meta-label, .book-title, .book-author { - font-weight: bold; -} - -.badge, .label-default { - background-color: black; -} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/bootstrap2/styles/typeahead.css b/COPS/cops-3.1.3/templates/bootstrap2/styles/typeahead.css deleted file mode 100644 index 23ccbc10..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap2/styles/typeahead.css +++ /dev/null @@ -1,200 +0,0 @@ -/* - * typehead.js-bootstrap3.less - * @version 0.2.3 - * https://github.com/hyspace/typeahead.js-bootstrap3.less - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ -.has-warning .twitter-typeahead .tt-input, -.has-warning .twitter-typeahead .tt-hint { - border-color: #8a6d3b; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.has-warning .twitter-typeahead .tt-input:focus, -.has-warning .twitter-typeahead .tt-hint:focus { - border-color: #66512c; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; -} -.has-error .twitter-typeahead .tt-input, -.has-error .twitter-typeahead .tt-hint { - border-color: #a94442; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.has-error .twitter-typeahead .tt-input:focus, -.has-error .twitter-typeahead .tt-hint:focus { - border-color: #843534; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; -} -.has-success .twitter-typeahead .tt-input, -.has-success .twitter-typeahead .tt-hint { - border-color: #3c763d; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.has-success .twitter-typeahead .tt-input:focus, -.has-success .twitter-typeahead .tt-hint:focus { - border-color: #2b542c; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; -} -.input-group .twitter-typeahead:first-child .tt-input, -.input-group .twitter-typeahead:first-child .tt-hint { - border-bottom-left-radius: 4px; - border-top-left-radius: 4px; - width: 100%; -} -.input-group .twitter-typeahead:last-child .tt-input, -.input-group .twitter-typeahead:last-child .tt-hint { - border-bottom-right-radius: 4px; - border-top-right-radius: 4px; - width: 100%; -} -.input-group.input-group-sm .twitter-typeahead .tt-input, -.input-group.input-group-sm .twitter-typeahead .tt-hint { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} -select.input-group.input-group-sm .twitter-typeahead .tt-input, -select.input-group.input-group-sm .twitter-typeahead .tt-hint { - height: 30px; - line-height: 30px; -} -textarea.input-group.input-group-sm .twitter-typeahead .tt-input, -textarea.input-group.input-group-sm .twitter-typeahead .tt-hint, -select[multiple].input-group.input-group-sm .twitter-typeahead .tt-input, -select[multiple].input-group.input-group-sm .twitter-typeahead .tt-hint { - height: auto; -} -.input-group.input-group-sm .twitter-typeahead:not(:first-child):not(:last-child) .tt-input, -.input-group.input-group-sm .twitter-typeahead:not(:first-child):not(:last-child) .tt-hint { - border-radius: 0; -} -.input-group.input-group-sm .twitter-typeahead:first-child .tt-input, -.input-group.input-group-sm .twitter-typeahead:first-child .tt-hint { - border-bottom-left-radius: 3px; - border-top-left-radius: 3px; - border-bottom-right-radius: 0; - border-top-right-radius: 0; -} -.input-group.input-group-sm .twitter-typeahead:last-child .tt-input, -.input-group.input-group-sm .twitter-typeahead:last-child .tt-hint { - border-bottom-left-radius: 0; - border-top-left-radius: 0; - border-bottom-right-radius: 3px; - border-top-right-radius: 3px; -} -.input-group.input-group-lg .twitter-typeahead .tt-input, -.input-group.input-group-lg .twitter-typeahead .tt-hint { - height: 46px; - padding: 10px 16px; - font-size: 18px; - line-height: 1.33; - border-radius: 6px; -} -select.input-group.input-group-lg .twitter-typeahead .tt-input, -select.input-group.input-group-lg .twitter-typeahead .tt-hint { - height: 46px; - line-height: 46px; -} -textarea.input-group.input-group-lg .twitter-typeahead .tt-input, -textarea.input-group.input-group-lg .twitter-typeahead .tt-hint, -select[multiple].input-group.input-group-lg .twitter-typeahead .tt-input, -select[multiple].input-group.input-group-lg .twitter-typeahead .tt-hint { - height: auto; -} -.input-group.input-group-lg .twitter-typeahead:not(:first-child):not(:last-child) .tt-input, -.input-group.input-group-lg .twitter-typeahead:not(:first-child):not(:last-child) .tt-hint { - border-radius: 0; -} -.input-group.input-group-lg .twitter-typeahead:first-child .tt-input, -.input-group.input-group-lg .twitter-typeahead:first-child .tt-hint { - border-bottom-left-radius: 6px; - border-top-left-radius: 6px; - border-bottom-right-radius: 0; - border-top-right-radius: 0; -} -.input-group.input-group-lg .twitter-typeahead:last-child .tt-input, -.input-group.input-group-lg .twitter-typeahead:last-child .tt-hint { - border-bottom-left-radius: 0; - border-top-left-radius: 0; - border-bottom-right-radius: 6px; - border-top-right-radius: 6px; -} -.twitter-typeahead { - width: 100%; - float: left; -} -.input-group .twitter-typeahead { - display: table-cell !important; -} -.twitter-typeahead .tt-hint { - color: #999999; -} -.twitter-typeahead .tt-input { - z-index: 2; -} -.twitter-typeahead .tt-input[disabled], -.twitter-typeahead .tt-input[readonly], -fieldset[disabled] .twitter-typeahead .tt-input { - cursor: not-allowed; - background-color: #eeeeee !important; -} -.tt-dropdown-menu, -.tt-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - min-width: 160px; - width: 100%; - padding: 5px 0; - margin: 2px 0 0; - list-style: none; - font-size: 14px; - background-color: #ffffff; - border: 1px solid #cccccc; - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 4px; - -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - background-clip: padding-box; - *border-right-width: 2px; - *border-bottom-width: 2px; -} -.tt-dropdown-menu .tt-suggestion, -.tt-menu .tt-suggestion { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: 1.42857143; - color: #333333; -} -.tt-dropdown-menu .tt-suggestion.tt-cursor, -.tt-menu .tt-suggestion.tt-cursor, -.tt-dropdown-menu .tt-suggestion:hover, -.tt-menu .tt-suggestion:hover { - cursor: pointer; - text-decoration: none; - outline: 0; - background-color: #f5f5f5; - color: #262626; -} -.tt-dropdown-menu .tt-suggestion.tt-cursor a, -.tt-menu .tt-suggestion.tt-cursor a, -.tt-dropdown-menu .tt-suggestion:hover a, -.tt-menu .tt-suggestion:hover a { - color: #262626; -} -.tt-dropdown-menu .tt-suggestion p, -.tt-menu .tt-suggestion p { - margin: 0; -} diff --git a/COPS/cops-3.1.3/templates/bootstrap2/suggestion.html b/COPS/cops-3.1.3/templates/bootstrap2/suggestion.html deleted file mode 100644 index 1107dade..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap2/suggestion.html +++ /dev/null @@ -1 +0,0 @@ -

    {{=it.title}}

    \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/bootstrap5/bookdetail.html b/COPS/cops-3.1.3/templates/bootstrap5/bookdetail.html deleted file mode 100644 index 7debae79..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap5/bookdetail.html +++ /dev/null @@ -1,65 +0,0 @@ -
    -
    -
    - {{? it.book.hasCover == 1}} - {{=it.c.i18n.coverAlt}} - {{?}} -
    -
    -

    {{=htmlspecialchars (it.title)}}

    -

    {{~it.book.authors:author:i}}{{? i > 0}}, {{?}}{{=htmlspecialchars (author.name)}}{{~}}

    - {{? it.book.pubDate != ""}} -

    {{=it.c.i18n.pubdateTitle}}: {{=it.book.pubDate}}

    - {{?}} - {{? it.book.rating != ""}} -

    {{= it.book.rating }}

    - {{?}} - {{? it.book.seriesName != ""}} -

    {{=htmlspecialchars (it.book.seriesName)}} ({{=it.book.seriesIndex}})

    - {{?}} - {{~it.book.datas:data:i}} -
    - {{=data.format}} - {{? data.mail == 1}} - - - {{?}} - {{? data.readerUrl != ""}} - - - {{?}} -
    - {{~}} - {{? it.book.content != ""}} -

    {{=it.c.i18n.contentTitle}}

    -
    {{=it.book.content}}
    - {{?}} - {{? it.book.publisherName != ""}} -

    {{=it.c.i18n.publisherName}}: {{=htmlspecialchars (it.book.publisherName)}}

    - {{?}} - {{? it.book.languagesName != ""}} -

    {{=it.c.i18n.languageTitle}}: {{=it.book.languagesName}}

    - {{?}} - {{? it.book.tagsName != ""}} -
    - {{~it.book.tags:tag:i}} - {{=htmlspecialchars (tag.name)}} - {{~}} -
    - {{?}} - {{? it.book.identifiers != ""}} -
    - {{~it.book.identifiers:id:i}} - {{=htmlspecialchars (id.name)}} - {{~}} -
    - {{?}} - {{~it.book.customcolumns_preview :column:column_index}} -

    {{=column.customColumnType.columnTitle}}: {{=column.htmlvalue}}

    - {{~}} - {{? it.book.extraFiles != ""}} -

    {{=it.c.i18n.filesTitle}}: {{~it.book.extraFiles:extraFile:i}}{{=htmlspecialchars (extraFile.name)}} {{~}}

    - {{?}} -
    -
    -
    \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/bootstrap5/file.html b/COPS/cops-3.1.3/templates/bootstrap5/file.html deleted file mode 100644 index c998014a..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap5/file.html +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - - - - - - - {{=it.title}} - - - - - {{? it.server_side_rendering == 0}} - - - - - {{?}} - - - - - - - - - - - - - - - {{? it.server_side_rendering == 0}} - - {{?}} - - diff --git a/COPS/cops-3.1.3/templates/bootstrap5/footer.html b/COPS/cops-3.1.3/templates/bootstrap5/footer.html deleted file mode 100644 index 08db24be..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap5/footer.html +++ /dev/null @@ -1,19 +0,0 @@ - \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/bootstrap5/header.html b/COPS/cops-3.1.3/templates/bootstrap5/header.html deleted file mode 100644 index 52c1ea66..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap5/header.html +++ /dev/null @@ -1,149 +0,0 @@ -
    - - {{? it.containsBook != 0 || it.filters || it.isFilterPage }} - - {{?}} -
    \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/bootstrap5/main.html b/COPS/cops-3.1.3/templates/bootstrap5/main.html deleted file mode 100644 index addf3ba4..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap5/main.html +++ /dev/null @@ -1,112 +0,0 @@ -
    -{{? it.page == 13 || it.page == 16}} - {{? it.page == 13}} - {{#def.bookdetail}} - {{??}} - {{= it.fullhtml}} - {{?}} -{{??}} - -{{? it.containsBook == 0}} - -
    - {{~it.entries:entry:i}} -
    -
    - {{? it.page == 19}} -
    - {{=htmlspecialchars (entry.title)}} -
    -

    - {{=entry.content}} -

    - {{??}} - - {{=htmlspecialchars (entry.title)}}  - {{=entry.number}} - {{?}} -
    -
    - {{~}} -
    - -{{??}} -
    - {{~it.entries:entry:idx}} -
    -
    - {{? entry.book.hasCover == 1}} - - {{=it.c.i18n.coverAlt}} - - {{?}} -
    -
    -
    {{=htmlspecialchars (entry.title)}}
    -
    - {{~ entry.book.authors:author:i}}{{? i != 0 }}, {{?}}{{=htmlspecialchars (author.name)}}{{~}} -
    - {{? entry.book.seriesName != ""}} -
    {{=htmlspecialchars (entry.book.seriesName)}} ({{=entry.book.seriesIndex}})
    - {{?}} - {{? entry.book.pubDate != "" && it.sortoptions.pubdate }} -
    {{=it.c.i18n.pubdateTitle}}: {{= entry.book.pubDate }}
    - {{?}} - {{? entry.book.rating != "" && it.sortoptions.rating }} -
    {{= entry.book.rating }}
    - {{?}} - - {{~ entry.book.customcolumns_list:column:column_index}} -
    {{=column.customColumnType.columnTitle}} : {{=column.htmlvalue}}
    - {{~}} -
    - -
    - {{~}} -
    -{{?}} -{{?}} -{{? it.isPaginated == 1}} - -{{?}} -{{? it.extra }} - {{? it.extra.series }} -
    -
    {{=it.c.i18n.seriesTitle}}
    -
    -
      - {{~it.extra.series:series:idx}} -
    • {{=series.title}} ({{=series.number}})
    • - {{~}} -
    -
    -
    - {{?}} - {{? it.extra.title }} -
    -
    {{=it.extra.title}}
    -
    - {{? it.extra.link }} -

    {{=it.c.i18n.linkTitle}}: {{=it.extra.link}}

    - {{?}} - {{? it.extra.content }} - {{=it.extra.content}} - {{?}} -
    -
    - {{?}} - -{{?}} -
    -
    diff --git a/COPS/cops-3.1.3/templates/bootstrap5/page.html b/COPS/cops-3.1.3/templates/bootstrap5/page.html deleted file mode 100644 index f7b6836f..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap5/page.html +++ /dev/null @@ -1,4 +0,0 @@ -{{#def.header}} - -{{#def.footer}} -{{#def.main}} diff --git a/COPS/cops-3.1.3/templates/bootstrap5/scripts/cops.js b/COPS/cops-3.1.3/templates/bootstrap5/scripts/cops.js deleted file mode 100644 index 9b013488..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap5/scripts/cops.js +++ /dev/null @@ -1,16 +0,0 @@ -function postRefresh() -{ - const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]'); - const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl)); - hash = window.location.hash.replace("#", ""); - var elmnt = document.getElementById(hash); - if (elmnt) elmnt.scrollIntoView(); - $(".tt-hint").attr("name","searchTypeahead"); - - /* Add submenu class to body to give extra spacing */ - if ($("#controls-menu").length > 0) { - document.body.classList.add("submenu"); - } else { - if (document.body.classList.contains("submenu")) document.body.classList.remove("submenu"); - } -} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/bootstrap5/styles/bootstrap5.css b/COPS/cops-3.1.3/templates/bootstrap5/styles/bootstrap5.css deleted file mode 100644 index f684972c..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap5/styles/bootstrap5.css +++ /dev/null @@ -1,172 +0,0 @@ -.demo{ - margin-bottom: -99999px; - padding-bottom: 99999px; - border:1px solid #efefef; -} - -.panel-body { padding: 5px 10px; } - -.bottom {position:absolute; bottom:15px; } - -.ellipsis { - overflow: hidden; text-overflow: ellipsis; white-space: nowrap; - display:block; -} - -.cover-image { text-align: center; margin-bottom: 10px;} - -.cover-image img { - max-width:100%; - max-height:100%; - color: white; - border: 1px solid #fff; - -webkit-box-shadow: 0 5px 8px -6px #777; - -moz-box-shadow: 0 5px 8px -6px #777; - box-shadow: 0 5px 8px -6px #777; -} - -.topspace { margin-top: 3px; } - -body { - background-color: #f2f2f2; - padding: 50px 0 38px 0; /* Needed with fixed header and footer */ -} - -body.submenu { - padding: 85px 0 38px 0; /* Increased padding when submenu present */ -} - -html { - scroll-padding-top: 85px; /* Better solution for fixed header */ -} - -.meta { - font-size: 12px; -} - -.meta p { - margin: 0; -} - -.meta .title { - font-weight: bold; - font-size: 15px; -} - -span.glyphicon { - padding-right: 5px; - vertical-align: text-top; -} - -span.glyphicon.glyphicon-tags { - color: #999; -} - -div.tags {margin-bottom: -5px} -div.tags a {margin-bottom: 5px} - -/* -* Responsive text aligning -* http://ohryan.ca/2014/08/14/set-responsive-text-alignment-bootstrap-3/ -*/ -.text-xs-left { text-align: left; } -.text-xs-right { text-align: right; } -.text-xs-center { text-align: center; } -.text-xs-justify { text-align: justify; } - -@media (min-width: 768px) { -.text-sm-left { text-align: left; } -.text-sm-right { text-align: right; } -.text-sm-center { text-align: center; } -.text-sm-justify { text-align: justify; } -} - -.d-flex { - display: flex; -} - -.row.d-flex { - flex-wrap: wrap; -} - -.row.d-flex > [class*='col-'] { - flex-direction: column; -} - -.panel { margin-bottom: 5px; } - -div[class*="books"] { - padding: 7px 7px; -} - -.col-half-padding { - padding: 0px 7px; -} - -.tt-dropdown-menu { - width: 322px; - text-align: left; - margin-top: 6px; - /*color: #000066;*/ - padding: 4px 0; - background-color: #fff; - border: 1px solid #DDD; -} - -.tt-header { - border-bottom: 1px solid #DDD; - font-weight: bold; -} - -.tt-suggestion { - padding: 3px 20px; - line-height: 14px; -} - -.tt-suggestion.tt-cursor { - /*color: #1c1c1c;*/ - background-color: #EEE; -} - -.tt-suggestion p { - margin: 0; -} - -.filtered { display: none; } - -#filter ul { - margin: 0; - padding: 0; - list-style-type: none; - text-align: left; - text-transform:none; -} - -#filter ul li { - cursor: pointer; -} - -#filter li { - display: inline-block; - padding: .2em 1em; - border: 2px solid #DDDDDD; - margin: 2px; - color: black; - background-color: white; - opacity: 0.5; -} - -#filter li.filter-include { - border-left:thick solid blue; - opacity: 1; -} - -#filter li.filter-exclude { - border-right:thick solid red; - opacity: 1; -} - -.nav-pills .nav-link.active, .nav-pills .show>.nav-link { - color: rgb(255, 255, 255); - background-color: rgb(108, 117, 125); -} diff --git a/COPS/cops-3.1.3/templates/bootstrap5/styles/style-base.css b/COPS/cops-3.1.3/templates/bootstrap5/styles/style-base.css deleted file mode 100644 index 4823668e..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap5/styles/style-base.css +++ /dev/null @@ -1,3 +0,0 @@ -.panel-body { padding: 5px; } - -.bottomright {position:absolute; bottom:0; margin-bottom:25px; right: 20px;} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/bootstrap5/styles/style-default.css b/COPS/cops-3.1.3/templates/bootstrap5/styles/style-default.css deleted file mode 100644 index 4823668e..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap5/styles/style-default.css +++ /dev/null @@ -1,3 +0,0 @@ -.panel-body { padding: 5px; } - -.bottomright {position:absolute; bottom:0; margin-bottom:25px; right: 20px;} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/bootstrap5/styles/typeahead.css b/COPS/cops-3.1.3/templates/bootstrap5/styles/typeahead.css deleted file mode 100644 index 23ccbc10..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap5/styles/typeahead.css +++ /dev/null @@ -1,200 +0,0 @@ -/* - * typehead.js-bootstrap3.less - * @version 0.2.3 - * https://github.com/hyspace/typeahead.js-bootstrap3.less - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ -.has-warning .twitter-typeahead .tt-input, -.has-warning .twitter-typeahead .tt-hint { - border-color: #8a6d3b; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.has-warning .twitter-typeahead .tt-input:focus, -.has-warning .twitter-typeahead .tt-hint:focus { - border-color: #66512c; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; -} -.has-error .twitter-typeahead .tt-input, -.has-error .twitter-typeahead .tt-hint { - border-color: #a94442; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.has-error .twitter-typeahead .tt-input:focus, -.has-error .twitter-typeahead .tt-hint:focus { - border-color: #843534; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; -} -.has-success .twitter-typeahead .tt-input, -.has-success .twitter-typeahead .tt-hint { - border-color: #3c763d; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.has-success .twitter-typeahead .tt-input:focus, -.has-success .twitter-typeahead .tt-hint:focus { - border-color: #2b542c; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; -} -.input-group .twitter-typeahead:first-child .tt-input, -.input-group .twitter-typeahead:first-child .tt-hint { - border-bottom-left-radius: 4px; - border-top-left-radius: 4px; - width: 100%; -} -.input-group .twitter-typeahead:last-child .tt-input, -.input-group .twitter-typeahead:last-child .tt-hint { - border-bottom-right-radius: 4px; - border-top-right-radius: 4px; - width: 100%; -} -.input-group.input-group-sm .twitter-typeahead .tt-input, -.input-group.input-group-sm .twitter-typeahead .tt-hint { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} -select.input-group.input-group-sm .twitter-typeahead .tt-input, -select.input-group.input-group-sm .twitter-typeahead .tt-hint { - height: 30px; - line-height: 30px; -} -textarea.input-group.input-group-sm .twitter-typeahead .tt-input, -textarea.input-group.input-group-sm .twitter-typeahead .tt-hint, -select[multiple].input-group.input-group-sm .twitter-typeahead .tt-input, -select[multiple].input-group.input-group-sm .twitter-typeahead .tt-hint { - height: auto; -} -.input-group.input-group-sm .twitter-typeahead:not(:first-child):not(:last-child) .tt-input, -.input-group.input-group-sm .twitter-typeahead:not(:first-child):not(:last-child) .tt-hint { - border-radius: 0; -} -.input-group.input-group-sm .twitter-typeahead:first-child .tt-input, -.input-group.input-group-sm .twitter-typeahead:first-child .tt-hint { - border-bottom-left-radius: 3px; - border-top-left-radius: 3px; - border-bottom-right-radius: 0; - border-top-right-radius: 0; -} -.input-group.input-group-sm .twitter-typeahead:last-child .tt-input, -.input-group.input-group-sm .twitter-typeahead:last-child .tt-hint { - border-bottom-left-radius: 0; - border-top-left-radius: 0; - border-bottom-right-radius: 3px; - border-top-right-radius: 3px; -} -.input-group.input-group-lg .twitter-typeahead .tt-input, -.input-group.input-group-lg .twitter-typeahead .tt-hint { - height: 46px; - padding: 10px 16px; - font-size: 18px; - line-height: 1.33; - border-radius: 6px; -} -select.input-group.input-group-lg .twitter-typeahead .tt-input, -select.input-group.input-group-lg .twitter-typeahead .tt-hint { - height: 46px; - line-height: 46px; -} -textarea.input-group.input-group-lg .twitter-typeahead .tt-input, -textarea.input-group.input-group-lg .twitter-typeahead .tt-hint, -select[multiple].input-group.input-group-lg .twitter-typeahead .tt-input, -select[multiple].input-group.input-group-lg .twitter-typeahead .tt-hint { - height: auto; -} -.input-group.input-group-lg .twitter-typeahead:not(:first-child):not(:last-child) .tt-input, -.input-group.input-group-lg .twitter-typeahead:not(:first-child):not(:last-child) .tt-hint { - border-radius: 0; -} -.input-group.input-group-lg .twitter-typeahead:first-child .tt-input, -.input-group.input-group-lg .twitter-typeahead:first-child .tt-hint { - border-bottom-left-radius: 6px; - border-top-left-radius: 6px; - border-bottom-right-radius: 0; - border-top-right-radius: 0; -} -.input-group.input-group-lg .twitter-typeahead:last-child .tt-input, -.input-group.input-group-lg .twitter-typeahead:last-child .tt-hint { - border-bottom-left-radius: 0; - border-top-left-radius: 0; - border-bottom-right-radius: 6px; - border-top-right-radius: 6px; -} -.twitter-typeahead { - width: 100%; - float: left; -} -.input-group .twitter-typeahead { - display: table-cell !important; -} -.twitter-typeahead .tt-hint { - color: #999999; -} -.twitter-typeahead .tt-input { - z-index: 2; -} -.twitter-typeahead .tt-input[disabled], -.twitter-typeahead .tt-input[readonly], -fieldset[disabled] .twitter-typeahead .tt-input { - cursor: not-allowed; - background-color: #eeeeee !important; -} -.tt-dropdown-menu, -.tt-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - min-width: 160px; - width: 100%; - padding: 5px 0; - margin: 2px 0 0; - list-style: none; - font-size: 14px; - background-color: #ffffff; - border: 1px solid #cccccc; - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 4px; - -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - background-clip: padding-box; - *border-right-width: 2px; - *border-bottom-width: 2px; -} -.tt-dropdown-menu .tt-suggestion, -.tt-menu .tt-suggestion { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: 1.42857143; - color: #333333; -} -.tt-dropdown-menu .tt-suggestion.tt-cursor, -.tt-menu .tt-suggestion.tt-cursor, -.tt-dropdown-menu .tt-suggestion:hover, -.tt-menu .tt-suggestion:hover { - cursor: pointer; - text-decoration: none; - outline: 0; - background-color: #f5f5f5; - color: #262626; -} -.tt-dropdown-menu .tt-suggestion.tt-cursor a, -.tt-menu .tt-suggestion.tt-cursor a, -.tt-dropdown-menu .tt-suggestion:hover a, -.tt-menu .tt-suggestion:hover a { - color: #262626; -} -.tt-dropdown-menu .tt-suggestion p, -.tt-menu .tt-suggestion p { - margin: 0; -} diff --git a/COPS/cops-3.1.3/templates/bootstrap5/suggestion.html b/COPS/cops-3.1.3/templates/bootstrap5/suggestion.html deleted file mode 100644 index 1107dade..00000000 --- a/COPS/cops-3.1.3/templates/bootstrap5/suggestion.html +++ /dev/null @@ -1 +0,0 @@ -

    {{=it.title}}

    \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/checkconfig.html b/COPS/cops-3.1.3/templates/checkconfig.html deleted file mode 100644 index 676c412c..00000000 --- a/COPS/cops-3.1.3/templates/checkconfig.html +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - COPS Configuration Check - - - -
    -
    -
    -

    COPS Configuration Check

    -
    -
    - -
    - {{=it.error}} -
    -

    Check if PHP version is correct

    -

    {{=it.phpversion}}

    -
    -
    -

    Check if GD is properly installed and loaded

    -

    {{=it.extension_gd}}

    -
    -
    -

    Check if Sqlite is properly installed and loaded

    -

    {{=it.extension_sqlite}}

    -
    -
    -

    Check if libxml is properly installed and loaded

    -

    {{=it.extension_libxml}}

    -
    -
    -

    Check if DOM is properly installed and loaded

    -

    {{=it.extension_dom}}

    -
    -
    -

    Check if XMLWriter is properly installed and loaded

    -

    {{=it.extension_xmlwriter}}

    -
    -
    -

    Check if Json is properly installed and loaded

    -

    {{=it.extension_json}}

    -
    -
    -

    Check if mbstring is properly installed and loaded

    -

    {{=it.extension_mbstring}}

    -
    -
    -

    Check if intl is properly installed and loaded

    -

    {{=it.extension_intl}}

    -
    -
    -

    Check if Normalizer class is properly installed and loaded

    -

    {{=it.extension_Normalizer}}

    -
    -
    -

    Check if zlib is properly installed and loaded

    -

    {{=it.extension_zlib}}

    -
    -
    -

    Check if the base URL looks OK

    -

    {{=it.baseurl}}

    -
    -
    -

    Check if the rendering will be done on client side or server side

    -

    {{=it.render}}

    -

    User agent detected

    -

    {{=it.agent}}

    -
    - {{=it.databases}} -
    -
    -
    - - diff --git a/COPS/cops-3.1.3/templates/default/bookdetail.html b/COPS/cops-3.1.3/templates/default/bookdetail.html deleted file mode 100644 index acb40896..00000000 --- a/COPS/cops-3.1.3/templates/default/bookdetail.html +++ /dev/null @@ -1,89 +0,0 @@ -
    - - {{? it.book.hasCover == 1}} - - {{=it.c.i18n.coverAlt}} - - {{?}} - -

    - {{~it.book.datas:data:i}} - {{=data.format}} - - {{? data.mail == 1}} - - {{?}} - {{? data.readerUrl != ""}} - - {{?}} -
    - {{~}} -

    -

    {{=htmlspecialchars (it.title)}}

    -

    -

    {{=it.c.i18n.authorsTitle}}:

    - {{~it.book.authors:author:i}} - {{? i > 0}}, {{?}}{{=htmlspecialchars (author.name)}} - {{~}} -

    - {{? it.book.tagsName != ""}} -

    -

    {{=it.c.i18n.tagsTitle}}:

    - {{~it.book.tags:tag:i}} - {{? i > 0}}, {{?}}{{=htmlspecialchars (tag.name)}} - {{~}} -

    - {{?}} - {{? it.book.rating != ""}} -

    -

    {{=it.c.i18n.ratingTitle}}:

    {{=it.book.rating}} -

    - {{?}} - {{? it.book.seriesName != ""}} -

    -

    {{=it.c.i18n.seriesTitle}} :

    {{=htmlspecialchars (it.book.seriesCompleteName)}} -

    - {{?}} - {{? it.book.publisherName != ""}} -

    -

    {{=it.c.i18n.publisherName}}:

    {{=htmlspecialchars (it.book.publisherName)}} -

    - {{?}} - {{? it.book.pubDate != ""}} -

    -

    {{=it.c.i18n.pubdateTitle}}:

    {{=it.book.pubDate}} -

    - {{?}} - {{? it.book.languagesName != ""}} -

    -

    {{=it.c.i18n.languagesTitle}}:

    {{=it.book.languagesName}} -

    - {{?}} - {{~it.book.customcolumns_preview :column:column_index}} -

    -

    {{=column.customColumnType.columnTitle}}:

    - {{? column.customColumnType.displaySettings.interpret_as }} -
    {{=column.htmlvalue}}
    - {{??}} -
    {{=column.htmlvalue}}
    - {{?}} -

    - {{~}} - {{? it.book.extraFiles != ""}} -

    -

    {{=it.c.i18n.filesTitle}}:

    - {{~it.book.extraFiles:extraFile:i}} - {{=htmlspecialchars (extraFile.name)}} - {{~}} -

    - {{?}} - {{? it.book.content != ""}} -
    -

    {{=it.c.i18n.contentTitle}}

    -
    {{=it.book.content}}
    - {{?}} -
    diff --git a/COPS/cops-3.1.3/templates/default/file.html b/COPS/cops-3.1.3/templates/default/file.html deleted file mode 100644 index fa76cdf4..00000000 --- a/COPS/cops-3.1.3/templates/default/file.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - {{=it.title}} - - - - -{{? it.server_side_rendering == 0}} - - - - -{{?}} - - - - - - - - - - - {{=it.customHeader}} - -{{? it.server_side_rendering == 0}} - -{{?}} - diff --git a/COPS/cops-3.1.3/templates/default/footer.html b/COPS/cops-3.1.3/templates/default/footer.html deleted file mode 100644 index 255463d1..00000000 --- a/COPS/cops-3.1.3/templates/default/footer.html +++ /dev/null @@ -1,15 +0,0 @@ -
    -
    -
    -
    -
    -
    -
    - {{? it.isPaginated == 1}} -
    - {{? it.prevLink != ""}}
    {{?}} -

    {{=it.currentPage}} / {{=it.maxPage}}

    - {{? it.nextLink != ""}}
    {{?}} -
    - {{?}} -
    \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/default/header.html b/COPS/cops-3.1.3/templates/default/header.html deleted file mode 100644 index 641611dc..00000000 --- a/COPS/cops-3.1.3/templates/default/header.html +++ /dev/null @@ -1,57 +0,0 @@ -
    - -
    -
    - {{? it.c.config.server_side_rendering == 0}} -
    - {{?}} -
    - {{? it.parenturl != ""}} -

    {{=it.title}}

    - {{??}} -

    {{=it.title}}

    - {{?}} -
    -
    -
    -
    -
    - - {{? it.databaseId != ""}} - - {{?}} - {{? it.libraryId != ""}} - - {{?}} - -
    - -
    -
    - {{? it.c.config.server_side_rendering == 0}} - -
    -
      -
    -
    - {{?}} -
    -
    diff --git a/COPS/cops-3.1.3/templates/default/main.html b/COPS/cops-3.1.3/templates/default/main.html deleted file mode 100644 index 0b6413e5..00000000 --- a/COPS/cops-3.1.3/templates/default/main.html +++ /dev/null @@ -1,53 +0,0 @@ -
    -{{? it.page == 13 || it.page == 16}} - {{? it.page == 13}} - {{#def.bookdetail}} - {{??}} - {{= it.fullhtml}} - {{?}} -{{??}} -{{~it.entries:entry:i}} - {{? it.containsBook == 0}} - - {{??}} -
    - - {{? entry.thumbnailurl }} - - {{=it.c.i18n.coverAlt}} - - {{?}} - -

    - {{~entry.book.preferedData:data:j}} - {{=data.name}} - -
    - {{~}} -

    - -
    -

    {{=htmlspecialchars (entry.title)}} - {{? entry.book.pubDate != ""}}({{=entry.book.pubDate}}){{?}} - {{? entry.book.rating != ""}}{{=entry.book.rating}}{{?}} -

    -

    {{=it.c.i18n.authorsTitle}} :

    {{=htmlspecialchars (entry.book.authorsName)}}
    - {{? entry.book.tagsName != ""}}

    {{=it.c.i18n.tagsTitle}} :

    {{=htmlspecialchars (entry.book.tagsName)}}
    {{?}} - {{? entry.book.seriesName != ""}}

    {{=it.c.i18n.seriesTitle}} :

    {{=htmlspecialchars (entry.book.seriesName)}} ({{=entry.book.seriesIndex}})
    {{?}} - {{~entry.book.customcolumns_list :column:column_index}} -

    {{=column.customColumnType.columnTitle}} :

    {{=column.htmlvalue}}
    - {{~}} -
    -
    - {{?}} -{{~}} -{{?}} -
    -
    diff --git a/COPS/cops-3.1.3/templates/default/page.html b/COPS/cops-3.1.3/templates/default/page.html deleted file mode 100644 index 20f1e0a3..00000000 --- a/COPS/cops-3.1.3/templates/default/page.html +++ /dev/null @@ -1,5 +0,0 @@ -
    -{{#def.header}} -{{#def.main}} -{{#def.footer}} -
    \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/default/styles/fa-solid.min.css b/COPS/cops-3.1.3/templates/default/styles/fa-solid.min.css deleted file mode 100644 index a06374a3..00000000 --- a/COPS/cops-3.1.3/templates/default/styles/fa-solid.min.css +++ /dev/null @@ -1,5 +0,0 @@ -/*! - * Font Awesome Free 5.0.13 by @fontawesome - https://fontawesome.com - * License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) - */ -@font-face{font-family:Font Awesome\ 5 Free;font-style:normal;font-weight:900;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.fas{font-family:Font Awesome\ 5 Free;font-weight:900} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/default/styles/fontawesome.min.css b/COPS/cops-3.1.3/templates/default/styles/fontawesome.min.css deleted file mode 100644 index 9c931e48..00000000 --- a/COPS/cops-3.1.3/templates/default/styles/fontawesome.min.css +++ /dev/null @@ -1,5 +0,0 @@ -/*! - * Font Awesome Free 5.0.13 by @fontawesome - https://fontawesome.com - * License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) - */ -.fa,.fab,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{animation:a 2s infinite linear}.fa-pulse{animation:a 1s infinite steps(8)}@keyframes a{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";transform:scaleX(-1)}.fa-flip-vertical{transform:scaleY(-1)}.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-aws:before{content:"\f375"}.fa-backward:before{content:"\f04a"}.fa-balance-scale:before{content:"\f24e"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bicycle:before{content:"\f206"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blind:before{content:"\f29d"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-book:before{content:"\f02d"}.fa-book-open:before{content:"\f518"}.fa-bookmark:before{content:"\f02e"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-btc:before{content:"\f15a"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-certificate:before{content:"\f0a3"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-square:before{content:"\f14a"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-credit-card:before{content:"\f09d"}.fa-crop:before{content:"\f125"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-delicious:before{content:"\f1a5"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-deviantart:before{content:"\f1bd"}.fa-diagnoses:before{content:"\f470"}.fa-dice:before{content:"\f522"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-divide:before{content:"\f529"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edit:before{content:"\f044"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-excel:before{content:"\f1c3"}.fa-file-image:before{content:"\f1c5"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fire:before{content:"\f06d"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-fulcrum:before{content:"\f50b"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-gift:before{content:"\f06b"}.fa-git:before{content:"\f1d3"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-martini:before{content:"\f000"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-handshake:before{content:"\f2b5"}.fa-hashtag:before{content:"\f292"}.fa-hdd:before{content:"\f0a0"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-heart:before{content:"\f004"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hockey-puck:before{content:"\f453"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-houzz:before{content:"\f27c"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-instagram:before{content:"\f16d"}.fa-internet-explorer:before{content:"\f26b"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-joget:before{content:"\f3b7"}.fa-joomla:before{content:"\f1aa"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-meh:before{content:"\f11a"}.fa-memory:before{content:"\f538"}.fa-mercury:before{content:"\f223"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-moon:before{content:"\f186"}.fa-motorcycle:before{content:"\f21c"}.fa-mouse-pointer:before{content:"\f245"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nintendo-switch:before{content:"\f418"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-old-republic:before{content:"\f510"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-osi:before{content:"\f41a"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-paint-brush:before{content:"\f1fc"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-people-carry:before{content:"\f4ce"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-volume:before{content:"\f2a0"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-plane:before{content:"\f072"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poo:before{content:"\f2fe"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-r-project:before{content:"\f4f7"}.fa-random:before{content:"\f074"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-rendact:before{content:"\f3e4"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-retweet:before{content:"\f079"}.fa-ribbon:before{content:"\f4d6"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-rupee-sign:before{content:"\f156"}.fa-safari:before{content:"\f267"}.fa-sass:before{content:"\f41e"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-search:before{content:"\f002"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shower:before{content:"\f2cc"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-simplybuilt:before{content:"\f215"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skull:before{content:"\f54c"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowflake:before{content:"\f2dc"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-spinner:before{content:"\f110"}.fa-spotify:before{content:"\f1bc"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-star:before{content:"\f005"}.fa-star-half:before{content:"\f089"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toolbox:before{content:"\f552"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-train:before{content:"\f238"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-tripadvisor:before{content:"\f262"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-moving:before{content:"\f4df"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-uikit:before{content:"\f403"}.fa-umbrella:before{content:"\f0e9"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-glass:before{content:"\f4e3"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/default/styles/style-base.css b/COPS/cops-3.1.3/templates/default/styles/style-base.css deleted file mode 100644 index 3ce14ec2..00000000 --- a/COPS/cops-3.1.3/templates/default/styles/style-base.css +++ /dev/null @@ -1,452 +0,0 @@ -/* Global Box Sizing and Font-Smoothing */ -*, *:after, *:before { - box-sizing:border-box; - -webkit-box-sizing:border-box; - -moz-box-sizing:border-box; - -webkit-font-smoothing:antialiased; - -moz-font-smoothing:antialiased; - -o-font-smoothing:antialiased; - font-smoothing:antialiased; -} - -html { font-size: 100%; -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; } - -body { - font-family: "Century Gothic", CenturyGothic, Geneva, AppleGothic, sans-serif; - line-height:18px; - color: #1c1c1c; /* Lighter on the eyes than #000 Black */ - margin: 0px; background: #cccccc; background-size: cover; -} - -img { - border: 0px; - max-width: 100%; - height: auto; - width: auto\9; /* ie8 */ -} - -/* ========================================================================== - Typography stuff goes here - ========================================================================== */ -h1,h2,h3,h4,h5,h6 { font-weight: bold; margin:0; padding:0;} -/*h1 see mediaqueries*/ -h2 {font-size: 1.2em;} -h3 {font-size: 1.1em;} -h4 {font-size: 1.0em; } -h5 {font-size: 0.83em;} -h6 {font-size: 0.75em;} - -a:hover, a:focus, a:active { outline: none; } -a { color: #000066; font-weight: 800; text-decoration: none;} -a:hover { color:#000; text-decoration: none; } -.frontpage a {display:block; } -.frontpage a:hover { width: 100%; background-color: #778899;} -.books:hover { width: 100%; background-color: #778899; } -.link a:hover { display:inline-block; width: 100%; background-color: #778899; /*Dirty IE Hack*/ zoom: 1; *display: inline;} - -.mfp-content .bookpopup { - position: relative; - background: #FFF; - padding: 20px; - width: auto; - max-width: 700px; - margin: 20px auto; - min-height: 198px; -} - -#email { -width: 300px; -} - -.filtered { -display: none; -} - -#filter { -clear:both; -} - -#filter ul { -margin: 0; -padding: 0; -list-style-type: none; -text-align: left; -text-transform:none; -} - -#filter ul li { -cursor: pointer; -} - -li { -display: inline-block; -padding: .2em 1em; -margin: 2px; -color: black; -background-color: white; -opacity: 0.5; -} - -.filter-include { - border-left:thick solid blue; - opacity: 1; -} - -.filter-include:after { - content: " \2713"; /* Tick mark */ -} - -.filter-exclude { - border-right:thick solid red; - opacity: 1; -} - -.filter-exclude:after { - content: " \2717"; /* Check mark */ -} - -img -{ -margin:0; -padding:0; -border:0; -} - -/* ============================================================================= - Main container stuff goes here and other globals - ========================================================================== */ -.container{ - background: #414141; border:1px solid #000; - max-width:800px;width:95%;margin:0 auto;position:relative; } - -/* ============================================================================= - Header stuff goes here - ========================================================================== */ -header { - clear:both; - color:white; - text-align:center; - text-transform:uppercase; - display:block; - min-height:70px; -} - -.hicon{ - display:inline-block; - color:lightgray; - text-align: center; - margin: 0 2px; -} - -.submit { - color: lightgray; - cursor: pointer; - background-color: transparent; - background-image: none; - border-color: transparent; - display: table-cell; -} - -.hicon64{ - font-size: 64px; - line-height: 64px; - width: 64px; - height: 64px; -} - -.hicon32{ - width: 32px; - height: 32px; -} - -.headleft { - float: left; -} - -.headcenter -{ -float:none; -margin:auto; -text-align:center; -height:70px; -display:table; -} - -header h1{ - display: table-cell; - vertical-align: middle; - text-align: center; - line-height: 100%; -} - -header a{ - color: white; -} - -.headright { - float: right; - /*for ios compatibility*/ - cursor: pointer; -} - -/* ============================================================================= - Section and Article stuff goes here - ========================================================================== */ -section { -clear:both; -background-color: #fff; -} - -article { -border-bottom: 1px solid black; -max-width:800px; -} - -/*-------------frontpage article-------------*/ - -.frontpage h2 { - padding: 5px 0 0 5px; -} - -.frontpage h4 { - padding: 5px 0 5px 20px; - font-style: italic; -} - -/*-------------books article-------------*/ -.books { - clear: both; - min-height: 90px; - position: relative; -} - -.books .cover { - float:left; - margin: 4px 10px 4px 4px; - width: 60px; - height: 82px; - position: absolute; -} - -.books .fancydetail .fullclickpopup { - margin: 0px 0px 4px 75px; -} - -.bookpopup .cover { - float:left; - margin: 4px 10px 4px 4px; - width: 100px; - height: 150px; -} - -.cover img { - max-width:100%; - max-height:100%; - color: white; -} - -.download { - float: right; - line-height:40px; - text-align: right; - margin: 6px; -} - -.download a { - background: darkgray; - color: #EEE; - text-decoration : none; - font-weight: bold; - padding: 5px 10px 5px 10px; - text-align: center; -} - -.download img { - vertical-align:middle; -} - -.books h4{ - display: inline; - font-style: italic; -} - -.customcolumncontent { - display: inline; -} - -.customcolumncontent[data-customcolumn-datatype='comments'][data-customcolumn-interpretas='long-text'], -.customcolumncontent[data-customcolumn-datatype='comments'][data-customcolumn-interpretas='html'], -.customcolumncontent[data-customcolumn-datatype='comments'][data-customcolumn-interpretas='markdown'] { - display: block; - white-space: pre-wrap; -} - -/*-------------books popup article-------------*/ -.bookpopup h2{ - margin: 15px 15px; -} - -.bookpopup h3{ - display:inline; /*Dirty IE Hack*/ zoom: 1; *display: inline; -} - -.bookpopup h4{ - border-top: 1px solid black; -} - -.fullclickpopup{ - display: block; - min-height: 86px; -} - -section .bookpopup{ - padding: 8px 8px; - min-height: 175px; -} - -/* ============================================================================= - Footer stuff goes here - ========================================================================== */ -footer -{ -clear:both; -color:white; -height:32px; -} - -.footleft -{ -float:left; -height:32px; -} - - -.footright -{ -float:right; -height:32px; -} - -.footcenter -{ -margin:auto; -text-align:center; -height:32px; -display:table; -font-weight: bold; -} - -.footcenter p, .footcenter a -{ -display: table-cell; -vertical-align: middle; -text-align: center; -line-height: 100%; -} - -/* ============================================================================= - Aside stuff goes here - ========================================================================== */ -#tool -{ -width:100%; -} - - -/*-------------Search Aside-------------*/ -#tool input[type=text], .twitter-typeahead -{ -vertical-align: middle; -width: 100%; -color: black; -background-color: white; -} - -.tt-hint, .tt-query { - width: 100%; - } - -.stop select -{ -vertical-align: middle; -margin: 4px; -color: black; -} - -#sort -{ -cursor:pointer; -} - -#searchForm { -display: table; -padding: 0 2px; -} - -.stop -{ -display: table-cell; -vertical-align: middle; -width: 100%; -} - -.tt-dropdown-menu { - width: 322px; - text-align: left; - margin-top: 6px; - color: #000066; - padding: 4px 0; - background-color: #fff; - border: 1px solid #ccc; -} - -.tt-header { - border-bottom: 1px solid #CCCCCC; - font-weight: bold; -} - -.tt-suggestion { - padding: 3px 20px; - line-height: 14px; -} - -.tt-suggestion.tt-cursor { - color: #1c1c1c; - background-color: #778899; -} - -.tt-suggestion p { - margin: 0; -} - -/* ============================================================================= - Mediaquerie stuff goes here - ========================================================================== */ -/* 100px and greater */ -@media only screen and (min-width: 100px) { -h1 {font-size: 1em;} -.container { width:100%; } -} - -/* 320px and greater */ -@media only screen and (min-width: 320px) { -h1 {font-size: 1.2em;} -} - -/* 480px and greater */ -@media only screen and (min-width: 480px) { -h1 {font-size: 1.5em;} -body { font-size: 1em;/*12px/16px */ - font-weight:450; /* Better supported than 'lighter' attribute */ - } -} - -/* 768px and greater */ -@media only screen and (min-width: 768px) { -h1 {font-size: 2em; line-height: 1em;} -body { margin: 5px; - font-size: 0.85em;/*12px/16px */ - font-weight:400; /* Better supported than 'lighter' attribute */ - } -} diff --git a/COPS/cops-3.1.3/templates/default/styles/style-default.css b/COPS/cops-3.1.3/templates/default/styles/style-default.css deleted file mode 100644 index 76885d23..00000000 --- a/COPS/cops-3.1.3/templates/default/styles/style-default.css +++ /dev/null @@ -1,62 +0,0 @@ -@import url("style-base.css"); - - -/* ============================================================================= - Main container stuff goes here and other globals - ========================================================================== */ -.container { -border-radius:10px; -} - -/* ============================================================================= - Header stuff goes here - ========================================================================== */ -header { - box-shadow:inset 0px -5px 8px #000000; - border-radius: 10px 10px 0px 0px; -} - -.hicon{ - text-shadow: 2px 2px 2px black; -} - -.submit { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} - -header h1{ - display: table-cell; - vertical-align: middle; - text-align: center; - line-height: 100%; -} - -header a{ - color: white; -} - -.download a { - border-radius: 6px; - box-shadow:0 0 10px #000; - background: radial-gradient(#666, black); -} - -footer -{ -box-shadow:inset 0px 5px 8px #000000; -border-radius: 0px 0px 10px 10px; -} - - -/* ============================================================================= - Mediaquerie stuff goes here - ========================================================================== */ -/* 768px and greater */ -@media only screen and (min-width: 768px) { -.container { box-shadow:0 0 20px #000; } -} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/default/styles/style-eink.css b/COPS/cops-3.1.3/templates/default/styles/style-eink.css deleted file mode 100644 index 2cc0b53a..00000000 --- a/COPS/cops-3.1.3/templates/default/styles/style-eink.css +++ /dev/null @@ -1,63 +0,0 @@ -@import url("style-base.css"); - -a { - color: black; - font-weight: bold; -} -.frontpage a:hover, .books:hover { background-color: white;} - -#filter ul { -font-variant: normal; -} - -li, .container { -background-color: white; -} - -header { - color: black; - text-transform: none; - border-bottom: 2px dashed gray; - font-variant: small-caps; - letter-spacing: 2px; -} - -#tool input[type=text], .twitter-typeahead -{ - font-variant: normal; -} - -.hicon, .footcenter, .submit, .fullclickpopup{ - color:black; -} - -.frontpage h2 { - text-align: center; - letter-spacing: 2px; - color: black; - font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif; -} - -.frontpage h4 { - padding: 5px 0; - text-align: center; - color: gray; - font-size: 13px; - text-decoration: overline; - } - -.download a { - background: black; - color: white; -} - - -.tt-dropdown-menu { - color: black; - background-color: white; - border: 1px solid #ccc; -} -.tt-suggestion.tt-is-under-cursor { - color: black; - background-color: white; -} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/default/styles/style-iphone.css b/COPS/cops-3.1.3/templates/default/styles/style-iphone.css deleted file mode 100644 index 6e2f6818..00000000 --- a/COPS/cops-3.1.3/templates/default/styles/style-iphone.css +++ /dev/null @@ -1,116 +0,0 @@ -@import url("style-base.css"); -/* ============================================================================= - Main container goes here and other globals - ========================================================================== */ - -.st, .sp, .sa, .se, .ss { - font: normal normal 400 14px Helvetica Neue Interface, Helvetica Neue, Helvetica; - color: #007aff; } - -.st { - font-weight: 600; } - -.frontpage a { - display: block; } - .frontpage a:hover { - width: 100%; - background-color: #e2e1e6; } - -.books:hover { - width: 100%; - background-color: #e2e1e6; } - -a { - color: #007aff; - font-weight: 600; } - a:hover { - color: black; } - -/*iphone - reduction des tailles de police et taille fixe en px*/ -body { - font: normal normal 300 12px Helvetica Neue Interface, Helvetica Neue, Helvetica; - color: black; } - -h2 { - font: normal normal 400 16px Helvetica Neue Interface, Helvetica Neue, Helvetica; - color: #007aff; } - -h3 { - font: normal normal 400 14px Helvetica Neue Interface, Helvetica Neue, Helvetica; - color: black; } - -h4 { - font: normal normal 400 14px Helvetica Neue Interface, Helvetica Neue, Helvetica; - color: black; } - -/*iphone - Suppression des arrondis -.container { -border-radius:10px; -} -*/ -/* ============================================================================= - Header stuff goes here - ========================================================================== */ -/* -header { -iphone - Suppression ombrage (bug avec formulaire recherche) - box-shadow:inset 0px -5px 8px #000000; -iphone - Suppression des arrondis - border-radius: 10px 10px 0px 0px; -}*/ -.hicon { - text-shadow: 2px 2px 2px black; } - -/*iphone - icone trop bas */ -#tool .hicon32 { - margin-top: -5px; } - -.submit { - border-radius: 0; - box-shadow: none; } - -header h1 { - vertical-align: middle; - text-align: center; - font: normal normal 500 24px Helvetica Neue Interface, Helvetica Neue, Helvetica; - color: #007aff; } - -.download a { - font: normal normal 400 16px Helvetica Neue Interface, Helvetica Neue, Helvetica; - color: #007aff; - box-shadow: 0 0 10px #c8c7cc; - color: #007aff; - border-color: #007aff; - border-radius: 5px; - border-style: solid; - border-width: 1px; - background: white; } - -/*iphone - bouton de donwload en haut dans book detail -(manque de place en mode paysage)*/ -.bookpopup .download { - float: none; - margin: -12px 30px -2px 4px; } - -/*iphone - modification des marges pour cover dans detail*/ -.bookpopup .cover { - margin: 27px 4px 4px 0px; } - -.mfp-content .bookpopup { - /*iphone - Taille minimum du detail du livre en popup - pour que la pochette ne depasse pas - (pas seulement pour iphone) */ - min-height: 210px; } - -footer { - box-shadow: inset 0px 5px 10px #000000; - /*iphone - Suppression des arrondis - border-radius: 0px 0px 10px 10px;*/ } - -/* ============================================================================= - Media query stuff goes here - ========================================================================== */ -/* 768px and greater */ -@media only screen and (min-width: 768px) { - .container { - box-shadow: 0 0 20px #000; } } diff --git a/COPS/cops-3.1.3/templates/default/styles/style-iphone7.css b/COPS/cops-3.1.3/templates/default/styles/style-iphone7.css deleted file mode 100644 index 85b18b9d..00000000 --- a/COPS/cops-3.1.3/templates/default/styles/style-iphone7.css +++ /dev/null @@ -1,116 +0,0 @@ -@import url("style-base.css"); -/* ============================================================================= - Main container stuff goes here and other globals - ========================================================================== */ - -.st, .sp, .sa, .se, .ss { - font: -apple-system-body; - color: #007aff; } - -.st { - font-weight: 600; } - -.frontpage a { - display: block; } - .frontpage a:hover { - width: 100%; - background-color: #e2e1e6; } - -.books:hover { - width: 100%; - background-color: #e2e1e6; } - -a { - color: #007aff; - font-weight: 600; } - a:hover { - color: black; } - -/*iphone - reduction des tailles de police et taille fixe en px*/ -body { - font: -apple-system-body; - color: black; } - -h2 { - font: -apple-system-subheadline; - color: #007aff; } - -h3 { - font: -apple-system-subheadline; - color: black; } - -h4 { - font: -apple-system-subheadline; - color: black; } - -/*iphone - Suppression des arrondis -.container { -border-radius:10px; -} -*/ -/* ============================================================================= - Header stuff goes here - ========================================================================== */ -/* -header { -iphone - Suppression ombrage (bug avec formulaire recherche) - box-shadow:inset 0px -5px 8px #000000; -iphone - Suppression des arrondis - border-radius: 10px 10px 0px 0px; -}*/ -.hicon { - text-shadow: 2px 2px 2px black; } - -/*iphone - icone trop bas */ -#tool .hicon32 { - margin-top: -5px; } - -.submit { - border-radius: 0; - box-shadow: none; } - -header h1 { - vertical-align: middle; - text-align: center; - font: -apple-system-headline; - color: #007aff; } - -.download a { - font: -apple-system-subheadline; - color: #007aff; - box-shadow: 0 0 10px #c8c7cc; - color: #007aff; - border-color: #007aff; - border-radius: 5px; - border-style: solid; - border-width: 1px; - background: white; } - -/*iphone - bouton de donwload en haut dans book detail -(manque de place en mode paysage)*/ -.bookpopup .download { - float: none; - margin: -12px 30px -2px 4px; } - -/*iphone - modification des marges pour cover dans detail*/ -.bookpopup .cover { - margin: 27px 4px 4px 0px; } - -.mfp-content .bookpopup { - /*iphone - Taille minimum du detail du livre en popup - pour que la pochette ne depasse pas - (pas seulement pour iphone) */ - min-height: 210px; } - -footer { - box-shadow: inset 0px 5px 10px #000000; - /*iphone - Suppression des arrondis - border-radius: 0px 0px 10px 10px;*/ } - -/* ============================================================================= - Media query stuff goes here - ========================================================================== */ -/* 768px and greater */ -@media only screen and (min-width: 768px) { - .container { - box-shadow: 0 0 20px #000; } } diff --git a/COPS/cops-3.1.3/templates/default/styles/style-kindle.css b/COPS/cops-3.1.3/templates/default/styles/style-kindle.css deleted file mode 100644 index 8279fd9c..00000000 --- a/COPS/cops-3.1.3/templates/default/styles/style-kindle.css +++ /dev/null @@ -1,665 +0,0 @@ -/* - * COPS 4 Kindle from https://github.com/Joduai/cops-kindle - * A dedicated COPS (Calibre OPDS) css theme for kindle e-book readers. - * Should also work elegantly on other manufacturers e-book readers. - */ -*, -*:after, -*:before { - box-sizing: border-box; - -webkit-font-smoothing: antialiased -} - -html, -body { - margin: 0; - padding: 0; - background: #FFF -} - -body { - font-family: "Amazon Ember", Helvetica, Futura, Caecilia, Georgia, Palatino, sans-serif; - font-size: 1.6em; - line-height: 1.6em; - color: #000 -} - -img { - border: 0; - max-width: 100%; - height: auto -} - -h1, -h2, -h3, -h4, -h5, -h6 { - margin: 0; - padding: 0; - line-height: 100% -} - -h1 { - font-family: "Amazon Ember Bold", Helvetica, Futura, Caecilia, sans-serif -} - -h1 { - font-size: 1.8em -} - -h2 { - font-size: 1.6em -} - -h3, -h4, -h5, -h6 { - font-size: 1.2em; - font-weight: normal -} - -a:hover, -a:focus, -a:active { - outline: none -} - -a { - color: #000; - text-decoration: none -} - -a:hover { - text-decoration: none -} - -.books:hover { - background-color: #ececec -} - -.link a:hover { - display: inline-block; - width: 100%; - background-color: #c2c2c2 -} - -.mfp-content .bookpopup { - position: relative; - background: #FFF; - padding: 20px; - width: auto; - max-width: 90%; - margin: 20px auto; - min-height: 198px -} - -button.mfp-close, -.mfp-close:active { - top: -20px; - right: -20px; - background: #FFF; - border-radius: 20%; - font-size: 2.4em; - opacity: 1 -} - -#email { - width: 300px -} - -.filtered { - display: none -} - -#filter { - clear: both -} - -#filter ul { - margin: 0; - padding: 0; - list-style-type: none; - text-align: left; - text-transform: none -} - -#filter ul li { - cursor: pointer -} - -li { - display: inline-block; - padding: .2em 1em; - margin: 2px; - color: black; - background-color: white; - opacity: 0.5 -} - -.filter-include { - border-left: thick solid blue; - opacity: 1 -} - -.filter-include:after { - content: " \2713"; - /* Tick mark */ -} - -.filter-exclude { - border-right: thick solid red; - opacity: 1 -} - -.filter-exclude:after { - content: " \2717"; - /* Check mark */ -} - -img { - margin: 0; - padding: 0; - border: 0 -} - -.container { - border: none; - width: 100%; - margin: 0 auto; - position: relative -} - -header { - clear: both; - color: #000; - text-align: center; - text-transform: uppercase; - display: block; - min-height: 120px; - padding-bottom: 10px; - border-bottom: 1px solid #000 -} - -.hicon { - display: inline-block; - text-align: center; - margin: 0 2px -} - -.submit { - cursor: pointer; - background-color: transparent; - background-image: none; - border-color: transparent; - display: table-cell -} - -.hicon64 { - font-size: 4em -} - -.hicon32 .fa-search { - font-size: 1.6em; - vertical-align: middle -} - -.headleft { - float: left; - padding: 10px; - display: block -} - -.headcenter { - float: none; - margin: auto; - text-align: center; - height: 70px; - display: table -} - -header h1 { - font-size: 1.4em; - display: table-cell; - vertical-align: middle; - text-align: center; - line-height: 100% -} - -.headright { - float: right -} - -section { - clear: both -} - -article { - border-bottom: 1px solid #000 -} - -.frontpage h2 { - padding: 5px 0 3px 5px -} - -.frontpage h4 { - padding: 8px 0 4px 40px; - font-style: italic -} - -.frontpage a { - padding: 10px; - display: block -} - -.frontpage a:hover, -.frontpage a:active .frontpage a:focus { - width: 100%; - background-color: #c2c2c2 -} - -.books { - clear: both; - width: 100%; - min-height: 100px; - position: relative; - overflow: auto; - padding: 10px 20px 10px 10px; - display: table; - direction: rtl -} - -section>article.books:first-of-type { - padding-top: 20px -} - -.books .cover { - width: 20%; - min-width: 110px; - height: 100%; - display: table-cell; - float: left; - vertical-align: top -} - -.books .cover a { - display: block -} - -.cover img { - margin: 0; - border: 1px solid #000 -} - -.bookpopup .cover { - max-width: 100% -} - -.bookpopup .cover img { - width: auto; - max-height: 350px -} - -.books .download, -.bookpopup .download { - margin: 0; - width: 15%; - min-width: 220px; - position: relative; - display: table-cell; - float: right; - vertical-align: top -} - -.download a { - text-decoration: none; - font-weight: bold; - padding: 5px 10px; - text-align: center -} - -.download br { - display: none -} - -.download img { - vertical-align: middle -} - -.download a { - display: block; - width: 100%; - color: #000; - border: 1px solid #000; - background: #FFF; - margin: 0 0 15px 0; - padding: 10px -} - -.download a[title*="Reader"] { - display: block -} - -article.books .download a:nth-of-type(even), -article.bookpopup .download a[title*="Open"] { - display: none -} - -.download a .fa-download { - float: left -} - -.books a.fancydetail { - display: table-cell; - padding: 0 5px 0 0; - vertical-align: top; - direction: ltr; - width: 65%; - min-width: 65%; - max-width: 65% -} - -.books .fullclickpopup { - line-height: 100% -} - -.books .fullclickpopup h4 { - display: inline; - font-style: italic; - line-height: 1.2em -} - -.books .fullclickpopup h4+span { - font-size: 1.1em -} - -section .bookpopup { - padding: 10px 20px; - margin-top: 40px -} - -.bookpopup .download { - max-width: 260px -} - -.bookpopup h1 { - clear: both; - margin: 20px 0 -} - -.bookpopup h1 a { - display: none -} - -.bookpopup h2 { - margin: 0 10px -} - -.bookpopup h3 { - display: inline-block; - margin-top: 5px -} - -.bookpopup h4 { - padding: 30px 0; - border-top: 1px solid black -} - -.bookpopup h3+a, -.bookpopup h3+p { - font-size: 1.2em -} - -.fullclickpopup { - display: block; - min-height: 100px -} - -.fullclickpopup h2 { - font-size: 1.4em; - margin-bottom: 10px -} - -.bookpopup p.popupless { - clear: both -} - -.bookpopup>p { - padding: 0; - margin: 0 -} - -.bookpopup>p.popupless:first-of-type { - padding-top: 10px; - border-top: 1px solid #000 -} - -.bookpopup>div:last-child { - font-size: 1.3em -} - -.bookpopup>div:last-child * { - font-family: inherit !important; - font-size: 1em !important; - line-height: 1.3em !important -} - -footer { - clear: both; - overflow: auto; - padding: 5px 20px 15px; - margin-bottom: 15px; - line-height: 1em; - position: relative -} - -.footleft { - float: left -} - -.footright { - float: right -} - -.footcenter { - margin: auto; - text-align: center; - height: 32px; - display: table; - font-weight: bold; - margin-top: -5px -} - -.footcenter p, -.footcenter a { - display: table-cell; - vertical-align: middle; - text-align: center; - line-height: 100% -} - -footer a { - display: block; - padding: 15px -} - -footer:before, -footer:after { - position: absolute; - bottom: 0; - font-size: 1em; - font-style: italic; - line-height: 1.2em -} - -footer:before { - content: "\63 \6f \70 \73 \20 \6b \69 \6e \64 \6c \65 \20 \74 \68 \65 \6d \65 \20 \62 \79 \20 \67 \69 \74 \68 \75 \62 .\63 \6f \6d /"; - font-size: 0.75em; - width: 63%; - color: #555; - left: 0; - text-align: right -} - -footer:after { - clear: both; - content: "\6A \6F \64 \75 \61 \69"; - font-size: 0.75em; - width: 37%; - display: block; - right: 0; - text-align: left; - color: #333 -} - -/* Aside stuff */ -#tool { - width: 100% -} - -#tool>div { - float: none !important; - width: 45% !important; - margin: 10px auto -} - -#tool input[type=text], -.twitter-typeahead { - vertical-align: middle; - width: 100% -} - -.tt-hint, -.tt-query { - width: 100% -} - -.stop select { - vertical-align: middle; - margin: 4px; - color: black -} - -#sort { - cursor: pointer -} - -#searchForm { - display: table; - padding: 0 2px -} - -.stop { - display: table-cell; - vertical-align: middle; - width: 100% -} - -.tt-dropdown-menu { - width: 322px; - text-align: left; - margin-top: 6px; - color: #000066; - padding: 4px 0; - background-color: #fff; - border: 1px solid #ccc; - font-size: 50% -} - -.tt-header { - border-bottom: 1px solid #CCCCCC; - font-weight: bold -} - -.tt-suggestion { - padding: 3px 20px; - line-height: 14px -} - -.tt-suggestion.tt-cursor { - color: #1c1c1c; - background-color: #c2c2c2 -} - -.tt-suggestion p { - margin: 0 -} - -#tool div form * { - border: none -} - -#tool form input { - padding: 5px; - border: 1px solid #000 -} - -input[type="radio"], input[type="checkbox"]{ /* Make radio buttons easier to hit with touchscreen */ - width: 30px; - height:30px; - margin-right: 10px; -} - -@media only screen and (min-width:1100px) { - - body .container, - body .mfp-content { - width: 70%; - max-width: 1000px; - font-size: 60% - } - - .download { - min-width: 120px - } - - .bookpopup .download { - min-width: 260px; - display: flex; - flex-wrap: wrap - } - - .bookpopup .download a { - flex: 0 50% - } - - .bookpopup .download a { - display: inline-block !important; - padding: 10px 0; - overflow: auto - } - - .bookpopup .download a .fa-download { - float: none - } - - .bookpopup .download #mailButton, - .bookpopup .download a[title*="Reader"] { - flex: 100% - } - - .bookpopup .download a:hover { - color: #FFF; - background: #000 - } - - .books .download { - min-width: 140px - } -} - -@media only screen and (max-width:900px) { - .books a.fancydetail { - width: 55%; - min-width: 55%; - max-width: 55% - } -} - -@media only screen and (max-width:900px) { - .books .cover { - float: none - } -} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/default/styles/typeahead.css b/COPS/cops-3.1.3/templates/default/styles/typeahead.css deleted file mode 100644 index 23ccbc10..00000000 --- a/COPS/cops-3.1.3/templates/default/styles/typeahead.css +++ /dev/null @@ -1,200 +0,0 @@ -/* - * typehead.js-bootstrap3.less - * @version 0.2.3 - * https://github.com/hyspace/typeahead.js-bootstrap3.less - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ -.has-warning .twitter-typeahead .tt-input, -.has-warning .twitter-typeahead .tt-hint { - border-color: #8a6d3b; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.has-warning .twitter-typeahead .tt-input:focus, -.has-warning .twitter-typeahead .tt-hint:focus { - border-color: #66512c; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; -} -.has-error .twitter-typeahead .tt-input, -.has-error .twitter-typeahead .tt-hint { - border-color: #a94442; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.has-error .twitter-typeahead .tt-input:focus, -.has-error .twitter-typeahead .tt-hint:focus { - border-color: #843534; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; -} -.has-success .twitter-typeahead .tt-input, -.has-success .twitter-typeahead .tt-hint { - border-color: #3c763d; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.has-success .twitter-typeahead .tt-input:focus, -.has-success .twitter-typeahead .tt-hint:focus { - border-color: #2b542c; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; -} -.input-group .twitter-typeahead:first-child .tt-input, -.input-group .twitter-typeahead:first-child .tt-hint { - border-bottom-left-radius: 4px; - border-top-left-radius: 4px; - width: 100%; -} -.input-group .twitter-typeahead:last-child .tt-input, -.input-group .twitter-typeahead:last-child .tt-hint { - border-bottom-right-radius: 4px; - border-top-right-radius: 4px; - width: 100%; -} -.input-group.input-group-sm .twitter-typeahead .tt-input, -.input-group.input-group-sm .twitter-typeahead .tt-hint { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} -select.input-group.input-group-sm .twitter-typeahead .tt-input, -select.input-group.input-group-sm .twitter-typeahead .tt-hint { - height: 30px; - line-height: 30px; -} -textarea.input-group.input-group-sm .twitter-typeahead .tt-input, -textarea.input-group.input-group-sm .twitter-typeahead .tt-hint, -select[multiple].input-group.input-group-sm .twitter-typeahead .tt-input, -select[multiple].input-group.input-group-sm .twitter-typeahead .tt-hint { - height: auto; -} -.input-group.input-group-sm .twitter-typeahead:not(:first-child):not(:last-child) .tt-input, -.input-group.input-group-sm .twitter-typeahead:not(:first-child):not(:last-child) .tt-hint { - border-radius: 0; -} -.input-group.input-group-sm .twitter-typeahead:first-child .tt-input, -.input-group.input-group-sm .twitter-typeahead:first-child .tt-hint { - border-bottom-left-radius: 3px; - border-top-left-radius: 3px; - border-bottom-right-radius: 0; - border-top-right-radius: 0; -} -.input-group.input-group-sm .twitter-typeahead:last-child .tt-input, -.input-group.input-group-sm .twitter-typeahead:last-child .tt-hint { - border-bottom-left-radius: 0; - border-top-left-radius: 0; - border-bottom-right-radius: 3px; - border-top-right-radius: 3px; -} -.input-group.input-group-lg .twitter-typeahead .tt-input, -.input-group.input-group-lg .twitter-typeahead .tt-hint { - height: 46px; - padding: 10px 16px; - font-size: 18px; - line-height: 1.33; - border-radius: 6px; -} -select.input-group.input-group-lg .twitter-typeahead .tt-input, -select.input-group.input-group-lg .twitter-typeahead .tt-hint { - height: 46px; - line-height: 46px; -} -textarea.input-group.input-group-lg .twitter-typeahead .tt-input, -textarea.input-group.input-group-lg .twitter-typeahead .tt-hint, -select[multiple].input-group.input-group-lg .twitter-typeahead .tt-input, -select[multiple].input-group.input-group-lg .twitter-typeahead .tt-hint { - height: auto; -} -.input-group.input-group-lg .twitter-typeahead:not(:first-child):not(:last-child) .tt-input, -.input-group.input-group-lg .twitter-typeahead:not(:first-child):not(:last-child) .tt-hint { - border-radius: 0; -} -.input-group.input-group-lg .twitter-typeahead:first-child .tt-input, -.input-group.input-group-lg .twitter-typeahead:first-child .tt-hint { - border-bottom-left-radius: 6px; - border-top-left-radius: 6px; - border-bottom-right-radius: 0; - border-top-right-radius: 0; -} -.input-group.input-group-lg .twitter-typeahead:last-child .tt-input, -.input-group.input-group-lg .twitter-typeahead:last-child .tt-hint { - border-bottom-left-radius: 0; - border-top-left-radius: 0; - border-bottom-right-radius: 6px; - border-top-right-radius: 6px; -} -.twitter-typeahead { - width: 100%; - float: left; -} -.input-group .twitter-typeahead { - display: table-cell !important; -} -.twitter-typeahead .tt-hint { - color: #999999; -} -.twitter-typeahead .tt-input { - z-index: 2; -} -.twitter-typeahead .tt-input[disabled], -.twitter-typeahead .tt-input[readonly], -fieldset[disabled] .twitter-typeahead .tt-input { - cursor: not-allowed; - background-color: #eeeeee !important; -} -.tt-dropdown-menu, -.tt-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - min-width: 160px; - width: 100%; - padding: 5px 0; - margin: 2px 0 0; - list-style: none; - font-size: 14px; - background-color: #ffffff; - border: 1px solid #cccccc; - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 4px; - -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - background-clip: padding-box; - *border-right-width: 2px; - *border-bottom-width: 2px; -} -.tt-dropdown-menu .tt-suggestion, -.tt-menu .tt-suggestion { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: 1.42857143; - color: #333333; -} -.tt-dropdown-menu .tt-suggestion.tt-cursor, -.tt-menu .tt-suggestion.tt-cursor, -.tt-dropdown-menu .tt-suggestion:hover, -.tt-menu .tt-suggestion:hover { - cursor: pointer; - text-decoration: none; - outline: 0; - background-color: #f5f5f5; - color: #262626; -} -.tt-dropdown-menu .tt-suggestion.tt-cursor a, -.tt-menu .tt-suggestion.tt-cursor a, -.tt-dropdown-menu .tt-suggestion:hover a, -.tt-menu .tt-suggestion:hover a { - color: #262626; -} -.tt-dropdown-menu .tt-suggestion p, -.tt-menu .tt-suggestion p { - margin: 0; -} diff --git a/COPS/cops-3.1.3/templates/default/suggestion.html b/COPS/cops-3.1.3/templates/default/suggestion.html deleted file mode 100644 index 1107dade..00000000 --- a/COPS/cops-3.1.3/templates/default/suggestion.html +++ /dev/null @@ -1 +0,0 @@ -

    {{=it.title}}

    \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/default/webfonts/fa-solid-900.eot b/COPS/cops-3.1.3/templates/default/webfonts/fa-solid-900.eot deleted file mode 100644 index a32dc8aeba4f2b2f64b1a58d96c0203311c8abf9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133140 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 Z&LDrYNQmbAqq6{-JLO40eg3QU{{hF*%Ju*N diff --git a/COPS/cops-3.1.3/templates/default/webfonts/fa-solid-900.svg b/COPS/cops-3.1.3/templates/default/webfonts/fa-solid-900.svg deleted file mode 100644 index 94bb8f27..00000000 --- a/COPS/cops-3.1.3/templates/default/webfonts/fa-solid-900.svg +++ /dev/null @@ -1,1896 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/COPS/cops-3.1.3/templates/default/webfonts/fa-solid-900.ttf b/COPS/cops-3.1.3/templates/default/webfonts/fa-solid-900.ttf deleted file mode 100644 index 4e518ad496cb5a5f4d69d5a164561f54e6177429..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 132920 zcmeFad3;pW-9LUl=g!QXJ+n{tOtwjYkc8~)!y+IeBAd8jL_}1i2v$+4jXSPI>q1>< zv{vb6skIiZ%b-@NRg25xW39ERZLLoiJ2RR1SeME7{kdmmG6`V)_IY04*YA%XllT3c zd+xbsUp~t@7ePV@hv*ZUXq~@o#q7v+^%n_2J@8$A%(9lYnR}0Y2KU$Fe&uQBoVw}g zOU^t4FMMB!ar4gDaN#=rf>mZACciD{dpp;ke(KtyU-o(tb^z#F4-eB+(|6&19H?7= z&UsrOi)C&>e18N%%>`n6pz z2>R1`LdcIdeQC>i>CH1@g5KXGMCH!~@=o#LIG*(lr-%PrUco+v|Kw)F2fk~*|C{$t zDVjDU9EcwO{>t^wxh;S&w*DmaE4IB5ybKJLz8A8sT zw`jR=Z#eb5jiOYT3Z56bX~UUkoQn9>n}l%ul;A_clJlj1&<=t6q}ym6{N`urkSGyX za3;(ed=K$&$+{!fidaGntuX4N8D*J=U1!4DS41Xs3@T_k*BV)rEiVY9v zpR=1GRCMg-D*9JY?~lYIg^Giz!k9Svvhi|0IITF4z&nX-IQAclmP$nb4M!2jW$IInKIDS9(u5oX~!_QRyWlZIPNS1h)a_L!~hikE$1b*GQYg3r>6Z6GC_+4!-Xj^B(+EI6RAG5zmGz2%E2? z0zV^dzR!ZwQF+VOSFYYfE=~Az7?juOKiM|Rl{X(>EEj$x?p$9O6_&$s+2Y9WA)ubA zHm69o-eRhra(On=BO&x4@dn?+c?2xlKlmDI<<} zHZFr2<9MX~@vf@J;WXamv5mgOX{vTr&qm(Q)tM1*U$!g)l-&UPtFj?aG0u1P-9Gkb zH|Mp$PYi#OyEkY|m4(A1E#xQvo@(zn@{4CiJP1o1Umv%BHm$yq_(#QyaHdH*IQTh3C~%pTTZK{e&Cd{LZk+b1{30yZE%#3YDqqTPr0omihC8N^&!5QV zBS(3RtuO4yh41I`HsY7hEAq$ge7s!7STyT*`Mzf&4nHPJewzhaQ$!#&J*H_00U?Xyl;U0{xLjc^nZ~J13#6wEM@<` z0yp0Sm`BuDLmC_x$AN!lKm(cp@Q;pn6pv?r6TZx%HGzUlg}=!T9-TJAQx_W(GGR`* z6aGXnQIaT6R3>I5<|Y;=PE4#$Y)ouR^d+uJT$8vVaZ}>f#LmR7#65`z6AvX`PP~$M zCoz!tL*lQAbRv^rywQZcg2rx+AqKbzf?C>XFo=sh_2uNIji;IrVDl?bM%Ae@^`+ z_4iaN^k!QR0&gO?3{d+@2jeS<$A{Keo)gRcz!c5q-y)J!D zdUN``^o8lKrY}ohoxU!8WBQi#?de_VAEbYrek}cDI-Y(y{cQT>^lRxi(!WmsCjGng zABJp0D~5-KNQi_fp(i}3@32wd)rnb&1&Jl7@7}~F)c57t`u;lV`>sTP;#-M5iFo2b z;tkaIyNN$15{ZwJBI!zclEtX+NU|>3nru&YC#NT4sPBczqmxULCnkH7mnE-E-juEH zyOQ5SeLs}kn~W!4GV1&7Pf{?N2iWOeV?1U(5UYn zMt$F%>Q6n8`boCF_obds9Z3BqU*E~pkWt@q&}P(k_u#5*eP4?De)4ncyB+mC`7rf; z66*U@)c5-ICe-%@>93?OO<#ffz9GFMeOtD^_oko7*7r+BeZPtNekc8I`s1N6*Z2Sb z@Bdj15ayK4bRJzs+wr^J_&rB2(wp=FeIV_!2EWGauSqt^R@o*O$VGC!JWF1L-!^%L zyk72<56V6AA^8}7Ps&&2>+((cjvSEhRWq4tsS`i<-upnoMo@b(p4^ zW@LY}O>?uqc_#iXz;B^xk?Ab7>M(too}+R~$YtWcq+bSQKx~%P^mBTazDaM1uT!a4 z8V-nEbO)U&>cxv9LsP}y#D9p_#Y=RHSV7+xchFLCnfNL_Os|WSNQ!gBiPR--5qHu* zWTl)ar_(gLiM}SMiF@fWDiKS>nN&n>@{kMqlrm8+N{Hl_q+9$&93^Vy3YsInhAH+t z;+u3S?L#gn(tMgnpU6&Wp<`t$eMy`m)`?zms<@5*LhsRkiRWdv_(a6$H?o7Sq}lRF z8l+({S=>x@!bYpbZ$vj)=o`W%+@eT0g;)55UwFj#X^OPc+4Nod9{o*RMem6Jrc=Z} zsat#?J>n*Mh>jHB5=g( z_^o(HyeED~v&5CuM^#ixm(y?Q1^R`UB|egEVk+HE7s&Nux#*D-M8AlN*XS!^n%E$| zBsR)gStq85W#W2zNvs!V(68jtw1qyV3V8yZOsC3m81Jj-czHaXL?_Y-biVkE_G8R1 z6lor>CanwLjs;5Tsk%RnXrvQ1$DWmiw*)CRz&|JT=L%ES1Hw zM26@;L@V8i+2?Gzf!5IPuyQrD2rA2f!Ev93{uf#Q?TGWW3 z2#K&L7O#j`#V^GT;zsc)&7>GDq~)}h&Y}%;Bi&6urkACTd9O;&lxK=&(ISoz7l|$6 zJn?05zPLba6&H%QNRy-peTV)o&GHoJ{3eL`Vu4sFmWq?b)ndE&fp|nbD)x#$h_9+bL0#ele6R;IaeMb=gIk)kr&FNp*MEneT-2LL$(29Ocg3M&1N@}AXnnBa4 zmrldVa1NbIn`kRtLRZiYbRYeIeo9Z#nIZlQ)TSW)ppX<8G6?EW!0I9r$O%Jm9$X5t8q}>oKL__%rC6pgskx zOd`Q)0OISQoCbi^N+iMx;#yE>`WaZkM507NJO#?-0jLGEQi1k>^80{<6qKk@pd&zQ z6|nk=M4f{82WY(lm4QYTN&vx1ll%J~Mc>WW0G0@h!Vn52M}SR~pM#7xk31?mLtP>@`&d=Fs77Kttetlc8f zt$xzN{cPZ|5t3uM>$26u{w$#8w6IRnQ9+=wZ-{6u|$9 z#Kj8W1Vw`TA^@IHB>EJ<9g4)|3WDqY3I%YCB5|bxct?@ANKa2V3GK)0=Qw3_?`l+f+E3f z0}z4!KtX;9^g#u1%_6Z!0sON_{73p91)7k>D`~fa4a4XB2p0 zN<6CoE?gvjt{}b%`kVq?3i`YPaeVs~j4}QTxB#W=fj$9!NkMjk zzN{cEpa&G_SkPA#WGm>kfCMBG zpDGB>|7Qx!nI$p`kdJt%8i1rElB58cNhGBLq$iQo6d*^5q)7o1l}MTuAX|wf;$=X} z5=mVF@|H+i6$JWp5_x6N6i~Z@RG{6U;}jrOisX0&@iOQH1<7^aqyU*yBqu6}Uw}3%(6>Qb z6?i{Ea*_gMQ;}>}fRrkdoCYBN3W_ntfaEHYTxI|=tVs4KK$;cF$qJBbMUwLkK*ANt z=?d6SB9b!{AoYr5Oabz*NX}A#BrKBX-wg3A=o|%l6m+fv-3mHS0TQ!FE>sZbf*z$n z*MJ_a0C`#@7b`%r7RexZ94F@+kQJa@9sn8wk-SVnyajr>0&)4SRFEislE(l5O@c^XtpJ^ZNN!hvc0nX> zQh=U8ByUy_Pk?@1L7oB1Z3EC;(AyQDj}XakD2V4k?^2N5U${L0(m=nb0KJ7s@;C>e z!4SzGC_tAXk`F2fF2^1P=r=_2Aq8kUMDoW9VmB!FR{+`%k$hA^a2-FUAbDQmb^@Rq z5lL=K09q1}+@}D2iAX-J0L_U=KBFK8K%Z5BHbo?Vt^mD?NOCy=Xjnw@c?IZNL~_3Z zv@RmaV-gU*1AR#Wni!FMSwV37aQOl11LgJus0x((4M3%!oCZK#C!7XA?8o^7i2E?- z34mrtB;Qqljz=W_pdda1<#Gbh`-mi$2M|+1Ij;b5d;Ud%E&%0r1)v`i$-gN;QzVif zDu^CXju(LTNF@KMAo@W+R)9uHBtKCQuYrE50441#vy7LjjsBkqRq7rzKLw3gQe<)HQ>C1zM&c zF~_9J6=(}+g#w{`sY(T6ziI_}0%(l_oeau(1?W^z&MP3tfz~U?Mo`odL#_gCP@v;M z`57SD&F=to66kmZIuR80&LB<~{hI+joJdVn5UAr+y8`V8#eC0@i$FUSpsy3DE(O7~ zM?rF4CM!UjCsHv5==DSjeTxANpGeJCfUZxZ<|shxCsK12#3axo6zDwAc?!g3ny)|? zfi6&>i$RZ6fW}ayxD5d44n=CQg5Y;CuQQ1A$z=eD>yq0ZAg<%(3dD7}LVMc2jw;Zi2DxLJ3s+Yu3vz>pj__&IYGHS0Lkfcdjs?%&0C77g*AYNhf!?4%L!dhp z=vC006zDb3n-zHHW$IQ1-u0QfLjf9Bk-A#}x>u3fr69P@`xT&%6{&j^pqUk^dljIg z6{&A2uys0hpMv-v=mQG$pP;)HXbI>~6rj}=sYeu`-xaAx71-LH`k4Y7%u`P&NbZCC z6o|*i(+boC`n-bVIC%^JvJ~_e3X;qIf`Tjo{iT8ofxf5!ZL&zcq=4O@B854eL3e^4 zP>^SVzM>${2Iaa2B=?2iD9{?vw-xC3pnp=3+`fNSkjH`kML~9f{#`+GxsnQ!%brr8 z4?($&0eTaZ?*V!P^q&g!Lr@;W0No|TAl_$CGpMFO*MiywblXBe~) z6#a}rm@@{^HyE@Q6z$HSvp_i?0HI9>f2%;8)_?-t4T?5p(2qg?u0St?eykvM(9aYk z*YU7|#JZohC`jZp?NNYzL8LK{FkopA=?(?h97MWH0oDhRo~!^ngh)?OfJH*2rzyZT zA<`T#04s$^&r*QBLZmToGhn$8X^snk4MU{oE5Mo|(nl$XIOt*pkp^9&z&p6p%M>UA zineCZcR){4Ak;@1?a7d4&{Gs(9TDkM6?nIF8tuz~#YCjnDZq9j((4sqMGje;8uCFLi4d^8bR15l51>&+?szChSWeUX4uTY?`gI=jX_kdy^ zXHY*VmjR$}fnKLT2S9I7paD?yMTRti?og06(3=!w8R*Rl5@RgQ=>d}4=N1KdI_PZ* zlI#9<1=yZMdY1z4Gf#8f0kB7j^p6!_nG$KPF90?wk$zMG)+&+CLSQVWpHLvq8{Y$@ zgT@tz`@qu*6asx#fiQ2RUs52hzn2w=>*F;A;_|(rKtBO}Q-Pib{j~xy{f&Zjfxe?4 zn?Zl4AbEVft01{AaoYp(9MF#yFR$hn}y3KC;%2-U=p zsLvr%kn=&Mfd7^+c#y-^I+D!}q6hUyexgA_yc3b00sp{N4vl47Vq0TxOz)TjVk zr5GBg0IQ`K8m|ERr5Ku^z$a3MniOEu6hjjgVBHi$XnThE5EO0C5NPM2Rs}SV7@DL& zT=#7X#BI{9KwJkM3dGMl75HS$P?rLs&kS`d5Z6CH1E?2tvI3n3Iz@ptf=*Q+^u3{J z3Un?gzYh?`<`BmV&{oiy3Umo*Oo6zK&@UNu11PsQK=*;7k22^7pmP=Ir=UkD&{Lq? zM*-qG0G2{{%f&fj$LYsvx3q`% z=2r7&^TXy3Ev1$jmNk~`mS-&=>#h2FeV0C9t+B4P-fw-=X17hVZLsaKy=-r?Kj$cS z+~)Yu+30-O`GISpYmY1KUgh3XR9dvC=!&Api_)GZ&sxu8-l+FHpT&2+e~JI0fG@B% zaAUA8xIXx7@U2j3XjAB}P$GO|_`Twq;-`y0Em>1)D&0`JxAgt8)n%#j2P*;TV1VP>$+ao2@6ix zc|!Wc-V@(FY3WIKob=Jj3r^mA^5d&ZS8rW?|0$MJUhMVs#!t1Ly7JUrr@pl&w&vzF z@13^(wEIu{c}Q;{-m`wy`u;QBXD&JOk~6=1<{M{4 z&$|9>_t_iI{@aEp&uKho_c{AFij8d>S8cpx<9!=n_|mj5eYk1WrX8D}-SoF}qvu|9 z?*7fwHt*Q{?v^QA&foIZdFAJAJMX@eC5VVFdwl;=E<+Eic^axpmvEFW=_7?fl#Bz3rph*WP~L z?FV+Q-no0{z&B=m==JSM2VtyZd%|cAd2Awr`4WZusVl z{Y(4ry(e(b{r8@K?|a```K|r;O}TIReQ$hw)wef)yZ_sn`+M)-c>neHKY0HiAMiXd z?Sbz;@cM4Kd-?90cmL%(t>3x#yUy>e{N6j?U-bRUeh~e^gAe*1yyC%+emLWYn}7Jw z58vK1WzQpf-u+SZM{9rd(L?JWy7$MXAFuoI;}1`JIQ^5@Pj>z!@yLQl`XBk=r>lQ@ zV6SKI%DwmPedp2Wqh~#O$D^6YHa_YhAX7ZLWrLvwytbT;4zt-P~x_ zTltMlFJD^?kC?hf_?3?6->nXZ)n8m=wbm5#UWefU8KZt!mWr_xV;VS;lTea^+;@6A zqUO)bYj_CozAVZRXx%GrBx!D{$r4_{gj z;liSYazBq0kGZd}t+BBG)NB`` zUYkCk+l)(Q5B0M%)63TaH_gulvC%D!{E#nCDZ=hyG2-4o;vC8IzQR0vJ3G42TSLf) z1-&;K9+SthdF~$byfAN`f@~IMxzJ4;@_D{yBy)v%?i=wQ$@4+=%z5Rp!+AFcb0bdG z_1HYuqhE79Bdjr0DPq%yg;B4#W(E#d1}X?uSlL(Si;&qjlG%S<*Zwhet&ge8vH2cb z*Zs(-k!{ZWj>A;;10z9f|F@NG9sX?iDa>vAAgvq)YsAU0>VFBEic8VAjVjDdSy3B0K{Nx^9dOMJ6BWu0(le2`%xv7VxC8)8+TOcCu?PyY}Y&lGQG=zuNtMyFKVR zHxSz6@@Eck8g5&!B7LLoBI+(S>KQsTWSil*ycFw419Y8S$7_VBukGw;q0wu|RP@-k zuFiIKRXx|7s|;iI%}+PAxpf2`3>A*S%&Un%AGo%&JuEkQ+-u!|rrhG<=~>d#2ehIZ zGUG6*HkOxfGiyD@+}XpW&O7(0r_**ct?k_qKrCvli3iFXdwLofHa()-HgOb<eR0KPNB4exD9wXYY0BU(KYqg~B0AZCglpQ*DE8iK0fjX381V z-Bn2z-J*Bp9iea~`j_5Jm_aLfo$a1M?KRQ*kflh%-_lG7+l_a!jwt%$48lw3O%2g5 z1mzdP-Cd!uUSr|(khT#~Gf}Olrl@LyL-)Ad9^EmaboCtFtu<*T%an2EaW&SETUrCI znns6Db34MpKugfB+k^EcpS>tZLATv!GC8eQCv7?C4O^h_4cq8s%1`2C9?iXO%Em{U zF3n}du96a0xZGB4GFy(0(i_sf{;*lPLtZIeW{Vv&p+3v*2v!ChHr;A# zIyk5+ToBZ3rO|QEH(t|i90U5QL_5W?_j{i)8;I_9t|U};7r2!!v`$SCS+II>+jNew zI5WTrHIoICayXb@;ex35hJv@yOBEmFia4Tm>o=^gi#j4!i+QeQ*XEin)>`+3hSm;d zemctQx|d9@D_1wI4HMk8BjKnFgS6D|@0}E_jpA=o5n@0DMGd84%aaBNWVW|eHT1~I zja6-Sv*GikC0yE&3rG=uztqobjT{~x{)lG5CLUlLSa(CT19Mkf6?z~pp#X|ogHFRk z6-93_${)akwy$m1^{^h$dwX#S>-u&*P^P>rr;d2V;jM>s4h0fGs7DX-VIBpeVK;1= zMjll9oOD>FkF-1VaHtIrkdJ(3EP;W8;yO6?R}RipHlKxAADf46-BQEJ&P0*36%q=d za=7_Xe4Q^ULti8hKm0;R6i=WR-R~sgYY|{A(iPrq+3zhK;wFU7xIGj#sG`Pil z;R|}hAsW8-pmt!p8vea+v?&e?Tqr~QfzVOSUxP`cTpdf(OAE3 zUe7}v7m8$JE_>q+_ulrrRT*knQFJSa1omXVuqG?;qMdu;i zv1ys}2_aEGmhPw;2%!;~kHm=7FgmiHkxWn>XJWIdFcV|b;^O3srnO^IRRcc?jy5~F zj!Db1S<^OKjEvLXk;D#FVs1Z{i3;kmTh*XS(#*5^$UKk4nVl<;kPcOX(bZUxo6%`O ze>|$qidcT;W~wNhShIz#DQvqP3*2^(-Mv5$>JDAM5)n=R`Sy(51D^+pRXMVpG!V>;rt{eUn zKS6FX((o574`?<>KY39VTDK3 z@T`_y-ywxSmxUgYkUw!PqB4SkO=7sQ+iMlUqsO>v_K(1ihLl=PkrVfXb`J(hY4Dw?2vv`FV&icxrCY!*6G3!#+A4IDGi>v=9E+u!S?3!R!6DL?rCpAoZg<3v zCA^vW#*&&PkMld#EiKicA-DVfmSbBDpYBMcySl{hsCD>CLX`-Oc&&D`GwiKsM8bbl zJb9lYk4vrRj72_^Jrp#BzBJc_7#={}Xm5%4NG8s1Ez@<$dN_hij9?|3M&bQ zxCK)QYKXNFGf_{*#MT0Kn)MPbY!w#$r=87{nSGqx-1$mn zrN^_Tq_yOf%z&Xtj^LW!ZME)(@NBBAwAoiqY}d`Z&3XqWEM6n=MIW5Iaq}6W?r;br z%Znk!OJTTr)U7jaEAjbCY;mW9DDQrt-zt4Bin)B!+HbG4kG|zO(QJ(SKInsj(8af4 z|K}R?pn z3)c(F6*;~%$R`4`BStCgF>hIPsB}UaYj{vc(L&B>W~9_roEffNx$KYZf=XxQvO=!t z{K&GEwM50P(#+fJ%nZYcG?_mX(9QKimhoe^Tm8Hw zk#~&PcXE%SrMOR|53PDmpI_h<8ph>* zNo2n&WFC{t6H7@#n1wD6eY&A1g6?*sE}PvC>ZDsC417++9;v zeay;Zs>`a~(W>hD`s&JP5pLM4yxQGhcvUq->@~GDRrb2*xGnZbbzP0EVO+G9_xokb zVM5RFpkGvB@9+fPXY04<;jVBu7ePmjek3PojhGR*D<%j-vUE*>A< zHFFtNl;7NBKf3$rnw71lj$Jjos*Y-;%CbVgc}H{}J%JvvHyzz|^{x(6>&lwNokz$C zUoESoWi#c$K&BauiZLO3MIipcK&rLdUde+uqn;W^x`WShfc1y@83$#j8*@z>194082Fsz{+;rDetLKH z_5ClW_qp|XA5Y|;lb~w9S>QE%n7Pq@^=!wf?W_*gX64`tSTC}iygA1ZRm(=ZyEoI< z>$bPT0Zw~%OADRS)41F2rbxfrzC9MB_1rD@$NAChmcGUww|%{`Uk^ZLy$4#m8mti0 z&|_HW8@+`A+$r-DI`q$w)u;;=&u+)C#FP!AX(F?mjkH+Tyi!LtV#w0?cG* zC_=r+FamDk>-ai*L-D26Ew9*3C3|i9ff4ifh)duf&&5y4S>W@%kbbdCuG^3o4H>At zp3M)IFv~qKDZmugX$B|U0On~X7=$XIJ10Qtl`}#vAKoqe=r`K{gkIy_=mrIKp%FF8O%l-_ zcSDN>!Hfh7*la*xd$SIt*UuQk;OEj{PA^`Ghys=mv+L-L??s z4#NTpXHGX{6ho$A`_N1ZvzW>|EMzm8L*ZKV9b+;#L@+mX*J71y4>!whGzB+R3mIaJ zMN&y3IEpu9#U(Bvm z%r9186meZ)XC*6zyVw#NY|o9x>jUlaHq9cxVl`hPWum&yTvF^XZ}gRx z)|Hn2U@LlrQ=g8Bz|&=RmK2+2S7{b)o$mMG<6}~LS=?pNh0=@QySX=8bCt#;}J!|BQA+0PNJlt~v zIi?A8XnqVvw-SZ0OrS7ethWIRO)4p`i}(WGlE-*LtghzkvyEj9ZP91vhTTqAdCAe| zIs?b9sHpM3=x(p7>w&^XA|Q4)VRsUwY^!5VQ$x=kx~0@xS`{~6T2m3M!Bh_0{!{qg z-9A1QMzvX$nNq!AhK6Fw5A9gvmKx3N+-?Ii0p-{Q&A4&vd$1fuE_3*uwuHm;wA1IL zR%bDC z|KZClz^>~RUQM@aUX#@pGud?$_2R^j0K2nhnHy z1SMnr7<+DT%zYS|JTyqPB|veoczbzg5G}wWg*7u1H{pY%m<>l=KFj=pX9j4vR?!l> zyQeV|XZFqVw_LE2DAFZptk|rW+Q>}c#ICP z=#**Qgs@yjCCfXZWvfIvg6UBU_BTC6 zzqY%tvC!>j=x*5~P3D~uGH*D;Y^KOgvk5-#GhOzx&$hc{!$S_Q)@3qvX=dwN zF6678^_pM!sJ}ND?6v7}evV7bxaR$0d6(fYgp>D1$Uf?a=7iUtTI`SRM1JSvD^$lr zH+y#0Cc`}?Z&1;A4&#X^oOAqdJ?evefoYZIb4M%dGvmwUva+8f*$$T^4g` zSEoajzRJ2G6HzUz%a~3xlsRw#YH}-+g3ppT%cdv*FW_*=1fg zPP0+@SyN3?8@JB<3zN^%U3_GpZnC8}Tof|%V`-XtRyo=Dv5Wf(uh&l@&A5p1cNprK zO@kDNT4&3$B_|12Pz`paVfC0v*q;uL+UPoHRkkj-gXLj92*$6F#sWY+jMugE8utav>4CcGyGb5T>jz8j>>_`j&Hhro=C+s4%r<^ zGlP?kbaT*Y6%miG%s;i+cw~4rPxX@@ui+16VV$sA^Zl6L+F>m}8vBsX;qOqHp>4`8 z{>Iddz8^J?s3?^W#&WdtpmjelIH*9Z7Esdf|Lq|WdN=^aVUOL79!GIK^SrTNbIhfq zk;}@L`PnlrV*-r1jnIA;aWg$QTEp?)l6&3UlXqx7A8VNMw;{Jd-e9~CY zrtr5(>%qOEs%n)`Ji_H;SYi#wxI~fua)g zma=+ly|2>aFAwwv${WU)w76~1Ra?y^wj!6uYq9v6t(xCc;jOjSmu)eZd}Vw%Vx4D= zgvT2^5}%FX{d7trh?7kPd(U{+figq#mI9U@xo?m1C1D(x!2y{`E80f*ra9`YPigJc z8pF_7GnKX)$7qa8Y-EetUUi};mJJ1)WVW7}&)cVLu&`Nx)n}~|Cgg^wX6OTq3dPJF zU)j+$>9|eDP3r1gF}}+ko;o$`?xOh7$1a~TqqnQ8cgB?E$7XKm93Lp36pKwN4~)mQ z0p<;P-$fj}FOTfwv1%D>(#VC?oVmz&X|U~%qDL*ToVpck)p6hWDal#CWNNOB~bj>-Hq(g zsIG21^gr-!H4LwzR`)~vdhV}h2M6U#Rz5TIIk_`S$KV@|Un=CE)$)hB9hGl0?nnAG zc8iR;uOD;IE_IvJlqIldRUB%M4V(XhB;pf{qaJ63dp-) z_A_GSc&T+g$H$k8^C2(Z&3?uu?{{V1H4<*r{HSKfW%z2_7I8U$bD1FH@VTQxexQ&u z;B!`Q7Pi*V-4VB3fDwo8Vc^xRjerOEGbN&Gd!J-CJ(b&T7%La=fx!({40D zBsJtHL#|eR=-(@gl8SOesr`!;0|pS?yq7OuDEIM^o{?_@)(3FDkNY>v$kKG81dqV>`cCS!U^GXjssvrg3@l&M#E3>&L!jMDV{>#{3rHd|w-T9HHThmC@2_ zGI7sqZAJe<&jTHG|Ah+Mf0&nZk@5Iqo+Xa)wGWa#YazzWQ)(6;X|@rUnyh#Qa~4b~ z^ytBJj+vkH#62=AG#zT*&^bRA+cDyn;9i4)|$aC^Sr9o-;OSGeh%(7 z*i3$=74FH09#O5o(57H=&Kd^6H&_fAEVoje#agBFq{&7<$}D2{wUtuC$wAZG)x19u z8y~Srv96)=*DDHN}c#u-a2;l9Ag(Z3V&112%mU8z;M>=3EU|XVrgflLNC>3yYRfEa=|T z-B$PP#)}$fyRFy@BOxtU6#200q7|GNSUC`nuc!iYwA3><=+%LX0@Zp^Cc);8(%K?h z0RR7q7O)l7vZAm!Sl`@SAGBMFt+onZYq4*}2oE>ISKR8Wuvv>OcIgj?{n4$^sMNX~ z8Y~bFS1oQ>--*&r263p73spUDY3@RuyX>}0Egs9IHam$DIN^fg4#D{%_ThV%{0{mT z!t(*HP&^lkW@R!XZ*yq%&Ue&1%)OvaA+lPcxmRWurl;nV0n91?BvzOhTpDwKnY%B>oOdzK`h94%(58_G<^30%;9pc^%vS|*^SI|6alFi5X==VT zT9tMbMzBrOwjqMZC_Z!THtgQnrqVko-(%-O?BZvGgQ1*k9bs0>`?FDxo&+*?eO}y! zc}53|)~f}>SPKuEL(d@+&9@KwfsNY~mOb7i%p2D&R9)DVy}9P%cX-}^(m2Q2s_cQ- zGZ!ktFvg6Cd9%9~(j0~nk7BJrmapQ|5xfDlVMM#32AMH{=%1P2Sg^C*EiFaf>gI^_ zz3Qzk4ptF)T=V8}=RU*gk~X@=>DF4LYvTk%w=rSl@Md4c=P1$3JmKm{i`UayO;i>1 zlw0XIW8aj+I??AiV6*qBl|Of0b8LB*b1nRj%7f(tO;O03@HFv%S-LY@jXedetYsc? zez6knRQnH&2nw7SOgNAK1pfcAXLt{4Jxp}0&5GjWDH{w76&Ehq&FzLo0T=AMU`v9b z48sL)K=DAoY_?lnGx5Ksxo3E^GW*1dwsOrg!yPdBX1c6=xZ-o3#wXg#3IeyZ*mZYd zR3lH_I!9Ib6nrrBW^w4#_ZgNK?C|Tx#sN&R*$wT6ij{Y~u=bpnZ8F5=ws2>)w-)C% zu=x;LQH-GI0h1PN3~HvT_DW;>TV?w(Ffc9Y>7h3>eSz}oD(a2(EvmE)VbSO%U8l;9 zDt~#ozpA4$!oimGP^==@>}$&m#A2nE#j-p*tv3R_`1{G5&1Al5 z{o`g03JtSL&`7HeXYA+lm!%Jx;#fg_>^}`|RS2n$Ple$@``hd&pBOPqnHpnH_+!7&V$d#>At7_azy-1TezK zRPgpqIF(bqpa-kc1)5d?va}lv`NnFTadMB%Ek$qus`|(tO*3LzG* ze%0?gp;vO?8?22O%zWg5&)wko6dK#jRz5z4Vtjr;aj)H65Q_ZKtZOsYO~dJYn^~7t zkSb00EHaT+y=>yFjkBh&pMfV2|Iuomwr+-|XZ~z8H!i9&k?EeBklV`0tc`seW|?&J zA64JZ>GZhI<*n~f?3oW1UqWq#$1F2{-D@_puKc!nxIihs-sCPg*Z16B{0EI;Ge0$l z;arbS$LmaPy{A?qd zyWpqrfRIgCu_X`VT)F6H>ejBe?c=Y zUfi4E4(IL>NY5gS=MBO3={U&)FV>H?^D7*c4%&%e8c+{#+-xvo7_T8Z1PQX6M9lct z$Jf4CCeD=laLKTX|HX}KAFdo2l%0LCVcZx_BSfDH7B>RLag%)=b9J8)EN;Y_bK_M6 z#UDIk#4b2g;_&Fp{@{$oxW47^C)g|VbM%WMXo&^BvSH}Z^N!!qW~PNU)1n{{h{8_S$+hR~>-{lQ{=C3#lr#pU_-rkSk;Aq;10jel^^U!&%j zr=T0>eMTL|83n^uncFb{t{s2iVv#l8X<+o_O7f3c&?qM@Q*S0-9GL8Khp@e!EEQ(x zTd+k^>gHQIR&@kMvaV--W_3C}PUpZtOQ^wKVF|n29A-z0MLMM{)2zE7440d1ddI5F z+aud!XbHdKapuNZE9AHd%-K|9_YwcF86c}$H3l9gNesKZ>~Cz`1xq@ji{Kh3>j9h7 z=Cax%T(6Cx(n<3sm4+~`baTYx@Y?k9%tuCzTXD6)bW#~@HnL*jAy)jdH?I;jTZ!&M?c4=xFxo$O^mO*lM#qP=#46_~Uh`0^*LAsoSIqXt= z0sS82STz9KU||WbMeoTQW!f9UFtqYm%x@;i7Xf22%kIO))3z!t&I{(Z=XT&QT|jS- zcIK-C1y&*R4i1j5Td2Ai;gLo~v!6$IsWdq*aTwGj-8JiLG^?dO#7`tNc8l|tymr&#F|12=;Xg2y zrmCv!MdG&8VzXH)k8>1B{3~)0{=-`QtHlzp#&7Oy-dMguKjb2hZB)6h>irqtXYpG7 z`nq*`z~Z%9uhs(vY{gIbLnzo^ho@E#LT%>-kNJv%^hSNNp&|c;f_%c*e(;H<6g{~{hQ0Cczu8y(kak)-E-D>qB>g{^r9>k4!D3kxB9VF7*w2R>uKJQL!=w-4&^?E@4<=^`q5I~#vo zL7lm;J;aNz9321HxYYT5KE(mOL{`ZWpo&98_QOL(HmZ#38#l~vtIvwD609wG@M|>v z5YemliDR9OW9I~R3Hf>Cvl_OWyFx8G1UC^jH?f3Nuye?Z9=Ub=wDI^GwwKyhu3O0) zGEVWkJTAY-xSnF8t(E+Ie1*+++;O~lV|8YT=fF*y_)3n|b{tGKY)RNJ6gN&7%mLTd z@VRpvmLC|T4JD>Qqx^+LSS;aR52j5SmFU2xoVEfYs&a0!T6s5EuQh{Dx@|hg>X7H0 zvk9LA`^DULLy#?ap?$8Y$ofGqZ`0}hz*=T~C`uIP07=o?;W zlss!@8v6{|X0GvI-;fvTCHK6wljoj08-srG+IcRG1u*WHxj93OsL!ElC>*SXLo-{? zMmzH^QCLW*);NZPwW4tE+Q=E-k8|EA$U22zUDIxSv0$6hx?$~!P<&_W4v48%){jp z9Ej?t4F@@}cq%J`f5fO_NX?!9;(lz|GM}o#Wlu7XKG1yaVL#+*JUF=YnVqWmqt7|V zm1oBIGOY1&*Cl+uV2n$Rk$l@VqgF=QQ@AS7^Fw*lP&mK%t8q(xXovxBwQTdnRnbW-tgodlbPO@>I1pTz%gNCTySF0Cl%qV$44P0aN&g`!fdFZF};B4<@nA@F9bpg!DFI*{o#21`G#nGdCf0-DJ`b+XT2UAeqOlU`}o{1YoHCcFmO z*bfFL`>0e(FIjNBtFoeLr17`_15zt9L8|tJOX`|Si>XA@Dm9WGDs8TizR!D@tJkQHbzp0B|E8z(lhD;!h=Sv>(}TNvg_Ej^7D#leNgEu1jE zt6_EnZNk>4DL*<3T9UJLt78^4#JX*k!}?pVud&Bd*EC__1Z&a47KFs%v*vlnoMl3| z0OnoH!B|vPJActU>7#Zk<%|P|$sE8Yt3vR|akf9VFAyzq3hS#FnB zbCzB(0eLv_M2$=nFn{bY;m=MB4QewLKAY*qOY{a#3*eh2=FE7rd2=(Ct0hbDTC+*J z8rsOKwJd>0{)v(Q4EhAim3~NTSoisRB;ZtxZ*1rG!C{u-Ri+ba2$arHprAS9IQS7U zb_mvHaJI3B*7FP-S&|VRm&1+&4-0H&yTcXhX*6~Ry6x{b_7H#D93Pyp+e!j~5}Vza z5BJeO@c(J>Zhd@F47JAU)fSwtVO;_nxu#=|0u#u4F~L%}yVDBB*X|l?a+S)G=MjiL&Z%6TWS}#MtnGapx?fAc7 z{?7mL4QrTDPG+H_*dZS6Eb=o5TJQ2VoOUX2*w_*gD*osF^wNg zPL_rc?_I^f`(LV0y$gA2h~m&TJ~RQGR$IJ!MMHYfB#ZfB9j z?DLx}MJ~6=ra5#dh>A3=2wu)s14yRe)Nm#hl7a;ONHL5;4UvWkhs#5nk2vi?JojfqAP!>k%Z{+}ir zb4bK5O!D{h!yHeI)M3|B|q z?gXnb$F4peQ6fgRAKt2wM6hh2r*-BS`La-%5VzCyR^Ai;Jt! z2n!Ts2n#f=(O*dC$x;56J>TSy@A+7<;C*mu|7Le5CTCs0v` z2Ya#;GdQ#NuCEhfCKkJ6#f~k)g|oUV-&=_T#U6z(1b4qYOLwmP!`dVKGidEhP;8rq zSGNRrW#yG?RN-nzOoPBRaZ@V-%PMCI(_LXrwclq5Z!zaO1(K z8N{@ZhNm+b%LsCw6|zv<=Q0U&A1t6NeJ(4AUO16JJ=?yPZP~2L>GJ<8;=y>~qOkS% ziviLt8NG-bibMM!6gK_^F*1ZK@7q4}Jf2Fo^%E=rn0Eq7kZNh96C<(P0{VxqSEZ61 zN|@e$t9W^rdTr13iv9pxC=GA_X8-M&GsGVQ|GNmi82LM1ihgO^H%R`&VoN534s^b) zo8CB$tQ?+Zx(k}p=;(ZWEjCz^-@6x9Ytp)t+e+*Iw2LavJJ!7Y zpilTN9H}i6zJ;8x5fLUd4|n8RHc~L|CVA3zX?r&oB2L$7j7m+6Q4zZv8m}qeyLV0W z?z%9A)0lk+@6y8$Jxv>uMY39U^Rph(b_S*=7gY7%jbGR=aHW~_cOeQJ}BrR)*pshlH(YL{BNWfg>s9!i1y=mv1o2$+W?Hu~7Q@=1p;~0Qhmh62P zyWHZ*T*Gs~q$afBNih>nsXgc`C~&C?9xaW6N;^UAE9)h>ww(;U4-%LQi@ z%5oAnX4%55fdSotfU#yiZdpSZjt_;CG!K&DhcM!XEDHzyd3O3V!;Z!mbRT~Rp6xW& z@_e9(RTEXA+Cqf}@RHD*L;O#q5_)|q2KVHDIpai}&>1Ufoe80ICbG1&w7kfkH~>`m z-#RJnD4;vA(Elv};s>-nv+TeD*81Kr?0jz^prhZO#k>9oD0v;4y>aMUw(tlLG@$Vk zqMtn^MtT(>@RVN%%&`VcrKm*=r768W-T>UnE2Y>Et_xW=hC(-5q3f(r(7e%gj~;d1 z8_i(ogNF})czd)DtOd^f!5y)U0kmY4%X|(`~up}UvnSj<8Vu04`wHMMFS_T6PSS5PzpR!$11@& zQgYyhc9O3YZSF(%@eu8BYwSryN$*SFnbC>K=-0JUNkecD9O#)laY0dj?ek(Tgv9O! zOg}^i$wE7l$=s14Js;r@OC`o15RKqu2Ktm=^Std}4v1-a3;oJMw+K48#C@T>IGA9! zfhr&ch6wwNF7b}B(t-a5tyyu*mbgb@XH(g}`GL*bEBu5gv$u`JOL6>(-90ypqnpzq z+YTLHam3qJ_(@WH>Psj}?f(z4slga@!Si59U3pmlDMM0!m)vMB7miq$E3MBcrt(qY zOM~6d7>jxm9yyoev3Xg(T(MfuD|jS#)A=Z#?$eegXdgve4KPnLj(BJwfr7>mFGrM~ zP^>bd#`>x7mfTsN0RlhdE`bvCweTdaj>plMAYce*K$!r6EiGbP=-dyTY=IP?VjAd; z*}%cTbr|VBg0>B%ML<%BWnjB7K#0vHr59B64X{IiG_pEL2PxH8hqkR+y8j@cT~^RZ zc2=l8KO=l%mi0_CZ2(sY1rCDkMY#P%@pDOk zX_06s$ILDXZRnhERe3UqC<3vou8JXmKrmglk6i{2ji#+G~Bcx#!83Z3eu?<&QEY@1b+G0q%&^DX_*h?`pa;%AM>wmA9>V#N< zFzW5R`Og-sxz0~o-Yj1dlYD-~&N~?Zd~!{_f0|mqrpo^AimJb2ExmgA)#Gbur(M_7 zOm2(#-EH+H@xGNW@`)W^f6y}+?;Ky{_tjpUd)3}*f9~4eYF~P#Zu2^7WrO&=x3pgG zt=nxYPhxsi08H0#N zm#`r{9NEQAqn)>cOFIuO9Dsg{FmLy9n z(jEE1Lx%?Q-|5RQmn-?dHCel}!`AZQ{WWVVeEio?TuCS!=Wrt~CduHL+jt{4^~ zqTH}N;|bQ$a9?i}6doFHZqibULsP?FoZ{FtN5*vTjij%UFTi$iU-4 zHuW`oNlIEGq-in=j<7$w1qe`kcPy+1m9i#jHF)Y^;gE`x0LG1!Z(ea#t&6LDn{6vJ z@a`21sae! zh!21|1PnA-1k#hJC4Qz$q(xFa)E&1@qKn!kA+DT3#00$j#Msyg?AfokTvMOt)iL!; zWk?b7*ZKBRoP$mP&ba16v4|34D40!ljBYI=Iv{>+kdPAZ?8OqwWsoPizgU#Vz5*95 zV(IWeWqO_S4d{|Eg6!613J>O2Jw{!Dl#L`Lv?nyH#0|BoJ-l5G8R_ziNr-w?;I&J=KPUL?lY zpk<41`3HA2R~QbaM)T*%!FQ7oM#2=)K;l^`PSF0qG2)T@biXhT0RB0R(E%--uzzVa z%mlD(WNamCp%_d+Y+y!luSpt8A}s@csaD$9WO6(KSB{5~nQg^1X91{Ey=a6LOS3gA z9fN+z)m*Et0eQSVo-SuB=pM{;OzoWBflSRTTr3RjpfIAXkJ5I>P=Qkdwgh@m^qz@m zglvbaTb3SSjvSO-4WZ+MP^!hWQX<>OR$KxN^e?pP84p4O98IPUH4zaRZ1_4)3$R&U}b2O&eTxN$L_Uz(#PZI`q8s_Y& zjdC>DdRQDh=OSLBw`yT-Vtn|zM6!@T87+)PP@n^dEtctSRbfcjZ@YDYFM38;it$Hr zSHFsQgrnp=!r&bO#WJM@z;e(-Qw4GBF_}5}r71*Y7$QBHO`r|YeXf8Nhv5aR7bDr- zzgQYQa9=@5DA`o19!Z{n?_{(vwB5FLUId+Zks2Ie0+z|o>;-pR9q*~VZnU&TIkML> z8`~x}j@DeaPjdBqEGru`L+1}KHs?*a`#R80lB`ViCEL)D@E$7(z zZHxPK;jM?2$1glHXE{gk@JHZ@{D^6VjyP;1)VENjIo8AD;lc3u!JoX4h!@iFNQ%(f3F(N}ox ziN%iSt5^ek-Jtl*+RNTzLBBqVTBiwRmgdSoc({56QXA5R-^G4GT%%K7k^v(EIG|e&EdP?vUVo+Gg?SDTqUTK$Lb-U)>16gVRc%^@aml8oN@;7Ps%l$M1*KFk*hmk1eTn74zHkg zL0i1Y3@-Bm5R2$*Vz#syEi{1$`M_oc;`XS()wbRx_Df>Nv9=tMi@SJxKOH!Um{%g! zV<6TRhQ-6m8b*&0hv(OM05jHomq$ZMhnL|fo;D`0L1H*pI6<3-JWo2Up~85LHX@T0 zsrk4%hgMKT2T^!l)0jv z>1n5UrS59Bt-1P@MJK%r0RF?`_%Moa?2!&d5iZ?`9zs#HbK8HfLN#YyBa7yR4y7R0 zKI&Mg1*yK}I`q~aedwzD^a_9ce>;#vJaU>2X6}HNPv@T&R-okhx@*BgZn^sTD^1wn zpGoQ&njRTFIin^L;~%1f4@IU_oBR@N6#*(Z{iY4+Var@2MVCsrcz8mY$6=(^aU zL^FhD4D@GcYu?=KKV%A%gof7T(%n|t;Vo&s^;@A>FmAnbNHxV(Qy;#^iU+}XAg=c} zXzqLi0E^5KGirp;ipJrasHv|iE4m${t1(+w%e)KtJVAS&W(Ohb_F@E!8nkuL^;O4g zu`^G)=S=KGMhCd&)F#y__qFhx~feC~EBYmZ>>4qK(iK6Q4-y8&Z?{{7f zIFwX~-ALAg6OTTy=k~eZ!s$hauJq#)SM-1Lf!zR85td*XIb$Cs7 zH(Mj~hA6_U3yms2AUE%>G*nv0u7N=ga~w=ttN}0ARB~`<_;vuHG(7jclJu}we8An_ zA4vcY1$Q(xmzjNYvP4x)N-RP9LaedrqTT{PSgHm`x4Nq2H8T~{lpf8jfS{@BFk)M( zb4}c;>d*wMc~##xIBYNj>J~nJUj7mI!}p`jU^j==6+;^vKM^3Yb>Qt(GSIcvlo&wZ z;b|0MNFRk4@SKjnxYK$BK|!7;46}cRC*ELb4Er%yU2zZoVa;$pwDORWnF`u3^21S# z;wsTNuFe(8Ufm~ebtJl=(D7`nUpY z$8im=q%vfzC22Q!7KcZF2A_|}!zC!033QlD$>(~jwAs+I(N-~<)r_-dsbmhW^J>E_ zrBWrtWpjf;xAploZx`*q6gUMsX~4fu=#vR3B76A|refkFPYJf`V;}*$KnEP_S_EDZ zd>4Bw*49vnhzkOS;6ECt&taZD%5y+^JUqES@=%>*xkT4d4>y1T@cDL-eYmV(h4m!@ ztS_(`kZmAIOv*9zU*DVF)F<4#(ZhYW+|oyG;p<$X+v3hq{DkfkN9Vq;`-*43SYln6 z0UDD+NFmYI`y4E?7z7@_LL-qz!YW=!3{erN&*OE-h(lv%h2@`uOLbZJKk6X~I8cD# z1YOsd-Hi+Q;49p@;wfG~OT^ctD9;If1~sp64{Cd+CK1mC*&!k&Vro1aIk)cePeGv6 zCN<~}F^!O6{RQfa1i$%GEiV3VFnmsc}IqrpAFB zO-<`{Ey;R|VfTs)_QUMiw{?@z2faXQ-{7Ds8zCdEwZ7~XCI*K1O^;N!SF@RTY%mth zWco6W0vCW!9gv4-M%nPt`N3>(`@kj16mB{;&`fMWj!p{?V1MKl&JXgNLbz__G}*!v zGSTeTOs=-^&GqdhJ76I0WOoBySLE@n@R5+m(4+Jr1Yjc_q@O|@#Md)#HO2)CSQ&@y zFez;s+JC`k`6u~>)-qmM-M*hTySH7o&E{`TWrwysbN9lj3q5C2Pn_}GEnSI_LTWa&`_$$`$2M`2^zbT}%# zJ{mDM_QoAx`y0642qhf?s^50llF)0nes#&9RC&gd z9pxhOQRIuIwVV707J0m*QMgv(k+ixYK1HQoL7)lzuLJpjxIhRW(V#SX-W`nz(HaPS zj(IH=7sk?e^&6p(afds$yBsven$0mISl&J6-a%*k?@Es?Y)C=prl_&hvg>{nNnh;8 z=7M`&*%&lrcW-d+F&pPT>bg+V5yAxVP0=jePDj2egnugmF|m{Q;kAf2sE>SJgO=~a z)aqkz1`{(vH#883V}b_w^3x>gP&SO?7Db)m*?$K z-_TxDF3;4af=DXuy5ILdX+_^u&^J6%``W&dDG(l~Ak_BogGc}xTd$EL1i&I-ekr*u z?Zw&7=d9?Ou-XS{0wP798ZH5~VP=Bycratm)2CQjGnmT-&FmfRPwM)hRtwsbKHfo9 z#G^X`FY#aoxY;cU%g8L`&p$sGG%~^bfjrK>$@@A8EQsBCKcA0TtkydyrV~=8i%|pR zA;mxF>NmBUY2fTFJ}!mH3&~-ctGMCl0ZxNr2#V++m_RfD<7`3H8RM`0!L9#dD%&Yx z{Zv_;N&Wp2D}u+^j^F~c{nf7XaegP;$Lo!pfL&wrUm4pbDH8k;6OzjM`j{%6XD~(j zbMQXi{#f_L1ixR%M*f_mDBbJLH)2sR<3@SR6PkM5ZyZyLt64>$P<{Qb+`4ruM52l= zSJhBVMnPBnGcYfhRdMRZ^?Gvt+G})M+iPV@(CuG)4f4z-Tsyv3v-P{Zej`0=r{5}s zO@F0c^A%935>Sum4!&8pNB%X|(^JpqzxQ&Wp8|v246d?&-Bx#nIppkEzbyA3#Xo_S z2d{e?bA+^vG~*H5LYOZ2I?G=Rc891I$w`H@FnbSUW3K_rwMci3T;~_Z z*2^M-dV-dE^;BVHies%LyZ1b}_}b*eM$i)k#Awv?I4#gHxlXL$Xwar9io1fW0C1Is zLloI%$EiU0d{Uu+7IBPzyTx^a@gNvgvhjIE(#YSZH=4M`(o9Rqeu8Rzikk9iN9u7f z5#f}WK)4ZE(o@kMH)$&&HPjOe569g~)?u1^F>jQEl4jb`2-4y$1^bXe1CeBv@C^*U zs$n_(vd9p~&hQoK@n|1Q1miF<=~gHn$xRm>&|p>VDXC%EwA_RiewMf1i_qmra9U(o z)M*ZgzSOz3hoS(Au>}ZWjh6SR$#r@ajfa>~D;LhMgq(0F_vdT-a;iVo50ytRk>rD= z{@;n@BHMm#Z9o3j#X>u&Xe6|2w>v=pA-P;21gMZ|&2Yw&)q%*Wi?H=`(&@P8= z(gzZQMh+XoV`}AqT+7+5x~{G|o?3PMs+{7g``Pmt=KU(v9(-refDvb)*q{q^rgfVq zQs8*K5)8v4tRiMXr*v$+TRZ32LY(fVBr4bnQnT_5F?y|Uv|q^?P+o&h=|#FaPn+3x ziJx0_U*{L-D#$`layvc=3DA^7r=1|ZHaY}MS`BK~G0dPZT61>xi#lWsOuH}siEYdn zA&4kn#H@qp5Bn@uJgj*$JTn#PSSrATz~)O>7@jhc2r+RA2?2OUw{sm2f~_Pdv@}2H zpc+1V(%P)rJ=KDxSJKgtVnkzdDD1>T#c=NcPq{JB+s}e0HN$8<<5_BdEiZ*xw3J9y zqOd8H&6tkJWll(ua>i8YN7R)smL`oH3nSi>q28$)qXOZG&&K>%;y&@9S`d7BojGqK zkj)SzxV4$9Y+!Sv>?q>@XWXO)Ty@0iNg7UVs*1)*g(KXtF&xT-ixoS;PTC>KnjS3Y zBl)BqOXRAx++pa&jC8R!z#SeZhiiqNNTC=dj5^WtWvK}{&4i_LoTRl3*DaE@9uZW9 z??~6g;dYsoEA&(qzKmiuR?2^m+@j{9+40 zd$MQ}{lxtD^bEx3>_)tlO9DrLmAx6cjslEZi^z;2nhBs-j|@yjINAtnFf?rh7{_W$ z<_a|d7jbI$6zD9dDl(5Irc+ZjGBm;155IDLy$a|EhS3g|z|D#2dLoHmu|E$NoGm-j z*>FB>#}Rc)#5fL>)A%t{OBMghSnFG(Ima=Re-f|6;2hvS++V8I{BosU?q|p9m1xXP z%EiIzZM8}tyHAfse;6?bp!70iH3j83*sgcM$ufHeD&H2=tsxmk~LdOdkk8=3Uvb#VLgMvTLB# zL&{t`7)romT*7A(KxE?6*% zhy+1Z0U`{|{kgk1)jUHFHSThZdX8<()s5C4jcHA7Y{Qcu;}zqZk3E^1ELSGpc)+k0 z7cJuex9z?x?ZKKN?06tIWN@Sfmh{9`tQX*DNIQ~m$aG8#=;dLbJ=cDlHm;|p?L7r{=-q(u>J(-8w(&bfGVsMrPc<_;Q?tyHIc=_YB z$-N6^x>;D$-j(yuZBpS}K5#?v;K2^Qhux)Wn%a7>>x>)0fA?~lK{+_T$ZhRCJZ=#| zV(MUkq0^(ugufI4^%`|(oVBWuMk$mS>AS#pkp*W>X^j9&RvaP9c1rB;5czsy`V-7) zjmV-DvYy#}XRSZTw`>9y^&o=mfujk+px%=d1v#JUkr32U#}z1pI(NwVwRf=hgyM?B zJ~1`fdb?lx%wJpQ&1~Jzx8pJ%pi4b@Y!D~2C*?mf=@+VJLKZSLo*bvTxf>1Hf+ zam7w2qII{Zg$zlptyS1!89d9%IosgYL9-!-q}mCRZ|be z#-c;mYj#GFf*~cFNZ65{$~)=G8!j_)#k}r>vjVnDQ;F8B?i{caSVdRhy?n{L;ulg- za(Z75T@ccI;rp~M*JKYZ{;*LWj@aRL37uqHXeO!mX6($UJkSehokEa^2Nx^tghi4W{E;!k3 z5FX3!h?MKwoeM5-w%04}j%>|1TrCuug+lePQG2m);6S0vnR$0|^C5XU);l=Z8=IC7 zZBFi*EC(-whimkrV0luxdS>QoYDX_W>UFSEZvvuKM1$hMIdpwvf&^C%vgCYk7h}!s zu3d~Z1eZh`&)sN)-@dl;IfJ?nS}wq2BHjl&0VqcKLfXH`u^ zO3=X(hlBA!EFz$169^TyM064?xoQ65K}3GC6{VJsV?0jw8MW*pTzHE{Bvs89M_&#s zE_Tt&!v_`I>?pPEiC+0pTB3@5lS>p0r?q%270LGu%koh1x!kS=z9v)MDNYhrKf)+L zncxQlA_f^Y0*sRmcmeYimoZFyJ0@JN{*w%(>RZsT6x8uPVK7zu4{B!4yu&m{#7;Zd zuhFHLaj*WLNpu2!z%8-&B1$I=vKsvW_vi2fzQYf^JMN=^Q5xsPn$Ta$(3u3Ws-=j2 z!PT{1q1^Km2wXLR2{y_~GA15ik-Ao6-@o#vy<>Y@f4^_x;=MQBbPqHd=dtwrnZkD8 zbJMdpT3V$4ia(KL@b_Plq+LIGS(1rH;>krehqVT{&X_-=S7a+ZApis=gx#v|IzSud z3Y?4*GSGNeycsuiMjU>r3al#W*DxWCSlZi?1fum;@c zkhsMOfyl>TLGBVv7HDjXvC!fYTN<<``wHn~E|*Lf`X;SmWEs-gGN@qdHz_nYF!YX_ zdHZD<*9jUn&Rnq=iYCWgBGwt z7%v>}L3U=OhXHJdU{H{xc*TWsk0|#P`!B-?wu(W+`17l62#OS@+_kS}pVs4X{V#st z!m~?PZTAO!?mQI$|`vx^xtVUd*zg57%ooKI89~juu*x%SPFi=-| zqYjeAs!)o#k!mriZjgGXdaEP50AQ5mT_aT-wH{=Jcr{Vzo2{_%LZXWIE0x*4lb?(B zL}iU08pgvFJmBMYHfw(z@8U`}dafqprq3D1zTU~+ZNv5Y@HQ0o8JEOzJ&9^4R892c zVgn(bE7pX(DtH|gt8^Ut3_>`QckMQ`JFO{U#1Ec;d7+{KN=1whR@Vt&%AupjX?3zu zfmwQ@hE@Sh)xi|uMleZWl@8ito5zBN{Dh1@wl{g{R3*GLb!qYzhh2HQEZ=Unj$>oq zF82rN#t6UEI>ql}#XW}(?U{%Dq=~*h>^6YTS9~)%dVOp?;z+7pqLrfi zV1Aj0L**2nmsoRZ_J*7oNH4#H&AZvpLyCX~5H^`nXk(H56r!H^xTyxdh_nOX z2&Nm=>68i^ky;tYjXDMq2JTc{dUNX^bGbjZkX0Fh7LdkGQCwOBq~I{7Qjo=SITlB$ z^$#$8d@MA5^(|LVhyL@hVQhCY2uu}L?jgO{JxUnGo>)kZ$7NhRjQ!gzYxIzaBm|?6 z-~rEozyDpJrYNpT3d|Wzxdsn%godpOEGfhMrgh0DMvYUaLLt>wa}L`;psCikLOC3U z*gFLlnVrCL!w&7)qohLx+g9HW*9-tO<+rQ0U9i)wZ+8&SoR+)S>8JkVO`RAV>!l@oydj0FQjNOAv4=Ju$Hp%se=yw~33O;Q; zEDn@6-ug=)C^R)4cOS?{OFq7blmW-!2q4@6_(JOyS3q<2AbUKgo*=tjMa~O91zz~8 zz{mjAU*%?Z!T4e<;B!+dUtVbna7`gb35Y0`Vo$C@!b*`|gkus0CiDLxj-5*3u z&Y1JDdhZYqI?fIzA`e-NjfG)8P(h6&3PPAkQEHT^R82=R>N&4``J8Pd@Dw`(_j7FJ zYx**2>eajF?dN)-z%q~wRRaNqfrA{SXu5+wzUPBXPy*+wf zkPET&ayA8#mD5JLl=A--%~DRa?$Z;&ue&)pr>0ml9l88eB%OAD=i9V>=C^74kHaA~ zR&pMlbRjVo!%EWH!ngME^j0igMC96So&EHCHl=G?Tmjy&N!%BmD2o zys8{`BJL@t6jMXPEKW1}>3-Vwr)f)@>*nb{kTOhxWsIFixjzcc#kCa0BXktBM$lIf z(+*oe+Q2Dz($ss5RsSO4V@T$C78%&b47MZQlaFJ50}eP!+c91~u8+~du0$<#LpY(+ z6qRGqJEM?jQ8(}@6w~i9qIIyT0v;upfc73kn&ciX{D|p_m6&GgGp~h^K|$~;^iZ_V zQ#?l?I3@m`DIyW*xCwucvlQQT!rRk|V*%uW_Yse*HzM14Sj-5 zbX3a*AH?sr*0S(4<3yp#kFA6meJ72*Bc)V+M9Xp>lww-l4~Yi|Kaf?btDn`vA89xv zBv)ER>sapaO{9^gn7c485<=1+h};c{grsj8*`#dL5Q#aYI?9z$2nLS=Ct<4Z(akKo zG8DT~aS&sY$u&bxW{pi*Q-2Q>@3Q^|EA|~rakIe*D2PI;cFRY}`{z56(EChV(-16t zsQklN=%cr2__eJ}1hcMUT~r=Arke;(XTC2K`3@X~NDuQ8|E?tTFExzZ>A+zOBi`0R zjl7Y*lIT^vCOF1OTZfB9h13=)U!$S|9K_YX^mEeR05ncQKHnhY)$d*wGOrKC%b__n z1W%moM--)D&ZFtaz|FyR^`*}=L$P`9fPLu~3aKsqQu2~RA+r&^Dn1p7+P%o^gg`K+ zDYFIRs$eN4S^E_$q^930E2kS~b2$`afn{MOg*Ii`3n&wNM?NkOZH-@GHkL1m0F`Aa zc8wzA27~BZqAA=*gmR+=pvtb1J{ucQ7aiHCc!_iHupfbCCiFkLl1d`p!c+t5Db7oi z|1P|7_!CgVuP4|Sksw9808FYjpy=-Pq&e@0hf;V>(aH7bg4D&pQ@n!4|y$hgA&~;P^8%3wWw)S{ zu>CA@Z87E!HME!)9Kgs~(9SvE=Ua#>TqOmVss9V1R~uqvJ!WT3eUapX+Ba&nM-kt9t z#TM6SQO*&BxwQ;O+PML!av;G|11`6~y8|h4V#7|!F|56Ju|y8+1qoV|XBSGkf{RSRXa4K}j5Nl7o)rfnPzKxae79f0Em?i(;hj+LP-| zNAjnUjplSdl4kd(>|{0`&nE3u_QH#L{>ZYP&R=vP=EqO)Ooe?K)_vmQIZ4wi-1oae zDi91Bu|;@UO19+#6(_a>Jk%Ul8O)w0 zH;*fEHTSlJ6aB^wrulQTPiWc`ey?uYsGTY)?&;wRUl7QN!JK4cNK_o#dh@nZ zG$uq`zf)(1RHNT8S#j|)YhiScb>Fi|Qr?GJPtZ+lpBs!Pv}P={?dGk`&Zuc_)@i$FlY;T-FlM-l$A_8yNBjVpd~>qrf+PDbU1xGGZTR9eONc+`o{8+aoqGdOOp&> zQC!Q}Y4E&IJy~SJ3~Eg6=Sg<5=?Oh<>K_go`o>baOJOQ--4~CsU9auE>jM^S7C z$LTP1D~o{=&>5UYd0+2S2){M3ni4j-K`fq_VBDy|mt^vTpo_Ez6v(meB>gl;7u{(& z%9DzLe}~}521wBrPC3+)nM}d={s9;Mfg<$D?0pYGidK)&@33*KhcxBmvixzSvG+kb zcmDoh@XzpzUPV4F;|~RnQ8m!7Pl3*oK79cEDdpq2FYv*@ComH`>M2mJ4xApEsSfu~ z(##tC*sI~e0JC3-qybMcy~?ikYI%L&9}x?|fUrP@1_?AV*1DsE^XilqJH<}PMLIj4 z?gq*2x{4<{cXUc@9_u@nd$=&4;1lQ=!qz@cZOY+ZN7|*6?NaC5yCh}hEBM=5Us>l? zF~^p`i&Lx@t^w(a<hn-a2~MHC!3z&Hz_MR)UuwTlaIEY?WQxhOu+%4O~N$;7O+Cvp3;G$#E(aHQ+{!D(1 zEp#wIyWbRzzG?TWz&uR}^UtXn_`0)hK^g*Q7!b(Y2risbn(cL?6+m-b9h_`!KT4eTC6nQ;kfCZV1vn8?SYW_duFJfSK*MW=Ih*|!a03{oE3${wLmvc*8a%|1`Wil zGK?~;K^$wdB+hEu)31j#;8n~>ZSODA|Gsj97? zh`PP)3B!`Ka>78}3`}>)s`AJ&3v6M2zT5J%C@Q!d(qkFJ$i(yzTcj0f9@PX6p@UUf#8qG{5nH7q&AibUmEUNH?rmNF zlf(BEj}`Cv#wSTU{-hngpWb(WcwwR0#Pe0qr)Qy$_%z3ql5ZdE>mnKnDZNCCq{M4@ zTM*HbR~=JiLE;B|f(rdDuO7JKNk}e>G`mU2IYj{hMKD0~mpZ4-U++3UGEY#Cd6nJL zPxsR1{bEPumjj(L#AW}MH_yY$y#xdIJPAF*{zZCQ!kR!pu7!Oe#_vgtvKo8#!HoT& z=l4QBMj4hrvIjAVj(m+)WX~?`IwVGUV|9TM_N+`=4fsWamV4l{hA&8Qh(3pH!!%MN z;{vxQfDp28AKbU^;K)TI_-mJ1j}?Z73fVmHGl@KlXLCs^WO0(sUwkn~l6kvj%$}s1 z&ALgk#UWq+J8@eksZL#-r|uJh737!H!-8w)8g-(?flk8W-4U!NnaugR%2{F9;jxk+ zlneIVc*5K0rgEl5SJT9$iFDvM>MEBvmjYyiD?nNXQe({vX;68h)-=N33!P6q9*3F3 zIA+*<{|F8aiKtiU6E;-jxb_#`9tZ5C2!4fr;d*d3h`z4iZ50?fp!x8XXrv}1?pEl} z#FcNBw+}$2sWa19)C|5aZ--iomp+L-2zn9NIRqHB`37jZb{X@L_z2GH^9&>;jRM85 z`*KmoUWCMFo@S;ZJ`pQLVD#Wv#7*l#SXKM^z|%ivjvkypIC@IZ3FeL+9F=oMzn1{w zfTe#bm&du$gMv0dD}w(dpmWT)~}yfv;;we14f5y?_%Izwb(lKQ~a*`W>(bI=V_>8)Ag1W zi;NA%sq^^PQo8Cj{^FJIYvbTP&Ev6?CSydx?7}i3OtS(wig`d3Iyup33uv4!O+aP7 z1(oZS_%Y9YD%T4f;G3hbn##!Gngq)4s-kjtnLCw5xMZfsH8v_uBiGk&`Ln0 z_w}bD-!F{iM^a%^4J9k1J14Km>?aC7t+8?1Z!v@8?EOfWp*|y^(Z6)Q840L-Jm1ge z;W1MLqG)5_c6@`k3Qv@DUURG`_@>S*o~T0&3SD^v(Q7?cp}s=tL5mdP*y^O{B6|}o z3Z$0gK&9yhxI9iIICb`TYJ|{uo~S-c-z}TCS=uC?jhVHdtyj5{aq+Wg)k{gD{9e+*-sdpc4C$ zX=$G^jL&G6suXXDxV4&{_)9-S(f9CJJexm0k+gz{?rT5=6bhN9WI-heFu&sjk@M40 z@NlbA;dk;i%F|QI;C^Y1ij*Q0?X7#&L#!tFm=OW4Ph#86M%1K0YXQ;o=7~e#&K-0A ztVvP3X-6gPpH;-ElZuE_#}+8V8!73R`HeW&npf>`7^{TZN2ef$P`45;b}Wiq7{W?fz!*e#qGPZn2eO(}R$^-U;?X%Mpc%XCGc$_z$oqmRPqpHgTd0wK);=_f|*DuS50IzZNu=1%c>V} z-SU&rEq@JKnmwoypCeeKF;mD+LO#$5s*Hq6z@>m!1slY*p2D`KB5EOh0U`2n3s89M z2a!QHlnfO&WQJ=am&GIKXo&HE?K4AtZaCJ2s`^yC3V4sPYror$_DH6YI zq&A${P{cFc!Sed2XY{dV4{{p?_457(maR~bPa&*JUAVl4>f>F}oMaQ!0d1vOu{yCr zgKcm)5HI8d^g^v~0ieh3>B8mxJxAe%(#oDaY8r67Hazdk9c%;jH|p>bd$+*lRmlsZ z`^_n@O6=A)9Iy3F!0`+=Az*q}uEygj9#GF8OHUyN;AzqX3#$Ofyun}t>M+gKnWW5$ zv&~11xN%f-tmYxO@gdYGxVa`G1t7uvF&#moU1dfMgT4EL6Z6Js`?*5C080W@88=FD z>N7>=p2>4Pm(6+)Zk-hmMjRA8m~5TCKSdOEE`b|@J!1ujmI8fhB-;i~8DytEEn^nw zH5FtyrFFArZ)!&JJF*|=*<5B$?#M@)@i;%lvizW%KYKer^J7Z*g48b#zpeHCuHOh+ z@f16T_Dn%@v=40x*2VWi+=c<;Gl^IkKqvYC9zTQ3HJBxQ(o~R{iyDV>!dP0Ml)w_< zSWs!{z`q<<^@j{w3WiM=nt#sd1dW7ihJ%uAJTzLONnMyMV9v(#27q=%fRQ28px`ET zL(iw2c-GDKbN*+nAH}$n%IgNiCj10H#P9johaKt(*rC3T_2Uw>F=i$a{Sk?%JZOr@ z2+o!ClUNX@xW^pkH#a7c843T>t#v5tgaa41wc|8F$;qyCUQayUv#004fi2kAbVT7a zWj&N&gIg236A9I3c2Wtd!H>bM1-IcI3r9*4=Mg}3cVg=xON6jK0EwyBaGB};ja%@8 z8r-IHu(UggEkks3LN$!2oq!eIc#r?y0-PwBlCYzOq2i9+iJ>hCG;uZu|LYp+C9o>M zoh|arL*RKuFCl@MNZSMns8jN}Kaew`32+zflspa$;?bRBs-8~Os~g^@zy^H3*m6?_ zau1u@xY+9I+)ei=`jW1U^%W!TCjp&O20-3=3hmMaEoXZv&oEsG7TTrLU>|N2YlYB< zkgYQeR4+;7n}L0}5&~+Q7g(heXvd{&7gn>8iB)Xw>f@D)gkJ#!qYM6v_&;s2ScxT{4fnNpUZW79R z1nwZG1&mIRI6$HBFOEfYN+&!at(3Hc;s!#k5$2XpO#iOhRH`veIz(FO#Z!W4yEI+ae|Q&P;YUK!8yuo((bopdH_-g zX!ao+@BTz0Y$AUTl4Bd1t{X8Exq(B-W+mHZP*Xo*nVK9iB*Y~}2r>!hg19fP#O$c; zKtFL|N0G3&Zjt&3^!#7YM<3=sq*-r#24LRtG(x^4+a8Upl_IO#Z}suK5CO-8pcfar z3(wIAde?bA0HHT}k9feM*!|c{)N!MVWe?=*y@U|J{JB& zK23q?!DFd0<~Vn``WSkfPVL=JvHP@ncasLfxi;)VU-M&rX5H^(&^!4*#y781M4u8~ z_(?>A`a^twfPq26a*su9x)B3@iaptyPny}xsp@d>Dbua8FFh3;uAa(d%_Lil)$j|> z?<`5g-@+4uR`#|c-#7n|ryhqc3aW~EhX)8lVxz@K3;o&l!PLm#v?DweeD1TO)ynrf`EXSWWJ@wwTzkFoP<9WTXIW3+=G7T+U z6D8s~KpVN=p_X8qTi>E;u#rwRo?rVg;!~ILjTEn%;y!k9c_5O!Zpn!wYktSFYoE?> z1b+ZM@>k%S1gu^a90Vw`CwBHyU?l`qii43L!5Tb=jL{{yicv1}OzN-?!kdUB_ZqRKqn=M{tfQ(7D`OJ#LvpwgGt^`0vl_l4ZWdjB6p<3I5)4em?pPawy-!{dKO z2jj7H7Lh?I2&grS-&$(i*qrDs4I+~1#`9yJjYa;qs<3d#Z2fZk>dt{+_U2q>YmSEn zMXZCoiAMn0iS>!{$S{m^$`3w_czxFf-WCV|+A`S?_=h;cXP0BC#wet1^6S%ysQ^?%n)7h9Ab}lFH~u94gHfqgzUf+BXSZY6Vc+_Y9{<|- zmE$klFbK;rxG<&Qd#J`_Snq9STxUcjNeY2+l3W*ZpB%zr6w%&JpX&nq5{H=5L?_3GB zgM1ATCUBMzwoy;Xm4t2=ZT=|Qycd@I0Oa;A#cjMRd9xV5Sa&cb0GA>|p-+tARZGk* z2OUjK()r3`kEnVgd=!9UcDdNAIP;jQXOhSvjIgax^|JoHZJY1evbC>{xdiRkTsV;k z&p{3B7j#^h+>lGBa~mdU!bP*@?3U?bp-`OOGHVr~=pb6cb)^BKS1aRqrYa(aCrx2a zafNouTQ=rJ9M21Q49|ET7G8*Q2)b=Ku=k1xo+k`gH;(h5U_8j*aS?Nc-X~&xQP%GO zToy_H)0SE=7eRK)4UtqKo_stzu+dFRDL@WOVJ^2~t~V$* zH7CU8M4{1Coe<92G8J&v-qnPkM(b3_(Wt=YLcUFi)5RrN=4u?x3%Ls<%eM=WYvyDf zR9{%fWM9WhskiC2I`=Ul(oZP1f<$1v?jNv27bELVWUMmi_i=JOB7=keV=n;xZgIV* z1meO^6-r9~_A2g9jst)VLb()HBjZVL2-F8FV*q!m7bAk#vKY+^bUiAU3Uo-1>DyAq z&pS8L_>^A$FN}|6b{K0MVm89tAEc&B-%7L0kqQ!&WQdFF4;3oW(p*P4P;NAhv+qLl zlIF_syxEiAzrPWWH}>z(_n3KpG96ZD6s7e~Y1C!c=pQ$ryGaAm1GG?oA;)jU4|0Wm zaW0KOres##nc|-!>IqwBl|2Rh9{fofHAK%6O%FZ{C2w&jnu8wjs1ND>kTy)JVakbW z{zvy48c=etUy)f+&A;j~v%K~h2i1YX$pI0CZa>@gh3{@xk!T{?@_u0Zc^wJ)fuX?d z+Qbp9Gj;@fgHgmytnER>?&O^xfeu*CD{?s6HA;(L#NVE4Tnf zb+l_x@RLw5<90MTjgBQTI;c(C_05xo-mCAL5x#ES=DMnMaCJ=%c2!^we)X%~3%dZ9 zi5Fqu>1;R0qDn+`69mQa#DBT>7okYz%%e`>gYFpyk>t+{GOU|<H3mycXZ2ag* z8gmqHxd*btUi2i`aAB|K&gMV}lAAdN5J`Fe*7{v}!c4~>t0V!;`4Z5aPBiLB3)r@9 zYc_!_z+bD_gqCih>tFMw1-7k15SWUZDP+_eZlK-U7wA8vtko<_%dOqc3qFFCuvQU9 zCQyZ%j@0s8G$DNlnb`&Sox-7!eF5&qof+OHNNrjGj+?|XqP(n_OGDj?)sNgHlt^k{ zDxyGBg@_|?Le|r{9pkWOz^=h3wJ477@Tlk6(k4KbN8x^~#KQ4-I0l`BI$G4?n@ST0 zf+AE**RLmo2PVW^?2Zo?hUK~e)Wz!pcOXLKFT;k*z0M(bdE*(VBtDq=26POt48Ea} z|FfN|l1~E`o$jeYv*~9&M?j!uni<&4D^gUE1_vbtCc@WJZb9^X%{S8nS6HYHfMG`1 zj4{N@P_BOsWtZQHAXxOP`PX(pB#`jpPhk$72Cf!566ohUTy`8X+Y|!EPj%X}T@r4A zSTVt~Aj_$+%IFmslL1WITs*0jc^&wM+JN(^*P#t21J{VP0E;M`mq!p++ZQ?3`x-32 z+xaaNlcU`<>y>;jN;ZdYuQzMOsRDm{_gCpNgZui;U+LjG680R`q9(NEKvr-Uu)=~wHi`I&xRU2LF=du?6A>-seE?tKB6dIZ#5 zVK~$`+UhH~>r~5h`IE!}>o`JKQZF#9X!`j*IRBE0q z*n})db`a7lqGPCbB!7`SgO3+$7k9?!tPu(3`Xo629>E&i(6LyoM9{X1f;G5>f6EMQ zIgR7<+kf}D-@Nus>pz~Jse^95%y|#WSTPMra~4QwSm{W6Nh`Qe^B{oC_-Y#1SlusE zumFLj2S}wIm=4q@RY6}(p&=&NysOF%qd;dCKGF&!p+OgTy?21xplI@H^p3a zu?nj+A6L)eTOWn3m;69T6G*@U3iImqA{k>~wh`7Eh$I|`==Z2}>(q{c$-=#b$${}9 zc+$o!bM=YV|LZaH48LZ zd#!a-$&sLvK+C6U?Lc`@tl$&CFCu!>YpC-}PvrX4N-A4r<$n{k|Cdy+Qi!LDtdM1| z{2}{wDOp$^>&wa)iZ9A*ax5o*R<5LF?gvG>Nin{{h<23$Hj{kx0&C`U*VysqPiNdn z^XrTcucl&bFtEAn41!alPGjBxAS~@N@Bc8y_%(?1d*3=WX$vOAw2}scW_CNbGoWWBj`G+VKCnAufjgA>g} z&vE{5RQVWbl(1P;2Nel_pW;Z zT2cP;?#*2LoEX2NO-=N!@N~O05E%C}LcA(AzS>2}$&{S%+t1g(p=93~=Rxyb9B2?#8Gt8>#f(x9;8h z*5<|yT38CEQ#Wp#zBa2u)6IRw0$g_{=EjAAs{(Jqi(r{(YeYbKg{!Jigrq8XlNf6l zS%9GEfI9)0h5O+cF3s9!_NH4WQVpnIe*wBuX;~7hT?38QvQ_WQ7^)$%hi@@|L|@%azTo zYcLf{nl_+2&Ox)E-BR9|+$bY{fhNo2@cI~&0C)^gu7e_?X$;nE&M+2ZRuC}541m|H zys1>#R+%0QTYbAyiReU6d2^+_b?@fN8K^nf1$H`_mBz}&)FpVLi6F(8a$Rj?I21E~OZrLV z*x6JG?A;6!2%J*o7hlBVyfjvvkMuXd{`$pE2`BrhnXus)9Ev|BVxs!m225cn9x-%0 zCQyWQ5R(p*hxFDwkOP_s^RFR%gwm6qWOhmG2SixDdBMAA*O*Y4mVwZB>5u5}H!l#( z<8DtLd?RNi=lOQkIqEvnMJ@6CVKhE=ajX;^6v1Dv>bkc75cghfFIeqJxaPZlc{+hIuHpb=K4aKoNN>uvj5fvBOxV9;GivSPHMp zTMJ(Ii^LQd1gw3AuAQX&uz^1T?Pe|K5FHd(|H@0K0Zq66WO(!9DVVLZ{x$#C=zG!? zzq$`oXW`?Yw#J8P)%Cika3@n&w-3{qWm>{$^TjR?rax+*{o2pszjVb4|0U{U5nDM1 zjt6lc(a9u3OnH`E1eS;a^@abru9Lfpf>Quw&ymjGzNfEb)e}mjH`8wqeU1nVHTH&VEeD7ZxUVI5_)eNMbCgutjCP5Gqb)NExXaU$QI_Ge<<<*&K^uMv z0EE_e=IoGp(WGhz*{LuxIN;g9$0Aq7*T@?-#bYKRESE&wjCVjrUJ}Fwn8t&^_`xms zmD*4~p6L0ruDGX1Xc=ez>PU{H^T7Z02!s`thEN4@7(B zF7Ej@5+x3A*^>NHif!1Dd>FaWleptyBmz;Ma0d(Fzsg-Ol|7~Mv!@F21aAw0H-VOl zkrf{ph6JK?gE~)55QG=uN;Jy2xheu&_@P$V(Mx)+Tf8w2UOD<5_9I|fH|X6fepfzJ&sAgB|2zX@A)WO}$i(K|dkeLq`h zj0}#C4~{ez*!|O^!@Y_A;c4A^1W5#OJAQ-bK4NkHZkhcK)}S)#?K=m0iwjWXZ7q&R zYS<&+AKpKVDD#|kg=YvDSgBJc4)JJ`dFBE;y>EO0$*|jzkE(e+n7z-!Axr7oX-01fCErR@3Hjuiytd`a{wP z2q8+uyFnVx&Z@bN7~QQ=ycE-$&uiU0)+w$~E`EWob3)MBpsk3G|1I>40>cwP9F4X` z2R){dcQIXebjV|E)VaQJ@+Zp9s zwkPiN0GLxX!&%p=ThZ{$rh%c^p@B{Rm5N2g~lEQQ_KR5UT_ z*kXH^8y?-@#v-(hzA&ih}j_t$RN_R_*fPWBU~{Vih|}+Eb-vg7aS}+ecQ8#+-Yi>> zDaywc+n`PVShHyNv5h1A0&d6M{rT39-vNYK61USsUI1$7xjwttL=ypjPH_?m zrxigh-$0yY%!f%~)g&1qo{ZHInvWC$P+-EbN5a4eOG1eYq6--ZqsajP5Nnr2G0NyJ zh(16rV0l5vdFZ;Zl5r3g#|ZC`wlkGf3^-k1z;FkKnSE63KQcTZKIXEL1|06{Qr4CC(cU$FFwcl51acp_vInXYDuPI|oBR}kkMQEVv2fo~Py zylq`0cPL^sg&1I_@DP<1P zcAw6Wu7A}kj2=T>X~?6lP?qD92#`h&sKQ5M1*K^{p&C+{sp>w}RC@b1MXE@fT7U!T zPF3%(?b^L+VTNG26K51Tj6iW-Epi5Drak*e9UxqsljUK5FtE!7_ogemuRE-gO_& z@f)veCX>n34ute?qCJa}rOkxHGnyq8(e6#v{xG6w!b1b574(oKX=?Cwg?PLGEwQS| z)vAnLa446T!<`$j)&4Ja?*S*rS>F%u^UTi7&i3B#Zuj=KTwh(+ z-RZPCb;*)WmXYPEQ#lnZOS0rj^BDs+m?8`$4kU1f6w?($027SYC5Z!uC_sQD#=ejS z1c(fT82+$&zrW|1Emvd<^3UgeUzM3>o_S{WnWy}EQC4L3WXN9x!oB!poLp9{jK+uo zHWQ!q1jfh$1WAK{!2px9cm>khV?U}bqr^31wZ+EVw$~jyIq>Q1 zt)4h~>~%I+3@U)LkMR=V>^ex!_K-{wmMox`1Z7JnGZu}>lMs~)nwG3tYBnsjl90+0 z>r#Uj`ThvH33?(j#EVVtXdo5Nf?LpMNB1~7kxrKZA`of~r@6H?R%nH0y(DrI;OKXe zkM=$IkI1N>o%Mp`W6}BM@MQ=Axp|nfz=*JG$xsZDr@}i4Hj?z((095JTYr{#8a(JW z%CH>NfW@p z{Vv}C`TPXB->T>e;zkZ{-rAx7H_(ZHUD0{O8A-A^07U>ffJ$+iKS_ktjmx_KB4 zpqco$1Y%F(6<<@RGAY(U88)Vm3(ZkAfFrhtAkScwC&H~lNLMS6jGp)qHh=1mR^Y998*d`72=qY~>5v@JU@;RGJ|Cor^c+BS1Mn9&zY@hSHJ*^(M zpT>(|N|k1fVnsIMgaCxjnC&6r)EcSN6=$8%sPn9I0X=$t2D0*V$oqGL4l+^jC6BTv zvCgpwkuQS;&zJ&A*^y%pRp#8S(Fn+(X|Kca{d0yI3s$E6V9?JQsg$6n%CJ`~TXe_) zNGLAmtBFMb@g%E-B^f~)W%4sL8JlV}Y-R!1P?X+W-p#|M;muyGng2#5DcSgvA&(L_+i{}?zo3{ji_ZWBHn}4AgZ9WXw1KIzVdvV)w(x)X&a(C2ot5(tf?vZWkezP8XjjP%lq#}0q644$7H z9!vmO#^6g5-F__vV7Y#KG?)PRObiZB;@9V-D+29X!4m_IJTCa*jg~1ucCzFK_#ng~ zkC0WEDN)Q+U9@ea{EieR1G#LC7IcGp09qvlZ@wx#V^6w09nJ1=E)J{bf@XMn)82S4 z>~8MxAo)W_GdtPbk*WMMCK-~nkK4va#&xb*&stRws8qGX-t24c2sFi!E}}5PL$P#k zF5VRAK&{pPh9n+QAX|r< z5t_RRK0^LbOR7+6Bj0m1DXcar`4~lf>AzFR>r2rzR)f+8F3M%NQlo8?q8ii~wNsA> zrx$|Z6qBiJ$x}=*LGNKcO=YeiwS?4GU_i_|_5~4!6r_q|0af7@J5wB4d(%Cq){Yd7 zkcx~>daA8^+cn#}+fq7mJE@_)LL4Lx>@BS~tXd00r<>NTdSyma4TQ&6qZ``0w|94M z@5yhBstApbs4M45OhN}*v(o3}F05G(w9cy}RHI+7%00~@qR&O7d`GOuCQ^W)*&>KH zSdG>wf>~BR0Zq6C#xfVpsa&qdji{suFtO=}mR0fy96&zlF^`*w6>>pHxkT8iu-Q(PvthLP}CM76?=&0^EDSq8ku&1BZ(Pw}?~oK;`P!CBbI(g82zPBsEF2+w8Dm9OwcqN#}x9%)|u?DZCN#tl@h+lA@Hbph_RZ zKCW>iMG(h&1x&^$Ut)c85!K9QrQ{Zq`xPPdMO;S8l3bdfXLGe%F#D;NnOLW|n)Ucj z7E7i29YJ4xk&_?r48~V#W`x3q@-7gzBkU=#CU!Y)OSDKrHUO&?KEjcN3<+{kOCpDf z5t9uekE3c+NJsW##D{U+<1yTJz@4B5*2!jTX=~|>HLFTM(K68D=nBGbTlaKzCDX}# zB#GqJPOGhLCKwOiZI{BMnyU<_A`a_v=85$FD zsLYBJn@&xqO4FrO3jgMD7uB;R+(csZ{kII63RLJAv{xN zufm!mn?CSWf~u;2fQ$vP{1=GD*25H2o|F61XlFi!;0c|!fEM-y60uOkWh8jc8;91} zj#&-GT_LAC5!*S~R49xV3alIrccXC{55?^+w>#`{8c4$7O&06~j5LQ`b9(GPP#GQB z*7nMM?JL{ykNQn`hxBrf!}7MB@J<#ILHwoVPJt{$s*)TML&(7%ZUIsx0~x630>G7I zvxIqxU^k&HGP1DUifXgFeC<8ifoywPQPjO)@5f_Jq2_2)DCGOk)}EfVJw2`OKsbE$ zd#y<47Q1p35{lOEsr=t>^dZbbIFYjJoHGs&j*|%W72Xo@K@1Ju=RMNyg{_Gp72Ly} zATEb)q>wJ14_jpzK4I@?0Zr0G@Smu0LXxJEQP3cDxRid$yX@RlE^ec-vq2w}43aps z^32k@aw(n@I0&uI6Jv{p%T$>>3%+4a_N|dW0Pe2ALKz$;T?3AiqpFf2@-90^y$LSp zOy!xSb;Q3c-<^d$6l;KT7d;56Xa+t#&~OWBHyB)s<}@4;4n`3mA;{;eolOH{)?NLH z;i;uL#F#^T{tI27LfC;Z)w*GDFoggBl>=7{4sNijC$Np!9jKV9wRlz#e-AzZ3KiXrZ=2 zXRyB=^26hrlf9wRD`?OagE;HNh4~8lr0^ z4*msvI&@fNK$4P0C?ha&;YcGc)*(3;e$ch8FJUT3QYyeUv^f%T|6?8RzD;+;foc*% z8x0Ue5xYCyrMshU_X|xU&QcxCe$*8#Itr1FNYrir9zohoyIfJBdw7l$U)c;Q-V&g= zeq?(s2mnejMWS$IXC%3JZU9MA2qp?SI7u&P-QIiF7I57#Sc)MAv&T@9&50|J5$vq( zcB;QI5J09PTrvKD&RzChwp{nMU0v-l6=BY~XQC%sq^2DT0Dfh~GK`_&KBN4n3q7 zzF^qAum`vQ3|0=fhC}^%oACu%M5B5`H=4MZe&nF8A4Ii7*E>H0UpU$(&vnwvf?@qL zvVaD)HqVK@fiXiqcIZBy0DLw`13X-XJb9G{3z7o3{R;wuxNlG$f=Y@6WLOpraoX0| z{MxlsZ1v_X_w&@%Y3sm_))3T*x;?mNP1vq?LaEUF3vkuz4Q{oCwWP}RLwjDo^YRZ_ z{eEri%3P$B+~UyO4(w^i7H_z#wellKW0D%uB!T`x2TN?$w4b$P6>?oQ?f3_UHb9~H z4r34ktv1d40X4J?0Lb7#78-g2x*-@NlUh*N6x8a18XtbM;?$=(L>LGWIgJnoZwAr+ zO$xiFTag2d*#Wn|2}9S%6!^5N$o-~k9h#1~jtGvW0^Hj466@1!0oa+V0h?C&Y9Iuw zY6v%=bvdHKST^)xipnW8n6)9*4a%ET8?=R>N0Hm@ag2Eyc(Dh&X$aB8H-owtUxPKI z33(*}8-hzfk;E92sjvbHzb5Ibx*yjnD8r*9svyV&7sk$=gkb6<39uL_i{2MXB}&YS z&}%13-~*}`pQN^dGB~z!;9VtR;!C~h%6T#}W!`jerJUL$A^ zXfPCa?X^P#rXY}n)g6sE_q*KVEm_8ngT^8S_{T{C$+FF>+|C2eNZ4ydYzl>Q-Lco@ zR{OMw`$)cLXj9A`zD+8y(O05Js`BY5`iuR`7RjiwRHWA!8D9@VSSw9N`7sU_hVmKNy|-i#@uqzeF&%Vu=-LrQKR^}hPOYVi%Qvpyg?Oe5t%zo2H=)9vY=?Ck zH6OWl2zq~Y?WuKUMMuYdmqU6+vWn-0Y}*EC3|qBf85Ri$f_f~dQqg092oTnGTX?__~!=VYze0IyO3e;560ko!VY3%Gwl`#9%hN<+9lw zvckIZx?zw@`sw}qR*suh#p3p)`Ow}JGr1{|XOrg-WZFcAE4qg2lU4_h2+6`A5f{01| zV_`kwf(aQ9!&>biS`;v3i9IlOU$sukN3i{n8x;9NswC*LCE&ZNJaA6hT{j*fG9hER z_rsvMQC=p>?H_ z;a;v(n*y&x$>CbN^~eZHPqG&fDkpXiuJVWQ6nJcY zsHF&%4S~PjmWDbG<33qumS*yL%t24GIP#$qP5V4#|8qjhDkrmUu-gY5XfmwCO^7lO zCT%(qV$H-IozNpQv2`lnrtS5L_Tc?={(zcqxdQa=A1UfCM3nj6m6xf5R6hojF3A3| z$;8%6h++aea8Ol#Pw{B?@eL!Q&IboyN!v;o?1RNL*&6~~ECj+z6$S@tt5zU$be27Q zg*#aJ8L`=9;Wsa}SL@BV^Z#nKBHrc174DjOrZZSMFZEAs#SHcE2);l89-vqsA_h3& z;b!>hQx-7Gps+k8r-ufOVO=y~TET^U#CH>Q0V%(4poYVSGZX-s@U)>%m9XQFM8!Um zXF*hK zi|Ap5RAY|!~Mg+9K!O5$j)3VE6?t7c=cTq)0Np< z9F9Rpv*VU<=L9QHPwdjYj$O0gx&>8(4%ALS&?x6g+SYq8ONbIwS0c-AhoYT`T|{Iu zIV2H`4|$D9kuI+t*AHbUwoGKjfmv$N zUn|cgiE6cbyF}BGy(>435EaWb1l%*9SlHK$r38x+v#+()QwJ@zY3mFBX8p$!MzX|h}`Zi@^t98xWiH+wUs#Rkt!v5 zeDOD|H)*Ca#@r)pU}66Z@F?t|>3j87#85#nbg5Z_f<%|rh6sWV+L~%bh=I8(ggg`W zuCrR#dAljK6Bp-h?>df)G&@!RRkhk-6VCh!W`I+QJK;CRg* z0MrR1D(V6NCYY4IhE7bk#t&JohvKcmF_X(e0hOFw!DmCI5dKlI;INBAsAPADwl$cx z2DCymX|ch2(S(!i8_1c6S+d0@2XFyv^iUdbm&D-M9(8_+C>hcyX?)}i!r5O|=!ylc zL8B!U-nQy>?tp&AR<4x$Rcol(rW$ut$IGtye8_g=foH0H6LWjEtaZBdXs*5eKzoX9 z0-t)X9{k(&tYi&)RDTuCT&3w8)_7p;&{?eQ=Y-6bB4&`SM-wqXQk4Z(AMU}#1`!X9 zSotsh_JRm=oFpG06@UO{B|TgPnVP(1a}$Y4vV$? z=j;XHtJ93pfU1c83U-9_cNhZV3zZc#CV6%~mmcov^ZQp82b){H?y}!sc6-ln?H%A} zS?TcZO+(#5n+>Uqx9qy!6ICHtoKmBePi42g;ur$TN?1wyl2x!8v}A=hsrXX!a|JVP zrn5&UOj-yFM@VOfhDl*aYla-iSUQx4td+g6!D;h#U< z?HP6yn`fJgj$tI{blba9O_j%))~y>5xy$`lSD-*Q3IW$!-D<|Qp*0v1c^Jpy z>2!Qd6hlE4*^{$cp|J&jYSJWSa3|MW4qJ}lJEX2$OqwL+svS3hpGnBkObTGQ^jg3L zL<0eIfDBQ5qwq;5Ga5h^$?hUvWq*X9^tunagIzMsn&2{IJc9E?lANPMz4QQiyWl?- ziBV~nTrcaA=kYUL2d9q(@vtd--dRKSC~ki=-ji#|h&e^y0XeZQ1BlMoMshZ6K!L)s zB5Sf8L|>r!%S5UZ0-8n644W1hdAc{vQjo?_ezVy*iK)IMPb`%ZXg!mvoTm@~%uAel zJhcE3Rr^9du^$9AF$mrVloDmL=!BsdBP7!cd6UVQLF`Ai&rqpPFpM4G2j#Mo`~w8^ z4dtp0Bdsrvjbe){34i6?{)8g+bZc+0#lu$H)DNd@)^OZ*!&(T{UX;l3q&&^b)Azh~ z_hbpxvKIgR!gc2DoHO z1exy_^aQ>@#9U72!S!-)ui|!AZZlvJf0%w}!v+`OLf_YXbo6N4?Wp`zV_BQ)UFRJB zZkt1NvGQSC+yfNZ>qSDtbi|tgGv-g(u|^?h0)6wKknatHCfy7l@@p&y5$WVsWFWiO z@=nWpEg!Oc4Ba;6$HRzdJxq8MA;c+vHwpWP!jTmwimSiH*Ep$L|I8<{d50o>b+ltS`SN7xdX2 zeo?{CoSr6epxNITo5T%hqxiIqA z4}nsd#y=P{fjq$z;N5^nD89lI*b8Hp1Mp}dzK3Kji_fI0z&0U=3xPc#u%#Xk_oI@0 zF+g#t$o4|A4sk^xSgE#t77LVg9oP6=6R&gne2zQci=*?suXXyF*ZJWVgiDPYuR-F9 zDX;eir+0Ik!_8eTTNE+CSxNOre2g8oMFNU#o4Qx0^Yzy4bk+y#5#!bVRqi&YPxD2+ znlFNL#2411u-&=Z?thyzzyntAkCE8R;j=5Ah`s9pr7 zsIgYluXcugMZ1`@3$Q)B3mh}%jC44dq}t3?2}^=_4f7{3XC0tG!}h|W`Kdg;cm@lY z%TF$up^q$`MxEfZluwe3jO=|Z6qtZI(70YC%?66jl+~e4nw_tl5vY?knHhx@E=@qo zA7+phu-S(CYKnK!zEYmIr~+;t!EaKGH_B_e1M)e5A5&c|RxioziI61vh&r_7y4Ef8 z{-WzP$pd4BBRP4s413U*E|!G2MjYB6pxr@-t>2>(9d4*RL`Aj-$NMT#QKouHM@icm zPu1>#^hHwQEWZL4QvGBtB}TYP7S$&=B%1fDi=Ki4V8L5vr)j^^AzLn%ixJP43RE#m zhr*XUks`CzTKsdZG%X*Y=cbCq;;1JABf09`Qp7U~X0m!&FJXN^Ck7lx>w{tSC#SNrZEjDR9V?sjA+n7MNwjE$jQbp`bRHp>LOxCvn^knH18d>D_(n zZ~0?si)fx$8QlKB)hX3$OzMtC$+SbCG`wo+>H+Zkm9n%&tXd>WxI}ny4(ofPlJgfxdDn}uACCOzBGrZz*h_n2+4OU{Z_KSjG_N)!>YyjDgWbCj99 zA?nYGHs`3iUMzX(+AD4~6z3Ys4aJL8V=jrNt;ai-I&~@5k$#Vns+D`DT7VHenY)7? z!+e7VBMPk{?y(Dt4p!-A_~Uco@yYS9mDydYw>Z%2v%*fc(TBr~fGiEyKN3$S;j3qG zH5i7znj0<|PfW%ZFf5cMAOkJsc0dLK1bGZ{Xt=Sr3Zze9%9%!%hmm^htZI%9sL`Z_ zQi!N<5a=|0gFS58&~Kd%Bf=;ap$Nvc{+12MB+$kjecoODJ9;xT*mu9CZxt%o`_rZ4F6Sp%4r-0kPO@jetb2ElSy#%rXNaE8NANsEgs{6a4lf zu|#yZ9C6fe_PATxM4{({GG8`=ga5@0n*_7Q;{SmU*HZ|2D7 zAl#g>d1-K9H9_`^gT%a1q58W+>`@r^+pk==?n=8?b=Z3cA;Sq6gMP&b_?7VZ8U&{d zYR%v)nzbOpv#l8qEB*lNo(9oMwGH+n?cB1D+hHQL;BiQfmU-N9zbyc}s!S%v9RVNL zTU6wfQCqqVzh)R$Wj2)bAnY=76GXaAbnaXB9d_Sx z@31ZZ3c_{2hR)}s!bY$Q_!~Yo!;+@}$tS`{zz9Ofe}vM{*rS7{^+9f;!vV$ahRnN4vVLdwTZPL z4kuI8hz`G~mF}sPWZZ-$-?;oNR$~wSw%@pPDt~(E-?(HJ0V}JY@p9it@`o2$(efZ= z9w+))Sn853+)(?E!I<3!cJ(&hJqJeaHl42ET||5LS@sd^-4y7#^^g#d#F$*i<+LrL z!ok96Im%}!;*N;0Bho1f@-8hmOrlHpsgoQ&4;g|$KO!NSsUpg;!61T#Sk)FJ-Jl(I zBOPL@z11IB9gaui9bump6a!*;MBPnY*ZB-hS9Fh)Jy8_H&|uNYwuj){1v3>D9$(nA z;xMYR|A+@e;doa^bE^(d^JchC7%pqU>4j;OMyUu(v`(=9O=HvQ{{CMXgY1GZLd16y zjr`k=LFN7bmj>ZqY9OLM2v|Fq`69cQ)()r-89e~g2IHbg!{ULUthRVa?tt|so`Ivo z!WDLF5gd9fKb-M z&4lRiR!~9xA$bH%4rWRQY#z=G(Iy6MAYAT&S;$R9<2z%k)0OY)##eju2u+jefcsVo ze~?k6BNN&b&G&v4fU`NhIu?$_?j+&`c{0yCTz1VKagRIvv$NSmDO!kn@xKHi?5y80 z?vCKD%Yj%Wv28+cUMN69EO{guqopAx8+`F3&!bfJh{M%_N)!uG9Fb}bh&sB4Hmz1D zN{KWHv|)bs1$nBxM%KFICG(rre`#KyS=j8{f_LnYSMtbm@+_7@?Hj=HQR;T&8^@%S zFy}(fIS+X<=?5(g{UkLG*&dM=XMri&Li@7ndmm*fRwfB0zRbfV2?m-AegP@NqprE% zR>z zOj+=@yB$#%kG;}BHog1TXpso}g!%6KogqzIw@%YS&ifA=(I5}K!D*AaH2l`{!hQ@Z zJYo_vBx{0GHR2`V$4nJJBn8O9`;-y$`(wsa;v&d|bl~it*|^_TnRWTO?bDwGq^f>H z?Y&hZVimpuObiKMTR_7K5DdDTUi_q;UTl9-T(EanNaCQ%H?zh!)1D-K{S)BL;X#NI zh6QefjE=FV^U_HKfJm4{wouzu9(EvX~rg zckWsFK7>MdF^A#B3$$0|M@I^;*6^$s?{IRL@xGN;Il8uX!LAQ&RA1!UVDI z$Zp31=qiH&%H@agf-3_VsY9VPf=Fd%Qgoa9zWusgL+T(K(ZW;DjqLxIEuZlb;;vN&o{kDN1wttPsYE!x>@KvaK{U zS`5S-jvE`wtW?i|J5?{9trrP?RON6oUnAtDi0mh&G?ACg*a&-ih(3fCoV3g!^`NJu z>~^MkfSG<03QB3Sc5<22j+3ZM7kk>qikZTSm5At&&iNh1md+K0$$|X?lZ6$XEo@er z#SK#S$0H)zAN-#2FPMDPZ)orV^t#})YIAuDJ|{xjIK0tRCK|BYZ1zAjlZs+>$Zz~6 zVA-Dl&-4gQVOs7QjIWRl)29H0(T6l}kAnP!k`-W1nrTQHHjKSSvw{^3({LC=KpH0~ zYc`J=crM~_wP%__2}AEjda$mE4P8b1dlN2iz@KbxwQD`P(Op=%w!PCeS0~854yQX1 zYeMjEPE#2uCgZJbrKa$-)8Pq6osJ;7)tg#7@z}C;w2{DG*V|QTy5amK)=AADxo}FB z04%TRP;!yFT0hWVVHhL&o5%BC=O2~*Q#ciM-@PY%v~KF%E|;w-OQ zyJ53RHOZuGk?d~uAr=U77NGH>hgy4*sCIJR)WmW6&0j2jYUz8^=tT9se~j+`2>r*>J#vJjwP`$q zy(0})Xwzj7fE+Lnh!<-OD~<#ps0U^P3s^1oweaBvT!&1a_gPbIo_I?#-x7FZ+j6ilE@Sso~{>7iofzhlct}(V2O3d`xJ*m>5F&Am_=mB`QS39 z2|bMjKIYnL&h;E@bzRUsra{%FtDHLd^)HvDah6#`0!BFLQ~t#wx>Kp9S7gLr1ieeL zEaJBaM?EIutL%VXJVJs7241+Tnj{;DUbe0@d1!0PXB;55#kOmPi2^fUi z8jQ7wP|XdYEg5e01!{JvAWia;yuzGdMpz(b_2{FHh}FyOwskJU(XZ?M4#Tz1X6IgO z#4)OStT8xVU0SnO)op`Q$>K;cDGuyY6Ey3&HhBdpZ_oH&+`Ah{V8d7@=X=~k60j(IzgyU zpa(P}&^@7_>Q{rpQBei5n)E&-6dUe1R@mBik*&*rADuDGfiDd4tN_5k1ufd zt$a&3{a&;Y8w*D^j#yPgU3u+bqx&!UvUeT&Q+~rmo0D=)+<*oye0?ZT2uN)VNXc@PI=--19kGHUJ|w( zRZjsC8Y*88_A8zBt9JV;FVXQ9aoW?*)vHRDZq|_)lPf;xkCnyjmQ_M)1 zm5Pjri71&VM7Cp=%tTIsrZ_i|IV+ChnypF7pqO9BlZb|ClP5D$rUm>2@uwxsJLQa_ zymn-vu?rX;07DwAliXhT%Y&Awt-ri9qlY%9x*}`0@UfC$(FrrdMB!kZc-QRG#pFwQyZ@5oNYU(NY%i^klTAWPzD3-URUm$~)?}bYeq#-82#f%FW zl&!9CxH`4wS0I*RFQ7K=2H8)(;l{63-&`?&jQyB?`xEi_U#y^>JogPaiq-lwC5g2+ zp(CG2Y)L#ty)yeDW#Qy&o2M0N&Wf5L8C}g8#}qr%IyEm%X4tJiZ9$yHR~;UQ%?yLJ zf>AjtK?*ZtbVdh8Xd~$1k_k#Il(X-=;0>hAV+6KYhtLD_r$}By5|7BsTmy^A zbrg_HX^j3KZ}uSld#_dTLMRp~LDJ=ewrAPO zaip207vcbRV430-raZiJlb0d`+pQj}HC$2@A0lhaZNdfk4l8bjS6lHbcF@$4t_H39 zAYx^#vTPs=Hj0g1^K=mQmNfxu%`hlkD@oC87AU`kr2#)`7O%)@Bo`U`YFO_~!0h*o z-R($p>fu1dg{va6D_F$I;fho~{Z05n`YJ#0F~b>Z4&fgw$@4Q;CRz)`S`=CnSL*3t z(Gxd@#I>j$GUA?MFnx`#QhK+h{wS6v4y;t9I^3Y>HS<-?q9}-O_zvt~ z=a&5j>fXX{KnOLdNhc@H=Y1-KFMmiKd&ndNaEjeLO;0p{qSfNbwOot7%(syMA z)i&H`b8h<_HC}M2yjZ(@qJB%t*XD)qQ?;)~+Qn)Jil;%)zRHX&9z{T} z1+yGkbWJk*>a+B_4MX)AxBU=(Jr1e*SfW_1{c3G2@2THsch_obYnF4``tS;5wn_}r+sGLbAKbkGV)h08RDYktX zSiDe~5BcnF^*cnoe@AsAl3%LWEBKKzVjYyh0d!LAzJUBu{GyQEiKtDOPeB&0CS@aS zXh|Gu!bbyD!oLyK&1@bWLg!i;emXVHQoW6xYeBbs9#Cu^9}^jhzTAc`X7DY=>>m|V zi@TTZox+zSe9bnIF7f*|_~n`XrE&DZ1_}LL+K1nCK+P__{Gd`-j)FdQ9kn&DyQIwTz@+PlAiF2(e&YUa(vVR+}I&5%-^1uN?bMa$BOO zUo!1|-F;Gt&``Kahg{~WgB8EqW@8_VXvv;F$?*3tQELAQR@ul)lt3ehk40@C4- zze1EOl6{NdTFu!>B^BEsm@oO4a5{;gK#EWnCqzl0fBh7n9oPwsnPAPdI;<&3w=@J= zu&bJC)$HDAQxFjked~j*DWxlviEB<+$_!|Dht^DW6 zz`(+GpWTz`2r23}RlP++_KsZK-4XD01&p{mlCg*UFg+~>T}!`jvFAeFCO~QgKn&mu z^h_AaMe&btEopNF!X<5j_&bObC9JAL&_3BcHiUFX4n7mhIPfJ_mu7cr@l2>oNwo&o z`w%W8*c3&6AuGnf?n?L*^YY{93r#mZc8?#u57{#jciaec`2rp8cn(QPv=$v-tAsi- z2yto;GbEF6k$I7@A$d&1s)hz6TeTLiQmThakg94QEqSadD97@n^OOnPI1nwI6Y$=u$t?@uQ zl+J?4z(ArGplFFHr#Pe_I{<=PHTXbPyGNAB;H+@0Ig<=RQj)>};2+YPc`6mrxwF(o zic8H>We8G)EQRuMn1w6o_BlF8I=gBELAz~%{;{Ug6Pz>*1DC1-8|@+>iYtIQTC)aR zSV2)HCl_5WFqZhMi!`b}BVb)`?gta&16wUc9{M zcdSM{UNsiCdSc$y4uA3TYnY9xPK_&pB;wL*&JtSXbCIhP-Fo@ ztJ`NF9lI+SblG&PfuxYtwQ?8Wjflb_#KcuR4)$M_N)M?3A(;Ry<)8$?HJdHN?*RYg zsq)r(Xbo0ck%~l8D}>)Jn;qD5gc{;d7BwP3$8~MjUfU)f5zAE^*1%`YOO{t;&w_m} zl0^WZH6urzhzSB+4En^$2cqG}8{R5w#m`+;WF(e;k9?P?{CBYY&*U~~{ z_WM1?6z!}jw0G_D5})Ul$6c;ciDKr|Dx|wqeVp!M`>=i>*9UK5GN@Ia$t1%E5g{L< zBDgk-NXqmnA@dUkA+Hd*Dq`})bk?M+o%A>kFVL9{*zR3oh_sp0+7Hyh0M|neM!%k!80A0$xqC?ND`(<_!d- z7-q@hiq+wrUd^L_Uq)kMWsmCH84i1c(zYuY@TneM6+eI%345=g zH`9TX??^pRK+XYrp;>fn@9)S=nZH~qo2lTZ2ZwP*o8vFQPbX}gH103?SXlu4RvI#;y}!lafa8K4=m zdO6{X%5dj55QOs-f^QlpVIr@RVWm)c0Fh!}98nSZRN5adbP8w3l6E%|7wTHTZKpZt zuY7?31%vQR-%Ma({$d9)ALJV?zsvFxU!+K-W?qqG!1BHQK#(N^KMy1k+eBqh28iA1SRUs-XTLH3D|S0J~#XD@N<` zG>qzxAg0(6(5&gp;RW8h3y0gie#7QCz4=PSy4i#OCvCQq@MhYB|5w@q z?r4)o4~2BM%Nui3ATi)M(EKHg3$0VKUM10&1Rkd3fk5`pPM4#Y$YRW}i?WHL!{zk5CyLD}cV&goU*e7k zdrQb2h&a%rSt&Sm+eZ=u;Z}HmyO7H~^oGw1oBK`?jc%>wGFl%J2h%hN{UP`lp-2bH?I-z# zAbccm4zxNPt$}ne|3eN?#r?YR>vLce;X!KV z6=zCLQ#-GvV2`N$`e;Dl*vi>-ug~N0^`>q3L(xWTFx}Z5KPz=c@;I+{n%7c(Sr+3j zbz+F;v^b^>eHmr%!^iw)QEK2xf?ZEJ_%1OJ4Lv|&8~QH@j+1iyM z19{RsR#EA~60o=kHh>0uMsOu1`0`C#PFiLyXDoA;vzD^u zoMj#q4H!8=29rWV8t4GSLf{U91@f)j&=SF7jfkUR#tQlkugx$BHR0p`^!e<|{Jy&G zx~s3gZXI%2c3Pdj*}`&?sVC@e(4 z0Xj51$o8y@;?Fv;%#FW8|4ERdgFbY#=U6VOg$@v?LmEsNoPJu8GP;3>X zOth|uP8j0dg?wigu~eDUlgzY4LD#vIY)8Hwc0=B-j@$3PqoW(HE0t$tZ%AC*+J|!L z(`}kIgjlFSS3KZKigKH3)5p6zdU`s#$92Q?J_*fS1OVP=W6${MJN?AtN!qoH@8|>m zqwL_s$}D9b0Hv0#N1W!gWHE>gB4N|~#`dlz&2HD;LWicprb3dak~fR1&W_6W*&JO9 z>+|tkVe`l9s-chP3x&eR8m>3B=b$)EQF|QFT_HpHEA|Wa2)H#!4Ky;0_#kO4gBH%Rz3yv=W)uX0GU+-*R`-K z^gejYCHr&-qUM}2qoE>tYN4LpVWciZ=#on3{Z8xZwr~<=F$g}d2b>gJ%L$uyO@*6w zGTgS>>f{a=jI0#I&4uxn%Zc$KI&hwyhrTfm&zTa&N-)ed$(Wp3%ptI!0>ILM5OY~c z8Kwn*7x}2jS&*Gq6|lq=IL<`j*Y`a|`5xl-O+jsgDK(F0>zO1XkpsJVY5BhuImlr;dT$g_dsmPef+eSh&Obi!R zs$>m9YhPH5Afbvp%R1bH*a|TWxZEC)F%9IUpC}v@!hH-v!|tZ-+sA^zrfw-M>kf5{ zhbURH7yr9M;~ltwsLhUc!Qj~T?Pv#I7HHio8>RN0J)#FY7T!nm+M~}R>rC~Pg@wOX zxrwy)cwT7l@xD5YB744mNk>UjOM%w`bA&Mpl-3KUMOZTsL=whdFLsP|3MGI0hF$C1 zqk?am#_{)MkpJ@G=FX00j59{OeM5W4hW5ikY9kI0Abo(ZNCyFb04=fK^OxQecIINg z{*ph7Whrbt$hWQx`>I|O(}=Z*13?r_Cge3(rlf7Ig5U*mgs@Kdg~&|7kWzsaunhOO z?8XDI9e%*DyY{%h3Pz~pG8IWfr2HDE*NJ~6^Mpv4F|;a>_{}zeBe(%#nh5Gis2s*h6I5gtkVkH&Jb%^C((Pc_`?fjn zS(JsnvaxNV4e0lEFWMgsOzxP>uj)OzDCPRw(ZU`~Vs8kXCdSMOYh6oL0)GkNOi!ii zZwlQpAqMy~*I2U~;5TER1Y&wzWC&{|}2Ni~Z{%P80!} zAX!|00~*3b@-PxB8}prmgPp>Vq*mBN3q4AtLQ%ZH>3mO1i*{K*2De0X1FZ4w{g>S# zB^0nrfh7vTqiS4n8gq(u|MH^_Hm^~vE@0Had|eX!S|4V@Cnp|TwGAGsU?HqW2`DA4 z)}1)LT`AY4xtJX^?x5M}Kw%bcibuMwXlhq3w<>Q_pmq>&z8-%FmTqKe39+{9Z4L7U zKs^xthS{(1LO~FshL}TZ+Xe8_>_udu-3Ua@fM5uK0NNExL?*8#au#msjf2e2 z*B5aNIqs~G%sQcPvufx4E=R*yUXv+I*GGB2zPx{j9=VJTP>yMZ9Ip;&^s?Wt53||- z*Q5XBr?S&>2l|iT%tBP-0hvItMk$sG?R6rGv9clYB>HzXR2dW!m?EzXL8eJWL!LBy z&~XH{g&P%LDq=l=>;Rw`1fc;vkn}UG?cU+sAU~j3<0`X9t!fOyxO7?z`r@iJVrTHP zu*NiQk66`s^-fH+Mseq@SR;j|rpmMRVfZ0@iFLc(=S(`Sb^>H}tI{}V(;g?^3hOjQ zOU0}Ta;G)TYOa>NE2gV9s~&e5 ztUBI?2Kr5m^JCy=VkZ3u)nwz%la7nn>ehOHbZFgV*36~tURd3mJ zZw^SeV^fE|+;(!Llm54Cisy9EGAQj2h3tm*d?&@MeyRSMuvVl)A%tXt zVyL4-Acdjk>|teyhnfe*>2QOsbwjJIWv~TcI2BB`41O9A3AW~YtVq#iZAt_}>`#Nq z<^en++T(!zkM>Qp|C>-CgBJWt*=(Lrf3iCn#LIz~WL&2wEq=22$m)4FZ=mH6+dUEj z%U}v0dtvmJA0#2YfDmMbEFwVVh|~(R)qD502|NMl)H+uAs0JTQWYzAls@&snPP)ZZ zyQd9ZH@+AQei7$8_wHrc@eDvIfM{ks`x7>%$7~a-VW<8KD1QkQr zu@P*+%w5`o4~HnVS`b7jkYb*~WSgA_*93{J5c&`~H#|so&v3>THVkAdcx9$K%liy~qn`7s9@1T}@qT54YPDe!1EdAmS*{r0%qB zUC~YA@NP_b6<5-}CfzDzvx_6Isg2{aJjKFKmI?FIp>nhi#g?GV^L6&Q*f3Ys8I+ik z=7?~T&=2?p9kbldFr~0HN)GfKcCnjL5SCB|rlad;W?Dzm*s$0S>5K!gJTWPK5_Ffcs0lr}&b?Bk~$j?*@K(4T68;J-Q18i?56G;K}CD}Php zGZSF5Tnj7tEeXPEf3P?;;1Blj4 zKY~isc^`_yV^Om;hlwT34_0k|I*Vu$ud1BSVG*qx$tdqy#QXgEpRl8@ul!SQ$^JFh zWIOuZGL$;Ci2EsEBRywqX`n61FC{N<+!7Cxd{tGl09ix^7h@Ad)Pj`%8h>I3JZi2n z62^4~?4$`2{-8d39}4*zM-Opale?}42H26nBX}Y~@d)v6Pi9oucWfBVoY<^Y0Z?Ex zS(8B$odW`S0d|0#Ctm6`g`ErHhOF7is7IFIQhD~ua53K43m3j}j1_a3`u0cmKPfEsa&!i1OwqDSF6^J7NWxzG5 z7H(LcIk;rj0o=nG8BsXJT4PRxn2W@!#PSo!!QyPm2fa2J%qS`|sbIVPkpR*mxB?l# zBspJqLB45&wQ~z{TTP0Xnbo0AR|`NnpvbFM^b~&w7P#>vz`I+X&2E3ygr1gyFE=uO()#gVE8w1$yK1CjRB(4@H63E8P z7Deo)u+*K8ced|NA&_V2TZXOQh}g>cj;^+r6oi;_2w9YBY3u69mu(TF-)4LZR=#bi z-R*G2ja7`gbAu}`XOnYFuDgu2ahWytS}k?E`|jUW!)0OO42)#5DeV# zId3-QVjg?R?qRM}*2^Ih1FE<2aG2XrfK>esuo(_$_aV337zjC>>`(W?+uZqMyT@by zv2!@ry4OJPnzt$Z?G(i3?Ob^q&XvD^#O{R|<~h52yn96v2`GvFo`*c_L176ngRzlQ z3gq*0hBzR@WrQEK?lvR@zPboi=5ChUC1=%Y!WU!Ev!azMU9AVEr zq-YAf=p8?4))JofaA)(+DLhXr|KK0Idk51Vf?GV&M>=0<-qqsw(>>hM*S&j(jHzPM zlq8*9i|Ff?06DYKoYrKsRXh>Outka;;rMouwwuJtBIOK}IqFtuaOQtKM~noYCZ6nt zCAViqk{T$5iu4c;)0O!;bH2e%v1QdZTO>=Hj*L+}8JR)fJ!oW%&C3 z7xa|p*`x3x^Wp6|WPby?LU=GZz$3>VvcsT+a|E#sa)g<}V2_%~E?U!bC}O9gn9l{^ z)et6K`tvNbey=Z>^mTSZb{6@HjlJoK`!_T@JMz0e5w?%7@4h^} zZOh8LJMvn0_qAUcS&=%mp*J&r;GujfcV=qhz&%^<>(kubr&lMuO`V;wVEYP0lON0V zwzVW3VIOnUbdi^TlfC~qbhhtqXAP)pN%ovnkNO!m6 z$HZ@2#BVSA%Zq~;tsc#xT1HNK_ndcC|e7>V1pQl%bK}5zzWYGcs9REa| zcF3lH(1G2n5!%6d167~`;z7|8Fb3*5@?7X;=dc&xEq*#`I7eU`?nJN;vX_m-kQ3V( z_gHO?afj8fMB*+bY;|<|R3j2`#+=4^)!t_W;`T8^bq6D0Gs%|%|K8(lYVA<14i#>T z)DFzL)iLgEaZWltTU;(J;=0P~=v(iLIUSlUiVV9(pFJKh#tmm{IL1}6R-YF(?@3|p z1;Y(t>q*RY&EyUQArUJzWX8TyxtqWn#pK6!K11$w>}{duX3%zIkb)3`&?)J`WHwPL zC$azmmSFOnG*vOz7uh2|1sFp4R(63`SOjesM=s1Sx<3pP8yG7}vpIp4hoqm1wC|$c z=GlvtGX!4QNjfelzY}Q_tn38pk5vBC@2{M9dsSshQIR1Fc@ag?>qa&KKxPS^>qVpn zsMg+hlg)OM7IjxXOwC>-QRjm&K}g5hERO%sxuvsn%WgV!rWL1C<*klr8WCk@yAP8a#o_K; zyiyj;OYz(Vi`f$oe8R2c+Jor1keTI zko5v@43Q=Z{hoyjDgM1#W$MV8Gb1>)!uX>7$dPuO?#Jcs(pY@#%g`H>bCAo;?GVi)iQN5f12=y20AqCA@a*jgKiTz&2-8!yP+?# zy9Wl641YhjAXr>)`kbUe7Em7RboF0U{a3I*1~GCj-CM*@zPnDCBw>Q3s{_F0pij#z z16lYrTXs-|F*LPcA@A3IOueWxu|J>9RK2z}Il$UT0c`vU*zOo~hQ^=DCD=oosbYjbi zkMgh#7B+oey#xd2D%nahVv-M!5$#M09yp}dOSN~U`}Isjya9W>e>LxiRu=CYq^sdf zzMl`!*B1joY(1*R+{ck_TJ5sJs_;f1)2$r{(&ZNeG-2C7Ew5-ts)&_{@6|C39h7w? zp6L)iLL2nTdv@9;^C~b5BqomBcCI@0qmYv@#p=wv*6KTvnt)7FcT#Y#-Mg)-JR0gw zQJoUU&rZ-nJ#t$a*c zZUhreQ@L*j2D5>`bNQQ+n=6kHky71o#01~;wh%du0X_eoJpFqEr-Ha57FckY ze9P~u%DqPjpB*U)qD2_$2TQW*Ub-)1+4726tJSEfd3ZSM&lqth{wsZADx@X^uL(J9y=&gnO0vXMmi zCf%w1j!yZ}vk7s!mYQ5Eisa*g8^5EGZJ`Ca=I7`O#2>1WWd>T?X_h%GHe1ZH0@|U? zEL%}tWtLUM?%i#cHK9qB@38|$-fGr6@XiN;C7G4XWuul)n`J~@vOHs!xy5eziCI>l zfBcnMwp#jFk6BhNVK!}+HA@G()hydBy8*A{`yG}X`}u|w$8S!pxozh3i5q7c%c;TC zhEp>$yG|TCdT^Qg)JxykJ#*^x(G$m0gFQuh*nIzB?Ts5}j?bLhck|4_)c!kCr*A#n zck|7MQio2RxG_b|XO0~^kve(m#4BeG+}v~I=9^EB_Vyk!>w6BIxDjjU1TtRTY)Qd# z`!-}>KaJ}falTl63VS+*yQk1*2DIx5lH(%Nz-m@vYuF^XzIALp+rT!mO>8sU!nU%@ z*fzGE?O;=EC%c^OVpp(Nu-)uRwufECu4dP;YuR<|dbXEMvwdtoJHQUI8Fq*rW=Ggj z_DXgGI|fK~oSk4N*-h*eyt;2@x3F8;ZR~b-2YVHJHG2(vEqfii6FDC4Vy|a+vp29e zvNy4N*uCt{>@Dm*_Ez>b_ICCTc80x^-Ot{|-p$^_euw=odw~5OdoOz*`+fEY?EUNm zY>qw1KFB`A{*e6<`(ySe>>>7HeVIMOzQVrB{)U}nf6KnczRteE z{*HZzhJ*)|A+mG{hC$S1#aPtLw|~t4l36W48z6^L^Kd7 z8K8Xja4+|9KM!yu$KYWe;ZYvrah~8w-o%@E3s3PhVq#`^8_)6_&+`Ir=N-J0ckyoC z!+SYIKD>{Ew&8<(h!67-z7ig4V|<*i;uCx|FYz^elCS0K_-hD2FQ4Z7_i6Z|Bxduj6;}S$-FPJ-?g3fxnTz ziQmKTk^0)D~^LOww{GI%M{x1G*{vQ52{CD{S{P*~K`TO|q^FQG4=O5s6 z{6YRf{vkNC{Sp6T{wMq){$Yd({V4w!|2Y2y|0F-l|CB$>KgB=I|BQczf0loaKf*uH z|D1n;Kgz$zALC{IIDdja$)DnX!T*x~6@QxlHUAR-GJl4Dg@2X*4L`^KmVb?ZoqvP> z9sef(7XLQ?d;SmnANjNVJN!BRJfG+P#J|h`ng0v_SN?DO-}(3W_xTU_fAAmjAMqda z|K#WS3;ZYir~GI9zxdDjfAbglFZeI{|KY#lzvdNwL9rm3B!?9Mf^kElt1C9efR(sI zal-QjxyC^!_!PeqP=W}p9abVrREa6bv#liI@Z7AlC@Ceav?>{;P01=bB@dJIcBMn< zRJxRII2`tZYhR)CDgDZTGN=qG!^#M}(nggrWn5XMOem|BlCnmbRMsl%l=aF6Wuvl5 z*{p0)wknq?+m!9f4u}VKDwiv}lq-~1D7%#_l|9N;%GJs>%C*XM%Js@#Wm?&%>{kvb z2bCG+kaAc#q8wFTsobC(Q*Km_D<_nb%1z2C<+R1Q@8H2xGpA2??>}+khT6q}eWwm; z`wqVHmeV&o_Z>TW_;~k$86dAyE_p%qM-Sa$msiJT4&CgK#ZyNQAGz7sckI~Asl!KS zP8<7f+<(ilea8>XWcJ-SbL!}UeaE{`)7wyY_?CT#XS$ElTTh;vx%uev!x|bMIdRH| zd&g$F51zPXzc}4?d|?g!oPR+Z@vEK%Rkxh9SFdk7ZWd)f#mmJLHre8qlls0>2aX*5 zf7&$LEyZyh44*TQkPs-Ux@SMm?lt71LSjgUBzD^gG=25^NDdU$vp+gW^0y_ul3aZ? z|ERpTx3cP|vhIAntp0bYO!Uvc_0>7Q|4lr*k0^VY@~b2sNS9vvEC+fO$$^w_tQ<(m zcpxR011UYbowf%(N&CuN<4A4!Zxup^9c+FQ4qt zjdR#PTU|eg&&H`6OvoOMOo;bZC2s0%8W|d0n0pgeU3 zd>g0!B2gdsB8fimMKn8Bm4#+^fSAfpkI0pmLlm{~fD?B+nQt{Fb2(Z}wVX`F4Y1Xx zNJyQ;RCy$^)kTOh%_4N2+3DRaps+CUD2cX+NFcNet#!r1$g0dH4HtB`^tp@zk&E0_ zw{hwIV>X7%)9&c~A`^%3o$u9K;P(@cewWGB{rOwJ<<7qj1{WUPL;+7mCfGk(bfoM< zmz^E^!1mI*ox#Z6vW?MBb(==!Q1_jSSIj7}uqQ9Dl0Vs`?rqJvdOMmAzQHs&oB|5h z^9{+|sAcrHftc=l6wU4-kg;=92&|Mi6wzWWbXwcf$(U7b&+zAv)V3SLrndb&@W1S+ zss@6W%(#2djh(Rlr9r`g?%FL|euMONRgG15p_Wz$UP>#`Dg+jC_gp@DVJtbO2DoEs1=_bv++VA|IS*p0cKzDgnrKW2(~zoV`reuZdIZn7-iGVu0@tM-L-4Xsu`=Iu|0sNA$TwJy*z;!KxLv_ z+Sn1Vp_}z()KIRp0N$26Tg-6X*efe@6wyr9%)?QjbuEWajFh%p*v=7N%J!4I?#*~L zJ(DRq9-drurR>3{29)SS3giUib2EFZTi%(UxammNfGWSi^wm&FJX*H(=c{P)ord?~ zMfhQUIt@<}CN&18Q9=WuWUP83;dqhh|NT|6;1&%9pj$TR*2&hO)p}M?`;$QTBQ)-m zJ6SJra&@YHZcc_UXMB1x1NdB=1P6>S|1wi{>c}<3J|hvck!@ro_~uHAtw$keGJPbw zfi&t}+n0#)Ing4B)4S$$&~8qGi^D~xID=Tnvck<`xY9{JL&}F8ew;cWoBO~^XAsVK zTD@UUp7Rpw-!P(csm^b3fVHp*pKvKoL{H8r_LD|>Ew3H>leM4mf3w`unpYAAii@PD zc_Q*|&IBHZiJhxZx_NNPxx#{0XESWi8l?$9VSVlZurmvWl3>g}yNz-tB{AIW)UhL7`0F z{gNP{w5za~g(MW2LzIdh6!l(tLF72U>Zw$W*}n_`%0D>_Q5g@s#!jK`La;u><$`-O z;Etwu93hbbL5BfPBt0$p(Ns|;G|h(N$uYO`>sml2BzodpzejG2roIFGxVlXX$XkCe zS{5;Pv{YZ#EiZ1n)&|#2_!NeHcrxKWpxEre?_1C;st$d=eR7)XeX?QV%JV0mb!9z! zj+k`~ifzuOfDqi3)iw*AsB@(H4M{hWilyXq1cQtpY8ZcqIAJf-y@0R}d=omAy?6DB zLuLHa2$x^FTSu7pP4=i@(w-1z-MR<6limz=Jcv!cSXBPx-+F`fsZEHY51|PF)YU29(M;(i{&M-1 zBZU=ILEpfRq~6;rjb`k{l)i6kIV1W{lw!biGiFMCcRbp0 zE%j^SEoV$67MW@5LBe=zE6An7*SXn=`0x2NTm+%>HkjnBfC*# zP^-zGf?cE*XIG{m`?-MNvV(1CJJV~tSwp(Ld?dD(lKIioq9##iU?S2*X*pKs!wVy? zAPid?rGic2$j%B`pzKE3*IwyIxY;R(d#ZkfN##@Zo6zxaQ@JEucpAt9f7{{@Rb`um z0eC9HV8#E$^fwEghtb|h(=O&fAe9MSTWMg}zwonrj~rODWGZj3g4yNDYDuruh`aIB zr!&Qw9}-^Lw8!k$^1BD1sB8joflqA67DoPbR>TW0<>e=hbS}}ql#F04)E;YeoFu+M z?UY+m$O2{}w;(s+%$UyQUJB|#TetW!vsrhma0{WL@)M;}VvDH;I`fn?5#P*>wS0$~ zT2S)bN{f}jC&Lxb$LQB7)UCQ_VaC@eSyo{li-4*6*q(*^SVw(9Yyu@CMa+((4^QUZ zZR|p#%vQgu+BA}z_!HhHP?e-ga#d_%MXI*uU*O{mgTqD0pIt@=Ouy=jiG-bOPahkU zzIDyiW>d@Ct3R8K5V-XpQ~M!R$*@eWuW#?K64ApKf#~7;YY*`o*8R_`?CWb>@zMlM zy(sbiHs%YB5h=wfFI&+Xx6d(m`V94m6UwZ~?x*c!&+C*Di8{y~5C$rgXyNJ-V3g ze@xemLwTy+DklUOFYiYgRK!ss-se#ODo8?H*QAKsML_bI&ZDGyNHl9>KOzA_)A;!D zMub$w$Mhw8u!~%*a;)ZQt8z^hib!fmTf{P79LXa|uI*B=@02?6E=fhOS7s@aOzb4% zHYy*QI8{u1RK%n4UmRJsCny`24F*7-7FtmhvbBviWxl7gO`{_!GR#3Vs& za=XxCTnh*^Q{KAb;~DL~Zi3^Z?CW@+44S|7!g|t$VWh diff --git a/COPS/cops-3.1.3/templates/default/webfonts/fa-solid-900.woff b/COPS/cops-3.1.3/templates/default/webfonts/fa-solid-900.woff deleted file mode 100644 index 277d8cebc7fc2e5de5f3d186f8d5e02c52e5c215..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63836 zcmV*1KzP4*Pew)n0RR910Qp=13jhEB0tYw%0RR91000000000000000000000000- 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%0A3#a=nzxPj;EeEek-hvbKP@a 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%0A3oRnnoJEAP@ONSo~r-?{% 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 nH* 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 FmqYSRVqO3M diff --git a/COPS/cops-3.1.3/templates/default/webfonts/fa-solid-900.woff2 b/COPS/cops-3.1.3/templates/default/webfonts/fa-solid-900.woff2 deleted file mode 100644 index 69bd4299c86b9b978f5ca322356d35d549873c50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50372 zcmV(~K+nH-Pew8T0RR910K~)q3jhEB0tYw%0K{+r0RR9100000000000000000000 z0000SR0dW6(nbn~*BFJYV*xe-Bm4dI!BlTT`r&K(zC(Rsk@#4S;4F z>s!8fMImm7h^C=_tb!eT5w}AH+jBq2{{R2~Uz03iY|YNW>>hUqB1$PnrB?M1xry-X z!XTB(8e~RO;4C1fsfJLI5!oJ0usO&PZk8&X!k+VrurII1all|5mpm=kTF7RXn`jYv zgP0&DhzVkXkGqfKKGSO6=|?Ot?VOLOz5DQq&Hh=jpRf;99f%es-*tCLi0F;dA8W8^ z+RukDQ~E7=_T-g}X67gBX_27Lr_IXB>_iDqI&>!cu)?dzCl>@+x8$vE{g2Xgr>1M&prnlEYvgPUT6;Yx4Nl{lOUvcH|| z-3`y@>CfK#_m7JBaqTkFb9!s7wPs2mH*zrlQ-!@JYmALy)(aWB^ynj>P=Op^vloac z8kI1L9%4}?ugSiI5RIX^FA)k~;edtiHsMIY`%c@uanEagIS2tl5T35OZ2y?>^0D&SF z2T>|YjY7QLoi_w;a9+scMTdO9S6BWyz^3uuaTrGnuMbeS?g9X#4VS6W3J{KLC)^a9 z4oK+^eoCFal)cS_n`Kc_nu!gm#bvjrG+;`~Z^TJB{&u*)m0aJvCrgwqvLssuvKxx& z+Y4o6ZW}pW&5+F1nufqfuS)nnz>eCEC;hbd&wErrRUs9s{;$m{X(yA$haU`gY#KN~ z%2f4jE2*+Pqhs%T4w9gk$k+p*Zx-1tEP1R*P=ukba#19L9qJT<#D$N+$Up8q)d-TUa1uR^~KBV9I-0xWDi z-4^2F>;(NxxA$07*kBAqz*J5vY3C=^{#q@v;{n++1a_uE3&6Iuz&V1)SNcld20{DS8EwjH(^(ZS6-RnDx_nAARZi#2Fu78#tBKgXfU=`o0IHKX$Fi8k^{&q zTXNVC@^kl63a@*7?(w|uJ>Kt|e^bp`fC^7?+~f<wKYe z>@UPzR9Cdu`CU_8S6+8*dyE67@i=_9ul^(Yw%NNWF47c5?wI6=Ql3O9k^a76%++BwZTzs$fn!Dn zF2DsU{`9!nH-VbmUJcr2u_#0#@n@RsA7svIP_Ml)gAGwuSV9#oPDEB96aQZ!0E>fF z*njpXwF@WL+t6NO}8T!D^;5 zpbE|7sbjy}6&2s$ujY*X%gDyf<{JTgnPCBdE#(ZBcu<`zep{#4bW1^?{^uX4GyEEv z9k2*E^+xHQx|i;Q?aFtLHkxX_1*BB9%M}C}j~i5(*jy4lO+s7k_k_vt-MeTi!XnI&@^IY-DZcXR0%-w9#gl z$tbF5>KdE7dU*Nxv+K~cCojDAPMLncw_nfhr8T*={msZ)QEer?`&Ow@r$L+8sk^@W z_2-&|m`mdfF>y($rp(+KmLgL$;W!+rh>-SlIQyT7fG3y^LEC>r;#U!PmVPd6YiKJj6A1iGj2t+nj zab)L1$6G_Lul;z@8Yl8<7PhXYm`-|)b7j8j=$pATzt-%#(w{u^TQHl9{Ad+_0f;b6 zMFR2$udVgIyg7ZT@ox9V9X#u+a`^I! zDHp%wm91jUv~B(tZ}TcvyZSY*llarSvm3j;2Ya+vbnN&2xvvATwhrZqM7?PGnS7KB>gsdn9O z@6AS9SKmMIp&mQud=<$jI+L={>*fs`F>0uLFI{VYOH6s{#7TVh&RfsA&sNngmE?l6 zHFxhf_yrCf6me0cX-(R>&u>vhwkpNqY_2mW4fTqerL$~g`lXRps+{JUQTS|uEHh`Y zz$fss4Xx;GZ;U9e*uE@$*c>-SRXXUdqfVChu^0X3*@gHE_U+!(EosOS`VcK;aRWp+ zo$ZM+Ve_yU&Z_X+6#XeHhK68XIkkg^OvhFxTgl z|N5{UrBtf5w;eUsIOB~Gh1x?SXFS!hcDLA|I=k+&&bsO9a^E=6nbkD1bgz8Wlb-gh z=e_LJ+{X8~%z>ztRDE3>n>=HGcxGXtvzv#On9_PX?5tM%QD;lLJ@c*4eC=}|`@}as zO=num194l_^M3AvX?~$XlxckhE7MfT`PeACJ1tOFUjy`?WFAUuVs1C>(4)&ssjh!> z+q7m>IIqc0Vu~oLQ1yA$+`RsFt6a(QOqx7K#HYq(i_)|qDI@++X4(S{gmnBhhkX_S+GcQVMj?e5E3HfM4Ks_)8q44Gl@3|8>Q-81lf#Z@ zmPN8?R*qd;o7z!Jm%B6aY`uWZ*sMiQJKYR3E@rWdTl^B2wA7`|wDe`&oN49Re7RVy zH{0EHe>k4bm)rgEeDnkSI{`vjFl(nQwCJL;=9QNv6Fv3OCq}HXdAmJce$Kn?8IHcm zKKI|G3taI^Q%eXI06?=#0E?mC-E3T=3^vLU=&k;(ZmmR#Eg1a0MNjQ(FkwC zc=8@5z;`eaHpL{e4wFd-rjR!<75)m)1mDAS@)yj2w_qmRh*@wGnn^Ea6C36*Ld=D0 zF^}xRX+(wj@EjJv=4geru@Kh5B3KuTVJ$2nz|(Lio&f=#g_rS1coNT%Ry{tfrwC*pyhVKKmeNdbO=pW%P7 z3;s{A@GC16=|ceBfKJdIh=LwKG;{@Gpcg{W8?n#_anKX-@CXScobXyJB9WO$CVP-V zhLA@7Bpr?-hdiJw`~}D*7UaP{fP4}{clZT`YdI0Y1r(G0=s^-t3OCUc&ZCSLPB|Gw zFQTS5yn;S7CwTopX@*dK`@Y%q6$`_8h*qeauh>gH-^F<41>KG4!bZ4x&WhT z5!Avm)WMUeho{g$j-iqCU@R%aMA(T*q!UxfMW(`KG{GiJhpm_aTQCz|z%23&n&B~K zlQHJdYA~0KU>}O^;7{-k zUVu;W64Bu=a0G7?JKiM%-X~m6kVW`ldG8UCpZS)~WNhXm4wrB)*?W6dR! zOPk?Ax{S2b733eZn_NRzk?ZJc!l6B6Io-g7(#^0p{RTFn0}F3k2o9rLVMDqN76-Z= zUZuOpEp(8W=po`l55v3YF$mBR7@$8edU}d@)6>M4o@ZR>PYjn{U^w(=#+6=Voas3E z6}<%8(qG6%dWET=SDBgg8dFK{ks^AZJVu{0+4LooLw{$2>1)QDzGqPAUnE~X>iCD; z*71?t)bW|@rQ<8vM4^bkLX)Kwfh1EfNuh`&l_HTe${k*%KQS0ziP4xMF$zemI*~XLbG zQ~mJ`GywlV6-g!w{HL2s_3%Kw zJN423692Q>?dyiXU-kO={anBQU53`I(V;~Ae1^lDm=>do#qwh4 zZ#gr3%4U)F-5^l~pUESG@tlk4d5I4hbvVFE6S#fZVk%567xNTGy<=Hn8z>Q8*l&Dr4*3j0Qs>E!BO~6!pnfb2PDEs^}&r9^m zXskD*Q8`N`Z5s5xB+W?B-c_X1+V}%wq)J8Slq(8XUl;e{-$sVd`N)Vs^6Wl9j*SHQ zcT)s70dezmf^j8S>(N6KBMHN#=WvdX1E!ht;{Cb(DjnJLCGmbwCEPN08{$af)M?gT zxz(k31VI<;lQF#n_<%zhbpt4lmQ6DcK;36(c<*%f9`E&g&!;IIilI_r2EaPcCQ~th zun6VWLVDZt!<*aJub)on!NVj`Q6-|KkD+sMB3lJ)v=jsjr7Df#2;P|ScM0H=L6W@l zm&F?LbX#G3iEU!EK?p!q#f)=i#W2d2F4S|f9DFKE0do+1ePzRy3zlhB%%{qU@4DLr z+`H`1Jhs$9P;0>2ESKG$-foEvaudR1GSqelqb=VITiXZXeF|a416&vtjVme<$DiD6 z3~4WiK>9h)pF#jH%Rz_$&+5MFWl1K;aGj>Z>V2AeM;hCbQn-a(J|#26V*7l%-JLIw zc_-lFRCB3@#>30oyV+(t8DiKMpVbX->+^$2)^>w%X(eB+stV?i*p$E`Vvjyadfk6z z3g=+W1gH&`5Nru}1 z@PKf7(~5(EG||Xy9!R1sT9%&E>N2ZuthIvCeoQX|8K6&307M?{Et#2=}ZbP3*X> z(t!;);lE1IO_h=pZlg7>IlL)k?UoNnyJ$~$wJa8{U9U~NBu%NH6wD0}VS-Sd_2KaH z{>#S}*7yKpDtL`V5p-C?rUAL)SDQuKHcdHvI{XU^G(vD1=+pU0PFrMY%TwBwZB#tG z>y|tNapweZMxct4bE<~_4fFLS2FOgQEn800z?ri7vWFuCDvq1FewBWH2WB)IZ@y^u zTr5=2FaO)RTa$oM#(WpK=)7L<_gxf^yOyCaYx0bSI}fbU%@$+SNi9q!w+-NVS&wcg z)WMbDti^`YtIx#U30$_iQH;WiHv#cNsk=hE;;Pe!q-jVw7`{wXxPbvBZR02hbsAnaKaQ zH!D@7h&V~fK*hAn=;uaa8F*)?{Xj@Es*x|?0Sbf10-#cU) zmDj3mv5}KTl14Y$#yX}wNx5!9cGI{6FZUb9HRgf0XM7H%xEoTwucxyZnhyUOQ!8+E3PsLX356ZRDIXX0J|RV}SP&;{h|LC`kg@bT0zd14v`jk<9QhI8`Ob z5OMVZxxGkH$(H;e!@^ypF&Q_4WTY@J+ErvRGVO#=o}NXUoIc_CgTxW+9`3M97Fm7V zF%672osW@^2g&P`VK^fnA=sikW@sgY+9B39-)Q7<5$bMuI1;yE%+-dXk}EymZU#^* z7H9)q$ydJ6&%joVb<90r6`}UE(!tw2h!yY_B2qLwGfT_0uQgk0705kwZ5at7 zj`{Xd5g1Ui_ucfu5U>T$d}pN*tYLUpBATzXOsX?w>t&G{jWr23v(|FuFY56RQGy|O zOp3jt8<*DZ{sR$dczBAGmDHm4ifwhRJhg5Vg#9bEvsG(n7k@Au(Ty@+lvSlEpi|fZ z!H|$SYZbQO1bCh8xh|eGZNx&5of@R+@@eutDOI5{%s$N-&-S)CZgCoBFgr5Q5TdBb z=dMpmTIBSeCO&3%*s2u`kM`;&D{t&ba~f%>rM!iu>Clr~nCfZ6A)449xhvFi9DgA(RnJdLsK}Y%DG@-2mFsw5XJwr@^|jn#Vc14M}Jb!=fbh? zB=j2KgA^?3_glO_S{=+ELs1u-4Lf@{v50F0i~IHP4T;XaSj|jsF?CJP+p+zIc16nx z>2OL7w#nm&@gz%9XSkj1wWUr2KV3TE2LGK)Yl@b7%i*D!%3K*%Z%lH%bG3~$*8Po{ zV^h^u>FOHNxm>F(PX04qnN_{hQ&Yj& zSe#XFmoIWoAIPSuovh$IC-lo+D`OYI4LgrfMm#bq1|Uz0xeh>=&~a)(@+4?PYz?Qm zxkyhALW}-~KD*RKncl5KR;u|3m0;n%A?9nc5gO8f@j?ZCWr~&bwUZ>ZjKX{;XSt7s zdg%9AzjTOy9*%gbn!*li-7*P6Xnl`IoZh<#FaI;k%D5xyuH>RRc2aNG?&@`?lv#aV zzHV!R0MGKwp3rYEoaT+*_{~ewV0`ydQVKRI{yL4~rn9n;>*aM^;!w-WthC>fCWhdg z#qnt88}J;#GUdR97^9ZGW?xvp&~^SNxQ>A)3VmU|6e05 zA_X3I*4B%SJ-H$68FcwGAY&(omOMYVm(TXI%bt^3o7j~M*-gr)Ymg`nN^@!2C;Rkx z6o%7BCGp7N(2E678gH|jzVYaUwf!VgO!-dM`=NhD%W-Wqfv$GL&YQlJ#dQ~Kg7K6+ zL#|k$?H`!^(6Lg9>_yb#d;#XWVjTp4}zPI`7~T)u|AXoOddz3(mphYvK*OjhfHs?#0Y zJ%&bjD@l)wKid5G(FsJ0>6ba63cRjM+hfFLg{ef@=_>q0q0!5bf4TW-LcvT9crFN~ z(hB;GMEkSe zCDQ~J8{jaftGpW6zyKlh5>jVOqx$0s_7ah8jm_X%xjp}VOHPWR<%N7LKgt!Z*HJKR zGPT+N{5N~w^ejBzc-eV5(OCE0mEIo(uFf6&bb%3F>oQbTV|+$rfJq`24SP$tM3U1W zO&K%xzW9ugVp1rMDv|E-KAt(q17sH}9B&5ZVI%y6ohB&@eE z8>$lTuF_q}u9OiMHIY8U3wDEriioo8EXzDEz3nz)bXEhTpVO z&3>vY4-WLs-&JHyc>9k+A1S>2=o6QmWDfYSo)X3Nm(O?6Sh*edGdHGyu_Ybe`O~U% zU5%rU;?L+yee8Sx4%K^!sV6ihNjN?cU@6GjZDzIf%9~@7Bpa&tFZ77FRsC8c?AEE2 zlE#TnW+PnFxmc8KCRx5msy{}Lve-i;Q+F}mU`y`bD>%EIDFJYqatasE;98Q*JSD<` zz&B!RExu1D(p_~c<1$lI&n#AyM?tFCqivbRLVP!e$@WkovsA=-7_h@e%mJezRTV(N z4e2e!{TX+fP&u5RzIutZ&F9@HYGS~T$IvA1FU3NX@+I9!x;IfYV{Z_*MtF;SdjC8{ zaN`Jec(zju4&A~Yo_!Zw&h6ykduJfz+lNh?e>c+Qqc=^T&V4`u>2VO+UF3mkL(A6J z?4k=6gRI5_ne_5jv7c=a63~V`XWaunYjCn5>+*Lobnr9>2og4(ZLJWR+|Csu5LPxb zYMwZkFs{xey*5Y4rVY@CQ({nEgcOhZz}+m#qD}+=)h-<;6vC125mEznT1E!Q^fvU^wx2j?kE~!39IL2u2*Np`Fw4+L2gMB; z_s9xCi&KaS$$8-Q<~_;A{+S|yD}eA(N2?~Jw=i1~Z;7&*$o8Wkhtj1WS5KCZ z`13)OC-dw=A&_bMz2inwpQlieeQ3BXa{pj|Jk*8Jll*t~v4m+?!7HOdYRHir-i!=J zA)!SFEAr-J5)yQfTd=uXLU|5y3AW^d1m{+{13lecwR^m+?&i?r?<(kNZSCkDJAy!| zE@@=!1Z4%xm%z!3g~7C7_~nsoR~)lbZ-ruUGmGCCB)I~TP1Vb@ zI`FjyfPi?PHnX~DmG!h6$JmPBsA{u(U!Sn+5`ajZhu6<0f+Imxbq=2Q0Dhvu4y`YY0Q)?Az2o)TFdqUk zn?6Xl6s^uc5$E0y+2~TYM>^ltmuhJt-W*>ndil2cRr61g@DrkV(_nZAsCUvyYXk_Z zz%sD{!zWV&+z=TWgnUPssfutjGQPNvg9ftO1Y32ysSy2rJ7C@pz{)GUpAWBI0z}u6 zc`G9Lda@!K_f)R{p^bA$`TA7h8WMi}Dp93!7}w7l1Xm{il)~lQ zIH(AN-5D1lyv8||sO4JB@;IcYyhDOZPF}t|8tw$~^duKmtv(rvK;sW9K7CIU&%( z4C8+NbfYizUmDoi45^ORo?&?}ZXuEWs}fQo-ut=0D0#`P7aD7h_0${P><3pTgb}C1 z;zENrokYS+zM?6RNxFFQgua>1Hp<0dPmz+~E<99*ESCd)Eo0q(Dx3Upm3JG{w72n@ zg@JI4!86l?VGm_Xije#o(%g2zYSW5^)^kf51Mp?WCVtAUI(aWpU2=P#l$LDn_orR{ za=RZV7yS#5gn&b-+RljYbk4fM+>-Bv^>IHrz#tE>pH#k6Rt7OeAYhPEF^j}43Rr=Y zYf`bbBeEk5RT|IdNU!OkbQsZHK}Af3+}q=rXK;6zPYQtm7wDakd@0#?lK5$E2d}-e zM{9SjOyt-{ADE! zFC#mJsfh9k`W+a5KQT?s?yRma8^K|RFYd~dRg|83bp?9~9DDr8@T0TadHtgkDFZNPJUuY?x6#CLP)7G8YG zNlu%VId!B5mpCxXE1g{CA-|~^${5Ean7pu049O#bvWo!1T9YGdAZpx5VwK7O(uCIv zA_D6O@nNsAC@wdK;!L}{_!-mp4Y|Y$avnw$ob|>~ovM{SK$W_~LEtPTX;J!*L{2n<6w zk`$Czb~y>(bHwe}00i)kPS+?oFg#tj%{Rd{$QPk-fV^;od=8q)O_ZxAk)NS)+C0EC{jt{P)>o@iPGQ4<^aM&P-YM;ML8SL}+7=(Yab$j~(GFUn!WjUy* zdt>9gmGYuKkH8hjc zM|ii^N3R%vpPBAxs)inkp}qqPfkZuK#Mof!FR>=WbJf5=o(4aw z8QzBvfd1r%xWNuN_=gbqCB3A_B3Xo`2uqq%LWWYnbwz-XTP}zOd`qLca>_vCy3x`$ zBfX)NP)9fR*RNyn(b3lYxIC$jqLM{3I*5qMC#}3iSk(-44oItay_!Ky?g`TVUbH=V_@q4OZ00q!_E6hEQYrHh5_C7!s*Pir+isS6N(9nkO*USd#4xGi?GX-AGn%vu$c% zw3A~UDkAuqLR@+ThFI_US|h1^Et5_?Y#6Y_gJ>PTM^{H1q?%wq@BP}X5Kg>H}N%;`BIoajNby>c5$J=Zs_s8 zsgBYP9`5`U`gye`OEz6a^zEek`1CUq;x`liqf<)my0MeeZ|UJq-_D2+Mtk)w2_;wzoaWSdE1<&HL|c#tLf?iY zm=U>=lYAeP(qC5YQM8Dy1d$)wms)03P70fv((2WHK&us}6qY4Y2EmmdIzBw8FMc_D zi%>n^55FWI^x5X?cS)JAJH0-w_kV@*@1S`QQU85+Gd!fP&UHuhPDA@GSt)CTF{*ho zRI*~&p$zGon^7c`F}blnG8Co()NwZ1UQ;LJ_M-vjDOYOI3WU$Ca9AK zqXm`d%evXYwXLtkC*vNH!9QD{W34auSDj9TB?Xef#R59%k0w;4TyvmaLVusDadFsq zI~n1wMJ3o1o^NTP#Jh|tdGpPqr`Uo{@UGM(GwceZXY|+Z`3DoYPf3g5MT1vRznXKL#|w8Nf@hZ3gQQ*oIHrE=sr`7G2P#6_L<4|v4yyT z;bG(mOKE^K8XlhDn*?*8rlXQGib4m%rNl>|89y`NTSMr|mxj^DG)dc1`qfnXl7+2u zzfgN7f6$Qma@Tyq*GiON0T7ZSM33iEmAaq>{1dBHGsNNNVT2k6&)fbWeJe3c zzv_K&?X^c8DgS`V)acc{cNIy!ivzZ=`X^hIeEIUB?jLPIEC41C*|k8h4)`0fCty9m ze8Dj5y68fns|cpxN?0S@x${U7>OkracknHP23t$z1YGqB=E|R~j>ing;WFWO$OpxH zMJuBzrb_2U8Vj85gB#{V#`58Z>@TVYfLq!iYW%u;wjGDN!RM13XFo6Lppzb0>^9uY z|T8tp*k?3{H)CFO(&-| zSWI<&zVBlwiA_rOl*!C$KYD_>7qKwxL(g3Iazif7JUkWebl34MZEG<~-Cc+mB4X;C+6@UN@xJP%ocI8Zg0TaA|b6-x-n5k=|PbIvB zOWZ^hUM||~&msL*C&yv2R*mYH%GFAq+%R4!#g}XtR(ny@CX!LASYIAROlHn$0uKDK zG?LC zJ_7w_CY&?SSg02U>kKi0lELZ#5(+yZnqW23mTh2QnpP`zFu)zOEr1^m>^BS=)o0F3 z*9i=uL@$SWAk9hD5~*9W&JlG-fV)*SiC60?gCaA?@EOb9YHSYZ>(Ma8k!>etL98)1 zzt@csn)XX8{h^Ny15@B_^b0$Bnw?`-Hohq?pL%S)Abc+$b6WKguRWw8|&|1|fd@@siQ*7XtFVUP(i^1V50(B;P z?HcdovA1mx^BOcI5w$;L7<80ca=v-zrJIV3^|ZRbl(Mkjl<<|)x$&Q`-8_)Chgy4j zjWOxzrE*<<NTu0>~TB0S8Vh znme%l_#n^aNtI}((?FAQ1SCzxeNUVSS8t#T#QjIDC&Ajo2*S%`EmDR=#x)R&rPaek z!N`_;rbfv!8fHyGCi@bOwO|`6XeOms&4|K^#9Rtwgl4GD<9<-Gs_L!w^4hc=(aN7D zGd@t|!qVede^i;7+rHV`9mY{)xkuAKn)aD#u-Mya_r*NV^cZ5pqs1dEb*SX>A&%-n z)p=|jVWD#r^YNUa`qq9T=D}{XWpL|lPA6=0oja)8jb*=4E|%{SdZ^cv?jP3kvjcdK zv&&s+EGsAW#pW5i!7Lbk{rJpzHFt6BB*?B%3%Ei&&zXBlSSLiumN!<4XMgWdPWbh* zSI@x~S*KPG{X+0K*mTNnpU{v{q2l}e__b_{2pfzF1IC=BVki(2beYWDN;~1gtPzp+ zTt+8?ZM$s;?DR*(e3U97X%5H@fgcR!=yYCkZ?15C?HG{R`#BSnF%VJcFP;Z4!_CDB ziI>ih#?JhtMF`}3i?c*ngGw>_Z&+s4yEY%jNwG&cO;2Yz)6~C`BP=0{i-zLBNI^yf z5$e`=;k6*5eP7OED4c;*KC5Wb#>rTR*GYC}D^MaO7a~bILX+2LC+lgl(p3g)0IQuN86ms3)H=2u(&E=~&9+>= z=&lyD=b2Xd{Yb&9--0;#ypvp1CKJkr6Aa;5C)8$CQB*->;Le1MvFY7hddyI4_mwz{ zf8*zR=eJ1eBbHv}EIbayPTLVA*&7{UU%bZ(D4guvvo4sjgH~e%_a*;)>5LxyJxMcf zHHL6+=GG7D?CJ5P2{}c4obp*=8o%?k&g6I&MtRa@f+bo!5@kBI(L<0Ok_vpKBKh6S z(SbofQIoSZPiE*`EC61s?d+P(V4DXTUPc?KA#y`@^gzq{_Gi_T_xN!_GO?&*&A(ir z`c@~d{+j9{p7IGW{=n?repdG#vjubdG?}P;5K}kP;`!>o?k;$H2GB;0MI+#EUEV7N z{hr;~Xx5AWPbT#$BvJMhnn-{m9Tm;F?Gi>v$A#NRte#?mO`m0W(S)k7Tc&LVR41); z)Tz-D6jOkf{1C_kNA!s&CAnooMBwY$3l=2n6WxO~?W}#(-UhH1gW@Tuwf_<3o3w#9 z)h2gF+WbA%J~dIajM7w=xsOMZhlkg8JpeIIls-y$LtMQp5!?WxHi)#*3(t)k5gt8k zAh9r_{eW%wfy{oY)dKoZTK5LdIvh88XDN1wrLai_;$-w|hs2_X%DU&29+D}xS^;Q0 zKGcNz5P@iSInHTaEHD;KpJ+a(qH;LbAx(2vNwKAW&o-rmM>9t?#cI-IOUR(~BgAS1 zWR++ZQbJLYsqn}S++TtO$%#%f$Y1Wr4nZ4zT+^C9Trfk)7*l=Y2s^aw@LVlks*SvA zYoA@KPF#b0lWXalTa9_^)C(gxEuY#6U8^hZzt;3GJhN;QEvfYsDHC5UqWv0fFhcO@ z$95{HHI7JAr#K+>JzxkS40n1R*LJu{7#?B~AO}_agrYAsk>hHe-n>2i@j4ESm@+A% zTDk^8H};&)F`AhFQW>kBYbCJ_{(5EOgAMr^Cg*gNJj?9tnDpFii^-4&tjP-Rooe6r zubl*J*$v)P#RL~-3)G54IUDep07gU9J%UwOH6WZr)iGkvFym#iJb@UhqWK0SqcqLR z(-MXO30_o9>?$}OPNf$OSC9!r&wGSWacJ9sXert#IdCr2*9-7|jvB7acdVCHwjkuR zW1O_=d}%omT9xjHEK%SQ+6pKdvf1OnLRI*xgj2p9rP_{0AfE30C zkrEHjqYwy2jzrPh%MBPaT_+%9J%TP8PG%9E=i_b1@cyGm`L`CytlDbTp)YnygRO}a zq#h$i;Qn@QU#2wxNw@L~*g4!>gW84o(l=iRq zqps#R#EM*9`x~l4gHt)?Lurrn2QTsdZV2uG@udlXc&QG-SYqyoY)*7m)~SEf`ucV0 zo14wcejteoJ=!smOTCJx^MZ0wnbKTUvlMF?;Yj21g6SjL+x;f#Ufmm6j!8-k!|EH~ z6m*4>JOo{y-iyDrG6ODw#jVTqS2iGS$f^#cpAkyN_%yTWD)XF0jm3ybuUYXOzWNQ& z+zvUmx_H1KgX6S;mSc)x3b!tR{y-`vx#v&X%L^}@$7sf*v!L%mSlLaOZc`cUP6$e$hiDtFd(ul0Y`!|$DwcD@*=JZN)>iD&D5#-P> z4dY;e$fY_VW;i7!c=nD#DWKPfy4!t(^w!3v<_#!}To*xgJ zRe)sLbeC}}mS9x@8icq&4|Sb!u3#LBiP7k(hV}Fsd9>2ns#N<_TqK_KMV30z(J$cF5Gq1Yeo4xo6RS=7EJlJ!ZuK zr^5=Wb&nE2PYsL<^>_F3w;J)pq~zUUe?4!TWrZg_dX#|zFy^EUf&TGeFG0!SSm+5buMhS*~S5kf4JVk;GW6=k}k;#|5v;ZIjB-NYdC;jCm{8 zL+z>^*VAgi0xErJuIVsms5C(**;B<|b=Tr0H&8VZxUri__1NjnNlzKmdbI1sh6Fc% zpwrqAo=A2eaSyGqXMg@cIQANmp%jSW!nM4#gQn9MQmBRoj9s7gl#h;Cf0a>;mq7|d z97l?Jq<9Z)xbx1-q(#8zV0XRq`%6%gkg9l62eUF1$`)N4*+sa&{(;TtYZwfl87;4X z2@q#Fo;q+vHSavsU+|HBa*`(v^^7}d+(ScPHX?am3)vnz&ys-(#R?&tMa?@@gcigO z6)-gOPkNBsdG!bn7@(!xGN+MBZtcGqv!p>$gN#VZiYD^BnMyfj;iFx(Db}dFt7PB} zkpsQ7Cnrv~mVvBzw{f-!5gpp(Z|tr$`kvL(k0?vj`?uoDIorE*eOP=~MWEDsFhK=_WSJLM1lUvr%6y{A1?}(NB)cF#8<|^qQ7Zt)N)zz>?Mw*!6 z3P8z6B;{@1azXiR^4{FL8&tyj41=g#Wb&PrUv4|+M4*5rZ}W5joVl*Oqe$8df^-s1 z=CcNbtSn8C73~2VEJrN`4ka-xezfm35-EVVzYc&R@RB555a72`pz&(cS0K=@k7Syv zwr*cazooXb;+9SuQ-PK5UYVxY0WM2Ip{VA^lim2jBj51Jp;D-}*aiH9KV;{HEQ_r5 zr`Bk+F7n+&HxvkqHliFC792fnYExJbrmv{-3(BNktr&9HBt!XAxV4TW{}~>>^D6+;^_3K+iJ=N0drqUm_d|To2EXCN`f55Th>ML zL_3-y@ilhXh~TAJU!AMZmzb`Y4)Ms*NzhUsVfHCR$+`vBSc7tbM`$|q{cH6#ZeBn2 zopUfPTe)8mdnTkTv%0U7gK`=3u?iGHZNQ-+r66#SF0lk=P(Mn`Do}KTH%9^YL)8LA zlYt(PRZio00DYHB?ej4&ThyGLWyQECwTTU<0q&)`1#QV=x3GjLdTcEeswOv>nR(vO zHSM^*B?DqdI?wXOwea{A<^xeCNAg#@p@9g!hu6C4dXxt#zt<`KIEq|4AVcTjaZws? zfUA;wd=*QrbuXDPh0XMY=fhQ$6Xis#?f5TeN0x2U`s4mLSgXyyW#B6y=IRk)b2_}z zdf$qBwlK3#v^Hyx)8en-^6Ylv_B#{w7G$@#L$Aq8=aPZtZYr%(40*J4!RrSm#j!WQ@6; zim#{aQQL4-ss3u&N$*2$;=mQcN6Li zU)3w%tm(265NwyboL z0@Ol_LytHA>va9CTV?H&yACl2JO9h0la$2S_*~h zG+w;n3?A|A6BN?QeJd|K6$vsC1AAgQyidyhVj_vXr*0Y?vPZWrlVMy%v!Xk~=1HMT zj&6vG`J?M*XSni6t2U_e8?$8zvCq&%PCrhhejZs1sguf*sT|)(rQEyHEhO>2lo%HY z+eBI3I_mGYAmRJLTgHMosin?^24lI!X$cAU5XHI}jzyyTpSM86o2ZxonCV`93Hb3w zp0ZEO02B1QfFaX~u_XBk1+mSK(r7vD-Jod&`OXVbTD!slp$-(v5c!XtL%G89!m^>RMv#UlW5oZ{GaZ0J>Ha6@d_K!jKjL zqa!XRYd(@{&FqnCQHmc~_Lyy0^N1uCJc?0=bsK#8fGVJul9fwB=zVKDJZI4@4fv2V zm_-7zo!MmKSCtlIr%$7ypB6ZoL5QQd*T;b)WQa;3B)RsI5W2LR!s=Lp(*yk+xVHH( z$f5fKAr+WMZDa>t`iVz&z`FZ`TEPejL#fh1Q{3$sI{ZAd|Nhk0#CYP<3c>TFukyrZX|F_`aD8|Ljf)`L4>;$7o1#WF3rN1Uw! zo6aHG-PmDGgcSPzndLwNB!rV#clijE&y$m2!;OujgU9oyH_KZ@?vr_==)MJVM7cD} z2UGqDB~nJ*FIt1kJa^kfMR6jnbTuPikE? zhFIzYQK!7oI@LE=T#x2qwQ<JQ^s{AoYVrWpn&?p;Yn(~3Yp{5Rcu=3T6 zVe(j2KAplspGg3z8z9vDgnsiJQj{4aB&NS*vFsXN2l*8}G#QtI>ZQqoNy&(+LDOuL z^PN(3%_S&Ws8YWgiQWCoj9BY) zDd~eNV{U$k17lGTs^4b@0Z?DSQ*z?PVf9S{f|zo4MVS>$$68bpU8w3jp;h=f7y_4DlW$L#V%T0`&M3%Y8)PPJlgpuO4>?@MTh08pkn)wC7hkDg7M|7 zZi#2*vV+#^=6t=TB*y{;nNqG5WBYQbWK02HJ(_IrJTU!WB3{qD)w-?(wZUgYj&w0f zwHXge=jKFG>Ds|~dj4W##cQdT@_pq5S{x^wG!CD>{WVCn`E3SiJBBmRVatA$d>m6r z&!EsCH#JOXimt24%r2)8dIlKz1Q%Sw=~Z(ntXPL1&D4^j85N;_WVeD^mCYga z<=vWceDM_7G+I>>jg$kz?Smgq}FaGkc}WAD6oFhO+p@L?GT9m z6x2d7h!5TxScc^;t_Ennpz&VoEA}?_oVYs)$Dr%g|!leuAZ_li=+_6aa zu8RkT&>VQ-yP@<-Uf+|f7ir{Q^U+G|L8wg^xG^iHK~rS9?Ia9&i__`g!AD2qU4;2=-krm^6jCZ}a!wM}1kF1`fF$?dOhW^BDQyfJ`g$mBjO`Vv-KGC)1HzM-#d zu-K`!&+A9mx$kEdnD9&3GUW4 z<7y?UarU&qDUK9NQ^tzF?0L$yd#ZYl=89v`VpTSIUt#V*$1=Y&D|V-~`n~nusmOYb z-_+Fg_}v;W7c*jpQbxw36Ez9ad_^lU#x2yy`ko}go8BI%G)-naGNp@&=|GpRFs*T^ zb5`_=rrDsbvj1tdTYuhY;WmAv_^*-hOzoWIA)g43E}>3j2t zl0E@<*X2tG_FcFr+xC~gmdz3;uZ5A#PmvW(46NW$7>~#;Bw$8=-c6a(pz(N?h$GfD zO$QH|+1-9LyxlKKV&D9_)L;yFzetfeyT&cq)@$GP+sGVO1-Ic1{RwV_=gRW|Dn zSwyyI##W-%%{yFb-BtSe;YC>?OA4I$N7Bc%I1{ks%o2o_IHEN!sb==W^ZB`&Fa2?Q zLsnrTJ!A|WA&YEV(+EGvD4M83zk!h^04;-v*^>OW6`S0p$(>ZN=1e0J9n7zRb)_<2 z2y|P`l@J^oCwh2{^6~z$!vhAZE+Fc~Yk$(Sjk}LPs~ake;M|_Q73W3D)0%5m0h^Ub z#&&s>M&W?xzeW@Ofr;y#a3E}<>PUae;G6Ps%g+%p^i%F1mQOz~BbtHOnJKW`i!A_Y z%irhxUh$-3n-yjwJe!2O4*HuXr8<4vE`SGs6^IJj-`gQ}%Z@?D?smRl75|^BMMrWM zg-T<=SeW~bn44pTICOu!)T*^hi)dHUp^bB&{da2W^oza54;O{~4gal=15>-=eb2Bp zD@|CKFe4cMQrP3JmQV+q?ch!1>O4DpM&`Odf9)KfmiJVYA7%Zb#ov;xpT;{xaWvNdV{= z{}_bzs99cFbHr^{`GT^WNpgz=h{9c0{yMj%ar4WsGr8r3EzOUc=c{)0O#6CL@dNIA z=@%ono|&KD!A-eeB!O?RB`$c!4enmDt<-D$Qz4?LP@S_(WTVTU_l*e*`BTQ5UYc%l z38VjTE_wGWvgYHUK%;Q$w#L!6i+#kmWvd0<$e~+PVdkk)cTuJy zO`}#Dkf`_`Z80N0jj+wowW>+%H{zhUf(%4aF2exXUby8Y)^V7=LtERUqc^U%_ctPl zCwD=4op4GEkLZ-!{XO;l42=Np6DD9u*MuNpV|kv$0&iyK6Yj|Dh?Q9*;ByKy&extY z(_pG(BB}pgmog~j`tpdIg|u`?IVqh`BW(^@Zu{?ISxEjX^t0j)-yQnU3CF?@5*3<_ z%yzz7hfq|-zQyTvrL|1Kq4BJ6+g|==)|inp47bS~;l_Ukg~``WjGa@C@H0%|f5-k^ zrOFTVuf-%z3QXh>y^v+nY_3vmJ~Pcctjc!-=O0kgoU2H#k%O=#7l?@*Q+!30$?Uak^Xmcy6vB3pS=j*rgh28xA^dJE1#5(*r3VOBu$XITspqnQ zYgUV;cm9e0nQ)NsGoHyQTB9*=;XiE$}EKCH;a`PsyOAHMy4N4TeSLXKLwTR2z z)xO2WKy2`l{!FlESLG)PXYjknb|E*NR%h>8q%+@8x*IV>$kW` zuWTtyRzFWzTe2qBLmS40sYbGa0&_!ykKpk~Ykhotd~2lVi55@N;+n(H$46s>*9M1% zr~xc3!U40=CasjF(mWu<7Z?o&F)X$m#sa+L=5FMllj<6`BQC8FP;^E6KJx0H;2dWxur4Vx5|ek8;5n z7Mty(N3|#lVxp4;>d6&EU0cknK6zj(vhEr9RGPGt2kJpOAW=g>cKl(&vHm0ofy!t+ zu?en^S<;HT#6>H}V(_~?3YRGA6 zsjZP5Ip+DHY~#%}Q4_YNnd>P(DFnD0B^MwA&m>>^EZrbx>-`ZprFS?3AXgv$vl;c{!OG0Qz|0a6@ysmEl-4d*3SJUc56js8E={~E zBtNJD0(QRAj~+(fz))XS&scW$0Rb3S>Z~y^-&Kc93!tf)LMh6H&X%{X+yaiNS8!Ko zc2g-u6qhE2W1v7dbRtP8{2_Fg3&8^~>!q{Hv2K_W^aAw)Il&EEe%S1%_YZ>*Xb|TQ z^EUvCoumC7t#q=MOmFSjXLihex0B(Q51<)&-6iQ)TCPWt zI??`@{_?J~o5y;?2)G$>KT|xP3hrz{IeqinHVA*Q_D(-A+;aOI9@+}-wipRXDak$3 z_RX80W}vBj^S)In2MNYxr;1Yxxn{R_=#1!h6TL_LmdLB2x|z2)ysG@v0^Vdry%Y0K z@DC$7Whc;(-fps(%vgCk`kfdSkBDJqL4icMqWGfh!}nsA=#8iw-|9`k3)z_0LX8Ei zMue|1Y$22Z09v6q@@VX>2K3P((P>V4x1Tqj#u{<)lQ&of>;s;@?`X>-`=h{!cqrufbLWEpLIXk29r^r-j)~*77z<64r5A zMQ>~U-=#@JOQJPSR;om#!nf(Qs1~$u;`6J0LWCUB7MzAB(JdcTM%o)dD>u32uv0((>-9@2GxTF zksDYa=TO}eGGH1A5HKq?_5gkjXz$XC^h_6%587%%$@MH1d9DOmZF0j3~?vU_M z@nCykF}+y-nz(>aP}bp16`-$MD}wJj)|D|U?T|mwrPH7b1%+t|*$Dm$r&%;)F&Pf> z_)nTkg|j?awc1+1Lf|rt*Awi~?&BFZSURu~ZvQUom9~DI4Q~O0^3hYaR3ljugU$I}{5%R@Z>EwDG=fH_@N+W8&KjY5I zcU1)HePuak`iw3&4_%;hPr9a5j~-;Dx0>DPZfp_o0(GKR?`tFn;T~S_7Jf)<^gHEq zl|-4jH(=&1&@NYPKv)QH3fE+$msU)9}= zC4R~vJCQOdf#T4MiRAFDR{|;NWG8aQr&!|6x>xv0LS;lI9>oVmT8!d3eHyXDTkYMh zd5uz`ZUD_9iG1~r|DL-wwIDZ=CrDIx)fatbvJq~E2;{aiMlt}Q5 znjb@SYdrGTe->yL$IMhB9*ecFM9t%|M)zY#&5T=RPCRxn$7ms$+?{MhP#t+75I4@8^lj5I9QkeQi zkX*SEfn8|tzcsP<0?3Ya`;xlHSQD|P(M2W@-io1fqY>YCHrPYO_~kD3zV$B4@nUER zW^V9Y%#x77kd*`pF|>F7U??mhtPJ@Nt4|WBLWycnPzqM}Z>UqMbxwYZZ7SZ&;$^9` zc&xpxVbY}Z`{@UziaG1VNe?2QB6Hfca000!xv27nk^!mTYEd;fI+szsxlo z$;Q%Bhqx7eyu5r!!4W%tZ=sP4=wWgoIfN#>f3cG*=JsZ{sQzw9GU#trOLnh$E1ehb z3uz(bK%ST!8u8kLJ+^|hOSvI zFycg^`T0eCA3>X^Thfi zON^cRC0n?$+%2(kUOx3$6V*#btewL8((C~t-@2eNNxLu% zgfv~u&qRaz4cd}pyE+o}lSjH`L;@?z%O8kg<%kMare`W)@yZn{I4V&+`gH^z4c0D$ z5GXS8M~SjJqP0Q&Q#T22nNv-nmq|vHF-!viizz?p9QBC>K|JVCVw6c2t6xy@kSwp4 z!8pgT<)DH*@W@N=GtmFz9JoZ3>K;y1^-(|l2eL+Rmk)*z-pqzO-on6(Q zv?<0~%^H!9uugB%%@{7@9i@?{m1}2!?+zjLH*|jTX1VRcjrtI5IlIw?;0AhK84Aw( z=%&noM!hf5?>Pzv{}pgEb7^Fk*E$tpSHS=gkwt zVsOUifS%{k%0MC^Kd-pIDsmMOO6-2?vD88)UghS#fN3rukh;^ZQ5C{!?HdgB%lVk> z*zwV}ZTO#EmUoh_di!7IT$t736WJ;CiS$`=UiA^V%GN97V;93*Km3ku`sssf9=lCs_R$3`tR!d<(JOGeqXO%S4FwKJ>A@Q-{G?ZcJ^JmG!jrDj4)OnE5r!=t_zrx zNI$0Fx?iebg#n5s-O|`uC)oa?$4aYEtF>#B?=1PpP#}_h0w6qQ)i%))`a2xiq@@bF zwPRY^(Ar`p68H{l)Eci^@gFLXTKy<1G^<8E=8@f9X3ra8ZB@CFT72TqB#}lj4g(32 z1@jY-(0>&3DiQ!n!Y!#oPz_J85HNC7qZn2;%n`$q@$#mho^DgZ;#rj-#dZRAECGO~ zXU`xT6PI@AC?TP!Zb z`tisS1I3VSBpZ8rVq*SKw)QM+HZ`SkJ0BGuIbyqp*&93?pp+WZojVX`#9(7LR#m-y z+sL*Vv^t(rn=>fRI`E8K6onMD20HoKfzVHljdX}UfyY=~{fo-;@6+eQkA|N={r5P^ z7j??R)tqmVECiHjC#RW`&=?k5Mit7=n5LmxbWp;hqwE;Q6@yatFABb`r9lQTuo7sa zV_LNISR^jMx^QxhBwk$ffI@k{?MA7DC8~4RCGNPQ7_)7b%SRe=l}v$tYe=l7T=I47IeQQ;zTa-vxj`rg^_|H8aMAH6xLF(DTB} ziWdtP7t8Qox+18FGgy?7##NFwWt~#SDgz>E*?K8~tQQo6S;9ty>#7QBDmuwm;oCf_ zDE#p>L8^Hf6Sy^h}G6p&{NT64GZR4 zyKcI;&^!eN?tPJ>?^k{=x7VDFs%cO~!3-itreUd?R!wse3ubh3f$B2 zH7KsXW)q%H^4pq{6%$Y#X4F^L=sK!VS7Qjn#mS0E-tU$NO+boG;}(%?Y8fp;g15QM zhP&Hdu3RB*x4*eEl(1?<)h(VVFH^$e6H3@$3bbuOJ&MjVkE(T6?X2jHN#7q}X&fvo zW<06_-dxjfq!0EV!H1F?_9M*5(HOA(RiwbVmj16KNDfI>0Tl_`2xwq#JNb&ja3Kny z!UOXMzdeM9bSx@dqVo8*)miT0Pq>u{){7ZrhE^0XcE^8w%QZS3Vt7j=YNr_$)~`XC z=$az-0jFmshP+Yk)?!HT$w~0`c3u28K?wmePo2(FRy~%~lK6+k45yZtt0*dKLh6XR zk^n2txlpYm*7@ywLgj-+LRtl!17OKq?N)i8*W(iAJW=kyR{XKM{WqRP!*A_Bsk`HP zv@9-6GSKFD+YM0W zfK8ji`JNKbT(Gf#29-jAVst4)E7-JviC5lr4s2sC{OhlUm>tNTwCOb%Wgs+ZW5qpZ z#p8OxUz^<$w_kHh+Fm+Dt22dk;>@VxvBh`A_#djXv+dvE#lP2&)uCcOZU`~e0W=5X zqL2+AV^Q^&7vB*RzO`qYYfccvcNbkQL1q85QI=LuD`-|Hx^c7jUEL8^FpLabrEIy% znfKTqg$3_tC2b19W7=+(nuUqyUj#QxxvJBiXA{zpbiTP zw~RZ9kHg6Gj9-?8eW=YDa?^Q)`OhD#$mVg%(lbw~LxcE+NBZT5d@}H^0TRhSEZVv#`^9Oy5DR5wimXH_=jf0-oRN zsm;n#R5>mt1i9%}?5@u!#@=X$LE>gud39vG+yyu&bIJzwkoC=iFM}tV_9*0;g^Cj`8)0C1qt_PlOSUWm%lw=@D zEwXWx0gjn6D6|T%0YHP~9~@7Cw6GAzhgrQ97xxn4t^7`ou3o*ySIPyxbMA0VNl6Us z9(tX73|!~KF^V0e+XuZ^EndgoY*bIq#y7{n>a#TOWq_rf1U3)B-DKB!92JheXo@WK zX=E+Z<>*40Qkx&zvb^e4a*57lq4Me*<2KS&gh$r&M-0`lMp$rIocG~%)6!SEJI|lg zIJ@um({}ER^A3ae&$Y6uPYi z9F21tO<_?^4|zTP+IG-;(JGlmJhi4+diLxpX3Z($EURSAY2s{n%cA1I$w`|EgcGOy zi?+bCiKmx)W(i`lJT7{aN_&M^jgC5=L%ihmxc|l!dyTqC4j`ok>$>P24*%8+V7%x^n)`+v|Ni^e z^4He*K>mPYi;o?i(*lP?i2ASsZhH=MM>*kcz`jP~{>HnGECzul8*oBw2gKoo`Vc#? zBHRXSeuThqX6rkBgQ|sps465R-*vtV`FgC2YpAOWLBda;%>7z7#w`h$x`8i5wR@VFj z|J-REP^afRM;v4yNSU)}-h9mUYwTEtso2Yl2v>);3wil0O>}t5(4OEo z#2c|0)3j~-i(3E%VQb=1tK$d1T2M8c%e33Q z21mqo&eRj%{27*E`({0nhEe_(-W=3mvc_9d7N(LoG=n!Ejo`&H#(jQ3X66d^4=f?; z2lk5U8p+-)XSqP8ERA)7Rjsw!pYe)}J~jJ+VZk}bo#PGthr|R=z=OHuUdQ_Nv(bbR2qEVV!V`gw)ezw;y^o>RfIiT>OIqIOrGS2ES!+G-O0yKC6YSFC)d*Szw!T^Kz!Iilfru<+>YF?fg zFTQ&>pU^!{AmrzVit*c-pi{I*Wfrr)YSkX$C>_yiUqIrftOC6IvL^cG`Q4yKB_L4S zv`C`arL?m4I8W>yedztrI!rk40VByQ2DW)oW+C4I5dSrWm(4+>g5G#O9LKF|US7NA zkPp}Akfy!o=yK!ebo6vlZI+qHyrOja3Obfvms$97fqcQs!UlAzK(U<={Qh}L$c}c` zEUR;E-%*3J4ss5jSFAK@uQbK0OTP5r-SItNN_H^#$%q$V#;+pNIHpL1Z_4Sdxivrf zZLgn`b+v@-vqQ6P!L%)gb`sOg*NI7LFWJ|ew@$Oe2e68JkQ!;!0RAsU_k?_+zh9a; zMZFfw1goTnbO&`0jCXb#^tEYeAi@K)L|f|Yt@VFVizz|pLuJ@@XT};#DSG;OR7?N5 zC8rw{^{f$0u6Da?{OmM~sCNdi)0vHC1I5>7WW5o4XH3>XD0$jPfp=z7}@f|LXcvMIIy^73)%^g zG;u@Ho?#ZP3AjgoeMHMkY^(OGf?E-FG&FsVi!|y+bX8f5X6=SJN&SU-Wsd$Fv?$}3 z`gkn3o+M4VA?0?4OILdV>-8Su?lQpRSdKTeB`{^S=MNz2p?7?OccRb!sAK6n3)V_+ zq$H-?NR*e?cleBFkNa>Bhty%2v(GrN{2e*4WA7c>#1(8={BB?lt{>XC2r%o1IoO<- zFWIwceU$-0rR(=dSfZt;k;vAP2^O%O^^@-)9id;Qk4$yZ6K`-dKsT2IPr#fpOaAbG zNtCcAQ;2$(d{KRjmN3naJJ+DbjU0a(dm3LyqHR~`)5LpX@H7Q_ z(t8rEpy6Zoi1lfT?KDzd_!#B&YdBLa)C-7*ArK#E@IU|;>G-KKGH{uB9q@$a@j=jd zlql4xqQx(=SSqo0I~GO?3$v=x3TL9S?6{U1pBq46aeWcTunLU=E*LYKo*nwUo*2Lj zaE5&!JWn(BE+VG~kf`G4jpM6Fh>H^DAWUR~qhpUMLcP1gVQCp+#Pfyi*|6TRXDD@O zk7IppMS4~|e9d(Pe2qA~8VT6ZsbJMC*pm;$X`l=`M5$#`AF<{@orP!HM9_p5`o<`grVOmtkE~7h)E0 z@r z6(x#yuFtB;%mDj8*e7ika`fmgr1fbbM>bKh8y4q1(r|JYZxz)kTsM4HdUJK5d>->u zXsxqMe);u%)hQvB_j0jlvU$5ZpG1pZ^5jmGExUN8MyMWYl==7mm-tXg`Y%1toS-9i zUo_9V#^z-O#qi7(t;c423wcp9sj|`IjB4NKmzF>JU$QR=WLCU##h8LM(z0y~J6+9r z&P^e0GBSKzj}hD{eQ}lXfqr{X!|8c)tZ~1Z9vxiJyc|W_uJaTQt=jY&LrNq{I6Y5~ zhTZ-OKS}JPZE;twx8+=-sJuOmtAmdHwVD@Oi#1M@u2%U-jjMu>epsF9QykA&She0N zjeF4ZK(26E?1!Fs!>kp?X&!MwVD>D!dVk~5r#&1AF_DCMZK|emDCc*zZPi{79Bs@v z_GH_d!Q1o?jH@q<0?_PVKe8VGmA-*&15gn`;1KuV8Oo0$i0BWH7#{Dxpd2D2h!lR z)?=1H@z4^?YXTm5%%N1RkYEqcW3@l?0UM(6ay@-yJxRDWi;~oY!#?gvS91DIt8trdT z4AwE$zuW!Tlxx=d(NTfZbMg;{ADo_sU7YJ-^o+~kW^udq`$iU%(*pMS)WMQF>>bw#CNS>P1MAr_`gWVr!nT*nF4-&mt+=FYSVru4ZJzz+3O&08teD#j@ z&ehP!f@?A-(Qf%EAs`%3R?OO-ep9xHxCS55VD|LvL6Jv*53mAN^904WtVd=_EHi0X z04>k>9?mvzEWXn^A{(*Q|wocBgzSLGU;kv>D{k~6(~9;{#2RH(^Ho^e95L_ zgFtQAz`)pOzxNteuEX4`3$|@5sCHl3*sFcXw24oBv?j7Rla7cHI;n2^!}qJ3vKPO9 zxV?_#w&iLDB8|m92L3+LP)B@3tZTS-{kQ3)DN?= zcb)xK;n}y$E22EHJi=?)mMPw{ucsd(k0U?*Z%F@sy3Y5Y3qDrxG*uw=*G2kxdU*Q8 zX#J&v)Te@2e0@6VE=$V3&z45U`zk!Fe5|{uP~Z4SAOl20KxVkYVFS)03^*R3g_=f9 zMn+}0LBCY4ms3hm-&8rng3v0WyjRHY*u}9l$MKT?{5kre2rsaQg0R$d#FH~1Y zRn8F2{Sfu^k%^1OR`)vX=s*cYOd$@hPTpC5ChW^ed;uawqDgj?2-5Y;tX;c)irUPn zTfkUZOl`)fF$zc|SG>~c&)<4tYhB&eaAE+QkJaD=qNCUOlQQWu@@bW-nL+<<1rf=6 z4J_`=`Q#sxhHm&at{#JF@Yrg<#D(nF5? z`$>*N%9VBf1Tmq%J10~b=u(WGLPbA9D|(6p))&nbb7f5vDt2elLG#d1%-N!K=WJyw zM;l!`rYDeH8X9joQ%TW0H&5z-_vhy!^s)Uab#`0Vbd(Hu0q!Oo+K3Tib#-PCYN@|X zXRsb_oKbjIMr*=^RcfKs^ElDy(vg$!Kf42#a2{aJ}I@L8O{YbyodYc8KM6Y=JSlaN+|Cd%HgWmofJ?3>5cRp z{ICazY_xs&TPS(wZT#N0e}2*3(B0^=j%EXUHFSiI7v5OD5PyX-`nh(6V%%4wN&Qfi z_`|EC$(5R_TrTk)#pEaGKtm=v0%ltG{B-c+t57=sqO3jYm+1>B-x4n3e3NCfw)qru zX!2m`f_%c`?)xQ-4U!GaO~-xn7({*7MLl+_`+N2*PpVqEh|WJzTXy}=A77^Oswb*X zpRK(azCZYtiZgB<>UJkw`tEj1c5h-nTXg;3JpKK-n^AI!;NE@cRz|U$#tGgZezW%M z>FN`NZz(T-{PTKQ?Fl}8(aNf%*MXqMFr zX33I$aTj-9IQ^HXcG<<}hQ9jP{L^=}f!_b@eY_14l@&q@I{ZwOE3DC$y_>aLG0VTO zK4t$Wyxh1`j_0@>{Cw}!Ts(VoEM^x#6Idr?7g>0L;S2Er3sd2|)6t+(v3%xH?)5BnWDA9o+n}n|y7wALR!P!}D`oTBi&;1}&(mRu{6{PaDm@ zS+*CUh&9&N8^O)xI}Jn~yHlm=^kNLeoxiyx(UMP$o$KTFjh!E%CD$SVysjvUXN86? zbc-uEbS#EyHtku9eib_m3?svF;)J75%)oGn8|hlIJ^_)K!`Sg*t%|}>R{YM!1hSrf z5-E70U8krB1c`{!4j;z;4{NXNj={_E%W#63{Tg%ark0Uc2E#WC?k+W}DeB|o*f)Ihk>WHi2>#QP%Aaq)eB+&3ZqWa*f zjXBIYUH!p%V24&YM+rpEMxT1u(VL_|V=*C_HIy6;f$aOWOM^YThN#NzI-Ad2gw zWL(;#pG9|w|BCVdmn-EQiKHcAq(xN8?{E-l+s(p{;1#gEnz;ciy)$d(u5r~7Zvb(W z#tUkPs<6xO1K0)t+*9SK9|TyOHv%eP-RYvB|J7_GO6445aId*kcz{V*$`7Ng+(7Jb zr(P7kyaY(3wvBkl*}xWz>%T2++UCgujK~p0v5oxz@SPhq$sIQ7{jjN&UgPqfHg}y` zm3uU?)#MGH!+96D-j#?lI7yMrKq(R&AuvW)236ha-^mfvD~m4!j0AA*I5JMtM>)Yo zjL$c8P(~0EWC3*Pl)G%JE7EPILbJnjhmY~r4URT$px;w14MHGDYpsdZE{^G|khCgq z>0KquPaM4+=*nEcT&?Gl$z1*F*Y>V~w~qa_l^F9n0gAzLMgebEd0PJ)EW~p^x7xY$ zAnY4RkP`-ukw9+0K!yIiiTwUd>ps(UvpEXlaUum|Xnt2G-FIS8$hj$+ z%4&x&=@r=4;Dm%=j&-MR1&H|I+jyfBZcjdcrj35U+4D(r&-$r0pXivUN}b*!XX-lZ zAs{-^R@KOAG@Web1gxcHL6Syh2Y7Yg2=Q8Yf(fEWhAFsZyH+%QB@Vw`)AyM_w(~CX z+hO9@Fs3U>aAi6ofPl%zFDoKcJ;xA=mf`tao-b^rC;o`@(2Erx5?Xf4Z?FOi`R{ z!6@pgtZ9Dz?QV)#j2E`uWaqoDX;rgLjG5`S!tVI%bqYctQ)zP*x)?%$3UFTIVw-q* z3Yx``C>_Ev1`_oq-&qVWP?1PfIYBA0OU#WOhEhDK)nri@FiZwL#NeRaFHQf}o6&dz zWN4hz(4KRR%Q*Twi*^F}d=4cekqAVR5h{hys}gd1if~jq4Z?>w1?Objj86N=L1PLh z5ixi(`uY38h2lDZ!#{Ln8Yp<7%Vqiw3- z9z(o2Nq2$FX-AMx6PN!%SE>RFqh`!NSV&EcS&jdxI%5UXr-T39j;z5ri$w_-L*UGr zfd)*1NbHPRa|DIA(iSpMEZVpb6-b+$qy?gc<1`kEu@HqBLlN(wZyvYMX-xV>k&}}4 z=@U)qB)Ujv(&#Nt7;qf)LI`A{8mVRQ{3Zy=CfX1bz-{wH%c}jB=ICro{nXwPAO-;+ z-yC##^StjygDT=-A@Riu5XXX$*u|{S#2R5a9#POlTF5(S;DxhBKvj58XJFi?;&;MU z^%jNiia!O$=`H14(px6Hm5KEQ1!Tu}CN)WI`tBbU72YH7aPM(j09vc}l5lqk&Cn)X2vnptTD1;n;*0!52Xj(3a?E zrLjgv4YZEMx(K=?B3H1K47g2S?Km+yR?!-kYdA~0NH|W?%34}-gX7M*QEV?pO{*HU zb{S~W{9<{i(ekjJluj(qZj7L{+5ymt2J1>KsTdo@Z1WNbjm|z0fBRwY=o02%#uPvsZb28Y4cWiFKVz1oKQvHq{q}Xg9_Vl zP8OdfL6OyZrWd8U&;)=d7{5aS9dF|8YhQ zTNfQ&ABywyOpQ_P5Qk=F89)vorCCQxE8k`Q6?0eQ9n=GP)NdRvRNNDzkR|#maE_h* z@<#ct#M&v-fXCmHo(}BtNA#ZUs6+B}t5V+}=ll0SNzGL}CwLsvcoc_?Ry7V6tjcQH zTB~F^qA$HZiyjK67#e7FC{i4;2_Tk63v*I%nZFI?2QQ!(ia?~0CSlPc>A#2C8;}Hi zWSUfhP4iIuwe#Pj+#l9NuK7W|OwF&eM1U+2018tN7JZ8}62QKI1f zMLzN%spzHYr5>!Z4Yn7Purn~m&*hPVYalS*Cnf);e#0w$qP(lzU-TF5S|31o$JxCJ z)(F^XHNVXGpg$dKcX$qJd#-I8=fRAm4zr4%pNNIbRb9z zvP^*if4`>4oy~&Z5YT+x;j_A0H?iy1n0>q$uhm;Gzr6?6Bu|`q>p4_O7l?(~f$7rI z`r8@49tu+pUi_Z!z6S*4SA=wU&M1O1e)Uw_vvZsBNZ*rk8~GlM?co0D0Lz+Tn2^hr z&r#1Y&EYVoul46_WUk>gBQLcrw0c|$MlFb!U}~aK1(=89+pi0zzR-7MjP{^Xc^kvx{J=Kz>mSqkuRT7DsX--Pr zht9=k{fGb%b5Sak8usOmfu0JmP=cCIB< z)EWXrqD@yRMQQ4nJO5eeA%UQnsM(;A(2)A8cuiR8YH!^){sJg6Hqx zdS?Pttd&9%v2C^zS{9r`YXW8#^4spf@7e!O5L@$Snq>N+WEHCO-&nK`&q zRJGKSrP`+QqD5xs%y9~>!s92<3}^=)nonHtwEGw0O}Agmecb<3Hb~w{O{72BWzos= zRcn*DaeLkE;Al59jg>ln<)(RW|H$vZn-3q)e)lcKymGZ+%vfq98@pCZV1yt!eC)0F zCHb4HzivqKi0>TQON1dr7I!I?nZg28SbA^$vy)%kgZXuKl!E&9>X0bc;mBdvsE}&A zbBs>)c7Cw?my^%d-z&xT;RufPzzAi((-yF!&`yr^1Y953%f9eshZ5p*xT1_~*$uhE zTx^lg<2*L42Lz2ySX_ctE(ib!0G&9fxNUf^hH4sp^=TeOq05XC}xh`q$v;9V|1!&(N zcUKMNu3@*_C?8fQw?5^5SXH^2Ne%T8hnkjt7ysST(DZ-Ly9nK*oq0Dtx^je+Xg2@) zWPBVunj+-zKi=RuN4pDM_>etRf8*pt@ky7D9ejOdT7>Bl}y@L+X z5jwQLix3uq*of7Ju)x>gjt4(`cGqJ36Y`0X3HehV1hMDx==^mZtFdGDSQ9?tNj_&i8LsozJWl46ZTsUl^NyaL{vtk>(#Va`n9A+?LPQ zBD=k;pSPS-AHF&g;!jVDUa(Q0M9Ak0NSIR}ED6&kzYNe~ON#iy%z@dODfG=KsS_Xg zMMB6Yf4GV!33!C*`lO8u6j?sAk_J1Qlek7Y$l&OB=14toV9C1m{`BMnNlP*+q}-V| z`*Jx+e9Tx@wFsnIi@M>iVESqX4r6^b_i_8^bkk`4odgzoV$6r4s({)S7Z)4n0zNUu z*}(2gi}EhW{HFPfYaBPxgx_qpxztR022{zSv-V-mSm{a#VxQOdLre?Qz@lg|3Az|J zU7PBe!hudz$yshOthHJ#MQ4N3WO}JiC)LZq+?XkLHanB|n{)PC!#=}gMub#gV)bC> z{4wMAIoKYSz$A^xm^AF`?(Y(Jc?=lLbQk8rg-jQ^*)ULGzRt{P`qw2yWsDLQC)X#7 zVO)qfur+t9WI$yW>Hs?Ko|eCd82i^=-;?+|_=Pj0%c7#nqGv9| zZw3<1ZDI~1N$9M5h`Nfihv&ra^dUa-!QCY|4S?o!CbB}=u5wS2{@3(AFhiZifSu|5 zQ-O;zJKL^&#B+Gm{?4hMegS9>$Y3@7K_t>2D)=k7EM0^X7Z4Mj;ky^&p z*Ay}3_0{P$CPLj?a(Dsd3T46Jy%mS~K-p`#e4Ew88eo*OLExvly?{!pnN)D~)E!%c zCJc|ysVLSKS44fdkVX(cQllu@N^mk0LZIo>>-$QqIA>GZsxL`gthT$m9-?se#0BQ^ z?8M8qN*72U>IuwN#g?Ob*4=|$Tg7K21SLQI zPoaD&%tOzA?a#M+G^B%Al{Q)_1Uh6m5(ODgSGUG5$+PV9BH;#>>w) zCD}JW#W%L$FO$ShmIQ`;i8mJ9dRG~eh#bGC6;&EAWa$sdVlsf|*s9g+(vd6y+EhPG z*`&qQX{p7ve2gAYQQ>SD=|f;=7d6;FL@llj(q+M1nc9(UF>9oFim5Ub52(iNC$|P@ znh*pJrL$GX-qmA75cC}l+|b!}v@ARv$_foE%5Uy5vLKE{AxvmR4l#G?NHqeCYZg^7 zd0gPMS>szc?5`Vu8Hz{RNBx>;&nsZ^4fXk=+dcXs9BW!oYaVXN&J2OB4u`$Omg8ZR=~*Oij*Df3Ju3J$D( zDIx2FP=wiSY~uE!+M+{k&-gUrkMG_~rkU#Y0~Q5=h_PD(VUc7I%>~YQ9sk;iC{)6L zzMs0Hr`G0USDJ*Q^b&VV{%XI&pr57?JF*D06&n~_%oV*IC;S}4t^OeoA>VzPcv4h! zkHJ+EzN_@V9PyliIpUnW-+XzlDYKlZ7aiZzvZfBm;pRMmrDBQ4N|V01pgnk7c%?Q}ebw-CA6GRjU6Nh7(G=mqz3?;efr^+^yO2zO0*vQ{7k%EbE&$jYb(jQH zEba*_R&UfsBhXKi%`HYA0jXjV6XJz(c!Gs&LbBo$YP|}oDoC}ta#3CwRl4^_Rxwjm zwg|AOd-`-etT!*u91i>l=FD-6eiaN#G!6B}px3;jaCCpe?ah^!OH2>-+>sWfdk+*~mBA_EsdIV=>KsJaE!x>iG z5ve1vjh!~SN%L-lZBQwOb(AC6XyWK5A&jk^41h`@4~PPO$-J>PLyK`E4i`5oR|Biw z2F^@v)?P>!UtV3URia5(KW^a_Wul!szJpq!R**BW%*}56-Pa=U3g5>iHt*!HSc*!A z5P$(UCdeF=6=d9-fKEznX-Q2&<9ge2;n?Eop`p`*v5whxI=isw+VH|Kt0lB3qBc-g zfKCfY3HVo^hAxOQ9O%PZlgVyM)oz0j=RjXJwW^U;&1*&<1CEX!RwpNGzCf%hzmePE?6JAT1+cgLM;HD8bAp)CO0v{ z@oPbeV_JKD&kmz!cqxM|IwvZ0iYT2uih_i00wYR{o`-X%CFkC`a)Bp@qFNO!T9?@?eD$KKKe0+sF6#tA%I&>kC=*}s|917Z zCdI@B1-{S-?Ml!PpP4zqBArW%Nvwy|rsnC4ic&~Vvj208N~{7e8|a)#yI-fbi8=Cq zbBki_+pg)asAtui;|_g}9u-)p>CkPTLmyqzBiZ~FYPIxLZL$~;(qf6u$k;ix)bye) zEiE_e>-V_tF+w6E%+Y(IfrJX_Y$W>p{UjPeSV(a(0@LQjtCVRAi$6kx$%|RLAgOu) zup~1OLqit|tW}?>pf`$Kb|i*k8v;}3Atb}T0X0uqsE0_)dQErF&E56_dQG$~`ug|( z&B>2a7lyGl(qp~iBw{0{1Y;8C{{^L!;c>)@Lc0EN{%Vj%MJ?g0AK#_qz;|Aw0AGhQ z&gCtXL0G)DRHIfeajjUR7$&;fC^@;-l}P$41(E%`IuPar9G?WrPID5N`iRK(mod3s z#mVx^3&1Gz2`19j(ZCwL5~J0sAXUtRdL3bIj%0b*b?Fc)mE-4k#U%Z97^Fv0gGwi$ zTsqzB^0QXEfVNBwRr!gTkNgnl2Q|oAF+MrY0kqI2H4EcP?=xLo+W(4mOAuugP$zGU zrd48%{>G#>8H^d=pRCGqnz=Ut=*GmvoT$ZYUS7booM()Z7kRGbn=!Q~Vq#8R|J$EK zFIR5G?sx8X_jkK1ay?qUf1inV2GjDSYu2oolfIS%HAU!{iLq|flPk`3?zK-5o6vXi z*ERx#cHwo;Z=agP39cU!Q;F-U6n()nho`-NT%@{?Oe>;z`X}H_oI4WHc)#7#@vK0f zvdT39m*DS7DFO%xC1KDk#0D7i&r}r z${XclOE3GUUAqw01Z;J{CIH9*coyOl3TAkcK)-10Lce_-1;iHY1`=>!EH_{mkZ9O< zq}|Wggrc(Nm{EwBs8WVMLqS0%4d*9nBP~Qd8eZsHNUT^X4(5 z!U`=sL2~CpSUNfe9TLqUu3v?tVS+Bi9~2;kID$7Fzl0e5J2IO7`u0>lWs zz2&uC&5y-SiygwVYFIm*UCgFR% z>Rlp|;7?vK@K5axYF_OH?RuwPQqzh*1$GZC#Oc0W5;&XKmt z`KgONTJ`m*FIElcQ~ET#y4ee2V}@-3ondKdYKqy?P)Afq(l4zb*3JGForUq>BX{kR z;pNX|E#yJqEc1CxL7*VLg@IwemCr|R-({i3LNUhKqT5_&CkhxPru#8fPg9m-$yWj# zB;xT^-{>(PV66FBRR9E&I%vBS0EN4}VgKS~Yxic~+~?{W8W1zf1PB|imcYtErT!SP zg?n)HEcCnW8gA?s{mx~2Xv}@S-V0WFJ7WVw(3>%fv`zQV9GOm}VF=iAinN?cLY+eI zDBG|H{~_rwP~lTmd+v~8A7m1~Y)!%By#+Gu(mzG+kw4 zRE9CfVN&1(6oNmoJJ&x=00`k#ymrwl)~TmBM>)dj=AUWU(PjV!-}$_H74PgEf(v)d zIm^4)UOD2xJw3IGrCpS7vw`p0`|ZPL4(cJBWUoJSU@xH&;GJPFKYeih{Pm}wTc@R5 zHGx5XS;K!A;qIpmoc0y{n!#%jTwa$mcz8-Rl~_`FGVHHQy38 zhQ;Sr5Cam^d@Lqk|78D~mt;CG%QdaR&=83oPl<(a5WEAPSQ@OZNx|TY$d4PYG|u{g zIz`8)OPImdUU>5|5 zG3n-(74&uV6uB@#R=_?7k0Lx1K)B(9d7(IX+yz zJClsU^T7}nkM$GR}X%7G}+dC>KFd|U*Bn4Ir4vs;&HRH&C}q>+z10kKT9XC(qg zUyTDWR=R9j7{Kc0D?0JZJQTT%HpiGjd&B{tY9rq289>K>vKMvUfXrbW1>op~H>yBf za1`D+x5H!K?m@5-M0^N-yUD}*)j^qH<@{fReDyan_NlKj$d{PAOa1cx8ulR&pbqTd zXDmMKw}yx&#Hup#eB$B=ce5aFXofo3-Ignc5F*p&`6q@DjGjA*uTBcj1Ox%6xMSkS zN^h(J>#ck&J{IW;oX74KjtP%NOm3+@{iIwQKx*d+F6RIH48yV(0}Q~EI@u|{;|hgU zVeL0`{QleptQ%K^JS$$avnrCRbJIYcdY95ly$3tT44CRoE>vA))y_4=&q7ut z^ONKCnL9lGocnJ}!iwbMpFusporPrUqv3#Lp0YChp#CIpY(? zM^XVZ4WQlI?6UBUV>X}nj-&DV^#X%i0_J$hy?Z*mXJ;NYNZRMt&8V?P{5yJpWy$#|Cb0b?%fi|Pe69#eB zUWEfeL_BQ@uCSZTUATo!B=NORs`IY7AU-4l3-a-Q?ns)!`U-|h81u_uz_

    &#Rd&2W|U`; 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 J;r - - - - - {{=it.title}} - - - - - - - - - - - - - - - - - - - - - - - diff --git a/COPS/cops-3.1.3/templates/epubreader.html b/COPS/cops-3.1.3/templates/epubreader.html deleted file mode 100644 index 2b9c8a4c..00000000 --- a/COPS/cops-3.1.3/templates/epubreader.html +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - COPS EPub Reader - - - - - - - - - - - -

    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - - \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/error.html b/COPS/cops-3.1.3/templates/error.html deleted file mode 100644 index a609da43..00000000 --- a/COPS/cops-3.1.3/templates/error.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - COPS - Error - - -

    Error

    - -

    COPS: {{=it.error}}

    -

    Please report this issue at https://github.com/mikespub-org/seblucas-cops/issues if needed

    -

    Link: Home

    - - \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/graphql.html b/COPS/cops-3.1.3/templates/graphql.html deleted file mode 100644 index bb1f6d0f..00000000 --- a/COPS/cops-3.1.3/templates/graphql.html +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - GraphQL Playground - - - - - - -
    - - -
    Loading - GraphQL Playground -
    -
    - - - - - diff --git a/COPS/cops-3.1.3/templates/notfound.html b/COPS/cops-3.1.3/templates/notfound.html deleted file mode 100644 index 2fea776b..00000000 --- a/COPS/cops-3.1.3/templates/notfound.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - COPS - Not Found - - -

    Not Found

    -

    COPS: I'm sorry Dave, I'm afraid I can't do that

    - -

    Link: Home

    - - \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/restapi.html b/COPS/cops-3.1.3/templates/restapi.html deleted file mode 100644 index bb440566..00000000 --- a/COPS/cops-3.1.3/templates/restapi.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - COPS - SwaggerUI - - - -
    - - - - - diff --git a/COPS/cops-3.1.3/templates/twigged/README.md b/COPS/cops-3.1.3/templates/twigged/README.md deleted file mode 100644 index c2ba9512..00000000 --- a/COPS/cops-3.1.3/templates/twigged/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# Moving templates from doT to Twig - -## Introduction - -This is an experiment to convert existing COPS templates from the doT.js syntax to the Twig syntax. -It is based on a one-to-one conversion of the 'bootstrap2' template to the 'twigged' template. - -The main use case is for server-side rendering with a well-known and supported template engine. -Client-side rendering is possible with Twig.js as well, but this hasn't been fully tested yet. - -References: -- doT: - * Client-side: See http://olado.github.io/doT/index.html for details of doT.js - * Server-side: See https://github.com/seblucas/doT-php for doT-php restrictions -- Twig: - * Server-side: see https://twig.symfony.com/doc/3.x/ for Twig documentation - * Client-side: see https://github.com/twigjs/twig.js/wiki/Implementation-Notes for Twig features supported by twig.js - -## Basic Cheatsheet - -| Feature | doT syntax | Twig syntax | Remark | -|---------|------------|-------------|--------| -| Dot Notation | it.data.entry | same | | -| Interpolate | {{= it.title }} | {{ it.title }} | | -| Include/use | {{#def:header}} | {% include 'header.html' %} | use include statement | -| Conditional | {{? it.containsBook == 0}}
    ...
    {{??}}
    ...
    {{?}} | {% if it.containsBook == 0 %}
    ...
    {% else %}
    ...
    {% endif %} | | -| AND clause | {{? entry.class == "" && entry.number == ""}} | {% if entry.class == "" and entry.number == "" %} | | -| OR clause | {{? it.page == 13 \|\| it.page == 16}} | {% if it.page == 13 or it.page == 16 %} | | -| Iterate | {{\~entry.book.preferedData:data:i}}
    ...
    {{\~}} | {% for data in entry.book.preferedData %}
    ...
    {% endfor %} | | -| first iteration | {{? i == 0}} | {% if loop.first %} | | -| last iteration | {{? i + 1 == entry.book.preferedCount}} | {% if loop.last %} | | -| Functions | str_format(it.sorturl, "title") | same | for defined Twig functions | -| | htmlspecialchars(entry.title) | entry.title\|escape | for defined Twig filters | -| | it.book.content | it.book.content\|raw | for pre-formatted HTML | -| | entry.book.preferedData.length | entry.book.preferedCount | not supported in doT-php | -| | {{=it.assets}}/whatever.js?v={{=it.version}} | {{asset('whatever.js')}} | quote issues in doT-php | -| Evaluate | {{ ... }} | N/A | not supported in doT-php | -| Encode | {{! it.title }} | N/A | not supported in doT-php | -| Define | {{##def:snippet: ... #}} | N/A | not supported in doT-php | - -## Templates and Inheritance - -1. [index.html](index.html) is rendered server-side to generate the initial HTML page -2. [page.html](page.html) is rendered client-side or server-side for each request, and it decides which template to include next -3. [base.html](base.html) is extended by all other templates: - - [about.html](about.html) (page=16) - - [bookdetail.html](bookdetail.html) (page=13) - - [mainlist.html](mainlist.html) - - [booklist.html](booklist.html) - - [recent.html](recent.html) (page=10) - - [authordetail.html](authordetail.html) (page=3) - - [customdetail.html](customdetail.html) (page=15) - - [identifierdetail.html](identifierdetail.html) (page=42) - - [languagedetail.html](languagedetail.html) (page=18) - - [publisherdetail.html](publisherdetail.html) (page=21) - - [ratingdetail.html](ratingdetail.html) (page=23) - - [seriedetail.html](seriedetail.html) (page=7) - - [tagdetail.html](tagdetail.html) (page=12) - - include [extra_series.html](extra_series.html) and/or [extra_info.html](extra_info.html) if it.extra is available - - [navlist.html](navlist.html) - - [customize.html](customize.html) (page=19) - - [filters.html](filters.html) (filter=1) diff --git a/COPS/cops-3.1.3/templates/twigged/about.html b/COPS/cops-3.1.3/templates/twigged/about.html deleted file mode 100644 index e31a6098..00000000 --- a/COPS/cops-3.1.3/templates/twigged/about.html +++ /dev/null @@ -1,8 +0,0 @@ -{# about.html is used for it.page == 16 #} -{% extends 'base.html' %} - -{% block main %} -
    - {{it.fullhtml|raw}} -
    -{% endblock main %} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/twigged/authordetail.html b/COPS/cops-3.1.3/templates/twigged/authordetail.html deleted file mode 100644 index 17ae4b4d..00000000 --- a/COPS/cops-3.1.3/templates/twigged/authordetail.html +++ /dev/null @@ -1,2 +0,0 @@ -{# authordetail.html is (not) used for it.page == 3 #} -{% extends 'booklist.html' %} diff --git a/COPS/cops-3.1.3/templates/twigged/base.html b/COPS/cops-3.1.3/templates/twigged/base.html deleted file mode 100644 index 46c0ffc3..00000000 --- a/COPS/cops-3.1.3/templates/twigged/base.html +++ /dev/null @@ -1,81 +0,0 @@ -{# base.html is extended by all other templates #} -{% block header %} - -{% endblock header %} - -{% block main %} -This is the main block -{% endblock main %} - -{% block extra %}{% endblock extra %} - -{% block footer %}{% endblock footer %} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/twigged/bookdetail.html b/COPS/cops-3.1.3/templates/twigged/bookdetail.html deleted file mode 100644 index 6ad12e44..00000000 --- a/COPS/cops-3.1.3/templates/twigged/bookdetail.html +++ /dev/null @@ -1,108 +0,0 @@ -{# bookdetail.html is used for it.page == 13 #} -{% extends 'base.html' %} - -{% block main %} -
    -
    -
    -
    - {% if it.book.hasCover == 1 %} -
    - - {{it.c.i18n.coverAlt}} - - {% endif %} -
    -
    - -
    - {% for data in it.book.datas %} -
    - {{data.format}} - {% if data.mail == 1 %} - - - {% endif %} - {% if data.readerUrl != "" %} - - - {% endif %} -
    - {% endfor %} -
    - - -
    -

    {{it.title|escape}}

    -

    {% for author in it.book.authors %}{% if not loop.first %}, {% endif %}{{author.name|escape}}{% endfor %}

    - {% if it.book.seriesName != "" %} -

    {{it.book.seriesName|escape}} ({{it.book.seriesIndex}})

    - {% endif %} -
    - - -
    - - {% if it.book.languagesName != "" %} -

    - {{it.c.i18n.languagesTitle}}: {{it.book.languagesName}} -

    - {% endif %} - - {% if it.book.identifiers != "" %} -
    -

    - - {% for id in it.book.identifiers %}{{id.name|escape}} {% endfor %} -

    -
    - {% endif %} - - {% if it.book.tagsName != "" %} -
    - - {% for tag in it.book.tags %}{{tag.name|escape}} {% endfor %} -
    - {% endif %} - - {% if it.book.rating != "" %} -

    -

    {{it.c.i18n.ratingTitle}}: {{it.book.rating}}

    -

    - {% endif %} - {% if it.book.publisherName != "" %} -

    -

    {{it.c.i18n.publisherName}}: {{it.book.publisherName|escape}}

    -

    - {% endif %} - {% if it.book.pubDate != "" %} -

    -

    {{it.c.i18n.pubdateTitle}}: {{it.book.pubDate}}

    -

    - {% endif %} - {% for column in it.book.customcolumns_preview %} -

    -

    {{column.customColumnType.columnTitle}}: {{column.htmlvalue}}

    -

    - {% endfor %} - {% if it.book.extraFiles != "" %} -

    -

    {{it.c.i18n.filesTitle}}: {% for extraFile in it.book.extraFiles %}{{extraFile.name|escape}} {% endfor %}

    -

    - {% endif %} - -
    - -
    - -
    -
    - {% if it.book.content != "" %} -
    -

    {{it.c.i18n.contentTitle}}

    -
    {{it.book.content|raw}}
    - {% endif %} -
    -
    -
    -{% endblock main %} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/twigged/booklist.html b/COPS/cops-3.1.3/templates/twigged/booklist.html deleted file mode 100644 index e278c8f8..00000000 --- a/COPS/cops-3.1.3/templates/twigged/booklist.html +++ /dev/null @@ -1,100 +0,0 @@ -{# booklist.html is used for it.containsBook != 0 #} -{% extends 'mainlist.html' %} - -{% block download %} - {% if it.download %} - {% for link in it.download %} - - - - {% endfor %} - {% endif %} -{% endblock download %} - -{% block sortlinks %} - - -{% endblock sortlinks %} - -{% block content %} -
    - {% for entry in it.entries %} -
    -
    - {% if entry.thumbnailurl %} - - {{it.c.i18n.coverAlt}} - - {% endif %} -
    -
    -

    {{entry.title|escape}}

    -
    {{entry.book.authorsName|escape}}
    - {% if entry.book.seriesName != "" %}
    {{entry.book.seriesName|escape}} ({{entry.book.seriesIndex}})
    {% endif %} - - {% for column in entry.book.customcolumns_list %} -
    {{column.customColumnType.columnTitle}} : {{column.htmlvalue}}
    - {% endfor %} -
    -
    -
    - - {% if entry.book.preferedCount > 1 %}
    {% endif %} - {% for data in entry.book.preferedData %} - {% if loop.first %} - {{data.name}} - {% if entry.book.preferedCount > 1 %} - - {% if entry.book.preferedCount > 1 %}{% endif %} - {% endif %} - {% endfor %} - {% if entry.book.preferedCount > 1 %}
    {% endif %} -
    -
    - {% endfor %} -
    -{% endblock content %} - -{% block extra %} - {% if it.extra %} - {% if it.extra.series %} - {% include 'extra_series.html' %} - {% endif %} - {% if it.extra.title %} - {% include 'extra_info.html' %} - {% endif %} - {% endif %} -{% endblock extra %} diff --git a/COPS/cops-3.1.3/templates/twigged/customdetail.html b/COPS/cops-3.1.3/templates/twigged/customdetail.html deleted file mode 100644 index f8ac5dee..00000000 --- a/COPS/cops-3.1.3/templates/twigged/customdetail.html +++ /dev/null @@ -1,2 +0,0 @@ -{# customdetail.html is (not) used for it.page == 15 #} -{% extends 'booklist.html' %} diff --git a/COPS/cops-3.1.3/templates/twigged/customize.html b/COPS/cops-3.1.3/templates/twigged/customize.html deleted file mode 100644 index 538fecd1..00000000 --- a/COPS/cops-3.1.3/templates/twigged/customize.html +++ /dev/null @@ -1,13 +0,0 @@ -{# customize.html is used for it.page == 19 #} -{% extends 'navlist.html' %} - -{% block entry %} -
    -
    - {{entry.title|escape}} -
    -
    - {{entry.content|raw}} -
    -
    -{% endblock entry %} diff --git a/COPS/cops-3.1.3/templates/twigged/extra_info.html b/COPS/cops-3.1.3/templates/twigged/extra_info.html deleted file mode 100644 index 6ac3c98d..00000000 --- a/COPS/cops-3.1.3/templates/twigged/extra_info.html +++ /dev/null @@ -1,21 +0,0 @@ -{# extra_info.html is included in booklist.html if it.extra.title is not empty #} - -
    -
    -
    -
    -
    - {{it.extra.title}} -
    -
    - {% if it.extra.link %} -

    {{it.c.i18n.linkTitle}}: {{it.extra.link}}

    - {% endif %} - {% if it.extra.content %} - {{it.extra.content|raw}} - {% endif %} -
    -
    -
    -
    -
    diff --git a/COPS/cops-3.1.3/templates/twigged/extra_series.html b/COPS/cops-3.1.3/templates/twigged/extra_series.html deleted file mode 100644 index 6754923f..00000000 --- a/COPS/cops-3.1.3/templates/twigged/extra_series.html +++ /dev/null @@ -1,20 +0,0 @@ -{# extra_series.html is included in booklist.html if it.extra.series is not empty #} - -
    -
    -
    -
    -
    - {{it.c.i18n.seriesTitle}} -
    -
    -
      - {% for series in it.extra.series %} -
    • {{series.title}} ({{series.number}})
    • - {% endfor %} -
    -
    -
    -
    -
    -
    diff --git a/COPS/cops-3.1.3/templates/twigged/filters.html b/COPS/cops-3.1.3/templates/twigged/filters.html deleted file mode 100644 index 7b0bd344..00000000 --- a/COPS/cops-3.1.3/templates/twigged/filters.html +++ /dev/null @@ -1,17 +0,0 @@ -{# filters.html is used for it.isFilterPage #} -{% extends 'navlist.html' %} - -{% block entry %} -{% if entry.class == "" and entry.number == "" %} - -{% else %} - {{ parent() }} -{% endif %} -{% endblock entry %} diff --git a/COPS/cops-3.1.3/templates/twigged/identifierdetail.html b/COPS/cops-3.1.3/templates/twigged/identifierdetail.html deleted file mode 100644 index 20ae760b..00000000 --- a/COPS/cops-3.1.3/templates/twigged/identifierdetail.html +++ /dev/null @@ -1,2 +0,0 @@ -{# identifierdetail.html is (not) used for it.page == 42 #} -{% extends 'booklist.html' %} diff --git a/COPS/cops-3.1.3/templates/twigged/index.html b/COPS/cops-3.1.3/templates/twigged/index.html deleted file mode 100644 index 1ffaa9ea..00000000 --- a/COPS/cops-3.1.3/templates/twigged/index.html +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - - - - - - - - - - {{it.title}} - - - - -{% if it.server_side_rendering == 0 %} - - - - -{% endif %} - - - - - - - - - - - - - - - - - -{% if it.server_side_rendering == 0 %} - -{% endif %} - - -{% if it.server_side_rendering %} - {# only this 'it' variable will be accessible inside page.html #} - {% include 'page.html' with {'it': it.page_it} only %} -{% endif %} - - \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/twigged/languagedetail.html b/COPS/cops-3.1.3/templates/twigged/languagedetail.html deleted file mode 100644 index 0d7dc1eb..00000000 --- a/COPS/cops-3.1.3/templates/twigged/languagedetail.html +++ /dev/null @@ -1,2 +0,0 @@ -{# languagedetail.html is (not) used for it.page == 18 #} -{% extends 'booklist.html' %} diff --git a/COPS/cops-3.1.3/templates/twigged/loader/README.md b/COPS/cops-3.1.3/templates/twigged/loader/README.md deleted file mode 100644 index 667fd6e3..00000000 --- a/COPS/cops-3.1.3/templates/twigged/loader/README.md +++ /dev/null @@ -1,13 +0,0 @@ -## Replacing templates for epub-loader - -If you want to override the standard templates of epub-loader, you can place -them here (or anywhere else really), and update $templateDir in ./loader.php - -Every action typically has its own template that extends [index.html](index.html) -and defines its own 'content' block. - -Check the [epub-loader templates](https://github.com/mikespub-org/epub-loader/tree/main/templates) -folder for specific action templates you want to re-use. Unlike the 'twigged' templates in COPS -itself, you don't need to use it.* for every variable. - -Note: they're also here under vendor/mikespub/epub-loader/templates if you installed the package. diff --git a/COPS/cops-3.1.3/templates/twigged/loader/actions.html b/COPS/cops-3.1.3/templates/twigged/loader/actions.html deleted file mode 100644 index f47279ab..00000000 --- a/COPS/cops-3.1.3/templates/twigged/loader/actions.html +++ /dev/null @@ -1,12 +0,0 @@ -{% extends 'index.html' %} - -{% block content %} -
    Select action
    -
      -{% for action, actionInfo in actions %} -
    • - {{actionInfo}} -
    • -{% endfor %} -
    -{% endblock content %} diff --git a/COPS/cops-3.1.3/templates/twigged/loader/databases.html b/COPS/cops-3.1.3/templates/twigged/loader/databases.html deleted file mode 100644 index c2630c6b..00000000 --- a/COPS/cops-3.1.3/templates/twigged/loader/databases.html +++ /dev/null @@ -1,24 +0,0 @@ -{% extends 'index.html' %} - -{% block content %} - - - - - - - - - - {% for dbNum, dbConfig in databases %} - - - - - - - - - {% endfor %} -
    Db numDb nameActionDb PathEpub pathNb Files
    {{dbNum}}{{dbConfig.name}}{{actionTitle}}{{dbConfig.db_path}}{{dbConfig.epub_path}}{{dbConfig.count}}
    -{% endblock content %} diff --git a/COPS/cops-3.1.3/templates/twigged/loader/index.html b/COPS/cops-3.1.3/templates/twigged/loader/index.html deleted file mode 100644 index c83e4dec..00000000 --- a/COPS/cops-3.1.3/templates/twigged/loader/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - {{app_name}} - - - - - - -
    - {{app_name}} - version {{version}} -
    - - - -
    - {% block content %} - {% if actionTitle %} - - {% endif %} - {{result|raw}} - {% endblock content %} -
    - - - {% if errors|length %} - -
    - - - - - {% for fileName, error in errors %} - - - - - - {% endfor %} -
    Errors ({{ errors|length }})
    {{fileName}}{{error}}
    -
    - - {% endif %} - - - - - - - diff --git a/COPS/cops-3.1.3/templates/twigged/mainlist.html b/COPS/cops-3.1.3/templates/twigged/mainlist.html deleted file mode 100644 index b966ef17..00000000 --- a/COPS/cops-3.1.3/templates/twigged/mainlist.html +++ /dev/null @@ -1,58 +0,0 @@ -{# mainlist.html is extended by booklist.html and navlist.html #} -{% extends 'base.html' %} - -{% block main %} -
    -{% block hierarchy %} -
    - - {% if it.filters %} - - {% endif %} -
    -{% endblock hierarchy %} - -{% block content %} -This is the content block -{% endblock content %} - -{% block pager %} -{% if it.isPaginated == 1 %} - -{% endif %} -{% endblock pager %} -
    -
    -{% endblock main %} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/twigged/navlist.html b/COPS/cops-3.1.3/templates/twigged/navlist.html deleted file mode 100644 index 499afd7e..00000000 --- a/COPS/cops-3.1.3/templates/twigged/navlist.html +++ /dev/null @@ -1,23 +0,0 @@ -{# navlist.html is used for it.containsBook == 0 #} -{% extends 'mainlist.html' %} - -{% block content %} -
    -
    - {% for entry in it.entries %} -
    - {% block entry %} - - {% endblock entry %} -
    - {% endfor %} -
    -
    -{% endblock content %} diff --git a/COPS/cops-3.1.3/templates/twigged/page.html b/COPS/cops-3.1.3/templates/twigged/page.html deleted file mode 100644 index 5b1658c0..00000000 --- a/COPS/cops-3.1.3/templates/twigged/page.html +++ /dev/null @@ -1,16 +0,0 @@ -{# page.html is rendered by Twig and it decides which template to include #} -{% if it.page == 13 %} - {% include 'bookdetail.html' %} -{% elseif it.page == 16 %} - {% include 'about.html' %} -{% elseif it.page == 19 %} - {% include 'customize.html' %} -{% elseif it.isFilterPage %} - {% include 'filters.html' %} -{% elseif it.containsBook == 0 %} - {% include 'navlist.html' %} -{% elseif it.page == 10 %} - {% include 'recent.html' %} -{% else %} - {% include 'booklist.html' %} -{% endif %} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/twigged/publisherdetail.html b/COPS/cops-3.1.3/templates/twigged/publisherdetail.html deleted file mode 100644 index 684916a2..00000000 --- a/COPS/cops-3.1.3/templates/twigged/publisherdetail.html +++ /dev/null @@ -1,2 +0,0 @@ -{# publisherdetail.html is (not) used for it.page == 21 #} -{% extends 'booklist.html' %} diff --git a/COPS/cops-3.1.3/templates/twigged/ratingdetail.html b/COPS/cops-3.1.3/templates/twigged/ratingdetail.html deleted file mode 100644 index 34f5e48e..00000000 --- a/COPS/cops-3.1.3/templates/twigged/ratingdetail.html +++ /dev/null @@ -1,2 +0,0 @@ -{# ratingdetail.html is (not) used for it.page == 23 #} -{% extends 'booklist.html' %} diff --git a/COPS/cops-3.1.3/templates/twigged/recent.html b/COPS/cops-3.1.3/templates/twigged/recent.html deleted file mode 100644 index 7e322464..00000000 --- a/COPS/cops-3.1.3/templates/twigged/recent.html +++ /dev/null @@ -1,2 +0,0 @@ -{# recent.html is (not) used for it.page == 10 #} -{% extends 'booklist.html' %} diff --git a/COPS/cops-3.1.3/templates/twigged/scripts/cops.js b/COPS/cops-3.1.3/templates/twigged/scripts/cops.js deleted file mode 100644 index 489950bd..00000000 --- a/COPS/cops-3.1.3/templates/twigged/scripts/cops.js +++ /dev/null @@ -1,40 +0,0 @@ -function postRefresh() -{ - $('[data-toggle="tooltip"]').tooltip(); - hash = window.location.hash.replace("#", ""); - var elmnt = document.getElementById(hash); - if (elmnt) elmnt.scrollIntoView(); -} - -function initiateTwig(url, theme, templates = 'templates') { - Twig.extendFunction("str_format", str_format); - Twig.extendFunction("asset", asset); - - let template = Twig.twig({ - id: 'page', - href: templates + '/' + theme + '/page.html', - async: false - }); - - templatePage = function (data) { - return Twig.twig({ref: 'page'}).render({it: data}); - }; - - $.when($.getJSON(url)).done(function(data){ - currentData = data; - - updatePage (currentData); - cache.put (url, currentData); - if (isPushStateEnabled) { - window.history.replaceState(url, "", window.location); - } - handleLinks (); - }).fail(function (error) { - if (error.responseText) { - document.write (error.responseText); - } else { - document.write ('Error loading templates from directory "' + encodeURI(templates + '/' + theme) + '/" for url: ' + encodeURI(url)); - } - console.log('getJSON failed: ' + JSON.stringify(error, null, 4)); - }); -} diff --git a/COPS/cops-3.1.3/templates/twigged/seriedetail.html b/COPS/cops-3.1.3/templates/twigged/seriedetail.html deleted file mode 100644 index 6a629c50..00000000 --- a/COPS/cops-3.1.3/templates/twigged/seriedetail.html +++ /dev/null @@ -1,2 +0,0 @@ -{# seriedetail.html is (not) used for it.page == 7 #} -{% extends 'booklist.html' %} diff --git a/COPS/cops-3.1.3/templates/twigged/styles/style-base.css b/COPS/cops-3.1.3/templates/twigged/styles/style-base.css deleted file mode 100644 index 4823668e..00000000 --- a/COPS/cops-3.1.3/templates/twigged/styles/style-base.css +++ /dev/null @@ -1,3 +0,0 @@ -.panel-body { padding: 5px; } - -.bottomright {position:absolute; bottom:0; margin-bottom:25px; right: 20px;} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/twigged/styles/style-default.css b/COPS/cops-3.1.3/templates/twigged/styles/style-default.css deleted file mode 100644 index 4823668e..00000000 --- a/COPS/cops-3.1.3/templates/twigged/styles/style-default.css +++ /dev/null @@ -1,3 +0,0 @@ -.panel-body { padding: 5px; } - -.bottomright {position:absolute; bottom:0; margin-bottom:25px; right: 20px;} \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/twigged/styles/typeahead.css b/COPS/cops-3.1.3/templates/twigged/styles/typeahead.css deleted file mode 100644 index 23ccbc10..00000000 --- a/COPS/cops-3.1.3/templates/twigged/styles/typeahead.css +++ /dev/null @@ -1,200 +0,0 @@ -/* - * typehead.js-bootstrap3.less - * @version 0.2.3 - * https://github.com/hyspace/typeahead.js-bootstrap3.less - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ -.has-warning .twitter-typeahead .tt-input, -.has-warning .twitter-typeahead .tt-hint { - border-color: #8a6d3b; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.has-warning .twitter-typeahead .tt-input:focus, -.has-warning .twitter-typeahead .tt-hint:focus { - border-color: #66512c; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; -} -.has-error .twitter-typeahead .tt-input, -.has-error .twitter-typeahead .tt-hint { - border-color: #a94442; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.has-error .twitter-typeahead .tt-input:focus, -.has-error .twitter-typeahead .tt-hint:focus { - border-color: #843534; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; -} -.has-success .twitter-typeahead .tt-input, -.has-success .twitter-typeahead .tt-hint { - border-color: #3c763d; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.has-success .twitter-typeahead .tt-input:focus, -.has-success .twitter-typeahead .tt-hint:focus { - border-color: #2b542c; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; -} -.input-group .twitter-typeahead:first-child .tt-input, -.input-group .twitter-typeahead:first-child .tt-hint { - border-bottom-left-radius: 4px; - border-top-left-radius: 4px; - width: 100%; -} -.input-group .twitter-typeahead:last-child .tt-input, -.input-group .twitter-typeahead:last-child .tt-hint { - border-bottom-right-radius: 4px; - border-top-right-radius: 4px; - width: 100%; -} -.input-group.input-group-sm .twitter-typeahead .tt-input, -.input-group.input-group-sm .twitter-typeahead .tt-hint { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} -select.input-group.input-group-sm .twitter-typeahead .tt-input, -select.input-group.input-group-sm .twitter-typeahead .tt-hint { - height: 30px; - line-height: 30px; -} -textarea.input-group.input-group-sm .twitter-typeahead .tt-input, -textarea.input-group.input-group-sm .twitter-typeahead .tt-hint, -select[multiple].input-group.input-group-sm .twitter-typeahead .tt-input, -select[multiple].input-group.input-group-sm .twitter-typeahead .tt-hint { - height: auto; -} -.input-group.input-group-sm .twitter-typeahead:not(:first-child):not(:last-child) .tt-input, -.input-group.input-group-sm .twitter-typeahead:not(:first-child):not(:last-child) .tt-hint { - border-radius: 0; -} -.input-group.input-group-sm .twitter-typeahead:first-child .tt-input, -.input-group.input-group-sm .twitter-typeahead:first-child .tt-hint { - border-bottom-left-radius: 3px; - border-top-left-radius: 3px; - border-bottom-right-radius: 0; - border-top-right-radius: 0; -} -.input-group.input-group-sm .twitter-typeahead:last-child .tt-input, -.input-group.input-group-sm .twitter-typeahead:last-child .tt-hint { - border-bottom-left-radius: 0; - border-top-left-radius: 0; - border-bottom-right-radius: 3px; - border-top-right-radius: 3px; -} -.input-group.input-group-lg .twitter-typeahead .tt-input, -.input-group.input-group-lg .twitter-typeahead .tt-hint { - height: 46px; - padding: 10px 16px; - font-size: 18px; - line-height: 1.33; - border-radius: 6px; -} -select.input-group.input-group-lg .twitter-typeahead .tt-input, -select.input-group.input-group-lg .twitter-typeahead .tt-hint { - height: 46px; - line-height: 46px; -} -textarea.input-group.input-group-lg .twitter-typeahead .tt-input, -textarea.input-group.input-group-lg .twitter-typeahead .tt-hint, -select[multiple].input-group.input-group-lg .twitter-typeahead .tt-input, -select[multiple].input-group.input-group-lg .twitter-typeahead .tt-hint { - height: auto; -} -.input-group.input-group-lg .twitter-typeahead:not(:first-child):not(:last-child) .tt-input, -.input-group.input-group-lg .twitter-typeahead:not(:first-child):not(:last-child) .tt-hint { - border-radius: 0; -} -.input-group.input-group-lg .twitter-typeahead:first-child .tt-input, -.input-group.input-group-lg .twitter-typeahead:first-child .tt-hint { - border-bottom-left-radius: 6px; - border-top-left-radius: 6px; - border-bottom-right-radius: 0; - border-top-right-radius: 0; -} -.input-group.input-group-lg .twitter-typeahead:last-child .tt-input, -.input-group.input-group-lg .twitter-typeahead:last-child .tt-hint { - border-bottom-left-radius: 0; - border-top-left-radius: 0; - border-bottom-right-radius: 6px; - border-top-right-radius: 6px; -} -.twitter-typeahead { - width: 100%; - float: left; -} -.input-group .twitter-typeahead { - display: table-cell !important; -} -.twitter-typeahead .tt-hint { - color: #999999; -} -.twitter-typeahead .tt-input { - z-index: 2; -} -.twitter-typeahead .tt-input[disabled], -.twitter-typeahead .tt-input[readonly], -fieldset[disabled] .twitter-typeahead .tt-input { - cursor: not-allowed; - background-color: #eeeeee !important; -} -.tt-dropdown-menu, -.tt-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - min-width: 160px; - width: 100%; - padding: 5px 0; - margin: 2px 0 0; - list-style: none; - font-size: 14px; - background-color: #ffffff; - border: 1px solid #cccccc; - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 4px; - -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - background-clip: padding-box; - *border-right-width: 2px; - *border-bottom-width: 2px; -} -.tt-dropdown-menu .tt-suggestion, -.tt-menu .tt-suggestion { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: 1.42857143; - color: #333333; -} -.tt-dropdown-menu .tt-suggestion.tt-cursor, -.tt-menu .tt-suggestion.tt-cursor, -.tt-dropdown-menu .tt-suggestion:hover, -.tt-menu .tt-suggestion:hover { - cursor: pointer; - text-decoration: none; - outline: 0; - background-color: #f5f5f5; - color: #262626; -} -.tt-dropdown-menu .tt-suggestion.tt-cursor a, -.tt-menu .tt-suggestion.tt-cursor a, -.tt-dropdown-menu .tt-suggestion:hover a, -.tt-menu .tt-suggestion:hover a { - color: #262626; -} -.tt-dropdown-menu .tt-suggestion p, -.tt-menu .tt-suggestion p { - margin: 0; -} diff --git a/COPS/cops-3.1.3/templates/twigged/suggestion.html b/COPS/cops-3.1.3/templates/twigged/suggestion.html deleted file mode 100644 index 424da8d5..00000000 --- a/COPS/cops-3.1.3/templates/twigged/suggestion.html +++ /dev/null @@ -1 +0,0 @@ -

    {{it.title}}

    \ No newline at end of file diff --git a/COPS/cops-3.1.3/templates/twigged/tagdetail.html b/COPS/cops-3.1.3/templates/twigged/tagdetail.html deleted file mode 100644 index 82d2931d..00000000 --- a/COPS/cops-3.1.3/templates/twigged/tagdetail.html +++ /dev/null @@ -1,2 +0,0 @@ -{# tagdetail.html is (not) used for it.page == 12 #} -{% extends 'booklist.html' %} diff --git a/COPS/cops-3.1.3/templates/twigged/var_dump.json.twig b/COPS/cops-3.1.3/templates/twigged/var_dump.json.twig deleted file mode 100644 index a07d4e84..00000000 --- a/COPS/cops-3.1.3/templates/twigged/var_dump.json.twig +++ /dev/null @@ -1,2 +0,0 @@ -{# dump all template variables as json for template development or debugging #} -{{ _context|json_encode()|raw }} \ No newline at end of file diff --git a/COPS/cops-3.1.3/util.js b/COPS/cops-3.1.3/util.js deleted file mode 100644 index 63591bd7..00000000 --- a/COPS/cops-3.1.3/util.js +++ /dev/null @@ -1,638 +0,0 @@ -// util.js -// copyright Sébastien Lucas -// https://github.com/seblucas/cops - -/*jshint curly: true, latedef: true, trailing: true, noarg: true, undef: true, browser: true, jquery: true, unused: true, devel: true, loopfunc: true */ -/*global LRUCache, doT, Bloodhound, postRefresh */ - -var templatePage, templateBookDetail, templateMain, templateSuggestion, currentData, before, filterList; - -var CLEAR_FILTER_ID = "_CLEAR_"; - -if (typeof LRUCache === 'undefined') { - console.log('ERROR: LRUCache module not loaded!'); -} -var cache = new LRUCache(30); - -$.ajaxSetup({ - cache: false -}); - -if (typeof Bloodhound === 'undefined') { - console.log('INFO: Bloodhound module not loaded!'); -} else { - var copsTypeahead = new Bloodhound({ - datumTokenizer: Bloodhound.tokenizers.obj.whitespace('title'), - queryTokenizer: Bloodhound.tokenizers.whitespace, - limit: 30, - remote: { - //url: 'getJSON.php?page=9&search=1&db=%DB&vl=%VL&query=%QUERY', - url: 'index.php?page=9&search=1&db=%DB&vl=%VL&query=%QUERY', - replace: function (url, query) { - //url = url.replace('getJSON.php', currentData.baseurl.replace('index.php', 'getJSON.php')); - url = url.replace('index.php', currentData.baseurl); - if (currentData.libraryId) { - url = url.replace('%VL', encodeURIComponent(currentData.libraryId)); - } else { - url = url.replace('&vl=%VL', ""); - } - if (currentData.multipleDatabase === 1 && currentData.databaseId === "") { - return url.replace('%QUERY', query).replace('&db=%DB', ""); - } - return url.replace('%QUERY', query).replace('%DB', currentData.databaseId); - } - } - }); - - copsTypeahead.initialize(); -} - -var DEBUG = false; -var isPushStateEnabled = window.history && window.history.pushState && window.history.replaceState && - // pushState isn't reliable on iOS until 5. - !window.navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork)/); - -function debug_log(text) { - if ( DEBUG ) { - console.log(text); - } -} - -/*exported updateCookie */ -function updateCookie (id) { - if ($(id).prop('pattern') && !$(id).val().match(new RegExp ($(id).prop('pattern')))) { - return; - } - var name = $(id).attr('id'); - var value = $(id).val (); - Cookies.set(name, value, { expires: 365 }); -} - -/*exported updateCookieFromCheckbox */ -function updateCookieFromCheckbox (id) { - var name = $(id).attr('id'); - if (name.includes('-')) { - var nameArray = name.split('-'); - name = nameArray[0]; - } - if ($(id).is(":checked")) - { - if ($(id).is(':radio')) { - Cookies.set(name, $(id).val (), { expires: 365 }); - } else { - Cookies.set(name, '1', { expires: 365 }); - } - } - else - { - Cookies.set(name, '0', { expires: 365 }); - } -} - -/*exported updateCookieFromCheckboxGroup */ -function updateCookieFromCheckboxGroup (id) { - var name = $(id).attr('name'); - var idBase = name.replace (/\[\]/, ""); - var group = []; - $(':checkbox[name="' + name + '"]:checked').each (function () { - var id = $(this).attr("id"); - group.push (id.replace (idBase + "_", "")); - }); - Cookies.set(idBase, group.join (), { expires: 365 }); -} - - -function elapsed () { - var elapsedTime = new Date () - before; - return "Elapsed : " + elapsedTime; -} - -function retourMail(data) { - $("#mailButton :first-child").removeClass ("fas fa-spinner fa-pulse").addClass ("fas fa-envelope"); - if (typeof data === 'string') { - alert ("Result: " + data); - } else { - alert ("Result: " + JSON.stringify(data, null, 4)); - } -} - -function errorMail(data) { - $("#mailButton :first-child").removeClass ("fas fa-spinner fa-pulse").addClass ("fas fa-envelope"); - if (typeof data === 'string') { - alert ("Error: " + data); - } else { - alert ("Error: " + JSON.stringify(data, null, 4)); - } -} - -/*exported sendToMailAddress */ -function sendToMailAddress (component, dataid) { - var email = Cookies.get('email'); - if (!Cookies.get('email')) { - email = window.prompt (currentData.c.i18n.customizeEmail, ""); - if (email === null) - { - return; - } - Cookies.set('email', email, { expires: 365 }); - } - var url = currentData.baseurl + '/mail'; - if (currentData.databaseId) { - url = url + '?db=' + currentData.databaseId; - } - $("#mailButton :first-child").removeClass ("fas fa-envelope").addClass ("fas fa-spinner fa-pulse"); - $.ajax ({'url': url, 'type': 'post', 'data': { 'data': dataid, 'email': email }, 'success': retourMail, 'error': errorMail}); -} - -/*exported asset */ -function asset (file) { - var url = currentData.assets + '/' + file; - if (currentData && currentData.version) { - url = url + '?v=' + currentData.version; - } - return url; -} - -function str_format () { - var s = arguments[0]; - if (typeof s === 'undefined') { - return ''; - } - for (var i = 0; i < arguments.length - 1; i++) { - var reg = new RegExp("\\{" + i + "\\}", "gm"); - s = s.replace(reg, arguments[i + 1]); - } - return s; -} - -function isDefined(x) { - return (typeof x !== 'undefined'); -} - -function getCurrentOption (option) { - if (!Cookies.get(option)) { - if (currentData && currentData.c && currentData.c.config && currentData.c.config [option]) { - return currentData.c.config [option]; - } - } - return Cookies.get(option); -} - -/*exported htmlspecialchars */ -function htmlspecialchars(str) { - return String(str) - .replace(/&/g, '&') - .replace(/"/g, '"') - .replace(/'/g, ''') - .replace(//g, '>'); -} - -/************************************************ - * All functions needed to filter the book list by tags - ************************************************ - */ - -function getTagList () { - var tagList = {}; - $(".se").each (function(){ - if ($(this).parents (".filtered").length > 0) { return; } - var tagtext = $(this).text(); - - var tagarray = tagtext.split (","); - for (var i in tagarray) { - if (!tagarray.hasOwnProperty(i)) { - continue; - } - var tag = tagarray [i].replace(/^\s+/g,'').replace(/\s+$/g,''); - tagList [tag] = 1; - } - }); - return tagList; -} - -function updateFilters () { - var tagList = getTagList (); - - // If there is already some filters then let's prepare to update the list - $("#filter ul li").each (function () { - var text = $(this).text (); - if (isDefined (tagList [text]) || $(this).attr ('class')) { - tagList [text] = 0; - } else { - tagList [text] = -1; - } - }); - - // Update the filter -1 to remove, 1 to add, 0 already there - for (var tag in tagList) { - if (!tagList.hasOwnProperty(tag)) { - continue; - } - var tagValue = tagList [tag]; - if (tagValue === -1) { - $("#filter ul li").filter (function () { return $.text([this]) === tag; }).remove(); - } - if (tagValue === 1) { - $("#filter ul").append ("
  • " + tag + "
  • "); - } - } - - $("#filter ul").append ("
  • " + currentData.c.i18n.filterClearAll + "
  • "); - - // Sort the list alphabetically - $('#filter ul li').sortElements(function(a, b){ - if (a.id === CLEAR_FILTER_ID) { - return 1; - } - if (b.id === CLEAR_FILTER_ID) { - return -1; - } - return $(a).text() > $(b).text() ? 1 : -1; - }); -} - -function doFilter () { - $(".books").removeClass("filtered"); - if (jQuery.isEmptyObject(filterList)) { - updateFilters (); - return; - } - - $(".se").each (function(){ - var tagtext = ", " + $(this).text() + ", "; - var toBeFiltered = false; - for (var filter in filterList) { - if (!filterList.hasOwnProperty(filter)) { - continue; - } - var onlyThisTag = filterList [filter]; - filter = ', ' + filter + ', '; - var myreg = new RegExp (filter); - if (myreg.test (tagtext)) { - if (onlyThisTag === false) { - toBeFiltered = true; - } - } else { - if (onlyThisTag === true) { - toBeFiltered = true; - } - } - } - if (toBeFiltered) { $(this).parents (".books").addClass ("filtered"); } - }); - - // Handle the books with no tags - var atLeastOneTagSelected = false; - for (var filter in filterList) { - if (!filterList.hasOwnProperty(filter)) { - continue; - } - if (filterList[filter] === true) { - atLeastOneTagSelected = true; - } - } - if (atLeastOneTagSelected) { - $(".books").not (":has(span.se)").addClass ("filtered"); - } - - updateFilters (); -} - -function handleFilterEvents () { - $("#filter ul").on ("click", "li", function(){ - var filter = $(this).text (); - var filterId = this.id; - console.log(filter, filterId); - if (filterId === CLEAR_FILTER_ID) { - filterList = {}; - $("#filter ul li").removeClass ("filter-exclude"); - $("#filter ul li").removeClass ("filter-include"); - doFilter (); - return; - } - switch ($(this).attr("class")) { - case "filter-include" : - $(this).attr("class", "filter-exclude"); - filterList [filter] = false; - break; - case "filter-exclude" : - $(this).removeClass ("filter-exclude"); - delete filterList [filter]; - break; - default : - $(this).attr("class", "filter-include"); - filterList [filter] = true; - break; - } - doFilter (); - }); -} - -/************************************************ - * Functions to handle Ajax navigation - ************************************************ - */ - -var updatePage, navigateTo; - -updatePage = function (data) { - var result; - filterList = {}; - data.c = currentData.c; - if (false && $("section").length && currentData.isPaginated === 0 && data.isPaginated === 0) { - // Partial update (for now disabled) - debug_log ("Partial update"); - result = templateMain (data); - $("h1").html (data.title); - $("section").html (result); - } else { - // Full update - result = templatePage (data); - $("body").html (result); - } - if (data.title != data.libraryName) { - if (data.libraryId) { - document.title = data.libraryName + ' ' + data.libraryId + ' - ' + data.title; - } else { - document.title = data.libraryName + ' - ' + data.title; - } - } else if (data.libraryId) { - document.title = data.libraryId + ' - ' + data.title; - } else { - document.title = data.title; - } - currentData = data; - - debug_log (elapsed ()); - - if (Cookies.get('toolbar') === '1') { $("#tool").show (); } - if (currentData.containsBook === 1) { - $("#sortForm").show (); - // disable html tag filter when dealing with hierarchical tags or custom columns - if (getCurrentOption ("html_tag_filter") === "1" && !currentData.hierarchy) { - $("#filter ul").empty (); - updateFilters (); - handleFilterEvents (); - } - } else { - $("#sortForm").hide (); - } - - $('input[name=query]').typeahead( - { - hint: true, - minLength : 3 - }, - { - name: 'search', - displayKey: 'title', - templates: { - suggestion: templateSuggestion - }, - source: copsTypeahead.ttAdapter() - }); - - $('input[name=query]').on('typeahead:selected', function(obj, datum) { - if (isPushStateEnabled) { - navigateTo (datum.navlink); - } else { - window.location = datum.navlink; - } - }); - - if(typeof postRefresh == 'function') - { postRefresh(); } -}; - -navigateTo = function (url) { - $("h1").append (" "); - before = new Date (); - //var jsonurl = url.replace ("index.php", "getJSON.php"); - var jsonurl = url; - var cachedData = cache.get (jsonurl); - if (cachedData) { - window.history.pushState(jsonurl, "", url); - updatePage (cachedData); - } else { - $.getJSON(jsonurl, function(data) { - window.history.pushState(jsonurl, "", url); - cache.put (jsonurl, data); - updatePage (data); - }).fail(function (error) { - window.history.pushState(jsonurl, "", url); - if (error.responseText) { - $("#error").html (error.responseText); - } else { - $("#error").html ('Error loading url: ' + encodeURI(jsonurl)); - } - console.log('getJSON failed: ' + JSON.stringify(error, null, 4)); - }); - } -}; - -function link_Clicked (event) { - var currentLink = $(this); - if (!isPushStateEnabled || - currentData.page === "19") { - return; - } - // let read, fetch, zippper etc. do their thing - var url = currentLink.attr('href'); - if (url.includes('/read/') || - url.includes('/fetch/') || - url.includes('/zipper/') || - url.includes('/covers/') || - url.includes('/files/')) { - return; - } - event.preventDefault(); - - if ($(".mfp-ready").length) - { - $.magnificPopup.close(); - } - - // The bookdetail / about should be displayed in a lightbox - if (getCurrentOption ("use_fancyapps") === "1" && - (currentLink.hasClass ("fancydetail") || currentLink.hasClass ("fancyabout"))) { - before = new Date (); - // @todo handle 'json' routes correctly - //var jsonurl = url.replace ("index.php", "getJSON.php"); - var jsonurl = url; - $.getJSON(jsonurl, function(data) { - data.c = currentData.c; - var detail = ""; - if (data.page === "16") { - detail = data.fullhtml; - } else { - detail = templateBookDetail (data); - } - $.magnificPopup.open({ - items: { - src: detail, - type: 'inline' - } - }); - debug_log (elapsed ()); - }); - return; - } - navigateTo (url); -} - -function search_Submitted (event) { - if (!isPushStateEnabled || - currentData.page === "19") { - return; - } - event.preventDefault(); - var url = str_format (currentData.baseurl + "?page=9¤t={0}&query={1}&db={2}", currentData.page, encodeURIComponent ($("input[name=query]").val ()), currentData.databaseId); - if (currentData.libraryId) { - url = url + '&vl=' + encodeURIComponent(currentData.libraryId); - } - navigateTo (url); -} - -/*exported handleLinks */ -function handleLinks () { - if (currentData && currentData.baseurl) { - $("body").on ("click", "a[href^='" + currentData.baseurl + "']", link_Clicked); - } else { - $("body").on ("click", "a[href^='index']", link_Clicked); - } - $("body").on ("submit", "#searchForm", search_Submitted); - $("body").on ("click", "#sort", function(){ - $('.books').sortElements(function(a, b){ - var test = 1; - if ($("#sortorder").val() === "desc") - { - test = -1; - } - return $(a).find ("." + $("#sortchoice").val()).text() > $(b).find ("." + $("#sortchoice").val()).text() ? test : -test; - }); - }); - - $("body").on ("click", ".headright", function(){ - if ($("#tool").is(":hidden")) { - $("#tool").slideDown("slow"); - Cookies.get('toolbar', '1', { expires: 365 }); - } else { - $("#tool").slideUp(); - Cookies.remove('toolbar'); - } - }); - $("body").magnificPopup({ - delegate: '.fancycover', // child items selector, by clicking on it popup will open - type: 'image', - gallery:{enabled:true, preload: [0,2]}, - disableOn: function() { - if( getCurrentOption ("use_fancyapps") === "1" ) { - return true; - } - return false; - } - }); -} - -window.onpopstate = function(event) { - if (!isDefined (currentData)) { - return; - } - - before = new Date (); - var data = cache.get (event.state); - updatePage (data); -}; - -$(document).on("keydown", function(e){ - if (e.which === 37 && $("#prevLink").length > 0) { - navigateTo ($("#prevLink").attr('href')); - } - if (e.which === 39 && $("#nextLink").length > 0) { - navigateTo ($("#nextLink").attr('href')); - } -}); - -/*exported initiateAjax */ -function initiateAjax (url, theme, templates) { - templates = typeof templates !== 'undefined' ? templates : 'templates'; - $.when($.get(templates + '/' + theme + '/header.html'), - $.get(templates + '/' + theme + '/footer.html'), - $.get(templates + '/' + theme + '/bookdetail.html'), - $.get(templates + '/' + theme + '/main.html'), - $.get(templates + '/' + theme + '/page.html'), - $.get(templates + '/' + theme + '/suggestion.html'), - $.getJSON(url)).done(function(header, footer, bookdetail, main, page, suggestion, data){ - templateBookDetail = doT.template (bookdetail [0]); - - var defMain = { - bookdetail: bookdetail [0] - }; - - templateMain = doT.template (main [0], undefined, defMain); - - var defPage = { - header: header [0], - footer: footer [0], - main : main [0], - bookdetail: bookdetail [0] - }; - - templatePage = doT.template (page [0], undefined, defPage); - - templateSuggestion = doT.template (suggestion [0]); - - currentData = data [0]; - - updatePage (data [0]); - cache.put (url, data [0]); - if (isPushStateEnabled) { - window.history.replaceState(url, "", window.location); - } - handleLinks (); - }).fail(function (error) { - if (error.responseText) { - document.write (error.responseText); - } else { - document.write ('Error loading templates from directory "' + encodeURI(templates + '/' + theme) + '/" for url: ' + encodeURI(url)); - } - console.log('getJSON failed: ' + JSON.stringify(error, null, 4)); - }); -} - -/** Moved from util.js to twigged cops.js due to unknown issue with Kindle - see #36 -function initiateTwig(url, theme, templates = 'templates') { - templates = typeof templates !== 'undefined' ? templates : 'templates'; - Twig.extendFunction("str_format", str_format); - Twig.extendFunction("asset", asset); - - let template = Twig.twig({ - id: 'page', - href: templates + '/' + theme + '/page.html', - async: false - }); - - templatePage = function (data) { - return Twig.twig({ref: 'page'}).render({it: data}); - }; - - $.when($.getJSON(url)).done(function(data){ - currentData = data; - - updatePage (currentData); - cache.put (url, currentData); - if (isPushStateEnabled) { - window.history.replaceState(url, "", window.location); - } - handleLinks (); - }).fail(function (error) { - if (error.responseText) { - document.write (error.responseText); - } else { - document.write ('Error loading templates from directory "' + encodeURI(templates + '/' + theme) + '/" for url: ' + encodeURI(url)); - } - console.log('getJSON failed: ' + JSON.stringify(error, null, 4)); - }); -} - */ diff --git a/COPS/cops-3.1.3/vendor/autoload.php b/COPS/cops-3.1.3/vendor/autoload.php deleted file mode 100644 index e8a5d317..00000000 --- a/COPS/cops-3.1.3/vendor/autoload.php +++ /dev/null @@ -1,25 +0,0 @@ - - * Jordi Boggiano - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Composer\Autoload; - -/** - * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. - * - * $loader = new \Composer\Autoload\ClassLoader(); - * - * // register classes with namespaces - * $loader->add('Symfony\Component', __DIR__.'/component'); - * $loader->add('Symfony', __DIR__.'/framework'); - * - * // activate the autoloader - * $loader->register(); - * - * // to enable searching the include path (eg. for PEAR packages) - * $loader->setUseIncludePath(true); - * - * In this example, if you try to use a class in the Symfony\Component - * namespace or one of its children (Symfony\Component\Console for instance), - * the autoloader will first look for the class under the component/ - * directory, and it will then fallback to the framework/ directory if not - * found before giving up. - * - * This class is loosely based on the Symfony UniversalClassLoader. - * - * @author Fabien Potencier - * @author Jordi Boggiano - * @see https://www.php-fig.org/psr/psr-0/ - * @see https://www.php-fig.org/psr/psr-4/ - */ -class ClassLoader -{ - /** @var \Closure(string):void */ - private static $includeFile; - - /** @var string|null */ - private $vendorDir; - - // PSR-4 - /** - * @var array> - */ - private $prefixLengthsPsr4 = array(); - /** - * @var array> - */ - private $prefixDirsPsr4 = array(); - /** - * @var list - */ - private $fallbackDirsPsr4 = array(); - - // PSR-0 - /** - * List of PSR-0 prefixes - * - * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) - * - * @var array>> - */ - private $prefixesPsr0 = array(); - /** - * @var list - */ - private $fallbackDirsPsr0 = array(); - - /** @var bool */ - private $useIncludePath = false; - - /** - * @var array - */ - private $classMap = array(); - - /** @var bool */ - private $classMapAuthoritative = false; - - /** - * @var array - */ - private $missingClasses = array(); - - /** @var string|null */ - private $apcuPrefix; - - /** - * @var array - */ - private static $registeredLoaders = array(); - - /** - * @param string|null $vendorDir - */ - public function __construct($vendorDir = null) - { - $this->vendorDir = $vendorDir; - self::initializeIncludeClosure(); - } - - /** - * @return array> - */ - public function getPrefixes() - { - if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); - } - - return array(); - } - - /** - * @return array> - */ - public function getPrefixesPsr4() - { - return $this->prefixDirsPsr4; - } - - /** - * @return list - */ - public function getFallbackDirs() - { - return $this->fallbackDirsPsr0; - } - - /** - * @return list - */ - public function getFallbackDirsPsr4() - { - return $this->fallbackDirsPsr4; - } - - /** - * @return array Array of classname => path - */ - public function getClassMap() - { - return $this->classMap; - } - - /** - * @param array $classMap Class to filename map - * - * @return void - */ - public function addClassMap(array $classMap) - { - if ($this->classMap) { - $this->classMap = array_merge($this->classMap, $classMap); - } else { - $this->classMap = $classMap; - } - } - - /** - * Registers a set of PSR-0 directories for a given prefix, either - * appending or prepending to the ones previously set for this prefix. - * - * @param string $prefix The prefix - * @param list|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories - * - * @return void - */ - public function add($prefix, $paths, $prepend = false) - { - $paths = (array) $paths; - if (!$prefix) { - if ($prepend) { - $this->fallbackDirsPsr0 = array_merge( - $paths, - $this->fallbackDirsPsr0 - ); - } else { - $this->fallbackDirsPsr0 = array_merge( - $this->fallbackDirsPsr0, - $paths - ); - } - - return; - } - - $first = $prefix[0]; - if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = $paths; - - return; - } - if ($prepend) { - $this->prefixesPsr0[$first][$prefix] = array_merge( - $paths, - $this->prefixesPsr0[$first][$prefix] - ); - } else { - $this->prefixesPsr0[$first][$prefix] = array_merge( - $this->prefixesPsr0[$first][$prefix], - $paths - ); - } - } - - /** - * Registers a set of PSR-4 directories for a given namespace, either - * appending or prepending to the ones previously set for this namespace. - * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param list|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories - * - * @throws \InvalidArgumentException - * - * @return void - */ - public function addPsr4($prefix, $paths, $prepend = false) - { - $paths = (array) $paths; - if (!$prefix) { - // Register directories for the root namespace. - if ($prepend) { - $this->fallbackDirsPsr4 = array_merge( - $paths, - $this->fallbackDirsPsr4 - ); - } else { - $this->fallbackDirsPsr4 = array_merge( - $this->fallbackDirsPsr4, - $paths - ); - } - } elseif (!isset($this->prefixDirsPsr4[$prefix])) { - // Register directories for a new namespace. - $length = strlen($prefix); - if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); - } - $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = $paths; - } elseif ($prepend) { - // Prepend directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - $paths, - $this->prefixDirsPsr4[$prefix] - ); - } else { - // Append directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - $this->prefixDirsPsr4[$prefix], - $paths - ); - } - } - - /** - * Registers a set of PSR-0 directories for a given prefix, - * replacing any others previously set for this prefix. - * - * @param string $prefix The prefix - * @param list|string $paths The PSR-0 base directories - * - * @return void - */ - public function set($prefix, $paths) - { - if (!$prefix) { - $this->fallbackDirsPsr0 = (array) $paths; - } else { - $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; - } - } - - /** - * Registers a set of PSR-4 directories for a given namespace, - * replacing any others previously set for this namespace. - * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param list|string $paths The PSR-4 base directories - * - * @throws \InvalidArgumentException - * - * @return void - */ - public function setPsr4($prefix, $paths) - { - if (!$prefix) { - $this->fallbackDirsPsr4 = (array) $paths; - } else { - $length = strlen($prefix); - if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); - } - $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; - } - } - - /** - * Turns on searching the include path for class files. - * - * @param bool $useIncludePath - * - * @return void - */ - public function setUseIncludePath($useIncludePath) - { - $this->useIncludePath = $useIncludePath; - } - - /** - * Can be used to check if the autoloader uses the include path to check - * for classes. - * - * @return bool - */ - public function getUseIncludePath() - { - return $this->useIncludePath; - } - - /** - * Turns off searching the prefix and fallback directories for classes - * that have not been registered with the class map. - * - * @param bool $classMapAuthoritative - * - * @return void - */ - public function setClassMapAuthoritative($classMapAuthoritative) - { - $this->classMapAuthoritative = $classMapAuthoritative; - } - - /** - * Should class lookup fail if not found in the current class map? - * - * @return bool - */ - public function isClassMapAuthoritative() - { - return $this->classMapAuthoritative; - } - - /** - * APCu prefix to use to cache found/not-found classes, if the extension is enabled. - * - * @param string|null $apcuPrefix - * - * @return void - */ - public function setApcuPrefix($apcuPrefix) - { - $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; - } - - /** - * The APCu prefix in use, or null if APCu caching is not enabled. - * - * @return string|null - */ - public function getApcuPrefix() - { - return $this->apcuPrefix; - } - - /** - * Registers this instance as an autoloader. - * - * @param bool $prepend Whether to prepend the autoloader or not - * - * @return void - */ - public function register($prepend = false) - { - spl_autoload_register(array($this, 'loadClass'), true, $prepend); - - if (null === $this->vendorDir) { - return; - } - - if ($prepend) { - self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; - } else { - unset(self::$registeredLoaders[$this->vendorDir]); - self::$registeredLoaders[$this->vendorDir] = $this; - } - } - - /** - * Unregisters this instance as an autoloader. - * - * @return void - */ - public function unregister() - { - spl_autoload_unregister(array($this, 'loadClass')); - - if (null !== $this->vendorDir) { - unset(self::$registeredLoaders[$this->vendorDir]); - } - } - - /** - * Loads the given class or interface. - * - * @param string $class The name of the class - * @return true|null True if loaded, null otherwise - */ - public function loadClass($class) - { - if ($file = $this->findFile($class)) { - $includeFile = self::$includeFile; - $includeFile($file); - - return true; - } - - return null; - } - - /** - * Finds the path to the file where the class is defined. - * - * @param string $class The name of the class - * - * @return string|false The path if found, false otherwise - */ - public function findFile($class) - { - // class map lookup - if (isset($this->classMap[$class])) { - return $this->classMap[$class]; - } - if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { - return false; - } - if (null !== $this->apcuPrefix) { - $file = apcu_fetch($this->apcuPrefix.$class, $hit); - if ($hit) { - return $file; - } - } - - $file = $this->findFileWithExtension($class, '.php'); - - // Search for Hack files if we are running on HHVM - if (false === $file && defined('HHVM_VERSION')) { - $file = $this->findFileWithExtension($class, '.hh'); - } - - if (null !== $this->apcuPrefix) { - apcu_add($this->apcuPrefix.$class, $file); - } - - if (false === $file) { - // Remember that this class does not exist. - $this->missingClasses[$class] = true; - } - - return $file; - } - - /** - * Returns the currently registered loaders keyed by their corresponding vendor directories. - * - * @return array - */ - public static function getRegisteredLoaders() - { - return self::$registeredLoaders; - } - - /** - * @param string $class - * @param string $ext - * @return string|false - */ - private function findFileWithExtension($class, $ext) - { - // PSR-4 lookup - $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; - - $first = $class[0]; - if (isset($this->prefixLengthsPsr4[$first])) { - $subPath = $class; - while (false !== $lastPos = strrpos($subPath, '\\')) { - $subPath = substr($subPath, 0, $lastPos); - $search = $subPath . '\\'; - if (isset($this->prefixDirsPsr4[$search])) { - $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); - foreach ($this->prefixDirsPsr4[$search] as $dir) { - if (file_exists($file = $dir . $pathEnd)) { - return $file; - } - } - } - } - } - - // PSR-4 fallback dirs - foreach ($this->fallbackDirsPsr4 as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { - return $file; - } - } - - // PSR-0 lookup - if (false !== $pos = strrpos($class, '\\')) { - // namespaced class name - $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) - . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); - } else { - // PEAR-like class name - $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; - } - - if (isset($this->prefixesPsr0[$first])) { - foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { - if (0 === strpos($class, $prefix)) { - foreach ($dirs as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; - } - } - } - } - } - - // PSR-0 fallback dirs - foreach ($this->fallbackDirsPsr0 as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; - } - } - - // PSR-0 include paths. - if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { - return $file; - } - - return false; - } - - /** - * @return void - */ - private static function initializeIncludeClosure() - { - if (self::$includeFile !== null) { - return; - } - - /** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - * - * @param string $file - * @return void - */ - self::$includeFile = \Closure::bind(static function($file) { - include $file; - }, null, null); - } -} diff --git a/COPS/cops-3.1.3/vendor/composer/InstalledVersions.php b/COPS/cops-3.1.3/vendor/composer/InstalledVersions.php deleted file mode 100644 index 51e734a7..00000000 --- a/COPS/cops-3.1.3/vendor/composer/InstalledVersions.php +++ /dev/null @@ -1,359 +0,0 @@ - - * Jordi Boggiano - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Composer; - -use Composer\Autoload\ClassLoader; -use Composer\Semver\VersionParser; - -/** - * This class is copied in every Composer installed project and available to all - * - * See also https://getcomposer.org/doc/07-runtime.md#installed-versions - * - * To require its presence, you can require `composer-runtime-api ^2.0` - * - * @final - */ -class InstalledVersions -{ - /** - * @var mixed[]|null - * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null - */ - private static $installed; - - /** - * @var bool|null - */ - private static $canGetVendors; - - /** - * @var array[] - * @psalm-var array}> - */ - private static $installedByVendor = array(); - - /** - * Returns a list of all package names which are present, either by being installed, replaced or provided - * - * @return string[] - * @psalm-return list - */ - public static function getInstalledPackages() - { - $packages = array(); - foreach (self::getInstalled() as $installed) { - $packages[] = array_keys($installed['versions']); - } - - if (1 === \count($packages)) { - return $packages[0]; - } - - return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); - } - - /** - * Returns a list of all package names with a specific type e.g. 'library' - * - * @param string $type - * @return string[] - * @psalm-return list - */ - public static function getInstalledPackagesByType($type) - { - $packagesByType = array(); - - foreach (self::getInstalled() as $installed) { - foreach ($installed['versions'] as $name => $package) { - if (isset($package['type']) && $package['type'] === $type) { - $packagesByType[] = $name; - } - } - } - - return $packagesByType; - } - - /** - * Checks whether the given package is installed - * - * This also returns true if the package name is provided or replaced by another package - * - * @param string $packageName - * @param bool $includeDevRequirements - * @return bool - */ - public static function isInstalled($packageName, $includeDevRequirements = true) - { - foreach (self::getInstalled() as $installed) { - if (isset($installed['versions'][$packageName])) { - return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; - } - } - - return false; - } - - /** - * Checks whether the given package satisfies a version constraint - * - * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: - * - * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') - * - * @param VersionParser $parser Install composer/semver to have access to this class and functionality - * @param string $packageName - * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package - * @return bool - */ - public static function satisfies(VersionParser $parser, $packageName, $constraint) - { - $constraint = $parser->parseConstraints((string) $constraint); - $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); - - return $provided->matches($constraint); - } - - /** - * Returns a version constraint representing all the range(s) which are installed for a given package - * - * It is easier to use this via isInstalled() with the $constraint argument if you need to check - * whether a given version of a package is installed, and not just whether it exists - * - * @param string $packageName - * @return string Version constraint usable with composer/semver - */ - public static function getVersionRanges($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - $ranges = array(); - if (isset($installed['versions'][$packageName]['pretty_version'])) { - $ranges[] = $installed['versions'][$packageName]['pretty_version']; - } - if (array_key_exists('aliases', $installed['versions'][$packageName])) { - $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); - } - if (array_key_exists('replaced', $installed['versions'][$packageName])) { - $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); - } - if (array_key_exists('provided', $installed['versions'][$packageName])) { - $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); - } - - return implode(' || ', $ranges); - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @param string $packageName - * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present - */ - public static function getVersion($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - if (!isset($installed['versions'][$packageName]['version'])) { - return null; - } - - return $installed['versions'][$packageName]['version']; - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @param string $packageName - * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present - */ - public static function getPrettyVersion($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - if (!isset($installed['versions'][$packageName]['pretty_version'])) { - return null; - } - - return $installed['versions'][$packageName]['pretty_version']; - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @param string $packageName - * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference - */ - public static function getReference($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - if (!isset($installed['versions'][$packageName]['reference'])) { - return null; - } - - return $installed['versions'][$packageName]['reference']; - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @param string $packageName - * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. - */ - public static function getInstallPath($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @return array - * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} - */ - public static function getRootPackage() - { - $installed = self::getInstalled(); - - return $installed[0]['root']; - } - - /** - * Returns the raw installed.php data for custom implementations - * - * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. - * @return array[] - * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} - */ - public static function getRawData() - { - @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); - - if (null === self::$installed) { - // only require the installed.php file if this file is loaded from its dumped location, - // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 - if (substr(__DIR__, -8, 1) !== 'C') { - self::$installed = include __DIR__ . '/installed.php'; - } else { - self::$installed = array(); - } - } - - return self::$installed; - } - - /** - * Returns the raw data of all installed.php which are currently loaded for custom implementations - * - * @return array[] - * @psalm-return list}> - */ - public static function getAllRawData() - { - return self::getInstalled(); - } - - /** - * Lets you reload the static array from another file - * - * This is only useful for complex integrations in which a project needs to use - * this class but then also needs to execute another project's autoloader in process, - * and wants to ensure both projects have access to their version of installed.php. - * - * A typical case would be PHPUnit, where it would need to make sure it reads all - * the data it needs from this class, then call reload() with - * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure - * the project in which it runs can then also use this class safely, without - * interference between PHPUnit's dependencies and the project's dependencies. - * - * @param array[] $data A vendor/composer/installed.php data set - * @return void - * - * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data - */ - public static function reload($data) - { - self::$installed = $data; - self::$installedByVendor = array(); - } - - /** - * @return array[] - * @psalm-return list}> - */ - private static function getInstalled() - { - if (null === self::$canGetVendors) { - self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); - } - - $installed = array(); - - if (self::$canGetVendors) { - foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { - if (isset(self::$installedByVendor[$vendorDir])) { - $installed[] = self::$installedByVendor[$vendorDir]; - } elseif (is_file($vendorDir.'/composer/installed.php')) { - /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ - $required = require $vendorDir.'/composer/installed.php'; - $installed[] = self::$installedByVendor[$vendorDir] = $required; - if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { - self::$installed = $installed[count($installed) - 1]; - } - } - } - } - - if (null === self::$installed) { - // only require the installed.php file if this file is loaded from its dumped location, - // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 - if (substr(__DIR__, -8, 1) !== 'C') { - /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ - $required = require __DIR__ . '/installed.php'; - self::$installed = $required; - } else { - self::$installed = array(); - } - } - - if (self::$installed !== array()) { - $installed[] = self::$installed; - } - - return $installed; - } -} diff --git a/COPS/cops-3.1.3/vendor/composer/LICENSE b/COPS/cops-3.1.3/vendor/composer/LICENSE deleted file mode 100644 index f27399a0..00000000 --- a/COPS/cops-3.1.3/vendor/composer/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ - -Copyright (c) Nils Adermann, Jordi Boggiano - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - diff --git a/COPS/cops-3.1.3/vendor/composer/autoload_classmap.php b/COPS/cops-3.1.3/vendor/composer/autoload_classmap.php deleted file mode 100644 index c4022e6a..00000000 --- a/COPS/cops-3.1.3/vendor/composer/autoload_classmap.php +++ /dev/null @@ -1,447 +0,0 @@ - $vendorDir . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php', - 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', - 'FastRoute\\BadRouteException' => $vendorDir . '/nikic/fast-route/src/BadRouteException.php', - 'FastRoute\\Cache' => $vendorDir . '/nikic/fast-route/src/Cache.php', - 'FastRoute\\Cache\\FileCache' => $vendorDir . '/nikic/fast-route/src/Cache/FileCache.php', - 'FastRoute\\Cache\\Psr16Cache' => $vendorDir . '/nikic/fast-route/src/Cache/Psr16Cache.php', - 'FastRoute\\ConfigureRoutes' => $vendorDir . '/nikic/fast-route/src/ConfigureRoutes.php', - 'FastRoute\\DataGenerator' => $vendorDir . '/nikic/fast-route/src/DataGenerator.php', - 'FastRoute\\DataGenerator\\CharCountBased' => $vendorDir . '/nikic/fast-route/src/DataGenerator/CharCountBased.php', - 'FastRoute\\DataGenerator\\GroupCountBased' => $vendorDir . '/nikic/fast-route/src/DataGenerator/GroupCountBased.php', - 'FastRoute\\DataGenerator\\GroupPosBased' => $vendorDir . '/nikic/fast-route/src/DataGenerator/GroupPosBased.php', - 'FastRoute\\DataGenerator\\MarkBased' => $vendorDir . '/nikic/fast-route/src/DataGenerator/MarkBased.php', - 'FastRoute\\DataGenerator\\RegexBasedAbstract' => $vendorDir . '/nikic/fast-route/src/DataGenerator/RegexBasedAbstract.php', - 'FastRoute\\Dispatcher' => $vendorDir . '/nikic/fast-route/src/Dispatcher.php', - 'FastRoute\\Dispatcher\\CharCountBased' => $vendorDir . '/nikic/fast-route/src/Dispatcher/CharCountBased.php', - 'FastRoute\\Dispatcher\\GroupCountBased' => $vendorDir . '/nikic/fast-route/src/Dispatcher/GroupCountBased.php', - 'FastRoute\\Dispatcher\\GroupPosBased' => $vendorDir . '/nikic/fast-route/src/Dispatcher/GroupPosBased.php', - 'FastRoute\\Dispatcher\\MarkBased' => $vendorDir . '/nikic/fast-route/src/Dispatcher/MarkBased.php', - 'FastRoute\\Dispatcher\\RegexBasedAbstract' => $vendorDir . '/nikic/fast-route/src/Dispatcher/RegexBasedAbstract.php', - 'FastRoute\\Dispatcher\\Result\\Matched' => $vendorDir . '/nikic/fast-route/src/Dispatcher/Result/Matched.php', - 'FastRoute\\Dispatcher\\Result\\MethodNotAllowed' => $vendorDir . '/nikic/fast-route/src/Dispatcher/Result/MethodNotAllowed.php', - 'FastRoute\\Dispatcher\\Result\\NotMatched' => $vendorDir . '/nikic/fast-route/src/Dispatcher/Result/NotMatched.php', - 'FastRoute\\Exception' => $vendorDir . '/nikic/fast-route/src/Exception.php', - 'FastRoute\\FastRoute' => $vendorDir . '/nikic/fast-route/src/FastRoute.php', - 'FastRoute\\GenerateUri' => $vendorDir . '/nikic/fast-route/src/GenerateUri.php', - 'FastRoute\\GenerateUri\\FromProcessedConfiguration' => $vendorDir . '/nikic/fast-route/src/GenerateUri/FromProcessedConfiguration.php', - 'FastRoute\\GenerateUri\\UriCouldNotBeGenerated' => $vendorDir . '/nikic/fast-route/src/GenerateUri/UriCouldNotBeGenerated.php', - 'FastRoute\\Route' => $vendorDir . '/nikic/fast-route/src/Route.php', - 'FastRoute\\RouteCollector' => $vendorDir . '/nikic/fast-route/src/RouteCollector.php', - 'FastRoute\\RouteParser' => $vendorDir . '/nikic/fast-route/src/RouteParser.php', - 'FastRoute\\RouteParser\\Std' => $vendorDir . '/nikic/fast-route/src/RouteParser/Std.php', - 'Marsender\\EPubLoader\\GoogleBooks\\AccessInfo' => $baseDir . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\Epub' => $baseDir . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\ImageLinks' => $baseDir . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\IndustryIdentifiers' => $baseDir . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\ListPrice' => $baseDir . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\OfferListPrice' => $baseDir . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\OfferRetailPrice' => $baseDir . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\Offers' => $baseDir . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\PanelizationSummary' => $baseDir . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\Pdf' => $baseDir . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\ReadingModes' => $baseDir . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\RetailPrice' => $baseDir . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\SaleInfo' => $baseDir . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\SearchInfo' => $baseDir . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\SearchResult' => $baseDir . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\SeriesInfo' => $baseDir . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\Volume' => $baseDir . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\VolumeInfo' => $baseDir . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\VolumeSeries' => $baseDir . '/tests/cache/google/authors_generated.php', - 'PHPMailer\\PHPMailer\\DSNConfigurator' => $vendorDir . '/phpmailer/phpmailer/src/DSNConfigurator.php', - 'PHPMailer\\PHPMailer\\Exception' => $vendorDir . '/phpmailer/phpmailer/src/Exception.php', - 'PHPMailer\\PHPMailer\\OAuth' => $vendorDir . '/phpmailer/phpmailer/src/OAuth.php', - 'PHPMailer\\PHPMailer\\OAuthTokenProvider' => $vendorDir . '/phpmailer/phpmailer/src/OAuthTokenProvider.php', - 'PHPMailer\\PHPMailer\\PHPMailer' => $vendorDir . '/phpmailer/phpmailer/src/PHPMailer.php', - 'PHPMailer\\PHPMailer\\POP3' => $vendorDir . '/phpmailer/phpmailer/src/POP3.php', - 'PHPMailer\\PHPMailer\\SMTP' => $vendorDir . '/phpmailer/phpmailer/src/SMTP.php', - 'Psr\\SimpleCache\\CacheException' => $vendorDir . '/psr/simple-cache/src/CacheException.php', - 'Psr\\SimpleCache\\CacheInterface' => $vendorDir . '/psr/simple-cache/src/CacheInterface.php', - 'Psr\\SimpleCache\\InvalidArgumentException' => $vendorDir . '/psr/simple-cache/src/InvalidArgumentException.php', - 'ReturnTypeWillChange' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php', - 'SebLucas\\Cops\\Calibre\\Annotation' => $baseDir . '/src/Calibre/Annotation.php', - 'SebLucas\\Cops\\Calibre\\Author' => $baseDir . '/src/Calibre/Author.php', - 'SebLucas\\Cops\\Calibre\\Base' => $baseDir . '/src/Calibre/Base.php', - 'SebLucas\\Cops\\Calibre\\BaseList' => $baseDir . '/src/Calibre/BaseList.php', - 'SebLucas\\Cops\\Calibre\\Book' => $baseDir . '/src/Calibre/Book.php', - 'SebLucas\\Cops\\Calibre\\BookList' => $baseDir . '/src/Calibre/BookList.php', - 'SebLucas\\Cops\\Calibre\\Category' => $baseDir . '/src/Calibre/Category.php', - 'SebLucas\\Cops\\Calibre\\Cover' => $baseDir . '/src/Calibre/Cover.php', - 'SebLucas\\Cops\\Calibre\\CustomColumn' => $baseDir . '/src/Calibre/CustomColumn.php', - 'SebLucas\\Cops\\Calibre\\CustomColumnType' => $baseDir . '/src/Calibre/CustomColumnType.php', - 'SebLucas\\Cops\\Calibre\\CustomColumnTypeBool' => $baseDir . '/src/Calibre/CustomColumnTypeBool.php', - 'SebLucas\\Cops\\Calibre\\CustomColumnTypeComment' => $baseDir . '/src/Calibre/CustomColumnTypeComment.php', - 'SebLucas\\Cops\\Calibre\\CustomColumnTypeDate' => $baseDir . '/src/Calibre/CustomColumnTypeDate.php', - 'SebLucas\\Cops\\Calibre\\CustomColumnTypeEnumeration' => $baseDir . '/src/Calibre/CustomColumnTypeEnumeration.php', - 'SebLucas\\Cops\\Calibre\\CustomColumnTypeFloat' => $baseDir . '/src/Calibre/CustomColumnTypeFloat.php', - 'SebLucas\\Cops\\Calibre\\CustomColumnTypeInteger' => $baseDir . '/src/Calibre/CustomColumnTypeInteger.php', - 'SebLucas\\Cops\\Calibre\\CustomColumnTypeRating' => $baseDir . '/src/Calibre/CustomColumnTypeRating.php', - 'SebLucas\\Cops\\Calibre\\CustomColumnTypeSeries' => $baseDir . '/src/Calibre/CustomColumnTypeSeries.php', - 'SebLucas\\Cops\\Calibre\\CustomColumnTypeText' => $baseDir . '/src/Calibre/CustomColumnTypeText.php', - 'SebLucas\\Cops\\Calibre\\Data' => $baseDir . '/src/Calibre/Data.php', - 'SebLucas\\Cops\\Calibre\\Database' => $baseDir . '/src/Calibre/Database.php', - 'SebLucas\\Cops\\Calibre\\Filter' => $baseDir . '/src/Calibre/Filter.php', - 'SebLucas\\Cops\\Calibre\\Identifier' => $baseDir . '/src/Calibre/Identifier.php', - 'SebLucas\\Cops\\Calibre\\Language' => $baseDir . '/src/Calibre/Language.php', - 'SebLucas\\Cops\\Calibre\\Metadata' => $baseDir . '/src/Calibre/Metadata.php', - 'SebLucas\\Cops\\Calibre\\Note' => $baseDir . '/src/Calibre/Note.php', - 'SebLucas\\Cops\\Calibre\\Preference' => $baseDir . '/src/Calibre/Preference.php', - 'SebLucas\\Cops\\Calibre\\Publisher' => $baseDir . '/src/Calibre/Publisher.php', - 'SebLucas\\Cops\\Calibre\\Rating' => $baseDir . '/src/Calibre/Rating.php', - 'SebLucas\\Cops\\Calibre\\Resource' => $baseDir . '/src/Calibre/Resource.php', - 'SebLucas\\Cops\\Calibre\\Serie' => $baseDir . '/src/Calibre/Serie.php', - 'SebLucas\\Cops\\Calibre\\Tag' => $baseDir . '/src/Calibre/Tag.php', - 'SebLucas\\Cops\\Calibre\\User' => $baseDir . '/src/Calibre/User.php', - 'SebLucas\\Cops\\Calibre\\VirtualLibrary' => $baseDir . '/src/Calibre/VirtualLibrary.php', - 'SebLucas\\Cops\\Framework' => $baseDir . '/src/Framework.php', - 'SebLucas\\Cops\\Handlers\\BaseHandler' => $baseDir . '/src/Handlers/BaseHandler.php', - 'SebLucas\\Cops\\Handlers\\CalResHandler' => $baseDir . '/src/Handlers/CalResHandler.php', - 'SebLucas\\Cops\\Handlers\\CheckHandler' => $baseDir . '/src/Handlers/CheckHandler.php', - 'SebLucas\\Cops\\Handlers\\EpubFsHandler' => $baseDir . '/src/Handlers/EpubFsHandler.php', - 'SebLucas\\Cops\\Handlers\\FeedHandler' => $baseDir . '/src/Handlers/FeedHandler.php', - 'SebLucas\\Cops\\Handlers\\FetchHandler' => $baseDir . '/src/Handlers/FetchHandler.php', - 'SebLucas\\Cops\\Handlers\\GraphQLHandler' => $baseDir . '/src/Handlers/GraphQLHandler.php', - 'SebLucas\\Cops\\Handlers\\HtmlHandler' => $baseDir . '/src/Handlers/HtmlHandler.php', - 'SebLucas\\Cops\\Handlers\\JsonHandler' => $baseDir . '/src/Handlers/JsonHandler.php', - 'SebLucas\\Cops\\Handlers\\LoaderHandler' => $baseDir . '/src/Handlers/LoaderHandler.php', - 'SebLucas\\Cops\\Handlers\\MailHandler' => $baseDir . '/src/Handlers/MailHandler.php', - 'SebLucas\\Cops\\Handlers\\OpdsHandler' => $baseDir . '/src/Handlers/OpdsHandler.php', - 'SebLucas\\Cops\\Handlers\\PageHandler' => $baseDir . '/src/Handlers/PageHandler.php', - 'SebLucas\\Cops\\Handlers\\QueueBasedHandler' => $baseDir . '/src/Handlers/QueueBasedHandler.php', - 'SebLucas\\Cops\\Handlers\\ReadHandler' => $baseDir . '/src/Handlers/ReadHandler.php', - 'SebLucas\\Cops\\Handlers\\RestApiHandler' => $baseDir . '/src/Handlers/RestApiHandler.php', - 'SebLucas\\Cops\\Handlers\\ZipFsHandler' => $baseDir . '/src/Handlers/ZipFsHandler.php', - 'SebLucas\\Cops\\Handlers\\ZipperHandler' => $baseDir . '/src/Handlers/ZipperHandler.php', - 'SebLucas\\Cops\\Input\\Config' => $baseDir . '/src/Input/Config.php', - 'SebLucas\\Cops\\Input\\Context' => $baseDir . '/src/Input/Context.php', - 'SebLucas\\Cops\\Input\\Request' => $baseDir . '/src/Input/Request.php', - 'SebLucas\\Cops\\Input\\Route' => $baseDir . '/src/Input/Route.php', - 'SebLucas\\Cops\\Language\\Translation' => $baseDir . '/src/Language/Translation.php', - 'SebLucas\\Cops\\Model\\Entry' => $baseDir . '/src/Model/Entry.php', - 'SebLucas\\Cops\\Model\\EntryBook' => $baseDir . '/src/Model/EntryBook.php', - 'SebLucas\\Cops\\Model\\Link' => $baseDir . '/src/Model/Link.php', - 'SebLucas\\Cops\\Model\\LinkEntry' => $baseDir . '/src/Model/LinkEntry.php', - 'SebLucas\\Cops\\Model\\LinkFacet' => $baseDir . '/src/Model/LinkFacet.php', - 'SebLucas\\Cops\\Model\\LinkFeed' => $baseDir . '/src/Model/LinkFeed.php', - 'SebLucas\\Cops\\Model\\LinkNavigation' => $baseDir . '/src/Model/LinkNavigation.php', - 'SebLucas\\Cops\\Output\\BaseRenderer' => $baseDir . '/src/Output/BaseRenderer.php', - 'SebLucas\\Cops\\Output\\DotPHPTemplate' => $baseDir . '/src/Output/DotPHPTemplate.php', - 'SebLucas\\Cops\\Output\\EPubReader' => $baseDir . '/src/Output/EPubReader.php', - 'SebLucas\\Cops\\Output\\FileResponse' => $baseDir . '/src/Output/FileResponse.php', - 'SebLucas\\Cops\\Output\\Format' => $baseDir . '/src/Output/Format.php', - 'SebLucas\\Cops\\Output\\HtmlRenderer' => $baseDir . '/src/Output/HtmlRenderer.php', - 'SebLucas\\Cops\\Output\\JsonRenderer' => $baseDir . '/src/Output/JsonRenderer.php', - 'SebLucas\\Cops\\Output\\KiwilanOPDS' => $baseDir . '/src/Output/KiwilanOPDS.php', - 'SebLucas\\Cops\\Output\\Mail' => $baseDir . '/src/Output/Mail.php', - 'SebLucas\\Cops\\Output\\OpdsRenderer' => $baseDir . '/src/Output/OpdsRenderer.php', - 'SebLucas\\Cops\\Output\\Response' => $baseDir . '/src/Output/Response.php', - 'SebLucas\\Cops\\Output\\RestApi' => $baseDir . '/src/Output/RestApi.php', - 'SebLucas\\Cops\\Output\\TwigTemplate' => $baseDir . '/src/Output/TwigTemplate.php', - 'SebLucas\\Cops\\Output\\Zipper' => $baseDir . '/src/Output/Zipper.php', - 'SebLucas\\Cops\\Pages\\Page' => $baseDir . '/src/Pages/Page.php', - 'SebLucas\\Cops\\Pages\\PageAbout' => $baseDir . '/src/Pages/PageAbout.php', - 'SebLucas\\Cops\\Pages\\PageAllAuthors' => $baseDir . '/src/Pages/PageAllAuthors.php', - 'SebLucas\\Cops\\Pages\\PageAllAuthorsLetter' => $baseDir . '/src/Pages/PageAllAuthorsLetter.php', - 'SebLucas\\Cops\\Pages\\PageAllBooks' => $baseDir . '/src/Pages/PageAllBooks.php', - 'SebLucas\\Cops\\Pages\\PageAllBooksLetter' => $baseDir . '/src/Pages/PageAllBooksLetter.php', - 'SebLucas\\Cops\\Pages\\PageAllBooksYear' => $baseDir . '/src/Pages/PageAllBooksYear.php', - 'SebLucas\\Cops\\Pages\\PageAllCustoms' => $baseDir . '/src/Pages/PageAllCustoms.php', - 'SebLucas\\Cops\\Pages\\PageAllIdentifiers' => $baseDir . '/src/Pages/PageAllIdentifiers.php', - 'SebLucas\\Cops\\Pages\\PageAllLanguages' => $baseDir . '/src/Pages/PageAllLanguages.php', - 'SebLucas\\Cops\\Pages\\PageAllPublishers' => $baseDir . '/src/Pages/PageAllPublishers.php', - 'SebLucas\\Cops\\Pages\\PageAllRating' => $baseDir . '/src/Pages/PageAllRating.php', - 'SebLucas\\Cops\\Pages\\PageAllSeries' => $baseDir . '/src/Pages/PageAllSeries.php', - 'SebLucas\\Cops\\Pages\\PageAllTags' => $baseDir . '/src/Pages/PageAllTags.php', - 'SebLucas\\Cops\\Pages\\PageAllVirtualLibraries' => $baseDir . '/src/Pages/PageAllVirtualLibraries.php', - 'SebLucas\\Cops\\Pages\\PageAuthorDetail' => $baseDir . '/src/Pages/PageAuthorDetail.php', - 'SebLucas\\Cops\\Pages\\PageBookDetail' => $baseDir . '/src/Pages/PageBookDetail.php', - 'SebLucas\\Cops\\Pages\\PageCustomDetail' => $baseDir . '/src/Pages/PageCustomDetail.php', - 'SebLucas\\Cops\\Pages\\PageCustomize' => $baseDir . '/src/Pages/PageCustomize.php', - 'SebLucas\\Cops\\Pages\\PageId' => $baseDir . '/src/Pages/PageId.php', - 'SebLucas\\Cops\\Pages\\PageIdentifierDetail' => $baseDir . '/src/Pages/PageIdentifierDetail.php', - 'SebLucas\\Cops\\Pages\\PageIndex' => $baseDir . '/src/Pages/PageIndex.php', - 'SebLucas\\Cops\\Pages\\PageLanguageDetail' => $baseDir . '/src/Pages/PageLanguageDetail.php', - 'SebLucas\\Cops\\Pages\\PagePublisherDetail' => $baseDir . '/src/Pages/PagePublisherDetail.php', - 'SebLucas\\Cops\\Pages\\PageQueryResult' => $baseDir . '/src/Pages/PageQueryResult.php', - 'SebLucas\\Cops\\Pages\\PageRatingDetail' => $baseDir . '/src/Pages/PageRatingDetail.php', - 'SebLucas\\Cops\\Pages\\PageRecentBooks' => $baseDir . '/src/Pages/PageRecentBooks.php', - 'SebLucas\\Cops\\Pages\\PageSerieDetail' => $baseDir . '/src/Pages/PageSerieDetail.php', - 'SebLucas\\Cops\\Pages\\PageTagDetail' => $baseDir . '/src/Pages/PageTagDetail.php', - 'SebLucas\\Cops\\Pages\\PageWithDetail' => $baseDir . '/src/Pages/PageWithDetail.php', - 'SebLucas\\Cops\\Tests\\BaseTest' => $baseDir . '/tests/baseTest.php', - 'SebLucas\\Cops\\Tests\\BookListTest' => $baseDir . '/tests/BookListTest.php', - 'SebLucas\\Cops\\Tests\\BookTest' => $baseDir . '/tests/BookTest.php', - 'SebLucas\\Cops\\Tests\\BrowserKitTest' => $baseDir . '/tests/BrowserKitTest.php', - 'SebLucas\\Cops\\Tests\\ConfigTest' => $baseDir . '/tests/ConfigTest.php', - 'SebLucas\\Cops\\Tests\\CustomColumnsTest' => $baseDir . '/tests/customColumnsTest.php', - 'SebLucas\\Cops\\Tests\\EpubFsTest' => $baseDir . '/tests/EpubFsTest.php', - 'SebLucas\\Cops\\Tests\\EpubReaderTest' => $baseDir . '/tests/EpubReaderTest.php', - 'SebLucas\\Cops\\Tests\\FetchHandlerTest' => $baseDir . '/tests/FetchHandlerTest.php', - 'SebLucas\\Cops\\Tests\\FilterTest' => $baseDir . '/tests/FilterTest.php', - 'SebLucas\\Cops\\Tests\\FrameworkTest' => $baseDir . '/tests/FrameworkTest.php', - 'SebLucas\\Cops\\Tests\\GraphQLHandlerTest' => $baseDir . '/tests/GraphQLHandlerTest.php', - 'SebLucas\\Cops\\Tests\\HtmlRendererTest' => $baseDir . '/tests/HtmlRendererTest.php', - 'SebLucas\\Cops\\Tests\\JsonRendererTest' => $baseDir . '/tests/JsonRendererTest.php', - 'SebLucas\\Cops\\Tests\\KiwilanTest' => $baseDir . '/tests/KiwilanTest.php', - 'SebLucas\\Cops\\Tests\\MailTest' => $baseDir . '/tests/MailTest.php', - 'SebLucas\\Cops\\Tests\\NoteResourceTest' => $baseDir . '/tests/NoteResourceTest.php', - 'SebLucas\\Cops\\Tests\\OpdsRendererTest' => $baseDir . '/tests/OpdsRendererTest.php', - 'SebLucas\\Cops\\Tests\\PageMultiDatabaseTest' => $baseDir . '/tests/PageMultiDatabaseTest.php', - 'SebLucas\\Cops\\Tests\\PageTest' => $baseDir . '/tests/PageTest.php', - 'SebLucas\\Cops\\Tests\\RestApiTest' => $baseDir . '/tests/RestApiTest.php', - 'SebLucas\\Cops\\Tests\\RouteTest' => $baseDir . '/tests/RouteTest.php', - 'SebLucas\\Cops\\Tests\\TypeAheadSearchTest' => $baseDir . '/tests/TypeAheadSearchTest.php', - 'SebLucas\\Cops\\Tests\\UserTest' => $baseDir . '/tests/UserTest.php', - 'SebLucas\\Cops\\Tests\\WebDriverTest' => $baseDir . '/tests/WebDriverTest.php', - 'SebLucas\\Cops\\Tests\\WebDriverTestCase' => $baseDir . '/tests/WebDriverTestCase.php', - 'SebLucas\\Cops\\Tests\\ZipperTest' => $baseDir . '/tests/ZipperTest.php', - 'SebLucas\\EPubMeta\\App\\Handler' => $vendorDir . '/mikespub/php-epub-meta/src/App/Handler.php', - 'SebLucas\\EPubMeta\\App\\Util' => $vendorDir . '/mikespub/php-epub-meta/src/App/Util.php', - 'SebLucas\\EPubMeta\\Contents\\Nav' => $vendorDir . '/mikespub/php-epub-meta/src/Contents/Nav.php', - 'SebLucas\\EPubMeta\\Contents\\NavPoint' => $vendorDir . '/mikespub/php-epub-meta/src/Contents/NavPoint.php', - 'SebLucas\\EPubMeta\\Contents\\NavPointList' => $vendorDir . '/mikespub/php-epub-meta/src/Contents/NavPointList.php', - 'SebLucas\\EPubMeta\\Contents\\Spine' => $vendorDir . '/mikespub/php-epub-meta/src/Contents/Spine.php', - 'SebLucas\\EPubMeta\\Contents\\Toc' => $vendorDir . '/mikespub/php-epub-meta/src/Contents/Toc.php', - 'SebLucas\\EPubMeta\\Data\\Item' => $vendorDir . '/mikespub/php-epub-meta/src/Data/Item.php', - 'SebLucas\\EPubMeta\\Data\\Manifest' => $vendorDir . '/mikespub/php-epub-meta/src/Data/Manifest.php', - 'SebLucas\\EPubMeta\\Dom\\Element' => $vendorDir . '/mikespub/php-epub-meta/src/Dom/Element.php', - 'SebLucas\\EPubMeta\\Dom\\XPath' => $vendorDir . '/mikespub/php-epub-meta/src/Dom/XPath.php', - 'SebLucas\\EPubMeta\\EPub' => $vendorDir . '/mikespub/php-epub-meta/src/EPub.php', - 'SebLucas\\EPubMeta\\Other' => $vendorDir . '/mikespub/php-epub-meta/src/Other.php', - 'SebLucas\\EPubMeta\\Tools\\HtmlTools' => $vendorDir . '/mikespub/php-epub-meta/src/Tools/HtmlTools.php', - 'SebLucas\\EPubMeta\\Tools\\ZipEdit' => $vendorDir . '/mikespub/php-epub-meta/src/Tools/ZipEdit.php', - 'SebLucas\\EPubMeta\\Tools\\ZipFile' => $vendorDir . '/mikespub/php-epub-meta/src/Tools/ZipFile.php', - 'SebLucas\\Template\\doT' => $baseDir . '/resources/dot-php/doT.php', - 'Symfony\\Polyfill\\Ctype\\Ctype' => $vendorDir . '/symfony/polyfill-ctype/Ctype.php', - 'Symfony\\Polyfill\\Mbstring\\Mbstring' => $vendorDir . '/symfony/polyfill-mbstring/Mbstring.php', - 'Symfony\\Polyfill\\Php81\\Php81' => $vendorDir . '/symfony/polyfill-php81/Php81.php', - 'Twig\\AbstractTwigCallable' => $vendorDir . '/twig/twig/src/AbstractTwigCallable.php', - 'Twig\\Attribute\\FirstClassTwigCallableReady' => $vendorDir . '/twig/twig/src/Attribute/FirstClassTwigCallableReady.php', - 'Twig\\Attribute\\YieldReady' => $vendorDir . '/twig/twig/src/Attribute/YieldReady.php', - 'Twig\\Cache\\CacheInterface' => $vendorDir . '/twig/twig/src/Cache/CacheInterface.php', - 'Twig\\Cache\\ChainCache' => $vendorDir . '/twig/twig/src/Cache/ChainCache.php', - 'Twig\\Cache\\FilesystemCache' => $vendorDir . '/twig/twig/src/Cache/FilesystemCache.php', - 'Twig\\Cache\\NullCache' => $vendorDir . '/twig/twig/src/Cache/NullCache.php', - 'Twig\\Cache\\ReadOnlyFilesystemCache' => $vendorDir . '/twig/twig/src/Cache/ReadOnlyFilesystemCache.php', - 'Twig\\Compiler' => $vendorDir . '/twig/twig/src/Compiler.php', - 'Twig\\Environment' => $vendorDir . '/twig/twig/src/Environment.php', - 'Twig\\Error\\Error' => $vendorDir . '/twig/twig/src/Error/Error.php', - 'Twig\\Error\\LoaderError' => $vendorDir . '/twig/twig/src/Error/LoaderError.php', - 'Twig\\Error\\RuntimeError' => $vendorDir . '/twig/twig/src/Error/RuntimeError.php', - 'Twig\\Error\\SyntaxError' => $vendorDir . '/twig/twig/src/Error/SyntaxError.php', - 'Twig\\ExpressionParser' => $vendorDir . '/twig/twig/src/ExpressionParser.php', - 'Twig\\ExtensionSet' => $vendorDir . '/twig/twig/src/ExtensionSet.php', - 'Twig\\Extension\\AbstractExtension' => $vendorDir . '/twig/twig/src/Extension/AbstractExtension.php', - 'Twig\\Extension\\CoreExtension' => $vendorDir . '/twig/twig/src/Extension/CoreExtension.php', - 'Twig\\Extension\\DebugExtension' => $vendorDir . '/twig/twig/src/Extension/DebugExtension.php', - 'Twig\\Extension\\EscaperExtension' => $vendorDir . '/twig/twig/src/Extension/EscaperExtension.php', - 'Twig\\Extension\\ExtensionInterface' => $vendorDir . '/twig/twig/src/Extension/ExtensionInterface.php', - 'Twig\\Extension\\GlobalsInterface' => $vendorDir . '/twig/twig/src/Extension/GlobalsInterface.php', - 'Twig\\Extension\\OptimizerExtension' => $vendorDir . '/twig/twig/src/Extension/OptimizerExtension.php', - 'Twig\\Extension\\ProfilerExtension' => $vendorDir . '/twig/twig/src/Extension/ProfilerExtension.php', - 'Twig\\Extension\\RuntimeExtensionInterface' => $vendorDir . '/twig/twig/src/Extension/RuntimeExtensionInterface.php', - 'Twig\\Extension\\SandboxExtension' => $vendorDir . '/twig/twig/src/Extension/SandboxExtension.php', - 'Twig\\Extension\\StagingExtension' => $vendorDir . '/twig/twig/src/Extension/StagingExtension.php', - 'Twig\\Extension\\StringLoaderExtension' => $vendorDir . '/twig/twig/src/Extension/StringLoaderExtension.php', - 'Twig\\Extension\\YieldNotReadyExtension' => $vendorDir . '/twig/twig/src/Extension/YieldNotReadyExtension.php', - 'Twig\\FileExtensionEscapingStrategy' => $vendorDir . '/twig/twig/src/FileExtensionEscapingStrategy.php', - 'Twig\\Lexer' => $vendorDir . '/twig/twig/src/Lexer.php', - 'Twig\\Loader\\ArrayLoader' => $vendorDir . '/twig/twig/src/Loader/ArrayLoader.php', - 'Twig\\Loader\\ChainLoader' => $vendorDir . '/twig/twig/src/Loader/ChainLoader.php', - 'Twig\\Loader\\FilesystemLoader' => $vendorDir . '/twig/twig/src/Loader/FilesystemLoader.php', - 'Twig\\Loader\\LoaderInterface' => $vendorDir . '/twig/twig/src/Loader/LoaderInterface.php', - 'Twig\\Markup' => $vendorDir . '/twig/twig/src/Markup.php', - 'Twig\\NodeTraverser' => $vendorDir . '/twig/twig/src/NodeTraverser.php', - 'Twig\\NodeVisitor\\AbstractNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/AbstractNodeVisitor.php', - 'Twig\\NodeVisitor\\EscaperNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/EscaperNodeVisitor.php', - 'Twig\\NodeVisitor\\MacroAutoImportNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/MacroAutoImportNodeVisitor.php', - 'Twig\\NodeVisitor\\NodeVisitorInterface' => $vendorDir . '/twig/twig/src/NodeVisitor/NodeVisitorInterface.php', - 'Twig\\NodeVisitor\\OptimizerNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/OptimizerNodeVisitor.php', - 'Twig\\NodeVisitor\\SafeAnalysisNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/SafeAnalysisNodeVisitor.php', - 'Twig\\NodeVisitor\\SandboxNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/SandboxNodeVisitor.php', - 'Twig\\NodeVisitor\\YieldNotReadyNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/YieldNotReadyNodeVisitor.php', - 'Twig\\Node\\AutoEscapeNode' => $vendorDir . '/twig/twig/src/Node/AutoEscapeNode.php', - 'Twig\\Node\\BlockNode' => $vendorDir . '/twig/twig/src/Node/BlockNode.php', - 'Twig\\Node\\BlockReferenceNode' => $vendorDir . '/twig/twig/src/Node/BlockReferenceNode.php', - 'Twig\\Node\\BodyNode' => $vendorDir . '/twig/twig/src/Node/BodyNode.php', - 'Twig\\Node\\CaptureNode' => $vendorDir . '/twig/twig/src/Node/CaptureNode.php', - 'Twig\\Node\\CheckSecurityCallNode' => $vendorDir . '/twig/twig/src/Node/CheckSecurityCallNode.php', - 'Twig\\Node\\CheckSecurityNode' => $vendorDir . '/twig/twig/src/Node/CheckSecurityNode.php', - 'Twig\\Node\\CheckToStringNode' => $vendorDir . '/twig/twig/src/Node/CheckToStringNode.php', - 'Twig\\Node\\DeprecatedNode' => $vendorDir . '/twig/twig/src/Node/DeprecatedNode.php', - 'Twig\\Node\\DoNode' => $vendorDir . '/twig/twig/src/Node/DoNode.php', - 'Twig\\Node\\EmbedNode' => $vendorDir . '/twig/twig/src/Node/EmbedNode.php', - 'Twig\\Node\\Expression\\AbstractExpression' => $vendorDir . '/twig/twig/src/Node/Expression/AbstractExpression.php', - 'Twig\\Node\\Expression\\ArrayExpression' => $vendorDir . '/twig/twig/src/Node/Expression/ArrayExpression.php', - 'Twig\\Node\\Expression\\ArrowFunctionExpression' => $vendorDir . '/twig/twig/src/Node/Expression/ArrowFunctionExpression.php', - 'Twig\\Node\\Expression\\AssignNameExpression' => $vendorDir . '/twig/twig/src/Node/Expression/AssignNameExpression.php', - 'Twig\\Node\\Expression\\Binary\\AbstractBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/AbstractBinary.php', - 'Twig\\Node\\Expression\\Binary\\AddBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/AddBinary.php', - 'Twig\\Node\\Expression\\Binary\\AndBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/AndBinary.php', - 'Twig\\Node\\Expression\\Binary\\BitwiseAndBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/BitwiseAndBinary.php', - 'Twig\\Node\\Expression\\Binary\\BitwiseOrBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/BitwiseOrBinary.php', - 'Twig\\Node\\Expression\\Binary\\BitwiseXorBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/BitwiseXorBinary.php', - 'Twig\\Node\\Expression\\Binary\\ConcatBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/ConcatBinary.php', - 'Twig\\Node\\Expression\\Binary\\DivBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/DivBinary.php', - 'Twig\\Node\\Expression\\Binary\\EndsWithBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/EndsWithBinary.php', - 'Twig\\Node\\Expression\\Binary\\EqualBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/EqualBinary.php', - 'Twig\\Node\\Expression\\Binary\\FloorDivBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/FloorDivBinary.php', - 'Twig\\Node\\Expression\\Binary\\GreaterBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/GreaterBinary.php', - 'Twig\\Node\\Expression\\Binary\\GreaterEqualBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/GreaterEqualBinary.php', - 'Twig\\Node\\Expression\\Binary\\HasEveryBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/HasEveryBinary.php', - 'Twig\\Node\\Expression\\Binary\\HasSomeBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/HasSomeBinary.php', - 'Twig\\Node\\Expression\\Binary\\InBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/InBinary.php', - 'Twig\\Node\\Expression\\Binary\\LessBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/LessBinary.php', - 'Twig\\Node\\Expression\\Binary\\LessEqualBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/LessEqualBinary.php', - 'Twig\\Node\\Expression\\Binary\\MatchesBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/MatchesBinary.php', - 'Twig\\Node\\Expression\\Binary\\ModBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/ModBinary.php', - 'Twig\\Node\\Expression\\Binary\\MulBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/MulBinary.php', - 'Twig\\Node\\Expression\\Binary\\NotEqualBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/NotEqualBinary.php', - 'Twig\\Node\\Expression\\Binary\\NotInBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/NotInBinary.php', - 'Twig\\Node\\Expression\\Binary\\OrBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/OrBinary.php', - 'Twig\\Node\\Expression\\Binary\\PowerBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/PowerBinary.php', - 'Twig\\Node\\Expression\\Binary\\RangeBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/RangeBinary.php', - 'Twig\\Node\\Expression\\Binary\\SpaceshipBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/SpaceshipBinary.php', - 'Twig\\Node\\Expression\\Binary\\StartsWithBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/StartsWithBinary.php', - 'Twig\\Node\\Expression\\Binary\\SubBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/SubBinary.php', - 'Twig\\Node\\Expression\\BlockReferenceExpression' => $vendorDir . '/twig/twig/src/Node/Expression/BlockReferenceExpression.php', - 'Twig\\Node\\Expression\\CallExpression' => $vendorDir . '/twig/twig/src/Node/Expression/CallExpression.php', - 'Twig\\Node\\Expression\\ConditionalExpression' => $vendorDir . '/twig/twig/src/Node/Expression/ConditionalExpression.php', - 'Twig\\Node\\Expression\\ConstantExpression' => $vendorDir . '/twig/twig/src/Node/Expression/ConstantExpression.php', - 'Twig\\Node\\Expression\\FilterExpression' => $vendorDir . '/twig/twig/src/Node/Expression/FilterExpression.php', - 'Twig\\Node\\Expression\\Filter\\DefaultFilter' => $vendorDir . '/twig/twig/src/Node/Expression/Filter/DefaultFilter.php', - 'Twig\\Node\\Expression\\Filter\\RawFilter' => $vendorDir . '/twig/twig/src/Node/Expression/Filter/RawFilter.php', - 'Twig\\Node\\Expression\\FunctionExpression' => $vendorDir . '/twig/twig/src/Node/Expression/FunctionExpression.php', - 'Twig\\Node\\Expression\\FunctionNode\\EnumCasesFunction' => $vendorDir . '/twig/twig/src/Node/Expression/FunctionNode/EnumCasesFunction.php', - 'Twig\\Node\\Expression\\GetAttrExpression' => $vendorDir . '/twig/twig/src/Node/Expression/GetAttrExpression.php', - 'Twig\\Node\\Expression\\InlinePrint' => $vendorDir . '/twig/twig/src/Node/Expression/InlinePrint.php', - 'Twig\\Node\\Expression\\MethodCallExpression' => $vendorDir . '/twig/twig/src/Node/Expression/MethodCallExpression.php', - 'Twig\\Node\\Expression\\NameExpression' => $vendorDir . '/twig/twig/src/Node/Expression/NameExpression.php', - 'Twig\\Node\\Expression\\NullCoalesceExpression' => $vendorDir . '/twig/twig/src/Node/Expression/NullCoalesceExpression.php', - 'Twig\\Node\\Expression\\ParentExpression' => $vendorDir . '/twig/twig/src/Node/Expression/ParentExpression.php', - 'Twig\\Node\\Expression\\TempNameExpression' => $vendorDir . '/twig/twig/src/Node/Expression/TempNameExpression.php', - 'Twig\\Node\\Expression\\TestExpression' => $vendorDir . '/twig/twig/src/Node/Expression/TestExpression.php', - 'Twig\\Node\\Expression\\Test\\ConstantTest' => $vendorDir . '/twig/twig/src/Node/Expression/Test/ConstantTest.php', - 'Twig\\Node\\Expression\\Test\\DefinedTest' => $vendorDir . '/twig/twig/src/Node/Expression/Test/DefinedTest.php', - 'Twig\\Node\\Expression\\Test\\DivisiblebyTest' => $vendorDir . '/twig/twig/src/Node/Expression/Test/DivisiblebyTest.php', - 'Twig\\Node\\Expression\\Test\\EvenTest' => $vendorDir . '/twig/twig/src/Node/Expression/Test/EvenTest.php', - 'Twig\\Node\\Expression\\Test\\NullTest' => $vendorDir . '/twig/twig/src/Node/Expression/Test/NullTest.php', - 'Twig\\Node\\Expression\\Test\\OddTest' => $vendorDir . '/twig/twig/src/Node/Expression/Test/OddTest.php', - 'Twig\\Node\\Expression\\Test\\SameasTest' => $vendorDir . '/twig/twig/src/Node/Expression/Test/SameasTest.php', - 'Twig\\Node\\Expression\\Unary\\AbstractUnary' => $vendorDir . '/twig/twig/src/Node/Expression/Unary/AbstractUnary.php', - 'Twig\\Node\\Expression\\Unary\\NegUnary' => $vendorDir . '/twig/twig/src/Node/Expression/Unary/NegUnary.php', - 'Twig\\Node\\Expression\\Unary\\NotUnary' => $vendorDir . '/twig/twig/src/Node/Expression/Unary/NotUnary.php', - 'Twig\\Node\\Expression\\Unary\\PosUnary' => $vendorDir . '/twig/twig/src/Node/Expression/Unary/PosUnary.php', - 'Twig\\Node\\Expression\\VariadicExpression' => $vendorDir . '/twig/twig/src/Node/Expression/VariadicExpression.php', - 'Twig\\Node\\FlushNode' => $vendorDir . '/twig/twig/src/Node/FlushNode.php', - 'Twig\\Node\\ForLoopNode' => $vendorDir . '/twig/twig/src/Node/ForLoopNode.php', - 'Twig\\Node\\ForNode' => $vendorDir . '/twig/twig/src/Node/ForNode.php', - 'Twig\\Node\\IfNode' => $vendorDir . '/twig/twig/src/Node/IfNode.php', - 'Twig\\Node\\ImportNode' => $vendorDir . '/twig/twig/src/Node/ImportNode.php', - 'Twig\\Node\\IncludeNode' => $vendorDir . '/twig/twig/src/Node/IncludeNode.php', - 'Twig\\Node\\MacroNode' => $vendorDir . '/twig/twig/src/Node/MacroNode.php', - 'Twig\\Node\\ModuleNode' => $vendorDir . '/twig/twig/src/Node/ModuleNode.php', - 'Twig\\Node\\NameDeprecation' => $vendorDir . '/twig/twig/src/Node/NameDeprecation.php', - 'Twig\\Node\\Node' => $vendorDir . '/twig/twig/src/Node/Node.php', - 'Twig\\Node\\NodeCaptureInterface' => $vendorDir . '/twig/twig/src/Node/NodeCaptureInterface.php', - 'Twig\\Node\\NodeOutputInterface' => $vendorDir . '/twig/twig/src/Node/NodeOutputInterface.php', - 'Twig\\Node\\PrintNode' => $vendorDir . '/twig/twig/src/Node/PrintNode.php', - 'Twig\\Node\\SandboxNode' => $vendorDir . '/twig/twig/src/Node/SandboxNode.php', - 'Twig\\Node\\SetNode' => $vendorDir . '/twig/twig/src/Node/SetNode.php', - 'Twig\\Node\\TextNode' => $vendorDir . '/twig/twig/src/Node/TextNode.php', - 'Twig\\Node\\TypesNode' => $vendorDir . '/twig/twig/src/Node/TypesNode.php', - 'Twig\\Node\\WithNode' => $vendorDir . '/twig/twig/src/Node/WithNode.php', - 'Twig\\Parser' => $vendorDir . '/twig/twig/src/Parser.php', - 'Twig\\Profiler\\Dumper\\BaseDumper' => $vendorDir . '/twig/twig/src/Profiler/Dumper/BaseDumper.php', - 'Twig\\Profiler\\Dumper\\BlackfireDumper' => $vendorDir . '/twig/twig/src/Profiler/Dumper/BlackfireDumper.php', - 'Twig\\Profiler\\Dumper\\HtmlDumper' => $vendorDir . '/twig/twig/src/Profiler/Dumper/HtmlDumper.php', - 'Twig\\Profiler\\Dumper\\TextDumper' => $vendorDir . '/twig/twig/src/Profiler/Dumper/TextDumper.php', - 'Twig\\Profiler\\NodeVisitor\\ProfilerNodeVisitor' => $vendorDir . '/twig/twig/src/Profiler/NodeVisitor/ProfilerNodeVisitor.php', - 'Twig\\Profiler\\Node\\EnterProfileNode' => $vendorDir . '/twig/twig/src/Profiler/Node/EnterProfileNode.php', - 'Twig\\Profiler\\Node\\LeaveProfileNode' => $vendorDir . '/twig/twig/src/Profiler/Node/LeaveProfileNode.php', - 'Twig\\Profiler\\Profile' => $vendorDir . '/twig/twig/src/Profiler/Profile.php', - 'Twig\\RuntimeLoader\\ContainerRuntimeLoader' => $vendorDir . '/twig/twig/src/RuntimeLoader/ContainerRuntimeLoader.php', - 'Twig\\RuntimeLoader\\FactoryRuntimeLoader' => $vendorDir . '/twig/twig/src/RuntimeLoader/FactoryRuntimeLoader.php', - 'Twig\\RuntimeLoader\\RuntimeLoaderInterface' => $vendorDir . '/twig/twig/src/RuntimeLoader/RuntimeLoaderInterface.php', - 'Twig\\Runtime\\EscaperRuntime' => $vendorDir . '/twig/twig/src/Runtime/EscaperRuntime.php', - 'Twig\\Sandbox\\SecurityError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityError.php', - 'Twig\\Sandbox\\SecurityNotAllowedFilterError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityNotAllowedFilterError.php', - 'Twig\\Sandbox\\SecurityNotAllowedFunctionError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityNotAllowedFunctionError.php', - 'Twig\\Sandbox\\SecurityNotAllowedMethodError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityNotAllowedMethodError.php', - 'Twig\\Sandbox\\SecurityNotAllowedPropertyError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityNotAllowedPropertyError.php', - 'Twig\\Sandbox\\SecurityNotAllowedTagError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityNotAllowedTagError.php', - 'Twig\\Sandbox\\SecurityPolicy' => $vendorDir . '/twig/twig/src/Sandbox/SecurityPolicy.php', - 'Twig\\Sandbox\\SecurityPolicyInterface' => $vendorDir . '/twig/twig/src/Sandbox/SecurityPolicyInterface.php', - 'Twig\\Sandbox\\SourcePolicyInterface' => $vendorDir . '/twig/twig/src/Sandbox/SourcePolicyInterface.php', - 'Twig\\Source' => $vendorDir . '/twig/twig/src/Source.php', - 'Twig\\Template' => $vendorDir . '/twig/twig/src/Template.php', - 'Twig\\TemplateWrapper' => $vendorDir . '/twig/twig/src/TemplateWrapper.php', - 'Twig\\Test\\IntegrationTestCase' => $vendorDir . '/twig/twig/src/Test/IntegrationTestCase.php', - 'Twig\\Test\\NodeTestCase' => $vendorDir . '/twig/twig/src/Test/NodeTestCase.php', - 'Twig\\Token' => $vendorDir . '/twig/twig/src/Token.php', - 'Twig\\TokenParser\\AbstractTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/AbstractTokenParser.php', - 'Twig\\TokenParser\\ApplyTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/ApplyTokenParser.php', - 'Twig\\TokenParser\\AutoEscapeTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/AutoEscapeTokenParser.php', - 'Twig\\TokenParser\\BlockTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/BlockTokenParser.php', - 'Twig\\TokenParser\\DeprecatedTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/DeprecatedTokenParser.php', - 'Twig\\TokenParser\\DoTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/DoTokenParser.php', - 'Twig\\TokenParser\\EmbedTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/EmbedTokenParser.php', - 'Twig\\TokenParser\\ExtendsTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/ExtendsTokenParser.php', - 'Twig\\TokenParser\\FlushTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/FlushTokenParser.php', - 'Twig\\TokenParser\\ForTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/ForTokenParser.php', - 'Twig\\TokenParser\\FromTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/FromTokenParser.php', - 'Twig\\TokenParser\\IfTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/IfTokenParser.php', - 'Twig\\TokenParser\\ImportTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/ImportTokenParser.php', - 'Twig\\TokenParser\\IncludeTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/IncludeTokenParser.php', - 'Twig\\TokenParser\\MacroTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/MacroTokenParser.php', - 'Twig\\TokenParser\\SandboxTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/SandboxTokenParser.php', - 'Twig\\TokenParser\\SetTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/SetTokenParser.php', - 'Twig\\TokenParser\\TokenParserInterface' => $vendorDir . '/twig/twig/src/TokenParser/TokenParserInterface.php', - 'Twig\\TokenParser\\TypesTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/TypesTokenParser.php', - 'Twig\\TokenParser\\UseTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/UseTokenParser.php', - 'Twig\\TokenParser\\WithTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/WithTokenParser.php', - 'Twig\\TokenStream' => $vendorDir . '/twig/twig/src/TokenStream.php', - 'Twig\\TwigCallableInterface' => $vendorDir . '/twig/twig/src/TwigCallableInterface.php', - 'Twig\\TwigFilter' => $vendorDir . '/twig/twig/src/TwigFilter.php', - 'Twig\\TwigFunction' => $vendorDir . '/twig/twig/src/TwigFunction.php', - 'Twig\\TwigTest' => $vendorDir . '/twig/twig/src/TwigTest.php', - 'Twig\\Util\\CallableArgumentsExtractor' => $vendorDir . '/twig/twig/src/Util/CallableArgumentsExtractor.php', - 'Twig\\Util\\DeprecationCollector' => $vendorDir . '/twig/twig/src/Util/DeprecationCollector.php', - 'Twig\\Util\\ReflectionCallable' => $vendorDir . '/twig/twig/src/Util/ReflectionCallable.php', - 'Twig\\Util\\TemplateDirIterator' => $vendorDir . '/twig/twig/src/Util/TemplateDirIterator.php', - 'ZipStream\\CentralDirectoryFileHeader' => $vendorDir . '/maennchen/zipstream-php/src/CentralDirectoryFileHeader.php', - 'ZipStream\\CompressionMethod' => $vendorDir . '/maennchen/zipstream-php/src/CompressionMethod.php', - 'ZipStream\\DataDescriptor' => $vendorDir . '/maennchen/zipstream-php/src/DataDescriptor.php', - 'ZipStream\\EndOfCentralDirectory' => $vendorDir . '/maennchen/zipstream-php/src/EndOfCentralDirectory.php', - 'ZipStream\\Exception' => $vendorDir . '/maennchen/zipstream-php/src/Exception.php', - 'ZipStream\\Exception\\DosTimeOverflowException' => $vendorDir . '/maennchen/zipstream-php/src/Exception/DosTimeOverflowException.php', - 'ZipStream\\Exception\\FileNotFoundException' => $vendorDir . '/maennchen/zipstream-php/src/Exception/FileNotFoundException.php', - 'ZipStream\\Exception\\FileNotReadableException' => $vendorDir . '/maennchen/zipstream-php/src/Exception/FileNotReadableException.php', - 'ZipStream\\Exception\\FileSizeIncorrectException' => $vendorDir . '/maennchen/zipstream-php/src/Exception/FileSizeIncorrectException.php', - 'ZipStream\\Exception\\OverflowException' => $vendorDir . '/maennchen/zipstream-php/src/Exception/OverflowException.php', - 'ZipStream\\Exception\\ResourceActionException' => $vendorDir . '/maennchen/zipstream-php/src/Exception/ResourceActionException.php', - 'ZipStream\\Exception\\SimulationFileUnknownException' => $vendorDir . '/maennchen/zipstream-php/src/Exception/SimulationFileUnknownException.php', - 'ZipStream\\Exception\\StreamNotReadableException' => $vendorDir . '/maennchen/zipstream-php/src/Exception/StreamNotReadableException.php', - 'ZipStream\\Exception\\StreamNotSeekableException' => $vendorDir . '/maennchen/zipstream-php/src/Exception/StreamNotSeekableException.php', - 'ZipStream\\File' => $vendorDir . '/maennchen/zipstream-php/src/File.php', - 'ZipStream\\GeneralPurposeBitFlag' => $vendorDir . '/maennchen/zipstream-php/src/GeneralPurposeBitFlag.php', - 'ZipStream\\LocalFileHeader' => $vendorDir . '/maennchen/zipstream-php/src/LocalFileHeader.php', - 'ZipStream\\OperationMode' => $vendorDir . '/maennchen/zipstream-php/src/OperationMode.php', - 'ZipStream\\PackField' => $vendorDir . '/maennchen/zipstream-php/src/PackField.php', - 'ZipStream\\Time' => $vendorDir . '/maennchen/zipstream-php/src/Time.php', - 'ZipStream\\Version' => $vendorDir . '/maennchen/zipstream-php/src/Version.php', - 'ZipStream\\Zip64\\DataDescriptor' => $vendorDir . '/maennchen/zipstream-php/src/Zip64/DataDescriptor.php', - 'ZipStream\\Zip64\\EndOfCentralDirectory' => $vendorDir . '/maennchen/zipstream-php/src/Zip64/EndOfCentralDirectory.php', - 'ZipStream\\Zip64\\EndOfCentralDirectoryLocator' => $vendorDir . '/maennchen/zipstream-php/src/Zip64/EndOfCentralDirectoryLocator.php', - 'ZipStream\\Zip64\\ExtendedInformationExtraField' => $vendorDir . '/maennchen/zipstream-php/src/Zip64/ExtendedInformationExtraField.php', - 'ZipStream\\ZipStream' => $vendorDir . '/maennchen/zipstream-php/src/ZipStream.php', - 'ZipStream\\Zs\\ExtendedInformationExtraField' => $vendorDir . '/maennchen/zipstream-php/src/Zs/ExtendedInformationExtraField.php', -); diff --git a/COPS/cops-3.1.3/vendor/composer/autoload_files.php b/COPS/cops-3.1.3/vendor/composer/autoload_files.php deleted file mode 100644 index 35ae312e..00000000 --- a/COPS/cops-3.1.3/vendor/composer/autoload_files.php +++ /dev/null @@ -1,19 +0,0 @@ - $vendorDir . '/symfony/deprecation-contracts/function.php', - '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', - '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', - '23c18046f52bef3eea034657bafda50f' => $vendorDir . '/symfony/polyfill-php81/bootstrap.php', - '253c157292f75eb38082b5acb06f3f01' => $vendorDir . '/nikic/fast-route/src/functions.php', - '89efb1254ef2d1c5d80096acd12c4098' => $vendorDir . '/twig/twig/src/Resources/core.php', - 'ffecb95d45175fd40f75be8a23b34f90' => $vendorDir . '/twig/twig/src/Resources/debug.php', - 'c7baa00073ee9c61edf148c51917cfb4' => $vendorDir . '/twig/twig/src/Resources/escaper.php', - 'f844ccf1d25df8663951193c3fc307c8' => $vendorDir . '/twig/twig/src/Resources/string_loader.php', - 'b468aea609079bd3f2a8b35133ae246a' => $baseDir . '/src/functions.php', -); diff --git a/COPS/cops-3.1.3/vendor/composer/autoload_namespaces.php b/COPS/cops-3.1.3/vendor/composer/autoload_namespaces.php deleted file mode 100644 index 15a2ff3a..00000000 --- a/COPS/cops-3.1.3/vendor/composer/autoload_namespaces.php +++ /dev/null @@ -1,9 +0,0 @@ - array($vendorDir . '/maennchen/zipstream-php/src'), - 'Twig\\' => array($vendorDir . '/twig/twig/src'), - 'Symfony\\Polyfill\\Php81\\' => array($vendorDir . '/symfony/polyfill-php81'), - 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), - 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), - 'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'), - 'PHPMailer\\PHPMailer\\' => array($vendorDir . '/phpmailer/phpmailer/src'), - 'FastRoute\\' => array($vendorDir . '/nikic/fast-route/src'), -); diff --git a/COPS/cops-3.1.3/vendor/composer/autoload_real.php b/COPS/cops-3.1.3/vendor/composer/autoload_real.php deleted file mode 100644 index c0c0e510..00000000 --- a/COPS/cops-3.1.3/vendor/composer/autoload_real.php +++ /dev/null @@ -1,50 +0,0 @@ -register(true); - - $filesToLoad = \Composer\Autoload\ComposerStaticInit0d1b0e9376a19e86b57f1563bfba988b::$files; - $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { - if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { - $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; - - require $file; - } - }, null, null); - foreach ($filesToLoad as $fileIdentifier => $file) { - $requireFile($fileIdentifier, $file); - } - - return $loader; - } -} diff --git a/COPS/cops-3.1.3/vendor/composer/autoload_static.php b/COPS/cops-3.1.3/vendor/composer/autoload_static.php deleted file mode 100644 index 26ef8bce..00000000 --- a/COPS/cops-3.1.3/vendor/composer/autoload_static.php +++ /dev/null @@ -1,533 +0,0 @@ - __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', - '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', - '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', - '23c18046f52bef3eea034657bafda50f' => __DIR__ . '/..' . '/symfony/polyfill-php81/bootstrap.php', - '253c157292f75eb38082b5acb06f3f01' => __DIR__ . '/..' . '/nikic/fast-route/src/functions.php', - '89efb1254ef2d1c5d80096acd12c4098' => __DIR__ . '/..' . '/twig/twig/src/Resources/core.php', - 'ffecb95d45175fd40f75be8a23b34f90' => __DIR__ . '/..' . '/twig/twig/src/Resources/debug.php', - 'c7baa00073ee9c61edf148c51917cfb4' => __DIR__ . '/..' . '/twig/twig/src/Resources/escaper.php', - 'f844ccf1d25df8663951193c3fc307c8' => __DIR__ . '/..' . '/twig/twig/src/Resources/string_loader.php', - 'b468aea609079bd3f2a8b35133ae246a' => __DIR__ . '/../..' . '/src/functions.php', - ); - - public static $prefixLengthsPsr4 = array ( - 'Z' => - array ( - 'ZipStream\\' => 10, - ), - 'T' => - array ( - 'Twig\\' => 5, - ), - 'S' => - array ( - 'Symfony\\Polyfill\\Php81\\' => 23, - 'Symfony\\Polyfill\\Mbstring\\' => 26, - 'Symfony\\Polyfill\\Ctype\\' => 23, - ), - 'P' => - array ( - 'Psr\\SimpleCache\\' => 16, - 'PHPMailer\\PHPMailer\\' => 20, - ), - 'F' => - array ( - 'FastRoute\\' => 10, - ), - ); - - public static $prefixDirsPsr4 = array ( - 'ZipStream\\' => - array ( - 0 => __DIR__ . '/..' . '/maennchen/zipstream-php/src', - ), - 'Twig\\' => - array ( - 0 => __DIR__ . '/..' . '/twig/twig/src', - ), - 'Symfony\\Polyfill\\Php81\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-php81', - ), - 'Symfony\\Polyfill\\Mbstring\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', - ), - 'Symfony\\Polyfill\\Ctype\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype', - ), - 'Psr\\SimpleCache\\' => - array ( - 0 => __DIR__ . '/..' . '/psr/simple-cache/src', - ), - 'PHPMailer\\PHPMailer\\' => - array ( - 0 => __DIR__ . '/..' . '/phpmailer/phpmailer/src', - ), - 'FastRoute\\' => - array ( - 0 => __DIR__ . '/..' . '/nikic/fast-route/src', - ), - ); - - public static $classMap = array ( - 'CURLStringFile' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php', - 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', - 'FastRoute\\BadRouteException' => __DIR__ . '/..' . '/nikic/fast-route/src/BadRouteException.php', - 'FastRoute\\Cache' => __DIR__ . '/..' . '/nikic/fast-route/src/Cache.php', - 'FastRoute\\Cache\\FileCache' => __DIR__ . '/..' . '/nikic/fast-route/src/Cache/FileCache.php', - 'FastRoute\\Cache\\Psr16Cache' => __DIR__ . '/..' . '/nikic/fast-route/src/Cache/Psr16Cache.php', - 'FastRoute\\ConfigureRoutes' => __DIR__ . '/..' . '/nikic/fast-route/src/ConfigureRoutes.php', - 'FastRoute\\DataGenerator' => __DIR__ . '/..' . '/nikic/fast-route/src/DataGenerator.php', - 'FastRoute\\DataGenerator\\CharCountBased' => __DIR__ . '/..' . '/nikic/fast-route/src/DataGenerator/CharCountBased.php', - 'FastRoute\\DataGenerator\\GroupCountBased' => __DIR__ . '/..' . '/nikic/fast-route/src/DataGenerator/GroupCountBased.php', - 'FastRoute\\DataGenerator\\GroupPosBased' => __DIR__ . '/..' . '/nikic/fast-route/src/DataGenerator/GroupPosBased.php', - 'FastRoute\\DataGenerator\\MarkBased' => __DIR__ . '/..' . '/nikic/fast-route/src/DataGenerator/MarkBased.php', - 'FastRoute\\DataGenerator\\RegexBasedAbstract' => __DIR__ . '/..' . '/nikic/fast-route/src/DataGenerator/RegexBasedAbstract.php', - 'FastRoute\\Dispatcher' => __DIR__ . '/..' . '/nikic/fast-route/src/Dispatcher.php', - 'FastRoute\\Dispatcher\\CharCountBased' => __DIR__ . '/..' . '/nikic/fast-route/src/Dispatcher/CharCountBased.php', - 'FastRoute\\Dispatcher\\GroupCountBased' => __DIR__ . '/..' . '/nikic/fast-route/src/Dispatcher/GroupCountBased.php', - 'FastRoute\\Dispatcher\\GroupPosBased' => __DIR__ . '/..' . '/nikic/fast-route/src/Dispatcher/GroupPosBased.php', - 'FastRoute\\Dispatcher\\MarkBased' => __DIR__ . '/..' . '/nikic/fast-route/src/Dispatcher/MarkBased.php', - 'FastRoute\\Dispatcher\\RegexBasedAbstract' => __DIR__ . '/..' . '/nikic/fast-route/src/Dispatcher/RegexBasedAbstract.php', - 'FastRoute\\Dispatcher\\Result\\Matched' => __DIR__ . '/..' . '/nikic/fast-route/src/Dispatcher/Result/Matched.php', - 'FastRoute\\Dispatcher\\Result\\MethodNotAllowed' => __DIR__ . '/..' . '/nikic/fast-route/src/Dispatcher/Result/MethodNotAllowed.php', - 'FastRoute\\Dispatcher\\Result\\NotMatched' => __DIR__ . '/..' . '/nikic/fast-route/src/Dispatcher/Result/NotMatched.php', - 'FastRoute\\Exception' => __DIR__ . '/..' . '/nikic/fast-route/src/Exception.php', - 'FastRoute\\FastRoute' => __DIR__ . '/..' . '/nikic/fast-route/src/FastRoute.php', - 'FastRoute\\GenerateUri' => __DIR__ . '/..' . '/nikic/fast-route/src/GenerateUri.php', - 'FastRoute\\GenerateUri\\FromProcessedConfiguration' => __DIR__ . '/..' . '/nikic/fast-route/src/GenerateUri/FromProcessedConfiguration.php', - 'FastRoute\\GenerateUri\\UriCouldNotBeGenerated' => __DIR__ . '/..' . '/nikic/fast-route/src/GenerateUri/UriCouldNotBeGenerated.php', - 'FastRoute\\Route' => __DIR__ . '/..' . '/nikic/fast-route/src/Route.php', - 'FastRoute\\RouteCollector' => __DIR__ . '/..' . '/nikic/fast-route/src/RouteCollector.php', - 'FastRoute\\RouteParser' => __DIR__ . '/..' . '/nikic/fast-route/src/RouteParser.php', - 'FastRoute\\RouteParser\\Std' => __DIR__ . '/..' . '/nikic/fast-route/src/RouteParser/Std.php', - 'Marsender\\EPubLoader\\GoogleBooks\\AccessInfo' => __DIR__ . '/../..' . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\Epub' => __DIR__ . '/../..' . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\ImageLinks' => __DIR__ . '/../..' . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\IndustryIdentifiers' => __DIR__ . '/../..' . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\ListPrice' => __DIR__ . '/../..' . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\OfferListPrice' => __DIR__ . '/../..' . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\OfferRetailPrice' => __DIR__ . '/../..' . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\Offers' => __DIR__ . '/../..' . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\PanelizationSummary' => __DIR__ . '/../..' . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\Pdf' => __DIR__ . '/../..' . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\ReadingModes' => __DIR__ . '/../..' . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\RetailPrice' => __DIR__ . '/../..' . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\SaleInfo' => __DIR__ . '/../..' . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\SearchInfo' => __DIR__ . '/../..' . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\SearchResult' => __DIR__ . '/../..' . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\SeriesInfo' => __DIR__ . '/../..' . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\Volume' => __DIR__ . '/../..' . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\VolumeInfo' => __DIR__ . '/../..' . '/tests/cache/google/authors_generated.php', - 'Marsender\\EPubLoader\\GoogleBooks\\VolumeSeries' => __DIR__ . '/../..' . '/tests/cache/google/authors_generated.php', - 'PHPMailer\\PHPMailer\\DSNConfigurator' => __DIR__ . '/..' . '/phpmailer/phpmailer/src/DSNConfigurator.php', - 'PHPMailer\\PHPMailer\\Exception' => __DIR__ . '/..' . '/phpmailer/phpmailer/src/Exception.php', - 'PHPMailer\\PHPMailer\\OAuth' => __DIR__ . '/..' . '/phpmailer/phpmailer/src/OAuth.php', - 'PHPMailer\\PHPMailer\\OAuthTokenProvider' => __DIR__ . '/..' . '/phpmailer/phpmailer/src/OAuthTokenProvider.php', - 'PHPMailer\\PHPMailer\\PHPMailer' => __DIR__ . '/..' . '/phpmailer/phpmailer/src/PHPMailer.php', - 'PHPMailer\\PHPMailer\\POP3' => __DIR__ . '/..' . '/phpmailer/phpmailer/src/POP3.php', - 'PHPMailer\\PHPMailer\\SMTP' => __DIR__ . '/..' . '/phpmailer/phpmailer/src/SMTP.php', - 'Psr\\SimpleCache\\CacheException' => __DIR__ . '/..' . '/psr/simple-cache/src/CacheException.php', - 'Psr\\SimpleCache\\CacheInterface' => __DIR__ . '/..' . '/psr/simple-cache/src/CacheInterface.php', - 'Psr\\SimpleCache\\InvalidArgumentException' => __DIR__ . '/..' . '/psr/simple-cache/src/InvalidArgumentException.php', - 'ReturnTypeWillChange' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php', - 'SebLucas\\Cops\\Calibre\\Annotation' => __DIR__ . '/../..' . '/src/Calibre/Annotation.php', - 'SebLucas\\Cops\\Calibre\\Author' => __DIR__ . '/../..' . '/src/Calibre/Author.php', - 'SebLucas\\Cops\\Calibre\\Base' => __DIR__ . '/../..' . '/src/Calibre/Base.php', - 'SebLucas\\Cops\\Calibre\\BaseList' => __DIR__ . '/../..' . '/src/Calibre/BaseList.php', - 'SebLucas\\Cops\\Calibre\\Book' => __DIR__ . '/../..' . '/src/Calibre/Book.php', - 'SebLucas\\Cops\\Calibre\\BookList' => __DIR__ . '/../..' . '/src/Calibre/BookList.php', - 'SebLucas\\Cops\\Calibre\\Category' => __DIR__ . '/../..' . '/src/Calibre/Category.php', - 'SebLucas\\Cops\\Calibre\\Cover' => __DIR__ . '/../..' . '/src/Calibre/Cover.php', - 'SebLucas\\Cops\\Calibre\\CustomColumn' => __DIR__ . '/../..' . '/src/Calibre/CustomColumn.php', - 'SebLucas\\Cops\\Calibre\\CustomColumnType' => __DIR__ . '/../..' . '/src/Calibre/CustomColumnType.php', - 'SebLucas\\Cops\\Calibre\\CustomColumnTypeBool' => __DIR__ . '/../..' . '/src/Calibre/CustomColumnTypeBool.php', - 'SebLucas\\Cops\\Calibre\\CustomColumnTypeComment' => __DIR__ . '/../..' . '/src/Calibre/CustomColumnTypeComment.php', - 'SebLucas\\Cops\\Calibre\\CustomColumnTypeDate' => __DIR__ . '/../..' . '/src/Calibre/CustomColumnTypeDate.php', - 'SebLucas\\Cops\\Calibre\\CustomColumnTypeEnumeration' => __DIR__ . '/../..' . '/src/Calibre/CustomColumnTypeEnumeration.php', - 'SebLucas\\Cops\\Calibre\\CustomColumnTypeFloat' => __DIR__ . '/../..' . '/src/Calibre/CustomColumnTypeFloat.php', - 'SebLucas\\Cops\\Calibre\\CustomColumnTypeInteger' => __DIR__ . '/../..' . '/src/Calibre/CustomColumnTypeInteger.php', - 'SebLucas\\Cops\\Calibre\\CustomColumnTypeRating' => __DIR__ . '/../..' . '/src/Calibre/CustomColumnTypeRating.php', - 'SebLucas\\Cops\\Calibre\\CustomColumnTypeSeries' => __DIR__ . '/../..' . '/src/Calibre/CustomColumnTypeSeries.php', - 'SebLucas\\Cops\\Calibre\\CustomColumnTypeText' => __DIR__ . '/../..' . '/src/Calibre/CustomColumnTypeText.php', - 'SebLucas\\Cops\\Calibre\\Data' => __DIR__ . '/../..' . '/src/Calibre/Data.php', - 'SebLucas\\Cops\\Calibre\\Database' => __DIR__ . '/../..' . '/src/Calibre/Database.php', - 'SebLucas\\Cops\\Calibre\\Filter' => __DIR__ . '/../..' . '/src/Calibre/Filter.php', - 'SebLucas\\Cops\\Calibre\\Identifier' => __DIR__ . '/../..' . '/src/Calibre/Identifier.php', - 'SebLucas\\Cops\\Calibre\\Language' => __DIR__ . '/../..' . '/src/Calibre/Language.php', - 'SebLucas\\Cops\\Calibre\\Metadata' => __DIR__ . '/../..' . '/src/Calibre/Metadata.php', - 'SebLucas\\Cops\\Calibre\\Note' => __DIR__ . '/../..' . '/src/Calibre/Note.php', - 'SebLucas\\Cops\\Calibre\\Preference' => __DIR__ . '/../..' . '/src/Calibre/Preference.php', - 'SebLucas\\Cops\\Calibre\\Publisher' => __DIR__ . '/../..' . '/src/Calibre/Publisher.php', - 'SebLucas\\Cops\\Calibre\\Rating' => __DIR__ . '/../..' . '/src/Calibre/Rating.php', - 'SebLucas\\Cops\\Calibre\\Resource' => __DIR__ . '/../..' . '/src/Calibre/Resource.php', - 'SebLucas\\Cops\\Calibre\\Serie' => __DIR__ . '/../..' . '/src/Calibre/Serie.php', - 'SebLucas\\Cops\\Calibre\\Tag' => __DIR__ . '/../..' . '/src/Calibre/Tag.php', - 'SebLucas\\Cops\\Calibre\\User' => __DIR__ . '/../..' . '/src/Calibre/User.php', - 'SebLucas\\Cops\\Calibre\\VirtualLibrary' => __DIR__ . '/../..' . '/src/Calibre/VirtualLibrary.php', - 'SebLucas\\Cops\\Framework' => __DIR__ . '/../..' . '/src/Framework.php', - 'SebLucas\\Cops\\Handlers\\BaseHandler' => __DIR__ . '/../..' . '/src/Handlers/BaseHandler.php', - 'SebLucas\\Cops\\Handlers\\CalResHandler' => __DIR__ . '/../..' . '/src/Handlers/CalResHandler.php', - 'SebLucas\\Cops\\Handlers\\CheckHandler' => __DIR__ . '/../..' . '/src/Handlers/CheckHandler.php', - 'SebLucas\\Cops\\Handlers\\EpubFsHandler' => __DIR__ . '/../..' . '/src/Handlers/EpubFsHandler.php', - 'SebLucas\\Cops\\Handlers\\FeedHandler' => __DIR__ . '/../..' . '/src/Handlers/FeedHandler.php', - 'SebLucas\\Cops\\Handlers\\FetchHandler' => __DIR__ . '/../..' . '/src/Handlers/FetchHandler.php', - 'SebLucas\\Cops\\Handlers\\GraphQLHandler' => __DIR__ . '/../..' . '/src/Handlers/GraphQLHandler.php', - 'SebLucas\\Cops\\Handlers\\HtmlHandler' => __DIR__ . '/../..' . '/src/Handlers/HtmlHandler.php', - 'SebLucas\\Cops\\Handlers\\JsonHandler' => __DIR__ . '/../..' . '/src/Handlers/JsonHandler.php', - 'SebLucas\\Cops\\Handlers\\LoaderHandler' => __DIR__ . '/../..' . '/src/Handlers/LoaderHandler.php', - 'SebLucas\\Cops\\Handlers\\MailHandler' => __DIR__ . '/../..' . '/src/Handlers/MailHandler.php', - 'SebLucas\\Cops\\Handlers\\OpdsHandler' => __DIR__ . '/../..' . '/src/Handlers/OpdsHandler.php', - 'SebLucas\\Cops\\Handlers\\PageHandler' => __DIR__ . '/../..' . '/src/Handlers/PageHandler.php', - 'SebLucas\\Cops\\Handlers\\QueueBasedHandler' => __DIR__ . '/../..' . '/src/Handlers/QueueBasedHandler.php', - 'SebLucas\\Cops\\Handlers\\ReadHandler' => __DIR__ . '/../..' . '/src/Handlers/ReadHandler.php', - 'SebLucas\\Cops\\Handlers\\RestApiHandler' => __DIR__ . '/../..' . '/src/Handlers/RestApiHandler.php', - 'SebLucas\\Cops\\Handlers\\ZipFsHandler' => __DIR__ . '/../..' . '/src/Handlers/ZipFsHandler.php', - 'SebLucas\\Cops\\Handlers\\ZipperHandler' => __DIR__ . '/../..' . '/src/Handlers/ZipperHandler.php', - 'SebLucas\\Cops\\Input\\Config' => __DIR__ . '/../..' . '/src/Input/Config.php', - 'SebLucas\\Cops\\Input\\Context' => __DIR__ . '/../..' . '/src/Input/Context.php', - 'SebLucas\\Cops\\Input\\Request' => __DIR__ . '/../..' . '/src/Input/Request.php', - 'SebLucas\\Cops\\Input\\Route' => __DIR__ . '/../..' . '/src/Input/Route.php', - 'SebLucas\\Cops\\Language\\Translation' => __DIR__ . '/../..' . '/src/Language/Translation.php', - 'SebLucas\\Cops\\Model\\Entry' => __DIR__ . '/../..' . '/src/Model/Entry.php', - 'SebLucas\\Cops\\Model\\EntryBook' => __DIR__ . '/../..' . '/src/Model/EntryBook.php', - 'SebLucas\\Cops\\Model\\Link' => __DIR__ . '/../..' . '/src/Model/Link.php', - 'SebLucas\\Cops\\Model\\LinkEntry' => __DIR__ . '/../..' . '/src/Model/LinkEntry.php', - 'SebLucas\\Cops\\Model\\LinkFacet' => __DIR__ . '/../..' . '/src/Model/LinkFacet.php', - 'SebLucas\\Cops\\Model\\LinkFeed' => __DIR__ . '/../..' . '/src/Model/LinkFeed.php', - 'SebLucas\\Cops\\Model\\LinkNavigation' => __DIR__ . '/../..' . '/src/Model/LinkNavigation.php', - 'SebLucas\\Cops\\Output\\BaseRenderer' => __DIR__ . '/../..' . '/src/Output/BaseRenderer.php', - 'SebLucas\\Cops\\Output\\DotPHPTemplate' => __DIR__ . '/../..' . '/src/Output/DotPHPTemplate.php', - 'SebLucas\\Cops\\Output\\EPubReader' => __DIR__ . '/../..' . '/src/Output/EPubReader.php', - 'SebLucas\\Cops\\Output\\FileResponse' => __DIR__ . '/../..' . '/src/Output/FileResponse.php', - 'SebLucas\\Cops\\Output\\Format' => __DIR__ . '/../..' . '/src/Output/Format.php', - 'SebLucas\\Cops\\Output\\HtmlRenderer' => __DIR__ . '/../..' . '/src/Output/HtmlRenderer.php', - 'SebLucas\\Cops\\Output\\JsonRenderer' => __DIR__ . '/../..' . '/src/Output/JsonRenderer.php', - 'SebLucas\\Cops\\Output\\KiwilanOPDS' => __DIR__ . '/../..' . '/src/Output/KiwilanOPDS.php', - 'SebLucas\\Cops\\Output\\Mail' => __DIR__ . '/../..' . '/src/Output/Mail.php', - 'SebLucas\\Cops\\Output\\OpdsRenderer' => __DIR__ . '/../..' . '/src/Output/OpdsRenderer.php', - 'SebLucas\\Cops\\Output\\Response' => __DIR__ . '/../..' . '/src/Output/Response.php', - 'SebLucas\\Cops\\Output\\RestApi' => __DIR__ . '/../..' . '/src/Output/RestApi.php', - 'SebLucas\\Cops\\Output\\TwigTemplate' => __DIR__ . '/../..' . '/src/Output/TwigTemplate.php', - 'SebLucas\\Cops\\Output\\Zipper' => __DIR__ . '/../..' . '/src/Output/Zipper.php', - 'SebLucas\\Cops\\Pages\\Page' => __DIR__ . '/../..' . '/src/Pages/Page.php', - 'SebLucas\\Cops\\Pages\\PageAbout' => __DIR__ . '/../..' . '/src/Pages/PageAbout.php', - 'SebLucas\\Cops\\Pages\\PageAllAuthors' => __DIR__ . '/../..' . '/src/Pages/PageAllAuthors.php', - 'SebLucas\\Cops\\Pages\\PageAllAuthorsLetter' => __DIR__ . '/../..' . '/src/Pages/PageAllAuthorsLetter.php', - 'SebLucas\\Cops\\Pages\\PageAllBooks' => __DIR__ . '/../..' . '/src/Pages/PageAllBooks.php', - 'SebLucas\\Cops\\Pages\\PageAllBooksLetter' => __DIR__ . '/../..' . '/src/Pages/PageAllBooksLetter.php', - 'SebLucas\\Cops\\Pages\\PageAllBooksYear' => __DIR__ . '/../..' . '/src/Pages/PageAllBooksYear.php', - 'SebLucas\\Cops\\Pages\\PageAllCustoms' => __DIR__ . '/../..' . '/src/Pages/PageAllCustoms.php', - 'SebLucas\\Cops\\Pages\\PageAllIdentifiers' => __DIR__ . '/../..' . '/src/Pages/PageAllIdentifiers.php', - 'SebLucas\\Cops\\Pages\\PageAllLanguages' => __DIR__ . '/../..' . '/src/Pages/PageAllLanguages.php', - 'SebLucas\\Cops\\Pages\\PageAllPublishers' => __DIR__ . '/../..' . '/src/Pages/PageAllPublishers.php', - 'SebLucas\\Cops\\Pages\\PageAllRating' => __DIR__ . '/../..' . '/src/Pages/PageAllRating.php', - 'SebLucas\\Cops\\Pages\\PageAllSeries' => __DIR__ . '/../..' . '/src/Pages/PageAllSeries.php', - 'SebLucas\\Cops\\Pages\\PageAllTags' => __DIR__ . '/../..' . '/src/Pages/PageAllTags.php', - 'SebLucas\\Cops\\Pages\\PageAllVirtualLibraries' => __DIR__ . '/../..' . '/src/Pages/PageAllVirtualLibraries.php', - 'SebLucas\\Cops\\Pages\\PageAuthorDetail' => __DIR__ . '/../..' . '/src/Pages/PageAuthorDetail.php', - 'SebLucas\\Cops\\Pages\\PageBookDetail' => __DIR__ . '/../..' . '/src/Pages/PageBookDetail.php', - 'SebLucas\\Cops\\Pages\\PageCustomDetail' => __DIR__ . '/../..' . '/src/Pages/PageCustomDetail.php', - 'SebLucas\\Cops\\Pages\\PageCustomize' => __DIR__ . '/../..' . '/src/Pages/PageCustomize.php', - 'SebLucas\\Cops\\Pages\\PageId' => __DIR__ . '/../..' . '/src/Pages/PageId.php', - 'SebLucas\\Cops\\Pages\\PageIdentifierDetail' => __DIR__ . '/../..' . '/src/Pages/PageIdentifierDetail.php', - 'SebLucas\\Cops\\Pages\\PageIndex' => __DIR__ . '/../..' . '/src/Pages/PageIndex.php', - 'SebLucas\\Cops\\Pages\\PageLanguageDetail' => __DIR__ . '/../..' . '/src/Pages/PageLanguageDetail.php', - 'SebLucas\\Cops\\Pages\\PagePublisherDetail' => __DIR__ . '/../..' . '/src/Pages/PagePublisherDetail.php', - 'SebLucas\\Cops\\Pages\\PageQueryResult' => __DIR__ . '/../..' . '/src/Pages/PageQueryResult.php', - 'SebLucas\\Cops\\Pages\\PageRatingDetail' => __DIR__ . '/../..' . '/src/Pages/PageRatingDetail.php', - 'SebLucas\\Cops\\Pages\\PageRecentBooks' => __DIR__ . '/../..' . '/src/Pages/PageRecentBooks.php', - 'SebLucas\\Cops\\Pages\\PageSerieDetail' => __DIR__ . '/../..' . '/src/Pages/PageSerieDetail.php', - 'SebLucas\\Cops\\Pages\\PageTagDetail' => __DIR__ . '/../..' . '/src/Pages/PageTagDetail.php', - 'SebLucas\\Cops\\Pages\\PageWithDetail' => __DIR__ . '/../..' . '/src/Pages/PageWithDetail.php', - 'SebLucas\\Cops\\Tests\\BaseTest' => __DIR__ . '/../..' . '/tests/baseTest.php', - 'SebLucas\\Cops\\Tests\\BookListTest' => __DIR__ . '/../..' . '/tests/BookListTest.php', - 'SebLucas\\Cops\\Tests\\BookTest' => __DIR__ . '/../..' . '/tests/BookTest.php', - 'SebLucas\\Cops\\Tests\\BrowserKitTest' => __DIR__ . '/../..' . '/tests/BrowserKitTest.php', - 'SebLucas\\Cops\\Tests\\ConfigTest' => __DIR__ . '/../..' . '/tests/ConfigTest.php', - 'SebLucas\\Cops\\Tests\\CustomColumnsTest' => __DIR__ . '/../..' . '/tests/customColumnsTest.php', - 'SebLucas\\Cops\\Tests\\EpubFsTest' => __DIR__ . '/../..' . '/tests/EpubFsTest.php', - 'SebLucas\\Cops\\Tests\\EpubReaderTest' => __DIR__ . '/../..' . '/tests/EpubReaderTest.php', - 'SebLucas\\Cops\\Tests\\FetchHandlerTest' => __DIR__ . '/../..' . '/tests/FetchHandlerTest.php', - 'SebLucas\\Cops\\Tests\\FilterTest' => __DIR__ . '/../..' . '/tests/FilterTest.php', - 'SebLucas\\Cops\\Tests\\FrameworkTest' => __DIR__ . '/../..' . '/tests/FrameworkTest.php', - 'SebLucas\\Cops\\Tests\\GraphQLHandlerTest' => __DIR__ . '/../..' . '/tests/GraphQLHandlerTest.php', - 'SebLucas\\Cops\\Tests\\HtmlRendererTest' => __DIR__ . '/../..' . '/tests/HtmlRendererTest.php', - 'SebLucas\\Cops\\Tests\\JsonRendererTest' => __DIR__ . '/../..' . '/tests/JsonRendererTest.php', - 'SebLucas\\Cops\\Tests\\KiwilanTest' => __DIR__ . '/../..' . '/tests/KiwilanTest.php', - 'SebLucas\\Cops\\Tests\\MailTest' => __DIR__ . '/../..' . '/tests/MailTest.php', - 'SebLucas\\Cops\\Tests\\NoteResourceTest' => __DIR__ . '/../..' . '/tests/NoteResourceTest.php', - 'SebLucas\\Cops\\Tests\\OpdsRendererTest' => __DIR__ . '/../..' . '/tests/OpdsRendererTest.php', - 'SebLucas\\Cops\\Tests\\PageMultiDatabaseTest' => __DIR__ . '/../..' . '/tests/PageMultiDatabaseTest.php', - 'SebLucas\\Cops\\Tests\\PageTest' => __DIR__ . '/../..' . '/tests/PageTest.php', - 'SebLucas\\Cops\\Tests\\RestApiTest' => __DIR__ . '/../..' . '/tests/RestApiTest.php', - 'SebLucas\\Cops\\Tests\\RouteTest' => __DIR__ . '/../..' . '/tests/RouteTest.php', - 'SebLucas\\Cops\\Tests\\TypeAheadSearchTest' => __DIR__ . '/../..' . '/tests/TypeAheadSearchTest.php', - 'SebLucas\\Cops\\Tests\\UserTest' => __DIR__ . '/../..' . '/tests/UserTest.php', - 'SebLucas\\Cops\\Tests\\WebDriverTest' => __DIR__ . '/../..' . '/tests/WebDriverTest.php', - 'SebLucas\\Cops\\Tests\\WebDriverTestCase' => __DIR__ . '/../..' . '/tests/WebDriverTestCase.php', - 'SebLucas\\Cops\\Tests\\ZipperTest' => __DIR__ . '/../..' . '/tests/ZipperTest.php', - 'SebLucas\\EPubMeta\\App\\Handler' => __DIR__ . '/..' . '/mikespub/php-epub-meta/src/App/Handler.php', - 'SebLucas\\EPubMeta\\App\\Util' => __DIR__ . '/..' . '/mikespub/php-epub-meta/src/App/Util.php', - 'SebLucas\\EPubMeta\\Contents\\Nav' => __DIR__ . '/..' . '/mikespub/php-epub-meta/src/Contents/Nav.php', - 'SebLucas\\EPubMeta\\Contents\\NavPoint' => __DIR__ . '/..' . '/mikespub/php-epub-meta/src/Contents/NavPoint.php', - 'SebLucas\\EPubMeta\\Contents\\NavPointList' => __DIR__ . '/..' . '/mikespub/php-epub-meta/src/Contents/NavPointList.php', - 'SebLucas\\EPubMeta\\Contents\\Spine' => __DIR__ . '/..' . '/mikespub/php-epub-meta/src/Contents/Spine.php', - 'SebLucas\\EPubMeta\\Contents\\Toc' => __DIR__ . '/..' . '/mikespub/php-epub-meta/src/Contents/Toc.php', - 'SebLucas\\EPubMeta\\Data\\Item' => __DIR__ . '/..' . '/mikespub/php-epub-meta/src/Data/Item.php', - 'SebLucas\\EPubMeta\\Data\\Manifest' => __DIR__ . '/..' . '/mikespub/php-epub-meta/src/Data/Manifest.php', - 'SebLucas\\EPubMeta\\Dom\\Element' => __DIR__ . '/..' . '/mikespub/php-epub-meta/src/Dom/Element.php', - 'SebLucas\\EPubMeta\\Dom\\XPath' => __DIR__ . '/..' . '/mikespub/php-epub-meta/src/Dom/XPath.php', - 'SebLucas\\EPubMeta\\EPub' => __DIR__ . '/..' . '/mikespub/php-epub-meta/src/EPub.php', - 'SebLucas\\EPubMeta\\Other' => __DIR__ . '/..' . '/mikespub/php-epub-meta/src/Other.php', - 'SebLucas\\EPubMeta\\Tools\\HtmlTools' => __DIR__ . '/..' . '/mikespub/php-epub-meta/src/Tools/HtmlTools.php', - 'SebLucas\\EPubMeta\\Tools\\ZipEdit' => __DIR__ . '/..' . '/mikespub/php-epub-meta/src/Tools/ZipEdit.php', - 'SebLucas\\EPubMeta\\Tools\\ZipFile' => __DIR__ . '/..' . '/mikespub/php-epub-meta/src/Tools/ZipFile.php', - 'SebLucas\\Template\\doT' => __DIR__ . '/../..' . '/resources/dot-php/doT.php', - 'Symfony\\Polyfill\\Ctype\\Ctype' => __DIR__ . '/..' . '/symfony/polyfill-ctype/Ctype.php', - 'Symfony\\Polyfill\\Mbstring\\Mbstring' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/Mbstring.php', - 'Symfony\\Polyfill\\Php81\\Php81' => __DIR__ . '/..' . '/symfony/polyfill-php81/Php81.php', - 'Twig\\AbstractTwigCallable' => __DIR__ . '/..' . '/twig/twig/src/AbstractTwigCallable.php', - 'Twig\\Attribute\\FirstClassTwigCallableReady' => __DIR__ . '/..' . '/twig/twig/src/Attribute/FirstClassTwigCallableReady.php', - 'Twig\\Attribute\\YieldReady' => __DIR__ . '/..' . '/twig/twig/src/Attribute/YieldReady.php', - 'Twig\\Cache\\CacheInterface' => __DIR__ . '/..' . '/twig/twig/src/Cache/CacheInterface.php', - 'Twig\\Cache\\ChainCache' => __DIR__ . '/..' . '/twig/twig/src/Cache/ChainCache.php', - 'Twig\\Cache\\FilesystemCache' => __DIR__ . '/..' . '/twig/twig/src/Cache/FilesystemCache.php', - 'Twig\\Cache\\NullCache' => __DIR__ . '/..' . '/twig/twig/src/Cache/NullCache.php', - 'Twig\\Cache\\ReadOnlyFilesystemCache' => __DIR__ . '/..' . '/twig/twig/src/Cache/ReadOnlyFilesystemCache.php', - 'Twig\\Compiler' => __DIR__ . '/..' . '/twig/twig/src/Compiler.php', - 'Twig\\Environment' => __DIR__ . '/..' . '/twig/twig/src/Environment.php', - 'Twig\\Error\\Error' => __DIR__ . '/..' . '/twig/twig/src/Error/Error.php', - 'Twig\\Error\\LoaderError' => __DIR__ . '/..' . '/twig/twig/src/Error/LoaderError.php', - 'Twig\\Error\\RuntimeError' => __DIR__ . '/..' . '/twig/twig/src/Error/RuntimeError.php', - 'Twig\\Error\\SyntaxError' => __DIR__ . '/..' . '/twig/twig/src/Error/SyntaxError.php', - 'Twig\\ExpressionParser' => __DIR__ . '/..' . '/twig/twig/src/ExpressionParser.php', - 'Twig\\ExtensionSet' => __DIR__ . '/..' . '/twig/twig/src/ExtensionSet.php', - 'Twig\\Extension\\AbstractExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/AbstractExtension.php', - 'Twig\\Extension\\CoreExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/CoreExtension.php', - 'Twig\\Extension\\DebugExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/DebugExtension.php', - 'Twig\\Extension\\EscaperExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/EscaperExtension.php', - 'Twig\\Extension\\ExtensionInterface' => __DIR__ . '/..' . '/twig/twig/src/Extension/ExtensionInterface.php', - 'Twig\\Extension\\GlobalsInterface' => __DIR__ . '/..' . '/twig/twig/src/Extension/GlobalsInterface.php', - 'Twig\\Extension\\OptimizerExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/OptimizerExtension.php', - 'Twig\\Extension\\ProfilerExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/ProfilerExtension.php', - 'Twig\\Extension\\RuntimeExtensionInterface' => __DIR__ . '/..' . '/twig/twig/src/Extension/RuntimeExtensionInterface.php', - 'Twig\\Extension\\SandboxExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/SandboxExtension.php', - 'Twig\\Extension\\StagingExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/StagingExtension.php', - 'Twig\\Extension\\StringLoaderExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/StringLoaderExtension.php', - 'Twig\\Extension\\YieldNotReadyExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/YieldNotReadyExtension.php', - 'Twig\\FileExtensionEscapingStrategy' => __DIR__ . '/..' . '/twig/twig/src/FileExtensionEscapingStrategy.php', - 'Twig\\Lexer' => __DIR__ . '/..' . '/twig/twig/src/Lexer.php', - 'Twig\\Loader\\ArrayLoader' => __DIR__ . '/..' . '/twig/twig/src/Loader/ArrayLoader.php', - 'Twig\\Loader\\ChainLoader' => __DIR__ . '/..' . '/twig/twig/src/Loader/ChainLoader.php', - 'Twig\\Loader\\FilesystemLoader' => __DIR__ . '/..' . '/twig/twig/src/Loader/FilesystemLoader.php', - 'Twig\\Loader\\LoaderInterface' => __DIR__ . '/..' . '/twig/twig/src/Loader/LoaderInterface.php', - 'Twig\\Markup' => __DIR__ . '/..' . '/twig/twig/src/Markup.php', - 'Twig\\NodeTraverser' => __DIR__ . '/..' . '/twig/twig/src/NodeTraverser.php', - 'Twig\\NodeVisitor\\AbstractNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/AbstractNodeVisitor.php', - 'Twig\\NodeVisitor\\EscaperNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/EscaperNodeVisitor.php', - 'Twig\\NodeVisitor\\MacroAutoImportNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/MacroAutoImportNodeVisitor.php', - 'Twig\\NodeVisitor\\NodeVisitorInterface' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/NodeVisitorInterface.php', - 'Twig\\NodeVisitor\\OptimizerNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/OptimizerNodeVisitor.php', - 'Twig\\NodeVisitor\\SafeAnalysisNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/SafeAnalysisNodeVisitor.php', - 'Twig\\NodeVisitor\\SandboxNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/SandboxNodeVisitor.php', - 'Twig\\NodeVisitor\\YieldNotReadyNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/YieldNotReadyNodeVisitor.php', - 'Twig\\Node\\AutoEscapeNode' => __DIR__ . '/..' . '/twig/twig/src/Node/AutoEscapeNode.php', - 'Twig\\Node\\BlockNode' => __DIR__ . '/..' . '/twig/twig/src/Node/BlockNode.php', - 'Twig\\Node\\BlockReferenceNode' => __DIR__ . '/..' . '/twig/twig/src/Node/BlockReferenceNode.php', - 'Twig\\Node\\BodyNode' => __DIR__ . '/..' . '/twig/twig/src/Node/BodyNode.php', - 'Twig\\Node\\CaptureNode' => __DIR__ . '/..' . '/twig/twig/src/Node/CaptureNode.php', - 'Twig\\Node\\CheckSecurityCallNode' => __DIR__ . '/..' . '/twig/twig/src/Node/CheckSecurityCallNode.php', - 'Twig\\Node\\CheckSecurityNode' => __DIR__ . '/..' . '/twig/twig/src/Node/CheckSecurityNode.php', - 'Twig\\Node\\CheckToStringNode' => __DIR__ . '/..' . '/twig/twig/src/Node/CheckToStringNode.php', - 'Twig\\Node\\DeprecatedNode' => __DIR__ . '/..' . '/twig/twig/src/Node/DeprecatedNode.php', - 'Twig\\Node\\DoNode' => __DIR__ . '/..' . '/twig/twig/src/Node/DoNode.php', - 'Twig\\Node\\EmbedNode' => __DIR__ . '/..' . '/twig/twig/src/Node/EmbedNode.php', - 'Twig\\Node\\Expression\\AbstractExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/AbstractExpression.php', - 'Twig\\Node\\Expression\\ArrayExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/ArrayExpression.php', - 'Twig\\Node\\Expression\\ArrowFunctionExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/ArrowFunctionExpression.php', - 'Twig\\Node\\Expression\\AssignNameExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/AssignNameExpression.php', - 'Twig\\Node\\Expression\\Binary\\AbstractBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/AbstractBinary.php', - 'Twig\\Node\\Expression\\Binary\\AddBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/AddBinary.php', - 'Twig\\Node\\Expression\\Binary\\AndBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/AndBinary.php', - 'Twig\\Node\\Expression\\Binary\\BitwiseAndBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/BitwiseAndBinary.php', - 'Twig\\Node\\Expression\\Binary\\BitwiseOrBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/BitwiseOrBinary.php', - 'Twig\\Node\\Expression\\Binary\\BitwiseXorBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/BitwiseXorBinary.php', - 'Twig\\Node\\Expression\\Binary\\ConcatBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/ConcatBinary.php', - 'Twig\\Node\\Expression\\Binary\\DivBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/DivBinary.php', - 'Twig\\Node\\Expression\\Binary\\EndsWithBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/EndsWithBinary.php', - 'Twig\\Node\\Expression\\Binary\\EqualBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/EqualBinary.php', - 'Twig\\Node\\Expression\\Binary\\FloorDivBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/FloorDivBinary.php', - 'Twig\\Node\\Expression\\Binary\\GreaterBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/GreaterBinary.php', - 'Twig\\Node\\Expression\\Binary\\GreaterEqualBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/GreaterEqualBinary.php', - 'Twig\\Node\\Expression\\Binary\\HasEveryBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/HasEveryBinary.php', - 'Twig\\Node\\Expression\\Binary\\HasSomeBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/HasSomeBinary.php', - 'Twig\\Node\\Expression\\Binary\\InBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/InBinary.php', - 'Twig\\Node\\Expression\\Binary\\LessBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/LessBinary.php', - 'Twig\\Node\\Expression\\Binary\\LessEqualBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/LessEqualBinary.php', - 'Twig\\Node\\Expression\\Binary\\MatchesBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/MatchesBinary.php', - 'Twig\\Node\\Expression\\Binary\\ModBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/ModBinary.php', - 'Twig\\Node\\Expression\\Binary\\MulBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/MulBinary.php', - 'Twig\\Node\\Expression\\Binary\\NotEqualBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/NotEqualBinary.php', - 'Twig\\Node\\Expression\\Binary\\NotInBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/NotInBinary.php', - 'Twig\\Node\\Expression\\Binary\\OrBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/OrBinary.php', - 'Twig\\Node\\Expression\\Binary\\PowerBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/PowerBinary.php', - 'Twig\\Node\\Expression\\Binary\\RangeBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/RangeBinary.php', - 'Twig\\Node\\Expression\\Binary\\SpaceshipBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/SpaceshipBinary.php', - 'Twig\\Node\\Expression\\Binary\\StartsWithBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/StartsWithBinary.php', - 'Twig\\Node\\Expression\\Binary\\SubBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/SubBinary.php', - 'Twig\\Node\\Expression\\BlockReferenceExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/BlockReferenceExpression.php', - 'Twig\\Node\\Expression\\CallExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/CallExpression.php', - 'Twig\\Node\\Expression\\ConditionalExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/ConditionalExpression.php', - 'Twig\\Node\\Expression\\ConstantExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/ConstantExpression.php', - 'Twig\\Node\\Expression\\FilterExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/FilterExpression.php', - 'Twig\\Node\\Expression\\Filter\\DefaultFilter' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Filter/DefaultFilter.php', - 'Twig\\Node\\Expression\\Filter\\RawFilter' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Filter/RawFilter.php', - 'Twig\\Node\\Expression\\FunctionExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/FunctionExpression.php', - 'Twig\\Node\\Expression\\FunctionNode\\EnumCasesFunction' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/FunctionNode/EnumCasesFunction.php', - 'Twig\\Node\\Expression\\GetAttrExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/GetAttrExpression.php', - 'Twig\\Node\\Expression\\InlinePrint' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/InlinePrint.php', - 'Twig\\Node\\Expression\\MethodCallExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/MethodCallExpression.php', - 'Twig\\Node\\Expression\\NameExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/NameExpression.php', - 'Twig\\Node\\Expression\\NullCoalesceExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/NullCoalesceExpression.php', - 'Twig\\Node\\Expression\\ParentExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/ParentExpression.php', - 'Twig\\Node\\Expression\\TempNameExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/TempNameExpression.php', - 'Twig\\Node\\Expression\\TestExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/TestExpression.php', - 'Twig\\Node\\Expression\\Test\\ConstantTest' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Test/ConstantTest.php', - 'Twig\\Node\\Expression\\Test\\DefinedTest' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Test/DefinedTest.php', - 'Twig\\Node\\Expression\\Test\\DivisiblebyTest' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Test/DivisiblebyTest.php', - 'Twig\\Node\\Expression\\Test\\EvenTest' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Test/EvenTest.php', - 'Twig\\Node\\Expression\\Test\\NullTest' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Test/NullTest.php', - 'Twig\\Node\\Expression\\Test\\OddTest' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Test/OddTest.php', - 'Twig\\Node\\Expression\\Test\\SameasTest' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Test/SameasTest.php', - 'Twig\\Node\\Expression\\Unary\\AbstractUnary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Unary/AbstractUnary.php', - 'Twig\\Node\\Expression\\Unary\\NegUnary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Unary/NegUnary.php', - 'Twig\\Node\\Expression\\Unary\\NotUnary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Unary/NotUnary.php', - 'Twig\\Node\\Expression\\Unary\\PosUnary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Unary/PosUnary.php', - 'Twig\\Node\\Expression\\VariadicExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/VariadicExpression.php', - 'Twig\\Node\\FlushNode' => __DIR__ . '/..' . '/twig/twig/src/Node/FlushNode.php', - 'Twig\\Node\\ForLoopNode' => __DIR__ . '/..' . '/twig/twig/src/Node/ForLoopNode.php', - 'Twig\\Node\\ForNode' => __DIR__ . '/..' . '/twig/twig/src/Node/ForNode.php', - 'Twig\\Node\\IfNode' => __DIR__ . '/..' . '/twig/twig/src/Node/IfNode.php', - 'Twig\\Node\\ImportNode' => __DIR__ . '/..' . '/twig/twig/src/Node/ImportNode.php', - 'Twig\\Node\\IncludeNode' => __DIR__ . '/..' . '/twig/twig/src/Node/IncludeNode.php', - 'Twig\\Node\\MacroNode' => __DIR__ . '/..' . '/twig/twig/src/Node/MacroNode.php', - 'Twig\\Node\\ModuleNode' => __DIR__ . '/..' . '/twig/twig/src/Node/ModuleNode.php', - 'Twig\\Node\\NameDeprecation' => __DIR__ . '/..' . '/twig/twig/src/Node/NameDeprecation.php', - 'Twig\\Node\\Node' => __DIR__ . '/..' . '/twig/twig/src/Node/Node.php', - 'Twig\\Node\\NodeCaptureInterface' => __DIR__ . '/..' . '/twig/twig/src/Node/NodeCaptureInterface.php', - 'Twig\\Node\\NodeOutputInterface' => __DIR__ . '/..' . '/twig/twig/src/Node/NodeOutputInterface.php', - 'Twig\\Node\\PrintNode' => __DIR__ . '/..' . '/twig/twig/src/Node/PrintNode.php', - 'Twig\\Node\\SandboxNode' => __DIR__ . '/..' . '/twig/twig/src/Node/SandboxNode.php', - 'Twig\\Node\\SetNode' => __DIR__ . '/..' . '/twig/twig/src/Node/SetNode.php', - 'Twig\\Node\\TextNode' => __DIR__ . '/..' . '/twig/twig/src/Node/TextNode.php', - 'Twig\\Node\\TypesNode' => __DIR__ . '/..' . '/twig/twig/src/Node/TypesNode.php', - 'Twig\\Node\\WithNode' => __DIR__ . '/..' . '/twig/twig/src/Node/WithNode.php', - 'Twig\\Parser' => __DIR__ . '/..' . '/twig/twig/src/Parser.php', - 'Twig\\Profiler\\Dumper\\BaseDumper' => __DIR__ . '/..' . '/twig/twig/src/Profiler/Dumper/BaseDumper.php', - 'Twig\\Profiler\\Dumper\\BlackfireDumper' => __DIR__ . '/..' . '/twig/twig/src/Profiler/Dumper/BlackfireDumper.php', - 'Twig\\Profiler\\Dumper\\HtmlDumper' => __DIR__ . '/..' . '/twig/twig/src/Profiler/Dumper/HtmlDumper.php', - 'Twig\\Profiler\\Dumper\\TextDumper' => __DIR__ . '/..' . '/twig/twig/src/Profiler/Dumper/TextDumper.php', - 'Twig\\Profiler\\NodeVisitor\\ProfilerNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/Profiler/NodeVisitor/ProfilerNodeVisitor.php', - 'Twig\\Profiler\\Node\\EnterProfileNode' => __DIR__ . '/..' . '/twig/twig/src/Profiler/Node/EnterProfileNode.php', - 'Twig\\Profiler\\Node\\LeaveProfileNode' => __DIR__ . '/..' . '/twig/twig/src/Profiler/Node/LeaveProfileNode.php', - 'Twig\\Profiler\\Profile' => __DIR__ . '/..' . '/twig/twig/src/Profiler/Profile.php', - 'Twig\\RuntimeLoader\\ContainerRuntimeLoader' => __DIR__ . '/..' . '/twig/twig/src/RuntimeLoader/ContainerRuntimeLoader.php', - 'Twig\\RuntimeLoader\\FactoryRuntimeLoader' => __DIR__ . '/..' . '/twig/twig/src/RuntimeLoader/FactoryRuntimeLoader.php', - 'Twig\\RuntimeLoader\\RuntimeLoaderInterface' => __DIR__ . '/..' . '/twig/twig/src/RuntimeLoader/RuntimeLoaderInterface.php', - 'Twig\\Runtime\\EscaperRuntime' => __DIR__ . '/..' . '/twig/twig/src/Runtime/EscaperRuntime.php', - 'Twig\\Sandbox\\SecurityError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityError.php', - 'Twig\\Sandbox\\SecurityNotAllowedFilterError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityNotAllowedFilterError.php', - 'Twig\\Sandbox\\SecurityNotAllowedFunctionError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityNotAllowedFunctionError.php', - 'Twig\\Sandbox\\SecurityNotAllowedMethodError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityNotAllowedMethodError.php', - 'Twig\\Sandbox\\SecurityNotAllowedPropertyError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityNotAllowedPropertyError.php', - 'Twig\\Sandbox\\SecurityNotAllowedTagError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityNotAllowedTagError.php', - 'Twig\\Sandbox\\SecurityPolicy' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityPolicy.php', - 'Twig\\Sandbox\\SecurityPolicyInterface' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityPolicyInterface.php', - 'Twig\\Sandbox\\SourcePolicyInterface' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SourcePolicyInterface.php', - 'Twig\\Source' => __DIR__ . '/..' . '/twig/twig/src/Source.php', - 'Twig\\Template' => __DIR__ . '/..' . '/twig/twig/src/Template.php', - 'Twig\\TemplateWrapper' => __DIR__ . '/..' . '/twig/twig/src/TemplateWrapper.php', - 'Twig\\Test\\IntegrationTestCase' => __DIR__ . '/..' . '/twig/twig/src/Test/IntegrationTestCase.php', - 'Twig\\Test\\NodeTestCase' => __DIR__ . '/..' . '/twig/twig/src/Test/NodeTestCase.php', - 'Twig\\Token' => __DIR__ . '/..' . '/twig/twig/src/Token.php', - 'Twig\\TokenParser\\AbstractTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/AbstractTokenParser.php', - 'Twig\\TokenParser\\ApplyTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/ApplyTokenParser.php', - 'Twig\\TokenParser\\AutoEscapeTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/AutoEscapeTokenParser.php', - 'Twig\\TokenParser\\BlockTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/BlockTokenParser.php', - 'Twig\\TokenParser\\DeprecatedTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/DeprecatedTokenParser.php', - 'Twig\\TokenParser\\DoTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/DoTokenParser.php', - 'Twig\\TokenParser\\EmbedTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/EmbedTokenParser.php', - 'Twig\\TokenParser\\ExtendsTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/ExtendsTokenParser.php', - 'Twig\\TokenParser\\FlushTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/FlushTokenParser.php', - 'Twig\\TokenParser\\ForTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/ForTokenParser.php', - 'Twig\\TokenParser\\FromTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/FromTokenParser.php', - 'Twig\\TokenParser\\IfTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/IfTokenParser.php', - 'Twig\\TokenParser\\ImportTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/ImportTokenParser.php', - 'Twig\\TokenParser\\IncludeTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/IncludeTokenParser.php', - 'Twig\\TokenParser\\MacroTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/MacroTokenParser.php', - 'Twig\\TokenParser\\SandboxTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/SandboxTokenParser.php', - 'Twig\\TokenParser\\SetTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/SetTokenParser.php', - 'Twig\\TokenParser\\TokenParserInterface' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/TokenParserInterface.php', - 'Twig\\TokenParser\\TypesTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/TypesTokenParser.php', - 'Twig\\TokenParser\\UseTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/UseTokenParser.php', - 'Twig\\TokenParser\\WithTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/WithTokenParser.php', - 'Twig\\TokenStream' => __DIR__ . '/..' . '/twig/twig/src/TokenStream.php', - 'Twig\\TwigCallableInterface' => __DIR__ . '/..' . '/twig/twig/src/TwigCallableInterface.php', - 'Twig\\TwigFilter' => __DIR__ . '/..' . '/twig/twig/src/TwigFilter.php', - 'Twig\\TwigFunction' => __DIR__ . '/..' . '/twig/twig/src/TwigFunction.php', - 'Twig\\TwigTest' => __DIR__ . '/..' . '/twig/twig/src/TwigTest.php', - 'Twig\\Util\\CallableArgumentsExtractor' => __DIR__ . '/..' . '/twig/twig/src/Util/CallableArgumentsExtractor.php', - 'Twig\\Util\\DeprecationCollector' => __DIR__ . '/..' . '/twig/twig/src/Util/DeprecationCollector.php', - 'Twig\\Util\\ReflectionCallable' => __DIR__ . '/..' . '/twig/twig/src/Util/ReflectionCallable.php', - 'Twig\\Util\\TemplateDirIterator' => __DIR__ . '/..' . '/twig/twig/src/Util/TemplateDirIterator.php', - 'ZipStream\\CentralDirectoryFileHeader' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/CentralDirectoryFileHeader.php', - 'ZipStream\\CompressionMethod' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/CompressionMethod.php', - 'ZipStream\\DataDescriptor' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/DataDescriptor.php', - 'ZipStream\\EndOfCentralDirectory' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/EndOfCentralDirectory.php', - 'ZipStream\\Exception' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/Exception.php', - 'ZipStream\\Exception\\DosTimeOverflowException' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/Exception/DosTimeOverflowException.php', - 'ZipStream\\Exception\\FileNotFoundException' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/Exception/FileNotFoundException.php', - 'ZipStream\\Exception\\FileNotReadableException' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/Exception/FileNotReadableException.php', - 'ZipStream\\Exception\\FileSizeIncorrectException' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/Exception/FileSizeIncorrectException.php', - 'ZipStream\\Exception\\OverflowException' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/Exception/OverflowException.php', - 'ZipStream\\Exception\\ResourceActionException' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/Exception/ResourceActionException.php', - 'ZipStream\\Exception\\SimulationFileUnknownException' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/Exception/SimulationFileUnknownException.php', - 'ZipStream\\Exception\\StreamNotReadableException' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/Exception/StreamNotReadableException.php', - 'ZipStream\\Exception\\StreamNotSeekableException' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/Exception/StreamNotSeekableException.php', - 'ZipStream\\File' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/File.php', - 'ZipStream\\GeneralPurposeBitFlag' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/GeneralPurposeBitFlag.php', - 'ZipStream\\LocalFileHeader' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/LocalFileHeader.php', - 'ZipStream\\OperationMode' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/OperationMode.php', - 'ZipStream\\PackField' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/PackField.php', - 'ZipStream\\Time' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/Time.php', - 'ZipStream\\Version' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/Version.php', - 'ZipStream\\Zip64\\DataDescriptor' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/Zip64/DataDescriptor.php', - 'ZipStream\\Zip64\\EndOfCentralDirectory' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/Zip64/EndOfCentralDirectory.php', - 'ZipStream\\Zip64\\EndOfCentralDirectoryLocator' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/Zip64/EndOfCentralDirectoryLocator.php', - 'ZipStream\\Zip64\\ExtendedInformationExtraField' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/Zip64/ExtendedInformationExtraField.php', - 'ZipStream\\ZipStream' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/ZipStream.php', - 'ZipStream\\Zs\\ExtendedInformationExtraField' => __DIR__ . '/..' . '/maennchen/zipstream-php/src/Zs/ExtendedInformationExtraField.php', - ); - - public static function getInitializer(ClassLoader $loader) - { - return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit0d1b0e9376a19e86b57f1563bfba988b::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit0d1b0e9376a19e86b57f1563bfba988b::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit0d1b0e9376a19e86b57f1563bfba988b::$classMap; - - }, null, ClassLoader::class); - } -} diff --git a/COPS/cops-3.1.3/vendor/composer/installed.json b/COPS/cops-3.1.3/vendor/composer/installed.json deleted file mode 100644 index 58f54ba8..00000000 --- a/COPS/cops-3.1.3/vendor/composer/installed.json +++ /dev/null @@ -1,1107 +0,0 @@ -{ - "packages": [ - { - "name": "maennchen/zipstream-php", - "version": "3.1.0", - "version_normalized": "3.1.0.0", - "source": { - "type": "git", - "url": "https://github.com/maennchen/ZipStream-PHP.git", - "reference": "b8174494eda667f7d13876b4a7bfef0f62a7c0d1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/b8174494eda667f7d13876b4a7bfef0f62a7c0d1", - "reference": "b8174494eda667f7d13876b4a7bfef0f62a7c0d1", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "ext-zlib": "*", - "php-64bit": "^8.1" - }, - "require-dev": { - "ext-zip": "*", - "friendsofphp/php-cs-fixer": "^3.16", - "guzzlehttp/guzzle": "^7.5", - "mikey179/vfsstream": "^1.6", - "php-coveralls/php-coveralls": "^2.5", - "phpunit/phpunit": "^10.0", - "vimeo/psalm": "^5.0" - }, - "suggest": { - "guzzlehttp/psr7": "^2.4", - "psr/http-message": "^2.0" - }, - "time": "2023-06-21T14:59:35+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "ZipStream\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paul Duncan", - "email": "pabs@pablotron.org" - }, - { - "name": "Jonatan Männchen", - "email": "jonatan@maennchen.ch" - }, - { - "name": "Jesse Donat", - "email": "donatj@gmail.com" - }, - { - "name": "András Kolesár", - "email": "kolesar@kolesar.hu" - } - ], - "description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.", - "keywords": [ - "stream", - "zip" - ], - "support": { - "issues": "https://github.com/maennchen/ZipStream-PHP/issues", - "source": "https://github.com/maennchen/ZipStream-PHP/tree/3.1.0" - }, - "funding": [ - { - "url": "https://github.com/maennchen", - "type": "github" - }, - { - "url": "https://opencollective.com/zipstream", - "type": "open_collective" - } - ], - "install-path": "../maennchen/zipstream-php" - }, - { - "name": "mikespub/epubjs-reader", - "version": "2024.7.15", - "version_normalized": "2024.7.15.0", - "source": { - "type": "git", - "url": "https://github.com/mikespub-org/intity-epubjs-reader.git", - "reference": "52b5f5a295f96465352379481da8565aa778b4e2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mikespub-org/intity-epubjs-reader/zipball/52b5f5a295f96465352379481da8565aa778b4e2", - "reference": "52b5f5a295f96465352379481da8565aa778b4e2", - "shasum": "" - }, - "suggest": { - "mikespub/seblucas-cops": "COPS - Calibre OPDS (and HTML) PHP Server" - }, - "time": "2024-07-15T15:03:35+00:00", - "type": "library", - "installation-source": "dist", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "fchasen", - "homepage": "https://github.com/futurepress/epubjs-reader", - "role": "Developer" - }, - { - "name": "intity", - "homepage": "https://github.com/intity/epubreader-js", - "role": "Developer" - }, - { - "name": "mikespub", - "homepage": "https://github.com/mikespub-org/intity-epubjs-reader", - "role": "Developer" - } - ], - "description": "Epub.js Reader with zipfs.php", - "support": { - "issues": "https://github.com/mikespub-org/intity-epubjs-reader/issues", - "source": "https://github.com/mikespub-org/intity-epubjs-reader/tree/2024.7.15" - }, - "install-path": "../mikespub/epubjs-reader" - }, - { - "name": "mikespub/php-epub-meta", - "version": "3.0.0", - "version_normalized": "3.0.0.0", - "source": { - "type": "git", - "url": "https://github.com/mikespub-org/php-epub-meta.git", - "reference": "87813284bfa29cc7931a0e2723e2f3ebea9dae6b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mikespub-org/php-epub-meta/zipball/87813284bfa29cc7931a0e2723e2f3ebea9dae6b", - "reference": "87813284bfa29cc7931a0e2723e2f3ebea9dae6b", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-zip": "*", - "ext-zlib": "*", - "maennchen/zipstream-php": "^3.1", - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.3" - }, - "suggest": { - "mikespub/epub-loader": "epub-loader is a utility resource for ebooks", - "mikespub/seblucas-cops": "COPS - Calibre OPDS (and HTML) PHP Server" - }, - "time": "2024-09-05T11:22:06+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Andreas Gohr", - "email": "andi@splitbrain.org", - "homepage": "https://www.splitbrain.org/", - "role": "Developer" - }, - { - "name": "Sébastien Lucas", - "email": "sebastien@slucas.fr", - "homepage": "http://www.slucas.fr/", - "role": "Developer" - }, - { - "name": "mikespub", - "homepage": "https://github.com/mikespub-org/php-epub-meta", - "role": "Developer" - } - ], - "description": "Reading and writing metadata included in the EPub ebook format", - "homepage": "https://github.com/mikespub-org/php-epub-meta", - "keywords": [ - "ebook", - "epub", - "metadata" - ], - "support": { - "issues": "https://github.com/mikespub-org/php-epub-meta/issues", - "source": "https://github.com/mikespub-org/php-epub-meta/tree/3.0.0" - }, - "install-path": "../mikespub/php-epub-meta" - }, - { - "name": "nikic/fast-route", - "version": "dev-master", - "version_normalized": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/nikic/FastRoute.git", - "reference": "d3ada013d0f683ad2a8d0614fc97917a6ab72ce9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/FastRoute/zipball/d3ada013d0f683ad2a8d0614fc97917a6ab72ce9", - "reference": "d3ada013d0f683ad2a8d0614fc97917a6ab72ce9", - "shasum": "" - }, - "require": { - "php": ">=8.1.0", - "psr/simple-cache": "^2.0 || ^3.0" - }, - "require-dev": { - "lcobucci/coding-standard": "^11.0", - "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.10", - "phpstan/phpstan-deprecation-rules": "^1.1", - "phpstan/phpstan-phpunit": "^1.3", - "phpstan/phpstan-strict-rules": "^1.5", - "phpunit/phpunit": "^10.3" - }, - "time": "2024-03-04T23:46:43+00:00", - "default-branch": true, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "FastRoute\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov", - "email": "nikic@php.net" - } - ], - "description": "Fast request router for PHP", - "keywords": [ - "router", - "routing" - ], - "support": { - "issues": "https://github.com/nikic/FastRoute/issues", - "source": "https://github.com/nikic/FastRoute/tree/2.0.0-beta1" - }, - "install-path": "../nikic/fast-route" - }, - { - "name": "npm-asset/babel--runtime", - "version": "7.25.6", - "version_normalized": "7.25.6.0", - "dist": { - "type": "tar", - "url": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz" - }, - "require": { - "npm-asset/regenerator-runtime": ">=0.14.0,<0.15.0" - }, - "type": "npm-asset", - "installation-source": "dist", - "license": [ - "MIT" - ], - "install-path": "../npm-asset/babel--runtime" - }, - { - "name": "npm-asset/balanced-match", - "version": "1.0.2", - "version_normalized": "1.0.2.0", - "dist": { - "type": "tar", - "url": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" - }, - "type": "npm-asset", - "installation-source": "dist", - "license": [ - "MIT" - ], - "install-path": "../npm-asset/balanced-match" - }, - { - "name": "npm-asset/bootstrap", - "version": "3.4.1", - "version_normalized": "3.4.1.0", - "dist": { - "type": "tar", - "url": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.4.1.tgz" - }, - "type": "npm-asset", - "installation-source": "dist", - "license": [ - "MIT" - ], - "install-path": "../npm-asset/bootstrap" - }, - { - "name": "npm-asset/brace-expansion", - "version": "1.1.11", - "version_normalized": "1.1.11.0", - "dist": { - "type": "tar", - "url": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" - }, - "require": { - "npm-asset/balanced-match": ">=1.0.0,<2.0.0", - "npm-asset/concat-map": "0.0.1" - }, - "type": "npm-asset", - "installation-source": "dist", - "license": [ - "MIT" - ], - "install-path": "../npm-asset/brace-expansion" - }, - { - "name": "npm-asset/concat-map", - "version": "0.0.1", - "version_normalized": "0.0.1.0", - "dist": { - "type": "tar", - "url": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - }, - "type": "npm-asset", - "installation-source": "dist", - "license": [ - "MIT" - ], - "install-path": "../npm-asset/concat-map" - }, - { - "name": "npm-asset/corejs-typeahead", - "version": "1.3.4", - "version_normalized": "1.3.4.0", - "dist": { - "type": "tar", - "url": "https://registry.npmjs.org/corejs-typeahead/-/corejs-typeahead-1.3.4.tgz" - }, - "require": { - "npm-asset/jquery": ">=1.11" - }, - "type": "npm-asset", - "installation-source": "dist", - "license": [ - "MIT" - ], - "install-path": "../npm-asset/corejs-typeahead" - }, - { - "name": "npm-asset/dot", - "version": "1.1.3", - "version_normalized": "1.1.3.0", - "dist": { - "type": "tar", - "url": "https://registry.npmjs.org/dot/-/dot-1.1.3.tgz" - }, - "type": "npm-asset", - "installation-source": "dist", - "license": [ - "MIT" - ], - "install-path": "../npm-asset/dot" - }, - { - "name": "npm-asset/foreachasync", - "version": "3.0.0", - "version_normalized": "3.0.0.0", - "dist": { - "type": "tar", - "url": "https://registry.npmjs.org/foreachasync/-/foreachasync-3.0.0.tgz" - }, - "type": "npm-asset", - "installation-source": "dist", - "license": [ - "Apache2" - ], - "install-path": "../npm-asset/foreachasync" - }, - { - "name": "npm-asset/jquery", - "version": "3.7.1", - "version_normalized": "3.7.1.0", - "dist": { - "type": "tar", - "url": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz" - }, - "type": "npm-asset", - "installation-source": "dist", - "license": [ - "MIT" - ], - "install-path": "../npm-asset/jquery" - }, - { - "name": "npm-asset/js-cookie", - "version": "2.2.1", - "version_normalized": "2.2.1.0", - "dist": { - "type": "tar", - "url": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz" - }, - "type": "npm-asset", - "installation-source": "dist", - "license": [ - "MIT" - ], - "install-path": "../npm-asset/js-cookie" - }, - { - "name": "npm-asset/locutus", - "version": "2.0.32", - "version_normalized": "2.0.32.0", - "dist": { - "type": "tar", - "url": "https://registry.npmjs.org/locutus/-/locutus-2.0.32.tgz" - }, - "type": "npm-asset", - "installation-source": "dist", - "license": [ - "MIT" - ], - "install-path": "../npm-asset/locutus" - }, - { - "name": "npm-asset/lru-fast", - "version": "0.2.2", - "version_normalized": "0.2.2.0", - "dist": { - "type": "tar", - "url": "https://registry.npmjs.org/lru-fast/-/lru-fast-0.2.2.tgz" - }, - "type": "npm-asset", - "installation-source": "dist", - "license": [ - "MIT" - ], - "install-path": "../npm-asset/lru-fast" - }, - { - "name": "npm-asset/magnific-popup", - "version": "1.2.0", - "version_normalized": "1.2.0.0", - "dist": { - "type": "tar", - "url": "https://registry.npmjs.org/magnific-popup/-/magnific-popup-1.2.0.tgz" - }, - "type": "npm-asset", - "installation-source": "dist", - "license": [ - "MIT" - ], - "install-path": "../npm-asset/magnific-popup" - }, - { - "name": "npm-asset/minimatch", - "version": "3.0.8", - "version_normalized": "3.0.8.0", - "dist": { - "type": "tar", - "url": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz" - }, - "require": { - "npm-asset/brace-expansion": ">=1.1.7,<2.0.0" - }, - "type": "npm-asset", - "installation-source": "dist", - "license": [ - "ISC" - ], - "install-path": "../npm-asset/minimatch" - }, - { - "name": "npm-asset/normalize.css", - "version": "8.0.1", - "version_normalized": "8.0.1.0", - "dist": { - "type": "tar", - "url": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz" - }, - "type": "npm-asset", - "installation-source": "dist", - "license": [ - "MIT" - ], - "install-path": "../npm-asset/normalize.css" - }, - { - "name": "npm-asset/regenerator-runtime", - "version": "0.14.1", - "version_normalized": "0.14.1.0", - "dist": { - "type": "tar", - "url": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz" - }, - "type": "npm-asset", - "installation-source": "dist", - "license": [ - "MIT" - ], - "install-path": "../npm-asset/regenerator-runtime" - }, - { - "name": "npm-asset/twig", - "version": "1.17.1", - "version_normalized": "1.17.1.0", - "dist": { - "type": "tar", - "url": "https://registry.npmjs.org/twig/-/twig-1.17.1.tgz" - }, - "require": { - "npm-asset/babel--runtime": ">=7.8.4,<8.0.0", - "npm-asset/locutus": ">=2.0.11,<3.0.0", - "npm-asset/minimatch": "dev-3.0.x|3.0.x", - "npm-asset/walk": "dev-2.3.x|2.3.x" - }, - "type": "npm-asset", - "installation-source": "dist", - "license": [ - "BSD-2-Clause" - ], - "install-path": "../npm-asset/twig" - }, - { - "name": "npm-asset/walk", - "version": "2.3.15", - "version_normalized": "2.3.15.0", - "dist": { - "type": "tar", - "url": "https://registry.npmjs.org/walk/-/walk-2.3.15.tgz" - }, - "require": { - "npm-asset/foreachasync": ">=3.0.0,<4.0.0" - }, - "type": "npm-asset", - "installation-source": "dist", - "license": [ - "(MIT OR Apache-2.0)" - ], - "install-path": "../npm-asset/walk" - }, - { - "name": "phpmailer/phpmailer", - "version": "v6.9.1", - "version_normalized": "6.9.1.0", - "source": { - "type": "git", - "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "039de174cd9c17a8389754d3b877a2ed22743e18" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/039de174cd9c17a8389754d3b877a2ed22743e18", - "reference": "039de174cd9c17a8389754d3b877a2ed22743e18", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-filter": "*", - "ext-hash": "*", - "php": ">=5.5.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^1.0", - "doctrine/annotations": "^1.2.6 || ^1.13.3", - "php-parallel-lint/php-console-highlighter": "^1.0.0", - "php-parallel-lint/php-parallel-lint": "^1.3.2", - "phpcompatibility/php-compatibility": "^9.3.5", - "roave/security-advisories": "dev-latest", - "squizlabs/php_codesniffer": "^3.7.2", - "yoast/phpunit-polyfills": "^1.0.4" - }, - "suggest": { - "decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication", - "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", - "ext-openssl": "Needed for secure SMTP sending and DKIM signing", - "greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication", - "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", - "league/oauth2-google": "Needed for Google XOAUTH2 authentication", - "psr/log": "For optional PSR-3 debug logging", - "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)", - "thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication" - }, - "time": "2023-11-25T22:23:28+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "PHPMailer\\PHPMailer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-only" - ], - "authors": [ - { - "name": "Marcus Bointon", - "email": "phpmailer@synchromedia.co.uk" - }, - { - "name": "Jim Jagielski", - "email": "jimjag@gmail.com" - }, - { - "name": "Andy Prevost", - "email": "codeworxtech@users.sourceforge.net" - }, - { - "name": "Brent R. Matzelle" - } - ], - "description": "PHPMailer is a full-featured email creation and transfer class for PHP", - "support": { - "issues": "https://github.com/PHPMailer/PHPMailer/issues", - "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.9.1" - }, - "funding": [ - { - "url": "https://github.com/Synchro", - "type": "github" - } - ], - "install-path": "../phpmailer/phpmailer" - }, - { - "name": "psr/simple-cache", - "version": "3.0.0", - "version_normalized": "3.0.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/simple-cache.git", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "time": "2021-10-29T13:26:27+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\SimpleCache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interfaces for simple caching", - "keywords": [ - "cache", - "caching", - "psr", - "psr-16", - "simple-cache" - ], - "support": { - "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" - }, - "install-path": "../psr/simple-cache" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v3.5.0", - "version_normalized": "3.5.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "time": "2024-04-18T09:32:20+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "install-path": "../symfony/deprecation-contracts" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.31.0", - "version_normalized": "1.31.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "time": "2024-09-09T11:45:10+00:00", - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "install-path": "../symfony/polyfill-ctype" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.31.0", - "version_normalized": "1.31.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "time": "2024-09-09T11:45:10+00:00", - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "install-path": "../symfony/polyfill-mbstring" - }, - { - "name": "symfony/polyfill-php81", - "version": "v1.31.0", - "version_normalized": "1.31.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", - "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "time": "2024-09-09T11:45:10+00:00", - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php81\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "install-path": "../symfony/polyfill-php81" - }, - { - "name": "twig/twig", - "version": "v3.14.0", - "version_normalized": "3.14.0.0", - "source": { - "type": "git", - "url": "https://github.com/twigphp/Twig.git", - "reference": "126b2c97818dbff0cdf3fbfc881aedb3d40aae72" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/126b2c97818dbff0cdf3fbfc881aedb3d40aae72", - "reference": "126b2c97818dbff0cdf3fbfc881aedb3d40aae72", - "shasum": "" - }, - "require": { - "php": ">=8.0.2", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-mbstring": "^1.3", - "symfony/polyfill-php81": "^1.29" - }, - "require-dev": { - "psr/container": "^1.0|^2.0", - "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0" - }, - "time": "2024-09-09T17:55:12+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "files": [ - "src/Resources/core.php", - "src/Resources/debug.php", - "src/Resources/escaper.php", - "src/Resources/string_loader.php" - ], - "psr-4": { - "Twig\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Twig Team", - "role": "Contributors" - }, - { - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "role": "Project Founder" - } - ], - "description": "Twig, the flexible, fast, and secure template language for PHP", - "homepage": "https://twig.symfony.com", - "keywords": [ - "templating" - ], - "support": { - "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.14.0" - }, - "funding": [ - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/twig/twig", - "type": "tidelift" - } - ], - "install-path": "../twig/twig" - } - ], - "dev": false, - "dev-package-names": [] -} diff --git a/COPS/cops-3.1.3/vendor/composer/installed.php b/COPS/cops-3.1.3/vendor/composer/installed.php deleted file mode 100644 index b41fa839..00000000 --- a/COPS/cops-3.1.3/vendor/composer/installed.php +++ /dev/null @@ -1,286 +0,0 @@ - array( - 'name' => 'mikespub/seblucas-cops', - 'pretty_version' => 'dev-main', - 'version' => 'dev-main', - 'reference' => '08e18b25e42a1d7f67d85bb4a2a34ab4ae3e376d', - 'type' => 'project', - 'install_path' => __DIR__ . '/../../', - 'aliases' => array(), - 'dev' => false, - ), - 'versions' => array( - 'maennchen/zipstream-php' => array( - 'pretty_version' => '3.1.0', - 'version' => '3.1.0.0', - 'reference' => 'b8174494eda667f7d13876b4a7bfef0f62a7c0d1', - 'type' => 'library', - 'install_path' => __DIR__ . '/../maennchen/zipstream-php', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'mikespub/epubjs-reader' => array( - 'pretty_version' => '2024.7.15', - 'version' => '2024.7.15.0', - 'reference' => '52b5f5a295f96465352379481da8565aa778b4e2', - 'type' => 'library', - 'install_path' => __DIR__ . '/../mikespub/epubjs-reader', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'mikespub/php-epub-meta' => array( - 'pretty_version' => '3.0.0', - 'version' => '3.0.0.0', - 'reference' => '87813284bfa29cc7931a0e2723e2f3ebea9dae6b', - 'type' => 'library', - 'install_path' => __DIR__ . '/../mikespub/php-epub-meta', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'mikespub/seblucas-cops' => array( - 'pretty_version' => 'dev-main', - 'version' => 'dev-main', - 'reference' => '08e18b25e42a1d7f67d85bb4a2a34ab4ae3e376d', - 'type' => 'project', - 'install_path' => __DIR__ . '/../../', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'nikic/fast-route' => array( - 'pretty_version' => 'dev-master', - 'version' => 'dev-master', - 'reference' => 'd3ada013d0f683ad2a8d0614fc97917a6ab72ce9', - 'type' => 'library', - 'install_path' => __DIR__ . '/../nikic/fast-route', - 'aliases' => array( - 0 => '2.0.x-dev', - ), - 'dev_requirement' => false, - ), - 'npm-asset/babel--runtime' => array( - 'pretty_version' => '7.25.6', - 'version' => '7.25.6.0', - 'reference' => null, - 'type' => 'npm-asset', - 'install_path' => __DIR__ . '/../npm-asset/babel--runtime', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'npm-asset/balanced-match' => array( - 'pretty_version' => '1.0.2', - 'version' => '1.0.2.0', - 'reference' => null, - 'type' => 'npm-asset', - 'install_path' => __DIR__ . '/../npm-asset/balanced-match', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'npm-asset/bootstrap' => array( - 'pretty_version' => '3.4.1', - 'version' => '3.4.1.0', - 'reference' => null, - 'type' => 'npm-asset', - 'install_path' => __DIR__ . '/../npm-asset/bootstrap', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'npm-asset/brace-expansion' => array( - 'pretty_version' => '1.1.11', - 'version' => '1.1.11.0', - 'reference' => null, - 'type' => 'npm-asset', - 'install_path' => __DIR__ . '/../npm-asset/brace-expansion', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'npm-asset/concat-map' => array( - 'pretty_version' => '0.0.1', - 'version' => '0.0.1.0', - 'reference' => null, - 'type' => 'npm-asset', - 'install_path' => __DIR__ . '/../npm-asset/concat-map', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'npm-asset/corejs-typeahead' => array( - 'pretty_version' => '1.3.4', - 'version' => '1.3.4.0', - 'reference' => null, - 'type' => 'npm-asset', - 'install_path' => __DIR__ . '/../npm-asset/corejs-typeahead', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'npm-asset/dot' => array( - 'pretty_version' => '1.1.3', - 'version' => '1.1.3.0', - 'reference' => null, - 'type' => 'npm-asset', - 'install_path' => __DIR__ . '/../npm-asset/dot', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'npm-asset/foreachasync' => array( - 'pretty_version' => '3.0.0', - 'version' => '3.0.0.0', - 'reference' => null, - 'type' => 'npm-asset', - 'install_path' => __DIR__ . '/../npm-asset/foreachasync', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'npm-asset/jquery' => array( - 'pretty_version' => '3.7.1', - 'version' => '3.7.1.0', - 'reference' => null, - 'type' => 'npm-asset', - 'install_path' => __DIR__ . '/../npm-asset/jquery', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'npm-asset/js-cookie' => array( - 'pretty_version' => '2.2.1', - 'version' => '2.2.1.0', - 'reference' => null, - 'type' => 'npm-asset', - 'install_path' => __DIR__ . '/../npm-asset/js-cookie', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'npm-asset/locutus' => array( - 'pretty_version' => '2.0.32', - 'version' => '2.0.32.0', - 'reference' => null, - 'type' => 'npm-asset', - 'install_path' => __DIR__ . '/../npm-asset/locutus', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'npm-asset/lru-fast' => array( - 'pretty_version' => '0.2.2', - 'version' => '0.2.2.0', - 'reference' => null, - 'type' => 'npm-asset', - 'install_path' => __DIR__ . '/../npm-asset/lru-fast', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'npm-asset/magnific-popup' => array( - 'pretty_version' => '1.2.0', - 'version' => '1.2.0.0', - 'reference' => null, - 'type' => 'npm-asset', - 'install_path' => __DIR__ . '/../npm-asset/magnific-popup', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'npm-asset/minimatch' => array( - 'pretty_version' => '3.0.8', - 'version' => '3.0.8.0', - 'reference' => null, - 'type' => 'npm-asset', - 'install_path' => __DIR__ . '/../npm-asset/minimatch', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'npm-asset/normalize.css' => array( - 'pretty_version' => '8.0.1', - 'version' => '8.0.1.0', - 'reference' => null, - 'type' => 'npm-asset', - 'install_path' => __DIR__ . '/../npm-asset/normalize.css', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'npm-asset/regenerator-runtime' => array( - 'pretty_version' => '0.14.1', - 'version' => '0.14.1.0', - 'reference' => null, - 'type' => 'npm-asset', - 'install_path' => __DIR__ . '/../npm-asset/regenerator-runtime', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'npm-asset/twig' => array( - 'pretty_version' => '1.17.1', - 'version' => '1.17.1.0', - 'reference' => null, - 'type' => 'npm-asset', - 'install_path' => __DIR__ . '/../npm-asset/twig', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'npm-asset/walk' => array( - 'pretty_version' => '2.3.15', - 'version' => '2.3.15.0', - 'reference' => null, - 'type' => 'npm-asset', - 'install_path' => __DIR__ . '/../npm-asset/walk', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'phpmailer/phpmailer' => array( - 'pretty_version' => 'v6.9.1', - 'version' => '6.9.1.0', - 'reference' => '039de174cd9c17a8389754d3b877a2ed22743e18', - 'type' => 'library', - 'install_path' => __DIR__ . '/../phpmailer/phpmailer', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'psr/simple-cache' => array( - 'pretty_version' => '3.0.0', - 'version' => '3.0.0.0', - 'reference' => '764e0b3939f5ca87cb904f570ef9be2d78a07865', - 'type' => 'library', - 'install_path' => __DIR__ . '/../psr/simple-cache', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'symfony/deprecation-contracts' => array( - 'pretty_version' => 'v3.5.0', - 'version' => '3.5.0.0', - 'reference' => '0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1', - 'type' => 'library', - 'install_path' => __DIR__ . '/../symfony/deprecation-contracts', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'symfony/polyfill-ctype' => array( - 'pretty_version' => 'v1.31.0', - 'version' => '1.31.0.0', - 'reference' => 'a3cc8b044a6ea513310cbd48ef7333b384945638', - 'type' => 'library', - 'install_path' => __DIR__ . '/../symfony/polyfill-ctype', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'symfony/polyfill-mbstring' => array( - 'pretty_version' => 'v1.31.0', - 'version' => '1.31.0.0', - 'reference' => '85181ba99b2345b0ef10ce42ecac37612d9fd341', - 'type' => 'library', - 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'symfony/polyfill-php81' => array( - 'pretty_version' => 'v1.31.0', - 'version' => '1.31.0.0', - 'reference' => '4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c', - 'type' => 'library', - 'install_path' => __DIR__ . '/../symfony/polyfill-php81', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'twig/twig' => array( - 'pretty_version' => 'v3.14.0', - 'version' => '3.14.0.0', - 'reference' => '126b2c97818dbff0cdf3fbfc881aedb3d40aae72', - 'type' => 'library', - 'install_path' => __DIR__ . '/../twig/twig', - 'aliases' => array(), - 'dev_requirement' => false, - ), - ), -); diff --git a/COPS/cops-3.1.3/vendor/composer/platform_check.php b/COPS/cops-3.1.3/vendor/composer/platform_check.php deleted file mode 100644 index d515d34b..00000000 --- a/COPS/cops-3.1.3/vendor/composer/platform_check.php +++ /dev/null @@ -1,30 +0,0 @@ -= 80200)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 8.2.0". You are running ' . PHP_VERSION . '.'; -} - -if (PHP_INT_SIZE !== 8) { - $issues[] = 'Your Composer dependencies require a 64-bit build of PHP.'; -} - -if ($issues) { - if (!headers_sent()) { - header('HTTP/1.1 500 Internal Server Error'); - } - if (!ini_get('display_errors')) { - if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { - fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); - } elseif (!headers_sent()) { - echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; - } - } - trigger_error( - 'Composer detected issues in your platform: ' . implode(' ', $issues), - E_USER_ERROR - ); -} diff --git a/COPS/cops-3.1.3/vendor/maennchen/zipstream-php/.editorconfig b/COPS/cops-3.1.3/vendor/maennchen/zipstream-php/.editorconfig deleted file mode 100644 index f7cd9142..00000000 --- a/COPS/cops-3.1.3/vendor/maennchen/zipstream-php/.editorconfig +++ /dev/null @@ -1,22 +0,0 @@ -root = true - -[*] -end_of_line = lf -insert_final_newline = true -charset = utf-8 - -[*.{yml,md,xml}] -indent_style = space -indent_size = 2 - -[*.{rst,php}] -indent_style = space -indent_size = 4 - -[composer.json] -indent_style = space -indent_size = 2 - -[composer.lock] -indent_style = space -indent_size = 4 diff --git a/COPS/cops-3.1.3/vendor/maennchen/zipstream-php/.php-cs-fixer.dist.php b/COPS/cops-3.1.3/vendor/maennchen/zipstream-php/.php-cs-fixer.dist.php deleted file mode 100644 index b978f064..00000000 --- a/COPS/cops-3.1.3/vendor/maennchen/zipstream-php/.php-cs-fixer.dist.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright 2022 Nicolas CARPi - * @see https://github.com/maennchen/ZipStream-PHP - * @license MIT - * @package maennchen/ZipStream-PHP - */ - -use PhpCsFixer\Config; -use PhpCsFixer\Finder; - -$finder = Finder::create() - ->exclude('.github') - ->exclude('.phpdoc') - ->exclude('docs') - ->exclude('tools') - ->exclude('vendor') - ->in(__DIR__); - -$config = new Config(); -return $config->setRules([ - '@PER' => true, - '@PER:risky' => true, - '@PHP82Migration' => true, - '@PHPUnit84Migration:risky' => true, - 'array_syntax' => ['syntax' => 'short'], - 'class_attributes_separation' => true, - 'declare_strict_types' => true, - 'dir_constant' => true, - 'is_null' => true, - 'no_homoglyph_names' => true, - 'no_null_property_initialization' => true, - 'no_php4_constructor' => true, - 'no_unused_imports' => true, - 'no_useless_else' => true, - 'non_printable_character' => true, - 'ordered_imports' => true, - 'ordered_class_elements' => true, - 'php_unit_construct' => true, - 'pow_to_exponentiation' => true, - 'psr_autoloading' => true, - 'random_api_migration' => true, - 'return_assignment' => true, - 'self_accessor' => true, - 'semicolon_after_instruction' => true, - 'short_scalar_cast' => true, - 'simplified_null_return' => true, - 'single_blank_line_before_namespace' => true, - 'single_class_element_per_statement' => true, - 'single_line_comment_style' => true, - 'single_quote' => true, - 'space_after_semicolon' => true, - 'standardize_not_equals' => true, - 'strict_param' => true, - 'ternary_operator_spaces' => true, - 'trailing_comma_in_multiline' => true, - 'trim_array_spaces' => true, - 'unary_operator_spaces' => true, - 'global_namespace_import' => [ - 'import_classes' => true, - 'import_functions' => true, - 'import_constants' => true, - ], - ]) - ->setFinder($finder) - ->setRiskyAllowed(true); diff --git a/COPS/cops-3.1.3/vendor/maennchen/zipstream-php/.tool-versions b/COPS/cops-3.1.3/vendor/maennchen/zipstream-php/.tool-versions deleted file mode 100644 index 26181781..00000000 --- a/COPS/cops-3.1.3/vendor/maennchen/zipstream-php/.tool-versions +++ /dev/null @@ -1 +0,0 @@ -php 8.2.5 diff --git a/COPS/cops-3.1.3/vendor/maennchen/zipstream-php/LICENSE b/COPS/cops-3.1.3/vendor/maennchen/zipstream-php/LICENSE deleted file mode 100644 index ebe7fe2f..00000000 --- a/COPS/cops-3.1.3/vendor/maennchen/zipstream-php/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -MIT License - -Copyright (C) 2007-2009 Paul Duncan -Copyright (C) 2014 Jonatan Männchen -Copyright (C) 2014 Jesse G. Donat -Copyright (C) 2018 Nicolas CARPi - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/COPS/cops-3.1.3/vendor/maennchen/zipstream-php/README.md b/COPS/cops-3.1.3/vendor/maennchen/zipstream-php/README.md deleted file mode 100644 index 8ebb2c3c..00000000 --- a/COPS/cops-3.1.3/vendor/maennchen/zipstream-php/README.md +++ /dev/null @@ -1,183 +0,0 @@ -# ZipStream-PHP - -[![Main Branch](https://github.com/maennchen/ZipStream-PHP/actions/workflows/branch_main.yml/badge.svg)](https://github.com/maennchen/ZipStream-PHP/actions/workflows/branch_main.yml) -[![Coverage Status](https://coveralls.io/repos/github/maennchen/ZipStream-PHP/badge.svg?branch=main)](https://coveralls.io/github/maennchen/ZipStream-PHP?branch=main) -[![Latest Stable Version](https://poser.pugx.org/maennchen/zipstream-php/v/stable)](https://packagist.org/packages/maennchen/zipstream-php) -[![Total Downloads](https://poser.pugx.org/maennchen/zipstream-php/downloads)](https://packagist.org/packages/maennchen/zipstream-php) -[![Financial Contributors on Open Collective](https://opencollective.com/zipstream/all/badge.svg?label=financial+contributors)](https://opencollective.com/zipstream) [![License](https://img.shields.io/github/license/maennchen/zipstream-php.svg)](LICENSE) - -## Unstable Branch - -The `main` branch is not stable. Please see the -[releases](https://github.com/maennchen/ZipStream-PHP/releases) for a stable -version. - -## Overview - -A fast and simple streaming zip file downloader for PHP. Using this library will -save you from having to write the Zip to disk. You can directly send it to the -user, which is much faster. It can work with S3 buckets or any PSR7 Stream. - -Please see the [LICENSE](LICENSE) file for licensing and warranty information. - -## Installation - -Simply add a dependency on maennchen/zipstream-php to your project's -`composer.json` file if you use Composer to manage the dependencies of your -project. Use following command to add the package to your project's dependencies: - -```bash -composer require maennchen/zipstream-php -``` - -## Usage - -For detailed instructions, please check the -[Documentation](https://maennchen.github.io/ZipStream-PHP/). - -```php -// Autoload the dependencies -require 'vendor/autoload.php'; - -// create a new zipstream object -$zip = new ZipStream\ZipStream( - outputName: 'example.zip', - - // enable output of HTTP headers - sendHttpHeaders: true, -); - -// create a file named 'hello.txt' -$zip->addFile( - fileName: 'hello.txt', - data: 'This is the contents of hello.txt', -); - -// add a file named 'some_image.jpg' from a local file 'path/to/image.jpg' -$zip->addFileFromPath( - fileName: 'some_image.jpg', - path: 'path/to/image.jpg', -); - -// finish the zip stream -$zip->finish(); -``` - -## Upgrade to version 3.0.0 - -### General - -- Minimum PHP Version: `8.1` -- Only 64bit Architecture is supported. -- The class `ZipStream\Option\Method` has been replaced with the enum - `ZipStream\CompressionMethod`. -- Most clases have been flagged as `@internal` and should not be used from the - outside. - If you're using internal resources to extend this library, please open an - issue so that a clean interface can be added & published. - The externally available classes & enums are: - - `ZipStream\CompressionMethod` - - `ZipStream\Exception*` - - `ZipStream\ZipStream` - -### Archive Options - -- The class `ZipStream\Option\Archive` has been replaced in favor of named - arguments in the `ZipStream\ZipStream` constuctor. -- The archive options `largeFileSize` & `largeFileMethod` has been removed. If - you want different `compressionMethods` based on the file size, you'll have to - implement this yourself. -- The archive option `httpHeaderCallback` changed the type from `callable` to - `Closure`. -- The archive option `zeroHeader` has been replaced with the option - `defaultEnableZeroHeader` and can be overridden for every file. Its default - value changed from `false` to `true`. -- The archive option `statFiles` was removed since the library no longer checks - filesizes this way. -- The archive option `deflateLevel` has been replaced with the option - `defaultDeflateLevel` and can be overridden for every file. -- The first argument (`name`) of the `ZipStream\ZipStream` constuctor has been - replaced with the named argument `outputName`. -- Headers are now also sent if the `outputName` is empty. If you do not want to - automatically send http headers, set `sendHttpHeaders` to `false`. - -### File Options - -- The class `ZipStream\Option\File` has been replaced in favor of named - arguments in the `ZipStream\ZipStream->addFile*` functions. -- The file option `method` has been renamed to `compressionMethod`. -- The file option `time` has been renamed to `lastModificationDateTime`. -- The file option `size` has been renamed to `maxSize`. - -## Upgrade to version 2.0.0 - -https://github.com/maennchen/ZipStream-PHP/tree/2.0.0#upgrade-to-version-200 - -## Upgrade to version 1.0.0 - -https://github.com/maennchen/ZipStream-PHP/tree/2.0.0#upgrade-to-version-100 - -## Contributing - -ZipStream-PHP is a collaborative project. Please take a look at the -[.github/CONTRIBUTING.md](.github/CONTRIBUTING.md) file. - -## Version Support - -Versions are supported according to the table below. - -Please do not open any pull requests contradicting the current version support -status. - -Careful: Always check the `README` on `main` for up-to-date information. - -| Version | New Features | Bugfixes | Security | -|---------|--------------|----------|----------| -| *3* | ✓ | ✓ | ✓ | -| *2* | ✗ | ✓ | ✓ | -| *1* | ✗ | ✗ | ✓ | -| *0* | ✗ | ✗ | ✗ | - -This library aligns itself with the PHP core support. New features and bugfixes -will only target PHP versions according to their current status. - -See: https://www.php.net/supported-versions.php - -## About the Authors - -- Paul Duncan - https://pablotron.org/ -- Jonatan Männchen - https://maennchen.dev -- Jesse G. Donat - https://donatstudios.com -- Nicolas CARPi - https://www.deltablot.com -- Nik Barham - https://www.brokencube.co.uk - -## Contributors - -### Code Contributors - -This project exists thanks to all the people who contribute. -[[Contribute](.github/CONTRIBUTING.md)]. - - -### Financial Contributors - -Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/zipstream/contribute)] - -#### Individuals - - - -#### Organizations - -Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/zipstream/contribute)] - - - - - - - - - - - diff --git a/COPS/cops-3.1.3/vendor/maennchen/zipstream-php/composer.json b/COPS/cops-3.1.3/vendor/maennchen/zipstream-php/composer.json deleted file mode 100644 index 98c536a4..00000000 --- a/COPS/cops-3.1.3/vendor/maennchen/zipstream-php/composer.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "name": "maennchen/zipstream-php", - "description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.", - "keywords": ["zip", "stream"], - "type": "library", - "license": "MIT", - "authors": [{ - "name": "Paul Duncan", - "email": "pabs@pablotron.org" - }, - { - "name": "Jonatan Männchen", - "email": "jonatan@maennchen.ch" - }, - { - "name": "Jesse Donat", - "email": "donatj@gmail.com" - }, - { - "name": "András Kolesár", - "email": "kolesar@kolesar.hu" - } - ], - "require": { - "php-64bit": "^8.1", - "ext-mbstring": "*", - "ext-zlib": "*" - }, - "require-dev": { - "phpunit/phpunit": "^10.0", - "guzzlehttp/guzzle": "^7.5", - "ext-zip": "*", - "mikey179/vfsstream": "^1.6", - "php-coveralls/php-coveralls": "^2.5", - "friendsofphp/php-cs-fixer": "^3.16", - "vimeo/psalm": "^5.0" - }, - "suggest": { - "psr/http-message": "^2.0", - "guzzlehttp/psr7": "^2.4" - }, - "scripts": { - "format": "php-cs-fixer fix", - "test": [ - "@test:unit", - "@test:formatted", - "@test:lint" - ], - "test:unit": "phpunit --coverage-clover=coverage.clover.xml --coverage-html cov", - "test:unit:slow": "@test:unit --group slow", - "test:unit:fast": "@test:unit --exclude-group slow", - "test:formatted": "@format --dry-run --stop-on-violation --using-cache=no", - "test:lint": "psalm --stats --show-info=true --find-unused-psalm-suppress", - "coverage:report": "php-coveralls --coverage_clover=coverage.clover.xml --json_path=coveralls-upload.json --insecure", - "install:tools": "phive install --trust-gpg-keys 0x67F861C3D889C656", - "docs:generate": "tools/phpdocumentor --sourcecode" - }, - "autoload": { - "psr-4": { - "ZipStream\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { "ZipStream\\Test\\": "test/" } - }, - "archive": { - "exclude": [ - "/composer.lock", - "/docs", - "/.gitattributes", - "/.github", - "/.gitignore", - "/guides", - "/.phive", - "/.php-cs-fixer.cache", - "/.php-cs-fixer.dist.php", - "/.phpdoc", - "/phpdoc.dist.xml", - "/.phpunit.result.cache", - "/phpunit.xml.dist", - "/psalm.xml", - "/test", - "/tools", - "/.tool-versions", - "/vendor" - ] - } -} diff --git a/COPS/cops-3.1.3/vendor/maennchen/zipstream-php/phpdoc.dist.xml b/COPS/cops-3.1.3/vendor/maennchen/zipstream-php/phpdoc.dist.xml deleted file mode 100644 index b98fe1cd..00000000 --- a/COPS/cops-3.1.3/vendor/maennchen/zipstream-php/phpdoc.dist.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - 💾 ZipStream-PHP - - docs - - - latest - - - src - - api - - - php - - public - ZipStream - true - - - - guides - - guide - - - -