UNPKG

qbittorrent-api-client

Version:
1 lines 33.8 kB
{"version":3,"sources":["../src/index.ts","../src/classes/QBittorrentClient.ts","../src/utils/QBittorrentClientError.ts","../src/types/QBittorrentTorrentsMethods.ts"],"sourcesContent":["// Client exports\nexport { default } from './classes/QBittorrentClient'\nexport { default as QBittorrentClient } from './classes/QBittorrentClient'\nexport * from './classes/QBittorrentClient'\n\n// Client Error exports\nexport { default as QBittorrentClientError } from './utils/QBittorrentClientError'\nexport * from './utils/QBittorrentClientError'\n\n// Types exports\nexport * from './types/QBittorrentAppMethods'\nexport * from './types/QBittorrentSyncMethods'\nexport * from './types/QBittorrentTorrentsMethods'\nexport * from './types/QBittorrentTransferMethods'","import {\n QBittorrentTorrentContentPriority,\n QBittorrentTorrentContents,\n QBittorrentTorrentProperties,\n QBittorrentTorrentsAddOptions,\n QBittorrentTorrentTrackers,\n TorrentInfo,\n} from '../types/QBittorrentTorrentsMethods.js'\nimport axios, { AxiosResponse } from 'axios'\nimport QBittorrentClientError, { ErrorType } from '../utils/QBittorrentClientError'\nimport { QBittorrentAppPreferences } from '../types/QBittorrentAppMethods'\nimport { QBittorrentSyncTorrentPeers, QBittorrentTorrentPeers } from '../types/QBittorrentSyncMethods'\nimport { QBittorrentTransferInfo } from '../types/QBittorrentTransferMethods'\nimport FormData from 'form-data'\n\nexport interface QBittorrentClientOptions {\n baseUrl: string\n}\n\nexport default class QBittorrentClient {\n httpClient = axios.create()\n sessionCookie?: string\n\n constructor(readonly options: QBittorrentClientOptions) {\n this.httpClient.defaults.baseURL = this.baseUrl\n this.httpClient.interceptors.response.use(response => response, error => {\n if (error.response.status === 403) {\n throw new QBittorrentClientError('Authentication needed', {\n type: ErrorType.FORBIDDEN,\n })\n }\n throw error\n })\n }\n\n protected get baseUrl(): string {\n return this.options.baseUrl + '/api/v2'\n }\n\n async authenticate(username?: string, password?: string): Promise<void> {\n return this.login(username, password)\n .then(sessionCookie => {\n if (!sessionCookie) {\n throw new Error('No session cookie')\n }\n this.sessionCookie = sessionCookie\n this.httpClient.defaults.headers.common['Cookie'] = sessionCookie\n })\n }\n\n async login(username?: string, password?: string): Promise<string | undefined> {\n const params = new URLSearchParams()\n if (username) params.append('username', username)\n if (password) params.append('password', password)\n\n return this.httpClient('auth/login', {\n method: 'POST',\n data: params,\n\n withCredentials: true,\n })\n .then(async response => {\n if (response.status === 403) {\n throw new QBittorrentClientError('Too many failed attempts, your IP is banned', {\n type: ErrorType.IP_BANNED,\n })\n }\n if (response.data === 'Fails.') {\n throw new QBittorrentClientError('Invalid credentials', {\n type: ErrorType.INVALID_CREDENTIALS,\n })\n }\n\n const cookies = response.headers['set-cookie']\n if (Array.isArray(cookies)) {\n return cookies\n .find((cookie) => cookie.startsWith('SID='))\n ?.split(';')[0]\n }\n\n return undefined\n },\n error => {\n if (error.response.status === 403) {\n throw new QBittorrentClientError('Too many failed attempts, your IP is banned', {\n type: ErrorType.IP_BANNED,\n })\n }\n throw error\n },\n )\n }\n\n async logout(): Promise<void> {\n await this.httpClient('/auth/logout', {\n method: 'POST',\n withCredentials: true,\n })\n }\n\n async version(): Promise<string> {\n return this.httpClient.get('app/version')\n .then(response => response.data)\n }\n\n async getAppPreferences(): Promise<QBittorrentAppPreferences> {\n return this.httpClient\n .get<QBittorrentAppPreferences>(`app/preferences`)\n .then((res) => res.data)\n }\n\n async setAppPreferences(preferences: Partial<QBittorrentAppPreferences>): Promise<void> {\n await this.httpClient\n .post(`app/setPreferences`, `json=${ JSON.stringify(preferences) }`)\n }\n\n async getTorrentInfos(): Promise<Array<TorrentInfo>> {\n return this.httpClient.get<any, AxiosResponse<Array<TorrentInfo>>>('torrents/info')\n .then((res) => res.data)\n }\n\n\n async getTorrentContents(hash: string): Promise<QBittorrentTorrentContents> {\n return this.httpClient\n .get<QBittorrentTorrentContents>(`torrents/files`, {\n params: {\n hash: hash.toLowerCase(),\n },\n\n })\n .then((res) => res.data)\n }\n\n async getTorrentProperties(hash: string): Promise<QBittorrentTorrentProperties> {\n return this.httpClient\n .get<QBittorrentTorrentProperties>(`torrents/properties`, {\n params: {\n hash: hash.toLowerCase(),\n },\n\n })\n .then((res) => res.data)\n }\n\n async getTorrentTrackers(hash: string): Promise<QBittorrentTorrentTrackers> {\n return this.httpClient\n .get<QBittorrentTorrentTrackers>(`torrents/trackers`, {\n params: {\n hash: hash.toLowerCase(),\n },\n\n })\n .then((res) => res.data)\n }\n\n async getTransferInfo(): Promise<QBittorrentTransferInfo> {\n return this.httpClient\n .get<QBittorrentTransferInfo>(`transfer/info`, {})\n .then((res) => res.data)\n }\n\n // async syncMainData(): Promise<QBittorrentMainData> {\n // const headers = await this.getRequestHeaders()\n //\n // if (this.isMainDataPending == false) {\n // this.isMainDataPending = true\n // this.syncRids.mainData = this.syncRids.mainData.then((rid) =>\n // this.client\n // .get<QBittorrentSyncMainData>(`sync/maindata`, {\n // params: {\n // rid,\n // },\n // headers,\n // })\n // .then(({ data }) => {\n // const {\n // rid: newRid = 0,\n // full_update = false,\n // categories = {},\n // categories_removed = [],\n // server_state = EMPTY_SERVER_STATE,\n // tags = [],\n // tags_removed = [],\n // torrents = {},\n // torrents_removed = [],\n // trackers = {},\n // trackers_removed = [],\n // } = data\n //\n // if (full_update) {\n // this.syncStates.mainData = {\n // categories,\n // server_state,\n // tags,\n // torrents,\n // trackers,\n // }\n // } else {\n // // categories\n // Object.keys(categories).forEach((category) => {\n // this.syncStates.mainData.categories[category] = {\n // ...this.syncStates.mainData.categories[category],\n // ...categories[category],\n // }\n // })\n //\n // categories_removed.forEach((category) => {\n // delete this.syncStates.mainData.categories[category]\n // })\n //\n // // tags\n // this.syncStates.mainData.tags.push(...tags)\n // this.syncStates.mainData.tags = this.syncStates.mainData.tags.filter(\n // (tag) => !tags_removed.includes(tag),\n // )\n //\n // // torrents\n // Object.keys(torrents).forEach((torrent) => {\n // this.syncStates.mainData.torrents[torrent] = {\n // ...this.syncStates.mainData.torrents[torrent],\n // ...torrents[torrent],\n // }\n // })\n //\n // torrents_removed.forEach((torrent) => {\n // delete this.syncStates.mainData.torrents[torrent]\n // })\n //\n // // trackers\n // Object.keys(trackers).forEach((tracker) => {\n // this.syncStates.mainData.trackers[tracker] = {\n // ...this.syncStates.mainData.trackers[tracker],\n // ...trackers[tracker],\n // }\n // })\n //\n // trackers_removed.forEach((tracker) => {\n // delete this.syncStates.mainData.trackers[tracker]\n // })\n // }\n //\n // return newRid\n // })\n // .finally(() => {\n // this.isMainDataPending = false\n // }),\n // )\n // }\n //\n // try {\n // await this.syncRids.mainData\n // } catch (e) {\n // this.syncRids.mainData = Promise.resolve(0)\n // throw e\n // }\n //\n // return this.syncStates.mainData\n // }\n\n async syncTorrentPeers(hash: string): Promise<QBittorrentTorrentPeers> {\n return this.httpClient\n .get<QBittorrentSyncTorrentPeers>(`sync/torrentPeers`, {\n params: {\n hash: hash.toLowerCase(),\n rid: 0,\n },\n\n })\n .then(({ data }) => data.peers)\n }\n\n async torrentsPause(hashes: Array<string>): Promise<void> {\n return this.httpClient\n .get(`torrents/pause`, {\n params: {\n hashes: hashes.join('|').toLowerCase(),\n },\n\n })\n .then(() => {\n // returns nothing\n })\n }\n\n async torrentsResume(hashes: Array<string>): Promise<void> {\n return this.httpClient\n .get(`torrents/resume`, {\n params: {\n hashes: hashes.join('|').toLowerCase(),\n },\n\n })\n .then(() => {\n // returns nothing\n })\n }\n\n async torrentsDelete(hashes: Array<string>, deleteFiles: boolean): Promise<void> {\n return this.httpClient\n .get(`torrents/delete`, {\n params: {\n hashes: hashes.join('|').toLowerCase(),\n deleteFiles: deleteFiles ? 'true' : 'false',\n },\n\n })\n .then(() => {\n // returns nothing\n })\n }\n\n async torrentsRecheck(hashes: Array<string>): Promise<void> {\n return this.httpClient\n .get(`torrents/recheck`, {\n params: {\n hashes: hashes.join('|').toLowerCase(),\n },\n\n })\n .then(() => {\n // returns nothing\n })\n }\n\n async torrentsSetLocation(hashes: Array<string>, location: string): Promise<void> {\n return this.httpClient\n .get(`torrents/setLocation`, {\n params: {\n hashes: hashes.join('|').toLowerCase(),\n location,\n },\n\n })\n .then(() => {\n // returns nothing\n })\n }\n\n async torrentsSetTopPrio(hashes: Array<string>): Promise<void> {\n return this.httpClient\n .get(`torrents/topPrio`, {\n params: {\n hashes: hashes.join('|').toLowerCase(),\n },\n\n })\n .then(() => {\n // returns nothing\n })\n }\n\n async torrentsSetBottomPrio(hashes: Array<string>): Promise<void> {\n return this.httpClient\n .get(`torrents/bottomPrio`, {\n params: {\n hashes: hashes.join('|').toLowerCase(),\n },\n\n })\n .then(() => {\n // returns nothing\n })\n }\n\n async torrentsAddFiles(files: Array<Buffer>, options: QBittorrentTorrentsAddOptions): Promise<void> {\n const form = new FormData()\n\n files.forEach((file, index) => {\n form.append('torrents', file, {\n filename: `${ index }.torrent`,\n contentType: 'application/x-bittorrent',\n })\n })\n\n Object.keys(options).forEach((key) => {\n const property = key as keyof typeof options\n form.append(property, `${ options[property] }`)\n })\n\n const headers = form.getHeaders({\n Cookie: this.sessionCookie,\n 'Content-Length': form.getLengthSync(),\n })\n\n return this.httpClient\n .post(`torrents/add`, form, {\n headers,\n })\n .then(response => {\n // Check if operation fail.\n // No more detail can be given in response due to the non verbosity of qBittorrent api error.\n if (response.data === 'Fails.') {\n throw new QBittorrentClientError('Can not add torrent file', {\n type: ErrorType.OPERATION_FAILED,\n })\n }\n })\n }\n\n async torrentsAddURLs(urls: Array<string>, options: QBittorrentTorrentsAddOptions): Promise<void> {\n const form = new FormData()\n\n form.append('urls', urls.join('\\n'))\n\n Object.keys(options).forEach((key) => {\n const property = key as keyof typeof options\n form.append(property, `${ options[property] }`)\n })\n\n const headers = form.getHeaders({\n Cookie: this.sessionCookie,\n 'Content-Length': form.getLengthSync(),\n })\n\n return this.httpClient\n .post(`torrents/add`, form, {\n headers,\n })\n .then(() => {\n // returns nothing\n })\n }\n\n async torrentsAddTags(hashes: Array<string>, tags: Array<string>): Promise<void> {\n return this.httpClient\n .get(`torrents/addTags`, {\n params: {\n hashes: hashes.join('|').toLowerCase(),\n tags: tags.join(','),\n },\n\n })\n .then(() => {\n // returns nothing\n })\n }\n\n async torrentsRemoveTags(hashes: Array<string>, tags?: Array<string>): Promise<void> {\n return this.httpClient\n .get(`torrents/removeTags`, {\n params: {\n hashes: hashes.join('|').toLowerCase(),\n tags: tags?.join(','),\n },\n\n })\n .then(() => {\n // returns nothing\n })\n }\n\n async torrentsAddTrackers(hash: string, urls: Array<string>): Promise<void> {\n if (urls.length > 0) {\n return this.httpClient\n .get(`torrents/addTrackers`, {\n params: {\n hash: hash.toLowerCase(),\n urls: urls.join('\\n'),\n },\n\n })\n .then(() => {\n // returns nothing\n })\n }\n }\n\n async torrentsReannounce(hashes: Array<string>): Promise<void> {\n if (hashes.length > 0) {\n return this.httpClient\n .get(`torrents/reannounce`, {\n params: {\n hashes: hashes.join('|').toLowerCase(),\n },\n\n })\n .then(() => {\n // returns nothing\n })\n }\n }\n\n async torrentsRemoveTrackers(hash: string, urls: Array<string>): Promise<void> {\n if (urls.length > 0) {\n return this.httpClient\n .get(`torrents/removeTrackers`, {\n params: {\n hash: hash.toLowerCase(),\n urls: urls.join('|'),\n },\n\n })\n .then(() => {\n // returns nothing\n })\n }\n }\n\n async torrentsSetSuperSeeding(hashes: Array<string>, value: boolean): Promise<void> {\n if (hashes.length > 0) {\n return this.httpClient\n .get(`torrents/setSuperSeeding`, {\n params: {\n hashes: hashes.join('|').toLowerCase(),\n value: value ? 'true' : 'false',\n },\n\n })\n .then(() => {\n // returns nothing\n })\n }\n }\n\n async torrentsToggleSequentialDownload(hashes: Array<string>): Promise<void> {\n if (hashes.length > 0) {\n return this.httpClient\n .get(`torrents/toggleSequentialDownload`, {\n params: {\n hashes: hashes.join('|').toLowerCase(),\n },\n })\n .then(() => {\n // returns nothing\n })\n }\n }\n\n async torrentsFilePrio(hash: string, ids: Array<number>, priority: QBittorrentTorrentContentPriority) {\n return this.httpClient\n .get(`torrents/filePrio`, {\n params: {\n hash: hash.toLowerCase(),\n id: ids.join('|'),\n priority,\n },\n })\n .then(() => {\n // returns nothing\n })\n }\n}","export enum ErrorType {\n FORBIDDEN = 'FORBIDDEN',\n IP_BANNED = 'IP_BANNED',\n INVALID_CREDENTIALS = 'INVALID_CREDENTIALS',\n OPERATION_FAILED = 'OPERATION_FAILED',\n}\n\nexport interface ErrorContext {\n type?: ErrorType\n}\n\nexport default class QBittorrentClientError extends Error {\n readonly name = 'QBittorrentClientError'\n readonly type?: ErrorType\n\n constructor(message?: string, context?: ErrorContext) {\n super(message ?? 'qBittorrent client error')\n this.type = context?.type\n }\n}","export type QBittorrentTorrentState =\n | 'error'\n | 'missingFiles'\n | 'uploading'\n | 'pausedUP'\n | 'queuedUP'\n | 'stalledUP'\n | 'checkingUP'\n | 'forcedUP'\n | 'allocating'\n | 'downloading'\n | 'metaDL'\n | 'pausedDL'\n | 'queuedDL'\n | 'stalledDL'\n | 'checkingDL'\n | 'forcedDL'\n | 'checkingResumeData'\n | 'moving'\n | 'unknown';\n\nexport interface TorrentInfo {\n // Time (Unix Epoch) when the torrent was added to the client\n added_on: number;\n // Amount of data left to download (bytes)\n amount_left: number;\n // Whether this torrent is managed by Automatic Torrent Management\n auto_tmm: boolean;\n // Percentage of file pieces currently available\n availability: number;\n // Category of the torrent\n category: string;\n // Amount of transfer data completed (bytes)\n completed: number;\n // Time (Unix Epoch) when the torrent completed\n completion_on: number;\n // Torrent download speed limit (bytes/s). -1 if unlimited.\n dl_limit: number;\n // Torrent download speed (bytes/s)\n dlspeed: number;\n // Amount of data downloaded\n downloaded: number;\n // Amount of data downloaded this session\n downloaded_session: number;\n // Torrent ETA (seconds)\n eta: number;\n // True if first last piece are prioritized\n f_l_piece_prio: boolean;\n // True if force start is enabled for this torrent\n force_start: boolean;\n // Torrent hash\n hash: string;\n // Last time (Unix Epoch) when a chunk was downloaded/uploaded\n last_activity: number;\n // Magnet URI corresponding to this torrent\n magnet_uri: string;\n // Maximum share ratio until torrent is stopped from seeding/uploading\n max_ratio: number;\n // Maximum seeding time (seconds) until torrent is stopped from seeding\n max_seeding_time: number;\n // Torrent name\n name: string;\n // Number of seeds in the swarm\n num_complete: number;\n // Number of leechers in the swarm\n num_incomplete: number;\n // Number of leechers connected to\n num_leechs: number;\n // Number of seeds connected to\n num_seeds: number;\n // Torrent priority. Returns -1 if queuing is disabled or torrent is in seed mode\n priority: number;\n // Torrent progress (percentage/100)\n progress: number;\n // Torrent share ratio. Max ratio value: 9999.\n ratio: number;\n // TODO (what is different from max_ratio?)\n ratio_limit: number;\n // Path where this torrent's data is stored\n save_path: string;\n // TODO (what is different from max_seeding_time?)\n seeding_time_limit: number;\n // Time (Unix Epoch) when this torrent was last seen complete\n seen_complete: number;\n // True if sequential download is enabled\n seq_dl: boolean;\n // Total size (bytes) of files selected for download\n size: number;\n // Torrent state\n state: QBittorrentTorrentState;\n // True if super seeding is enabled\n super_seeding: boolean;\n // Comma-concatenated tag list of the torrent\n tags: string;\n // Total active time (seconds)\n time_active: number;\n // Total size (bytes) of all file in this torrent (including unselected ones)\n total_size: number;\n // The first tracker with working status. Returns empty string if no tracker is working.\n tracker: string;\n // Torrent upload speed limit (bytes/s). -1 if unlimited.\n up_limit: number;\n // Amount of data uploaded\n uploaded: number;\n // Amount of data uploaded this session\n uploaded_session: number;\n // Torrent upload speed (bytes/s)\n upspeed: number;\n}\n\nexport interface QBittorrentTorrentsAddOptions {\n // Download folder\n savepath?: string;\n // Cookie sent to download the .torrent file\n cookie?: string;\n // Category for the torrent\n category?: string;\n // Tags for the torrent, split by ','\n tags?: string;\n // Skip hash checking. Possible values are true, false (default)\n skip_checking?: boolean;\n // Add torrents in the paused state. Possible values are true, false (default)\n paused?: boolean;\n // Create the root folder. Possible values are true, false, unset (default)\n root_folder?: boolean;\n // Content layout mode, replaces root_folder\n contentLayout?: 'Original' | 'Subfolder' | 'NoSubfolder';\n // Rename torrent\n rename?: string;\n // Set torrent upload speed limit. Unit in bytes/second\n upLimit?: number;\n // Set torrent download speed limit. Unit in bytes/second\n dlLimit?: number;\n // Whether Automatic Torrent Management should be used\n autoTMM?: boolean;\n // Enable sequential download. Possible values are true, false (default)\n sequentialDownload?: boolean;\n // Prioritize download first last piece. Possible values are true, false (default)\n firstLastPiecePrio?: boolean;\n}\n\nexport enum QBittorrentTorrentContentPriority {\n DO_NOT_DOWNLOAD = 0,\n NORMAL = 1,\n HIGH = 6,\n MAXIMUM = 7,\n}\n\nexport interface QBittorrentTorrentContent {\n // File name (including relative path)\n name: string;\n // File size (bytes)\n size: number;\n // File progress (percentage/100)\n progress: number;\n // File priority\n priority: QBittorrentTorrentContentPriority;\n // True if file is seeding/complete\n is_seed: boolean;\n // The first number is the starting piece index and the second number is the ending piece index (inclusive)\n piece_range: Array<number>;\n // Percentage of file pieces currently available\n availability: number;\n}\n\nexport type QBittorrentTorrentContents = Array<QBittorrentTorrentContent>;\n\nexport interface QBittorrentTorrentProperties {\n // Torrent save path\n save_path: string;\n // Torrent creation date (Unix timestamp)\n creation_date: number;\n // Torrent piece size (bytes)\n piece_size: number;\n // Torrent comment\n comment: string;\n // Total data wasted for torrent (bytes)\n total_wasted: number;\n // Total data uploaded for torrent (bytes)\n total_uploaded: number;\n // Total data uploaded this session (bytes)\n total_uploaded_session: number;\n // Total data downloaded for torrent (bytes)\n total_downloaded: number;\n // Total data downloaded this session (bytes)\n total_downloaded_session: number;\n // Torrent upload limit (bytes/s)\n up_limit: number;\n // Torrent download limit (bytes/s)\n dl_limit: number;\n // Torrent elapsed time (seconds)\n time_elapsed: number;\n // Torrent elapsed time while complete (seconds)\n seeding_time: number;\n // Torrent connection count\n nb_connections: number;\n // Torrent connection count limit\n nb_connections_limit: number;\n // Torrent share ratio\n share_ratio: number;\n // When this torrent was added (unix timestamp)\n addition_date: number;\n // Torrent completion date (unix timestamp)\n completion_date: number;\n // Torrent creator\n created_by: string;\n // Torrent average download speed (bytes/second)\n dl_speed_avg: number;\n // Torrent download speed (bytes/second)\n dl_speed: number;\n // Torrent ETA (seconds)\n eta: number;\n // Last seen complete date (unix timestamp)\n last_seen: number;\n // Number of peers connected to\n peers: number;\n // Number of peers in the swarm\n peers_total: number;\n // Number of pieces owned\n pieces_have: number;\n // Number of pieces of the torrent\n pieces_num: number;\n // Number of seconds until the next announce\n reannounce: number;\n // Number of seeds connected to\n seeds: number;\n // Number of seeds in the swarm\n seeds_total: number;\n // Torrent total size (bytes)\n total_size: number;\n // Torrent average upload speed (bytes/second)\n up_speed_avg: number;\n // Torrent upload speed (bytes/second)\n up_speed: number;\n}\n\nexport enum QBittorrentTorrentTrackerStatus {\n // Tracker is disabled (used for DHT, PeX, and LSD)\n DISABLED = 0,\n // Tracker has not been contacted yet\n NOT_CONTACTED = 1,\n // Tracker has been contacted and is working\n CONTACTED = 2,\n // Tracker is updating\n UPDATING = 3,\n // Tracker has been contacted, but it is not working (or doesn't send proper replies)\n ERROR = 4,\n}\n\nexport interface QBittorrentTorrentTracker {\n // Tracker url\n url: string;\n // Tracker status\n status: QBittorrentTorrentTrackerStatus;\n // Tracker priority tier. Lower tier trackers are tried before higher tiers\n tier: number;\n // Number of peers for current torrent, as reported by the tracker\n num_peers: number;\n // Number of seeds for current torrent, as reported by the tracker\n num_seeds: number;\n // Number of leeches for current torrent, as reported by the tracker\n num_leeches: number;\n // Number of completed downloads for current torrent, as reported by the tracker\n num_downloaded: number;\n // Tracker message (there is no way of knowing what this message is - it's up to tracker admins)\n msg: string;\n}\n\nexport type QBittorrentTorrentTrackers = Array<QBittorrentTorrentTracker>;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACQA,mBAAqC;;;ACR9B,IAAK,YAAL,kBAAKA,eAAL;AACL,EAAAA,WAAA,eAAY;AACZ,EAAAA,WAAA,eAAY;AACZ,EAAAA,WAAA,yBAAsB;AACtB,EAAAA,WAAA,sBAAmB;AAJT,SAAAA;AAAA,GAAA;AAWZ,IAAqB,yBAArB,cAAoD,MAAM;AAAA,EAC/C,OAAO;AAAA,EACP;AAAA,EAET,YAAY,SAAkB,SAAwB;AACpD,UAAM,WAAW,0BAA0B;AAC3C,SAAK,OAAO,SAAS;AAAA,EACvB;AACF;;;ADNA,uBAAqB;AAMrB,IAAqB,oBAArB,MAAuC;AAAA,EAIrC,YAAqB,SAAmC;AAAnC;AACnB,SAAK,WAAW,SAAS,UAAU,KAAK;AACxC,SAAK,WAAW,aAAa,SAAS,IAAI,cAAY,UAAU,WAAS;AACvE,UAAI,MAAM,SAAS,WAAW,KAAK;AACjC,cAAM,IAAI,uBAAuB,yBAAyB;AAAA,UACxD;AAAA,QACF,CAAC;AAAA,MACH;AACA,YAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA,EAbA,aAAa,aAAAC,QAAM,OAAO;AAAA,EAC1B;AAAA,EAcA,IAAc,UAAkB;AAC9B,WAAO,KAAK,QAAQ,UAAU;AAAA,EAChC;AAAA,EAEA,MAAM,aAAa,UAAmB,UAAkC;AACtE,WAAO,KAAK,MAAM,UAAU,QAAQ,EACjC,KAAK,mBAAiB;AACrB,UAAI,CAAC,eAAe;AAClB,cAAM,IAAI,MAAM,mBAAmB;AAAA,MACrC;AACA,WAAK,gBAAgB;AACrB,WAAK,WAAW,SAAS,QAAQ,OAAO,QAAQ,IAAI;AAAA,IACtD,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,MAAM,UAAmB,UAAgD;AAC7E,UAAM,SAAS,IAAI,gBAAgB;AACnC,QAAI;AAAU,aAAO,OAAO,YAAY,QAAQ;AAChD,QAAI;AAAU,aAAO,OAAO,YAAY,QAAQ;AAEhD,WAAO,KAAK,WAAW,cAAc;AAAA,MACnC,QAAQ;AAAA,MACR,MAAM;AAAA,MAEN,iBAAiB;AAAA,IACnB,CAAC,EACE;AAAA,MAAK,OAAM,aAAY;AACpB,YAAI,SAAS,WAAW,KAAK;AAC3B,gBAAM,IAAI,uBAAuB,+CAA+C;AAAA,YAC9E;AAAA,UACF,CAAC;AAAA,QACH;AACA,YAAI,SAAS,SAAS,UAAU;AAC9B,gBAAM,IAAI,uBAAuB,uBAAuB;AAAA,YACtD;AAAA,UACF,CAAC;AAAA,QACH;AAEA,cAAM,UAAU,SAAS,QAAQ,YAAY;AAC7C,YAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,iBAAO,QACJ,KAAK,CAAC,WAAW,OAAO,WAAW,MAAM,CAAC,GACzC,MAAM,GAAG,EAAE,CAAC;AAAA,QAClB;AAEA,eAAO;AAAA,MACT;AAAA,MACA,WAAS;AACP,YAAI,MAAM,SAAS,WAAW,KAAK;AACjC,gBAAM,IAAI,uBAAuB,+CAA+C;AAAA,YAC9E;AAAA,UACF,CAAC;AAAA,QACH;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACJ;AAAA,EAEA,MAAM,SAAwB;AAC5B,UAAM,KAAK,WAAW,gBAAgB;AAAA,MACpC,QAAQ;AAAA,MACR,iBAAiB;AAAA,IACnB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,UAA2B;AAC/B,WAAO,KAAK,WAAW,IAAI,aAAa,EACrC,KAAK,cAAY,SAAS,IAAI;AAAA,EACnC;AAAA,EAEA,MAAM,oBAAwD;AAC5D,WAAO,KAAK,WACT,IAA+B,iBAAiB,EAChD,KAAK,CAAC,QAAQ,IAAI,IAAI;AAAA,EAC3B;AAAA,EAEA,MAAM,kBAAkB,aAAgE;AACtF,UAAM,KAAK,WACR,KAAK,sBAAsB,QAAS,KAAK,UAAU,WAAW,CAAE,EAAE;AAAA,EACvE;AAAA,EAEA,MAAM,kBAA+C;AACnD,WAAO,KAAK,WAAW,IAA4C,eAAe,EAC/E,KAAK,CAAC,QAAQ,IAAI,IAAI;AAAA,EAC3B;AAAA,EAGA,MAAM,mBAAmB,MAAmD;AAC1E,WAAO,KAAK,WACT,IAAgC,kBAAkB;AAAA,MACjD,QAAQ;AAAA,QACN,MAAM,KAAK,YAAY;AAAA,MACzB;AAAA,IAEF,CAAC,EACA,KAAK,CAAC,QAAQ,IAAI,IAAI;AAAA,EAC3B;AAAA,EAEA,MAAM,qBAAqB,MAAqD;AAC9E,WAAO,KAAK,WACT,IAAkC,uBAAuB;AAAA,MACxD,QAAQ;AAAA,QACN,MAAM,KAAK,YAAY;AAAA,MACzB;AAAA,IAEF,CAAC,EACA,KAAK,CAAC,QAAQ,IAAI,IAAI;AAAA,EAC3B;AAAA,EAEA,MAAM,mBAAmB,MAAmD;AAC1E,WAAO,KAAK,WACT,IAAgC,qBAAqB;AAAA,MACpD,QAAQ;AAAA,QACN,MAAM,KAAK,YAAY;AAAA,MACzB;AAAA,IAEF,CAAC,EACA,KAAK,CAAC,QAAQ,IAAI,IAAI;AAAA,EAC3B;AAAA,EAEA,MAAM,kBAAoD;AACxD,WAAO,KAAK,WACT,IAA6B,iBAAiB,CAAC,CAAC,EAChD,KAAK,CAAC,QAAQ,IAAI,IAAI;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoGA,MAAM,iBAAiB,MAAgD;AACrE,WAAO,KAAK,WACT,IAAiC,qBAAqB;AAAA,MACrD,QAAQ;AAAA,QACN,MAAM,KAAK,YAAY;AAAA,QACvB,KAAK;AAAA,MACP;AAAA,IAEF,CAAC,EACA,KAAK,CAAC,EAAE,KAAK,MAAM,KAAK,KAAK;AAAA,EAClC;AAAA,EAEA,MAAM,cAAc,QAAsC;AACxD,WAAO,KAAK,WACT,IAAI,kBAAkB;AAAA,MACrB,QAAQ;AAAA,QACN,QAAQ,OAAO,KAAK,GAAG,EAAE,YAAY;AAAA,MACvC;AAAA,IAEF,CAAC,EACA,KAAK,MAAM;AAAA,IAEZ,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,eAAe,QAAsC;AACzD,WAAO,KAAK,WACT,IAAI,mBAAmB;AAAA,MACtB,QAAQ;AAAA,QACN,QAAQ,OAAO,KAAK,GAAG,EAAE,YAAY;AAAA,MACvC;AAAA,IAEF,CAAC,EACA,KAAK,MAAM;AAAA,IAEZ,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,eAAe,QAAuB,aAAqC;AAC/E,WAAO,KAAK,WACT,IAAI,mBAAmB;AAAA,MACtB,QAAQ;AAAA,QACN,QAAQ,OAAO,KAAK,GAAG,EAAE,YAAY;AAAA,QACrC,aAAa,cAAc,SAAS;AAAA,MACtC;AAAA,IAEF,CAAC,EACA,KAAK,MAAM;AAAA,IAEZ,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,gBAAgB,QAAsC;AAC1D,WAAO,KAAK,WACT,IAAI,oBAAoB;AAAA,MACvB,QAAQ;AAAA,QACN,QAAQ,OAAO,KAAK,GAAG,EAAE,YAAY;AAAA,MACvC;AAAA,IAEF,CAAC,EACA,KAAK,MAAM;AAAA,IAEZ,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,oBAAoB,QAAuB,UAAiC;AAChF,WAAO,KAAK,WACT,IAAI,wBAAwB;AAAA,MAC3B,QAAQ;AAAA,QACN,QAAQ,OAAO,KAAK,GAAG,EAAE,YAAY;AAAA,QACrC;AAAA,MACF;AAAA,IAEF,CAAC,EACA,KAAK,MAAM;AAAA,IAEZ,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,mBAAmB,QAAsC;AAC7D,WAAO,KAAK,WACT,IAAI,oBAAoB;AAAA,MACvB,QAAQ;AAAA,QACN,QAAQ,OAAO,KAAK,GAAG,EAAE,YAAY;AAAA,MACvC;AAAA,IAEF,CAAC,EACA,KAAK,MAAM;AAAA,IAEZ,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,sBAAsB,QAAsC;AAChE,WAAO,KAAK,WACT,IAAI,uBAAuB;AAAA,MAC1B,QAAQ;AAAA,QACN,QAAQ,OAAO,KAAK,GAAG,EAAE,YAAY;AAAA,MACvC;AAAA,IAEF,CAAC,EACA,KAAK,MAAM;AAAA,IAEZ,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,iBAAiB,OAAsB,SAAuD;AAClG,UAAM,OAAO,IAAI,iBAAAC,QAAS;AAE1B,UAAM,QAAQ,CAAC,MAAM,UAAU;AAC7B,WAAK,OAAO,YAAY,MAAM;AAAA,QAC5B,UAAU,GAAI,KAAM;AAAA,QACpB,aAAa;AAAA,MACf,CAAC;AAAA,IACH,CAAC;AAED,WAAO,KAAK,OAAO,EAAE,QAAQ,CAAC,QAAQ;AACpC,YAAM,WAAW;AACjB,WAAK,OAAO,UAAU,GAAI,QAAQ,QAAQ,CAAE,EAAE;AAAA,IAChD,CAAC;AAED,UAAM,UAAU,KAAK,WAAW;AAAA,MAC9B,QAAQ,KAAK;AAAA,MACb,kBAAkB,KAAK,cAAc;AAAA,IACvC,CAAC;AAED,WAAO,KAAK,WACT,KAAK,gBAAgB,MAAM;AAAA,MAC1B;AAAA,IACF,CAAC,EACA,KAAK,cAAY;AAGhB,UAAI,SAAS,SAAS,UAAU;AAC9B,cAAM,IAAI,uBAAuB,4BAA4B;AAAA,UAC3D;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,gBAAgB,MAAqB,SAAuD;AAChG,UAAM,OAAO,IAAI,iBAAAA,QAAS;AAE1B,SAAK,OAAO,QAAQ,KAAK,KAAK,IAAI,CAAC;AAEnC,WAAO,KAAK,OAAO,EAAE,QAAQ,CAAC,QAAQ;AACpC,YAAM,WAAW;AACjB,WAAK,OAAO,UAAU,GAAI,QAAQ,QAAQ,CAAE,EAAE;AAAA,IAChD,CAAC;AAED,UAAM,UAAU,KAAK,WAAW;AAAA,MAC9B,QAAQ,KAAK;AAAA,MACb,kBAAkB,KAAK,cAAc;AAAA,IACvC,CAAC;AAED,WAAO,KAAK,WACT,KAAK,gBAAgB,MAAM;AAAA,MAC1B;AAAA,IACF,CAAC,EACA,KAAK,MAAM;AAAA,IAEZ,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,gBAAgB,QAAuB,MAAoC;AAC/E,WAAO,KAAK,WACT,IAAI,oBAAoB;AAAA,MACvB,QAAQ;AAAA,QACN,QAAQ,OAAO,KAAK,GAAG,EAAE,YAAY;AAAA,QACrC,MAAM,KAAK,KAAK,GAAG;AAAA,MACrB;AAAA,IAEF,CAAC,EACA,KAAK,MAAM;AAAA,IAEZ,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,mBAAmB,QAAuB,MAAqC;AACnF,WAAO,KAAK,WACT,IAAI,uBAAuB;AAAA,MAC1B,QAAQ;AAAA,QACN,QAAQ,OAAO,KAAK,GAAG,EAAE,YAAY;AAAA,QACrC,MAAM,MAAM,KAAK,GAAG;AAAA,MACtB;AAAA,IAEF,CAAC,EACA,KAAK,MAAM;AAAA,IAEZ,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,oBAAoB,MAAc,MAAoC;AAC1E,QAAI,KAAK,SAAS,GAAG;AACnB,aAAO,KAAK,WACT,IAAI,wBAAwB;AAAA,QAC3B,QAAQ;AAAA,UACN,MAAM,KAAK,YAAY;AAAA,UACvB,MAAM,KAAK,KAAK,IAAI;AAAA,QACtB;AAAA,MAEF,CAAC,EACA,KAAK,MAAM;AAAA,MAEZ,CAAC;AAAA,IACL;AAAA,EACF;AAAA,EAEA,MAAM,mBAAmB,QAAsC;AAC7D,QAAI,OAAO,SAAS,GAAG;AACrB,aAAO,KAAK,WACT,IAAI,uBAAuB;AAAA,QAC1B,QAAQ;AAAA,UACN,QAAQ,OAAO,KAAK,GAAG,EAAE,YAAY;AAAA,QACvC;AAAA,MAEF,CAAC,EACA,KAAK,MAAM;AAAA,MAEZ,CAAC;AAAA,IACL;AAAA,EACF;AAAA,EAEA,MAAM,uBAAuB,MAAc,MAAoC;AAC7E,QAAI,KAAK,SAAS,GAAG;AACnB,aAAO,KAAK,WACT,IAAI,2BAA2B;AAAA,QAC9B,QAAQ;AAAA,UACN,MAAM,KAAK,YAAY;AAAA,UACvB,MAAM,KAAK,KAAK,GAAG;AAAA,QACrB;AAAA,MAEF,CAAC,EACA,KAAK,MAAM;AAAA,MAEZ,CAAC;AAAA,IACL;AAAA,EACF;AAAA,EAEA,MAAM,wBAAwB,QAAuB,OAA+B;AAClF,QAAI,OAAO,SAAS,GAAG;AACrB,aAAO,KAAK,WACT,IAAI,4BAA4B;AAAA,QAC/B,QAAQ;AAAA,UACN,QAAQ,OAAO,KAAK,GAAG,EAAE,YAAY;AAAA,UACrC,OAAO,QAAQ,SAAS;AAAA,QAC1B;AAAA,MAEF,CAAC,EACA,KAAK,MAAM;AAAA,MAEZ,CAAC;AAAA,IACL;AAAA,EACF;AAAA,EAEA,MAAM,iCAAiC,QAAsC;AAC3E,QAAI,OAAO,SAAS,GAAG;AACrB,aAAO,KAAK,WACT,IAAI,qCAAqC;AAAA,QACxC,QAAQ;AAAA,UACN,QAAQ,OAAO,KAAK,GAAG,EAAE,YAAY;AAAA,QACvC;AAAA,MACF,CAAC,EACA,KAAK,MAAM;AAAA,MAEZ,CAAC;AAAA,IACL;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,MAAc,KAAoB,UAA6C;AACpG,WAAO,KAAK,WACT,IAAI,qBAAqB;AAAA,MACxB,QAAQ;AAAA,QACN,MAAM,KAAK,YAAY;AAAA,QACvB,IAAI,IAAI,KAAK,GAAG;AAAA,QAChB;AAAA,MACF;AAAA,IACF,CAAC,EACA,KAAK,MAAM;AAAA,IAEZ,CAAC;AAAA,EACL;AACF;;;AEhZO,IAAK,oCAAL,kBAAKC,uCAAL;AACL,EAAAA,sEAAA,qBAAkB,KAAlB;AACA,EAAAA,sEAAA,YAAS,KAAT;AACA,EAAAA,sEAAA,UAAO,KAAP;AACA,EAAAA,sEAAA,aAAU,KAAV;AAJU,SAAAA;AAAA,GAAA;AA+FL,IAAK,kCAAL,kBAAKC,qCAAL;AAEL,EAAAA,kEAAA,cAAW,KAAX;AAEA,EAAAA,kEAAA,mBAAgB,KAAhB;AAEA,EAAAA,kEAAA,eAAY,KAAZ;AAEA,EAAAA,kEAAA,cAAW,KAAX;AAEA,EAAAA,kEAAA,WAAQ,KAAR;AAVU,SAAAA;AAAA,GAAA;","names":["ErrorType","axios","FormData","QBittorrentTorrentContentPriority","QBittorrentTorrentTrackerStatus"]}