From d1d654ebac2d51e3841675faeb56480e440f622f Mon Sep 17 00:00:00 2001 From: Wolfgang Müller Date: Tue, 5 Mar 2024 18:08:09 +0100 Subject: Initial commit --- frontend/src/app.css | 180 ++ frontend/src/app.d.ts | 12 + frontend/src/app.html | 13 + frontend/src/gql/Mutations.ts | 244 +++ frontend/src/gql/Queries.ts | 243 +++ frontend/src/gql/Utils.ts | 74 + frontend/src/gql/graphql.ts | 1764 ++++++++++++++++++++ frontend/src/lib/Actions.ts | 109 ++ frontend/src/lib/Enums.ts | 325 ++++ frontend/src/lib/Filter.ts | 365 ++++ frontend/src/lib/Meta.ts | 1 + frontend/src/lib/Navigation.ts | 114 ++ frontend/src/lib/Pagination.ts | 31 + frontend/src/lib/Reader.ts | 62 + frontend/src/lib/Scraper.ts | 156 ++ frontend/src/lib/Selection.ts | 141 ++ frontend/src/lib/Shortcuts.ts | 153 ++ frontend/src/lib/Sort.ts | 42 + frontend/src/lib/Tabs.ts | 18 + frontend/src/lib/Toasts.ts | 19 + frontend/src/lib/Transitions.ts | 10 + frontend/src/lib/Update.ts | 97 ++ frontend/src/lib/Utils.ts | 108 ++ frontend/src/lib/assets/logo.webp | Bin 0 -> 89322 bytes frontend/src/lib/components/AddButton.svelte | 7 + frontend/src/lib/components/Badge.svelte | 15 + frontend/src/lib/components/BookmarkButton.svelte | 9 + frontend/src/lib/components/Card.svelte | 106 ++ frontend/src/lib/components/Cardlet.svelte | 37 + frontend/src/lib/components/DeleteButton.svelte | 15 + frontend/src/lib/components/Dialog.svelte | 36 + frontend/src/lib/components/Dropdown.svelte | 18 + frontend/src/lib/components/Empty.svelte | 10 + frontend/src/lib/components/Expander.svelte | 17 + frontend/src/lib/components/Guard.svelte | 13 + frontend/src/lib/components/Head.svelte | 12 + frontend/src/lib/components/Labelled.svelte | 10 + frontend/src/lib/components/LabelledBlock.svelte | 18 + frontend/src/lib/components/OrganizedButton.svelte | 9 + frontend/src/lib/components/RefreshButton.svelte | 3 + .../src/lib/components/RemovePageButton.svelte | 13 + frontend/src/lib/components/Select.svelte | 55 + frontend/src/lib/components/Spinner.svelte | 36 + frontend/src/lib/components/SubmitButton.svelte | 7 + frontend/src/lib/components/Titlebar.svelte | 32 + frontend/src/lib/containers/Cardlets.svelte | 11 + frontend/src/lib/containers/Cards.svelte | 8 + frontend/src/lib/containers/Carousel.svelte | 15 + frontend/src/lib/containers/Column.svelte | 3 + frontend/src/lib/containers/Grid.svelte | 23 + frontend/src/lib/dialogs/AddArtist.svelte | 30 + frontend/src/lib/dialogs/AddCharacter.svelte | 30 + frontend/src/lib/dialogs/AddCircle.svelte | 30 + frontend/src/lib/dialogs/AddNamespace.svelte | 30 + frontend/src/lib/dialogs/AddTag.svelte | 30 + frontend/src/lib/dialogs/AddWorld.svelte | 30 + frontend/src/lib/dialogs/ConfirmDeletion.svelte | 51 + frontend/src/lib/dialogs/EditArtist.svelte | 46 + frontend/src/lib/dialogs/EditCharacter.svelte | 46 + frontend/src/lib/dialogs/EditCircle.svelte | 46 + frontend/src/lib/dialogs/EditNamespace.svelte | 46 + frontend/src/lib/dialogs/EditTag.svelte | 44 + frontend/src/lib/dialogs/EditWorld.svelte | 46 + frontend/src/lib/dialogs/UpdateComics.svelte | 96 ++ frontend/src/lib/dialogs/UpdateTags.svelte | 45 + .../dialogs/components/UpdateModeSelector.svelte | 24 + frontend/src/lib/filter/ComicFilterForm.svelte | 48 + frontend/src/lib/filter/TagFilterForm.svelte | 31 + .../lib/filter/components/ComicFilterGroup.svelte | 27 + frontend/src/lib/filter/components/Filter.svelte | 77 + .../src/lib/filter/components/FilterForm.svelte | 47 + .../lib/filter/components/TagFilterGroup.svelte | 14 + frontend/src/lib/forms/ArtistForm.svelte | 25 + frontend/src/lib/forms/CharacterForm.svelte | 25 + frontend/src/lib/forms/CircleForm.svelte | 25 + frontend/src/lib/forms/ComicForm.svelte | 100 ++ frontend/src/lib/forms/NamespaceForm.svelte | 28 + frontend/src/lib/forms/TagForm.svelte | 42 + frontend/src/lib/forms/WorldForm.svelte | 25 + frontend/src/lib/gallery/Gallery.svelte | 42 + frontend/src/lib/gallery/GalleryPage.svelte | 93 ++ frontend/src/lib/icons/Bookmark.svelte | 10 + frontend/src/lib/icons/Female.svelte | 1 + frontend/src/lib/icons/Location.svelte | 1 + frontend/src/lib/icons/Male.svelte | 1 + frontend/src/lib/icons/Organized.svelte | 21 + frontend/src/lib/icons/Star.svelte | 25 + frontend/src/lib/icons/Transgender.svelte | 1 + frontend/src/lib/navigation/Link.svelte | 20 + frontend/src/lib/navigation/Navigation.svelte | 5 + frontend/src/lib/pagination/Pagination.svelte | 45 + frontend/src/lib/pagination/Target.svelte | 21 + frontend/src/lib/pills/AssociationPill.svelte | 30 + frontend/src/lib/pills/ComicPills.svelte | 37 + frontend/src/lib/pills/Pill.svelte | 40 + frontend/src/lib/pills/TagPill.svelte | 40 + frontend/src/lib/reader/PageView.svelte | 67 + frontend/src/lib/reader/Reader.svelte | 39 + frontend/src/lib/reader/ReaderPage.svelte | 24 + .../lib/reader/components/CloseReaderButton.svelte | 19 + .../lib/reader/components/ReaderMenuButton.svelte | 16 + frontend/src/lib/scraper/ComicScrapeForm.svelte | 138 ++ .../lib/scraper/components/SelectorButton.svelte | 22 + .../lib/scraper/components/SelectorGroup.svelte | 35 + .../src/lib/scraper/components/SelectorItem.svelte | 24 + frontend/src/lib/selection/Selectable.svelte | 24 + frontend/src/lib/selection/SelectionOverlay.svelte | 34 + frontend/src/lib/tabs/AddOverlay.svelte | 36 + frontend/src/lib/tabs/ArchiveDelete.svelte | 42 + frontend/src/lib/tabs/ArchiveDetails.svelte | 50 + frontend/src/lib/tabs/ArchiveEdit.svelte | 68 + frontend/src/lib/tabs/ComicDelete.svelte | 34 + frontend/src/lib/tabs/ComicDetails.svelte | 121 ++ frontend/src/lib/tabs/DetailsHeader.svelte | 11 + frontend/src/lib/tabs/DetailsSection.svelte | 10 + frontend/src/lib/tabs/Tab.svelte | 14 + frontend/src/lib/tabs/Tabs.svelte | 40 + frontend/src/lib/toolbar/DeleteSelection.svelte | 26 + frontend/src/lib/toolbar/EditSelection.svelte | 29 + frontend/src/lib/toolbar/FilterBookmarked.svelte | 24 + frontend/src/lib/toolbar/FilterFavourites.svelte | 24 + frontend/src/lib/toolbar/FilterOrganized.svelte | 30 + frontend/src/lib/toolbar/MarkBookmark.svelte | 27 + frontend/src/lib/toolbar/MarkFavourite.svelte | 27 + frontend/src/lib/toolbar/MarkOrganized.svelte | 27 + frontend/src/lib/toolbar/MarkSelection.svelte | 24 + frontend/src/lib/toolbar/Search.svelte | 21 + frontend/src/lib/toolbar/SelectItems.svelte | 19 + frontend/src/lib/toolbar/SelectSort.svelte | 61 + frontend/src/lib/toolbar/SelectionControls.svelte | 57 + .../src/lib/toolbar/ToggleAdvancedFilters.svelte | 40 + frontend/src/lib/toolbar/Toolbar.svelte | 42 + frontend/src/routes/+layout.svelte | 95 ++ frontend/src/routes/+layout.ts | 1 + frontend/src/routes/+page.svelte | 66 + frontend/src/routes/archives/+page.svelte | 119 ++ frontend/src/routes/archives/+page.ts | 12 + frontend/src/routes/archives/[id]/+page.svelte | 99 ++ frontend/src/routes/archives/[id]/+page.ts | 5 + frontend/src/routes/artists/+page.svelte | 101 ++ frontend/src/routes/artists/+page.ts | 12 + frontend/src/routes/characters/+page.svelte | 101 ++ frontend/src/routes/characters/+page.ts | 12 + frontend/src/routes/circles/+page.svelte | 101 ++ frontend/src/routes/circles/+page.ts | 12 + frontend/src/routes/comics/+page.svelte | 116 ++ frontend/src/routes/comics/+page.ts | 12 + frontend/src/routes/comics/[id]/+page.svelte | 176 ++ frontend/src/routes/comics/[id]/+page.ts | 5 + frontend/src/routes/namespaces/+page.svelte | 101 ++ frontend/src/routes/namespaces/+page.ts | 12 + frontend/src/routes/tags/+page.svelte | 109 ++ frontend/src/routes/tags/+page.ts | 12 + frontend/src/routes/worlds/+page.svelte | 102 ++ frontend/src/routes/worlds/+page.ts | 12 + 155 files changed, 9175 insertions(+) create mode 100644 frontend/src/app.css create mode 100644 frontend/src/app.d.ts create mode 100644 frontend/src/app.html create mode 100644 frontend/src/gql/Mutations.ts create mode 100644 frontend/src/gql/Queries.ts create mode 100644 frontend/src/gql/Utils.ts create mode 100644 frontend/src/gql/graphql.ts create mode 100644 frontend/src/lib/Actions.ts create mode 100644 frontend/src/lib/Enums.ts create mode 100644 frontend/src/lib/Filter.ts create mode 100644 frontend/src/lib/Meta.ts create mode 100644 frontend/src/lib/Navigation.ts create mode 100644 frontend/src/lib/Pagination.ts create mode 100644 frontend/src/lib/Reader.ts create mode 100644 frontend/src/lib/Scraper.ts create mode 100644 frontend/src/lib/Selection.ts create mode 100644 frontend/src/lib/Shortcuts.ts create mode 100644 frontend/src/lib/Sort.ts create mode 100644 frontend/src/lib/Tabs.ts create mode 100644 frontend/src/lib/Toasts.ts create mode 100644 frontend/src/lib/Transitions.ts create mode 100644 frontend/src/lib/Update.ts create mode 100644 frontend/src/lib/Utils.ts create mode 100644 frontend/src/lib/assets/logo.webp create mode 100644 frontend/src/lib/components/AddButton.svelte create mode 100644 frontend/src/lib/components/Badge.svelte create mode 100644 frontend/src/lib/components/BookmarkButton.svelte create mode 100644 frontend/src/lib/components/Card.svelte create mode 100644 frontend/src/lib/components/Cardlet.svelte create mode 100644 frontend/src/lib/components/DeleteButton.svelte create mode 100644 frontend/src/lib/components/Dialog.svelte create mode 100644 frontend/src/lib/components/Dropdown.svelte create mode 100644 frontend/src/lib/components/Empty.svelte create mode 100644 frontend/src/lib/components/Expander.svelte create mode 100644 frontend/src/lib/components/Guard.svelte create mode 100644 frontend/src/lib/components/Head.svelte create mode 100644 frontend/src/lib/components/Labelled.svelte create mode 100644 frontend/src/lib/components/LabelledBlock.svelte create mode 100644 frontend/src/lib/components/OrganizedButton.svelte create mode 100644 frontend/src/lib/components/RefreshButton.svelte create mode 100644 frontend/src/lib/components/RemovePageButton.svelte create mode 100644 frontend/src/lib/components/Select.svelte create mode 100644 frontend/src/lib/components/Spinner.svelte create mode 100644 frontend/src/lib/components/SubmitButton.svelte create mode 100644 frontend/src/lib/components/Titlebar.svelte create mode 100644 frontend/src/lib/containers/Cardlets.svelte create mode 100644 frontend/src/lib/containers/Cards.svelte create mode 100644 frontend/src/lib/containers/Carousel.svelte create mode 100644 frontend/src/lib/containers/Column.svelte create mode 100644 frontend/src/lib/containers/Grid.svelte create mode 100644 frontend/src/lib/dialogs/AddArtist.svelte create mode 100644 frontend/src/lib/dialogs/AddCharacter.svelte create mode 100644 frontend/src/lib/dialogs/AddCircle.svelte create mode 100644 frontend/src/lib/dialogs/AddNamespace.svelte create mode 100644 frontend/src/lib/dialogs/AddTag.svelte create mode 100644 frontend/src/lib/dialogs/AddWorld.svelte create mode 100644 frontend/src/lib/dialogs/ConfirmDeletion.svelte create mode 100644 frontend/src/lib/dialogs/EditArtist.svelte create mode 100644 frontend/src/lib/dialogs/EditCharacter.svelte create mode 100644 frontend/src/lib/dialogs/EditCircle.svelte create mode 100644 frontend/src/lib/dialogs/EditNamespace.svelte create mode 100644 frontend/src/lib/dialogs/EditTag.svelte create mode 100644 frontend/src/lib/dialogs/EditWorld.svelte create mode 100644 frontend/src/lib/dialogs/UpdateComics.svelte create mode 100644 frontend/src/lib/dialogs/UpdateTags.svelte create mode 100644 frontend/src/lib/dialogs/components/UpdateModeSelector.svelte create mode 100644 frontend/src/lib/filter/ComicFilterForm.svelte create mode 100644 frontend/src/lib/filter/TagFilterForm.svelte create mode 100644 frontend/src/lib/filter/components/ComicFilterGroup.svelte create mode 100644 frontend/src/lib/filter/components/Filter.svelte create mode 100644 frontend/src/lib/filter/components/FilterForm.svelte create mode 100644 frontend/src/lib/filter/components/TagFilterGroup.svelte create mode 100644 frontend/src/lib/forms/ArtistForm.svelte create mode 100644 frontend/src/lib/forms/CharacterForm.svelte create mode 100644 frontend/src/lib/forms/CircleForm.svelte create mode 100644 frontend/src/lib/forms/ComicForm.svelte create mode 100644 frontend/src/lib/forms/NamespaceForm.svelte create mode 100644 frontend/src/lib/forms/TagForm.svelte create mode 100644 frontend/src/lib/forms/WorldForm.svelte create mode 100644 frontend/src/lib/gallery/Gallery.svelte create mode 100644 frontend/src/lib/gallery/GalleryPage.svelte create mode 100644 frontend/src/lib/icons/Bookmark.svelte create mode 100644 frontend/src/lib/icons/Female.svelte create mode 100644 frontend/src/lib/icons/Location.svelte create mode 100644 frontend/src/lib/icons/Male.svelte create mode 100644 frontend/src/lib/icons/Organized.svelte create mode 100644 frontend/src/lib/icons/Star.svelte create mode 100644 frontend/src/lib/icons/Transgender.svelte create mode 100644 frontend/src/lib/navigation/Link.svelte create mode 100644 frontend/src/lib/navigation/Navigation.svelte create mode 100644 frontend/src/lib/pagination/Pagination.svelte create mode 100644 frontend/src/lib/pagination/Target.svelte create mode 100644 frontend/src/lib/pills/AssociationPill.svelte create mode 100644 frontend/src/lib/pills/ComicPills.svelte create mode 100644 frontend/src/lib/pills/Pill.svelte create mode 100644 frontend/src/lib/pills/TagPill.svelte create mode 100644 frontend/src/lib/reader/PageView.svelte create mode 100644 frontend/src/lib/reader/Reader.svelte create mode 100644 frontend/src/lib/reader/ReaderPage.svelte create mode 100644 frontend/src/lib/reader/components/CloseReaderButton.svelte create mode 100644 frontend/src/lib/reader/components/ReaderMenuButton.svelte create mode 100644 frontend/src/lib/scraper/ComicScrapeForm.svelte create mode 100644 frontend/src/lib/scraper/components/SelectorButton.svelte create mode 100644 frontend/src/lib/scraper/components/SelectorGroup.svelte create mode 100644 frontend/src/lib/scraper/components/SelectorItem.svelte create mode 100644 frontend/src/lib/selection/Selectable.svelte create mode 100644 frontend/src/lib/selection/SelectionOverlay.svelte create mode 100644 frontend/src/lib/tabs/AddOverlay.svelte create mode 100644 frontend/src/lib/tabs/ArchiveDelete.svelte create mode 100644 frontend/src/lib/tabs/ArchiveDetails.svelte create mode 100644 frontend/src/lib/tabs/ArchiveEdit.svelte create mode 100644 frontend/src/lib/tabs/ComicDelete.svelte create mode 100644 frontend/src/lib/tabs/ComicDetails.svelte create mode 100644 frontend/src/lib/tabs/DetailsHeader.svelte create mode 100644 frontend/src/lib/tabs/DetailsSection.svelte create mode 100644 frontend/src/lib/tabs/Tab.svelte create mode 100644 frontend/src/lib/tabs/Tabs.svelte create mode 100644 frontend/src/lib/toolbar/DeleteSelection.svelte create mode 100644 frontend/src/lib/toolbar/EditSelection.svelte create mode 100644 frontend/src/lib/toolbar/FilterBookmarked.svelte create mode 100644 frontend/src/lib/toolbar/FilterFavourites.svelte create mode 100644 frontend/src/lib/toolbar/FilterOrganized.svelte create mode 100644 frontend/src/lib/toolbar/MarkBookmark.svelte create mode 100644 frontend/src/lib/toolbar/MarkFavourite.svelte create mode 100644 frontend/src/lib/toolbar/MarkOrganized.svelte create mode 100644 frontend/src/lib/toolbar/MarkSelection.svelte create mode 100644 frontend/src/lib/toolbar/Search.svelte create mode 100644 frontend/src/lib/toolbar/SelectItems.svelte create mode 100644 frontend/src/lib/toolbar/SelectSort.svelte create mode 100644 frontend/src/lib/toolbar/SelectionControls.svelte create mode 100644 frontend/src/lib/toolbar/ToggleAdvancedFilters.svelte create mode 100644 frontend/src/lib/toolbar/Toolbar.svelte create mode 100644 frontend/src/routes/+layout.svelte create mode 100644 frontend/src/routes/+layout.ts create mode 100644 frontend/src/routes/+page.svelte create mode 100644 frontend/src/routes/archives/+page.svelte create mode 100644 frontend/src/routes/archives/+page.ts create mode 100644 frontend/src/routes/archives/[id]/+page.svelte create mode 100644 frontend/src/routes/archives/[id]/+page.ts create mode 100644 frontend/src/routes/artists/+page.svelte create mode 100644 frontend/src/routes/artists/+page.ts create mode 100644 frontend/src/routes/characters/+page.svelte create mode 100644 frontend/src/routes/characters/+page.ts create mode 100644 frontend/src/routes/circles/+page.svelte create mode 100644 frontend/src/routes/circles/+page.ts create mode 100644 frontend/src/routes/comics/+page.svelte create mode 100644 frontend/src/routes/comics/+page.ts create mode 100644 frontend/src/routes/comics/[id]/+page.svelte create mode 100644 frontend/src/routes/comics/[id]/+page.ts create mode 100644 frontend/src/routes/namespaces/+page.svelte create mode 100644 frontend/src/routes/namespaces/+page.ts create mode 100644 frontend/src/routes/tags/+page.svelte create mode 100644 frontend/src/routes/tags/+page.ts create mode 100644 frontend/src/routes/worlds/+page.svelte create mode 100644 frontend/src/routes/worlds/+page.ts (limited to 'frontend/src') diff --git a/frontend/src/app.css b/frontend/src/app.css new file mode 100644 index 0000000..13a7883 --- /dev/null +++ b/frontend/src/app.css @@ -0,0 +1,180 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + body { + display: grid; + grid-template-columns: 3rem 1fr; + scrollbar-color: theme('colors.gray.500') rgba(0, 0, 0, 0); + font-family: 'Noto Sans', sans-serif; + } + + input, + textarea { + @apply w-full rounded bg-slate-900 p-[.4rem] focus:outline focus:outline-1 focus:outline-slate-500; + } + + label { + @apply mb-0.5 inline-block; + } + + form { + @apply flex flex-col gap-4 p-px text-sm; + } + + .rounded-group > * { + @apply rounded-none first:rounded-l-sm last:rounded-r-sm !important; + } + + .rounded-group-start > * { + @apply rounded-none first:rounded-l-sm !important; + } + + .rounded-group-end > * { + @apply rounded-none last:rounded-r-sm !important; + } + + .grid-labels { + @apply grid grid-cols-[1fr_5fr] gap-2; + } + + header { + grid-area: header; + } + + aside { + overflow: auto; + grid-area: sidebar; + @apply lg:w-[28rem] xl:w-[32rem] min-[1920px]:w-[36rem]; + } + + main { + grid-area: main; + } +} + +@layer components { + .btn { + @apply flex items-center justify-center rounded-sm p-2 text-white transition-colors disabled:opacity-40; + } + + .btn-xs { + @apply btn rounded-sm p-0.5 py-0; + } + + .btn-blue { + @apply btn bg-blue-700 hover:bg-blue-600 disabled:bg-blue-900; + } + + .btn-rose { + @apply btn bg-rose-700 hover:bg-rose-600 disabled:bg-rose-900; + } + + .btn-slate { + @apply btn bg-slate-700 hover:bg-slate-600 disabled:bg-slate-800; + } + + .btn-indigo { + @apply btn bg-indigo-700 hover:bg-indigo-600 disabled:bg-indigo-800; + } + + .icon-xs { + @apply text-[18px]; + } + + .icon-base { + @apply text-[24px]; + } + + .icon-lg { + @apply text-[28px]; + } + + .icon-2xl { + @apply text-[48px]; + } + + .icon-gray.hoverable:hover { + @apply text-gray-200/80; + } + + .icon-gray.dim { + @apply text-gray-100/40; + } + + .icon-yellow { + @apply text-yellow-300; + } + + .icon-yellow.hoverable:hover { + @apply text-yellow-300/80; + } + + .icon-yellow.dim { + @apply text-slate-100/40; + } +} + +@layer utilities { + .toggled { + @apply bg-indigo-700 hover:bg-indigo-600; + } + + .floating { + @apply rounded-full bg-black/50 p-1 text-white/80 backdrop-blur-sm hover:bg-black/50 hover:text-white; + } + + .ellipsis-nowrap { + @apply overflow-hidden text-ellipsis whitespace-nowrap; + } + + .rounded-inherit { + border-radius: inherit; + } + + .grid-card-h { + grid-template-columns: 210px 1fr; + grid-template-rows: 300px; + } + + .grid-card-cover-only { + @apply !grid-card-h; + } + + .grid-card-v { + grid-template-columns: 1fr; + grid-template-rows: 500px 1fr; + } +} + +.svelecte-control { + --sv-item-color: inherit !important; + --sv-bg: theme(colors.slate.900) !important; + --sv-disabled-bg: theme(colors.slate.900) !important; + --sv-border: 1px solid rgba(0, 0, 0, 0) !important; + --sv-disabled-border-color: rgba(0, 0, 0, 0) !important; + --sv-border-color: theme(colors.slate.600) !important; + --sv-active-border: 1px solid theme(colors.slate.500) !important; + --sv-item-selected-bg: theme(colors.indigo.800) !important; + --sv-item-active-bg: theme(colors.indigo.800) !important; + --sv-highlight-bg: none !important; + --sv-item-btn-bg-hover: theme(colors.rose.900) !important; + --sv-placeholder-color: theme(colors.gray.500) !important; +} + +.svelecte-control input { + @apply !h-8; +} + +.exclude .svelecte-control { + --sv-border: 1px solid theme('colors.red.900') !important; + --sv-active-border: 1px solid theme('colors.red.700') !important; + + --sv-item-selected-bg: theme(colors.rose.800) !important; + --sv-item-active-bg: theme(colors.rose.800) !important; +} + +.sv-dropdown { + @apply my-1 !bg-slate-950; +} diff --git a/frontend/src/app.d.ts b/frontend/src/app.d.ts new file mode 100644 index 0000000..41634fe --- /dev/null +++ b/frontend/src/app.d.ts @@ -0,0 +1,12 @@ +/// +/// + +// See https://kit.svelte.dev/docs/types#app +// for information about these interfaces +// and what to do when importing types +declare namespace App { + // interface Locals {} + // interface PageData {} + // interface Error {} + // interface Platform {} +} diff --git a/frontend/src/app.html b/frontend/src/app.html new file mode 100644 index 0000000..6303945 --- /dev/null +++ b/frontend/src/app.html @@ -0,0 +1,13 @@ + + + + + + + hircine + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/frontend/src/gql/Mutations.ts b/frontend/src/gql/Mutations.ts new file mode 100644 index 0000000..d669b25 --- /dev/null +++ b/frontend/src/gql/Mutations.ts @@ -0,0 +1,244 @@ +import { toastSuccess } from '$lib/Toasts'; +import { + Client, + type AnyVariables, + type OperationResult, + type OperationResultSource +} from '@urql/svelte'; +import { isError, isSuccess, type RequiredName } from './Utils'; +import * as gql from './graphql'; + +export type DeleteMutation = (client: Client, args: { ids: number | number[] }) => Promise; + +const comicTypes = ['Comic']; +const comicUpsertTypes = comicTypes.concat([ + 'Artist', + 'Character', + 'Circle', + 'Namespace', + 'Collection', + 'Tag', + 'World' +]); + +function handleResult(result: OperationResult): Promise { + return new Promise((resolve, reject) => { + if (result.error) { + return reject(`${result.error.name}: ${result.error.message}`); + } + + if (!result.data) { + return reject('Mutation resolved, but result contains no data.'); + } + + const obj = Object.values(result.data)[0]; + + if (isError(obj)) { + reject(obj.message); + } else if (isSuccess(obj)) { + toastSuccess(obj.message); + resolve(result.data); + } + + reject('This should not happen.'); + }); +} + +async function handleMutation( + mutation: OperationResultSource> +) { + return await mutation.toPromise().then(handleResult); +} + +export async function addComic(client: Client, args: gql.AddComicMutationVariables) { + return await handleMutation( + client.mutation(gql.AddComicDocument, args, { + additionalTypenames: comicTypes.concat('Archive', 'Page') + }) + ); +} + +export async function updateComics(client: Client, args: gql.UpdateComicsMutationVariables) { + return await handleMutation( + client.mutation(gql.UpdateComicsDocument, args, { + additionalTypenames: comicTypes + }) + ); +} + +export async function upsertComics(client: Client, args: gql.UpsertComicsMutationVariables) { + return await handleMutation( + client.mutation(gql.UpsertComicsDocument, args, { + additionalTypenames: comicUpsertTypes + }) + ); +} + +export async function updateArchives(client: Client, args: gql.UpdateArchivesMutationVariables) { + return await handleMutation( + client.mutation(gql.UpdateArchivesDocument, args, { + additionalTypenames: ['Archive'] + }) + ); +} + +export async function deleteArchives(client: Client, args: gql.DeleteArchivesMutationVariables) { + return await handleMutation( + client.mutation(gql.DeleteArchivesDocument, args, { + additionalTypenames: comicTypes.concat('Archive') + }) + ); +} + +export async function deleteComics(client: Client, args: gql.DeleteComicsMutationVariables) { + return await handleMutation( + client.mutation(gql.DeleteComicsDocument, args, { additionalTypenames: comicTypes }) + ); +} + +export async function addArtist(client: Client, args: gql.AddArtistMutationVariables) { + return await handleMutation( + client.mutation(gql.AddArtistDocument, args, { additionalTypenames: ['ArtistFilterResult'] }) + ); +} + +export async function updateArtists(client: Client, args: gql.UpdateArtistsMutationVariables) { + return await handleMutation( + client.mutation(gql.UpdateArtistsDocument, args, { additionalTypenames: ['Artist'] }) + ); +} + +export async function deleteArtists(client: Client, args: gql.DeleteArtistsMutationVariables) { + return await handleMutation( + client.mutation(gql.DeleteArtistsDocument, args, { + additionalTypenames: ['Artist'] + }) + ); +} + +export async function addCharacter(client: Client, args: gql.AddCharacterMutationVariables) { + return await handleMutation( + client.mutation(gql.AddCharacterDocument, args, { + additionalTypenames: ['CharacterFilterResult'] + }) + ); +} + +export async function updateCharacters( + client: Client, + args: gql.UpdateCharactersMutationVariables +) { + return await handleMutation( + client.mutation(gql.UpdateCharactersDocument, args, { additionalTypenames: ['Character'] }) + ); +} + +export async function deleteCharacters( + client: Client, + args: gql.DeleteCharactersMutationVariables +) { + return await handleMutation( + client.mutation(gql.DeleteCharactersDocument, args, { + additionalTypenames: ['Character'] + }) + ); +} + +export async function addCircle(client: Client, args: gql.AddCircleMutationVariables) { + return await handleMutation( + client.mutation(gql.AddCircleDocument, args, { additionalTypenames: ['CircleFilterResult'] }) + ); +} + +export async function updateCircles(client: Client, args: gql.UpdateCirclesMutationVariables) { + return await handleMutation( + client.mutation(gql.UpdateCirclesDocument, args, { additionalTypenames: ['Circle'] }) + ); +} + +export async function deleteCircles(client: Client, args: gql.DeleteCirclesMutationVariables) { + return await handleMutation( + client.mutation(gql.DeleteCirclesDocument, args, { + additionalTypenames: ['Circle'] + }) + ); +} + +export async function addNamespace(client: Client, args: gql.AddNamespaceMutationVariables) { + return await handleMutation( + client.mutation(gql.AddNamespaceDocument, args, { + additionalTypenames: ['NamespaceFilterResult', 'ComicTagFilterResult'] + }) + ); +} + +export async function updateNamespaces( + client: Client, + args: gql.UpdateNamespacesMutationVariables +) { + return await handleMutation( + client.mutation(gql.UpdateNamespacesDocument, args, { + additionalTypenames: ['Namespace', 'ComicTag'] + }) + ); +} + +export async function deleteNamespaces( + client: Client, + args: gql.DeleteNamespacesMutationVariables +) { + return await handleMutation( + client.mutation(gql.DeleteNamespacesDocument, args, { + additionalTypenames: ['NamespaceFilterResult', 'ComicTag'] + }) + ); +} + +export async function addTag(client: Client, args: gql.AddTagMutationVariables) { + return await handleMutation( + client.mutation(gql.AddTagDocument, args, { + additionalTypenames: ['TagFilterResult', 'ComicTagFilterResult'] + }) + ); +} + +export async function updateTags(client: Client, args: gql.UpdateTagsMutationVariables) { + return await handleMutation( + client.mutation(gql.UpdateTagsDocument, args, { + additionalTypenames: ['Tag', 'ComicTag'] + }) + ); +} + +export async function deleteTags(client: Client, args: gql.DeleteTagsMutationVariables) { + return await handleMutation( + client.mutation(gql.DeleteTagsDocument, args, { + additionalTypenames: ['TagFilterResult', 'ComicTag'] + }) + ); +} + +export async function addWorld(client: Client, args: gql.AddWorldMutationVariables) { + return await handleMutation( + client.mutation(gql.AddWorldDocument, args, { additionalTypenames: ['WorldFilterResult'] }) + ); +} + +export async function updateWorlds(client: Client, args: gql.UpdateWorldsMutationVariables) { + return await handleMutation( + client.mutation(gql.UpdateWorldsDocument, args, { additionalTypenames: ['World'] }) + ); +} + +export async function deleteWorlds(client: Client, args: gql.DeleteWorldsMutationVariables) { + return await handleMutation( + client.mutation(gql.DeleteWorldsDocument, args, { additionalTypenames: ['World'] }) + ); +} + +export type ArtistInput = RequiredName; +export type CharacterInput = RequiredName; +export type CircleInput = RequiredName; +export type NamespaceInput = RequiredName; +export type TagInput = RequiredName; +export type WorldInput = RequiredName; diff --git a/frontend/src/gql/Queries.ts b/frontend/src/gql/Queries.ts new file mode 100644 index 0000000..cc9dd4c --- /dev/null +++ b/frontend/src/gql/Queries.ts @@ -0,0 +1,243 @@ +import { Client, queryStore, type OperationResult } from '@urql/svelte'; +import { isError } from './Utils'; +import * as gql from './graphql'; + +function handleResult(result: OperationResult): Promise { + return new Promise((resolve, reject) => { + if (result.error) { + return reject(`${result.error.name}: ${result.error.message}`); + } + + if (!result.data) { + return reject('Query resolved, but result contains no data.'); + } + + const data = Object.values(result.data)[0]; + + if (isError(data)) { + reject(data.message); + } else { + resolve(data); + } + + reject('This should not happen.'); + }); +} + +export function comicTagList(client: Client, args?: gql.ComicTagListQueryVariables) { + return queryStore({ + client: client, + query: gql.ComicTagListDocument, + context: { + additionalTypenames: ['Namespace', 'Tag'] + }, + variables: args + }); +} + +export function artistList(client: Client) { + return queryStore({ + client: client, + query: gql.ArtistListDocument, + context: { + additionalTypenames: ['Artist'] + } + }); +} + +export function characterList(client: Client) { + return queryStore({ + client: client, + query: gql.CharacterListDocument, + context: { + additionalTypenames: ['Character'] + } + }); +} + +export function circleList(client: Client) { + return queryStore({ + client: client, + query: gql.CircleListDocument, + context: { + additionalTypenames: ['Circle'] + } + }); +} + +export function worldList(client: Client) { + return queryStore({ + client: client, + query: gql.WorldListDocument, + context: { + additionalTypenames: ['World'] + } + }); +} + +export function namespaceList(client: Client) { + return queryStore({ + client: client, + query: gql.NamespaceListDocument, + context: { + additionalTypenames: ['Namespace'] + } + }); +} + +export function comicScrapersQuery(client: Client, args: gql.ComicScrapersQueryVariables) { + return queryStore({ + client: client, + query: gql.ComicScrapersDocument, + variables: args, + context: { + additionalTypenames: ['Comic'] + } + }); +} + +export async function scrapeComic(client: Client, args: gql.ScrapeComicQueryVariables) { + return await client + .query(gql.ScrapeComicDocument, args, { additionalTypenames: ['Comic'] }) + .toPromise(); +} + +export function archiveQuery(client: Client, args: gql.ArchiveQueryVariables) { + return queryStore({ + client: client, + query: gql.ArchiveDocument, + variables: args, + context: { additionalTypenames: ['Archive'] } + }); +} + +export function archivesQuery(client: Client, args: gql.ArchivesQueryVariables) { + return queryStore({ + client: client, + query: gql.ArchivesDocument, + variables: args, + context: { additionalTypenames: ['Archive'] } + }); +} + +export function artistsQuery(client: Client, args?: gql.ArtistsQueryVariables) { + return queryStore({ + client: client, + query: gql.ArtistsDocument, + variables: args, + context: { additionalTypenames: ['Artist'] } + }); +} + +export function charactersQuery(client: Client, args?: gql.CharactersQueryVariables) { + return queryStore({ + client: client, + query: gql.CharactersDocument, + variables: args, + context: { additionalTypenames: ['Character'] } + }); +} + +export function circlesQuery(client: Client, args?: gql.CirclesQueryVariables) { + return queryStore({ + client: client, + query: gql.CirclesDocument, + variables: args, + context: { additionalTypenames: ['Circle'] } + }); +} + +export function comicQuery(client: Client, args: gql.ComicQueryVariables) { + return queryStore({ + client: client, + query: gql.ComicDocument, + variables: args, + context: { additionalTypenames: ['Comic'] } + }); +} + +export function comicsQuery(client: Client, args?: gql.ComicsQueryVariables) { + return queryStore({ + client: client, + query: gql.ComicsDocument, + variables: args, + context: { additionalTypenames: ['Comic'] } + }); +} + +export function namespacesQuery(client: Client, args?: gql.NamespacesQueryVariables) { + return queryStore({ + client: client, + query: gql.NamespacesDocument, + variables: args, + context: { additionalTypenames: ['Namespace'] } + }); +} + +export function tagsQuery(client: Client, args?: gql.TagsQueryVariables) { + return queryStore({ + client: client, + query: gql.TagsDocument, + variables: args, + context: { additionalTypenames: ['Tag'] } + }); +} + +export function worldsQuery(client: Client, args?: gql.WorldsQueryVariables) { + return queryStore({ + client: client, + query: gql.WorldsDocument, + variables: args, + context: { additionalTypenames: ['World'] } + }); +} + +export function frontpageQuery(client: Client) { + return queryStore({ + client: client, + query: gql.FrontpageDocument, + requestPolicy: 'network-only' + }); +} + +export function fetchArtist(client: Client, id: number) { + return client + .query(gql.ArtistDocument, { id }, { requestPolicy: 'cache-and-network' }) + .toPromise() + .then(handleResult); +} + +export function fetchCharacter(client: Client, id: number) { + return client + .query(gql.CharacterDocument, { id }, { requestPolicy: 'cache-and-network' }) + .toPromise() + .then(handleResult); +} + +export function fetchCircle(client: Client, id: number) { + return client + .query(gql.CircleDocument, { id }, { requestPolicy: 'cache-and-network' }) + .toPromise() + .then(handleResult); +} + +export function fetchNamespace(client: Client, id: number) { + return client + .query(gql.NamespaceDocument, { id }, { requestPolicy: 'cache-and-network' }) + .toPromise() + .then(handleResult); +} + +export function fetchTag(client: Client, id: number) { + return client + .query(gql.TagDocument, { id }, { requestPolicy: 'cache-and-network' }) + .toPromise() + .then(handleResult); +} + +export function fetchWorld(client: Client, id: number) { + return client + .query(gql.WorldDocument, { id }, { requestPolicy: 'cache-and-network' }) + .toPromise() + .then(handleResult); +} diff --git a/frontend/src/gql/Utils.ts b/frontend/src/gql/Utils.ts new file mode 100644 index 0000000..dd21bbe --- /dev/null +++ b/frontend/src/gql/Utils.ts @@ -0,0 +1,74 @@ +import equal from 'fast-deep-equal'; +import * as gql from './graphql'; + +export type OmitIdentifiers = Omit; +export type RequiredName = T & { name: string }; + +export function isSuccess(object: any): object is gql.Success { + if (object.__typename === undefined) { + return false; + } + + return object.__typename.endsWith('Success') && (object as gql.Success).message !== undefined; +} + +export function isError(object: any): object is gql.Error { + if (object.__typename === undefined) { + return false; + } + return object.__typename.endsWith('Error') && (object as gql.Error).message !== undefined; +} + +type Item = { + id: number | string; + name: string; +}; + +export function itemEquals(a: Item, b: Item) { + return a.name == b.name; +} + +function assocEquals(as: Item[], bs: Item[]) { + return equal( + as.map((a) => a.id), + bs.map((b) => b.id) + ); +} + +function stringEquals(a: string | null | undefined, b: string | null | undefined) { + return (a ? a : null) == (b ? b : null); +} + +export function tagEquals(a: gql.FullTag, b: gql.FullTag) { + return ( + itemEquals(a, b) && + stringEquals(a.description, b.description) && + assocEquals(a.namespaces, b.namespaces) + ); +} + +export function comicEquals( + a: gql.FullComicFragment | undefined, + b: gql.FullComicFragment | undefined +) { + if (a === undefined) return b === undefined; + if (b === undefined) return a === undefined; + + return ( + stringEquals(a.title, b.title) && + stringEquals(a.originalTitle, b.originalTitle) && + stringEquals(a.url, b.url) && + stringEquals(a.date, b.date) && + a.category == b.category && + a.rating == b.rating && + a.censorship == b.censorship && + a.language == b.language && + a.direction == b.direction && + a.layout == b.layout && + assocEquals(a.artists, b.artists) && + assocEquals(a.circles, b.circles) && + assocEquals(a.characters, b.characters) && + assocEquals(a.tags, b.tags) && + assocEquals(a.worlds, b.worlds) + ); +} diff --git a/frontend/src/gql/graphql.ts b/frontend/src/gql/graphql.ts new file mode 100644 index 0000000..139068c --- /dev/null +++ b/frontend/src/gql/graphql.ts @@ -0,0 +1,1764 @@ +import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; +export type Maybe = T | null; +export type InputMaybe = Maybe; +export type Exact = { [K in keyof T]: T[K] }; +export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; +export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; +export type MakeEmpty = { [_ in K]?: never }; +export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; +/** All built-in and custom scalars, mapped to their actual values */ +export type Scalars = { + ID: { input: string; output: string; } + String: { input: string; output: string; } + Boolean: { input: boolean; output: boolean; } + Int: { input: number; output: number; } + Float: { input: number; output: number; } + Date: { input: string; output: string; } + DateTime: { input: string; output: string; } +}; + +export type AddArtistInput = { + name: Scalars['String']['input']; +}; + +export type AddCharacterInput = { + name: Scalars['String']['input']; +}; + +export type AddCircleInput = { + name: Scalars['String']['input']; +}; + +export type AddComicInput = { + archive: ArchiveInput; + cover: CoverInput; + pages: UniquePagesInput; + title: Scalars['String']['input']; +}; + +export type AddComicResponse = AddComicSuccess | IdNotFoundError | InvalidParameterError | PageClaimedError | PageRemoteError; + +export type AddComicSuccess = Success & { + __typename?: 'AddComicSuccess'; + archivePagesRemaining: Scalars['Boolean']['output']; + id: Scalars['Int']['output']; + message: Scalars['String']['output']; +}; + +export type AddNamespaceInput = { + name: Scalars['String']['input']; + sortName?: InputMaybe; +}; + +export type AddResponse = AddSuccess | IdNotFoundError | InvalidParameterError | NameExistsError; + +export type AddSuccess = Success & { + __typename?: 'AddSuccess'; + id: Scalars['Int']['output']; + message: Scalars['String']['output']; +}; + +export type AddTagInput = { + description?: InputMaybe; + name: Scalars['String']['input']; + namespaces?: InputMaybe; +}; + +export type AddWorldInput = { + name: Scalars['String']['input']; +}; + +export type Archive = { + __typename?: 'Archive'; + cover: Image; + id: Scalars['Int']['output']; + name: Scalars['String']['output']; + organized: Scalars['Boolean']['output']; + pageCount: Scalars['Int']['output']; + path: Scalars['String']['output']; + size: Scalars['Int']['output']; +}; + +export type ArchiveFilter = { + organized?: InputMaybe; + path?: InputMaybe; +}; + +export type ArchiveFilterInput = { + exclude?: InputMaybe; + include?: InputMaybe; +}; + +export type ArchiveFilterResult = { + __typename?: 'ArchiveFilterResult'; + count: Scalars['Int']['output']; + edges: Array; +}; + +export type ArchiveInput = { + id: Scalars['Int']['input']; +}; + +export type ArchiveResponse = FullArchive | IdNotFoundError; + +export enum ArchiveSort { + CreatedAt = 'CREATED_AT', + PageCount = 'PAGE_COUNT', + Path = 'PATH', + Random = 'RANDOM', + Size = 'SIZE' +} + +export type ArchiveSortInput = { + direction?: InputMaybe; + on: ArchiveSort; + seed?: InputMaybe; +}; + +export type Artist = { + __typename?: 'Artist'; + id: Scalars['Int']['output']; + name: Scalars['String']['output']; +}; + +export type ArtistFilter = { + name?: InputMaybe; +}; + +export type ArtistFilterInput = { + exclude?: InputMaybe; + include?: InputMaybe; +}; + +export type ArtistFilterResult = { + __typename?: 'ArtistFilterResult'; + count: Scalars['Int']['output']; + edges: Array; +}; + +export type ArtistResponse = Artist | IdNotFoundError; + +export enum ArtistSort { + CreatedAt = 'CREATED_AT', + Name = 'NAME', + Random = 'RANDOM', + UpdatedAt = 'UPDATED_AT' +} + +export type ArtistSortInput = { + direction?: InputMaybe; + on: ArtistSort; + seed?: InputMaybe; +}; + +export type ArtistsUpdateInput = { + ids: Array; + options?: InputMaybe; +}; + +export type ArtistsUpsertInput = { + names?: Array; + options?: InputMaybe; +}; + +export type AssociationFilter = { + all?: InputMaybe>; + any?: InputMaybe>; + empty?: InputMaybe; + exact?: InputMaybe>; +}; + +export enum Category { + Artbook = 'ARTBOOK', + Comic = 'COMIC', + Doujinshi = 'DOUJINSHI', + GameCg = 'GAME_CG', + ImageSet = 'IMAGE_SET', + Manga = 'MANGA', + VariantSet = 'VARIANT_SET', + Webtoon = 'WEBTOON' +} + +export type CategoryFilter = { + any?: InputMaybe>; + empty?: InputMaybe; +}; + +export enum Censorship { + Bar = 'BAR', + Full = 'FULL', + Mosaic = 'MOSAIC', + None = 'NONE' +} + +export type CensorshipFilter = { + any?: InputMaybe>; + empty?: InputMaybe; +}; + +export type Character = { + __typename?: 'Character'; + id: Scalars['Int']['output']; + name: Scalars['String']['output']; +}; + +export type CharacterFilter = { + name?: InputMaybe; +}; + +export type CharacterFilterInput = { + exclude?: InputMaybe; + include?: InputMaybe; +}; + +export type CharacterFilterResult = { + __typename?: 'CharacterFilterResult'; + count: Scalars['Int']['output']; + edges: Array; +}; + +export type CharacterResponse = Character | IdNotFoundError; + +export enum CharacterSort { + CreatedAt = 'CREATED_AT', + Name = 'NAME', + Random = 'RANDOM', + UpdatedAt = 'UPDATED_AT' +} + +export type CharacterSortInput = { + direction?: InputMaybe; + on: CharacterSort; + seed?: InputMaybe; +}; + +export type CharactersUpdateInput = { + ids: Array; + options?: InputMaybe; +}; + +export type CharactersUpsertInput = { + names?: Array; + options?: InputMaybe; +}; + +export type Circle = { + __typename?: 'Circle'; + id: Scalars['Int']['output']; + name: Scalars['String']['output']; +}; + +export type CircleFilter = { + name?: InputMaybe; +}; + +export type CircleFilterInput = { + exclude?: InputMaybe; + include?: InputMaybe; +}; + +export type CircleFilterResult = { + __typename?: 'CircleFilterResult'; + count: Scalars['Int']['output']; + edges: Array; +}; + +export type CircleResponse = Circle | IdNotFoundError; + +export enum CircleSort { + CreatedAt = 'CREATED_AT', + Name = 'NAME', + Random = 'RANDOM', + UpdatedAt = 'UPDATED_AT' +} + +export type CircleSortInput = { + direction?: InputMaybe; + on: CircleSort; + seed?: InputMaybe; +}; + +export type CirclesUpdateInput = { + ids: Array; + options?: InputMaybe; +}; + +export type CirclesUpsertInput = { + names?: Array; + options?: InputMaybe; +}; + +export type Comic = { + __typename?: 'Comic'; + artists: Array; + bookmarked: Scalars['Boolean']['output']; + category?: Maybe; + censorship?: Maybe; + characters: Array; + circles: Array; + cover: Image; + date?: Maybe; + favourite: Scalars['Boolean']['output']; + id: Scalars['Int']['output']; + language?: Maybe; + organized: Scalars['Boolean']['output']; + originalTitle?: Maybe; + pageCount: Scalars['Int']['output']; + rating?: Maybe; + tags: Array; + title: Scalars['String']['output']; + worlds: Array; +}; + +export type ComicFilter = { + artists?: InputMaybe; + bookmarked?: InputMaybe; + category?: InputMaybe; + censorship?: InputMaybe; + characters?: InputMaybe; + circles?: InputMaybe; + favourite?: InputMaybe; + language?: InputMaybe; + organized?: InputMaybe; + originalTitle?: InputMaybe; + rating?: InputMaybe; + tags?: InputMaybe; + title?: InputMaybe; + url?: InputMaybe; + worlds?: InputMaybe; +}; + +export type ComicFilterInput = { + exclude?: InputMaybe; + include?: InputMaybe; +}; + +export type ComicFilterResult = { + __typename?: 'ComicFilterResult'; + count: Scalars['Int']['output']; + edges: Array; +}; + +export type ComicResponse = FullComic | IdNotFoundError; + +export type ComicScraper = { + __typename?: 'ComicScraper'; + id: Scalars['String']['output']; + name: Scalars['String']['output']; +}; + +export enum ComicSort { + CreatedAt = 'CREATED_AT', + Date = 'DATE', + OriginalTitle = 'ORIGINAL_TITLE', + PageCount = 'PAGE_COUNT', + Random = 'RANDOM', + TagCount = 'TAG_COUNT', + Title = 'TITLE', + UpdatedAt = 'UPDATED_AT' +} + +export type ComicSortInput = { + direction?: InputMaybe; + on: ComicSort; + seed?: InputMaybe; +}; + +export type ComicTag = { + __typename?: 'ComicTag'; + description?: Maybe; + id: Scalars['String']['output']; + name: Scalars['String']['output']; +}; + +export type ComicTagFilterResult = { + __typename?: 'ComicTagFilterResult'; + count: Scalars['Int']['output']; + edges: Array; +}; + +export type ComicTagsUpdateInput = { + ids?: Array; + options?: InputMaybe; +}; + +export type ComicTagsUpsertInput = { + names?: Array; + options?: InputMaybe; +}; + +export type CoverInput = { + id: Scalars['Int']['input']; +}; + +export type CoverUpdateInput = { + id: Scalars['Int']['input']; +}; + +export type DeleteResponse = DeleteSuccess | IdNotFoundError; + +export type DeleteSuccess = Success & { + __typename?: 'DeleteSuccess'; + message: Scalars['String']['output']; +}; + +export enum Direction { + LeftToRight = 'LEFT_TO_RIGHT', + RightToLeft = 'RIGHT_TO_LEFT' +} + +export type Error = { + message: Scalars['String']['output']; +}; + +export type FullArchive = { + __typename?: 'FullArchive'; + comics: Array; + cover: Image; + createdAt: Scalars['DateTime']['output']; + id: Scalars['Int']['output']; + mtime: Scalars['DateTime']['output']; + name: Scalars['String']['output']; + organized: Scalars['Boolean']['output']; + pageCount: Scalars['Int']['output']; + pages: Array; + path: Scalars['String']['output']; + size: Scalars['Int']['output']; +}; + +export type FullComic = { + __typename?: 'FullComic'; + archive: Archive; + artists: Array; + bookmarked: Scalars['Boolean']['output']; + category?: Maybe; + censorship?: Maybe; + characters: Array; + circles: Array; + cover: Image; + createdAt: Scalars['DateTime']['output']; + date?: Maybe; + direction: Direction; + favourite: Scalars['Boolean']['output']; + id: Scalars['Int']['output']; + language?: Maybe; + layout: Layout; + organized: Scalars['Boolean']['output']; + originalTitle?: Maybe; + pageCount: Scalars['Int']['output']; + pages: Array; + rating?: Maybe; + tags: Array; + title: Scalars['String']['output']; + updatedAt: Scalars['DateTime']['output']; + url?: Maybe; + worlds: Array; +}; + +export type FullTag = { + __typename?: 'FullTag'; + description?: Maybe; + id: Scalars['Int']['output']; + name: Scalars['String']['output']; + namespaces: Array; +}; + +export type IdNotFoundError = Error & { + __typename?: 'IDNotFoundError'; + id: Scalars['Int']['output']; + message: Scalars['String']['output']; +}; + +export type Image = { + __typename?: 'Image'; + aspectRatio: Scalars['Float']['output']; + hash: Scalars['String']['output']; + height: Scalars['Int']['output']; + id: Scalars['Int']['output']; + width: Scalars['Int']['output']; +}; + +export type InvalidParameterError = Error & { + __typename?: 'InvalidParameterError'; + message: Scalars['String']['output']; + parameter: Scalars['String']['output']; +}; + +export enum Language { + Aa = 'AA', + Ab = 'AB', + Ae = 'AE', + Af = 'AF', + Ak = 'AK', + Am = 'AM', + An = 'AN', + Ar = 'AR', + As = 'AS', + Av = 'AV', + Ay = 'AY', + Az = 'AZ', + Ba = 'BA', + Be = 'BE', + Bg = 'BG', + Bh = 'BH', + Bi = 'BI', + Bm = 'BM', + Bn = 'BN', + Bo = 'BO', + Br = 'BR', + Bs = 'BS', + Ca = 'CA', + Ce = 'CE', + Ch = 'CH', + Co = 'CO', + Cr = 'CR', + Cs = 'CS', + Cu = 'CU', + Cv = 'CV', + Cy = 'CY', + Da = 'DA', + De = 'DE', + Dv = 'DV', + Dz = 'DZ', + Ee = 'EE', + El = 'EL', + En = 'EN', + Eo = 'EO', + Es = 'ES', + Et = 'ET', + Eu = 'EU', + Fa = 'FA', + Ff = 'FF', + Fi = 'FI', + Fj = 'FJ', + Fo = 'FO', + Fr = 'FR', + Fy = 'FY', + Ga = 'GA', + Gd = 'GD', + Gl = 'GL', + Gn = 'GN', + Gu = 'GU', + Gv = 'GV', + Ha = 'HA', + He = 'HE', + Hi = 'HI', + Ho = 'HO', + Hr = 'HR', + Ht = 'HT', + Hu = 'HU', + Hy = 'HY', + Hz = 'HZ', + Ia = 'IA', + Id = 'ID', + Ie = 'IE', + Ig = 'IG', + Ii = 'II', + Ik = 'IK', + Io = 'IO', + Is = 'IS', + It = 'IT', + Iu = 'IU', + Ja = 'JA', + Jv = 'JV', + Ka = 'KA', + Kg = 'KG', + Ki = 'KI', + Kj = 'KJ', + Kk = 'KK', + Kl = 'KL', + Km = 'KM', + Kn = 'KN', + Ko = 'KO', + Kr = 'KR', + Ks = 'KS', + Ku = 'KU', + Kv = 'KV', + Kw = 'KW', + Ky = 'KY', + La = 'LA', + Lb = 'LB', + Lg = 'LG', + Li = 'LI', + Ln = 'LN', + Lo = 'LO', + Lt = 'LT', + Lu = 'LU', + Lv = 'LV', + Mg = 'MG', + Mh = 'MH', + Mi = 'MI', + Mk = 'MK', + Ml = 'ML', + Mn = 'MN', + Mr = 'MR', + Ms = 'MS', + Mt = 'MT', + My = 'MY', + Na = 'NA', + Nb = 'NB', + Nd = 'ND', + Ne = 'NE', + Ng = 'NG', + Nl = 'NL', + Nn = 'NN', + No = 'NO', + Nr = 'NR', + Nv = 'NV', + Ny = 'NY', + Oc = 'OC', + Oj = 'OJ', + Om = 'OM', + Or = 'OR', + Os = 'OS', + Pa = 'PA', + Pi = 'PI', + Pl = 'PL', + Ps = 'PS', + Pt = 'PT', + Qu = 'QU', + Rm = 'RM', + Rn = 'RN', + Ro = 'RO', + Ru = 'RU', + Rw = 'RW', + Sa = 'SA', + Sc = 'SC', + Sd = 'SD', + Se = 'SE', + Sg = 'SG', + Si = 'SI', + Sk = 'SK', + Sl = 'SL', + Sm = 'SM', + Sn = 'SN', + So = 'SO', + Sq = 'SQ', + Sr = 'SR', + Ss = 'SS', + St = 'ST', + Su = 'SU', + Sv = 'SV', + Sw = 'SW', + Ta = 'TA', + Te = 'TE', + Tg = 'TG', + Th = 'TH', + Ti = 'TI', + Tk = 'TK', + Tl = 'TL', + Tn = 'TN', + To = 'TO', + Tr = 'TR', + Ts = 'TS', + Tt = 'TT', + Tw = 'TW', + Ty = 'TY', + Ug = 'UG', + Uk = 'UK', + Ur = 'UR', + Uz = 'UZ', + Ve = 'VE', + Vi = 'VI', + Vo = 'VO', + Wa = 'WA', + Wo = 'WO', + Xh = 'XH', + Yi = 'YI', + Yo = 'YO', + Za = 'ZA', + Zh = 'ZH', + Zu = 'ZU' +} + +export type LanguageFilter = { + any?: InputMaybe>; + empty?: InputMaybe; +}; + +export enum Layout { + Double = 'DOUBLE', + DoubleOffset = 'DOUBLE_OFFSET', + Single = 'SINGLE' +} + +export type Mutation = { + __typename?: 'Mutation'; + addArtist: AddResponse; + addCharacter: AddResponse; + addCircle: AddResponse; + addComic: AddComicResponse; + addNamespace: AddResponse; + addTag: AddResponse; + addWorld: AddResponse; + deleteArchives: DeleteResponse; + deleteArtists: DeleteResponse; + deleteCharacters: DeleteResponse; + deleteCircles: DeleteResponse; + deleteComics: DeleteResponse; + deleteNamespaces: DeleteResponse; + deleteTags: DeleteResponse; + deleteWorlds: DeleteResponse; + updateArchives: UpdateResponse; + updateArtists: UpdateResponse; + updateCharacters: UpdateResponse; + updateCircles: UpdateResponse; + updateComics: UpdateResponse; + updateNamespaces: UpdateResponse; + updateTags: UpdateResponse; + updateWorlds: UpdateResponse; + upsertComics: UpsertResponse; +}; + + +export type MutationAddArtistArgs = { + input: AddArtistInput; +}; + + +export type MutationAddCharacterArgs = { + input: AddCharacterInput; +}; + + +export type MutationAddCircleArgs = { + input: AddCircleInput; +}; + + +export type MutationAddComicArgs = { + input: AddComicInput; +}; + + +export type MutationAddNamespaceArgs = { + input: AddNamespaceInput; +}; + + +export type MutationAddTagArgs = { + input: AddTagInput; +}; + + +export type MutationAddWorldArgs = { + input: AddWorldInput; +}; + + +export type MutationDeleteArchivesArgs = { + ids: Array; +}; + + +export type MutationDeleteArtistsArgs = { + ids: Array; +}; + + +export type MutationDeleteCharactersArgs = { + ids: Array; +}; + + +export type MutationDeleteCirclesArgs = { + ids: Array; +}; + + +export type MutationDeleteComicsArgs = { + ids: Array; +}; + + +export type MutationDeleteNamespacesArgs = { + ids: Array; +}; + + +export type MutationDeleteTagsArgs = { + ids: Array; +}; + + +export type MutationDeleteWorldsArgs = { + ids: Array; +}; + + +export type MutationUpdateArchivesArgs = { + ids: Array; + input: UpdateArchiveInput; +}; + + +export type MutationUpdateArtistsArgs = { + ids: Array; + input: UpdateArtistInput; +}; + + +export type MutationUpdateCharactersArgs = { + ids: Array; + input: UpdateCharacterInput; +}; + + +export type MutationUpdateCirclesArgs = { + ids: Array; + input: UpdateCircleInput; +}; + + +export type MutationUpdateComicsArgs = { + ids: Array; + input: UpdateComicInput; +}; + + +export type MutationUpdateNamespacesArgs = { + ids: Array; + input: UpdateNamespaceInput; +}; + + +export type MutationUpdateTagsArgs = { + ids: Array; + input: UpdateTagInput; +}; + + +export type MutationUpdateWorldsArgs = { + ids: Array; + input: UpdateWorldInput; +}; + + +export type MutationUpsertComicsArgs = { + ids: Array; + input: UpsertComicInput; +}; + +export type NameExistsError = Error & { + __typename?: 'NameExistsError'; + message: Scalars['String']['output']; +}; + +export type Namespace = { + __typename?: 'Namespace'; + id: Scalars['Int']['output']; + name: Scalars['String']['output']; + sortName?: Maybe; +}; + +export type NamespaceFilter = { + name?: InputMaybe; +}; + +export type NamespaceFilterInput = { + exclude?: InputMaybe; + include?: InputMaybe; +}; + +export type NamespaceFilterResult = { + __typename?: 'NamespaceFilterResult'; + count: Scalars['Int']['output']; + edges: Array; +}; + +export type NamespaceResponse = IdNotFoundError | Namespace; + +export enum NamespaceSort { + CreatedAt = 'CREATED_AT', + Name = 'NAME', + Random = 'RANDOM', + SortName = 'SORT_NAME', + UpdatedAt = 'UPDATED_AT' +} + +export type NamespaceSortInput = { + direction?: InputMaybe; + on: NamespaceSort; + seed?: InputMaybe; +}; + +export type NamespacesInput = { + ids: Array; +}; + +export type NamespacesUpdateInput = { + ids: Array; + options?: InputMaybe; +}; + +export enum OnMissing { + Create = 'CREATE', + Ignore = 'IGNORE' +} + +export type Page = { + __typename?: 'Page'; + comicId?: Maybe; + id: Scalars['Int']['output']; + image: Image; + path: Scalars['String']['output']; +}; + +export type PageClaimedError = Error & { + __typename?: 'PageClaimedError'; + comicId: Scalars['Int']['output']; + id: Scalars['Int']['output']; + message: Scalars['String']['output']; +}; + +export type PageRemoteError = Error & { + __typename?: 'PageRemoteError'; + archiveId: Scalars['Int']['output']; + id: Scalars['Int']['output']; + message: Scalars['String']['output']; +}; + +export type Pagination = { + items?: Scalars['Int']['input']; + page?: Scalars['Int']['input']; +}; + +export type Query = { + __typename?: 'Query'; + archive: ArchiveResponse; + archives: ArchiveFilterResult; + artist: ArtistResponse; + artists: ArtistFilterResult; + character: CharacterResponse; + characters: CharacterFilterResult; + circle: CircleResponse; + circles: CircleFilterResult; + comic: ComicResponse; + comicScrapers: Array; + comicTags: ComicTagFilterResult; + comics: ComicFilterResult; + namespace: NamespaceResponse; + namespaces: NamespaceFilterResult; + scrapeComic: ScrapeComicResponse; + tag: TagResponse; + tags: TagFilterResult; + world: WorldResponse; + worlds: WorldFilterResult; +}; + + +export type QueryArchiveArgs = { + id: Scalars['Int']['input']; +}; + + +export type QueryArchivesArgs = { + filter?: InputMaybe; + pagination?: InputMaybe; + sort?: InputMaybe; +}; + + +export type QueryArtistArgs = { + id: Scalars['Int']['input']; +}; + + +export type QueryArtistsArgs = { + filter?: InputMaybe; + pagination?: InputMaybe; + sort?: InputMaybe; +}; + + +export type QueryCharacterArgs = { + id: Scalars['Int']['input']; +}; + + +export type QueryCharactersArgs = { + filter?: InputMaybe; + pagination?: InputMaybe; + sort?: InputMaybe; +}; + + +export type QueryCircleArgs = { + id: Scalars['Int']['input']; +}; + + +export type QueryCirclesArgs = { + filter?: InputMaybe; + pagination?: InputMaybe; + sort?: InputMaybe; +}; + + +export type QueryComicArgs = { + id: Scalars['Int']['input']; +}; + + +export type QueryComicScrapersArgs = { + id: Scalars['Int']['input']; +}; + + +export type QueryComicTagsArgs = { + forFilter?: Scalars['Boolean']['input']; +}; + + +export type QueryComicsArgs = { + filter?: InputMaybe; + pagination?: InputMaybe; + sort?: InputMaybe; +}; + + +export type QueryNamespaceArgs = { + id: Scalars['Int']['input']; +}; + + +export type QueryNamespacesArgs = { + filter?: InputMaybe; + pagination?: InputMaybe; + sort?: InputMaybe; +}; + + +export type QueryScrapeComicArgs = { + id: Scalars['Int']['input']; + scraper: Scalars['String']['input']; +}; + + +export type QueryTagArgs = { + id: Scalars['Int']['input']; +}; + + +export type QueryTagsArgs = { + filter?: InputMaybe; + pagination?: InputMaybe; + sort?: InputMaybe; +}; + + +export type QueryWorldArgs = { + id: Scalars['Int']['input']; +}; + + +export type QueryWorldsArgs = { + filter?: InputMaybe; + pagination?: InputMaybe; + sort?: InputMaybe; +}; + +export enum Rating { + Explicit = 'EXPLICIT', + Questionable = 'QUESTIONABLE', + Safe = 'SAFE' +} + +export type RatingFilter = { + any?: InputMaybe>; + empty?: InputMaybe; +}; + +export type ScrapeComicResponse = IdNotFoundError | ScrapeComicResult | ScraperError | ScraperNotAvailableError | ScraperNotFoundError; + +export type ScrapeComicResult = { + __typename?: 'ScrapeComicResult'; + data: ScrapedComic; + warnings: Array; +}; + +export type ScrapedComic = { + __typename?: 'ScrapedComic'; + artists: Array; + category?: Maybe; + censorship?: Maybe; + characters: Array; + circles: Array; + date?: Maybe; + direction?: Maybe; + language?: Maybe; + layout?: Maybe; + originalTitle?: Maybe; + rating?: Maybe; + tags: Array; + title?: Maybe; + url?: Maybe; + worlds: Array; +}; + +export type ScraperError = Error & { + __typename?: 'ScraperError'; + error: Scalars['String']['output']; + message: Scalars['String']['output']; +}; + +export type ScraperNotAvailableError = Error & { + __typename?: 'ScraperNotAvailableError'; + comicId: Scalars['Int']['output']; + message: Scalars['String']['output']; + scraper: Scalars['String']['output']; +}; + +export type ScraperNotFoundError = Error & { + __typename?: 'ScraperNotFoundError'; + message: Scalars['String']['output']; + name: Scalars['String']['output']; +}; + +export enum SortDirection { + Ascending = 'ASCENDING', + Descending = 'DESCENDING' +} + +export type StringFilter = { + contains?: InputMaybe; +}; + +export type Success = { + message: Scalars['String']['output']; +}; + +export type Tag = { + __typename?: 'Tag'; + description?: Maybe; + id: Scalars['Int']['output']; + name: Scalars['String']['output']; +}; + +export type TagAssociationFilter = { + all?: InputMaybe>; + any?: InputMaybe>; + empty?: InputMaybe; + exact?: InputMaybe>; +}; + +export type TagFilter = { + name?: InputMaybe; + namespaces?: InputMaybe; +}; + +export type TagFilterInput = { + exclude?: InputMaybe; + include?: InputMaybe; +}; + +export type TagFilterResult = { + __typename?: 'TagFilterResult'; + count: Scalars['Int']['output']; + edges: Array; +}; + +export type TagResponse = FullTag | IdNotFoundError; + +export enum TagSort { + CreatedAt = 'CREATED_AT', + Name = 'NAME', + Random = 'RANDOM', + UpdatedAt = 'UPDATED_AT' +} + +export type TagSortInput = { + direction?: InputMaybe; + on: TagSort; + seed?: InputMaybe; +}; + +export type UniquePagesInput = { + ids: Array; +}; + +export type UniquePagesUpdateInput = { + ids: Array; + options?: InputMaybe; +}; + +export type UpdateArchiveInput = { + cover?: InputMaybe; + organized?: InputMaybe; +}; + +export type UpdateArtistInput = { + name?: InputMaybe; +}; + +export type UpdateCharacterInput = { + name?: InputMaybe; +}; + +export type UpdateCircleInput = { + name?: InputMaybe; +}; + +export type UpdateComicInput = { + artists?: InputMaybe; + bookmarked?: InputMaybe; + category?: InputMaybe; + censorship?: InputMaybe; + characters?: InputMaybe; + circles?: InputMaybe; + cover?: InputMaybe; + date?: InputMaybe; + direction?: InputMaybe; + favourite?: InputMaybe; + language?: InputMaybe; + layout?: InputMaybe; + organized?: InputMaybe; + originalTitle?: InputMaybe; + pages?: InputMaybe; + rating?: InputMaybe; + tags?: InputMaybe; + title?: InputMaybe; + url?: InputMaybe; + worlds?: InputMaybe; +}; + +export enum UpdateMode { + Add = 'ADD', + Remove = 'REMOVE', + Replace = 'REPLACE' +} + +export type UpdateNamespaceInput = { + name?: InputMaybe; + sortName?: InputMaybe; +}; + +export type UpdateOptions = { + mode?: UpdateMode; +}; + +export type UpdateResponse = IdNotFoundError | InvalidParameterError | NameExistsError | PageClaimedError | PageRemoteError | UpdateSuccess; + +export type UpdateSuccess = Success & { + __typename?: 'UpdateSuccess'; + message: Scalars['String']['output']; +}; + +export type UpdateTagInput = { + description?: InputMaybe; + name?: InputMaybe; + namespaces?: InputMaybe; +}; + +export type UpdateWorldInput = { + name?: InputMaybe; +}; + +export type UpsertComicInput = { + artists?: InputMaybe; + bookmarked?: InputMaybe; + category?: InputMaybe; + censorship?: InputMaybe; + characters?: InputMaybe; + circles?: InputMaybe; + date?: InputMaybe; + direction?: InputMaybe; + favourite?: InputMaybe; + language?: InputMaybe; + layout?: InputMaybe; + organized?: InputMaybe; + originalTitle?: InputMaybe; + rating?: InputMaybe; + tags?: InputMaybe; + title?: InputMaybe; + url?: InputMaybe; + worlds?: InputMaybe; +}; + +export type UpsertOptions = { + onMissing?: OnMissing; +}; + +export type UpsertResponse = InvalidParameterError | NameExistsError | UpsertSuccess; + +export type UpsertSuccess = Success & { + __typename?: 'UpsertSuccess'; + message: Scalars['String']['output']; +}; + +export type World = { + __typename?: 'World'; + id: Scalars['Int']['output']; + name: Scalars['String']['output']; +}; + +export type WorldFilter = { + name?: InputMaybe; +}; + +export type WorldFilterInput = { + exclude?: InputMaybe; + include?: InputMaybe; +}; + +export type WorldFilterResult = { + __typename?: 'WorldFilterResult'; + count: Scalars['Int']['output']; + edges: Array; +}; + +export type WorldResponse = IdNotFoundError | World; + +export enum WorldSort { + CreatedAt = 'CREATED_AT', + Name = 'NAME', + Random = 'RANDOM', + UpdatedAt = 'UPDATED_AT' +} + +export type WorldSortInput = { + direction?: InputMaybe; + on: WorldSort; + seed?: InputMaybe; +}; + +export type WorldsUpdateInput = { + ids: Array; + options?: InputMaybe; +}; + +export type WorldsUpsertInput = { + names?: Array; + options?: InputMaybe; +}; + +export type ImageFragment = { __typename?: 'Image', hash: string, width: number, height: number }; + +export type PageFragment = { __typename?: 'Page', id: number, path: string, comicId?: number | null, image: { __typename?: 'Image', id: number, hash: string, aspectRatio: number, width: number, height: number } }; + +export type ComicFragment = { __typename?: 'Comic', id: number, title: string, originalTitle?: string | null, favourite: boolean, cover: { __typename?: 'Image', hash: string, width: number, height: number }, tags: Array<{ __typename?: 'ComicTag', name: string, description?: string | null }>, artists: Array<{ __typename?: 'Artist', name: string }>, characters: Array<{ __typename?: 'Character', name: string }>, worlds: Array<{ __typename?: 'World', name: string }>, circles: Array<{ __typename?: 'Circle', name: string }> }; + +export type FullArchiveFragment = { __typename?: 'FullArchive', id: number, name: string, path: string, size: number, createdAt: string, mtime: string, organized: boolean, pageCount: number, pages: Array<{ __typename?: 'Page', id: number, path: string, comicId?: number | null, image: { __typename?: 'Image', id: number, hash: string, aspectRatio: number, width: number, height: number } }>, comics: Array<{ __typename?: 'Comic', id: number, title: string, originalTitle?: string | null, favourite: boolean, cover: { __typename?: 'Image', hash: string, width: number, height: number }, tags: Array<{ __typename?: 'ComicTag', name: string, description?: string | null }>, artists: Array<{ __typename?: 'Artist', name: string }>, characters: Array<{ __typename?: 'Character', name: string }>, worlds: Array<{ __typename?: 'World', name: string }>, circles: Array<{ __typename?: 'Circle', name: string }> }> }; + +export type ArchiveFragment = { __typename?: 'Archive', id: number, name: string, size: number, pageCount: number, cover: { __typename?: 'Image', hash: string, width: number, height: number } }; + +export type FullComicFragment = { __typename?: 'FullComic', id: number, title: string, originalTitle?: string | null, url?: string | null, language?: Language | null, direction: Direction, date?: string | null, layout: Layout, rating?: Rating | null, category?: Category | null, censorship?: Censorship | null, favourite: boolean, createdAt: string, updatedAt: string, organized: boolean, bookmarked: boolean, pages: Array<{ __typename?: 'Page', id: number, path: string, comicId?: number | null, image: { __typename?: 'Image', id: number, hash: string, aspectRatio: number, width: number, height: number } }>, archive: { __typename?: 'Archive', id: number }, tags: Array<{ __typename?: 'ComicTag', id: string, name: string, description?: string | null }>, artists: Array<{ __typename?: 'Artist', id: number, name: string }>, characters: Array<{ __typename?: 'Character', id: number, name: string }>, worlds: Array<{ __typename?: 'World', id: number, name: string }>, circles: Array<{ __typename?: 'Circle', id: number, name: string }> }; + +export type ComicScraperFragment = { __typename?: 'ComicScraper', id: string, name: string }; + +export type ScrapeComicResultFragment = { __typename?: 'ScrapeComicResult', warnings: Array, data: { __typename?: 'ScrapedComic', artists: Array, category?: Category | null, censorship?: Censorship | null, characters: Array, circles: Array, date?: string | null, direction?: Direction | null, language?: Language | null, layout?: Layout | null, originalTitle?: string | null, url?: string | null, rating?: Rating | null, tags: Array, title?: string | null, worlds: Array } }; + +export type ComicsQueryVariables = Exact<{ + pagination: Pagination; + filter?: InputMaybe; + sort?: InputMaybe; +}>; + + +export type ComicsQuery = { __typename?: 'Query', comics: { __typename?: 'ComicFilterResult', count: number, edges: Array<{ __typename?: 'Comic', id: number, title: string, originalTitle?: string | null, favourite: boolean, cover: { __typename?: 'Image', hash: string, width: number, height: number }, tags: Array<{ __typename?: 'ComicTag', name: string, description?: string | null }>, artists: Array<{ __typename?: 'Artist', name: string }>, characters: Array<{ __typename?: 'Character', name: string }>, worlds: Array<{ __typename?: 'World', name: string }>, circles: Array<{ __typename?: 'Circle', name: string }> }> } }; + +export type ArchivesQueryVariables = Exact<{ + pagination: Pagination; + filter?: InputMaybe; + sort?: InputMaybe; +}>; + + +export type ArchivesQuery = { __typename?: 'Query', archives: { __typename?: 'ArchiveFilterResult', count: number, edges: Array<{ __typename?: 'Archive', id: number, name: string, size: number, pageCount: number, cover: { __typename?: 'Image', hash: string, width: number, height: number } }> } }; + +export type ArchiveQueryVariables = Exact<{ + id: Scalars['Int']['input']; +}>; + + +export type ArchiveQuery = { __typename?: 'Query', archive: { __typename?: 'FullArchive', id: number, name: string, path: string, size: number, createdAt: string, mtime: string, organized: boolean, pageCount: number, pages: Array<{ __typename?: 'Page', id: number, path: string, comicId?: number | null, image: { __typename?: 'Image', id: number, hash: string, aspectRatio: number, width: number, height: number } }>, comics: Array<{ __typename?: 'Comic', id: number, title: string, originalTitle?: string | null, favourite: boolean, cover: { __typename?: 'Image', hash: string, width: number, height: number }, tags: Array<{ __typename?: 'ComicTag', name: string, description?: string | null }>, artists: Array<{ __typename?: 'Artist', name: string }>, characters: Array<{ __typename?: 'Character', name: string }>, worlds: Array<{ __typename?: 'World', name: string }>, circles: Array<{ __typename?: 'Circle', name: string }> }> } | { __typename?: 'IDNotFoundError', message: string } }; + +export type ComicQueryVariables = Exact<{ + id: Scalars['Int']['input']; +}>; + + +export type ComicQuery = { __typename?: 'Query', comic: { __typename?: 'FullComic', id: number, title: string, originalTitle?: string | null, url?: string | null, language?: Language | null, direction: Direction, date?: string | null, layout: Layout, rating?: Rating | null, category?: Category | null, censorship?: Censorship | null, favourite: boolean, createdAt: string, updatedAt: string, organized: boolean, bookmarked: boolean, pages: Array<{ __typename?: 'Page', id: number, path: string, comicId?: number | null, image: { __typename?: 'Image', id: number, hash: string, aspectRatio: number, width: number, height: number } }>, archive: { __typename?: 'Archive', id: number }, tags: Array<{ __typename?: 'ComicTag', id: string, name: string, description?: string | null }>, artists: Array<{ __typename?: 'Artist', id: number, name: string }>, characters: Array<{ __typename?: 'Character', id: number, name: string }>, worlds: Array<{ __typename?: 'World', id: number, name: string }>, circles: Array<{ __typename?: 'Circle', id: number, name: string }> } | { __typename?: 'IDNotFoundError', message: string } }; + +export type TagQueryVariables = Exact<{ + id: Scalars['Int']['input']; +}>; + + +export type TagQuery = { __typename?: 'Query', tag: { __typename?: 'FullTag', id: number, name: string, description?: string | null, namespaces: Array<{ __typename?: 'Namespace', id: number, name: string }> } | { __typename?: 'IDNotFoundError', message: string } }; + +export type TagsQueryVariables = Exact<{ + pagination: Pagination; + filter?: InputMaybe; + sort?: InputMaybe; +}>; + + +export type TagsQuery = { __typename?: 'Query', tags: { __typename?: 'TagFilterResult', count: number, edges: Array<{ __typename?: 'Tag', id: number, name: string, description?: string | null }> } }; + +export type NamespaceQueryVariables = Exact<{ + id: Scalars['Int']['input']; +}>; + + +export type NamespaceQuery = { __typename?: 'Query', namespace: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'Namespace', id: number, name: string, sortName?: string | null } }; + +export type NamespacesQueryVariables = Exact<{ + pagination: Pagination; + filter?: InputMaybe; + sort?: InputMaybe; +}>; + + +export type NamespacesQuery = { __typename?: 'Query', namespaces: { __typename?: 'NamespaceFilterResult', count: number, edges: Array<{ __typename?: 'Namespace', id: number, name: string }> } }; + +export type ComicTagListQueryVariables = Exact<{ + forFilter?: InputMaybe; +}>; + + +export type ComicTagListQuery = { __typename?: 'Query', comicTags: { __typename?: 'ComicTagFilterResult', edges: Array<{ __typename?: 'ComicTag', id: string, name: string }> } }; + +export type ArtistListQueryVariables = Exact<{ [key: string]: never; }>; + + +export type ArtistListQuery = { __typename?: 'Query', artists: { __typename?: 'ArtistFilterResult', edges: Array<{ __typename?: 'Artist', id: number, name: string }> } }; + +export type CharacterListQueryVariables = Exact<{ [key: string]: never; }>; + + +export type CharacterListQuery = { __typename?: 'Query', characters: { __typename?: 'CharacterFilterResult', edges: Array<{ __typename?: 'Character', id: number, name: string }> } }; + +export type CircleListQueryVariables = Exact<{ [key: string]: never; }>; + + +export type CircleListQuery = { __typename?: 'Query', circles: { __typename?: 'CircleFilterResult', edges: Array<{ __typename?: 'Circle', id: number, name: string }> } }; + +export type WorldListQueryVariables = Exact<{ [key: string]: never; }>; + + +export type WorldListQuery = { __typename?: 'Query', worlds: { __typename?: 'WorldFilterResult', edges: Array<{ __typename?: 'World', id: number, name: string }> } }; + +export type NamespaceListQueryVariables = Exact<{ [key: string]: never; }>; + + +export type NamespaceListQuery = { __typename?: 'Query', namespaces: { __typename?: 'NamespaceFilterResult', edges: Array<{ __typename?: 'Namespace', id: number, name: string }> } }; + +export type ArtistsQueryVariables = Exact<{ + pagination: Pagination; + filter?: InputMaybe; + sort?: InputMaybe; +}>; + + +export type ArtistsQuery = { __typename?: 'Query', artists: { __typename?: 'ArtistFilterResult', count: number, edges: Array<{ __typename?: 'Artist', id: number, name: string }> } }; + +export type ArtistQueryVariables = Exact<{ + id: Scalars['Int']['input']; +}>; + + +export type ArtistQuery = { __typename?: 'Query', artist: { __typename?: 'Artist', id: number, name: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export type CharactersQueryVariables = Exact<{ + pagination: Pagination; + filter?: InputMaybe; + sort?: InputMaybe; +}>; + + +export type CharactersQuery = { __typename?: 'Query', characters: { __typename?: 'CharacterFilterResult', count: number, edges: Array<{ __typename?: 'Character', id: number, name: string }> } }; + +export type CharacterQueryVariables = Exact<{ + id: Scalars['Int']['input']; +}>; + + +export type CharacterQuery = { __typename?: 'Query', character: { __typename?: 'Character', id: number, name: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export type CirclesQueryVariables = Exact<{ + pagination: Pagination; + filter?: InputMaybe; + sort?: InputMaybe; +}>; + + +export type CirclesQuery = { __typename?: 'Query', circles: { __typename?: 'CircleFilterResult', count: number, edges: Array<{ __typename?: 'Circle', id: number, name: string }> } }; + +export type CircleQueryVariables = Exact<{ + id: Scalars['Int']['input']; +}>; + + +export type CircleQuery = { __typename?: 'Query', circle: { __typename?: 'Circle', id: number, name: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export type WorldsQueryVariables = Exact<{ + pagination: Pagination; + filter?: InputMaybe; + sort?: InputMaybe; +}>; + + +export type WorldsQuery = { __typename?: 'Query', worlds: { __typename?: 'WorldFilterResult', count: number, edges: Array<{ __typename?: 'World', id: number, name: string }> } }; + +export type WorldQueryVariables = Exact<{ + id: Scalars['Int']['input']; +}>; + + +export type WorldQuery = { __typename?: 'Query', world: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'World', id: number, name: string } }; + +export type ComicScrapersQueryVariables = Exact<{ + id: Scalars['Int']['input']; +}>; + + +export type ComicScrapersQuery = { __typename?: 'Query', comicScrapers: Array<{ __typename?: 'ComicScraper', id: string, name: string }> }; + +export type ScrapeComicQueryVariables = Exact<{ + id: Scalars['Int']['input']; + scraper: Scalars['String']['input']; +}>; + + +export type ScrapeComicQuery = { __typename?: 'Query', scrapeComic: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'ScrapeComicResult', warnings: Array, data: { __typename?: 'ScrapedComic', artists: Array, category?: Category | null, censorship?: Censorship | null, characters: Array, circles: Array, date?: string | null, direction?: Direction | null, language?: Language | null, layout?: Layout | null, originalTitle?: string | null, url?: string | null, rating?: Rating | null, tags: Array, title?: string | null, worlds: Array } } | { __typename?: 'ScraperError', message: string } | { __typename?: 'ScraperNotAvailableError', message: string } | { __typename?: 'ScraperNotFoundError', message: string } }; + +export type FrontpageQueryVariables = Exact<{ [key: string]: never; }>; + + +export type FrontpageQuery = { __typename?: 'Query', recent: { __typename?: 'ComicFilterResult', count: number, edges: Array<{ __typename?: 'Comic', id: number, title: string, originalTitle?: string | null, favourite: boolean, cover: { __typename?: 'Image', hash: string, width: number, height: number }, tags: Array<{ __typename?: 'ComicTag', name: string, description?: string | null }>, artists: Array<{ __typename?: 'Artist', name: string }>, characters: Array<{ __typename?: 'Character', name: string }>, worlds: Array<{ __typename?: 'World', name: string }>, circles: Array<{ __typename?: 'Circle', name: string }> }> }, favourites: { __typename?: 'ComicFilterResult', count: number, edges: Array<{ __typename?: 'Comic', id: number, title: string, originalTitle?: string | null, favourite: boolean, cover: { __typename?: 'Image', hash: string, width: number, height: number }, tags: Array<{ __typename?: 'ComicTag', name: string, description?: string | null }>, artists: Array<{ __typename?: 'Artist', name: string }>, characters: Array<{ __typename?: 'Character', name: string }>, worlds: Array<{ __typename?: 'World', name: string }>, circles: Array<{ __typename?: 'Circle', name: string }> }> }, bookmarked: { __typename?: 'ComicFilterResult', count: number, edges: Array<{ __typename?: 'Comic', id: number, title: string, originalTitle?: string | null, favourite: boolean, cover: { __typename?: 'Image', hash: string, width: number, height: number }, tags: Array<{ __typename?: 'ComicTag', name: string, description?: string | null }>, artists: Array<{ __typename?: 'Artist', name: string }>, characters: Array<{ __typename?: 'Character', name: string }>, worlds: Array<{ __typename?: 'World', name: string }>, circles: Array<{ __typename?: 'Circle', name: string }> }> } }; + +export type AddComicMutationVariables = Exact<{ + input: AddComicInput; +}>; + + +export type AddComicMutation = { __typename?: 'Mutation', addComic: { __typename?: 'AddComicSuccess', message: string, archivePagesRemaining: boolean } | { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'PageClaimedError', message: string } | { __typename?: 'PageRemoteError', message: string } }; + +export type UpdateArchivesMutationVariables = Exact<{ + ids: Array | Scalars['Int']['input']; + input: UpdateArchiveInput; +}>; + + +export type UpdateArchivesMutation = { __typename?: 'Mutation', updateArchives: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } | { __typename?: 'PageClaimedError', message: string } | { __typename?: 'PageRemoteError', message: string } | { __typename?: 'UpdateSuccess', message: string } }; + +export type UpdateComicsMutationVariables = Exact<{ + ids: Array | Scalars['Int']['input']; + input: UpdateComicInput; +}>; + + +export type UpdateComicsMutation = { __typename?: 'Mutation', updateComics: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } | { __typename?: 'PageClaimedError', message: string } | { __typename?: 'PageRemoteError', message: string } | { __typename?: 'UpdateSuccess', message: string } }; + +export type UpsertComicsMutationVariables = Exact<{ + ids: Array | Scalars['Int']['input']; + input: UpsertComicInput; +}>; + + +export type UpsertComicsMutation = { __typename?: 'Mutation', upsertComics: { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } | { __typename?: 'UpsertSuccess', message: string } }; + +export type DeleteArchivesMutationVariables = Exact<{ + ids: Array | Scalars['Int']['input']; +}>; + + +export type DeleteArchivesMutation = { __typename?: 'Mutation', deleteArchives: { __typename?: 'DeleteSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export type DeleteComicsMutationVariables = Exact<{ + ids: Array | Scalars['Int']['input']; +}>; + + +export type DeleteComicsMutation = { __typename?: 'Mutation', deleteComics: { __typename?: 'DeleteSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export type AddTagMutationVariables = Exact<{ + input: AddTagInput; +}>; + + +export type AddTagMutation = { __typename?: 'Mutation', addTag: { __typename?: 'AddSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } }; + +export type UpdateTagsMutationVariables = Exact<{ + ids: Array | Scalars['Int']['input']; + input: UpdateTagInput; +}>; + + +export type UpdateTagsMutation = { __typename?: 'Mutation', updateTags: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } | { __typename?: 'PageClaimedError', message: string } | { __typename?: 'PageRemoteError', message: string } | { __typename?: 'UpdateSuccess', message: string } }; + +export type DeleteTagsMutationVariables = Exact<{ + ids: Array | Scalars['Int']['input']; +}>; + + +export type DeleteTagsMutation = { __typename?: 'Mutation', deleteTags: { __typename?: 'DeleteSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export type AddNamespaceMutationVariables = Exact<{ + input: AddNamespaceInput; +}>; + + +export type AddNamespaceMutation = { __typename?: 'Mutation', addNamespace: { __typename?: 'AddSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } }; + +export type UpdateNamespacesMutationVariables = Exact<{ + ids: Array | Scalars['Int']['input']; + input: UpdateNamespaceInput; +}>; + + +export type UpdateNamespacesMutation = { __typename?: 'Mutation', updateNamespaces: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } | { __typename?: 'PageClaimedError', message: string } | { __typename?: 'PageRemoteError', message: string } | { __typename?: 'UpdateSuccess', message: string } }; + +export type DeleteNamespacesMutationVariables = Exact<{ + ids: Array | Scalars['Int']['input']; +}>; + + +export type DeleteNamespacesMutation = { __typename?: 'Mutation', deleteNamespaces: { __typename?: 'DeleteSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export type AddArtistMutationVariables = Exact<{ + input: AddArtistInput; +}>; + + +export type AddArtistMutation = { __typename?: 'Mutation', addArtist: { __typename?: 'AddSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } }; + +export type UpdateArtistsMutationVariables = Exact<{ + ids: Array | Scalars['Int']['input']; + input: UpdateArtistInput; +}>; + + +export type UpdateArtistsMutation = { __typename?: 'Mutation', updateArtists: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } | { __typename?: 'PageClaimedError', message: string } | { __typename?: 'PageRemoteError', message: string } | { __typename?: 'UpdateSuccess', message: string } }; + +export type DeleteArtistsMutationVariables = Exact<{ + ids: Array | Scalars['Int']['input']; +}>; + + +export type DeleteArtistsMutation = { __typename?: 'Mutation', deleteArtists: { __typename?: 'DeleteSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export type AddCharacterMutationVariables = Exact<{ + input: AddCharacterInput; +}>; + + +export type AddCharacterMutation = { __typename?: 'Mutation', addCharacter: { __typename?: 'AddSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } }; + +export type UpdateCharactersMutationVariables = Exact<{ + ids: Array | Scalars['Int']['input']; + input: UpdateCharacterInput; +}>; + + +export type UpdateCharactersMutation = { __typename?: 'Mutation', updateCharacters: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } | { __typename?: 'PageClaimedError', message: string } | { __typename?: 'PageRemoteError', message: string } | { __typename?: 'UpdateSuccess', message: string } }; + +export type DeleteCharactersMutationVariables = Exact<{ + ids: Array | Scalars['Int']['input']; +}>; + + +export type DeleteCharactersMutation = { __typename?: 'Mutation', deleteCharacters: { __typename?: 'DeleteSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export type AddCircleMutationVariables = Exact<{ + input: AddCircleInput; +}>; + + +export type AddCircleMutation = { __typename?: 'Mutation', addCircle: { __typename?: 'AddSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } }; + +export type UpdateCirclesMutationVariables = Exact<{ + ids: Array | Scalars['Int']['input']; + input: UpdateCircleInput; +}>; + + +export type UpdateCirclesMutation = { __typename?: 'Mutation', updateCircles: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } | { __typename?: 'PageClaimedError', message: string } | { __typename?: 'PageRemoteError', message: string } | { __typename?: 'UpdateSuccess', message: string } }; + +export type DeleteCirclesMutationVariables = Exact<{ + ids: Array | Scalars['Int']['input']; +}>; + + +export type DeleteCirclesMutation = { __typename?: 'Mutation', deleteCircles: { __typename?: 'DeleteSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export type AddWorldMutationVariables = Exact<{ + input: AddWorldInput; +}>; + + +export type AddWorldMutation = { __typename?: 'Mutation', addWorld: { __typename?: 'AddSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } }; + +export type UpdateWorldsMutationVariables = Exact<{ + ids: Array | Scalars['Int']['input']; + input: UpdateWorldInput; +}>; + + +export type UpdateWorldsMutation = { __typename?: 'Mutation', updateWorlds: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } | { __typename?: 'PageClaimedError', message: string } | { __typename?: 'PageRemoteError', message: string } | { __typename?: 'UpdateSuccess', message: string } }; + +export type DeleteWorldsMutationVariables = Exact<{ + ids: Array | Scalars['Int']['input']; +}>; + + +export type DeleteWorldsMutation = { __typename?: 'Mutation', deleteWorlds: { __typename?: 'DeleteSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export const PageFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Page"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Page"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"image"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"aspectRatio"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comicId"}}]}}]} as unknown as DocumentNode; +export const ImageFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Image"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Image"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}}]} as unknown as DocumentNode; +export const ComicFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Comic"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Comic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"originalTitle"}},{"kind":"Field","name":{"kind":"Name","value":"favourite"}},{"kind":"Field","name":{"kind":"Name","value":"cover"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Image"}}]}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"Field","name":{"kind":"Name","value":"artists"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"characters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"worlds"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"circles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Image"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Image"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}}]} as unknown as DocumentNode; +export const FullArchiveFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FullArchive"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullArchive"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"size"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"mtime"}},{"kind":"Field","name":{"kind":"Name","value":"organized"}},{"kind":"Field","name":{"kind":"Name","value":"pageCount"}},{"kind":"Field","name":{"kind":"Name","value":"pages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Page"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Comic"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Image"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Image"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Page"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Page"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"image"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"aspectRatio"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comicId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Comic"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Comic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"originalTitle"}},{"kind":"Field","name":{"kind":"Name","value":"favourite"}},{"kind":"Field","name":{"kind":"Name","value":"cover"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Image"}}]}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"Field","name":{"kind":"Name","value":"artists"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"characters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"worlds"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"circles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode; +export const ArchiveFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Archive"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Archive"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"size"}},{"kind":"Field","name":{"kind":"Name","value":"pageCount"}},{"kind":"Field","name":{"kind":"Name","value":"cover"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Image"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Image"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Image"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}}]} as unknown as DocumentNode; +export const FullComicFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FullComic"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullComic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"originalTitle"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"language"}},{"kind":"Field","name":{"kind":"Name","value":"direction"}},{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"layout"}},{"kind":"Field","name":{"kind":"Name","value":"rating"}},{"kind":"Field","name":{"kind":"Name","value":"category"}},{"kind":"Field","name":{"kind":"Name","value":"censorship"}},{"kind":"Field","name":{"kind":"Name","value":"favourite"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"organized"}},{"kind":"Field","name":{"kind":"Name","value":"bookmarked"}},{"kind":"Field","name":{"kind":"Name","value":"pages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Page"}}]}},{"kind":"Field","name":{"kind":"Name","value":"archive"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"Field","name":{"kind":"Name","value":"artists"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"characters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"worlds"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"circles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Page"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Page"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"image"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"aspectRatio"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comicId"}}]}}]} as unknown as DocumentNode; +export const ComicScraperFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ComicScraper"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ComicScraper"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]} as unknown as DocumentNode; +export const ScrapeComicResultFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ScrapeComicResult"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ScrapeComicResult"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"artists"}},{"kind":"Field","name":{"kind":"Name","value":"category"}},{"kind":"Field","name":{"kind":"Name","value":"censorship"}},{"kind":"Field","name":{"kind":"Name","value":"characters"}},{"kind":"Field","name":{"kind":"Name","value":"circles"}},{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"direction"}},{"kind":"Field","name":{"kind":"Name","value":"language"}},{"kind":"Field","name":{"kind":"Name","value":"layout"}},{"kind":"Field","name":{"kind":"Name","value":"originalTitle"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"rating"}},{"kind":"Field","name":{"kind":"Name","value":"tags"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"worlds"}}]}},{"kind":"Field","name":{"kind":"Name","value":"warnings"}}]}}]} as unknown as DocumentNode; +export const ComicsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"comics"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Pagination"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ComicFilterInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ComicSortInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"comics"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Comic"}}]}},{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Image"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Image"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Comic"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Comic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"originalTitle"}},{"kind":"Field","name":{"kind":"Name","value":"favourite"}},{"kind":"Field","name":{"kind":"Name","value":"cover"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Image"}}]}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"Field","name":{"kind":"Name","value":"artists"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"characters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"worlds"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"circles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode; +export const ArchivesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"archives"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Pagination"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ArchiveFilterInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ArchiveSortInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"archives"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Archive"}}]}},{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Image"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Image"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Archive"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Archive"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"size"}},{"kind":"Field","name":{"kind":"Name","value":"pageCount"}},{"kind":"Field","name":{"kind":"Name","value":"cover"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Image"}}]}}]}}]} as unknown as DocumentNode; +export const ArchiveDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"archive"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"archive"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullArchive"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullArchive"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Image"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Image"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Page"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Page"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"image"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"aspectRatio"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comicId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Comic"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Comic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"originalTitle"}},{"kind":"Field","name":{"kind":"Name","value":"favourite"}},{"kind":"Field","name":{"kind":"Name","value":"cover"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Image"}}]}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"Field","name":{"kind":"Name","value":"artists"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"characters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"worlds"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"circles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FullArchive"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullArchive"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"size"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"mtime"}},{"kind":"Field","name":{"kind":"Name","value":"organized"}},{"kind":"Field","name":{"kind":"Name","value":"pageCount"}},{"kind":"Field","name":{"kind":"Name","value":"pages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Page"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Comic"}}]}}]}}]} as unknown as DocumentNode; +export const ComicDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"comic"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"comic"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullComic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullComic"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Page"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Page"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"image"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"aspectRatio"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comicId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FullComic"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullComic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"originalTitle"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"language"}},{"kind":"Field","name":{"kind":"Name","value":"direction"}},{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"layout"}},{"kind":"Field","name":{"kind":"Name","value":"rating"}},{"kind":"Field","name":{"kind":"Name","value":"category"}},{"kind":"Field","name":{"kind":"Name","value":"censorship"}},{"kind":"Field","name":{"kind":"Name","value":"favourite"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"organized"}},{"kind":"Field","name":{"kind":"Name","value":"bookmarked"}},{"kind":"Field","name":{"kind":"Name","value":"pages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Page"}}]}},{"kind":"Field","name":{"kind":"Name","value":"archive"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"Field","name":{"kind":"Name","value":"artists"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"characters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"worlds"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"circles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode; +export const TagDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"tag"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"tag"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullTag"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"namespaces"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const TagsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"tags"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Pagination"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"TagFilterInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"TagSortInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"tags"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}}]} as unknown as DocumentNode; +export const NamespaceDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"namespace"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"namespace"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Namespace"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"sortName"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const NamespacesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"namespaces"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Pagination"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"NamespaceFilterInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"NamespaceSortInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"namespaces"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}},{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; +export const ComicTagListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"comicTagList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"forFilter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}},"defaultValue":{"kind":"BooleanValue","value":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"comicTags"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"forFilter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"forFilter"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; +export const ArtistListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"artistList"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"artists"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; +export const CharacterListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"characterList"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"characters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; +export const CircleListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"circleList"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"circles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; +export const WorldListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"worldList"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"worlds"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; +export const NamespaceListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"namespaceList"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"namespaces"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; +export const ArtistsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"artists"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Pagination"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ArtistFilterInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ArtistSortInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"artists"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}},{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; +export const ArtistDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"artist"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"artist"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Artist"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const CharactersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"characters"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Pagination"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"CharacterFilterInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"CharacterSortInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"characters"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}},{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; +export const CharacterDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"character"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"character"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Character"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const CirclesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"circles"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Pagination"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"CircleFilterInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"CircleSortInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"circles"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}},{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; +export const CircleDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"circle"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"circle"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Circle"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const WorldsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"worlds"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Pagination"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"WorldFilterInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"WorldSortInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"worlds"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}},{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; +export const WorldDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"world"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"world"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"World"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const ComicScrapersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"comicScrapers"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"comicScrapers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode; +export const ScrapeComicDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"scrapeComic"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"scraper"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"scrapeComic"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}},{"kind":"Argument","name":{"kind":"Name","value":"scraper"},"value":{"kind":"Variable","name":{"kind":"Name","value":"scraper"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ScrapeComicResult"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ScrapeComicResult"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ScrapeComicResult"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ScrapeComicResult"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"artists"}},{"kind":"Field","name":{"kind":"Name","value":"category"}},{"kind":"Field","name":{"kind":"Name","value":"censorship"}},{"kind":"Field","name":{"kind":"Name","value":"characters"}},{"kind":"Field","name":{"kind":"Name","value":"circles"}},{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"direction"}},{"kind":"Field","name":{"kind":"Name","value":"language"}},{"kind":"Field","name":{"kind":"Name","value":"layout"}},{"kind":"Field","name":{"kind":"Name","value":"originalTitle"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"rating"}},{"kind":"Field","name":{"kind":"Name","value":"tags"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"worlds"}}]}},{"kind":"Field","name":{"kind":"Name","value":"warnings"}}]}}]} as unknown as DocumentNode; +export const FrontpageDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"frontpage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"recent"},"name":{"kind":"Name","value":"comics"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"items"},"value":{"kind":"IntValue","value":"6"}}]}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"on"},"value":{"kind":"EnumValue","value":"CREATED_AT"}},{"kind":"ObjectField","name":{"kind":"Name","value":"direction"},"value":{"kind":"EnumValue","value":"DESCENDING"}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Comic"}}]}},{"kind":"Field","name":{"kind":"Name","value":"count"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"favourites"},"name":{"kind":"Name","value":"comics"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"items"},"value":{"kind":"IntValue","value":"6"}}]}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"include"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"favourite"},"value":{"kind":"BooleanValue","value":true}}]}}]}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"on"},"value":{"kind":"EnumValue","value":"RANDOM"}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Comic"}}]}},{"kind":"Field","name":{"kind":"Name","value":"count"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"bookmarked"},"name":{"kind":"Name","value":"comics"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"items"},"value":{"kind":"IntValue","value":"6"}}]}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"include"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"bookmarked"},"value":{"kind":"BooleanValue","value":true}}]}}]}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"on"},"value":{"kind":"EnumValue","value":"RANDOM"}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Comic"}}]}},{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Image"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Image"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Comic"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Comic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"originalTitle"}},{"kind":"Field","name":{"kind":"Name","value":"favourite"}},{"kind":"Field","name":{"kind":"Name","value":"cover"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Image"}}]}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"Field","name":{"kind":"Name","value":"artists"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"characters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"worlds"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"circles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode; +export const AddComicDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"addComic"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AddComicInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addComic"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AddComicSuccess"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"archivePagesRemaining"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const UpdateArchivesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"updateArchives"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateArchiveInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateArchives"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const UpdateComicsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"updateComics"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateComicInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateComics"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const UpsertComicsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"upsertComics"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpsertComicInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"upsertComics"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const DeleteArchivesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"deleteArchives"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteArchives"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const DeleteComicsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"deleteComics"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteComics"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const AddTagDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"addTag"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AddTagInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addTag"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const UpdateTagsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"updateTags"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateTagInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateTags"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const DeleteTagsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"deleteTags"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteTags"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const AddNamespaceDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"addNamespace"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AddNamespaceInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addNamespace"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const UpdateNamespacesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"updateNamespaces"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateNamespaceInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateNamespaces"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const DeleteNamespacesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"deleteNamespaces"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteNamespaces"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const AddArtistDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"addArtist"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AddArtistInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addArtist"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const UpdateArtistsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"updateArtists"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateArtistInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateArtists"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const DeleteArtistsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"deleteArtists"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteArtists"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const AddCharacterDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"addCharacter"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AddCharacterInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addCharacter"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const UpdateCharactersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"updateCharacters"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateCharacterInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateCharacters"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const DeleteCharactersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"deleteCharacters"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteCharacters"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const AddCircleDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"addCircle"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AddCircleInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addCircle"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const UpdateCirclesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"updateCircles"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateCircleInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateCircles"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const DeleteCirclesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"deleteCircles"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteCircles"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const AddWorldDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"addWorld"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AddWorldInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addWorld"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const UpdateWorldsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"updateWorlds"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateWorldInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateWorlds"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; +export const DeleteWorldsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"deleteWorlds"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteWorlds"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/frontend/src/lib/Actions.ts b/frontend/src/lib/Actions.ts new file mode 100644 index 0000000..7231c2f --- /dev/null +++ b/frontend/src/lib/Actions.ts @@ -0,0 +1,109 @@ +export function debounce( + node: HTMLInputElement, + { callback, timeout = 500 }: { callback: () => void; timeout?: number } +) { + let timer: NodeJS.Timeout; + + function trigger(event: KeyboardEvent) { + clearTimeout(timer); + if (event.key !== 'Enter') { + timer = setTimeout(callback, timeout); + } else { + callback(); + } + } + + node.addEventListener('keyup', trigger); + + return { + destroy() { + clearTimeout(timer); + node.removeEventListener('keyup', trigger); + } + }; +} + +export function clickOutside( + node: HTMLElement, + { handler, ignore }: { handler: () => void; ignore?: HTMLElement } +) { + const handle = (event: Event) => { + const target = event.target as HTMLElement; + if (!target || target === ignore) return; + + if (node && !node.contains(target) && !event.defaultPrevented) { + handler(); + } + }; + + document.addEventListener('click', handle, true); + + return { + destroy() { + document.removeEventListener('click', handle, true); + } + }; +} + +export const focusableElements = [ + 'a[href]', + 'area[href]', + 'input:not([disabled]):not([type="hidden"]):not([aria-hidden])', + 'select:not([disabled]):not([aria-hidden])', + 'textarea:not([disabled]):not([aria-hidden])', + 'button:not([disabled]):not([aria-hidden])', + 'iframe', + 'object', + 'embed', + '[contenteditable]', + '[tabindex]:not([tabindex^="-"])' +]; + +let trapped: HTMLElement[] = []; + +export function trapFocus(node: HTMLElement) { + function handler(event: KeyboardEvent) { + if (event.target === window) return; + + // return if we're not the topmost node to handle + if (trapped.at(0) !== node) return; + + const focusable = node.querySelectorAll(focusableElements.join()); + + const first = focusable[0]; + const last = focusable[focusable.length - 1]; + + if (event.key === 'Tab') { + if (!node.contains(document.activeElement)) { + first.focus(); + event.preventDefault(); + } + + if (event.shiftKey && event.target === first) { + last.focus(); + event.preventDefault(); + } else if (!event.shiftKey && event.target === last) { + first.focus(); + event.preventDefault(); + } + } + } + + if (document.activeElement instanceof HTMLElement) { + // if we trap focus, make sure to blur any previously selected external + // item such that focus does not remain outside of the node + if (!node.contains(document.activeElement)) { + document.activeElement.blur(); + } + } + + document.addEventListener('keydown', handler); + trapped.unshift(node); + + return { + destroy() { + document.removeEventListener('keydown', handler); + trapped = trapped.filter((i) => i !== node); + } + }; +} diff --git a/frontend/src/lib/Enums.ts b/frontend/src/lib/Enums.ts new file mode 100644 index 0000000..876aec8 --- /dev/null +++ b/frontend/src/lib/Enums.ts @@ -0,0 +1,325 @@ +import { + ArchiveSort, + ArtistSort, + Category, + Censorship, + CharacterSort, + CircleSort, + ComicSort, + Direction, + Language, + Layout, + NamespaceSort, + Rating, + TagSort, + UpdateMode, + WorldSort +} from '$gql/graphql'; + +export interface EnumOption { + id: T; + name: string; +} + +export const DirectionLabel: Record = { + [Direction.LeftToRight]: 'Left to Right', + [Direction.RightToLeft]: 'Right to Left' +}; + +export const LayoutLabel: Record = { + [Layout.Single]: 'Single Page', + [Layout.Double]: 'Double Page', + [Layout.DoubleOffset]: 'Double Page, offset' +}; + +export const RatingLabel: Record = { + [Rating.Safe]: 'Safe', + [Rating.Questionable]: 'Questionable', + [Rating.Explicit]: 'Explicit' +}; + +export const CensorshipLabel: Record = { + [Censorship.None]: 'None', + [Censorship.Bar]: 'Bars', + [Censorship.Mosaic]: 'Mosaic', + [Censorship.Full]: 'Full' +}; + +export const CategoryLabel: Record = { + [Category.Manga]: 'Manga', + [Category.Doujinshi]: 'Doujinshi', + [Category.Comic]: 'Comic', + [Category.Artbook]: 'Artbook', + [Category.GameCg]: 'Game CG', + [Category.ImageSet]: 'Image Set', + [Category.VariantSet]: 'Variant Set', + [Category.Webtoon]: 'Webtoon' +}; + +export const ArchiveSortLabel: Record = { + [ArchiveSort.Path]: 'Path', + [ArchiveSort.Size]: 'File Size', + [ArchiveSort.CreatedAt]: 'Created At', + [ArchiveSort.PageCount]: 'Page Count', + [ArchiveSort.Random]: 'Random' +}; + +export const ComicSortLabel: Record = { + [ComicSort.Title]: 'Title', + [ComicSort.OriginalTitle]: 'Original Title', + [ComicSort.Date]: 'Date', + [ComicSort.CreatedAt]: 'Created At', + [ComicSort.UpdatedAt]: 'Updated At', + [ComicSort.TagCount]: 'Tag Count', + [ComicSort.PageCount]: 'Page Count', + [ComicSort.Random]: 'Random' +}; + +export const ArtistSortLabel: Record = { + [ArtistSort.Name]: 'Name', + [ArtistSort.CreatedAt]: 'Created At', + [ArtistSort.UpdatedAt]: 'Updated At', + [ArchiveSort.Random]: 'Random' +}; + +export const CharacterSortLabel: Record = { + [CharacterSort.Name]: 'Name', + [CharacterSort.CreatedAt]: 'Created At', + [CharacterSort.UpdatedAt]: 'Updated At', + [ArchiveSort.Random]: 'Random' +}; + +export const CircleSortLabel: Record = { + [CircleSort.Name]: 'Name', + [CircleSort.CreatedAt]: 'Created At', + [CircleSort.UpdatedAt]: 'Updated At', + [ArchiveSort.Random]: 'Random' +}; + +export const NamespaceSortLabel: Record = { + [NamespaceSort.Name]: 'Name', + [NamespaceSort.SortName]: 'Sort Name', + [NamespaceSort.CreatedAt]: 'Created At', + [NamespaceSort.UpdatedAt]: 'Updated At', + [ArchiveSort.Random]: 'Random' +}; + +export const TagSortLabel: Record = { + [TagSort.Name]: 'Name', + [TagSort.CreatedAt]: 'Created At', + [TagSort.UpdatedAt]: 'Updated At', + [ArchiveSort.Random]: 'Random' +}; + +export const WorldSortLabel: Record = { + [WorldSort.Name]: 'Name', + [WorldSort.CreatedAt]: 'Created At', + [WorldSort.UpdatedAt]: 'Updated At', + [ArchiveSort.Random]: 'Random' +}; + +export const UpdateModeLabel: Record = { + [UpdateMode.Add]: 'Add', + [UpdateMode.Remove]: 'Remove', + [UpdateMode.Replace]: 'Replace' +}; + +export const LanguageLabel: Record = { + [Language.Ab]: 'Abkhazian', + [Language.Aa]: 'Afar', + [Language.Af]: 'Afrikaans', + [Language.Ak]: 'Akan', + [Language.Sq]: 'Albanian', + [Language.Am]: 'Amharic', + [Language.Ar]: 'Arabic', + [Language.An]: 'Aragonese', + [Language.Hy]: 'Armenian', + [Language.As]: 'Assamese', + [Language.Av]: 'Avaric', + [Language.Ae]: 'Avestan', + [Language.Ay]: 'Aymara', + [Language.Az]: 'Azerbaijani', + [Language.Bm]: 'Bambara', + [Language.Ba]: 'Bashkir', + [Language.Eu]: 'Basque', + [Language.Be]: 'Belarusian', + [Language.Bn]: 'Bengali', + [Language.Bh]: 'Bihari languages', + [Language.Bi]: 'Bislama', + [Language.Bs]: 'Bosnian', + [Language.Br]: 'Breton', + [Language.Bg]: 'Bulgarian', + [Language.My]: 'Burmese', + [Language.Ca]: 'Catalan', + [Language.Km]: 'Central Khmer', + [Language.Ch]: 'Chamorro', + [Language.Ce]: 'Chechen', + [Language.Ny]: 'Chichewa', + [Language.Zh]: 'Chinese', + [Language.Cu]: 'Church Slavic', + [Language.Cv]: 'Chuvash', + [Language.Kw]: 'Cornish', + [Language.Co]: 'Corsican', + [Language.Cr]: 'Cree', + [Language.Hr]: 'Croatian', + [Language.Cs]: 'Czech', + [Language.Da]: 'Danish', + [Language.Dv]: 'Divehi', + [Language.Nl]: 'Dutch', + [Language.Dz]: 'Dzongkha', + [Language.En]: 'English', + [Language.Eo]: 'Esperanto', + [Language.Et]: 'Estonian', + [Language.Ee]: 'Ewe', + [Language.Fo]: 'Faroese', + [Language.Fj]: 'Fijian', + [Language.Fi]: 'Finnish', + [Language.Fr]: 'French', + [Language.Ff]: 'Fulah', + [Language.Gd]: 'Gaelic', + [Language.Gl]: 'Galician', + [Language.Lg]: 'Ganda', + [Language.Ka]: 'Georgian', + [Language.De]: 'German', + [Language.Gn]: 'Guarani', + [Language.Gu]: 'Gujarati', + [Language.Ht]: 'Haitian', + [Language.Ha]: 'Hausa', + [Language.He]: 'Hebrew', + [Language.Hz]: 'Herero', + [Language.Hi]: 'Hindi', + [Language.Ho]: 'Hiri Motu', + [Language.Hu]: 'Hungarian', + [Language.Is]: 'Icelandic', + [Language.Io]: 'Ido', + [Language.Ig]: 'Igbo', + [Language.Id]: 'Indonesian', + [Language.Ia]: 'Interlingua', + [Language.Ie]: 'Interlingue', + [Language.Iu]: 'Inuktitut', + [Language.Ik]: 'Inupiaq', + [Language.Ga]: 'Irish', + [Language.It]: 'Italian', + [Language.Ja]: 'Japanese', + [Language.Jv]: 'Javanese', + [Language.Kl]: 'Kalaallisut', + [Language.Kn]: 'Kannada', + [Language.Kr]: 'Kanuri', + [Language.Ks]: 'Kashmiri', + [Language.Kk]: 'Kazakh', + [Language.Ki]: 'Kikuyu', + [Language.Rw]: 'Kinyarwanda', + [Language.Ky]: 'Kirghiz', + [Language.Kv]: 'Komi', + [Language.Kg]: 'Kongo', + [Language.Ko]: 'Korean', + [Language.Kj]: 'Kuanyama', + [Language.Ku]: 'Kurdish', + [Language.Lo]: 'Lao', + [Language.La]: 'Latin', + [Language.Lv]: 'Latvian', + [Language.Li]: 'Limburgan', + [Language.Ln]: 'Lingala', + [Language.Lt]: 'Lithuanian', + [Language.Lu]: 'Luba-Katanga', + [Language.Lb]: 'Luxembourgish', + [Language.Mk]: 'Macedonian', + [Language.Mg]: 'Malagasy', + [Language.Ms]: 'Malay', + [Language.Ml]: 'Malayalam', + [Language.Mt]: 'Maltese', + [Language.Gv]: 'Manx', + [Language.Mi]: 'Maori', + [Language.Mr]: 'Marathi', + [Language.Mh]: 'Marshallese', + [Language.El]: 'Modern Greek', + [Language.Mn]: 'Mongolian', + [Language.Na]: 'Nauru', + [Language.Nv]: 'Navajo', + [Language.Ng]: 'Ndonga', + [Language.Ne]: 'Nepali', + [Language.Se]: 'Northern Sami', + [Language.Nd]: 'North Ndebele', + [Language.No]: 'Norwegian', + [Language.Nb]: 'Norwegian Bokmål', + [Language.Nn]: 'Norwegian Nynorsk', + [Language.Oc]: 'Occitan', + [Language.Oj]: 'Ojibwa', + [Language.Or]: 'Oriya', + [Language.Om]: 'Oromo', + [Language.Os]: 'Ossetian', + [Language.Pi]: 'Pali', + [Language.Pa]: 'Panjabi', + [Language.Fa]: 'Persian', + [Language.Pl]: 'Polish', + [Language.Pt]: 'Portuguese', + [Language.Ps]: 'Pushto', + [Language.Qu]: 'Quechua', + [Language.Ro]: 'Romanian', + [Language.Rm]: 'Romansh', + [Language.Rn]: 'Rundi', + [Language.Ru]: 'Russian', + [Language.Sm]: 'Samoan', + [Language.Sg]: 'Sango', + [Language.Sa]: 'Sanskrit', + [Language.Sc]: 'Sardinian', + [Language.Sr]: 'Serbian', + [Language.Sn]: 'Shona', + [Language.Ii]: 'Sichuan Yi', + [Language.Sd]: 'Sindhi', + [Language.Si]: 'Sinhala', + [Language.Sk]: 'Slovak', + [Language.Sl]: 'Slovenian', + [Language.So]: 'Somali', + [Language.St]: 'Southern Sotho', + [Language.Nr]: 'South Ndebele', + [Language.Es]: 'Spanish', + [Language.Su]: 'Sundanese', + [Language.Sw]: 'Swahili', + [Language.Ss]: 'Swati', + [Language.Sv]: 'Swedish', + [Language.Tl]: 'Tagalog', + [Language.Ty]: 'Tahitian', + [Language.Tg]: 'Tajik', + [Language.Ta]: 'Tamil', + [Language.Tt]: 'Tatar', + [Language.Te]: 'Telugu', + [Language.Th]: 'Thai', + [Language.Bo]: 'Tibetan', + [Language.Ti]: 'Tigrinya', + [Language.To]: 'Tonga', + [Language.Ts]: 'Tsonga', + [Language.Tn]: 'Tswana', + [Language.Tr]: 'Turkish', + [Language.Tk]: 'Turkmen', + [Language.Tw]: 'Twi', + [Language.Ug]: 'Uighur', + [Language.Uk]: 'Ukrainian', + [Language.Ur]: 'Urdu', + [Language.Uz]: 'Uzbek', + [Language.Ve]: 'Venda', + [Language.Vi]: 'Vietnamese', + [Language.Vo]: 'Volapük', + [Language.Wa]: 'Walloon', + [Language.Cy]: 'Welsh', + [Language.Fy]: 'Western Frisian', + [Language.Wo]: 'Wolof', + [Language.Xh]: 'Xhosa', + [Language.Yi]: 'Yiddish', + [Language.Yo]: 'Yoruba', + [Language.Za]: 'Zhuang', + [Language.Zu]: 'Zulu' +}; + +export const directions: EnumOption[] = optionsFromLabel(DirectionLabel); +export const layouts: EnumOption[] = optionsFromLabel(LayoutLabel); +export const ratings: EnumOption[] = optionsFromLabel(RatingLabel); +export const censorships: EnumOption[] = optionsFromLabel(CensorshipLabel); +export const categories: EnumOption[] = optionsFromLabel(CategoryLabel); +export const languages: EnumOption[] = optionsFromLabel(LanguageLabel); + +function optionsFromLabel( + labels: Record +): EnumOption[] { + return Object.entries(labels).map(([k, v]) => ({ id: k as T, name: v as string })); +} diff --git a/frontend/src/lib/Filter.ts b/frontend/src/lib/Filter.ts new file mode 100644 index 0000000..8e419f3 --- /dev/null +++ b/frontend/src/lib/Filter.ts @@ -0,0 +1,365 @@ +import { + type ArchiveFilter, + type ArchiveFilterInput, + type ComicFilter, + type ComicFilterInput, + type StringFilter, + type TagFilter, + type TagFilterInput +} from '$gql/graphql'; +import { getContext, setContext } from 'svelte'; +import { writable, type Writable } from 'svelte/store'; +import { navigate } from './Navigation'; +import { numKeys } from './Utils'; + +interface FilterInput { + include?: T | null; + exclude?: T | null; +} + +interface BasicFilter { + name?: { contains?: string | null } | null; +} + +type FilterMode = 'any' | 'all' | 'exact'; + +type Key = string | number | symbol; + +type Filter = { + [Property in K]?: T | null; +}; + +type AssocFilter = Filter< + { + any?: T[] | null; + all?: T[] | null; + exact?: T[] | null; + empty?: boolean | null; + }, + K +>; + +type EnumFilter = Filter< + { + any?: string[] | null; + empty?: boolean | null; + }, + K +>; + +interface Integrateable { + integrate(filter: F): void; +} + +class ComplexMember { + values: unknown[] = []; + key: K; + mode: FilterMode; + empty?: boolean | null; + + constructor(key: K, mode: FilterMode) { + this.key = key; + this.mode = mode; + } + + integrate(filter: AssocFilter) { + if (this.values.length > 0) { + filter[this.key] = { [this.mode]: this.values }; + } + + if (this.empty) { + filter[this.key] = { ...filter[this.key], empty: this.empty }; + } + } +} + +export class Association extends ComplexMember { + values: (string | number)[] = []; + + constructor(key: K, mode: FilterMode, filter?: AssocFilter | null) { + super(key, mode); + + if (!filter) { + return; + } + + const prop = filter[key]; + this.empty = prop?.empty; + + if (prop?.all && prop.all.length > 0) { + this.mode = 'all'; + this.values = prop.all; + } else if (prop?.any && prop.any.length > 0) { + this.mode = 'any'; + this.values = prop.any; + } else if (prop?.exact && prop.exact.length > 0) { + this.mode = 'exact'; + this.values = prop.exact; + } + } +} + +export class Enum extends ComplexMember { + values: string[] = []; + + constructor(key: K, filter?: EnumFilter | null) { + super(key, 'any'); + + if (!filter) { + return; + } + + this.empty = filter[key]?.empty; + + const prop = filter[key]; + if (prop?.any) { + this.values = prop.any; + } + } +} + +class Bool { + key: K; + value?: boolean = undefined; + + constructor(key: K, filter?: Filter | null) { + this.key = key; + + if (filter) { + this.value = filter[key] ?? undefined; + } + } + + integrate(filter: Filter) { + if (this.value !== undefined) { + filter[this.key] = this.value; + } + } +} + +class Str { + key: K; + contains = ''; + + constructor(key: K, filter?: Filter | null) { + this.key = key; + + if (filter) { + this.contains = filter[key]?.contains ?? ''; + } + } + + integrate(filter: Filter) { + if (this.contains) { + filter[this.key] = { contains: this.contains }; + } + } +} + +abstract class Controls { + buildFilter() { + const filter = {} as F; + Object.values(this).forEach((v: Integrateable) => v.integrate(filter)); + return filter; + } +} + +export class ArchiveFilterControls extends Controls { + path: Str<'path'>; + organized: Bool<'organized'>; + + constructor(filter: ArchiveFilter | null | undefined) { + super(); + + this.path = new Str('path', filter); + this.organized = new Bool('organized', filter); + } +} + +export class ComicFilterControls extends Controls { + title: Str<'title'>; + categories: Enum<'category'>; + censorships: Enum<'censorship'>; + ratings: Enum<'rating'>; + tags: Association<'tags'>; + languages: Enum<'language'>; + artists: Association<'artists'>; + circles: Association<'circles'>; + characters: Association<'characters'>; + worlds: Association<'worlds'>; + favourite: Bool<'favourite'>; + organized: Bool<'organized'>; + bookmarked: Bool<'bookmarked'>; + + constructor(filter: ComicFilter | null | undefined, mode: FilterMode); + constructor(filter: ComicFilter | null | undefined, mode: FilterMode); + constructor(filter: ComicFilter | null | undefined, mode: FilterMode) { + super(); + + this.title = new Str('title', filter); + this.favourite = new Bool('favourite', filter); + this.organized = new Bool('organized', filter); + this.bookmarked = new Bool('bookmarked', filter); + this.tags = new Association('tags', mode, filter); + this.languages = new Enum('language', filter); + this.categories = new Enum('category', filter); + this.censorships = new Enum('censorship', filter); + this.ratings = new Enum('rating', filter); + this.artists = new Association('artists', mode, filter); + this.circles = new Association('circles', mode, filter); + this.characters = new Association('characters', mode, filter); + this.worlds = new Association('worlds', mode, filter); + } +} + +export class BasicFilterControls extends Controls { + name: Str<'name'>; + + constructor(filter?: BasicFilter | null) { + super(); + + this.name = new Str('name', filter); + } +} + +export class TagFilterControls extends BasicFilterControls { + namespaces: Association<'namespaces'>; + + constructor(filter: TagFilter | null | undefined, mode: FilterMode) { + super(filter); + + this.namespaces = new Association('namespaces', mode, filter); + } +} + +function buildFilterInput(include?: F, exclude?: F) { + const input: FilterInput = {}; + + if (include && Object.keys(include).length > 0) { + input.include = include; + } + + if (exclude && Object.keys(exclude).length > 0) { + input.exclude = exclude; + } + + return input; +} + +abstract class FilterContext { + include!: { controls: Controls; size: number }; + exclude!: { controls: Controls; size: number }; + + apply(params: URLSearchParams) { + navigate( + { + filter: buildFilterInput( + this.include.controls.buildFilter(), + this.exclude.controls.buildFilter() + ) + }, + params + ); + } +} + +export class ArchiveFilterContext extends FilterContext { + include: { controls: ArchiveFilterControls; size: number }; + exclude: { controls: ArchiveFilterControls; size: number }; + private static ignore = ['organized']; + + constructor(filter: ArchiveFilterInput) { + super(); + + this.include = { + controls: new ArchiveFilterControls(filter.include), + size: numKeys(filter.include, ArchiveFilterContext.ignore) + }; + this.exclude = { + controls: new ArchiveFilterControls(filter.exclude), + size: numKeys(filter.exclude, ArchiveFilterContext.ignore) + }; + } +} + +export class ComicFilterContext extends FilterContext { + include: { controls: ComicFilterControls; size: number }; + exclude: { controls: ComicFilterControls; size: number }; + private static ignore = ['title', 'favourite', 'organized', 'bookmarked']; + + constructor(filter: ComicFilterInput) { + super(); + + this.include = { + controls: new ComicFilterControls(filter.include, 'all'), + size: numKeys(filter.include, ComicFilterContext.ignore) + }; + this.exclude = { + controls: new ComicFilterControls(filter.exclude, 'any'), + size: numKeys(filter.exclude, ComicFilterContext.ignore) + }; + } +} + +export class BasicFilterContext extends FilterContext { + include: { controls: BasicFilterControls; size: number }; + exclude: { controls: BasicFilterControls; size: number }; + + constructor(filter: FilterInput) { + super(); + + this.include = { + controls: new BasicFilterControls(filter.include), + size: numKeys(filter.include) + }; + this.exclude = { + controls: new BasicFilterControls(), + size: 0 + }; + } +} + +export class TagFilterContext extends FilterContext { + include: { controls: TagFilterControls; size: number }; + exclude: { controls: TagFilterControls; size: number }; + private static ignore = ['name']; + + constructor(filter: TagFilterInput) { + super(); + + this.include = { + controls: new TagFilterControls(filter.include, 'all'), + size: numKeys(filter.include, TagFilterContext.ignore) + }; + this.exclude = { + controls: new TagFilterControls(filter.exclude, 'any'), + size: numKeys(filter.exclude, TagFilterContext.ignore) + }; + } +} + +export function initFilterContext>() { + return setContext>('filter', writable()); +} + +export function getFilterContext>() { + return getContext>('filter'); +} + +export function cycleBooleanFilter(value: boolean | undefined, tristate = true) { + if (tristate) { + if (value === undefined) { + return true; + } else if (value) { + return false; + } else { + return undefined; + } + } else { + if (value) { + return undefined; + } else { + return true; + } + } +} diff --git a/frontend/src/lib/Meta.ts b/frontend/src/lib/Meta.ts new file mode 100644 index 0000000..8cfad6b --- /dev/null +++ b/frontend/src/lib/Meta.ts @@ -0,0 +1 @@ +export const codename = 'Satanic Satyr'; diff --git a/frontend/src/lib/Navigation.ts b/frontend/src/lib/Navigation.ts new file mode 100644 index 0000000..e6b17cd --- /dev/null +++ b/frontend/src/lib/Navigation.ts @@ -0,0 +1,114 @@ +import { goto as svelteGoto } from '$app/navigation'; +import { SortDirection } from '$gql/graphql'; +import JsonURL from '@jsonurl/jsonurl'; +import { type PaginationData } from './Pagination'; +import { type SortData } from './Sort'; +import { toastError } from './Toasts'; + +function paramToNum(value: string | null, fallback: T) { + if (value) { + const number = +value; + + if (Number.isNaN(number) || number < 0) { + return fallback; + } + + return number; + } + + return fallback; +} + +export function parseSortData(params: URLSearchParams, fallback: T): SortData { + return { + on: (params.get('s') as T) || fallback, + direction: (params.get('d') as SortDirection) || SortDirection.Ascending, + seed: paramToNum(params.get('r'), undefined) + }; +} + +export function parsePaginationData(params: URLSearchParams, defaultItems = 120): PaginationData { + return { + page: paramToNum(params.get('p'), 1), + items: paramToNum(params.get('i'), defaultItems) + }; +} + +export function parseFilter(params: URLSearchParams): T { + const param = params.get('f'); + + if (!param) return {} as T; + + try { + return JsonURL.parse(param, { AQF: true, impliedObject: {} }) as T; + } catch (e) { + return {} as T; + } +} + +interface NavigationOptions { + to?: string; + params: URLSearchParams; + options?: Parameters[1]; +} + +export function goto({ to = '', params, options }: NavigationOptions) { + svelteGoto(`${to}?${params.toString()}`, options).catch(() => toastError('Navigation failed')); +} + +interface NavigationParameters { + filter?: T; + sort?: Partial>; + pagination?: Partial; +} + +function paramsFrom( + { pagination, filter, sort }: NavigationParameters, + current?: URLSearchParams +) { + const params = new URLSearchParams(current); + + if (filter !== undefined) { + const json = JsonURL.stringify(filter, { AQF: true, impliedObject: true }); + if (json) { + params.set('f', json); + } else { + params.delete('f'); + } + } + + if (sort !== undefined) { + if (sort.on !== undefined) { + params.set('s', sort.on); + } + if (sort.direction !== undefined) { + params.set('d', sort.direction); + } + if (sort.seed !== undefined) { + params.set('r', sort.seed.toString()); + } + } + + params.delete('p'); + + if (pagination?.items) { + params.set('i', pagination.items.toString()); + } + + if (pagination?.page) { + params.set('p', pagination.page.toString()); + } + + return params; +} + +export function navigate(parameters: NavigationParameters, current?: URLSearchParams) { + goto({ + params: paramsFrom(parameters, current), + options: { noScroll: false, keepFocus: true, replaceState: true } + }); +} + +export function href(base: string, params: NavigationParameters) { + return `/${base}/?${paramsFrom(params).toString()}`; +} diff --git a/frontend/src/lib/Pagination.ts b/frontend/src/lib/Pagination.ts new file mode 100644 index 0000000..f05492b --- /dev/null +++ b/frontend/src/lib/Pagination.ts @@ -0,0 +1,31 @@ +import { navigate } from '$lib/Navigation'; +import { getContext, setContext } from 'svelte'; +import { writable, type Writable } from 'svelte/store'; + +export interface PaginationData { + page: number; + items: number; +} + +export class PaginationContext { + page = 0; + items = 0; + total = 0; + + set update({ page, items }: PaginationData) { + this.page = page; + this.items = items; + } + + apply(params: URLSearchParams) { + navigate({ pagination: { items: this.items } }, params); + } +} + +export function initPaginationContext() { + return setContext>('pagination', writable(new PaginationContext())); +} + +export function getPaginationContext() { + return getContext>('pagination'); +} diff --git a/frontend/src/lib/Reader.ts b/frontend/src/lib/Reader.ts new file mode 100644 index 0000000..8777b9b --- /dev/null +++ b/frontend/src/lib/Reader.ts @@ -0,0 +1,62 @@ +import { Layout, type PageFragment } from '$gql/graphql'; +import { getContext, setContext } from 'svelte'; +import { writable, type Writable } from 'svelte/store'; + +export interface Chunk { + main: PageFragment; + secondary?: PageFragment; + index: number; +} + +class ReaderContext { + visible = false; + sidebar = false; + pages: PageFragment[] = []; + page = 0; + + open(page: number) { + this.page = page; + this.visible = true; + + return this; + } +} + +export function initReaderContext() { + return setContext>('reader', writable(new ReaderContext())); +} + +export function getReaderContext() { + return getContext>('reader'); +} + +export function partition(pages: PageFragment[], layout: Layout): [Chunk[], number[]] { + const single = layout === Layout.Single; + const offset = layout === Layout.DoubleOffset; + + const chunks: Chunk[] = []; + const lookup: number[] = Array(pages.length); + + for (let chunkIndex = 0, pageIndex = 0; pageIndex < pages.length; chunkIndex++) { + const wide = () => pages[pageIndex].image.aspectRatio > 1; + + const nextPage = () => { + lookup[pageIndex] = chunkIndex; + return pages[pageIndex++]; + }; + + const offsetFirst = pageIndex === 0 && offset; + const full = single || wide() || offsetFirst; + + const chunk: Chunk = { index: pageIndex, main: nextPage() }; + + if (!full && pageIndex < pages.length) { + if (!wide()) { + chunk.secondary = nextPage(); + } + } + + chunks.push(chunk); + } + return [chunks, lookup]; +} diff --git a/frontend/src/lib/Scraper.ts b/frontend/src/lib/Scraper.ts new file mode 100644 index 0000000..4baf370 --- /dev/null +++ b/frontend/src/lib/Scraper.ts @@ -0,0 +1,156 @@ +import { + Category, + Censorship, + Direction, + Language, + Layout, + OnMissing, + Rating, + type FullComicFragment, + type ScrapedComic, + type UpsertComicInput, + type UpsertOptions +} from '$gql/graphql'; +import { + CategoryLabel, + CensorshipLabel, + DirectionLabel, + LanguageLabel, + LayoutLabel, + RatingLabel +} from '$lib/Enums'; +import { getContext, setContext } from 'svelte'; +import { writable, type Writable } from 'svelte/store'; + +interface ScraperContext { + scraper: string; + warnings: string[]; + selector?: ScrapedComicSelector; +} + +export function initScraperContext() { + return setContext>('scraper', writable({ scraper: '', warnings: [] })); +} + +export function getScraperContext() { + return getContext>('scraper'); +} + +export class Selector { + keep = true; + value: T; + display: string | undefined; + + constructor(value: T, display?: string) { + this.value = value; + this.display = display; + } + + toString() { + return this.display ?? this.value; + } + + static from( + scraped: T | undefined | null, + have: string | undefined | null, + label?: Record + ) { + if (scraped && have !== scraped) { + return new Selector(scraped, label ? label[scraped] : undefined); + } + return undefined; + } + + static fromList(scraped: string[], have: { name: string }[]) { + const haves = new Set(have.map((i) => i.name)); + + return scraped.filter((i) => !haves.has(i)).map((i) => new Selector(i)); + } +} + +function keepItem(selector?: Selector): T | undefined | null { + if (selector?.keep) { + return selector.value; + } + return undefined; +} + +function keepList( + selectorList: Selector[], + onMissing: OnMissing +): { names: T[]; options: UpsertOptions } { + return { + names: selectorList.filter((v) => v.keep).map((v) => v.value), + options: { onMissing } + }; +} + +export class ScrapedComicSelector { + title?: Selector; + originalTitle?: Selector; + url?: Selector; + date?: Selector; + category?: Selector; + censorship?: Selector; + rating?: Selector; + language?: Selector; + direction?: Selector; + layout?: Selector; + artists: Selector[]; + circles: Selector[]; + characters: Selector[]; + worlds: Selector[]; + tags: Selector[]; + + constructor(scraped: ScrapedComic, comic: FullComicFragment) { + this.title = Selector.from(scraped.title, comic.title); + this.originalTitle = Selector.from(scraped.originalTitle, comic.originalTitle); + this.url = Selector.from(scraped.url, comic.url); + this.date = Selector.from(scraped.date, comic.date); + this.category = Selector.from(scraped.category, comic.category, CategoryLabel); + this.censorship = Selector.from(scraped.censorship, comic.censorship, CensorshipLabel); + this.rating = Selector.from(scraped.rating, comic.rating, RatingLabel); + this.language = Selector.from(scraped.language, comic.language, LanguageLabel); + this.direction = Selector.from(scraped.direction, comic.direction, DirectionLabel); + this.layout = Selector.from(scraped.layout, comic.layout, LayoutLabel); + + this.artists = Selector.fromList(scraped.artists, comic.artists); + this.circles = Selector.fromList(scraped.circles, comic.circles); + this.characters = Selector.fromList(scraped.characters, comic.characters); + this.tags = Selector.fromList(scraped.tags, comic.tags); + this.worlds = Selector.fromList(scraped.worlds, comic.worlds); + } + + hasData() { + return ( + Object.values(this).filter((i) => { + if (i === undefined) { + return false; + } else if (Array.isArray(i) && i.length === 0) { + return false; + } + return true; + }).length > 0 + ); + } + + toInput(onMissing: OnMissing): UpsertComicInput { + return { + title: keepItem(this.title), + originalTitle: keepItem(this.originalTitle), + url: keepItem(this.url), + date: keepItem(this.date), + category: keepItem(this.category), + censorship: keepItem(this.censorship), + rating: keepItem(this.rating), + language: keepItem(this.language), + direction: keepItem(this.direction), + layout: keepItem(this.layout), + artists: keepList(this.artists, onMissing), + circles: keepList(this.circles, onMissing), + characters: keepList(this.characters, onMissing), + worlds: keepList(this.worlds, onMissing), + tags: keepList(this.tags, onMissing) + }; + } +} diff --git a/frontend/src/lib/Selection.ts b/frontend/src/lib/Selection.ts new file mode 100644 index 0000000..0ea85cc --- /dev/null +++ b/frontend/src/lib/Selection.ts @@ -0,0 +1,141 @@ +import { getContext, hasContext, setContext } from 'svelte'; +import { writable, type Writable } from 'svelte/store'; +import { range } from './Utils'; + +interface Item { + id: number; +} + +export const hasSelectionContext = () => hasContext('selection'); + +export function getSelectionContext() { + return getContext>>('selection'); +} + +export function initSelectionContext( + typename?: string, + toName?: (item: T) => string +) { + return setContext>>( + 'selection', + writable(new ItemSelection(typename, toName)) + ); +} + +export class ItemSelection { + active = false; + typename: string; + #toName: (item: T) => string; + + #view: T[] = []; + selectable: (item: T) => boolean = () => true; + + #ids = new Set(); + #masked = new Set(); + + constructor(typename?: string, toName?: (item: T) => string) { + this.typename = typename ?? 'unknown'; + this.#toName = toName ?? (() => 'unknown'); + } + + set view(view: T[]) { + this.#view = view; + this.#updateMasked(); + } + + #indexOf = (id: number) => this.#view.findIndex((v) => v.id === id); + + update(index: number, shift: boolean) { + const id = this.#view[index].id; + + const selectableRange = (first: number, last: number) => + range(first, last) + .filter((i) => this.selectable(this.#view[i])) + .map((i) => this.#view[i].id); + + if (shift) { + const indices = this.indices; + + const first = indices.at(0); + const last = indices.at(-1); + + if (first === undefined || last === undefined) { + this.#ids.add(id); + } else if (index === first || index === last) { + this.#ids.clear(); + } else if (index > last) { + this.#ids = new Set([...this.#ids, ...selectableRange(last, index)]); + } else if (index < last) { + this.#ids = new Set([...this.#ids, ...selectableRange(index, last)]); + } + } else { + if (this.#ids.has(id)) { + this.#ids.delete(id); + } else { + this.#ids.add(id); + } + } + + this.#updateMasked(); + + return this; + } + + toggle() { + this.active = !this.active; + + if (!this.active) { + return this.none(); + } + + return this; + } + + all() { + this.#ids = new Set(this.#view.filter(this.selectable).map((i) => i.id)); + this.#updateMasked(); + + return this; + } + + none() { + this.#ids.clear(); + this.#masked.clear(); + + return this; + } + + clear() { + this.active = false; + + return this.none(); + } + + contains(id: number) { + return this.#masked.has(id); + } + + #updateMasked() { + this.#masked = new Set([...this.#ids].filter((i) => this.#indexOf(i) >= 0)); + } + + get ids() { + return [...this.#masked]; + } + + get size() { + return this.#masked.size; + } + + get indices() { + return [...this.#ids].map(this.#indexOf).filter((i) => i >= 0); + } + + get items() { + return this.indices.map((i) => this.#view[i]); + } + + get names() { + return this.items.map(this.#toName); + } +} diff --git a/frontend/src/lib/Shortcuts.ts b/frontend/src/lib/Shortcuts.ts new file mode 100644 index 0000000..063bd40 --- /dev/null +++ b/frontend/src/lib/Shortcuts.ts @@ -0,0 +1,153 @@ +import { closeModal, modals } from 'svelte-modals'; +import { get } from 'svelte/store'; + +type LowercaseLetter = + | 'a' + | 'b' + | 'c' + | 'd' + | 'e' + | 'f' + | 'g' + | 'h' + | 'i' + | 'j' + | 'l' + | 'm' + | 'n' + | 'o' + | 'p' + | 'q' + | 'r' + | 's' + | 't' + | 'u' + | 'v' + | 'w' + | 'x' + | 'y' + | 'z'; + +type UppercaseLetter = Uppercase; +type Letter = LowercaseLetter | UppercaseLetter; +type Special = '?' | 'Enter' | 'Escape' | 'Delete'; + +const modeSwitches = ['n', 'g', 'i'] as const; +type ModeSwitch = (typeof modeSwitches)[number]; + +function isModeSwitch(s: string): s is ModeSwitch { + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument + return modeSwitches.indexOf(s as any) !== -1; +} + +type Key = Letter | Special; +type KeyCombo = `${ModeSwitch}${Letter}`; +export type Shortcut = Key | KeyCombo; + +type EventAction = (event: KeyboardEvent) => void; +type FocusAction = HTMLInputElement; +type ClickAction = HTMLElement; + +type Action = EventAction | FocusAction | ClickAction; + +const handlers = new Map(); +let mode: ModeSwitch | undefined; + +export function handleShortcuts(event: KeyboardEvent) { + if (isInputElement(event.target)) { + if (event.key === 'Escape') { + event.target.blur(); + event.preventDefault(); + event.stopImmediatePropagation(); + } + return; + } + + if (event.ctrlKey) { + return; + } + + if (event.key === 'Escape') { + if (get(modals).length > 0) { + closeModal(); + event.preventDefault(); + event.stopImmediatePropagation(); + return; + } + } + + if (isModeSwitch(event.key) && mode === undefined) { + mode = event.key; + event.preventDefault(); + return; + } + + const handler = handlers.get(mode === undefined ? event.key : `${mode}${event.key}`); + + if (!handler || get(modals).length > 0) { + mode = undefined; + return; + } + + if (handler instanceof HTMLInputElement) { + handler.focus(); + } else if (handler instanceof HTMLElement) { + handler.click(); + } else { + handler(event); + } + + mode = undefined; + event.preventDefault(); +} + +export function accelerator(node: HTMLElement | HTMLInputElement, sc: Shortcut) { + handlers.set(sc, node); + + return { + destroy() { + handlers.delete(sc); + } + }; +} + +export function binds(node: Document, scs: [string, EventAction][]) { + const handlers = new Map(); + + for (const [k, a] of scs) { + handlers.set(k, a); + } + + function keydown(event: KeyboardEvent) { + if (isInputElement(event.target)) return; + + const handler = handlers.get(event.key); + + if (!handler) return; + + handler(event); + event.preventDefault(); + } + + node.addEventListener('keydown', keydown); + + return { + destroy() { + node.removeEventListener('keydown', keydown); + } + }; +} + +export function addShortcut(sc: Shortcut, action: EventAction) { + handlers.set(sc, action); +} + +function isInputElement(target: EventTarget | null): target is HTMLElement { + return ( + target instanceof HTMLElement && + (target instanceof HTMLInputElement || + target instanceof HTMLSelectElement || + target instanceof HTMLTextAreaElement || + target.isContentEditable) + ); +} diff --git a/frontend/src/lib/Sort.ts b/frontend/src/lib/Sort.ts new file mode 100644 index 0000000..4c9a353 --- /dev/null +++ b/frontend/src/lib/Sort.ts @@ -0,0 +1,42 @@ +import { SortDirection } from '$gql/graphql'; +import { getContext, setContext } from 'svelte'; +import { writable, type Writable } from 'svelte/store'; +import { navigate } from './Navigation'; + +export interface SortData { + on: T; + direction: SortDirection; + seed: number | undefined; +} + +export class SortContext { + on: T; + direction: SortDirection; + seed: number | undefined; + labels: Record; + + constructor({ on, direction, seed }: SortData, labels: Record) { + this.on = on; + this.direction = direction; + this.seed = seed; + this.labels = labels; + } + + set update({ on, direction, seed }: SortData) { + this.on = on; + this.direction = direction; + this.seed = seed; + } + + apply(params: URLSearchParams) { + navigate({ sort: { on: this.on, direction: this.direction, seed: this.seed } }, params); + } +} + +export function initSortContext(sort: SortData, labels: Record) { + return setContext>>('sort', writable(new SortContext(sort, labels))); +} + +export function getSortContext() { + return getContext>>('sort'); +} diff --git a/frontend/src/lib/Tabs.ts b/frontend/src/lib/Tabs.ts new file mode 100644 index 0000000..1c43068 --- /dev/null +++ b/frontend/src/lib/Tabs.ts @@ -0,0 +1,18 @@ +import { getContext, setContext } from 'svelte'; +import { writable, type Writable } from 'svelte/store'; + +type Tab = string; +type Tabs = Record; + +interface TabContext { + tabs: Tabs; + current: Tab; +} + +export function setTabContext(context: TabContext) { + return setContext>('tabs', writable(context)); +} + +export function getTabContext() { + return getContext>('tabs'); +} diff --git a/frontend/src/lib/Toasts.ts b/frontend/src/lib/Toasts.ts new file mode 100644 index 0000000..abc9a7d --- /dev/null +++ b/frontend/src/lib/Toasts.ts @@ -0,0 +1,19 @@ +import { toast } from '@zerodevx/svelte-toast'; + +export function toastSuccess(message: string) { + toast.push(message, { + theme: { '--toastBackground': 'rgba(72, 187, 120, 0.9)', '--toastColor': 'mintcream' }, + duration: 1000 + }); +} + +export function toastError(message: string) { + toast.push(message, { + theme: { '--toastBackground': 'rgba(187, 72, 72, 0.9)', '--toastColor': 'lavenderblush' }, + duration: 5000, + pausable: true + }); +} + +// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any +export const toastFinally = (reason: any) => toastError(reason); diff --git a/frontend/src/lib/Transitions.ts b/frontend/src/lib/Transitions.ts new file mode 100644 index 0000000..59ebaf2 --- /dev/null +++ b/frontend/src/lib/Transitions.ts @@ -0,0 +1,10 @@ +import { quartInOut } from 'svelte/easing'; +import type { FadeParams, SlideParams } from 'svelte/transition'; + +export const fadeFast: FadeParams = { duration: 60 }; +export const fadeDefault: FadeParams = { duration: 100 }; + +export const slideYDefault: SlideParams = { axis: 'y', duration: 300, easing: quartInOut }; + +export const slideXDefault: SlideParams = { axis: 'x', duration: 300, easing: quartInOut }; +export const slideXFast: SlideParams = { axis: 'x', duration: 200 }; diff --git a/frontend/src/lib/Update.ts b/frontend/src/lib/Update.ts new file mode 100644 index 0000000..507dd52 --- /dev/null +++ b/frontend/src/lib/Update.ts @@ -0,0 +1,97 @@ +import { + UpdateMode, + type UpdateComicInput, + type UpdateOptions, + type UpdateTagInput +} from '$gql/graphql'; + +type Key = string | number | symbol; + +interface AssociationUpdate { + ids?: number[] | string[] | null; + options?: UpdateOptions | null; +} + +type Input = { + [Property in K]?: T | null; +}; + +abstract class Entry { + key: K; + + constructor(key: K) { + this.key = key; + } + + abstract integrate(input: Input): void; + abstract hasInput(): boolean; +} + +class Association extends Entry { + ids = []; + options = { + mode: UpdateMode.Add + }; + + constructor(key: K) { + super(key); + } + + integrate(input: Input) { + if (this.hasInput()) { + input[this.key] = { ids: this.ids, options: this.options }; + } + } + + hasInput() { + return this.ids.length > 0; + } +} + +class Enum extends Entry { + value?: string = undefined; + + constructor(key: K) { + super(key); + } + + integrate(input: Input): void { + if (this.hasInput()) { + input[this.key] = this.value; + } + } + + hasInput() { + return this.value !== undefined && this.value !== null; + } +} + +abstract class Controls { + toInput() { + const input = {} as I; + Object.values(this).forEach((v: Entry) => v.integrate(input)); + return input; + } + + hasInput() { + return Object.values(this).some((i: Entry) => i.hasInput()); + } +} + +export class UpdateTagsControls extends Controls { + namespaces = new Association('namespaces'); +} + +export class UpdateComicsControls extends Controls { + artists = new Association('artists'); + category = new Enum('category'); + censorship = new Enum('censorship'); + direction = new Enum('direction'); + layout = new Enum('layout'); + characters = new Association('characters'); + circles = new Association('circles'); + language = new Enum('language'); + rating = new Enum('rating'); + tags = new Association('tags'); + worlds = new Association('worlds'); +} diff --git a/frontend/src/lib/Utils.ts b/frontend/src/lib/Utils.ts new file mode 100644 index 0000000..1a07be1 --- /dev/null +++ b/frontend/src/lib/Utils.ts @@ -0,0 +1,108 @@ +import { isError } from '$gql/Utils'; +import type { ImageFragment } from '$gql/graphql'; +import type { BeforeNavigate } from '@sveltejs/kit'; +import type { OperationResultState } from '@urql/svelte'; +import { openModal } from 'svelte-modals'; +import ConfirmDeletion from './dialogs/ConfirmDeletion.svelte'; + +export function range(from: number, to: number) { + return Array.from({ length: to - from + 1 }, (_, k) => k + from); +} + +export function getRandomInt(min: number, max: number) { + const minCeiled = Math.ceil(min); + const maxFloored = Math.floor(max); + + return Math.floor(Math.random() * (maxFloored - minCeiled) + minCeiled); +} + +export interface ListItem { + id: number | string; + name: string; +} + +export interface ResultState { + fetching: boolean; + message?: string; +} + +export function getResultState(state: OperationResultState): ResultState { + let message: string | undefined; + + if (state.error) { + message = `${state.error.name}: ${state.error.message}`; + } else if (state.data) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + const obj = Object.values(state.data)[0]; + if (isError(obj)) { + message = obj.message; + } + } + + return { fetching: state.fetching, message: message }; +} + +export function src(image: ImageFragment, type: 'full' | 'thumb' = 'thumb') { + const dir = image.hash.slice(0, 2); + const file = image.hash.slice(2); + + return `/objects/${dir}/${file}_${type}.webp`; +} + +export function numKeys(obj?: object | null, ignore: string[] = []) { + if (!obj) return 0; + + const len = Object.keys(obj).length; + let ignored = 0; + + for (const i of ignore) { + if (Object.hasOwn(obj, i)) ignored++; + } + + return len - ignored; +} + +export function confirmDeletion( + typename: string, + names: string | string[], + callback: () => void, + warning?: string +) { + openModal( + ConfirmDeletion, + { names: Array.isArray(names) ? names : [names], typename, callback: callback, warning }, + { replace: true } + ); +} + +export function idFromLabel(label: string) { + return label.toLowerCase().replaceAll(' ', '-'); +} + +export function pluralize(singular: string, size: number) { + return `${singular}${size > 1 ? 's' : ''}`; +} + +export function formatListSize(word: string, size: number) { + return `${size} ${pluralize(word, size)}`; +} + +export function joinText(items: string[], separator = ', ') { + return items.filter((i) => i).join(separator); +} + +export function confirmPending() { + return confirm('There are pending changes. Click Cancel to keep editing or OK to dismiss them.'); +} + +export function preventOnPending({ to, cancel }: BeforeNavigate, pending: boolean) { + if (!pending) return; + + if (to) { + if (confirmPending()) { + return; + } + } + + cancel(); +} diff --git a/frontend/src/lib/assets/logo.webp b/frontend/src/lib/assets/logo.webp new file mode 100644 index 0000000..e41cbb0 Binary files /dev/null and b/frontend/src/lib/assets/logo.webp differ diff --git a/frontend/src/lib/components/AddButton.svelte b/frontend/src/lib/components/AddButton.svelte new file mode 100644 index 0000000..9c0ab29 --- /dev/null +++ b/frontend/src/lib/components/AddButton.svelte @@ -0,0 +1,7 @@ + + + diff --git a/frontend/src/lib/components/Badge.svelte b/frontend/src/lib/components/Badge.svelte new file mode 100644 index 0000000..7ad3173 --- /dev/null +++ b/frontend/src/lib/components/Badge.svelte @@ -0,0 +1,15 @@ + + +{#if number > 0} + + {number} + +{/if} diff --git a/frontend/src/lib/components/BookmarkButton.svelte b/frontend/src/lib/components/BookmarkButton.svelte new file mode 100644 index 0000000..89570e6 --- /dev/null +++ b/frontend/src/lib/components/BookmarkButton.svelte @@ -0,0 +1,9 @@ + + + diff --git a/frontend/src/lib/components/Card.svelte b/frontend/src/lib/components/Card.svelte new file mode 100644 index 0000000..2384799 --- /dev/null +++ b/frontend/src/lib/components/Card.svelte @@ -0,0 +1,106 @@ + + + + + + + {#if details.cover} + + {/if} + {#if !coverOnly} +
+
+

+ {details.title} +

+ {#if details.subtitle} +

+ {details.subtitle} +

+ {/if} + {#if details.favourite} +
+ +
+ {/if} +
+ +
+ +
+
+ {/if} +
+ + diff --git a/frontend/src/lib/components/Cardlet.svelte b/frontend/src/lib/components/Cardlet.svelte new file mode 100644 index 0000000..04d8599 --- /dev/null +++ b/frontend/src/lib/components/Cardlet.svelte @@ -0,0 +1,37 @@ + + + + + diff --git a/frontend/src/lib/components/DeleteButton.svelte b/frontend/src/lib/components/DeleteButton.svelte new file mode 100644 index 0000000..8f5f116 --- /dev/null +++ b/frontend/src/lib/components/DeleteButton.svelte @@ -0,0 +1,15 @@ + + + diff --git a/frontend/src/lib/components/Dialog.svelte b/frontend/src/lib/components/Dialog.svelte new file mode 100644 index 0000000..a0bbe5e --- /dev/null +++ b/frontend/src/lib/components/Dialog.svelte @@ -0,0 +1,36 @@ + + +{#if isOpen} + +{/if} diff --git a/frontend/src/lib/components/Dropdown.svelte b/frontend/src/lib/components/Dropdown.svelte new file mode 100644 index 0000000..9e935e4 --- /dev/null +++ b/frontend/src/lib/components/Dropdown.svelte @@ -0,0 +1,18 @@ + + +{#if visible} +
(visible = false), ignore: parent }} + > + +
+{/if} diff --git a/frontend/src/lib/components/Empty.svelte b/frontend/src/lib/components/Empty.svelte new file mode 100644 index 0000000..7f9557c --- /dev/null +++ b/frontend/src/lib/components/Empty.svelte @@ -0,0 +1,10 @@ + + +
+ +
+

There is nothing here...

+
+
diff --git a/frontend/src/lib/components/Expander.svelte b/frontend/src/lib/components/Expander.svelte new file mode 100644 index 0000000..a382658 --- /dev/null +++ b/frontend/src/lib/components/Expander.svelte @@ -0,0 +1,17 @@ + + + diff --git a/frontend/src/lib/components/Guard.svelte b/frontend/src/lib/components/Guard.svelte new file mode 100644 index 0000000..fd7ded4 --- /dev/null +++ b/frontend/src/lib/components/Guard.svelte @@ -0,0 +1,13 @@ + + +{#if state.fetching} + +{:else} +

{state.message}

+{/if} diff --git a/frontend/src/lib/components/Head.svelte b/frontend/src/lib/components/Head.svelte new file mode 100644 index 0000000..b4aed5b --- /dev/null +++ b/frontend/src/lib/components/Head.svelte @@ -0,0 +1,12 @@ + + + + {formatTitle(section, title)} + diff --git a/frontend/src/lib/components/Labelled.svelte b/frontend/src/lib/components/Labelled.svelte new file mode 100644 index 0000000..4b36ad6 --- /dev/null +++ b/frontend/src/lib/components/Labelled.svelte @@ -0,0 +1,10 @@ + + + + diff --git a/frontend/src/lib/components/LabelledBlock.svelte b/frontend/src/lib/components/LabelledBlock.svelte new file mode 100644 index 0000000..feb563e --- /dev/null +++ b/frontend/src/lib/components/LabelledBlock.svelte @@ -0,0 +1,18 @@ + + +
+
+ + {#if $$slots.controls} +
+ + {/if} +
+ +
diff --git a/frontend/src/lib/components/OrganizedButton.svelte b/frontend/src/lib/components/OrganizedButton.svelte new file mode 100644 index 0000000..9be985c --- /dev/null +++ b/frontend/src/lib/components/OrganizedButton.svelte @@ -0,0 +1,9 @@ + + + diff --git a/frontend/src/lib/components/RefreshButton.svelte b/frontend/src/lib/components/RefreshButton.svelte new file mode 100644 index 0000000..afab640 --- /dev/null +++ b/frontend/src/lib/components/RefreshButton.svelte @@ -0,0 +1,3 @@ + diff --git a/frontend/src/lib/components/RemovePageButton.svelte b/frontend/src/lib/components/RemovePageButton.svelte new file mode 100644 index 0000000..e23c079 --- /dev/null +++ b/frontend/src/lib/components/RemovePageButton.svelte @@ -0,0 +1,13 @@ + + + diff --git a/frontend/src/lib/components/Select.svelte b/frontend/src/lib/components/Select.svelte new file mode 100644 index 0000000..83f026c --- /dev/null +++ b/frontend/src/lib/components/Select.svelte @@ -0,0 +1,55 @@ + + +{#if options !== null && options !== undefined} + +{:else} + +{/if} diff --git a/frontend/src/lib/components/Spinner.svelte b/frontend/src/lib/components/Spinner.svelte new file mode 100644 index 0000000..946329c --- /dev/null +++ b/frontend/src/lib/components/Spinner.svelte @@ -0,0 +1,36 @@ + + +{#if show} +
+ +
+{/if} + + diff --git a/frontend/src/lib/components/SubmitButton.svelte b/frontend/src/lib/components/SubmitButton.svelte new file mode 100644 index 0000000..8ac90b9 --- /dev/null +++ b/frontend/src/lib/components/SubmitButton.svelte @@ -0,0 +1,7 @@ + + + diff --git a/frontend/src/lib/components/Titlebar.svelte b/frontend/src/lib/components/Titlebar.svelte new file mode 100644 index 0000000..8aab2dd --- /dev/null +++ b/frontend/src/lib/components/Titlebar.svelte @@ -0,0 +1,32 @@ + + +
+
+ {#if favourite !== undefined} + + {/if} +

{title}

+
+ + {#if subtitle} +

+ {subtitle} +

+ {/if} +
diff --git a/frontend/src/lib/containers/Cardlets.svelte b/frontend/src/lib/containers/Cardlets.svelte new file mode 100644 index 0000000..129da61 --- /dev/null +++ b/frontend/src/lib/containers/Cardlets.svelte @@ -0,0 +1,11 @@ + + +
+ +
diff --git a/frontend/src/lib/containers/Cards.svelte b/frontend/src/lib/containers/Cards.svelte new file mode 100644 index 0000000..a19e8be --- /dev/null +++ b/frontend/src/lib/containers/Cards.svelte @@ -0,0 +1,8 @@ + + +
+ +
diff --git a/frontend/src/lib/containers/Carousel.svelte b/frontend/src/lib/containers/Carousel.svelte new file mode 100644 index 0000000..1268a78 --- /dev/null +++ b/frontend/src/lib/containers/Carousel.svelte @@ -0,0 +1,15 @@ + + +
+

+ + {title} + +

+
+ +
+
diff --git a/frontend/src/lib/containers/Column.svelte b/frontend/src/lib/containers/Column.svelte new file mode 100644 index 0000000..05daece --- /dev/null +++ b/frontend/src/lib/containers/Column.svelte @@ -0,0 +1,3 @@ +
+ +
diff --git a/frontend/src/lib/containers/Grid.svelte b/frontend/src/lib/containers/Grid.svelte new file mode 100644 index 0000000..1224156 --- /dev/null +++ b/frontend/src/lib/containers/Grid.svelte @@ -0,0 +1,23 @@ + + +
+ +
+ + diff --git a/frontend/src/lib/dialogs/AddArtist.svelte b/frontend/src/lib/dialogs/AddArtist.svelte new file mode 100644 index 0000000..6ec93c5 --- /dev/null +++ b/frontend/src/lib/dialogs/AddArtist.svelte @@ -0,0 +1,30 @@ + + + + +

Add Artist

+
+ +
+ 0} /> +
+
+
diff --git a/frontend/src/lib/dialogs/AddCharacter.svelte b/frontend/src/lib/dialogs/AddCharacter.svelte new file mode 100644 index 0000000..23fea08 --- /dev/null +++ b/frontend/src/lib/dialogs/AddCharacter.svelte @@ -0,0 +1,30 @@ + + + + +

Add Character

+
+ +
+ 0} /> +
+
+
diff --git a/frontend/src/lib/dialogs/AddCircle.svelte b/frontend/src/lib/dialogs/AddCircle.svelte new file mode 100644 index 0000000..f0ef014 --- /dev/null +++ b/frontend/src/lib/dialogs/AddCircle.svelte @@ -0,0 +1,30 @@ + + + + +

Add Circle

+
+ +
+ 0} /> +
+
+
diff --git a/frontend/src/lib/dialogs/AddNamespace.svelte b/frontend/src/lib/dialogs/AddNamespace.svelte new file mode 100644 index 0000000..e81b22a --- /dev/null +++ b/frontend/src/lib/dialogs/AddNamespace.svelte @@ -0,0 +1,30 @@ + + + + +

Add Namespace

+
+ +
+ 0} /> +
+
+
diff --git a/frontend/src/lib/dialogs/AddTag.svelte b/frontend/src/lib/dialogs/AddTag.svelte new file mode 100644 index 0000000..00d3a03 --- /dev/null +++ b/frontend/src/lib/dialogs/AddTag.svelte @@ -0,0 +1,30 @@ + + + + +

Add Tag

+
+ +
+ 0} /> +
+
+
diff --git a/frontend/src/lib/dialogs/AddWorld.svelte b/frontend/src/lib/dialogs/AddWorld.svelte new file mode 100644 index 0000000..ceb946e --- /dev/null +++ b/frontend/src/lib/dialogs/AddWorld.svelte @@ -0,0 +1,30 @@ + + + + +

Add World

+
+ +
+ 0} /> +
+
+
diff --git a/frontend/src/lib/dialogs/ConfirmDeletion.svelte b/frontend/src/lib/dialogs/ConfirmDeletion.svelte new file mode 100644 index 0000000..6b0cbf8 --- /dev/null +++ b/frontend/src/lib/dialogs/ConfirmDeletion.svelte @@ -0,0 +1,51 @@ + + + + +

Delete {formattedTypename}

+
+
+
+

+ Are you sure you want to delete {formattedNames}? +

+ {#if multiple} +
    + {#each names.slice(0, 10) as name} +
  • {name}
  • + {/each} +
+ {#if names.length - 10 > 0} +

... and {names.length - 10} more.

+ {/if} + {/if} + {#if warning} +

Warning: {warning}

+ {/if} +
+ +
+ + +
+
+
diff --git a/frontend/src/lib/dialogs/EditArtist.svelte b/frontend/src/lib/dialogs/EditArtist.svelte new file mode 100644 index 0000000..dd08bc6 --- /dev/null +++ b/frontend/src/lib/dialogs/EditArtist.svelte @@ -0,0 +1,46 @@ + + + + +

Edit Artist

+
+ +
+ +
+ +
+ +
diff --git a/frontend/src/lib/dialogs/EditCharacter.svelte b/frontend/src/lib/dialogs/EditCharacter.svelte new file mode 100644 index 0000000..3b45e78 --- /dev/null +++ b/frontend/src/lib/dialogs/EditCharacter.svelte @@ -0,0 +1,46 @@ + + + + +

Edit Character

+
+ +
+ +
+ +
+ +
diff --git a/frontend/src/lib/dialogs/EditCircle.svelte b/frontend/src/lib/dialogs/EditCircle.svelte new file mode 100644 index 0000000..bdc1217 --- /dev/null +++ b/frontend/src/lib/dialogs/EditCircle.svelte @@ -0,0 +1,46 @@ + + + + +

Edit Circle

+
+ +
+ +
+ +
+ +
diff --git a/frontend/src/lib/dialogs/EditNamespace.svelte b/frontend/src/lib/dialogs/EditNamespace.svelte new file mode 100644 index 0000000..f398b21 --- /dev/null +++ b/frontend/src/lib/dialogs/EditNamespace.svelte @@ -0,0 +1,46 @@ + + + + +

Edit Namespace

+
+ +
+ +
+ +
+ +
diff --git a/frontend/src/lib/dialogs/EditTag.svelte b/frontend/src/lib/dialogs/EditTag.svelte new file mode 100644 index 0000000..d2d0013 --- /dev/null +++ b/frontend/src/lib/dialogs/EditTag.svelte @@ -0,0 +1,44 @@ + + + + +

Edit Tag

+
+ +
+ +
+ +
+ +
diff --git a/frontend/src/lib/dialogs/EditWorld.svelte b/frontend/src/lib/dialogs/EditWorld.svelte new file mode 100644 index 0000000..82afe6a --- /dev/null +++ b/frontend/src/lib/dialogs/EditWorld.svelte @@ -0,0 +1,46 @@ + + + + +

Edit World

+
+ +
+ +
+ +
+ +
diff --git a/frontend/src/lib/dialogs/UpdateComics.svelte b/frontend/src/lib/dialogs/UpdateComics.svelte new file mode 100644 index 0000000..8de9622 --- /dev/null +++ b/frontend/src/lib/dialogs/UpdateComics.svelte @@ -0,0 +1,96 @@ + + + + +

Edit Comics

+
+
+
+ + + + + + + + + +
+ + + + + + + + + + + + + + +
+ +
+
+
diff --git a/frontend/src/lib/dialogs/components/UpdateModeSelector.svelte b/frontend/src/lib/dialogs/components/UpdateModeSelector.svelte new file mode 100644 index 0000000..e4b4479 --- /dev/null +++ b/frontend/src/lib/dialogs/components/UpdateModeSelector.svelte @@ -0,0 +1,24 @@ + + +
+ {#each Object.entries(UpdateModeLabel) as [e, label]} + + {/each} +
diff --git a/frontend/src/lib/filter/ComicFilterForm.svelte b/frontend/src/lib/filter/ComicFilterForm.svelte new file mode 100644 index 0000000..13b5320 --- /dev/null +++ b/frontend/src/lib/filter/ComicFilterForm.svelte @@ -0,0 +1,48 @@ + + + + + + diff --git a/frontend/src/lib/filter/TagFilterForm.svelte b/frontend/src/lib/filter/TagFilterForm.svelte new file mode 100644 index 0000000..be5996e --- /dev/null +++ b/frontend/src/lib/filter/TagFilterForm.svelte @@ -0,0 +1,31 @@ + + + + + + diff --git a/frontend/src/lib/filter/components/ComicFilterGroup.svelte b/frontend/src/lib/filter/components/ComicFilterGroup.svelte new file mode 100644 index 0000000..d302de4 --- /dev/null +++ b/frontend/src/lib/filter/components/ComicFilterGroup.svelte @@ -0,0 +1,27 @@ + + + + + + + + + + + diff --git a/frontend/src/lib/filter/components/Filter.svelte b/frontend/src/lib/filter/components/Filter.svelte new file mode 100644 index 0000000..ead5c4d --- /dev/null +++ b/frontend/src/lib/filter/components/Filter.svelte @@ -0,0 +1,77 @@ + + +
+
+ +
+ {#if filter instanceof Association} + + + +
+ {/if} + +
+
+ + +
+ + diff --git a/frontend/src/lib/forms/CharacterForm.svelte b/frontend/src/lib/forms/CharacterForm.svelte new file mode 100644 index 0000000..4cec37c --- /dev/null +++ b/frontend/src/lib/forms/CharacterForm.svelte @@ -0,0 +1,25 @@ + + +
+
+ + + + +
+ + diff --git a/frontend/src/lib/forms/CircleForm.svelte b/frontend/src/lib/forms/CircleForm.svelte new file mode 100644 index 0000000..b71256c --- /dev/null +++ b/frontend/src/lib/forms/CircleForm.svelte @@ -0,0 +1,25 @@ + + +
+
+ + + + +
+ + diff --git a/frontend/src/lib/forms/ComicForm.svelte b/frontend/src/lib/forms/ComicForm.svelte new file mode 100644 index 0000000..74051c8 --- /dev/null +++ b/frontend/src/lib/forms/ComicForm.svelte @@ -0,0 +1,100 @@ + + +
+
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + +
+ + diff --git a/frontend/src/lib/forms/TagForm.svelte b/frontend/src/lib/forms/TagForm.svelte new file mode 100644 index 0000000..6cc2227 --- /dev/null +++ b/frontend/src/lib/forms/TagForm.svelte @@ -0,0 +1,42 @@ + + +
+
+ + + + + +