├── dist
├── upload.js.LICENSE.txt
└── upload.js
├── src
├── utils
│ ├── index.js
│ └── computeFileHashDirect.js
└── upload.js
├── webpack.config.js
├── LICENSE
├── package.json
├── README.md
├── CHANGELOG.md
└── index.d.ts
/dist/upload.js.LICENSE.txt:
--------------------------------------------------------------------------------
1 | /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
2 |
--------------------------------------------------------------------------------
/src/utils/index.js:
--------------------------------------------------------------------------------
1 | // utils.js
2 | import computeFileHashDirect from "./computeFileHashDirect";
3 |
4 | const utils = {
5 | computeFileHashDirect,
6 | };
7 |
8 | export default utils;
9 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | module.exports = {
4 | mode: 'production',
5 | entry: './src/upload.js',
6 | output: {
7 | path: path.resolve(__dirname, 'dist'),
8 | filename: 'upload.js',
9 | library: 'createUploader',
10 | libraryTarget: 'umd',
11 | globalObject: 'this'
12 | },
13 | module: {
14 | rules: [
15 | {
16 | test: /\.js$/,
17 | exclude: /node_modules/,
18 | use: {
19 | loader: 'babel-loader',
20 | options: {
21 | presets: ['@babel/preset-env']
22 | }
23 | }
24 | }
25 | ]
26 | }
27 | };
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | ISC License
2 |
3 | Copyright (c) 2024-present Jiang Kunju
4 |
5 | Permission to use, copy, modify, and/or distribute this software for any
6 | purpose with or without fee is hereby granted, provided that the above
7 | copyright notice and this permission notice appear in all copies.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "enlarge-file-upload",
3 | "version": "x.y.z",
4 | "description": "A tool for chunked file upload with concurrency control.",
5 | "main": "dist/upload.js",
6 | "files": [
7 | "dist",
8 | "CHANGELOG.md"
9 | ],
10 | "scripts": {
11 | "build": "webpack"
12 | },
13 | "keywords": [
14 | "file",
15 | "upload",
16 | "big files",
17 | "large files",
18 | "pause",
19 | "resume",
20 | "chunk",
21 | "chunked upload"
22 | ],
23 |
24 | "author": "",
25 | "license": "ISC",
26 | "dependencies": {
27 | "axios": "^1.7.2"
28 | },
29 | "devDependencies": {
30 | "@babel/core": "^7.24.7",
31 | "@babel/preset-env": "^7.24.7",
32 | "babel-loader": "^9.1.3",
33 | "webpack": "^5.92.1",
34 | "webpack-cli": "^5.1.4"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # File Upload Tool
2 |
3 | **请优先下载最新版本库**
4 | 这是一个用于大文件上传的工具包,提供了系列函数用来支持暂停、恢复、上传进度等功能,内置了错误重传策略,支持断点续传、重传、重试等功能(此库上传基于 axios 库,如果项目不支持 axios,勿用...)。
5 | **QQ 讨论群:324710217 群内有相关问题可以直接咨询,做到有问必答,可以加入群聊,与其他开发者共同讨论。**
6 | ## 使用文档
7 | **地址:** http://jiang-12-13.com:9898/
8 |
9 | ## 演示案例
10 | **地址:** http://jiang-12-13.com:8988/
11 | **本演示仅用于本库大文件上传案例在线演示,严禁上传违法内容和做其它用处。请善待服务器**
12 |
13 | ## npm 地址
14 | **地址:** https://www.npmjs.com/package/enlarge-file-upload
15 |
16 | ## 安装
17 |
18 | ```sh
19 | npm install enlarge-file-upload
20 | ```
21 | ## CDN引入
22 | ```sh
23 |
24 | ```
25 |
26 | ## 简介
27 | 本库底层采用javascript编写,支持任何前端框架或非框架项目。主要功能为大文件上传,做到开箱即用,只需要极简的操作便可实现大文件上传相关操作,且拥有强大的可扩展性。具体使用请参考使用文档:http://jiang-12-13.com:9898/
28 |
29 | ## 建议
30 |
31 | 如果对此工具包有更好的建议或需要支持新的功能,欢迎提 issue 或者加入QQ群:324710217,做到一起讨论,一起改进。
32 |
--------------------------------------------------------------------------------
/src/utils/computeFileHashDirect.js:
--------------------------------------------------------------------------------
1 | async function computeFileHashDirect(file, progressCallback, chunkSize = 5 * 1024 * 1024) {
2 | return new Promise((resolve, reject) => {
3 | const shaObj = sha256.create(); // 支持增量 update()
4 | const reader = new FileReader();
5 | let offset = 0;
6 |
7 | reader.onerror = () => reject(reader.error);
8 | reader.onload = (e) => {
9 | const data = new Uint8Array(e.target.result);
10 | shaObj.update(data); // 增量计算
11 | offset += data.length;
12 | // 调用进度回调函数
13 | if (progressCallback) {
14 | progressCallback((offset / file.size) * 100);
15 | }
16 |
17 | if (offset < file.size) {
18 | readNext();
19 | } else {
20 | resolve(shaObj.hex());
21 | }
22 | };
23 |
24 | function readNext() {
25 | const slice = file.slice(offset, offset + chunkSize);
26 | reader.readAsArrayBuffer(slice);
27 | }
28 |
29 | readNext();
30 | });
31 | }
32 |
33 | export default computeFileHashDirect;
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ### 更新日志
2 |
3 | 说明:1.0.4 版本及之前版本,都是测试版,有功能缺陷,请勿使用
4 |
5 | ### 1.0.0
6 |
7 | - 测试版,有功能缺陷,请勿使用
8 | - 初始化
9 | - 添加基础方法
10 |
11 | ### 1.0.1
12 |
13 | - 测试版,有功能缺陷,请勿使用
14 |
15 | ### 1.0.2
16 |
17 | - 测试版,有功能缺陷,请勿使用
18 |
19 | ### 1.0.3
20 |
21 | - 测试版,有功能缺陷,请勿使用
22 |
23 | ### 1.0.4
24 |
25 | - 测试版,有功能缺陷,请勿使用
26 |
27 | ### 1.0.5
28 |
29 | - 修复上传缺陷
30 |
31 | ### 1.0.6
32 |
33 | - 删除冗余模块,不涉及功能上的更改
34 |
35 | ## 1.0.7
36 |
37 | - 完善使用文档及更新日志
38 |
39 | ## 1.0.8 - 1.0.16
40 |
41 | - 测试版,仅支持部分功能
42 |
43 | ## 1.0.17
44 |
45 | - 稳定版本,具备大文件上传基本功能
46 |
47 | ## 1.0.18
48 |
49 | - 增加上传速度回调函数
50 | - 增加文件 hash 值计算
51 |
52 | ## 1.0.19
53 |
54 | - 修复二次上传,速度回调函数不被调用 bug
55 |
56 | ## 1.0.20
57 |
58 | - 增加可选项,可选择异步或同步计算 hash 值
59 |
60 | ## 1.0.21
61 |
62 | - 不涉及功能变更,仅更新文档,增加 react hooks 封装使用示例
63 |
64 | ## 1.0.22
65 |
66 | - 增加可选参数 startOffset,可指定从某个切片索引位置开始上传
67 | - 增加可选参数 includeChunks,可指定只上传某几个切片
68 | - 如果 startOffset 和 includeChunks 参数同时存在,且 startOffset 不为 0,默认优先使用 startOffset 参数
69 |
70 | ## 1.0.23
71 |
72 | - 不涉及功能变更,仅更新文档,增加 github 地址
73 |
74 | ## 1.0.24
75 |
76 | - 不涉及功能变更,仅更新文档,更新 github 地址
77 |
78 | ## 1.0.25
79 |
80 | - 测试 TS 类型支持-----测试版,勿用
81 |
82 | ## 1.0.26
83 |
84 | - 测试 TS 类型支持-----测试版,勿用
85 |
86 | ## 1.0.27
87 |
88 | - 增加 TS 类型支持
89 |
90 | ## 1.0.28
91 |
92 | - 修改失败重传 bug
93 | - state 增加 file 、errorMsg 和 totalChunks 数据
94 | - 上传失败时,有更友好的错误提示
95 |
96 | ## 1.0.29
97 |
98 | - 修复文件hash值计算异常问题
99 |
100 | ## 1.0.30
101 |
102 | - 不涉及功能变更,仅更新README文档
103 |
104 | ## 1.0.31
105 |
106 | - 不涉及功能变更,仅更新README文档
107 |
108 | ## 1.0.32
109 |
110 | - 不涉及功能变更,仅更新README文档
111 |
112 | ## 1.0.33
113 |
114 | - 不涉及功能变更,仅更新README文档
115 |
116 | ## 1.0.34
117 |
118 | - 不涉及功能变更,增加线上演示地址
119 |
120 | ## 2.0.35
121 |
122 | - 新增重置上传函数
123 | - 完善ts类型描述
124 |
125 | # 2.1.0
126 | hahs重构一期:
127 | - hash计算逻辑重构
128 | - 新增所有切片hashMap
129 | - 返回所有切片
130 |
131 | # 2.2.0
132 | hahs重构二期:
133 | - hash计算逻辑重构
134 | - 新增checker函数
135 | - 重新上线onError回调
136 |
137 | # 2.3.0-beta.1
138 | - 优化onSuccess回调
139 | - 优化reset函数
140 | - 其它非主要变更
141 |
142 | # 2.3.0-rc.1
143 | - 修复暂停函数死循环问题
144 | - ts补充类型暴露
145 |
146 | # 2.3.0-rc.2
147 | - 修复hash包被多次引入问题
148 |
149 | # 2.3.0
150 | - 修复错误回调函数参数bug
151 | - 全面实战测试
152 |
153 | # 2.3.1
154 | - ts类型补充及修复
155 |
156 | # 2.3.2
157 | - ts类型补充及修复
158 | - 增加文档地址
159 |
160 | # 2.3.3
161 | - 不涉及功能变更,仅更新文档
162 |
163 | # 2.3.4
164 | - 不涉及功能变更,仅更新文档
165 |
166 | # 2.3.5
167 | - ts类型补充及修复
168 |
169 | # 2.3.6
170 | - 支持自定义hash值计算
171 | - 修改readme文档
172 |
173 | # 2.3.7
174 | - 类型补充
175 |
176 | # 2.3.8
177 | - 支持抽样hash计算
178 | - 增加LICENSE文件
179 |
180 | # 2.3.9 - 该版本有严重缺陷,请勿使用
181 | - 新增utils工具函数模块
182 | - hash256改为本地导入
183 |
184 | # 2.3.10-beta.1
185 | - 修复hash256本地导入异常问题
186 |
187 | # 2.3.10
188 | - 完善ts类型定义
189 |
190 | # 2.3.11
191 | - 优化包体积,减少包大小
--------------------------------------------------------------------------------
/index.d.ts:
--------------------------------------------------------------------------------
1 | // index.d.ts
2 |
3 | import { CancelToken } from "axios";
4 |
5 | /**
6 | * Custom hash calculation result:
7 | * - hash: The overall hash value of the current file (string)
8 | * - hashMap: A Map used to store the hash value of each chunk
9 | */
10 | type HashResult = Promise<{
11 | hash: string;
12 | hashMap: Map;
13 | }>;
14 |
15 | /**
16 | * Stream calculation mode:
17 | * - Parameters:
18 | * - chunk: Binary data of current chunk
19 | * - index: Index of current chunk
20 | * - Returns:
21 | * - A Promise that resolves to HashResult
22 | */
23 | type ChunkHashFn = (chunk: Blob, index: number) => HashResult;
24 |
25 | /**
26 | * Single calculation mode:
27 | * - Parameters:
28 | * - file: Complete file object
29 | * - Returns:
30 | * - A Promise that resolves to HashResult
31 | */
32 | type FileHashFn = (file: File) => HashResult;
33 |
34 | export interface UploadOptions {
35 | /**
36 | * Current chunk data
37 | * @example new Blob([file.slice(0, chunkSize)])
38 | */
39 | chunk: Blob;
40 | /**
41 | * Current chunk index (absolute position starting from 0, including start offset)
42 | * @example If startOffset=3, then actual index range is [3,4,5...]
43 | */
44 | index: number;
45 | /**
46 | * Unique hash value of the file
47 | * @example "sha256-xxxxxx"
48 | */
49 | hash: string | null;
50 | /**
51 | * Axios cancel token for request cancellation
52 | * @example axios.CancelToken.source().token
53 | */
54 | cancelToken: CancelToken;
55 | }
56 |
57 | export interface Config {
58 | /**
59 | * [Required] Chunk upload handling function
60 | * @example ({ chunk, index, hash }) => axios.post(uploadUrl, formData)
61 | */
62 | uploadFunction: (options: UploadOptions) => Promise;
63 | /**
64 | * [Optional] Chunk size (bytes), default is 5MB
65 | * @default 5 * 1024 * 1024
66 | */
67 | chunkSize?: number;
68 | /**
69 | * [Optional] Starting chunk position index (for resumable uploads), defaults to start from first chunk
70 | * @example 3 (starts from 4th chunk)
71 | */
72 | startOffset?: number;
73 | /**
74 | * [Optional] Specify chunk indices to upload (higher priority than startOffset)
75 | * @example [0,2,3] (only upload chunks with index 0, 2, 3)
76 | */
77 | includeChunks?: number[];
78 | /**
79 | * [Optional] Maximum retry attempts on upload failure, default 3 times
80 | * @default 3
81 | */
82 | maxRetries?: number;
83 | /**
84 | * [Optional] Maximum concurrent requests, default 5
85 | * @default 5
86 | */
87 | concurrency?: number;
88 | /**
89 | * [Optional] Whether to calculate file hash, default false
90 | * @default false
91 | */
92 | hash?: boolean;
93 | /**
94 | * [Optional] Specify number of webworker threads needed for hash calculation
95 | * @default System CPU cores - 2
96 | */
97 | threads?: number;
98 | /**
99 | * [Optional] Whether to wait for hash calculation completion before upload, default true
100 | * @default true
101 | */
102 | awaitHash?: boolean;
103 | /**
104 | * [Optional] Custom hash calculation function:
105 | * Supports two modes:
106 | * 1. Direct file hash function input
107 | * 2. Pass an object to enable stream calculation mode:
108 | * - flow: Whether to enable chunk stream processing mode
109 | * - calculationHash: Chunk-level hash function
110 | */
111 | customHash?:
112 | | FileHashFn
113 | | {
114 | flow: Boolean;
115 | calculationHash: ChunkHashFn;
116 | };
117 | /**
118 | * [Optional] Whether to calculate all chunk hashes, default false
119 | * @default false
120 | */
121 | chunkMap?: boolean | { async: boolean; indices?: number[] };
122 | /**
123 | * [Callback] Triggered when hash calculation starts
124 | */
125 | beginHash?: () => void;
126 | /**
127 | * [Callback] Triggered when hash calculation completes, returns final hash value
128 | */
129 | endHash?: (hash: string) => void;
130 | /**
131 | * [Callback] Triggered when upload progress changes, returns value 0-100
132 | */
133 | onProgress?: (progress: number) => void;
134 | /**
135 | * [Callback] Triggered when real-time upload speed changes, returns string with unit
136 | * @example "2.45 MB/s"
137 | */
138 | onSpeed?: (speed: string) => void;
139 | /**
140 | * [Callback] Triggered when all chunks are uploaded and merged successfully
141 | */
142 | onSuccess?: () => void;
143 | }
144 |
145 | export interface State {
146 | /**
147 | * Upload progress percentage (0-100)
148 | */
149 | progress: number;
150 | /**
151 | * Current real-time upload speed (with unit)
152 | * @example "1.23 MB/s"
153 | */
154 | speed: string;
155 | /**
156 | * Whether upload is completed
157 | */
158 | uploadEnd: boolean;
159 | /**
160 | * File hash value (SHA256 based on chunk content)
161 | */
162 | hash: string;
163 | /**
164 | * Current uploading original File object
165 | */
166 | file: File | null;
167 | /**
168 | * Total number of chunks (including offset chunks)
169 | */
170 | totalChunks: number;
171 | /**
172 | * Upload error message
173 | */
174 | errorMsg: Error | null;
175 | /**
176 | * All chunks
177 | */
178 | allChunks: [];
179 | /**
180 | * All chunks hashMap (only available when calculation is enabled, disabled by default)
181 | */
182 | hashMap: Map;
183 | }
184 |
185 | export interface Uploader {
186 | /**
187 | * Start file upload
188 | * @param file - Browser File object to upload
189 | * @throws Chunk initialization failure/Unhandled error during upload
190 | */
191 | upload: (file: File) => Promise;
192 | /**
193 | * Pause upload (will cancel ongoing transfer requests)
194 | */
195 | pause: () => void;
196 | /**
197 | * Resume paused upload (continue from breakpoint)
198 | * @throws Error if called before chunk initialization
199 | */
200 | resume: () => Promise;
201 | /**
202 | * Reset all states to initial values (equivalent to reinitialization)
203 | * - Clear all chunk data
204 | * - Cancel all ongoing requests
205 | * - Clear timers and cached data
206 | * - Reset progress to 0%
207 | */
208 | reset: () => void;
209 | /**
210 | * Real-time state object, can achieve reactive updates by monitoring related properties
211 | */
212 | state: State;
213 | }
214 |
215 | // Define base upload configuration interface, keeping only core configuration items
216 | export interface CheckerConfig
217 | extends Omit<
218 | Config,
219 | | "startOffset"
220 | | "concurrency"
221 | | "maxRetries"
222 | | "includeChunks"
223 | | "onProgress"
224 | | "onSpeed"
225 | | "onSuccess"
226 | | "uploadFunction"
227 | | "customHash"
228 | > {}
229 |
230 | // Return type for checker function
231 | export interface CheckerResult {
232 | /**
233 | * All chunks hashMap
234 | */
235 | chunkHashMap: Map;
236 | /**
237 | * File hash value
238 | */
239 | hash: string;
240 | /**
241 | * Total number of chunks
242 | */
243 | totalChunks: number;
244 | /**
245 | * All chunks
246 | */
247 | allChunks: Blob[];
248 | }
249 | declare function createUploader(config: Config): Uploader;
250 | declare function checker(
251 | file: File,
252 | config: CheckerConfig
253 | ): Promise;
254 |
255 | export { createUploader, checker };
256 |
--------------------------------------------------------------------------------
/src/upload.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @description:This is not the latest source code, so please do not use the files in the src directory directly!
3 | However, the files in the dist directory are compiled from the latest version and can be used directly!
4 | We will gradually open-source the new source code, so we apologize!
5 | * @date: 2023-06-28 current src file version: 1.0.0
6 | * @date: 2023-7-07 current dist file version: 1.0.22
7 | * @author: Jam
8 | */
9 | const axios = require('axios');
10 | function createUploader(config) {
11 | let fileChunks = null;
12 | let currentHash = null;
13 | let currentChunkIndex = 0;
14 | let isPaused = false;
15 | let activeRequests = [];
16 | let cancelTokens = [];
17 | let totalChunks = 0;
18 | let uploadedChunks = 0;
19 | let canceledChunks = [];
20 | let state = new Proxy(
21 | {
22 | progress: 0, // 进度
23 | speed: 0, // 上传速度
24 | uploadEnd: false, // 上传结束标志
25 | hash: "", // 文件总哈希值
26 | file: "", // 文件对象
27 | totalChunks: "", // 切片总数
28 | errorMsg: "", // 错误信息
29 | allChunks: [], // 所有切片数组
30 | hashMap: new Map(), // 哈希映射
31 | },
32 | {
33 | set(target, property, value) {
34 | if (property === "progress") {
35 | target[property] = value;
36 | return true;
37 | }
38 | if (property === "speed") {
39 | target[property] = value;
40 | return true;
41 | }
42 | if (property === "uploadEnd") {
43 | target[property] = true;
44 | return true;
45 | }
46 | if (property === "hash") {
47 | target[property] = value;
48 | return true;
49 | }
50 | if (property === "file") {
51 | target[property] = value;
52 | return true;
53 | }
54 | if (property === "totalChunks") {
55 | target[property] = value;
56 | return true;
57 | }
58 | if (property === "errorMsg") {
59 | target[property] = value;
60 | return true;
61 | }
62 | if (property === "allChunks") {
63 | target[property] = value;
64 | return true;
65 | }
66 | if (property === "hashMap") {
67 | target[property] = value;
68 | return true;
69 | }
70 | return false;
71 | },
72 | }
73 | );
74 |
75 | function createFileChunk(file, size = 1 * 1024 * 1024) {
76 | let chunks = [];
77 | let count = Math.ceil(file.size / size);
78 | for (let i = 0; i < count; i++) {
79 | let chunk = file.slice(size * i, size * (i + 1));
80 | chunks.push(chunk);
81 | }
82 | return chunks;
83 | }
84 |
85 | function calculateHash(fileChunks) {
86 |
87 | return new Promise((resolve) => {
88 | setTimeout(() => resolve("fake-hash-value"), 1000);
89 | });
90 | }
91 |
92 | function createChunkUploader(
93 | chunk,
94 | index,
95 | hash,
96 | retryCount = 0,
97 | maxRetries,
98 | cancelToken
99 | ) {
100 | return async function () {
101 | const formData = new FormData();
102 | formData.append("chunk", chunk);
103 | formData.append("hash", hash);
104 | formData.append("index", index);
105 | const url = config.url || `http://localhost:3000/api/users`;
106 | try {
107 | await axios.post(url, formData, { cancelToken });
108 | uploadedChunks++;
109 | state.progress = (uploadedChunks / totalChunks) * 100;
110 | } catch (error) {
111 | if (axios.isCancel(error)) {
112 | canceledChunks.push({ chunk, index });
113 | return;
114 | }
115 | if (retryCount < maxRetries) {
116 | return createChunkUploader(
117 | chunk,
118 | index,
119 | hash,
120 | retryCount + 1,
121 | maxRetries,
122 | cancelToken
123 | )();
124 | }
125 | }
126 | };
127 | }
128 | async function uploadChunksWithConcurrencyControl(
129 | concurrency,
130 | maxRetries
131 | ) {
132 | const scheduleNext = async () => {
133 | if (isPaused || currentChunkIndex >= fileChunks.length) return;
134 | const chunk = fileChunks[currentChunkIndex];
135 | const cancelTokenSource = axios.CancelToken.source();
136 | cancelTokens.push(cancelTokenSource);
137 | const chunkUploader = createChunkUploader(
138 | chunk,
139 | currentChunkIndex,
140 | currentHash,
141 | 0,
142 | maxRetries,
143 | cancelTokenSource.token
144 | );
145 | currentChunkIndex++;
146 | const chunkUploadPromise = chunkUploader().then(() => {
147 | activeRequests = activeRequests.filter(
148 | (p) => p !== chunkUploadPromise
149 | );
150 | });
151 | activeRequests.push(chunkUploadPromise);
152 | if (activeRequests.length < concurrency) {
153 | scheduleNext();
154 | }
155 | };
156 | while (
157 | activeRequests.length < concurrency &&
158 | currentChunkIndex < fileChunks.length
159 | ) {
160 | scheduleNext();
161 | }
162 | await Promise.all(activeRequests);
163 | if (canceledChunks.length > 0 && !isPaused) {
164 | const tempCanceledChunks = [...canceledChunks];
165 | canceledChunks = [];
166 | for (const { chunk, index } of tempCanceledChunks) {
167 | const cancelTokenSource = axios.CancelToken.source();
168 | cancelTokens.push(cancelTokenSource);
169 | const chunkUploader = createChunkUploader(
170 | chunk,
171 | index,
172 | currentHash,
173 | 0,
174 | maxRetries,
175 | cancelTokenSource.token
176 | );
177 | const chunkUploadPromise = chunkUploader().then(() => {
178 | activeRequests = activeRequests.filter(
179 | (p) => p !== chunkUploadPromise
180 | );
181 | });
182 | activeRequests.push(chunkUploadPromise);
183 | if (activeRequests.length < concurrency) {
184 | scheduleNext();
185 | }
186 | }
187 | await Promise.all(activeRequests);
188 | }
189 | }
190 |
191 | function pauseUpload() {
192 | isPaused = true;
193 | cancelTokens = [];
194 | }
195 | async function resumeUpload() {
196 | if (!fileChunks) {
197 | }
198 | if (!isPaused) return;
199 | isPaused = false;
200 | await uploadChunksWithConcurrencyControl(
201 | config.concurrency || 5,
202 | config.maxRetries || 3
203 | );
204 | }
205 |
206 | async function handleUpload(file) {
207 | if (currentChunkIndex === 0) {
208 | }
209 | await uploadChunksWithConcurrencyControl(
210 | config.concurrency || 5,
211 | config.maxRetries || 3
212 | );
213 | }
214 | /**
215 | * 重置所有上传数据
216 | */
217 | function reset() {
218 | isReset = true;
219 | // 取消所有进行中的请求
220 | cancelTokens.forEach((source) => source.cancel("Upload reset"));
221 | // 清空所有状态和计数器
222 | fileChunks = [];
223 | currentHash = null;
224 | currentChunkIndex = 0;
225 | isPaused = false;
226 | activeRequests = [];
227 | cancelTokens = [];
228 | totalChunks = 0;
229 | uploadedChunks = 0;
230 | canceledChunks = [];
231 | uploadedSize = 0;
232 | accumulatedPausedTime = 0;
233 | lastPauseTime = 0;
234 | globalObj = {};
235 |
236 | // 停止速度计算定时器
237 | if (intervalId) {
238 | clearInterval(intervalId);
239 | intervalId = null;
240 | }
241 |
242 | // 重置状态对象
243 | Object.keys(state).forEach((key) => {
244 | if (key === "progress") state[key] = 0;
245 | else if (key === "speed") state[key] = 0;
246 | else if (key === "uploadEnd") state[key] = false;
247 | else if (key === "hash") state[key] = "";
248 | else if (key === "file") state[key] = "";
249 | else if (key === "totalChunks") state[key] = "";
250 | else if (key === "errorMsg") state[key] = "";
251 | else if (key === "allChunks") state[key] = [];
252 | else if (key === "hashMap") state[key] = new Map();
253 | });
254 | }
255 |
256 | return {
257 | upload: handleUpload,
258 | pause: pauseUpload,
259 | resume: resumeUpload,
260 | reset,
261 | state,
262 | };
263 | }
264 |
265 | /**
266 | * 检查文件hash值
267 | * @param {File} file - 待检查的文件对象
268 | * @param {Object} config - 配置对象
269 | * @returns {Promise<{hash: string, chunks: number}>} Promise对象,包含文件哈希值和切片数量
270 | */
271 | async function checker(file, config = {}) {
272 | let allChunks = [];
273 | let totalChunks = 0;
274 | let fileHash;
275 | let chunkHashMap = new Map();
276 | let cpuThreads = config.threads || cupNum;
277 | let optHash = [];
278 | let hashNumFlag = false;
279 | const startOffset = 0;
280 | globalObj = {};
281 | // (config.startOffset || 0) * (config.chunkSize || 5 * 1024 * 1024);
282 | // 创建文件切片
283 | allChunks = createFileChunk(
284 | file,
285 | config.chunkSize || 5 * 1024 * 1024,
286 | startOffset
287 | );
288 | totalChunks = allChunks.length;
289 | if (totalChunks === 0) {
290 | throw new Error(
291 | "The startOffset parameter is too large and the file slices array is empty."
292 | );
293 | }
294 | config.beginHash && config.beginHash();
295 | if (config.chunkMap?.indices?.length) {
296 | optHash = config.chunkMap?.indices.map((index) => allChunks[index]);
297 | } else {
298 | optHash = allChunks;
299 | }
300 | // 计算各个分片哈希值
301 | async function computeHash() {
302 | const thashMap = config.chunkMap && config.chunkMap?.async !== true;
303 | const yhashMap = config.chunkMap?.async;
304 | if (
305 | (yhashMap && config.awaitHash !== false) ||
306 | config.hash !== true ||
307 | (config.awaitHash == false && thashMap)
308 | ) {
309 | if (thashMap) {
310 | chunkHashMap = await hashAllSlices(optHash, config, cpuThreads);
311 | } else if (yhashMap) {
312 | hashAllSlices(optHash, config, cpuThreads).then((hashes) => {
313 | chunkHashMap = hashes;
314 | });
315 | }
316 | } else {
317 | hashNumFlag = true;
318 | }
319 | }
320 | await computeHash();
321 | config.endHash && config.endHash(fileHash);
322 | globalObj = {
323 | config,
324 | chunkHashMap: chunkHashMap,
325 | hash: fileHash,
326 | totalChunks,
327 | allChunks,
328 | chunkSize: config.chunkSize || 5 * 1024 * 1024,
329 | };
330 | return {
331 | chunkHashMap,
332 | hash: fileHash,
333 | totalChunks,
334 | allChunks,
335 | };
336 | }
337 |
338 | // 修改导出方式
339 | export { createUploader, checker };
340 |
341 | // 为了兼容 CommonJS
342 | if (typeof module !== "undefined" && module.exports) {
343 | module.exports = { createUploader, checker };
344 | }
--------------------------------------------------------------------------------
/dist/upload.js:
--------------------------------------------------------------------------------
1 | /*! For license information please see upload.js.LICENSE.txt */
2 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.fileUploader=t():e.fileUploader=t()}(this,(()=>(()=>{"use strict";var e={425:(e,t,n)=>{var r;function o(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,o,s,a,i=[],c=!0,u=!1;try{if(s=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;c=!1}else for(;!(c=(r=s.call(n)).done)&&(i.push(r.value),i.length!==t);c=!0);}catch(e){u=!0,o=e}finally{try{if(!c&&null!=n.return&&(a=n.return(),Object(a)!==a))return}finally{if(u)throw o}}return i}}(e,t)||a(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function s(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=a(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,o=function(){};return{s:o,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var s,i=!0,c=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return i=e.done,e},e:function(e){c=!0,s=e},f:function(){try{i||null==n.return||n.return()}finally{if(c)throw s}}}}function a(e,t){if(e){if("string"==typeof e)return i(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?i(e,t):void 0}}function i(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=0;--s){var a=this.tryEntries[s],i=a.completion;if("root"===a.tryLoc)return o("end");if(a.tryLoc<=this.prev){var c=r.call(a,"catchLoc"),u=r.call(a,"finallyLoc");if(c&&u){if(this.prev=0;--n){var o=this.tryEntries[n];if(o.tryLoc<=this.prev&&r.call(o,"finallyLoc")&&this.prev=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),P(n),b}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var r=n.completion;if("throw"===r.type){var o=r.arg;P(n)}return o}}throw Error("illegal catch attempt")},delegateYield:function(t,n,r){return this.delegate={iterator:N(t),resultName:n,nextLoc:r},"next"===this.method&&(this.arg=e),b}},t}function u(e){return u="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},u(e)}function l(e,t,n,r,o,s,a){try{var i=e[s](a),c=i.value}catch(e){return void n(e)}i.done?t(c):Promise.resolve(c).then(r,o)}function h(e){return function(){var t=this,n=arguments;return new Promise((function(r,o){var s=e.apply(t,n);function a(e){l(s,r,o,a,i,"next",e)}function i(e){l(s,r,o,a,i,"throw",e)}a(void 0)}))}}n.r(t),n.d(t,{checker:()=>g,createUploader:()=>y}),e=n.hmd(e);var f=n(806),p=(null===(r=navigator)||void 0===r?void 0:r.hardwareConcurrency)||0;p=p?Math.max(p-2,1):1;var d={},m=null;function y(e){if(!e.uploadFunction)throw e.onError&&e.onError(),new Error("The required parameter uploadFunction is missing");null==e.hash&&(e.hash=!0),e.customHash&&(e.hash=!1);var t=!1,n=[],r=null,o=0,l=!1,m=[],y=[],g=0,b=0,E=[],x=0,O=null,S=null,T=0,j=0,A=e.threads||p,C=!1;e.chunkSize=d.chunkSize||e.chunkSize||5242880;var P=new Proxy({progress:0,speed:0,uploadEnd:!1,hash:"",file:"",totalChunks:"",errorMsg:"",allChunks:[],hashMap:new Map},{set:function(e,t,n){return"progress"===t||"speed"===t?(e[t]=n,!0):"uploadEnd"===t?(e[t]=!0,!0):("hash"===t||"file"===t||"totalChunks"===t||"errorMsg"===t||"allChunks"===t||"hashMap"===t)&&(e[t]=n,!0)}});function L(t,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,o=arguments.length>3?arguments[3]:void 0,s=arguments.length>4&&void 0!==arguments[4]?arguments[4]:e.maxRetries||3;return h(c().mark((function a(){var i,l,h,p,d;return c().wrap((function(a){for(;;)switch(a.prev=a.next){case 0:if(i=!1,a.prev=1,!e.startOffset&&(null===(l=e.includeChunks)||void 0===l?void 0:l.length)>0?e.includeChunks.includes(n)&&(i=!0):i=!0,!i){a.next=15;break}if(i=!1,"object"!==u(e.customHash)||null===e.customHash||!e.customHash.flow){a.next=13;break}return a.next=8,e.customHash.calculationHash(t,n);case 8:h=a.sent,p=h.hash,d=h.hashMap,P.hash=p,P.hashMap=d;case 13:return a.next=15,e.uploadFunction({chunk:t,index:n,hash:P.hash,cancelToken:o});case 15:b++,x+=t.size,P.progress=b/g*100,e.onProgress&&e.onProgress(P.progress),a.next=39;break;case 21:if(a.prev=21,a.t0=a.catch(1),!f.isCancel(a.t0)){a.next=26;break}return E.push({chunk:t,index:n}),a.abrupt("return");case 26:if(!(r=1?"".concat(n.toFixed(2)," MB/s"):"".concat((1024*n).toFixed(2)," KB/s")}(O,x);P.speed=t,e.onSpeed(t)}b>=g&&0===E.length&&0===m.length&&!l&&(M(),P.uploadEnd=!0,e.onSuccess&&e.onSuccess())}),1e3))}function M(){S&&(clearInterval(S),S=null)}function U(){return _.apply(this,arguments)}function _(){return _=h(c().mark((function r(){var u,p,d,b,w,v,x,O,k,S=arguments;return c().wrap((function(r){for(;;)switch(r.prev=r.next){case 0:if(u=S.length>0&&void 0!==S[0]?S[0]:e.concurrency||5,!l&&!t){r.next=3;break}return r.abrupt("return");case 3:if(0!==n.length){r.next=6;break}throw e.onError&&e.onError(),new Error("The file slice has not been initialized. Please call the handleUpload method first.");case 6:for(p=Math.floor((e.startOffset||0)*e.chunkSize/e.chunkSize),d=JSON.parse(JSON.stringify(e.includeChunks||[])),b=0===p&&d.length>0,w=function(){var e=h(c().mark((function e(){var t,r,s,a,i;return c().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(!(l||o>=n.length)){e.next=2;break}return e.abrupt("return");case 2:if(!((t=b?d.shift()+p:o+p)>=g)){e.next=7;break}return console.warn("Chunk index ".concat(t," is out of range. Skipping.")),o++,e.abrupt("return");case 7:r=n[o],s=f.CancelToken.source(),y.push(s),a=L(r,p+o,0,s.token),o++,i=a().then((function(){m=m.filter((function(e){return e!==i})),w()})),m.push(i),m.length0)||l){r.next=34;break}v=function(e){if(Array.isArray(e))return i(e)}(R=E)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(R)||a(R)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(),E=[],x=s(v),r.prev=17,k=c().mark((function e(){var t,n,r,o,s,a;return c().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:t=O.value,n=t.chunk,r=t.index,o=f.CancelToken.source(),y.push(o),s=L(n,p+r-p,0,o.token),a=s().then((function(){m=m.filter((function(e){return e!==a}))})),m.push(a),m.length1&&void 0!==b[1]?b[1]:{},o=[],s=0,i=new Map,u=r.threads||p,l=[],f=!1,d={},o=w(t,r.chunkSize||5242880,0),0!==(s=o.length)){e.next=15;break}throw new Error("The startOffset parameter is too large and the file slices array is empty.");case 15:return r.beginHash&&r.beginHash(),l=null!==(n=r.chunkMap)&&void 0!==n&&null!==(n=n.indices)&&void 0!==n&&n.length?null===(m=r.chunkMap)||void 0===m?void 0:m.indices.map((function(e){return o[e]})):o,e.next=19,y();case 19:return r.endHash&&r.endHash(a),d={config:r,chunkHashMap:i,hash:a,totalChunks:s,allChunks:o,chunkSize:r.chunkSize||5242880},e.abrupt("return",{chunkHashMap:i,hash:a,totalChunks:s,allChunks:o});case 22:case"end":return e.stop()}}),e)}))),b.apply(this,arguments)}function w(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:5242880,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,r=[],o=Math.ceil((e.size-n)/t),s=0;s1&&void 0!==i[1]?i[1]:{},r=i.length>2&&void 0!==i[2]?i[2]:4,e.next=4,x();case 4:return a=e.sent,e.abrupt("return",new Promise((function(e){r=Math.min(r,t.length);for(var i=Math.ceil(t.length/r),c=0,u=new Map,l=0;l {\n const { slices, startIndex } = e.data;\n const hashes = new Map();\n\n for (let i = 0; i < slices.length; i++) {\n const blob = slices[i];\n try {\n const arrayBuffer = await blob.arrayBuffer();\n const chunk = new Uint8Array(arrayBuffer);\n const hashHex = sha256(chunk);\n hashes.set(startIndex + i, hashHex);\n } catch (error) {\n console.error('Error processing chunk:', error);\n hashes.set(startIndex + i, 'error');\n }\n }\n\n self.postMessage({ results: Array.from(hashes.entries()) });\n self.close();\n };\n "),n=new Blob([t],{type:"text/javascript"}),e.abrupt("return",URL.createObjectURL(n));case 7:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function k(e,t,n){return S.apply(this,arguments)}function S(){return(S=h(c().mark((function e(t,n,r){return c().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(m){e.next=4;break}return e.next=3,fetch("https://unpkg.com/js-sha256@0.9.0/src/sha256.js").then((function(e){return e.text()}));case 3:m=e.sent;case 4:return e.abrupt("return",new Promise((function(e,o){var s=URL.createObjectURL(new Blob(["\n ".concat(m,"\n // importScripts('https://cdn.jsdelivr.net/npm/js-sha256@0.9.0/src/sha256.js');\n \n self.onmessage = async function (event) {\n const { chunks, hashNumFlag, chunkMap, startOffset } = event.data;\n const hash = sha256.create();\n const hashes = new Map();\n const hashPromises = [];\n \n let index = 0;\n for (const chunk of chunks) {\n try {\n const chunkBuffer = await chunk.arrayBuffer();\n const uint8Array = new Uint8Array(chunkBuffer);\n hash.update(uint8Array);\n const angency = Array.isArray(chunkMap?.indices) && chunkMap.indices.length > 0\n ? chunkMap.indices.includes(Number(index)) // 如果是非空数组,检查是否包含 i\n : true; // 否则返回 true\n\n if (hashNumFlag && chunkMap && angency) {\n hashPromises.push(Promise.resolve({\n index,\n hash: sha256(uint8Array)\n }));\n }\n } catch (e) {\n self.postMessage({ error: e });\n return;\n }\n index++;\n }\n if (hashPromises.length > 0) {\n const results = await Promise.all(hashPromises);\n results.forEach(({ index, hash }) => {\n hashes.set(index+startOffset, hash);\n });\n }\n \n self.postMessage({ \n finalHash: hash.hex(), \n hashes: hashes.size > 0 ? hashes : undefined \n });\n self.close();\n };\n ")],{type:"application/javascript"})),a=new Worker(s);a.postMessage({chunks:t,hashNumFlag:n,chunkMap:r.chunkMap,startOffset:r.startOffset||0}),a.onmessage=function(t){t.data.error?o(t.data.error):e({hash:t.data.finalHash,hashMap:t.data.hashes}),URL.revokeObjectURL(s)},a.onerror=function(e){console.error("Worker error:",e),o(e),setTimeout((function(){return URL.revokeObjectURL(s)}),0)}})));case 5:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function R(e,t){var n,r,o,s,a="",i=new Map;if(d.hash&&(!1===e.hash||0!=e.startOffset&&e.startOffset||e.includeChunks&&0!==(null===(r=e.includeChunks)||void 0===r?void 0:r.length)||(a=d.hash)),null!==(n=d.chunkHashMap)&&void 0!==n&&n.size&&e.chunkMap)if(0!=e.startOffset&&e.startOffset||e.includeChunks&&0!=(null===(o=e.includeChunks)||void 0===o?void 0:o.length)){if((null===(s=e.includeChunks)||void 0===s?void 0:s.length)>0)for(var c=e.includeChunks,u=0;u0)for(var f=Array.from({length:t},(function(t,n){return e.startOffset+n})),p=0;p{function r(e,t){return function(){return e.apply(t,arguments)}}const{toString:o}=Object.prototype,{getPrototypeOf:s}=Object,a=(i=Object.create(null),e=>{const t=o.call(e);return i[t]||(i[t]=t.slice(8,-1).toLowerCase())});var i;const c=e=>(e=e.toLowerCase(),t=>a(t)===e),u=e=>t=>typeof t===e,{isArray:l}=Array,h=u("undefined"),f=c("ArrayBuffer"),p=u("string"),d=u("function"),m=u("number"),y=e=>null!==e&&"object"==typeof e,g=e=>{if("object"!==a(e))return!1;const t=s(e);return!(null!==t&&t!==Object.prototype&&null!==Object.getPrototypeOf(t)||Symbol.toStringTag in e||Symbol.iterator in e)},b=c("Date"),w=c("File"),v=c("Blob"),E=c("FileList"),x=c("URLSearchParams"),[O,k,S,R]=["ReadableStream","Request","Response","Headers"].map(c);function T(e,t,{allOwnKeys:n=!1}={}){if(null==e)return;let r,o;if("object"!=typeof e&&(e=[e]),l(e))for(r=0,o=e.length;r0;)if(r=n[o],t===r.toLowerCase())return r;return null}const A="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:n.g,C=e=>!h(e)&&e!==A,P=(L="undefined"!=typeof Uint8Array&&s(Uint8Array),e=>L&&e instanceof L);var L;const N=c("HTMLFormElement"),M=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),U=c("RegExp"),_=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),r={};T(n,((n,o)=>{let s;!1!==(s=t(n,o,e))&&(r[o]=s||n)})),Object.defineProperties(e,r)},F="abcdefghijklmnopqrstuvwxyz",B="0123456789",D={DIGIT:B,ALPHA:F,ALPHA_DIGIT:F+F.toUpperCase()+B},H=c("AsyncFunction");var z={isArray:l,isArrayBuffer:f,isBuffer:function(e){return null!==e&&!h(e)&&null!==e.constructor&&!h(e.constructor)&&d(e.constructor.isBuffer)&&e.constructor.isBuffer(e)},isFormData:e=>{let t;return e&&("function"==typeof FormData&&e instanceof FormData||d(e.append)&&("formdata"===(t=a(e))||"object"===t&&d(e.toString)&&"[object FormData]"===e.toString()))},isArrayBufferView:function(e){let t;return t="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&f(e.buffer),t},isString:p,isNumber:m,isBoolean:e=>!0===e||!1===e,isObject:y,isPlainObject:g,isReadableStream:O,isRequest:k,isResponse:S,isHeaders:R,isUndefined:h,isDate:b,isFile:w,isBlob:v,isRegExp:U,isFunction:d,isStream:e=>y(e)&&d(e.pipe),isURLSearchParams:x,isTypedArray:P,isFileList:E,forEach:T,merge:function e(){const{caseless:t}=C(this)&&this||{},n={},r=(r,o)=>{const s=t&&j(n,o)||o;g(n[s])&&g(r)?n[s]=e(n[s],r):g(r)?n[s]=e({},r):l(r)?n[s]=r.slice():n[s]=r};for(let e=0,t=arguments.length;e(T(t,((t,o)=>{n&&d(t)?e[o]=r(t,n):e[o]=t}),{allOwnKeys:o}),e),trim:e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),stripBOM:e=>(65279===e.charCodeAt(0)&&(e=e.slice(1)),e),inherits:(e,t,n,r)=>{e.prototype=Object.create(t.prototype,r),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),n&&Object.assign(e.prototype,n)},toFlatObject:(e,t,n,r)=>{let o,a,i;const c={};if(t=t||{},null==e)return t;do{for(o=Object.getOwnPropertyNames(e),a=o.length;a-- >0;)i=o[a],r&&!r(i,e,t)||c[i]||(t[i]=e[i],c[i]=!0);e=!1!==n&&s(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},kindOf:a,kindOfTest:c,endsWith:(e,t,n)=>{e=String(e),(void 0===n||n>e.length)&&(n=e.length),n-=t.length;const r=e.indexOf(t,n);return-1!==r&&r===n},toArray:e=>{if(!e)return null;if(l(e))return e;let t=e.length;if(!m(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},forEachEntry:(e,t)=>{const n=(e&&e[Symbol.iterator]).call(e);let r;for(;(r=n.next())&&!r.done;){const n=r.value;t.call(e,n[0],n[1])}},matchAll:(e,t)=>{let n;const r=[];for(;null!==(n=e.exec(t));)r.push(n);return r},isHTMLForm:N,hasOwnProperty:M,hasOwnProp:M,reduceDescriptors:_,freezeMethods:e=>{_(e,((t,n)=>{if(d(e)&&-1!==["arguments","caller","callee"].indexOf(n))return!1;const r=e[n];d(r)&&(t.enumerable=!1,"writable"in t?t.writable=!1:t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")}))}))},toObjectSet:(e,t)=>{const n={},r=e=>{e.forEach((e=>{n[e]=!0}))};return l(e)?r(e):r(String(e).split(t)),n},toCamelCase:e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,(function(e,t,n){return t.toUpperCase()+n})),noop:()=>{},toFiniteNumber:(e,t)=>null!=e&&Number.isFinite(e=+e)?e:t,findKey:j,global:A,isContextDefined:C,ALPHABET:D,generateString:(e=16,t=D.ALPHA_DIGIT)=>{let n="";const{length:r}=t;for(;e--;)n+=t[Math.random()*r|0];return n},isSpecCompliantForm:function(e){return!!(e&&d(e.append)&&"FormData"===e[Symbol.toStringTag]&&e[Symbol.iterator])},toJSONObject:e=>{const t=new Array(10),n=(e,r)=>{if(y(e)){if(t.indexOf(e)>=0)return;if(!("toJSON"in e)){t[r]=e;const o=l(e)?[]:{};return T(e,((e,t)=>{const s=n(e,r+1);!h(s)&&(o[t]=s)})),t[r]=void 0,o}}return e};return n(e,0)},isAsyncFn:H,isThenable:e=>e&&(y(e)||d(e))&&d(e.then)&&d(e.catch)};function I(e,t,n,r,o){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack,this.message=e,this.name="AxiosError",t&&(this.code=t),n&&(this.config=n),r&&(this.request=r),o&&(this.response=o)}z.inherits(I,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:z.toJSONObject(this.config),code:this.code,status:this.response&&this.response.status?this.response.status:null}}});const q=I.prototype,J={};function W(e){return z.isPlainObject(e)||z.isArray(e)}function K(e){return z.endsWith(e,"[]")?e.slice(0,-2):e}function G(e,t,n){return e?e.concat(t).map((function(e,t){return e=K(e),!n&&t?"["+e+"]":e})).join(n?".":""):t}["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach((e=>{J[e]={value:e}})),Object.defineProperties(I,J),Object.defineProperty(q,"isAxiosError",{value:!0}),I.from=(e,t,n,r,o,s)=>{const a=Object.create(q);return z.toFlatObject(e,a,(function(e){return e!==Error.prototype}),(e=>"isAxiosError"!==e)),I.call(a,e.message,t,n,r,o),a.cause=e,a.name=e.name,s&&Object.assign(a,s),a};const V=z.toFlatObject(z,{},null,(function(e){return/^is[A-Z]/.test(e)}));function $(e,t,n){if(!z.isObject(e))throw new TypeError("target must be an object");t=t||new FormData;const r=(n=z.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,(function(e,t){return!z.isUndefined(t[e])}))).metaTokens,o=n.visitor||u,s=n.dots,a=n.indexes,i=(n.Blob||"undefined"!=typeof Blob&&Blob)&&z.isSpecCompliantForm(t);if(!z.isFunction(o))throw new TypeError("visitor must be a function");function c(e){if(null===e)return"";if(z.isDate(e))return e.toISOString();if(!i&&z.isBlob(e))throw new I("Blob is not supported. Use a Buffer instead.");return z.isArrayBuffer(e)||z.isTypedArray(e)?i&&"function"==typeof Blob?new Blob([e]):Buffer.from(e):e}function u(e,n,o){let i=e;if(e&&!o&&"object"==typeof e)if(z.endsWith(n,"{}"))n=r?n:n.slice(0,-2),e=JSON.stringify(e);else if(z.isArray(e)&&function(e){return z.isArray(e)&&!e.some(W)}(e)||(z.isFileList(e)||z.endsWith(n,"[]"))&&(i=z.toArray(e)))return n=K(n),i.forEach((function(e,r){!z.isUndefined(e)&&null!==e&&t.append(!0===a?G([n],r,s):null===a?n:n+"[]",c(e))})),!1;return!!W(e)||(t.append(G(o,n,s),c(e)),!1)}const l=[],h=Object.assign(V,{defaultVisitor:u,convertValue:c,isVisitable:W});if(!z.isObject(e))throw new TypeError("data must be an object");return function e(n,r){if(!z.isUndefined(n)){if(-1!==l.indexOf(n))throw Error("Circular reference detected in "+r.join("."));l.push(n),z.forEach(n,(function(n,s){!0===(!(z.isUndefined(n)||null===n)&&o.call(t,n,z.isString(s)?s.trim():s,r,h))&&e(n,r?r.concat(s):[s])})),l.pop()}}(e),t}function X(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,(function(e){return t[e]}))}function Y(e,t){this._pairs=[],e&&$(e,this,t)}const Q=Y.prototype;function Z(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}function ee(e,t,n){if(!t)return e;const r=n&&n.encode||Z,o=n&&n.serialize;let s;if(s=o?o(t,n):z.isURLSearchParams(t)?t.toString():new Y(t,n).toString(r),s){const t=e.indexOf("#");-1!==t&&(e=e.slice(0,t)),e+=(-1===e.indexOf("?")?"?":"&")+s}return e}Q.append=function(e,t){this._pairs.push([e,t])},Q.toString=function(e){const t=e?function(t){return e.call(this,t,X)}:X;return this._pairs.map((function(e){return t(e[0])+"="+t(e[1])}),"").join("&")};var te=class{constructor(){this.handlers=[]}use(e,t,n){return this.handlers.push({fulfilled:e,rejected:t,synchronous:!!n&&n.synchronous,runWhen:n?n.runWhen:null}),this.handlers.length-1}eject(e){this.handlers[e]&&(this.handlers[e]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(e){z.forEach(this.handlers,(function(t){null!==t&&e(t)}))}},ne={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},re={isBrowser:!0,classes:{URLSearchParams:"undefined"!=typeof URLSearchParams?URLSearchParams:Y,FormData:"undefined"!=typeof FormData?FormData:null,Blob:"undefined"!=typeof Blob?Blob:null},protocols:["http","https","file","blob","url","data"]};const oe="undefined"!=typeof window&&"undefined"!=typeof document,se=(ae="undefined"!=typeof navigator&&navigator.product,oe&&["ReactNative","NativeScript","NS"].indexOf(ae)<0);var ae;const ie="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&"function"==typeof self.importScripts,ce=oe&&window.location.href||"http://localhost";var ue={...Object.freeze({__proto__:null,hasBrowserEnv:oe,hasStandardBrowserWebWorkerEnv:ie,hasStandardBrowserEnv:se,origin:ce}),...re};function le(e){function t(e,n,r,o){let s=e[o++];if("__proto__"===s)return!0;const a=Number.isFinite(+s),i=o>=e.length;return s=!s&&z.isArray(r)?r.length:s,i?(z.hasOwnProp(r,s)?r[s]=[r[s],n]:r[s]=n,!a):(r[s]&&z.isObject(r[s])||(r[s]=[]),t(e,n,r[s],o)&&z.isArray(r[s])&&(r[s]=function(e){const t={},n=Object.keys(e);let r;const o=n.length;let s;for(r=0;r{t(function(e){return z.matchAll(/\w+|\[(\w*)]/g,e).map((e=>"[]"===e[0]?"":e[1]||e[0]))}(e),r,n,0)})),n}return null}const he={transitional:ne,adapter:["xhr","http","fetch"],transformRequest:[function(e,t){const n=t.getContentType()||"",r=n.indexOf("application/json")>-1,o=z.isObject(e);if(o&&z.isHTMLForm(e)&&(e=new FormData(e)),z.isFormData(e))return r?JSON.stringify(le(e)):e;if(z.isArrayBuffer(e)||z.isBuffer(e)||z.isStream(e)||z.isFile(e)||z.isBlob(e)||z.isReadableStream(e))return e;if(z.isArrayBufferView(e))return e.buffer;if(z.isURLSearchParams(e))return t.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),e.toString();let s;if(o){if(n.indexOf("application/x-www-form-urlencoded")>-1)return function(e,t){return $(e,new ue.classes.URLSearchParams,Object.assign({visitor:function(e,t,n,r){return ue.isNode&&z.isBuffer(e)?(this.append(t,e.toString("base64")),!1):r.defaultVisitor.apply(this,arguments)}},t))}(e,this.formSerializer).toString();if((s=z.isFileList(e))||n.indexOf("multipart/form-data")>-1){const t=this.env&&this.env.FormData;return $(s?{"files[]":e}:e,t&&new t,this.formSerializer)}}return o||r?(t.setContentType("application/json",!1),function(e,t,n){if(z.isString(e))try{return(0,JSON.parse)(e),z.trim(e)}catch(e){if("SyntaxError"!==e.name)throw e}return(0,JSON.stringify)(e)}(e)):e}],transformResponse:[function(e){const t=this.transitional||he.transitional,n=t&&t.forcedJSONParsing,r="json"===this.responseType;if(z.isResponse(e)||z.isReadableStream(e))return e;if(e&&z.isString(e)&&(n&&!this.responseType||r)){const n=!(t&&t.silentJSONParsing)&&r;try{return JSON.parse(e)}catch(e){if(n){if("SyntaxError"===e.name)throw I.from(e,I.ERR_BAD_RESPONSE,this,null,this.response);throw e}}}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:ue.classes.FormData,Blob:ue.classes.Blob},validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};z.forEach(["delete","get","head","post","put","patch"],(e=>{he.headers[e]={}}));var fe=he;const pe=z.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),de=Symbol("internals");function me(e){return e&&String(e).trim().toLowerCase()}function ye(e){return!1===e||null==e?e:z.isArray(e)?e.map(ye):String(e)}function ge(e,t,n,r,o){return z.isFunction(r)?r.call(this,t,n):(o&&(t=n),z.isString(t)?z.isString(r)?-1!==t.indexOf(r):z.isRegExp(r)?r.test(t):void 0:void 0)}class be{constructor(e){e&&this.set(e)}set(e,t,n){const r=this;function o(e,t,n){const o=me(t);if(!o)throw new Error("header name must be a non-empty string");const s=z.findKey(r,o);(!s||void 0===r[s]||!0===n||void 0===n&&!1!==r[s])&&(r[s||t]=ye(e))}const s=(e,t)=>z.forEach(e,((e,n)=>o(e,n,t)));if(z.isPlainObject(e)||e instanceof this.constructor)s(e,t);else if(z.isString(e)&&(e=e.trim())&&!/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim()))s((e=>{const t={};let n,r,o;return e&&e.split("\n").forEach((function(e){o=e.indexOf(":"),n=e.substring(0,o).trim().toLowerCase(),r=e.substring(o+1).trim(),!n||t[n]&&pe[n]||("set-cookie"===n?t[n]?t[n].push(r):t[n]=[r]:t[n]=t[n]?t[n]+", "+r:r)})),t})(e),t);else if(z.isHeaders(e))for(const[t,r]of e.entries())o(r,t,n);else null!=e&&o(t,e,n);return this}get(e,t){if(e=me(e)){const n=z.findKey(this,e);if(n){const e=this[n];if(!t)return e;if(!0===t)return function(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let r;for(;r=n.exec(e);)t[r[1]]=r[2];return t}(e);if(z.isFunction(t))return t.call(this,e,n);if(z.isRegExp(t))return t.exec(e);throw new TypeError("parser must be boolean|regexp|function")}}}has(e,t){if(e=me(e)){const n=z.findKey(this,e);return!(!n||void 0===this[n]||t&&!ge(0,this[n],n,t))}return!1}delete(e,t){const n=this;let r=!1;function o(e){if(e=me(e)){const o=z.findKey(n,e);!o||t&&!ge(0,n[o],o,t)||(delete n[o],r=!0)}}return z.isArray(e)?e.forEach(o):o(e),r}clear(e){const t=Object.keys(this);let n=t.length,r=!1;for(;n--;){const o=t[n];e&&!ge(0,this[o],o,e,!0)||(delete this[o],r=!0)}return r}normalize(e){const t=this,n={};return z.forEach(this,((r,o)=>{const s=z.findKey(n,o);if(s)return t[s]=ye(r),void delete t[o];const a=e?function(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,((e,t,n)=>t.toUpperCase()+n))}(o):String(o).trim();a!==o&&delete t[o],t[a]=ye(r),n[a]=!0})),this}concat(...e){return this.constructor.concat(this,...e)}toJSON(e){const t=Object.create(null);return z.forEach(this,((n,r)=>{null!=n&&!1!==n&&(t[r]=e&&z.isArray(n)?n.join(", "):n)})),t}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map((([e,t])=>e+": "+t)).join("\n")}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(e){return e instanceof this?e:new this(e)}static concat(e,...t){const n=new this(e);return t.forEach((e=>n.set(e))),n}static accessor(e){const t=(this[de]=this[de]={accessors:{}}).accessors,n=this.prototype;function r(e){const r=me(e);t[r]||(function(e,t){const n=z.toCamelCase(" "+t);["get","set","has"].forEach((r=>{Object.defineProperty(e,r+n,{value:function(e,n,o){return this[r].call(this,t,e,n,o)},configurable:!0})}))}(n,e),t[r]=!0)}return z.isArray(e)?e.forEach(r):r(e),this}}be.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]),z.reduceDescriptors(be.prototype,(({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(e){this[n]=e}}})),z.freezeMethods(be);var we=be;function ve(e,t){const n=this||fe,r=t||n,o=we.from(r.headers);let s=r.data;return z.forEach(e,(function(e){s=e.call(n,s,o.normalize(),t?t.status:void 0)})),o.normalize(),s}function Ee(e){return!(!e||!e.__CANCEL__)}function xe(e,t,n){I.call(this,null==e?"canceled":e,I.ERR_CANCELED,t,n),this.name="CanceledError"}function Oe(e,t,n){const r=n.config.validateStatus;n.status&&r&&!r(n.status)?t(new I("Request failed with status code "+n.status,[I.ERR_BAD_REQUEST,I.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n)):e(n)}z.inherits(xe,I,{__CANCEL__:!0});var ke=(e,t,n=3)=>{let r=0;const o=function(e,t){e=e||10;const n=new Array(e),r=new Array(e);let o,s=0,a=0;return t=void 0!==t?t:1e3,function(i){const c=Date.now(),u=r[a];o||(o=c),n[s]=i,r[s]=c;let l=a,h=0;for(;l!==s;)h+=n[l++],l%=e;if(s=(s+1)%e,s===a&&(a=(a+1)%e),c-or)return o&&(clearTimeout(o),o=null),n=s,e.apply(null,arguments);o||(o=setTimeout((()=>(o=null,n=Date.now(),e.apply(null,arguments))),r-(s-n)))}}((n=>{const s=n.loaded,a=n.lengthComputable?n.total:void 0,i=s-r,c=o(i);r=s;const u={loaded:s,total:a,progress:a?s/a:void 0,bytes:i,rate:c||void 0,estimated:c&&a&&s<=a?(a-s)/c:void 0,event:n,lengthComputable:null!=a};u[t?"download":"upload"]=!0,e(u)}),n)},Se=ue.hasStandardBrowserEnv?function(){const e=/(msie|trident)/i.test(navigator.userAgent),t=document.createElement("a");let n;function r(n){let r=n;return e&&(t.setAttribute("href",r),r=t.href),t.setAttribute("href",r),{href:t.href,protocol:t.protocol?t.protocol.replace(/:$/,""):"",host:t.host,search:t.search?t.search.replace(/^\?/,""):"",hash:t.hash?t.hash.replace(/^#/,""):"",hostname:t.hostname,port:t.port,pathname:"/"===t.pathname.charAt(0)?t.pathname:"/"+t.pathname}}return n=r(window.location.href),function(e){const t=z.isString(e)?r(e):e;return t.protocol===n.protocol&&t.host===n.host}}():function(){return!0},Re=ue.hasStandardBrowserEnv?{write(e,t,n,r,o,s){const a=[e+"="+encodeURIComponent(t)];z.isNumber(n)&&a.push("expires="+new Date(n).toGMTString()),z.isString(r)&&a.push("path="+r),z.isString(o)&&a.push("domain="+o),!0===s&&a.push("secure"),document.cookie=a.join("; ")},read(e){const t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove(e){this.write(e,"",Date.now()-864e5)}}:{write(){},read:()=>null,remove(){}};function Te(e,t){return e&&!/^([a-z][a-z\d+\-.]*:)?\/\//i.test(t)?function(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}(e,t):t}const je=e=>e instanceof we?{...e}:e;function Ae(e,t){t=t||{};const n={};function r(e,t,n){return z.isPlainObject(e)&&z.isPlainObject(t)?z.merge.call({caseless:n},e,t):z.isPlainObject(t)?z.merge({},t):z.isArray(t)?t.slice():t}function o(e,t,n){return z.isUndefined(t)?z.isUndefined(e)?void 0:r(void 0,e,n):r(e,t,n)}function s(e,t){if(!z.isUndefined(t))return r(void 0,t)}function a(e,t){return z.isUndefined(t)?z.isUndefined(e)?void 0:r(void 0,e):r(void 0,t)}function i(n,o,s){return s in t?r(n,o):s in e?r(void 0,n):void 0}const c={url:s,method:s,data:s,baseURL:a,transformRequest:a,transformResponse:a,paramsSerializer:a,timeout:a,timeoutMessage:a,withCredentials:a,withXSRFToken:a,adapter:a,responseType:a,xsrfCookieName:a,xsrfHeaderName:a,onUploadProgress:a,onDownloadProgress:a,decompress:a,maxContentLength:a,maxBodyLength:a,beforeRedirect:a,transport:a,httpAgent:a,httpsAgent:a,cancelToken:a,socketPath:a,responseEncoding:a,validateStatus:i,headers:(e,t)=>o(je(e),je(t),!0)};return z.forEach(Object.keys(Object.assign({},e,t)),(function(r){const s=c[r]||o,a=s(e[r],t[r],r);z.isUndefined(a)&&s!==i||(n[r]=a)})),n}var Ce=e=>{const t=Ae({},e);let n,{data:r,withXSRFToken:o,xsrfHeaderName:s,xsrfCookieName:a,headers:i,auth:c}=t;if(t.headers=i=we.from(i),t.url=ee(Te(t.baseURL,t.url),e.params,e.paramsSerializer),c&&i.set("Authorization","Basic "+btoa((c.username||"")+":"+(c.password?unescape(encodeURIComponent(c.password)):""))),z.isFormData(r))if(ue.hasStandardBrowserEnv||ue.hasStandardBrowserWebWorkerEnv)i.setContentType(void 0);else if(!1!==(n=i.getContentType())){const[e,...t]=n?n.split(";").map((e=>e.trim())).filter(Boolean):[];i.setContentType([e||"multipart/form-data",...t].join("; "))}if(ue.hasStandardBrowserEnv&&(o&&z.isFunction(o)&&(o=o(t)),o||!1!==o&&Se(t.url))){const e=s&&a&&Re.read(a);e&&i.set(s,e)}return t},Pe="undefined"!=typeof XMLHttpRequest&&function(e){return new Promise((function(t,n){const r=Ce(e);let o=r.data;const s=we.from(r.headers).normalize();let a,{responseType:i}=r;function c(){r.cancelToken&&r.cancelToken.unsubscribe(a),r.signal&&r.signal.removeEventListener("abort",a)}let u=new XMLHttpRequest;function l(){if(!u)return;const r=we.from("getAllResponseHeaders"in u&&u.getAllResponseHeaders());Oe((function(e){t(e),c()}),(function(e){n(e),c()}),{data:i&&"text"!==i&&"json"!==i?u.response:u.responseText,status:u.status,statusText:u.statusText,headers:r,config:e,request:u}),u=null}u.open(r.method.toUpperCase(),r.url,!0),u.timeout=r.timeout,"onloadend"in u?u.onloadend=l:u.onreadystatechange=function(){u&&4===u.readyState&&(0!==u.status||u.responseURL&&0===u.responseURL.indexOf("file:"))&&setTimeout(l)},u.onabort=function(){u&&(n(new I("Request aborted",I.ECONNABORTED,r,u)),u=null)},u.onerror=function(){n(new I("Network Error",I.ERR_NETWORK,r,u)),u=null},u.ontimeout=function(){let e=r.timeout?"timeout of "+r.timeout+"ms exceeded":"timeout exceeded";const t=r.transitional||ne;r.timeoutErrorMessage&&(e=r.timeoutErrorMessage),n(new I(e,t.clarifyTimeoutError?I.ETIMEDOUT:I.ECONNABORTED,r,u)),u=null},void 0===o&&s.setContentType(null),"setRequestHeader"in u&&z.forEach(s.toJSON(),(function(e,t){u.setRequestHeader(t,e)})),z.isUndefined(r.withCredentials)||(u.withCredentials=!!r.withCredentials),i&&"json"!==i&&(u.responseType=r.responseType),"function"==typeof r.onDownloadProgress&&u.addEventListener("progress",ke(r.onDownloadProgress,!0)),"function"==typeof r.onUploadProgress&&u.upload&&u.upload.addEventListener("progress",ke(r.onUploadProgress)),(r.cancelToken||r.signal)&&(a=t=>{u&&(n(!t||t.type?new xe(null,e,u):t),u.abort(),u=null)},r.cancelToken&&r.cancelToken.subscribe(a),r.signal&&(r.signal.aborted?a():r.signal.addEventListener("abort",a)));const h=function(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}(r.url);h&&-1===ue.protocols.indexOf(h)?n(new I("Unsupported protocol "+h+":",I.ERR_BAD_REQUEST,e)):u.send(o||null)}))},Le=(e,t)=>{let n,r=new AbortController;const o=function(e){if(!n){n=!0,a();const t=e instanceof Error?e:this.reason;r.abort(t instanceof I?t:new xe(t instanceof Error?t.message:t))}};let s=t&&setTimeout((()=>{o(new I(`timeout ${t} of ms exceeded`,I.ETIMEDOUT))}),t);const a=()=>{e&&(s&&clearTimeout(s),s=null,e.forEach((e=>{e&&(e.removeEventListener?e.removeEventListener("abort",o):e.unsubscribe(o))})),e=null)};e.forEach((e=>e&&e.addEventListener&&e.addEventListener("abort",o)));const{signal:i}=r;return i.unsubscribe=a,[i,()=>{s&&clearTimeout(s),s=null}]};const Ne=function*(e,t){let n=e.byteLength;if(!t||n{const s=async function*(e,t,n){for await(const r of e)yield*Ne(ArrayBuffer.isView(r)?r:await n(String(r)),t)}(e,t,o);let a=0;return new ReadableStream({type:"bytes",async pull(e){const{done:t,value:o}=await s.next();if(t)return e.close(),void r();let i=o.byteLength;n&&n(a+=i),e.enqueue(new Uint8Array(o))},cancel:e=>(r(e),s.return())},{highWaterMark:2})},Ue=(e,t)=>{const n=null!=e;return r=>setTimeout((()=>t({lengthComputable:n,total:e,loaded:r})))},_e="function"==typeof fetch&&"function"==typeof Request&&"function"==typeof Response,Fe=_e&&"function"==typeof ReadableStream,Be=_e&&("function"==typeof TextEncoder?(De=new TextEncoder,e=>De.encode(e)):async e=>new Uint8Array(await new Response(e).arrayBuffer()));var De;const He=Fe&&(()=>{let e=!1;const t=new Request(ue.origin,{body:new ReadableStream,method:"POST",get duplex(){return e=!0,"half"}}).headers.has("Content-Type");return e&&!t})(),ze=Fe&&!!(()=>{try{return z.isReadableStream(new Response("").body)}catch(e){}})(),Ie={stream:ze&&(e=>e.body)};var qe;_e&&(qe=new Response,["text","arrayBuffer","blob","formData","stream"].forEach((e=>{!Ie[e]&&(Ie[e]=z.isFunction(qe[e])?t=>t[e]():(t,n)=>{throw new I(`Response type '${e}' is not supported`,I.ERR_NOT_SUPPORT,n)})})));const Je={http:null,xhr:Pe,fetch:_e&&(async e=>{let{url:t,method:n,data:r,signal:o,cancelToken:s,timeout:a,onDownloadProgress:i,onUploadProgress:c,responseType:u,headers:l,withCredentials:h="same-origin",fetchOptions:f}=Ce(e);u=u?(u+"").toLowerCase():"text";let p,d,[m,y]=o||s||a?Le([o,s],a):[];const g=()=>{!p&&setTimeout((()=>{m&&m.unsubscribe()})),p=!0};let b;try{if(c&&He&&"get"!==n&&"head"!==n&&0!==(b=await(async(e,t)=>{const n=z.toFiniteNumber(e.getContentLength());return null==n?(async e=>null==e?0:z.isBlob(e)?e.size:z.isSpecCompliantForm(e)?(await new Request(e).arrayBuffer()).byteLength:z.isArrayBufferView(e)?e.byteLength:(z.isURLSearchParams(e)&&(e+=""),z.isString(e)?(await Be(e)).byteLength:void 0))(t):n})(l,r))){let e,n=new Request(t,{method:"POST",body:r,duplex:"half"});z.isFormData(r)&&(e=n.headers.get("content-type"))&&l.setContentType(e),n.body&&(r=Me(n.body,65536,Ue(b,ke(c)),null,Be))}z.isString(h)||(h=h?"cors":"omit"),d=new Request(t,{...f,signal:m,method:n.toUpperCase(),headers:l.normalize().toJSON(),body:r,duplex:"half",withCredentials:h});let o=await fetch(d);const s=ze&&("stream"===u||"response"===u);if(ze&&(i||s)){const e={};["status","statusText","headers"].forEach((t=>{e[t]=o[t]}));const t=z.toFiniteNumber(o.headers.get("content-length"));o=new Response(Me(o.body,65536,i&&Ue(t,ke(i,!0)),s&&g,Be),e)}u=u||"text";let a=await Ie[z.findKey(Ie,u)||"text"](o,e);return!s&&g(),y&&y(),await new Promise(((t,n)=>{Oe(t,n,{data:a,headers:we.from(o.headers),status:o.status,statusText:o.statusText,config:e,request:d})}))}catch(t){if(g(),t&&"TypeError"===t.name&&/fetch/i.test(t.message))throw Object.assign(new I("Network Error",I.ERR_NETWORK,e,d),{cause:t.cause||t});throw I.from(t,t&&t.code,e,d)}})};z.forEach(Je,((e,t)=>{if(e){try{Object.defineProperty(e,"name",{value:t})}catch(e){}Object.defineProperty(e,"adapterName",{value:t})}}));const We=e=>`- ${e}`,Ke=e=>z.isFunction(e)||null===e||!1===e;var Ge=e=>{e=z.isArray(e)?e:[e];const{length:t}=e;let n,r;const o={};for(let s=0;s`adapter ${e} `+(!1===t?"is not supported by the environment":"is not available in the build")));throw new I("There is no suitable adapter to dispatch the request "+(t?e.length>1?"since :\n"+e.map(We).join("\n"):" "+We(e[0]):"as no adapter specified"),"ERR_NOT_SUPPORT")}return r};function Ve(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new xe(null,e)}function $e(e){return Ve(e),e.headers=we.from(e.headers),e.data=ve.call(e,e.transformRequest),-1!==["post","put","patch"].indexOf(e.method)&&e.headers.setContentType("application/x-www-form-urlencoded",!1),Ge(e.adapter||fe.adapter)(e).then((function(t){return Ve(e),t.data=ve.call(e,e.transformResponse,t),t.headers=we.from(t.headers),t}),(function(t){return Ee(t)||(Ve(e),t&&t.response&&(t.response.data=ve.call(e,e.transformResponse,t.response),t.response.headers=we.from(t.response.headers))),Promise.reject(t)}))}const Xe={};["object","boolean","number","function","string","symbol"].forEach(((e,t)=>{Xe[e]=function(n){return typeof n===e||"a"+(t<1?"n ":" ")+e}}));const Ye={};Xe.transitional=function(e,t,n){function r(e,t){return"[Axios v1.7.2] Transitional option '"+e+"'"+t+(n?". "+n:"")}return(n,o,s)=>{if(!1===e)throw new I(r(o," has been removed"+(t?" in "+t:"")),I.ERR_DEPRECATED);return t&&!Ye[o]&&(Ye[o]=!0,console.warn(r(o," has been deprecated since v"+t+" and will be removed in the near future"))),!e||e(n,o,s)}};var Qe={assertOptions:function(e,t,n){if("object"!=typeof e)throw new I("options must be an object",I.ERR_BAD_OPTION_VALUE);const r=Object.keys(e);let o=r.length;for(;o-- >0;){const s=r[o],a=t[s];if(a){const t=e[s],n=void 0===t||a(t,s,e);if(!0!==n)throw new I("option "+s+" must be "+n,I.ERR_BAD_OPTION_VALUE)}else if(!0!==n)throw new I("Unknown option "+s,I.ERR_BAD_OPTION)}},validators:Xe};const Ze=Qe.validators;class et{constructor(e){this.defaults=e,this.interceptors={request:new te,response:new te}}async request(e,t){try{return await this._request(e,t)}catch(e){if(e instanceof Error){let t;Error.captureStackTrace?Error.captureStackTrace(t={}):t=new Error;const n=t.stack?t.stack.replace(/^.+\n/,""):"";try{e.stack?n&&!String(e.stack).endsWith(n.replace(/^.+\n.+\n/,""))&&(e.stack+="\n"+n):e.stack=n}catch(e){}}throw e}}_request(e,t){"string"==typeof e?(t=t||{}).url=e:t=e||{},t=Ae(this.defaults,t);const{transitional:n,paramsSerializer:r,headers:o}=t;void 0!==n&&Qe.assertOptions(n,{silentJSONParsing:Ze.transitional(Ze.boolean),forcedJSONParsing:Ze.transitional(Ze.boolean),clarifyTimeoutError:Ze.transitional(Ze.boolean)},!1),null!=r&&(z.isFunction(r)?t.paramsSerializer={serialize:r}:Qe.assertOptions(r,{encode:Ze.function,serialize:Ze.function},!0)),t.method=(t.method||this.defaults.method||"get").toLowerCase();let s=o&&z.merge(o.common,o[t.method]);o&&z.forEach(["delete","get","head","post","put","patch","common"],(e=>{delete o[e]})),t.headers=we.concat(s,o);const a=[];let i=!0;this.interceptors.request.forEach((function(e){"function"==typeof e.runWhen&&!1===e.runWhen(t)||(i=i&&e.synchronous,a.unshift(e.fulfilled,e.rejected))}));const c=[];let u;this.interceptors.response.forEach((function(e){c.push(e.fulfilled,e.rejected)}));let l,h=0;if(!i){const e=[$e.bind(this),void 0];for(e.unshift.apply(e,a),e.push.apply(e,c),l=e.length,u=Promise.resolve(t);h{if(!n._listeners)return;let t=n._listeners.length;for(;t-- >0;)n._listeners[t](e);n._listeners=null})),this.promise.then=e=>{let t;const r=new Promise((e=>{n.subscribe(e),t=e})).then(e);return r.cancel=function(){n.unsubscribe(t)},r},e((function(e,r,o){n.reason||(n.reason=new xe(e,r,o),t(n.reason))}))}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){this.reason?e(this.reason):this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;const t=this._listeners.indexOf(e);-1!==t&&this._listeners.splice(t,1)}static source(){let e;return{token:new nt((function(t){e=t})),cancel:e}}}var rt=nt;const ot={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(ot).forEach((([e,t])=>{ot[t]=e}));var st=ot;const at=function e(t){const n=new tt(t),o=r(tt.prototype.request,n);return z.extend(o,tt.prototype,n,{allOwnKeys:!0}),z.extend(o,n,null,{allOwnKeys:!0}),o.create=function(n){return e(Ae(t,n))},o}(fe);at.Axios=tt,at.CanceledError=xe,at.CancelToken=rt,at.isCancel=Ee,at.VERSION="1.7.2",at.toFormData=$,at.AxiosError=I,at.Cancel=at.CanceledError,at.all=function(e){return Promise.all(e)},at.spread=function(e){return function(t){return e.apply(null,t)}},at.isAxiosError=function(e){return z.isObject(e)&&!0===e.isAxiosError},at.mergeConfig=Ae,at.AxiosHeaders=we,at.formToJSON=e=>le(z.isHTMLForm(e)?new FormData(e):e),at.getAdapter=Ge,at.HttpStatusCode=st,at.default=at,e.exports=at}},t={};function n(r){var o=t[r];if(void 0!==o)return o.exports;var s=t[r]={id:r,loaded:!1,exports:{}};return e[r](s,s.exports,n),s.loaded=!0,s.exports}return n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n.hmd=e=>((e=Object.create(e)).children||(e.children=[]),Object.defineProperty(e,"exports",{enumerable:!0,set:()=>{throw new Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+e.id)}}),e),n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n(425)})()));
--------------------------------------------------------------------------------