├── .gitignore
├── .idea
└── vcs.xml
├── LICENSE
├── README.md
├── build.gradle.kts
├── design
└── BUFFER.md
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── kotlin-js-store
└── yarn.lock
├── settings.gradle.kts
└── src
├── commonMain
└── kotlin
│ └── io
│ └── ktor
│ └── io
│ ├── BitOperations.kt
│ ├── Buffer.kt
│ ├── BufferOperations.kt
│ ├── BufferedBytesDestination.kt
│ ├── BufferedBytesSource.kt
│ ├── ByteArrayBuffer.kt
│ ├── ByteArrayBufferPool.kt
│ ├── ByteArrayOperations.kt
│ ├── ByteOperations.kt
│ ├── BytesDestination.kt
│ ├── BytesSource.kt
│ ├── Closeable.kt
│ ├── DefaultPool.kt
│ ├── Errors.kt
│ ├── NoPoolImpl.kt
│ └── Pool.kt
├── commonTest
└── kotlin
│ └── io
│ └── ktor
│ └── io
│ ├── BufferTest.kt
│ ├── BufferedBytesDestinationTest.kt
│ ├── BufferedBytesSourceTest.kt
│ ├── ByteArrayBufferTest.kt
│ ├── TestBytesSource.kt
│ └── utils
│ ├── TestBytesDestination.kt
│ └── testSuspend.kt
├── jsMain
└── kotlin
│ └── io
│ └── ktor
│ └── io
│ ├── CloseableJs.kt
│ ├── DefaultPool.kt
│ └── IOExceptionJs.kt
├── jsTest
└── kotlin
│ └── io
│ └── ktor
│ └── io
│ └── utils
│ └── TestUtilsJs.kt
├── jvmMain
└── kotlin
│ └── io
│ └── ktor
│ └── io
│ ├── CloseableJvm.kt
│ ├── DefaultPool.kt
│ ├── DirectByteBufferPool.kt
│ ├── FileBytesDestination.kt
│ ├── FileBytesSource.kt
│ ├── IOExceptionJvm.kt
│ ├── JvmBuffer.kt
│ └── JvmBufferPool.kt
├── jvmTest
└── kotlin
│ └── io
│ └── ktor
│ └── io
│ ├── FilesTest.kt
│ ├── JvmBufferTest.kt
│ └── utils
│ └── TestUtilsJvm.kt
├── nativeMain
└── kotlin
│ └── io
│ └── ktor
│ └── io
│ ├── Closeable.native.kt
│ ├── DefaultPool.native.kt
│ └── IOException.native.kt
└── nativeTest
└── kotlin
└── io
└── ktor
└── io
└── utils
└── TestUtilsNative.kt
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | .gradle
3 | .gradletasknamecache
4 | .idea/*
5 | !.idea/runConfigurations
6 | !.idea/runConfigurations/*
7 | !.idea/vcs.xml
8 | !.idea/dictionaries
9 | !.idea/dictionaries/*
10 | !.idea/copyright
11 | !.idea/copyright/*
12 | !.idea/codeStyles
13 | !.idea/codeStyles/*
14 | !.idea/icon.png
15 | out
16 | *.iml
17 | .vscode
18 |
19 | *.versionsBackup
20 | *.releaseBackup
21 | release.properties
22 | local.properties
23 | *.swp
24 |
25 | .video
26 | .attach_pid*
27 | apidoc
28 |
29 | bin/
30 | .settings
31 | .project
32 | .classpath
33 | .konan
34 |
35 | .DS_Store
36 |
37 | hs_err_pid*.log
38 |
39 | gradle-user-home
40 |
41 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Ktor IO
2 |
3 | Collection of IO primitives to work with network and files written in Kotlin using kotlinx.coroutines library
4 |
5 | ## Design Process
6 |
7 | Please note, current version of this library is not finished yet. We do not provide any guarantees that it will keep any
8 | backward compatibility. To get a motivation why things are implemented as it is, please see the [design](design)
9 | folder.
10 |
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
3 | */
4 |
5 | import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
6 |
7 | buildscript {
8 | repositories {
9 | mavenLocal()
10 | mavenCentral()
11 | google()
12 | gradlePluginPortal()
13 | maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev")
14 | }
15 |
16 | val kotlin_version: String by extra
17 | val atomicfu_version: String by extra
18 |
19 | dependencies {
20 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
21 | classpath("org.jetbrains.kotlinx:atomicfu-gradle-plugin:$atomicfu_version")
22 | }
23 | }
24 |
25 | plugins {
26 | kotlin("multiplatform") version "1.6.20"
27 | id("org.jetbrains.kotlinx.kover") version "0.5.0"
28 | `maven-publish`
29 | }
30 |
31 | group = "io.ktor"
32 |
33 | repositories {
34 | mavenLocal()
35 | mavenCentral()
36 | maven(url = "https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven")
37 | maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev")
38 | }
39 |
40 | apply(plugin = "kotlin-multiplatform")
41 | apply(plugin = "kotlinx-atomicfu")
42 |
43 | val coroutines_version: String by extra
44 |
45 | kotlin {
46 | jvm {
47 | compilations.all {
48 | kotlinOptions.jvmTarget = "1.8"
49 | }
50 | testRuns["test"].executionTask.configure {
51 | useJUnitPlatform()
52 | }
53 | }
54 | js(IR) {
55 | browser()
56 | nodejs()
57 | }
58 |
59 | val platforms: List = listOf(
60 | mingwX64(),
61 | linuxX64(),
62 | macosX64(),
63 | macosArm64(),
64 | iosX64(),
65 | iosArm64(),
66 | iosArm32(),
67 | iosSimulatorArm64(),
68 | watchosX86(),
69 | watchosX64(),
70 | watchosArm32(),
71 | watchosArm64(),
72 | watchosSimulatorArm64(),
73 | tvosX64(),
74 | tvosArm64(),
75 | tvosSimulatorArm64()
76 | )
77 |
78 | explicitApi()
79 |
80 | sourceSets {
81 | val commonMain by getting {
82 | dependencies {
83 | }
84 | }
85 | val commonTest by getting {
86 | dependencies {
87 | api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version")
88 | implementation(kotlin("test"))
89 | }
90 | }
91 |
92 | val nativeMain by creating
93 | val nativeTest by creating
94 |
95 | nativeMain.dependsOn(commonMain)
96 | nativeTest.dependsOn(commonTest)
97 | nativeTest.dependsOn(nativeMain)
98 |
99 | val platformMain = platforms.map { sourceSets.getByName("${it.name}Main") }
100 | val platformTest = platforms.map { sourceSets.getByName("${it.name}Test") }
101 |
102 | platformMain.forEach {
103 | it.dependsOn(nativeMain)
104 | }
105 |
106 | platformTest.forEach {
107 | it.dependsOn(nativeTest)
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/design/BUFFER.md:
--------------------------------------------------------------------------------
1 | ## Buffer
2 |
3 | The goal of IO library is to provide a common interface for all the different types of inputs and outputs, considering
4 | usability and performance.
5 |
6 | The main purpose of IO is read and write arrays of bytes. There is a `ByteArray` - common Kotlin array of bytes
7 | abstraction, but it usually is not the efficient way to represent array of bytes on the platform(`ByteBuffer` on JVM,
8 | `NSData` on iOS, `CPointer` on Native, `ArrayBuffer` on Js and so on).
9 |
10 | So firstly we need a primitive type to abstract array of bytes.
11 |
12 | The `Buffer` is an abstraction to hold some platform primitive byte storage and give simple access to it.
13 |
14 | `Buffer` can hold a `ByteArray`:
15 |
16 | ```kotlin
17 | val message = Buffer("Hello, World!".encodeToByteArray())
18 | ```
19 |
20 | You can also allocate buffer with `ByteArray` directly:
21 |
22 | ```kotlin
23 | val message = ByteArrayBuffer(size = 1024)
24 | ```
25 |
26 | And has most of the `ByteArray` methods:
27 |
28 | ```kotlin
29 | println("My message size is: ${message.size}")
30 | println("It starts with ${buffer[0]}")
31 | ```
32 |
33 | `Buffer` is also mutable:
34 |
35 | ```kotlin
36 | fun Buffer.fill(value: Byte) {
37 | for (position in buffer.indices) {
38 | buffer[position] = value
39 | }
40 | }
41 |
42 | message.fill(0.toByte())
43 | ```
44 |
45 | ## Where My Data is Located?
46 |
47 | Imagine that you want to read some data from stdin. You don't know how much data to expect, so you will likely allocate
48 | some buffer with big enough size in advance:
49 |
50 | ```kotlin
51 | /** Reads StdIn to a [buffer] and returns read count */
52 | fun readFromStdInTo(buffer: Buffer): Int = TODO()
53 |
54 | val buffer = ByteArrayBuffer(size = 1024)
55 | val readCount = readFromStdInTo(buffer)
56 | ```
57 |
58 | Now you have a problem: you have to pass some position and `readCount` across all usages of this `buffer`.
59 | Moreover, if you want to use this buffer again without consuming all data, you will need to make all API accepting
60 | indexes:
61 |
62 | ```kotlin
63 | /** Reads StdIn to a [buffer] and returns read count */
64 | fun readFromStdInTo(buffer: Buffer, offset: Int): Int = TODO()
65 |
66 | val MESSAGE_HEADER_SIZE = 10
67 | val buffer = ByteArrayBuffer(size = 1024)
68 |
69 | var writeIndex = 0
70 | while (writeIndex < MESSAGE_HEADER_SIZE) {
71 | bytesAvailable += readFromStdInTo(buffer, writeIndex)
72 | }
73 | ```
74 |
75 | Already smells a bit?
76 | Let's implement method that will read data from one buffer and write it to another:
77 |
78 | ```kotlin
79 | fun copyAndLog(
80 | from: Buffer,
81 | fromOffset: Int,
82 | readLength: Int,
83 | to: Buffer,
84 | toWriteOffset: Int
85 | ): Int {
86 | for (index in 0 until readLength) {
87 | val fromIndex = fromOffset + index
88 | val toIndex = toWriteOffset + index
89 |
90 | val byte = from[fromIndex]
91 | println("Copy byte: $byte")
92 |
93 | to[toIndex] = byte
94 | }
95 | }
96 | ```
97 |
98 | Or you can write it like this:
99 |
100 | ```kotlin
101 | fun copyAndLog(
102 | from: Buffer,
103 | fromStartIndex: Int,
104 | fromEndIndex: Int,
105 | to: Buffer,
106 | toStartIndex: Int
107 | ): Int {
108 | for (index in 0 until (fromEndIndex - fromStartIndex)) {
109 | val fromIndex = fromStartIndex + index
110 | val toIndex = toStartIndex + index
111 |
112 | val byte = from[fromIndex]
113 | println("Copy byte: $byte")
114 | to[toIndex] = byte
115 | }
116 | }
117 | ```
118 |
119 | So we have lots of opinionated ways of making a single stuff with indexes, offsets. It looks nasty in combination.
120 |
121 | Let's make it a bit simpler:
122 |
123 | ## Buffer indexes
124 |
125 | The `Buffer` keep track of positions where data is in the `readPosition`, and where you can write it in
126 | the `writePosition`. They are public and mutable:
127 |
128 | ```kotlin
129 | fun copyAndLog(from: Buffer, to: Buffer) {
130 | for (index in from.readPosition until from.writePosition) {
131 | val byte = from[index]
132 | println("Copy byte: $byte")
133 | to[index] = byte
134 | }
135 |
136 | val bytesCount = from.writePosition - from.readPosition
137 | to.writePosition += bytesCount
138 | from.readPosition += bytesCount
139 | }
140 | ```
141 |
142 | It looks similar to `ByteBuffer.position/limit`, but doesn't require developer to track the Buffer state.
143 |
144 | ## How to Connect the Buffer With All My Data Classes?
145 |
146 | Imagine you have a class:
147 |
148 | ```kotlin
149 | data class User(
150 | val id: Long,
151 | val name: String,
152 | val age: Int,
153 | val email: String
154 | )
155 | ```
156 |
157 | To send it over the network you need to convert it to bytes.
158 | Using get and set methods are not convenient: you have to encode each field manually.
159 |
160 | There are some utility methods to help you:
161 |
162 | ```kotlin
163 | fun Buffer.writeUser(user: User) {
164 | with(user) {
165 | writeLong(id)
166 | writeInt(name.length)
167 | writeBytes(name.encodeToByteArray())
168 | writeInt(age)
169 | writeInt(email.length)
170 | writeBytes(email.encodeToByteArray())
171 | }
172 | }
173 | ```
174 |
175 | ```kotlin
176 | fun Buffer.readUser(): User {
177 | val id = readLong()
178 | val nameLength = readInt()
179 | val name = Strign(readBytes(nameLength))
180 | val age = readInt()
181 | val emailLength = readInt()
182 | val email = String(readBytes(emailLength))
183 |
184 | return User(id, name, age, email)
185 | }
186 | ```
187 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | version=1.0.0-SNAPSHOT
2 |
3 | kotlin.code.style=official
4 | kotlin.js.generate.executable.default=false
5 | kotlin.native.binary.memoryModel=experimental
6 | kotlin.incremental.js=true
7 | kotlin.incremental.multiplatform=true
8 | kotlin.native.ignoreIncorrectDependencies=true
9 | kotlin.native.ignoreDisabledTargets=true
10 | kotlin.mpp.stability.nowarn=true
11 | kotlin.mpp.enableCompatibilityMetadataVariant=true
12 | kotlin.mpp.enableCInteropCommonization=true
13 | kotlin.internal.mpp.hierarchicalStructureByDefault=true
14 |
15 | # versions
16 | coroutines_version=1.6.4
17 | atomicfu_version=0.18.3
18 | kotlin_version=1.7.10
19 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ktorio/ktor-io/315c48062a9c050d27a5bc87d2775c875e2c245b/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MSYS* | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM's JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/kotlin-js-store/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@colors/colors@1.5.0":
6 | version "1.5.0"
7 | resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
8 | integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==
9 |
10 | "@discoveryjs/json-ext@^0.5.0":
11 | version "0.5.7"
12 | resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
13 | integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
14 |
15 | "@types/component-emitter@^1.2.10":
16 | version "1.2.11"
17 | resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.11.tgz#50d47d42b347253817a39709fef03ce66a108506"
18 | integrity sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==
19 |
20 | "@types/cookie@^0.4.1":
21 | version "0.4.1"
22 | resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d"
23 | integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==
24 |
25 | "@types/cors@^2.8.12":
26 | version "2.8.12"
27 | resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080"
28 | integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==
29 |
30 | "@types/eslint-scope@^3.7.3":
31 | version "3.7.4"
32 | resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16"
33 | integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==
34 | dependencies:
35 | "@types/eslint" "*"
36 | "@types/estree" "*"
37 |
38 | "@types/eslint@*":
39 | version "8.4.1"
40 | resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.1.tgz#c48251553e8759db9e656de3efc846954ac32304"
41 | integrity sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA==
42 | dependencies:
43 | "@types/estree" "*"
44 | "@types/json-schema" "*"
45 |
46 | "@types/estree@*", "@types/estree@^0.0.51":
47 | version "0.0.51"
48 | resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40"
49 | integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==
50 |
51 | "@types/json-schema@*", "@types/json-schema@^7.0.8":
52 | version "7.0.11"
53 | resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3"
54 | integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==
55 |
56 | "@types/node@*", "@types/node@>=10.0.0":
57 | version "17.0.23"
58 | resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.23.tgz#3b41a6e643589ac6442bdbd7a4a3ded62f33f7da"
59 | integrity sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==
60 |
61 | "@ungap/promise-all-settled@1.1.2":
62 | version "1.1.2"
63 | resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44"
64 | integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==
65 |
66 | "@webassemblyjs/ast@1.11.1":
67 | version "1.11.1"
68 | resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7"
69 | integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==
70 | dependencies:
71 | "@webassemblyjs/helper-numbers" "1.11.1"
72 | "@webassemblyjs/helper-wasm-bytecode" "1.11.1"
73 |
74 | "@webassemblyjs/floating-point-hex-parser@1.11.1":
75 | version "1.11.1"
76 | resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f"
77 | integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==
78 |
79 | "@webassemblyjs/helper-api-error@1.11.1":
80 | version "1.11.1"
81 | resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16"
82 | integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==
83 |
84 | "@webassemblyjs/helper-buffer@1.11.1":
85 | version "1.11.1"
86 | resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5"
87 | integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==
88 |
89 | "@webassemblyjs/helper-numbers@1.11.1":
90 | version "1.11.1"
91 | resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae"
92 | integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==
93 | dependencies:
94 | "@webassemblyjs/floating-point-hex-parser" "1.11.1"
95 | "@webassemblyjs/helper-api-error" "1.11.1"
96 | "@xtuc/long" "4.2.2"
97 |
98 | "@webassemblyjs/helper-wasm-bytecode@1.11.1":
99 | version "1.11.1"
100 | resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1"
101 | integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==
102 |
103 | "@webassemblyjs/helper-wasm-section@1.11.1":
104 | version "1.11.1"
105 | resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a"
106 | integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==
107 | dependencies:
108 | "@webassemblyjs/ast" "1.11.1"
109 | "@webassemblyjs/helper-buffer" "1.11.1"
110 | "@webassemblyjs/helper-wasm-bytecode" "1.11.1"
111 | "@webassemblyjs/wasm-gen" "1.11.1"
112 |
113 | "@webassemblyjs/ieee754@1.11.1":
114 | version "1.11.1"
115 | resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614"
116 | integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==
117 | dependencies:
118 | "@xtuc/ieee754" "^1.2.0"
119 |
120 | "@webassemblyjs/leb128@1.11.1":
121 | version "1.11.1"
122 | resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5"
123 | integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==
124 | dependencies:
125 | "@xtuc/long" "4.2.2"
126 |
127 | "@webassemblyjs/utf8@1.11.1":
128 | version "1.11.1"
129 | resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff"
130 | integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==
131 |
132 | "@webassemblyjs/wasm-edit@1.11.1":
133 | version "1.11.1"
134 | resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6"
135 | integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==
136 | dependencies:
137 | "@webassemblyjs/ast" "1.11.1"
138 | "@webassemblyjs/helper-buffer" "1.11.1"
139 | "@webassemblyjs/helper-wasm-bytecode" "1.11.1"
140 | "@webassemblyjs/helper-wasm-section" "1.11.1"
141 | "@webassemblyjs/wasm-gen" "1.11.1"
142 | "@webassemblyjs/wasm-opt" "1.11.1"
143 | "@webassemblyjs/wasm-parser" "1.11.1"
144 | "@webassemblyjs/wast-printer" "1.11.1"
145 |
146 | "@webassemblyjs/wasm-gen@1.11.1":
147 | version "1.11.1"
148 | resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76"
149 | integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==
150 | dependencies:
151 | "@webassemblyjs/ast" "1.11.1"
152 | "@webassemblyjs/helper-wasm-bytecode" "1.11.1"
153 | "@webassemblyjs/ieee754" "1.11.1"
154 | "@webassemblyjs/leb128" "1.11.1"
155 | "@webassemblyjs/utf8" "1.11.1"
156 |
157 | "@webassemblyjs/wasm-opt@1.11.1":
158 | version "1.11.1"
159 | resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2"
160 | integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==
161 | dependencies:
162 | "@webassemblyjs/ast" "1.11.1"
163 | "@webassemblyjs/helper-buffer" "1.11.1"
164 | "@webassemblyjs/wasm-gen" "1.11.1"
165 | "@webassemblyjs/wasm-parser" "1.11.1"
166 |
167 | "@webassemblyjs/wasm-parser@1.11.1":
168 | version "1.11.1"
169 | resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199"
170 | integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==
171 | dependencies:
172 | "@webassemblyjs/ast" "1.11.1"
173 | "@webassemblyjs/helper-api-error" "1.11.1"
174 | "@webassemblyjs/helper-wasm-bytecode" "1.11.1"
175 | "@webassemblyjs/ieee754" "1.11.1"
176 | "@webassemblyjs/leb128" "1.11.1"
177 | "@webassemblyjs/utf8" "1.11.1"
178 |
179 | "@webassemblyjs/wast-printer@1.11.1":
180 | version "1.11.1"
181 | resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0"
182 | integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==
183 | dependencies:
184 | "@webassemblyjs/ast" "1.11.1"
185 | "@xtuc/long" "4.2.2"
186 |
187 | "@webpack-cli/configtest@^1.2.0":
188 | version "1.2.0"
189 | resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.2.0.tgz#7b20ce1c12533912c3b217ea68262365fa29a6f5"
190 | integrity sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==
191 |
192 | "@webpack-cli/info@^1.5.0":
193 | version "1.5.0"
194 | resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.5.0.tgz#6c78c13c5874852d6e2dd17f08a41f3fe4c261b1"
195 | integrity sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==
196 | dependencies:
197 | envinfo "^7.7.3"
198 |
199 | "@webpack-cli/serve@^1.7.0":
200 | version "1.7.0"
201 | resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.7.0.tgz#e1993689ac42d2b16e9194376cfb6753f6254db1"
202 | integrity sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==
203 |
204 | "@xtuc/ieee754@^1.2.0":
205 | version "1.2.0"
206 | resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
207 | integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==
208 |
209 | "@xtuc/long@4.2.2":
210 | version "4.2.2"
211 | resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
212 | integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
213 |
214 | abab@^2.0.6:
215 | version "2.0.6"
216 | resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291"
217 | integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==
218 |
219 | accepts@~1.3.4:
220 | version "1.3.8"
221 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
222 | integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==
223 | dependencies:
224 | mime-types "~2.1.34"
225 | negotiator "0.6.3"
226 |
227 | acorn-import-assertions@^1.7.6:
228 | version "1.8.0"
229 | resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9"
230 | integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==
231 |
232 | acorn@^8.4.1, acorn@^8.5.0:
233 | version "8.7.0"
234 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf"
235 | integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==
236 |
237 | ajv-keywords@^3.5.2:
238 | version "3.5.2"
239 | resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d"
240 | integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==
241 |
242 | ajv@^6.12.5:
243 | version "6.12.6"
244 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
245 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
246 | dependencies:
247 | fast-deep-equal "^3.1.1"
248 | fast-json-stable-stringify "^2.0.0"
249 | json-schema-traverse "^0.4.1"
250 | uri-js "^4.2.2"
251 |
252 | ansi-colors@4.1.1:
253 | version "4.1.1"
254 | resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
255 | integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
256 |
257 | ansi-regex@^5.0.1:
258 | version "5.0.1"
259 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
260 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
261 |
262 | ansi-styles@^4.0.0, ansi-styles@^4.1.0:
263 | version "4.3.0"
264 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
265 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
266 | dependencies:
267 | color-convert "^2.0.1"
268 |
269 | anymatch@~3.1.2:
270 | version "3.1.2"
271 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
272 | integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==
273 | dependencies:
274 | normalize-path "^3.0.0"
275 | picomatch "^2.0.4"
276 |
277 | argparse@^2.0.1:
278 | version "2.0.1"
279 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
280 | integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
281 |
282 | balanced-match@^1.0.0:
283 | version "1.0.2"
284 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
285 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
286 |
287 | base64id@2.0.0, base64id@~2.0.0:
288 | version "2.0.0"
289 | resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6"
290 | integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==
291 |
292 | binary-extensions@^2.0.0:
293 | version "2.2.0"
294 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
295 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
296 |
297 | body-parser@^1.19.0:
298 | version "1.20.0"
299 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5"
300 | integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==
301 | dependencies:
302 | bytes "3.1.2"
303 | content-type "~1.0.4"
304 | debug "2.6.9"
305 | depd "2.0.0"
306 | destroy "1.2.0"
307 | http-errors "2.0.0"
308 | iconv-lite "0.4.24"
309 | on-finished "2.4.1"
310 | qs "6.10.3"
311 | raw-body "2.5.1"
312 | type-is "~1.6.18"
313 | unpipe "1.0.0"
314 |
315 | brace-expansion@^1.1.7:
316 | version "1.1.11"
317 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
318 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
319 | dependencies:
320 | balanced-match "^1.0.0"
321 | concat-map "0.0.1"
322 |
323 | brace-expansion@^2.0.1:
324 | version "2.0.1"
325 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
326 | integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
327 | dependencies:
328 | balanced-match "^1.0.0"
329 |
330 | braces@^3.0.2, braces@~3.0.2:
331 | version "3.0.2"
332 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
333 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
334 | dependencies:
335 | fill-range "^7.0.1"
336 |
337 | browser-stdout@1.3.1:
338 | version "1.3.1"
339 | resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60"
340 | integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==
341 |
342 | browserslist@^4.14.5:
343 | version "4.20.2"
344 | resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.2.tgz#567b41508757ecd904dab4d1c646c612cd3d4f88"
345 | integrity sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==
346 | dependencies:
347 | caniuse-lite "^1.0.30001317"
348 | electron-to-chromium "^1.4.84"
349 | escalade "^3.1.1"
350 | node-releases "^2.0.2"
351 | picocolors "^1.0.0"
352 |
353 | buffer-from@^1.0.0:
354 | version "1.1.2"
355 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
356 | integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
357 |
358 | bytes@3.1.2:
359 | version "3.1.2"
360 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
361 | integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
362 |
363 | call-bind@^1.0.0:
364 | version "1.0.2"
365 | resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
366 | integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==
367 | dependencies:
368 | function-bind "^1.1.1"
369 | get-intrinsic "^1.0.2"
370 |
371 | camelcase@^6.0.0:
372 | version "6.3.0"
373 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
374 | integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
375 |
376 | caniuse-lite@^1.0.30001317:
377 | version "1.0.30001325"
378 | resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001325.tgz#2b4ad19b77aa36f61f2eaf72e636d7481d55e606"
379 | integrity sha512-sB1bZHjseSjDtijV1Hb7PB2Zd58Kyx+n/9EotvZ4Qcz2K3d0lWB8dB4nb8wN/TsOGFq3UuAm0zQZNQ4SoR7TrQ==
380 |
381 | chalk@^4.1.0:
382 | version "4.1.2"
383 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
384 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
385 | dependencies:
386 | ansi-styles "^4.1.0"
387 | supports-color "^7.1.0"
388 |
389 | chokidar@3.5.3, chokidar@^3.5.1:
390 | version "3.5.3"
391 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
392 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
393 | dependencies:
394 | anymatch "~3.1.2"
395 | braces "~3.0.2"
396 | glob-parent "~5.1.2"
397 | is-binary-path "~2.1.0"
398 | is-glob "~4.0.1"
399 | normalize-path "~3.0.0"
400 | readdirp "~3.6.0"
401 | optionalDependencies:
402 | fsevents "~2.3.2"
403 |
404 | chrome-trace-event@^1.0.2:
405 | version "1.0.3"
406 | resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac"
407 | integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==
408 |
409 | cliui@^7.0.2:
410 | version "7.0.4"
411 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
412 | integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==
413 | dependencies:
414 | string-width "^4.2.0"
415 | strip-ansi "^6.0.0"
416 | wrap-ansi "^7.0.0"
417 |
418 | clone-deep@^4.0.1:
419 | version "4.0.1"
420 | resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387"
421 | integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==
422 | dependencies:
423 | is-plain-object "^2.0.4"
424 | kind-of "^6.0.2"
425 | shallow-clone "^3.0.0"
426 |
427 | color-convert@^2.0.1:
428 | version "2.0.1"
429 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
430 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
431 | dependencies:
432 | color-name "~1.1.4"
433 |
434 | color-name@~1.1.4:
435 | version "1.1.4"
436 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
437 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
438 |
439 | colorette@^2.0.14:
440 | version "2.0.16"
441 | resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da"
442 | integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==
443 |
444 | commander@^2.20.0:
445 | version "2.20.3"
446 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
447 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
448 |
449 | commander@^7.0.0:
450 | version "7.2.0"
451 | resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
452 | integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
453 |
454 | component-emitter@~1.3.0:
455 | version "1.3.0"
456 | resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
457 | integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==
458 |
459 | concat-map@0.0.1:
460 | version "0.0.1"
461 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
462 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
463 |
464 | connect@^3.7.0:
465 | version "3.7.0"
466 | resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8"
467 | integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==
468 | dependencies:
469 | debug "2.6.9"
470 | finalhandler "1.1.2"
471 | parseurl "~1.3.3"
472 | utils-merge "1.0.1"
473 |
474 | content-type@~1.0.4:
475 | version "1.0.4"
476 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
477 | integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
478 |
479 | cookie@~0.4.1:
480 | version "0.4.2"
481 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432"
482 | integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==
483 |
484 | cors@~2.8.5:
485 | version "2.8.5"
486 | resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29"
487 | integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==
488 | dependencies:
489 | object-assign "^4"
490 | vary "^1"
491 |
492 | cross-spawn@^7.0.3:
493 | version "7.0.3"
494 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
495 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
496 | dependencies:
497 | path-key "^3.1.0"
498 | shebang-command "^2.0.0"
499 | which "^2.0.1"
500 |
501 | custom-event@~1.0.0:
502 | version "1.0.1"
503 | resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425"
504 | integrity sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=
505 |
506 | date-format@^4.0.10:
507 | version "4.0.11"
508 | resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.11.tgz#ae0d1e069d7f0687938fd06f98c12f3a6276e526"
509 | integrity sha512-VS20KRyorrbMCQmpdl2hg5KaOUsda1RbnsJg461FfrcyCUg+pkd0b40BSW4niQyTheww4DBXQnS7HwSrKkipLw==
510 |
511 | debug@2.6.9:
512 | version "2.6.9"
513 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
514 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
515 | dependencies:
516 | ms "2.0.0"
517 |
518 | debug@4.3.4, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2:
519 | version "4.3.4"
520 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
521 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
522 | dependencies:
523 | ms "2.1.2"
524 |
525 | decamelize@^4.0.0:
526 | version "4.0.0"
527 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837"
528 | integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==
529 |
530 | depd@2.0.0:
531 | version "2.0.0"
532 | resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
533 | integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
534 |
535 | destroy@1.2.0:
536 | version "1.2.0"
537 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
538 | integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
539 |
540 | di@^0.0.1:
541 | version "0.0.1"
542 | resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c"
543 | integrity sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=
544 |
545 | diff@5.0.0:
546 | version "5.0.0"
547 | resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b"
548 | integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==
549 |
550 | dom-serialize@^2.2.1:
551 | version "2.2.1"
552 | resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b"
553 | integrity sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=
554 | dependencies:
555 | custom-event "~1.0.0"
556 | ent "~2.2.0"
557 | extend "^3.0.0"
558 | void-elements "^2.0.0"
559 |
560 | ee-first@1.1.1:
561 | version "1.1.1"
562 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
563 | integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
564 |
565 | electron-to-chromium@^1.4.84:
566 | version "1.4.105"
567 | resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.105.tgz#30de5e4ba020140b698539b2d366cd9c3a337ec7"
568 | integrity sha512-6w2bmoQBSUgCQjbSjiVv9IS1lXwW2aQABlUJ1vlE8Vci/sVXxUNQrHLQa5N1ioc82Py+a36DlUA5KvrAlHMMeA==
569 |
570 | emoji-regex@^8.0.0:
571 | version "8.0.0"
572 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
573 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
574 |
575 | encodeurl@~1.0.2:
576 | version "1.0.2"
577 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
578 | integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
579 |
580 | engine.io-parser@~5.0.3:
581 | version "5.0.4"
582 | resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.4.tgz#0b13f704fa9271b3ec4f33112410d8f3f41d0fc0"
583 | integrity sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==
584 |
585 | engine.io@~6.2.0:
586 | version "6.2.0"
587 | resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.2.0.tgz#003bec48f6815926f2b1b17873e576acd54f41d0"
588 | integrity sha512-4KzwW3F3bk+KlzSOY57fj/Jx6LyRQ1nbcyIadehl+AnXjKT7gDO0ORdRi/84ixvMKTym6ZKuxvbzN62HDDU1Lg==
589 | dependencies:
590 | "@types/cookie" "^0.4.1"
591 | "@types/cors" "^2.8.12"
592 | "@types/node" ">=10.0.0"
593 | accepts "~1.3.4"
594 | base64id "2.0.0"
595 | cookie "~0.4.1"
596 | cors "~2.8.5"
597 | debug "~4.3.1"
598 | engine.io-parser "~5.0.3"
599 | ws "~8.2.3"
600 |
601 | enhanced-resolve@^5.9.3:
602 | version "5.10.0"
603 | resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6"
604 | integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==
605 | dependencies:
606 | graceful-fs "^4.2.4"
607 | tapable "^2.2.0"
608 |
609 | ent@~2.2.0:
610 | version "2.2.0"
611 | resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d"
612 | integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0=
613 |
614 | envinfo@^7.7.3:
615 | version "7.8.1"
616 | resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475"
617 | integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==
618 |
619 | es-module-lexer@^0.9.0:
620 | version "0.9.3"
621 | resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19"
622 | integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==
623 |
624 | escalade@^3.1.1:
625 | version "3.1.1"
626 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
627 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
628 |
629 | escape-html@~1.0.3:
630 | version "1.0.3"
631 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
632 | integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
633 |
634 | escape-string-regexp@4.0.0:
635 | version "4.0.0"
636 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
637 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
638 |
639 | eslint-scope@5.1.1:
640 | version "5.1.1"
641 | resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
642 | integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
643 | dependencies:
644 | esrecurse "^4.3.0"
645 | estraverse "^4.1.1"
646 |
647 | esrecurse@^4.3.0:
648 | version "4.3.0"
649 | resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
650 | integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
651 | dependencies:
652 | estraverse "^5.2.0"
653 |
654 | estraverse@^4.1.1:
655 | version "4.3.0"
656 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
657 | integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
658 |
659 | estraverse@^5.2.0:
660 | version "5.3.0"
661 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
662 | integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
663 |
664 | eventemitter3@^4.0.0:
665 | version "4.0.7"
666 | resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
667 | integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
668 |
669 | events@^3.2.0:
670 | version "3.3.0"
671 | resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
672 | integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
673 |
674 | extend@^3.0.0:
675 | version "3.0.2"
676 | resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
677 | integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
678 |
679 | fast-deep-equal@^3.1.1:
680 | version "3.1.3"
681 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
682 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
683 |
684 | fast-json-stable-stringify@^2.0.0:
685 | version "2.1.0"
686 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
687 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
688 |
689 | fastest-levenshtein@^1.0.12:
690 | version "1.0.12"
691 | resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2"
692 | integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==
693 |
694 | fill-range@^7.0.1:
695 | version "7.0.1"
696 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
697 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
698 | dependencies:
699 | to-regex-range "^5.0.1"
700 |
701 | finalhandler@1.1.2:
702 | version "1.1.2"
703 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d"
704 | integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==
705 | dependencies:
706 | debug "2.6.9"
707 | encodeurl "~1.0.2"
708 | escape-html "~1.0.3"
709 | on-finished "~2.3.0"
710 | parseurl "~1.3.3"
711 | statuses "~1.5.0"
712 | unpipe "~1.0.0"
713 |
714 | find-up@5.0.0:
715 | version "5.0.0"
716 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
717 | integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==
718 | dependencies:
719 | locate-path "^6.0.0"
720 | path-exists "^4.0.0"
721 |
722 | find-up@^4.0.0:
723 | version "4.1.0"
724 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
725 | integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
726 | dependencies:
727 | locate-path "^5.0.0"
728 | path-exists "^4.0.0"
729 |
730 | flat@^5.0.2:
731 | version "5.0.2"
732 | resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241"
733 | integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==
734 |
735 | flatted@^3.2.5:
736 | version "3.2.5"
737 | resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3"
738 | integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==
739 |
740 | follow-redirects@^1.0.0:
741 | version "1.14.9"
742 | resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7"
743 | integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==
744 |
745 | format-util@1.0.5:
746 | version "1.0.5"
747 | resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271"
748 | integrity sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg==
749 |
750 | fs-extra@^10.1.0:
751 | version "10.1.0"
752 | resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf"
753 | integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==
754 | dependencies:
755 | graceful-fs "^4.2.0"
756 | jsonfile "^6.0.1"
757 | universalify "^2.0.0"
758 |
759 | fs.realpath@^1.0.0:
760 | version "1.0.0"
761 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
762 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
763 |
764 | fsevents@~2.3.2:
765 | version "2.3.2"
766 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
767 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
768 |
769 | function-bind@^1.1.1:
770 | version "1.1.1"
771 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
772 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
773 |
774 | get-caller-file@^2.0.5:
775 | version "2.0.5"
776 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
777 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
778 |
779 | get-intrinsic@^1.0.2:
780 | version "1.1.1"
781 | resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6"
782 | integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==
783 | dependencies:
784 | function-bind "^1.1.1"
785 | has "^1.0.3"
786 | has-symbols "^1.0.1"
787 |
788 | glob-parent@~5.1.2:
789 | version "5.1.2"
790 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
791 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
792 | dependencies:
793 | is-glob "^4.0.1"
794 |
795 | glob-to-regexp@^0.4.1:
796 | version "0.4.1"
797 | resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
798 | integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
799 |
800 | glob@7.2.0, glob@^7.1.3, glob@^7.1.7:
801 | version "7.2.0"
802 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
803 | integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
804 | dependencies:
805 | fs.realpath "^1.0.0"
806 | inflight "^1.0.4"
807 | inherits "2"
808 | minimatch "^3.0.4"
809 | once "^1.3.0"
810 | path-is-absolute "^1.0.0"
811 |
812 | graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
813 | version "4.2.10"
814 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
815 | integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
816 |
817 | has-flag@^4.0.0:
818 | version "4.0.0"
819 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
820 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
821 |
822 | has-symbols@^1.0.1:
823 | version "1.0.3"
824 | resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
825 | integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
826 |
827 | has@^1.0.3:
828 | version "1.0.3"
829 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
830 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
831 | dependencies:
832 | function-bind "^1.1.1"
833 |
834 | he@1.2.0:
835 | version "1.2.0"
836 | resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
837 | integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
838 |
839 | http-errors@2.0.0:
840 | version "2.0.0"
841 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
842 | integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==
843 | dependencies:
844 | depd "2.0.0"
845 | inherits "2.0.4"
846 | setprototypeof "1.2.0"
847 | statuses "2.0.1"
848 | toidentifier "1.0.1"
849 |
850 | http-proxy@^1.18.1:
851 | version "1.18.1"
852 | resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549"
853 | integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==
854 | dependencies:
855 | eventemitter3 "^4.0.0"
856 | follow-redirects "^1.0.0"
857 | requires-port "^1.0.0"
858 |
859 | iconv-lite@0.4.24:
860 | version "0.4.24"
861 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
862 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
863 | dependencies:
864 | safer-buffer ">= 2.1.2 < 3"
865 |
866 | iconv-lite@^0.6.3:
867 | version "0.6.3"
868 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"
869 | integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==
870 | dependencies:
871 | safer-buffer ">= 2.1.2 < 3.0.0"
872 |
873 | import-local@^3.0.2:
874 | version "3.1.0"
875 | resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4"
876 | integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==
877 | dependencies:
878 | pkg-dir "^4.2.0"
879 | resolve-cwd "^3.0.0"
880 |
881 | inflight@^1.0.4:
882 | version "1.0.6"
883 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
884 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
885 | dependencies:
886 | once "^1.3.0"
887 | wrappy "1"
888 |
889 | inherits@2, inherits@2.0.4:
890 | version "2.0.4"
891 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
892 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
893 |
894 | interpret@^2.2.0:
895 | version "2.2.0"
896 | resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9"
897 | integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==
898 |
899 | is-binary-path@~2.1.0:
900 | version "2.1.0"
901 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
902 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
903 | dependencies:
904 | binary-extensions "^2.0.0"
905 |
906 | is-core-module@^2.8.1:
907 | version "2.8.1"
908 | resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211"
909 | integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==
910 | dependencies:
911 | has "^1.0.3"
912 |
913 | is-extglob@^2.1.1:
914 | version "2.1.1"
915 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
916 | integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
917 |
918 | is-fullwidth-code-point@^3.0.0:
919 | version "3.0.0"
920 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
921 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
922 |
923 | is-glob@^4.0.1, is-glob@~4.0.1:
924 | version "4.0.3"
925 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
926 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
927 | dependencies:
928 | is-extglob "^2.1.1"
929 |
930 | is-number@^7.0.0:
931 | version "7.0.0"
932 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
933 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
934 |
935 | is-plain-obj@^2.1.0:
936 | version "2.1.0"
937 | resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287"
938 | integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==
939 |
940 | is-plain-object@^2.0.4:
941 | version "2.0.4"
942 | resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
943 | integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==
944 | dependencies:
945 | isobject "^3.0.1"
946 |
947 | is-unicode-supported@^0.1.0:
948 | version "0.1.0"
949 | resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7"
950 | integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==
951 |
952 | isbinaryfile@^4.0.8:
953 | version "4.0.10"
954 | resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3"
955 | integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==
956 |
957 | isexe@^2.0.0:
958 | version "2.0.0"
959 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
960 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
961 |
962 | isobject@^3.0.1:
963 | version "3.0.1"
964 | resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
965 | integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
966 |
967 | jest-worker@^27.4.5:
968 | version "27.5.1"
969 | resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0"
970 | integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==
971 | dependencies:
972 | "@types/node" "*"
973 | merge-stream "^2.0.0"
974 | supports-color "^8.0.0"
975 |
976 | js-yaml@4.1.0:
977 | version "4.1.0"
978 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
979 | integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
980 | dependencies:
981 | argparse "^2.0.1"
982 |
983 | json-parse-even-better-errors@^2.3.1:
984 | version "2.3.1"
985 | resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
986 | integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
987 |
988 | json-schema-traverse@^0.4.1:
989 | version "0.4.1"
990 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
991 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
992 |
993 | jsonfile@^6.0.1:
994 | version "6.1.0"
995 | resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
996 | integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
997 | dependencies:
998 | universalify "^2.0.0"
999 | optionalDependencies:
1000 | graceful-fs "^4.1.6"
1001 |
1002 | karma-chrome-launcher@3.1.1:
1003 | version "3.1.1"
1004 | resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz#baca9cc071b1562a1db241827257bfe5cab597ea"
1005 | integrity sha512-hsIglcq1vtboGPAN+DGCISCFOxW+ZVnIqhDQcCMqqCp+4dmJ0Qpq5QAjkbA0X2L9Mi6OBkHi2Srrbmm7pUKkzQ==
1006 | dependencies:
1007 | which "^1.2.1"
1008 |
1009 | karma-mocha@2.0.1:
1010 | version "2.0.1"
1011 | resolved "https://registry.yarnpkg.com/karma-mocha/-/karma-mocha-2.0.1.tgz#4b0254a18dfee71bdbe6188d9a6861bf86b0cd7d"
1012 | integrity sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ==
1013 | dependencies:
1014 | minimist "^1.2.3"
1015 |
1016 | karma-sourcemap-loader@0.3.8:
1017 | version "0.3.8"
1018 | resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.8.tgz#d4bae72fb7a8397328a62b75013d2df937bdcf9c"
1019 | integrity sha512-zorxyAakYZuBcHRJE+vbrK2o2JXLFWK8VVjiT/6P+ltLBUGUvqTEkUiQ119MGdOrK7mrmxXHZF1/pfT6GgIZ6g==
1020 | dependencies:
1021 | graceful-fs "^4.1.2"
1022 |
1023 | karma-webpack@5.0.0:
1024 | version "5.0.0"
1025 | resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-5.0.0.tgz#2a2c7b80163fe7ffd1010f83f5507f95ef39f840"
1026 | integrity sha512-+54i/cd3/piZuP3dr54+NcFeKOPnys5QeM1IY+0SPASwrtHsliXUiCL50iW+K9WWA7RvamC4macvvQ86l3KtaA==
1027 | dependencies:
1028 | glob "^7.1.3"
1029 | minimatch "^3.0.4"
1030 | webpack-merge "^4.1.5"
1031 |
1032 | karma@6.4.0:
1033 | version "6.4.0"
1034 | resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.0.tgz#82652dfecdd853ec227b74ed718a997028a99508"
1035 | integrity sha512-s8m7z0IF5g/bS5ONT7wsOavhW4i4aFkzD4u4wgzAQWT4HGUeWI3i21cK2Yz6jndMAeHETp5XuNsRoyGJZXVd4w==
1036 | dependencies:
1037 | "@colors/colors" "1.5.0"
1038 | body-parser "^1.19.0"
1039 | braces "^3.0.2"
1040 | chokidar "^3.5.1"
1041 | connect "^3.7.0"
1042 | di "^0.0.1"
1043 | dom-serialize "^2.2.1"
1044 | glob "^7.1.7"
1045 | graceful-fs "^4.2.6"
1046 | http-proxy "^1.18.1"
1047 | isbinaryfile "^4.0.8"
1048 | lodash "^4.17.21"
1049 | log4js "^6.4.1"
1050 | mime "^2.5.2"
1051 | minimatch "^3.0.4"
1052 | mkdirp "^0.5.5"
1053 | qjobs "^1.2.0"
1054 | range-parser "^1.2.1"
1055 | rimraf "^3.0.2"
1056 | socket.io "^4.4.1"
1057 | source-map "^0.6.1"
1058 | tmp "^0.2.1"
1059 | ua-parser-js "^0.7.30"
1060 | yargs "^16.1.1"
1061 |
1062 | kind-of@^6.0.2:
1063 | version "6.0.3"
1064 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
1065 | integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
1066 |
1067 | loader-runner@^4.2.0:
1068 | version "4.2.0"
1069 | resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384"
1070 | integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==
1071 |
1072 | locate-path@^5.0.0:
1073 | version "5.0.0"
1074 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
1075 | integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
1076 | dependencies:
1077 | p-locate "^4.1.0"
1078 |
1079 | locate-path@^6.0.0:
1080 | version "6.0.0"
1081 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
1082 | integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==
1083 | dependencies:
1084 | p-locate "^5.0.0"
1085 |
1086 | lodash@^4.17.15, lodash@^4.17.21:
1087 | version "4.17.21"
1088 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
1089 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
1090 |
1091 | log-symbols@4.1.0:
1092 | version "4.1.0"
1093 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503"
1094 | integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==
1095 | dependencies:
1096 | chalk "^4.1.0"
1097 | is-unicode-supported "^0.1.0"
1098 |
1099 | log4js@^6.4.1:
1100 | version "6.5.2"
1101 | resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.5.2.tgz#9ae371e5b3cb3a3a209c24686e5547f8670834e5"
1102 | integrity sha512-DXtpNtt+KDOMT7RHUDIur/WsSA3rntlUh9Zg4XCdV42wUuMmbFkl38+LZ92Z5QvQA7mD5kAVkLiBSEH/tvUB8A==
1103 | dependencies:
1104 | date-format "^4.0.10"
1105 | debug "^4.3.4"
1106 | flatted "^3.2.5"
1107 | rfdc "^1.3.0"
1108 | streamroller "^3.1.1"
1109 |
1110 | media-typer@0.3.0:
1111 | version "0.3.0"
1112 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
1113 | integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
1114 |
1115 | merge-stream@^2.0.0:
1116 | version "2.0.0"
1117 | resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
1118 | integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
1119 |
1120 | mime-db@1.52.0:
1121 | version "1.52.0"
1122 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
1123 | integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
1124 |
1125 | mime-types@^2.1.27, mime-types@~2.1.24, mime-types@~2.1.34:
1126 | version "2.1.35"
1127 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
1128 | integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
1129 | dependencies:
1130 | mime-db "1.52.0"
1131 |
1132 | mime@^2.5.2:
1133 | version "2.6.0"
1134 | resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367"
1135 | integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==
1136 |
1137 | minimatch@5.0.1:
1138 | version "5.0.1"
1139 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b"
1140 | integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==
1141 | dependencies:
1142 | brace-expansion "^2.0.1"
1143 |
1144 | minimatch@^3.0.4:
1145 | version "3.1.2"
1146 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
1147 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
1148 | dependencies:
1149 | brace-expansion "^1.1.7"
1150 |
1151 | minimist@^1.2.3, minimist@^1.2.6:
1152 | version "1.2.6"
1153 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
1154 | integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
1155 |
1156 | mkdirp@^0.5.5:
1157 | version "0.5.6"
1158 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6"
1159 | integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==
1160 | dependencies:
1161 | minimist "^1.2.6"
1162 |
1163 | mocha@10.0.0:
1164 | version "10.0.0"
1165 | resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.0.0.tgz#205447d8993ec755335c4b13deba3d3a13c4def9"
1166 | integrity sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==
1167 | dependencies:
1168 | "@ungap/promise-all-settled" "1.1.2"
1169 | ansi-colors "4.1.1"
1170 | browser-stdout "1.3.1"
1171 | chokidar "3.5.3"
1172 | debug "4.3.4"
1173 | diff "5.0.0"
1174 | escape-string-regexp "4.0.0"
1175 | find-up "5.0.0"
1176 | glob "7.2.0"
1177 | he "1.2.0"
1178 | js-yaml "4.1.0"
1179 | log-symbols "4.1.0"
1180 | minimatch "5.0.1"
1181 | ms "2.1.3"
1182 | nanoid "3.3.3"
1183 | serialize-javascript "6.0.0"
1184 | strip-json-comments "3.1.1"
1185 | supports-color "8.1.1"
1186 | workerpool "6.2.1"
1187 | yargs "16.2.0"
1188 | yargs-parser "20.2.4"
1189 | yargs-unparser "2.0.0"
1190 |
1191 | ms@2.0.0:
1192 | version "2.0.0"
1193 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
1194 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
1195 |
1196 | ms@2.1.2:
1197 | version "2.1.2"
1198 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
1199 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
1200 |
1201 | ms@2.1.3:
1202 | version "2.1.3"
1203 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
1204 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
1205 |
1206 | nanoid@3.3.3:
1207 | version "3.3.3"
1208 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25"
1209 | integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==
1210 |
1211 | negotiator@0.6.3:
1212 | version "0.6.3"
1213 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
1214 | integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
1215 |
1216 | neo-async@^2.6.2:
1217 | version "2.6.2"
1218 | resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
1219 | integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
1220 |
1221 | node-releases@^2.0.2:
1222 | version "2.0.2"
1223 | resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01"
1224 | integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==
1225 |
1226 | normalize-path@^3.0.0, normalize-path@~3.0.0:
1227 | version "3.0.0"
1228 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
1229 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
1230 |
1231 | object-assign@^4:
1232 | version "4.1.1"
1233 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
1234 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
1235 |
1236 | object-inspect@^1.9.0:
1237 | version "1.12.0"
1238 | resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0"
1239 | integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==
1240 |
1241 | on-finished@2.4.1:
1242 | version "2.4.1"
1243 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
1244 | integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
1245 | dependencies:
1246 | ee-first "1.1.1"
1247 |
1248 | on-finished@~2.3.0:
1249 | version "2.3.0"
1250 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
1251 | integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=
1252 | dependencies:
1253 | ee-first "1.1.1"
1254 |
1255 | once@^1.3.0:
1256 | version "1.4.0"
1257 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
1258 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
1259 | dependencies:
1260 | wrappy "1"
1261 |
1262 | p-limit@^2.2.0:
1263 | version "2.3.0"
1264 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
1265 | integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
1266 | dependencies:
1267 | p-try "^2.0.0"
1268 |
1269 | p-limit@^3.0.2:
1270 | version "3.1.0"
1271 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
1272 | integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
1273 | dependencies:
1274 | yocto-queue "^0.1.0"
1275 |
1276 | p-locate@^4.1.0:
1277 | version "4.1.0"
1278 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07"
1279 | integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
1280 | dependencies:
1281 | p-limit "^2.2.0"
1282 |
1283 | p-locate@^5.0.0:
1284 | version "5.0.0"
1285 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834"
1286 | integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==
1287 | dependencies:
1288 | p-limit "^3.0.2"
1289 |
1290 | p-try@^2.0.0:
1291 | version "2.2.0"
1292 | resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
1293 | integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
1294 |
1295 | parseurl@~1.3.3:
1296 | version "1.3.3"
1297 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
1298 | integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
1299 |
1300 | path-exists@^4.0.0:
1301 | version "4.0.0"
1302 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
1303 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
1304 |
1305 | path-is-absolute@^1.0.0:
1306 | version "1.0.1"
1307 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
1308 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
1309 |
1310 | path-key@^3.1.0:
1311 | version "3.1.1"
1312 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
1313 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
1314 |
1315 | path-parse@^1.0.7:
1316 | version "1.0.7"
1317 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
1318 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
1319 |
1320 | picocolors@^1.0.0:
1321 | version "1.0.0"
1322 | resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
1323 | integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
1324 |
1325 | picomatch@^2.0.4, picomatch@^2.2.1:
1326 | version "2.3.1"
1327 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
1328 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
1329 |
1330 | pkg-dir@^4.2.0:
1331 | version "4.2.0"
1332 | resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
1333 | integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
1334 | dependencies:
1335 | find-up "^4.0.0"
1336 |
1337 | punycode@^2.1.0:
1338 | version "2.1.1"
1339 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
1340 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
1341 |
1342 | qjobs@^1.2.0:
1343 | version "1.2.0"
1344 | resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071"
1345 | integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==
1346 |
1347 | qs@6.10.3:
1348 | version "6.10.3"
1349 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e"
1350 | integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==
1351 | dependencies:
1352 | side-channel "^1.0.4"
1353 |
1354 | randombytes@^2.1.0:
1355 | version "2.1.0"
1356 | resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
1357 | integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
1358 | dependencies:
1359 | safe-buffer "^5.1.0"
1360 |
1361 | range-parser@^1.2.1:
1362 | version "1.2.1"
1363 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
1364 | integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
1365 |
1366 | raw-body@2.5.1:
1367 | version "2.5.1"
1368 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857"
1369 | integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==
1370 | dependencies:
1371 | bytes "3.1.2"
1372 | http-errors "2.0.0"
1373 | iconv-lite "0.4.24"
1374 | unpipe "1.0.0"
1375 |
1376 | readdirp@~3.6.0:
1377 | version "3.6.0"
1378 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
1379 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
1380 | dependencies:
1381 | picomatch "^2.2.1"
1382 |
1383 | rechoir@^0.7.0:
1384 | version "0.7.1"
1385 | resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686"
1386 | integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==
1387 | dependencies:
1388 | resolve "^1.9.0"
1389 |
1390 | require-directory@^2.1.1:
1391 | version "2.1.1"
1392 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
1393 | integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
1394 |
1395 | requires-port@^1.0.0:
1396 | version "1.0.0"
1397 | resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
1398 | integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
1399 |
1400 | resolve-cwd@^3.0.0:
1401 | version "3.0.0"
1402 | resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d"
1403 | integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==
1404 | dependencies:
1405 | resolve-from "^5.0.0"
1406 |
1407 | resolve-from@^5.0.0:
1408 | version "5.0.0"
1409 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
1410 | integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
1411 |
1412 | resolve@^1.9.0:
1413 | version "1.22.0"
1414 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198"
1415 | integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==
1416 | dependencies:
1417 | is-core-module "^2.8.1"
1418 | path-parse "^1.0.7"
1419 | supports-preserve-symlinks-flag "^1.0.0"
1420 |
1421 | rfdc@^1.3.0:
1422 | version "1.3.0"
1423 | resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b"
1424 | integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==
1425 |
1426 | rimraf@^3.0.0, rimraf@^3.0.2:
1427 | version "3.0.2"
1428 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
1429 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
1430 | dependencies:
1431 | glob "^7.1.3"
1432 |
1433 | safe-buffer@^5.1.0:
1434 | version "5.2.1"
1435 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
1436 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
1437 |
1438 | "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0":
1439 | version "2.1.2"
1440 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
1441 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
1442 |
1443 | schema-utils@^3.1.0, schema-utils@^3.1.1:
1444 | version "3.1.1"
1445 | resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281"
1446 | integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==
1447 | dependencies:
1448 | "@types/json-schema" "^7.0.8"
1449 | ajv "^6.12.5"
1450 | ajv-keywords "^3.5.2"
1451 |
1452 | serialize-javascript@6.0.0, serialize-javascript@^6.0.0:
1453 | version "6.0.0"
1454 | resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8"
1455 | integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==
1456 | dependencies:
1457 | randombytes "^2.1.0"
1458 |
1459 | setprototypeof@1.2.0:
1460 | version "1.2.0"
1461 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
1462 | integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
1463 |
1464 | shallow-clone@^3.0.0:
1465 | version "3.0.1"
1466 | resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3"
1467 | integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==
1468 | dependencies:
1469 | kind-of "^6.0.2"
1470 |
1471 | shebang-command@^2.0.0:
1472 | version "2.0.0"
1473 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
1474 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
1475 | dependencies:
1476 | shebang-regex "^3.0.0"
1477 |
1478 | shebang-regex@^3.0.0:
1479 | version "3.0.0"
1480 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
1481 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
1482 |
1483 | side-channel@^1.0.4:
1484 | version "1.0.4"
1485 | resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
1486 | integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
1487 | dependencies:
1488 | call-bind "^1.0.0"
1489 | get-intrinsic "^1.0.2"
1490 | object-inspect "^1.9.0"
1491 |
1492 | socket.io-adapter@~2.4.0:
1493 | version "2.4.0"
1494 | resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz#b50a4a9ecdd00c34d4c8c808224daa1a786152a6"
1495 | integrity sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==
1496 |
1497 | socket.io-parser@~4.0.4:
1498 | version "4.0.5"
1499 | resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.0.5.tgz#cb404382c32324cc962f27f3a44058cf6e0552df"
1500 | integrity sha512-sNjbT9dX63nqUFIOv95tTVm6elyIU4RvB1m8dOeZt+IgWwcWklFDOdmGcfo3zSiRsnR/3pJkjY5lfoGqEe4Eig==
1501 | dependencies:
1502 | "@types/component-emitter" "^1.2.10"
1503 | component-emitter "~1.3.0"
1504 | debug "~4.3.1"
1505 |
1506 | socket.io@^4.4.1:
1507 | version "4.5.1"
1508 | resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.5.1.tgz#aa7e73f8a6ce20ee3c54b2446d321bbb6b1a9029"
1509 | integrity sha512-0y9pnIso5a9i+lJmsCdtmTTgJFFSvNQKDnPQRz28mGNnxbmqYg2QPtJTLFxhymFZhAIn50eHAKzJeiNaKr+yUQ==
1510 | dependencies:
1511 | accepts "~1.3.4"
1512 | base64id "~2.0.0"
1513 | debug "~4.3.2"
1514 | engine.io "~6.2.0"
1515 | socket.io-adapter "~2.4.0"
1516 | socket.io-parser "~4.0.4"
1517 |
1518 | source-map-js@^1.0.2:
1519 | version "1.0.2"
1520 | resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
1521 | integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
1522 |
1523 | source-map-loader@4.0.0:
1524 | version "4.0.0"
1525 | resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-4.0.0.tgz#bdc6b118bc6c87ee4d8d851f2d4efcc5abdb2ef5"
1526 | integrity sha512-i3KVgM3+QPAHNbGavK+VBq03YoJl24m9JWNbLgsjTj8aJzXG9M61bantBTNBt7CNwY2FYf+RJRYJ3pzalKjIrw==
1527 | dependencies:
1528 | abab "^2.0.6"
1529 | iconv-lite "^0.6.3"
1530 | source-map-js "^1.0.2"
1531 |
1532 | source-map-support@0.5.21, source-map-support@~0.5.20:
1533 | version "0.5.21"
1534 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
1535 | integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
1536 | dependencies:
1537 | buffer-from "^1.0.0"
1538 | source-map "^0.6.0"
1539 |
1540 | source-map@^0.6.0, source-map@^0.6.1:
1541 | version "0.6.1"
1542 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
1543 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
1544 |
1545 | source-map@~0.7.2:
1546 | version "0.7.3"
1547 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
1548 | integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
1549 |
1550 | statuses@2.0.1:
1551 | version "2.0.1"
1552 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
1553 | integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
1554 |
1555 | statuses@~1.5.0:
1556 | version "1.5.0"
1557 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
1558 | integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
1559 |
1560 | streamroller@^3.1.1:
1561 | version "3.1.1"
1562 | resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.1.1.tgz#679aae10a4703acdf2740755307df0a05ad752e6"
1563 | integrity sha512-iPhtd9unZ6zKdWgMeYGfSBuqCngyJy1B/GPi/lTpwGpa3bajuX30GjUVd0/Tn/Xhg0mr4DOSENozz9Y06qyonQ==
1564 | dependencies:
1565 | date-format "^4.0.10"
1566 | debug "^4.3.4"
1567 | fs-extra "^10.1.0"
1568 |
1569 | string-width@^4.1.0, string-width@^4.2.0:
1570 | version "4.2.3"
1571 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
1572 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
1573 | dependencies:
1574 | emoji-regex "^8.0.0"
1575 | is-fullwidth-code-point "^3.0.0"
1576 | strip-ansi "^6.0.1"
1577 |
1578 | strip-ansi@^6.0.0, strip-ansi@^6.0.1:
1579 | version "6.0.1"
1580 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
1581 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
1582 | dependencies:
1583 | ansi-regex "^5.0.1"
1584 |
1585 | strip-json-comments@3.1.1:
1586 | version "3.1.1"
1587 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
1588 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
1589 |
1590 | supports-color@8.1.1, supports-color@^8.0.0:
1591 | version "8.1.1"
1592 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
1593 | integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
1594 | dependencies:
1595 | has-flag "^4.0.0"
1596 |
1597 | supports-color@^7.1.0:
1598 | version "7.2.0"
1599 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
1600 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
1601 | dependencies:
1602 | has-flag "^4.0.0"
1603 |
1604 | supports-preserve-symlinks-flag@^1.0.0:
1605 | version "1.0.0"
1606 | resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
1607 | integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
1608 |
1609 | tapable@^2.1.1, tapable@^2.2.0:
1610 | version "2.2.1"
1611 | resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"
1612 | integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
1613 |
1614 | terser-webpack-plugin@^5.1.3:
1615 | version "5.3.1"
1616 | resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz#0320dcc270ad5372c1e8993fabbd927929773e54"
1617 | integrity sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==
1618 | dependencies:
1619 | jest-worker "^27.4.5"
1620 | schema-utils "^3.1.1"
1621 | serialize-javascript "^6.0.0"
1622 | source-map "^0.6.1"
1623 | terser "^5.7.2"
1624 |
1625 | terser@^5.7.2:
1626 | version "5.12.1"
1627 | resolved "https://registry.yarnpkg.com/terser/-/terser-5.12.1.tgz#4cf2ebed1f5bceef5c83b9f60104ac4a78b49e9c"
1628 | integrity sha512-NXbs+7nisos5E+yXwAD+y7zrcTkMqb0dEJxIGtSKPdCBzopf7ni4odPul2aechpV7EXNvOudYOX2bb5tln1jbQ==
1629 | dependencies:
1630 | acorn "^8.5.0"
1631 | commander "^2.20.0"
1632 | source-map "~0.7.2"
1633 | source-map-support "~0.5.20"
1634 |
1635 | tmp@^0.2.1:
1636 | version "0.2.1"
1637 | resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14"
1638 | integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==
1639 | dependencies:
1640 | rimraf "^3.0.0"
1641 |
1642 | to-regex-range@^5.0.1:
1643 | version "5.0.1"
1644 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
1645 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
1646 | dependencies:
1647 | is-number "^7.0.0"
1648 |
1649 | toidentifier@1.0.1:
1650 | version "1.0.1"
1651 | resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
1652 | integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
1653 |
1654 | type-is@~1.6.18:
1655 | version "1.6.18"
1656 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
1657 | integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
1658 | dependencies:
1659 | media-typer "0.3.0"
1660 | mime-types "~2.1.24"
1661 |
1662 | ua-parser-js@^0.7.30:
1663 | version "0.7.31"
1664 | resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6"
1665 | integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==
1666 |
1667 | universalify@^2.0.0:
1668 | version "2.0.0"
1669 | resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
1670 | integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
1671 |
1672 | unpipe@1.0.0, unpipe@~1.0.0:
1673 | version "1.0.0"
1674 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
1675 | integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=
1676 |
1677 | uri-js@^4.2.2:
1678 | version "4.4.1"
1679 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
1680 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
1681 | dependencies:
1682 | punycode "^2.1.0"
1683 |
1684 | utils-merge@1.0.1:
1685 | version "1.0.1"
1686 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
1687 | integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
1688 |
1689 | vary@^1:
1690 | version "1.1.2"
1691 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
1692 | integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
1693 |
1694 | void-elements@^2.0.0:
1695 | version "2.0.1"
1696 | resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
1697 | integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=
1698 |
1699 | watchpack@^2.3.1:
1700 | version "2.4.0"
1701 | resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d"
1702 | integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==
1703 | dependencies:
1704 | glob-to-regexp "^0.4.1"
1705 | graceful-fs "^4.1.2"
1706 |
1707 | webpack-cli@4.10.0:
1708 | version "4.10.0"
1709 | resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.10.0.tgz#37c1d69c8d85214c5a65e589378f53aec64dab31"
1710 | integrity sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==
1711 | dependencies:
1712 | "@discoveryjs/json-ext" "^0.5.0"
1713 | "@webpack-cli/configtest" "^1.2.0"
1714 | "@webpack-cli/info" "^1.5.0"
1715 | "@webpack-cli/serve" "^1.7.0"
1716 | colorette "^2.0.14"
1717 | commander "^7.0.0"
1718 | cross-spawn "^7.0.3"
1719 | fastest-levenshtein "^1.0.12"
1720 | import-local "^3.0.2"
1721 | interpret "^2.2.0"
1722 | rechoir "^0.7.0"
1723 | webpack-merge "^5.7.3"
1724 |
1725 | webpack-merge@^4.1.5:
1726 | version "4.2.2"
1727 | resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d"
1728 | integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==
1729 | dependencies:
1730 | lodash "^4.17.15"
1731 |
1732 | webpack-merge@^5.7.3:
1733 | version "5.8.0"
1734 | resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61"
1735 | integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==
1736 | dependencies:
1737 | clone-deep "^4.0.1"
1738 | wildcard "^2.0.0"
1739 |
1740 | webpack-sources@^3.2.3:
1741 | version "3.2.3"
1742 | resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"
1743 | integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
1744 |
1745 | webpack@5.73.0:
1746 | version "5.73.0"
1747 | resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.73.0.tgz#bbd17738f8a53ee5760ea2f59dce7f3431d35d38"
1748 | integrity sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA==
1749 | dependencies:
1750 | "@types/eslint-scope" "^3.7.3"
1751 | "@types/estree" "^0.0.51"
1752 | "@webassemblyjs/ast" "1.11.1"
1753 | "@webassemblyjs/wasm-edit" "1.11.1"
1754 | "@webassemblyjs/wasm-parser" "1.11.1"
1755 | acorn "^8.4.1"
1756 | acorn-import-assertions "^1.7.6"
1757 | browserslist "^4.14.5"
1758 | chrome-trace-event "^1.0.2"
1759 | enhanced-resolve "^5.9.3"
1760 | es-module-lexer "^0.9.0"
1761 | eslint-scope "5.1.1"
1762 | events "^3.2.0"
1763 | glob-to-regexp "^0.4.1"
1764 | graceful-fs "^4.2.9"
1765 | json-parse-even-better-errors "^2.3.1"
1766 | loader-runner "^4.2.0"
1767 | mime-types "^2.1.27"
1768 | neo-async "^2.6.2"
1769 | schema-utils "^3.1.0"
1770 | tapable "^2.1.1"
1771 | terser-webpack-plugin "^5.1.3"
1772 | watchpack "^2.3.1"
1773 | webpack-sources "^3.2.3"
1774 |
1775 | which@^1.2.1:
1776 | version "1.3.1"
1777 | resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
1778 | integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
1779 | dependencies:
1780 | isexe "^2.0.0"
1781 |
1782 | which@^2.0.1:
1783 | version "2.0.2"
1784 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
1785 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
1786 | dependencies:
1787 | isexe "^2.0.0"
1788 |
1789 | wildcard@^2.0.0:
1790 | version "2.0.0"
1791 | resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec"
1792 | integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==
1793 |
1794 | workerpool@6.2.1:
1795 | version "6.2.1"
1796 | resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343"
1797 | integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==
1798 |
1799 | wrap-ansi@^7.0.0:
1800 | version "7.0.0"
1801 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
1802 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
1803 | dependencies:
1804 | ansi-styles "^4.0.0"
1805 | string-width "^4.1.0"
1806 | strip-ansi "^6.0.0"
1807 |
1808 | wrappy@1:
1809 | version "1.0.2"
1810 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
1811 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
1812 |
1813 | ws@~8.2.3:
1814 | version "8.2.3"
1815 | resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba"
1816 | integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==
1817 |
1818 | y18n@^5.0.5:
1819 | version "5.0.8"
1820 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
1821 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
1822 |
1823 | yargs-parser@20.2.4:
1824 | version "20.2.4"
1825 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54"
1826 | integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==
1827 |
1828 | yargs-parser@^20.2.2:
1829 | version "20.2.9"
1830 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
1831 | integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
1832 |
1833 | yargs-unparser@2.0.0:
1834 | version "2.0.0"
1835 | resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb"
1836 | integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==
1837 | dependencies:
1838 | camelcase "^6.0.0"
1839 | decamelize "^4.0.0"
1840 | flat "^5.0.2"
1841 | is-plain-obj "^2.1.0"
1842 |
1843 | yargs@16.2.0, yargs@^16.1.1:
1844 | version "16.2.0"
1845 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
1846 | integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
1847 | dependencies:
1848 | cliui "^7.0.2"
1849 | escalade "^3.1.1"
1850 | get-caller-file "^2.0.5"
1851 | require-directory "^2.1.1"
1852 | string-width "^4.2.0"
1853 | y18n "^5.0.5"
1854 | yargs-parser "^20.2.2"
1855 |
1856 | yocto-queue@^0.1.0:
1857 | version "0.1.0"
1858 | resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
1859 | integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
1860 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | rootProject.name = "ktor-io"
2 |
--------------------------------------------------------------------------------
/src/commonMain/kotlin/io/ktor/io/BitOperations.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | public inline val Short.highByte: Byte get() = (toInt() ushr 8).toByte()
4 |
5 | public inline val Short.lowByte: Byte get() = (toInt() and 0xff).toByte()
6 |
7 | public inline val Int.highShort: Short get() = (this ushr 16).toShort()
8 |
9 | public inline val Int.lowShort: Short get() = (this and 0xffff).toShort()
10 |
11 | public inline val Long.highInt: Int get() = (this ushr 32).toInt()
12 |
13 | public inline val Long.lowInt: Int get() = (this and 0xffffffffL).toInt()
14 |
15 | internal fun Short(highByte: Byte, lowByte: Byte): Short =
16 | ((highByte.toInt() shl 8) or (lowByte.toInt() and 0xff)).toShort()
17 |
18 | internal fun Int(highShort: Short, lowShort: Short): Int =
19 | (highShort.toInt() shl 16) or (lowShort.toInt() and 0xffff)
20 |
21 | internal fun Long(highInt: Int, lowInt: Int): Long =
22 | (highInt.toLong() shl 32) or (lowInt.toLong() and 0xffffffffL)
23 |
--------------------------------------------------------------------------------
/src/commonMain/kotlin/io/ktor/io/Buffer.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | import kotlin.math.max
4 | import kotlin.math.min
5 |
6 | /**
7 | * The [Buffer] class represents a mutable sequence of bytes in memory.
8 | *
9 | * The buffer is not thread-safe by default.
10 | */
11 | public interface Buffer : Closeable {
12 | /**
13 | * The number of bytes can be stored in the buffer. Upper bound for write operations.
14 | */
15 | public val capacity: Int
16 |
17 | /**
18 | * The index in buffer for the read operation.
19 | *
20 | * Should be between 0 and [writeIndex]
21 | */
22 | public var readIndex: Int
23 |
24 | /**
25 | * The index in buffer for the write operation.
26 | *
27 | * Should be between the [readIndex] and [capacity].
28 | */
29 | public var writeIndex: Int
30 |
31 | /**
32 | * Reads [Byte] at specific [index].
33 | *
34 | * The operation doesn't modify [readIndex] or [writeIndex].
35 | *
36 | * @throws IndexOutOfBoundsException if [index + 1] is greater [capacity].
37 | */
38 | public fun getByteAt(index: Int): Byte
39 |
40 | /**
41 | * Writes [Byte] at specific [index].
42 | *
43 | * The operation doesn't modify [readIndex] or [writeIndex].
44 | *
45 | * @throws IndexOutOfBoundsException if [index + 1] is greater than [capacity].
46 | */
47 | public fun setByteAt(index: Int, value: Byte)
48 |
49 | /**
50 | * Reads [Byte] from the buffer at [readIndex].
51 | *
52 | * @throws IndexOutOfBoundsException if [availableForRead] < 1.
53 | */
54 | public fun readByte(): Byte {
55 | ensureCanRead(1)
56 | return getByteAt(readIndex++)
57 | }
58 |
59 | /**
60 | * Writes [Byte] to the buffer at [writeIndex].
61 | *
62 | * @throws IndexOutOfBoundsException if [availableForWrite] < 1.
63 | */
64 | public fun writeByte(value: Byte) {
65 | ensureCanWrite(1)
66 | setByteAt(writeIndex++, value)
67 | }
68 |
69 | /**
70 | * Reads [Boolean] at specific [index].
71 | *
72 | * The operation doesn't modify [readIndex] or [writeIndex].
73 | *
74 | * @throws IndexOutOfBoundsException if [index + 1] is greater [capacity].
75 | */
76 | public fun getBooleanAt(index: Int): Boolean = getByteAt(index) != 0.toByte()
77 |
78 | /**
79 | * Writes [Boolean] at specific [index].
80 | *
81 | * The operation doesn't modify [readIndex] or [writeIndex].
82 | *
83 | * @throws IndexOutOfBoundsException if [index + 1] is greater than [capacity].
84 | */
85 | public fun setBooleanAt(index: Int, value: Boolean) {
86 | setByteAt(index, if (value) 1.toByte() else 0.toByte())
87 | }
88 |
89 | /**
90 | * Read boolean from the buffer at [readIndex].
91 | *
92 | * @throws IndexOutOfBoundsException if [availableForRead] < 1.
93 | */
94 | public fun readBoolean(): Boolean = getBooleanAt(readIndex++)
95 |
96 | /**
97 | * Write boolean to the buffer at [writeIndex].
98 | *
99 | * @throws IndexOutOfBoundsException if [availableForWrite] < 1.
100 | */
101 | public fun writeBoolean(value: Boolean) {
102 | ensureCanWrite(1)
103 | setBooleanAt(writeIndex++, value)
104 | }
105 |
106 | /**
107 | * Reads [Short] at specific [index].
108 | *
109 | * The operation doesn't modify [readIndex] or [writeIndex].
110 | *
111 | * @throws IndexOutOfBoundsException if [index + 2] is greater [capacity].
112 | */
113 | public fun getShortAt(index: Int): Short {
114 | ensureCanRead(index, 2)
115 |
116 | val byte1 = getByteAt(index)
117 | val byte2 = getByteAt(index + 1)
118 | return Short(byte1, byte2)
119 | }
120 |
121 | /**
122 | * Writes [Short] at specific [index].
123 | *
124 | * The operation doesn't modify [readIndex] or [writeIndex].
125 | *
126 | * @throws IndexOutOfBoundsException if [index + 2] is greater than [capacity].
127 | */
128 | public fun setShortAt(index: Int, value: Short) {
129 | ensureCanWrite(index, 2)
130 |
131 | setByteAt(index, value.highByte)
132 | setByteAt(index + 1, value.lowByte)
133 | }
134 |
135 | /**
136 | * Writes [Short] to the buffer at [writeIndex].
137 | *
138 | * @throws IndexOutOfBoundsException if [availableForWrite] < 2.
139 | */
140 | public fun writeShort(value: Short) {
141 | ensureCanWrite(2)
142 |
143 | setShortAt(writeIndex, value)
144 | writeIndex += 2
145 | }
146 |
147 | /**
148 | * Reads [Short] from the buffer at [readIndex].
149 | *
150 | * @throws IndexOutOfBoundsException if [availableForRead] < 2.
151 | */
152 | public fun readShort(): Short {
153 | ensureCanRead(2)
154 |
155 | val result = getShortAt(readIndex)
156 | readIndex += 2
157 | return result
158 | }
159 |
160 | /**
161 | * Reads [Int] at specific [index].
162 | *
163 | * The operation doesn't modify [readIndex] or [writeIndex].
164 | *
165 | * @throws IndexOutOfBoundsException if [index + 4] is greater than [capacity].
166 | */
167 | public fun getIntAt(index: Int): Int {
168 | ensureCanRead(index, 4)
169 |
170 | val highShort = getShortAt(index)
171 | val lowShort = getShortAt(index + 2)
172 | return Int(highShort, lowShort)
173 | }
174 |
175 | /**
176 | * Writes [Int] at specific [index].
177 | *
178 | * The operation doesn't modify [readIndex] or [writeIndex].
179 | *
180 | * @throws IndexOutOfBoundsException if [index + 4] is greater than [capacity].
181 | */
182 | public fun setIntAt(index: Int, value: Int) {
183 | ensureCanWrite(index, 4)
184 |
185 | setShortAt(index, value.highShort)
186 | setShortAt(index + 2, value.lowShort)
187 | }
188 |
189 | /**
190 | * Reads [Int] from the buffer at [readIndex].
191 | *
192 | * @throws IndexOutOfBoundsException if [availableForRead] < 4.
193 | */
194 | public fun readInt(): Int {
195 | ensureCanRead(4)
196 |
197 | val result = getIntAt(readIndex)
198 | readIndex += 4
199 | return result
200 | }
201 |
202 | /**
203 | * Writes [Int] to the buffer at [writeIndex].
204 | *
205 | * @throws IndexOutOfBoundsException if [availableForWrite] < 4.
206 | */
207 | public fun writeInt(value: Int) {
208 | ensureCanWrite(4)
209 |
210 | setIntAt(writeIndex, value)
211 | writeIndex += 4
212 | }
213 |
214 | /**
215 | * Reads [Long] at specific [index].
216 | *
217 | * The operation doesn't modify [readIndex] or [writeIndex].
218 | *
219 | * @throws IndexOutOfBoundsException if [index + 8] is greater than [capacity].
220 | */
221 | public fun getLongAt(index: Int): Long {
222 | ensureCanRead(index, 8)
223 |
224 | val highInt = getIntAt(index)
225 | val lowInt = getIntAt(index + 4)
226 | return Long(highInt, lowInt)
227 | }
228 |
229 | /**
230 | * Writes [Long] at specific [index].
231 | *
232 | * The operation doesn't modify [readIndex] or [writeIndex].
233 | *
234 | * @throws IndexOutOfBoundsException if [index + 8] is greater than [capacity] or not enough space available.
235 | */
236 | public fun setLongAt(index: Int, value: Long) {
237 | ensureCanWrite(index, 8)
238 |
239 | setIntAt(index, value.highInt)
240 | setIntAt(index + 4, value.lowInt)
241 | }
242 |
243 | /**
244 | * Reads [Long] from the buffer at [readIndex].
245 | *
246 | * @throws IndexOutOfBoundsException if [availableForRead] < 8.
247 | */
248 | public fun readLong(): Long {
249 | ensureCanRead(8)
250 |
251 | val result = getLongAt(readIndex)
252 | readIndex += 8
253 | return result
254 | }
255 |
256 | /**
257 | * Writes [Long] to the buffer at [writeIndex].
258 | *
259 | * @throws IndexOutOfBoundsException if [availableForWrite] < 8.
260 | */
261 | public fun writeLong(value: Long) {
262 | ensureCanWrite(8)
263 |
264 | setLongAt(writeIndex, value)
265 | writeIndex += 8
266 | }
267 |
268 | /**
269 | * Writes as many bytes as possible from the [value] at specific [index].
270 | *
271 | * The [value.readIndex] increased by amount of copied bytes.
272 | *
273 | * @return Number of written bytes: `min(availableForWrite, buffer.availableForRead)`
274 | */
275 | public fun copyFromBufferAt(index: Int, value: Buffer): Int {
276 | val count = min(capacity - index, value.availableForRead)
277 | for (currentIndex in 0 until count) {
278 | setByteAt(index + currentIndex, value.getByteAt(value.readIndex++))
279 | }
280 |
281 | return max(count, 0)
282 | }
283 |
284 | /**
285 | * Write [value] to the current buffer. The implementation depends on the actual buffer implementation.
286 | */
287 | public fun copyFromBuffer(value: Buffer): Int {
288 | val count = copyFromBufferAt(writeIndex, value)
289 | writeIndex += count
290 | return count
291 | }
292 |
293 | /**
294 | * Copy as much as possible bytes from the current buffer to the [destination] between [startIndex] and [endIndex].
295 | *
296 | * This operation increase [readIndex] by the number of copied bytes.
297 | *
298 | * @return Number of copied bytes: `min(availableForRead, endPosition - startPosition)`
299 | */
300 | public fun copyToByteArrayAt(
301 | index: Int,
302 | destination: ByteArray,
303 | startIndex: Int = 0,
304 | endIndex: Int = destination.size
305 | ): Int {
306 | val count = min(endIndex - startIndex, capacity - index)
307 | for (offset in 0 until count) {
308 | destination[startIndex + offset] = getByteAt(index + offset)
309 | }
310 |
311 | return max(count, 0)
312 | }
313 |
314 | /**
315 | * Copy as much as possible bytes from the current buffer to the [destination] between [startIndex] and [endIndex].
316 | *
317 | * This operation increase [readIndex] by the number of copied bytes.
318 | *
319 | * @return Number of copied bytes: `min(availableForRead, endPosition - startPosition)`
320 | */
321 | public fun copyToByteArray(
322 | destination: ByteArray,
323 | startIndex: Int = 0,
324 | endIndex: Int = destination.size
325 | ): Int {
326 | val count = min(endIndex - startIndex, availableForRead)
327 | if (count < 0) return 0
328 |
329 | val result = copyToByteArrayAt(readIndex, destination, startIndex, startIndex + count)
330 | readIndex += result
331 | return result
332 | }
333 |
334 | /**
335 | * Copy all bytes from [value] between [startIndex] and [endIndex] to the buffer at specific [index].
336 | *
337 | * The operation doesn't modify [readIndex] or [writeIndex].
338 | *
339 | * @return Number of written bytes: `min(availableForWrite, endPosition - startPosition)`
340 | * @throws IndexOutOfBoundsException if [index] is greater or equal [capacity].
341 | */
342 | public fun copyFromByteArrayAt(
343 | index: Int,
344 | value: ByteArray,
345 | startIndex: Int = 0,
346 | endIndex: Int = value.size
347 | ): Int {
348 | val count = min(endIndex - startIndex, capacity - index)
349 | for (offset in 0 until count) {
350 | setByteAt(index + offset, value[startIndex + offset])
351 | }
352 |
353 | return max(count, 0)
354 | }
355 |
356 | /**
357 | * Copy values from byte array to the buffer at [writeIndex] between [startIndex] and [endIndex].
358 | *
359 | * @ return number of copied bytes = `min(availableForWrite, endIndex - startIndex)`
360 | */
361 | public fun copyFromByteArray(value: ByteArray, startIndex: Int = 0, endIndex: Int = value.size): Int {
362 | val result = copyFromByteArrayAt(writeIndex, value, startIndex, endIndex)
363 | writeIndex += result
364 | return result
365 | }
366 |
367 | /**
368 | * Move all bytes in range [readIndex], [writeIndex] to range [0] and [writeIndex - readIndex] and modifies the
369 | * [readIndex] and [writeIndex] accordingly.
370 | */
371 | public fun compact() {
372 | if (readIndex == 0) return
373 |
374 | if (readIndex == writeIndex) {
375 | readIndex = 0
376 | writeIndex = 0
377 | return
378 | }
379 |
380 | val count = writeIndex - readIndex
381 | for (index in 0 until count) {
382 | setByteAt(index, getByteAt(readIndex + index))
383 | }
384 |
385 | readIndex = 0
386 | writeIndex = count
387 | }
388 |
389 | /**
390 | * Release [Buffer] back to pool if necessary.
391 | */
392 | override fun close() {
393 | }
394 |
395 | public companion object {
396 | /**
397 | * The buffer with zero capacity.
398 | */
399 | public val Empty: Buffer = object : Buffer {
400 | override val capacity: Int
401 | get() = 0
402 |
403 | override var readIndex: Int
404 | get() = 0
405 | set(value) {
406 | require(value == 0) { "Can't modify default empty buffer" }
407 | }
408 |
409 | override var writeIndex: Int
410 | get() = 0
411 | set(value) {
412 | require(value == 0) { "Can't modify default empty buffer" }
413 | }
414 |
415 | override fun getByteAt(index: Int): Byte {
416 | throw IndexOutOfBoundsException("Can't read from empty buffer")
417 | }
418 |
419 | override fun setByteAt(index: Int, value: Byte) {
420 | throw IndexOutOfBoundsException("Can't write to empty buffer")
421 | }
422 | }
423 | }
424 | }
425 |
--------------------------------------------------------------------------------
/src/commonMain/kotlin/io/ktor/io/BufferOperations.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | public val Buffer.isEmpty: Boolean get() = availableForRead == 0
4 | public val Buffer.isNotEmpty: Boolean get() = !isEmpty
5 |
6 | public val Buffer.isFull: Boolean get() = availableForWrite == 0
7 | public val Buffer.isNotFull: Boolean get() = !isFull
8 |
9 | public val Buffer.availableForRead: Int get() = writeIndex - readIndex
10 | public val Buffer.availableForWrite: Int get() = capacity - writeIndex
11 |
12 | internal fun Buffer.reset() {
13 | readIndex = 0
14 | writeIndex = 0
15 | }
16 |
17 | public operator fun Buffer.get(index: Int): Byte = getByteAt(index)
18 |
19 | public operator fun Buffer.set(index: Int, value: Byte) {
20 | setByteAt(index, value)
21 | }
22 |
23 | /**
24 | * Check if the Buffer has [count] bytes to read.
25 | *
26 | * @throws IndexOutOfBoundsException if the [count] is greater [availableForRead].
27 | */
28 | public fun Buffer.ensureCanRead(count: Int) {
29 | if (availableForRead < count) {
30 | throw IndexOutOfBoundsException("Can't read $count bytes. Available: $availableForRead.")
31 | }
32 | }
33 |
34 | internal fun Buffer.ensureCanRead(index: Int, count: Int) {
35 | if (index + count > capacity) {
36 | throw IndexOutOfBoundsException("Can't read $count bytes at index $index. Capacity: $capacity.")
37 | }
38 | }
39 |
40 |
41 | /**
42 | * Check if the Buffer has space to write [count] bytes.
43 | *
44 | * @throws IndexOutOfBoundsException if the [count] is greater [availableForWrite].
45 | */
46 | public fun Buffer.ensureCanWrite(count: Int) {
47 | if (availableForWrite < count) {
48 | throw IndexOutOfBoundsException("Can't write $count bytes. Available space: $availableForWrite.")
49 | }
50 | }
51 |
52 | internal fun Buffer.ensureCanWrite(index: Int, count: Int) {
53 | if (index + count > capacity) {
54 | throw IndexOutOfBoundsException("Can't write $count bytes at index $index. Capacity: $capacity.")
55 | }
56 | }
--------------------------------------------------------------------------------
/src/commonMain/kotlin/io/ktor/io/BufferedBytesDestination.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | public class BufferedBytesDestination(
4 | private val delegate: BytesDestination,
5 | bufferSize: Int = DEFAULT_BUFFER_SIZE
6 | ) : BytesDestination() {
7 |
8 | private val buffer: Buffer
9 |
10 | init {
11 | buffer = if (bufferSize == DEFAULT_BUFFER_SIZE) {
12 | ByteArrayBufferPool.Default.borrow()
13 | } else {
14 | ByteArrayBuffer(bufferSize)
15 | }
16 | }
17 |
18 | override val closedCause: Throwable?
19 | get() = delegate.closedCause
20 |
21 | override fun canWrite(): Boolean = delegate.canWrite()
22 |
23 | override fun write(buffer: Buffer): Int {
24 | closedCause?.let { throw it }
25 |
26 | return this.buffer.copyFromBuffer(buffer)
27 | }
28 |
29 | override suspend fun flush() {
30 | closedCause?.let { throw it }
31 |
32 | while (buffer.isNotEmpty) {
33 | delegate.write(buffer)
34 | delegate.awaitFreeSpace()
35 | }
36 |
37 | buffer.reset()
38 | delegate.flush()
39 | }
40 |
41 | override suspend fun awaitFreeSpace() {
42 | closedCause?.let { throw it }
43 |
44 | while (buffer.isFull) {
45 | delegate.awaitFreeSpace()
46 | delegate.write(buffer)
47 | buffer.compact()
48 | }
49 | }
50 |
51 | override fun close(cause: Throwable?) {
52 | buffer.close()
53 | delegate.close(cause)
54 | }
55 |
56 | override fun close() {
57 | delegate.close()
58 | }
59 |
60 | public suspend fun writeByte(value: Byte) {
61 | closedCause?.let { throw it }
62 |
63 | if (buffer.isNotFull) {
64 | buffer.writeByte(value)
65 | } else {
66 | awaitFreeSpace()
67 | buffer.writeByte(value)
68 | }
69 |
70 | flushIfFull()
71 | }
72 |
73 | public suspend fun writeShort(value: Short) {
74 | closedCause?.let { throw it }
75 |
76 | if (buffer.availableForWrite >= 2) {
77 | buffer.writeShort(value)
78 | } else {
79 | writeByte(value.highByte)
80 | writeByte(value.lowByte)
81 | }
82 |
83 | flushIfFull()
84 | }
85 |
86 | public suspend fun writeInt(value: Int) {
87 | closedCause?.let { throw it }
88 |
89 | if (buffer.availableForWrite >= 4) {
90 | buffer.writeInt(value)
91 | } else {
92 | writeShort(value.highShort)
93 | writeShort(value.lowShort)
94 | }
95 |
96 | flushIfFull()
97 | }
98 |
99 | public suspend fun writeLong(value: Long) {
100 | closedCause?.let { throw it }
101 |
102 | if (buffer.availableForWrite >= 8) {
103 | buffer.writeLong(value)
104 | } else {
105 | writeInt(value.highInt)
106 | writeInt(value.lowInt)
107 | }
108 |
109 | flushIfFull()
110 | }
111 |
112 | private suspend fun flushIfFull() {
113 | if (buffer.isFull) {
114 | flush()
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/src/commonMain/kotlin/io/ktor/io/BufferedBytesSource.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | public class BufferedBytesSource(
4 | private val delegate: BytesSource
5 | ) : BytesSource() {
6 |
7 | private var buffer: Buffer
8 |
9 | init {
10 | buffer = delegate.read()
11 | }
12 |
13 | override val closedCause: Throwable?
14 | get() = delegate.closedCause
15 |
16 | override fun canRead(): Boolean {
17 | return delegate.canRead() || buffer.isNotEmpty
18 | }
19 |
20 | override fun read(): Buffer {
21 | closedCause?.let { throw it }
22 |
23 | if (buffer.isNotEmpty) {
24 | return buffer
25 | }
26 |
27 | buffer.close()
28 | buffer = delegate.read()
29 | return buffer
30 | }
31 |
32 | override suspend fun awaitContent() {
33 | closedCause?.let { throw it }
34 |
35 | if (buffer.isNotEmpty) return
36 | delegate.awaitContent()
37 | }
38 |
39 | override fun cancel(cause: Throwable) {
40 | delegate.cancel(cause)
41 | }
42 |
43 | public suspend fun readByte(): Byte {
44 | closedCause?.let { throw it }
45 |
46 | while (buffer.isEmpty) {
47 | awaitContent()
48 | read()
49 | }
50 | return buffer.readByte()
51 | }
52 |
53 | public suspend fun readShort(): Short {
54 | closedCause?.let { throw it }
55 |
56 | if (buffer.availableForRead >= 2) {
57 | return buffer.readShort()
58 | }
59 | return Short(readByte(), readByte())
60 | }
61 |
62 | public suspend fun readInt(): Int {
63 | closedCause?.let { throw it }
64 |
65 | if (buffer.availableForRead >= 4) {
66 | return buffer.readInt()
67 | }
68 | return Int(readShort(), readShort())
69 | }
70 |
71 | public suspend fun readLong(): Long {
72 | closedCause?.let { throw it }
73 |
74 | if (buffer.availableForRead >= 8) {
75 | return buffer.readLong()
76 | }
77 | return Long(readInt(), readInt())
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/commonMain/kotlin/io/ktor/io/ByteArrayBuffer.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | import kotlin.math.min
4 |
5 | public const val DEFAULT_POOL_CAPACITY: Int = 2000
6 | public const val DEFAULT_BUFFER_SIZE: Int = 1024 * 16
7 |
8 | public class ByteArrayBuffer(
9 | array: ByteArray,
10 | readIndex: Int = 0,
11 | writeIndex: Int = array.size,
12 | /**
13 | * The pool used for allocation of the [array].
14 | */
15 | public val pool: ObjectPool = ByteArrayPool.Empty
16 | ) : Buffer {
17 |
18 | /**
19 | * Creates buffer of fixed [capacity].
20 | */
21 | public constructor(capacity: Int) : this(ByteArray(capacity), readIndex = 0, writeIndex = 0)
22 |
23 | public constructor(pool: ObjectPool = ByteArrayPool.Empty) : this(
24 | pool.borrow(),
25 | readIndex = 0,
26 | writeIndex = 0,
27 | pool = pool
28 | )
29 |
30 | /**
31 | * Provides access to underlying byte array.
32 | *
33 | * Please note, all changes of the array will be reflected in the buffer.
34 | */
35 | @Suppress("CanBePrimaryConstructorProperty")
36 | public var array: ByteArray = array
37 | private set
38 |
39 | override val capacity: Int
40 | get() = array.size
41 |
42 | override var readIndex: Int = readIndex
43 | set(value) {
44 | if (value < 0 || value > writeIndex) {
45 | throw IndexOutOfBoundsException("readIndex($value) must be >= 0 and < writeIndex: $writeIndex")
46 | }
47 | field = value
48 | }
49 |
50 | override var writeIndex: Int = writeIndex
51 | set(value) {
52 | if (value < 0 || value > capacity) {
53 | throw IndexOutOfBoundsException("Write index $value is out of bounds: $capacity")
54 | }
55 |
56 | field = value
57 | }
58 |
59 | override fun getByteAt(index: Int): Byte {
60 | ensureCanRead(index, 1, writeIndex)
61 | return array[index]
62 | }
63 |
64 | override fun setByteAt(index: Int, value: Byte) {
65 | ensureCanWrite(index, 1, capacity)
66 | array[index] = value
67 | }
68 |
69 | override fun copyFromBufferAt(index: Int, value: Buffer): Int {
70 | return value.copyToByteArray(array, index, capacity)
71 | }
72 |
73 | override fun copyToByteArrayAt(index: Int, destination: ByteArray, startIndex: Int, endIndex: Int): Int {
74 | require(startIndex >= 0) { "startIndex($startIndex) must be >= 0" }
75 | require(endIndex <= destination.size) { "endIndex($endIndex) must be <= destination.size(${destination.size})" }
76 | require(startIndex <= endIndex) { "startIndex($startIndex) must be <= endIndex($endIndex)" }
77 | require(index < capacity) { "index($index) must be < capacity($capacity)" }
78 |
79 | val count = min(capacity - index, endIndex - startIndex)
80 |
81 | array.copyInto(destination, startIndex, index, index + count)
82 | readIndex += count
83 | return count
84 | }
85 |
86 | override fun copyToByteArray(destination: ByteArray, startIndex: Int, endIndex: Int): Int {
87 | require(startIndex >= 0) { "startIndex($startIndex) must be >= 0" }
88 | require(endIndex <= destination.size) { "endIndex($endIndex) must be <= destination.size(${destination.size})" }
89 | require(startIndex <= endIndex) { "startIndex($startIndex) must be <= endIndex($endIndex)" }
90 |
91 | val count = min(availableForRead, endIndex - startIndex)
92 |
93 | array.copyInto(destination, startIndex, readIndex, readIndex + count)
94 | readIndex += count
95 | return count
96 | }
97 |
98 | override fun copyFromByteArrayAt(index: Int, value: ByteArray, startIndex: Int, endIndex: Int): Int {
99 | require(startIndex >= 0) { "startPosition($startIndex) must be >= 0" }
100 | require(endIndex <= value.size) { "endPosition($endIndex) must be <= value.size(${value.size})" }
101 | require(startIndex <= endIndex) { "startPosition($startIndex) must be <= endPosition($endIndex)" }
102 |
103 | val count = min(capacity - index, endIndex - startIndex)
104 | value.copyInto(array, index, startIndex, startIndex + count)
105 | return count
106 | }
107 |
108 | /**
109 | * Returns this buffer back to the pool.
110 | */
111 | override fun close() {
112 | pool.recycle(array)
113 | }
114 |
115 | override fun compact() {
116 | if (readIndex == 0) return
117 | array.copyInto(array, 0, readIndex, writeIndex)
118 | writeIndex = availableForRead
119 | readIndex = 0
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/commonMain/kotlin/io/ktor/io/ByteArrayBufferPool.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | public class ByteArrayBufferPool(
4 | capacity: Int = DEFAULT_POOL_CAPACITY,
5 | public val arrayPool: ObjectPool = ByteArrayPool.Default,
6 | ) : DefaultPool(capacity) {
7 |
8 | override fun produceInstance(): ByteArrayBuffer = ByteArrayBuffer(arrayPool)
9 |
10 | override fun clearInstance(instance: ByteArrayBuffer): ByteArrayBuffer {
11 | instance.reset()
12 | return instance
13 | }
14 |
15 | public companion object {
16 | public val Default: ObjectPool = ByteArrayBufferPool()
17 |
18 | public val Empty: ObjectPool = ByteArrayBufferPool(
19 | capacity = 0,
20 | arrayPool = ByteArrayPool.Empty
21 | )
22 | }
23 | }
24 |
25 | public class ByteArrayPool(
26 | private val size: Int = DEFAULT_BUFFER_SIZE,
27 | capacity: Int = DEFAULT_POOL_CAPACITY,
28 | ) : DefaultPool(capacity) {
29 |
30 | override fun produceInstance(): ByteArray = ByteArray(size)
31 |
32 | override fun clearInstance(instance: ByteArray): ByteArray {
33 | instance.fill(0)
34 | return instance
35 | }
36 |
37 | public companion object {
38 | public val Default: ObjectPool = ByteArrayPool()
39 |
40 | public val Empty: ObjectPool = ByteArrayPool(capacity = 0)
41 | }
42 | }
--------------------------------------------------------------------------------
/src/commonMain/kotlin/io/ktor/io/ByteArrayOperations.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | /**
4 | * Loads [Short] from the byte array at the specified [index].
5 | *
6 | * @throws IndexOutOfBoundsException if there are not enough bytes in the array.
7 | */
8 | public fun ByteArray.getShortAt(index: Int): Short {
9 | ensureCanRead(index, 2, size)
10 | return Short(this[index], this[index + 1])
11 | }
12 |
13 | /**
14 | * Loads [Int] from the byte array at the specified [index].
15 | *
16 | * @throws IndexOutOfBoundsException if there are not enough bytes in the array.
17 | */
18 | public fun ByteArray.getIntAt(index: Int): Int {
19 | ensureCanRead(index, 4, size)
20 |
21 | return Int(getShortAt(index), getShortAt(index + 2))
22 | }
23 |
24 | /**
25 | * Loads [Long] from the byte array at the specified [index].
26 | *
27 | * @throws IndexOutOfBoundsException if there are not enough bytes in the array.
28 | */
29 | public fun ByteArray.getLongAt(index: Int): Long {
30 | ensureCanRead(index, 8, size)
31 | return Long(getIntAt(index), getIntAt(index + 4))
32 | }
33 |
34 | /**
35 | * Stores [value] to the byte array at the specified [index].
36 | *
37 | * @throws IndexOutOfBoundsException if there are not enough bytes in the array.
38 | */
39 | public fun ByteArray.setShortAt(index: Int, value: Short): ByteArray {
40 | ensureCanWrite(index, 2, size)
41 |
42 | this[index] = value.highByte
43 | this[index + 1] = value.lowByte
44 |
45 | return this
46 | }
47 |
48 | /**
49 | * Stores [value] to the byte array at the specified [index].
50 | *
51 | * @throws IndexOutOfBoundsException if there are not enough bytes in the array.
52 | */
53 | public fun ByteArray.setIntAt(index: Int, value: Int): ByteArray {
54 | ensureCanWrite(index, 4, size)
55 |
56 | setShortAt(index, value.highShort)
57 | setShortAt(index + 2, value.lowShort)
58 |
59 | return this
60 | }
61 |
62 | /**
63 | * Stores [value] to the byte array at the specified [index].
64 | *
65 | * @throws IndexOutOfBoundsException if there are not enough bytes in the array.
66 | */
67 | public fun ByteArray.setLongAt(index: Int, value: Long): ByteArray {
68 | ensureCanWrite(index, 8, size)
69 |
70 | setIntAt(index, value.highInt)
71 | setIntAt(index + 4, value.lowInt)
72 |
73 | return this
74 | }
75 |
76 | internal fun ensureCanRead(index: Int, count: Int, capacity: Int) {
77 | if (index + count > capacity) {
78 | throw IndexOutOfBoundsException("Can't read $count bytes at index $index from array of size $capacity")
79 | }
80 | }
81 |
82 | internal fun ensureCanWrite(index: Int, count: Int, capacity: Int) {
83 | if (index + count > capacity) {
84 | throw IndexOutOfBoundsException("Can't write $count bytes at index $index to array of size $capacity")
85 | }
86 | }
87 |
88 | private fun Byte.asInt(): Int = toInt() and 0xFF
--------------------------------------------------------------------------------
/src/commonMain/kotlin/io/ktor/io/ByteOperations.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | public infix fun Byte.and(other: Byte): Byte = ((toInt() and 0xFF) and (other.toInt() and 0xFF)).toByte()
4 |
5 | public infix fun Byte.or(other: Byte): Byte = ((toInt() and 0xFF) and (other.toInt() and 0xFF)).toByte()
6 |
--------------------------------------------------------------------------------
/src/commonMain/kotlin/io/ktor/io/BytesDestination.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | public abstract class BytesDestination : Closeable {
4 | public abstract val closedCause: Throwable?
5 | public abstract fun canWrite(): Boolean
6 |
7 | public abstract fun write(buffer: Buffer): Int
8 | public abstract suspend fun flush()
9 | public abstract suspend fun awaitFreeSpace()
10 |
11 | public abstract fun close(cause: Throwable? = null)
12 | }
13 |
--------------------------------------------------------------------------------
/src/commonMain/kotlin/io/ktor/io/BytesSource.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | public abstract class BytesSource {
4 | public abstract val closedCause: Throwable?
5 | public abstract fun canRead(): Boolean
6 |
7 | public abstract fun read(): Buffer
8 | public abstract suspend fun awaitContent()
9 |
10 | public abstract fun cancel(cause: Throwable = IOException("FooBar"))
11 | }
12 |
--------------------------------------------------------------------------------
/src/commonMain/kotlin/io/ktor/io/Closeable.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | public expect interface Closeable {
4 | public fun close()
5 | }
6 |
7 | public inline fun C.use(block: (C) -> R): R {
8 | var closed = false
9 |
10 | return try {
11 | block(this)
12 | } catch (first: Throwable) {
13 | try {
14 | closed = true
15 | close()
16 | } catch (second: Throwable) {
17 | first.addSuppressedInternal(second)
18 | }
19 |
20 | throw first
21 | } finally {
22 | if (!closed) {
23 | close()
24 | }
25 | }
26 | }
27 |
28 | @PublishedApi
29 | internal expect fun Throwable.addSuppressedInternal(other: Throwable)
30 |
--------------------------------------------------------------------------------
/src/commonMain/kotlin/io/ktor/io/DefaultPool.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | /**
4 | * Default object pool implementation.
5 | */
6 | public expect abstract class DefaultPool(capacity: Int) : ObjectPool {
7 | /**
8 | * Pool capacity.
9 | */
10 | final override val capacity: Int
11 |
12 | /**
13 | * Creates a new instance of [T]
14 | */
15 | protected abstract fun produceInstance(): T
16 |
17 | /**
18 | * Dispose [instance] and release its resources
19 | */
20 | protected open fun disposeInstance(instance: T)
21 |
22 | /**
23 | * Clear [instance]'s state before reuse: reset pointers, counters and so on
24 | */
25 | protected open fun clearInstance(instance: T): T
26 |
27 | /**
28 | * Validate [instance] of [T]. Could verify that the object has been borrowed from this pool
29 | */
30 | protected open fun validateInstance(instance: T)
31 |
32 | final override fun borrow(): T
33 |
34 | final override fun recycle(instance: T)
35 |
36 | final override fun dispose()
37 | }
38 |
--------------------------------------------------------------------------------
/src/commonMain/kotlin/io/ktor/io/Errors.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | public expect open class IOException(message: String, cause: Throwable?) : Exception {
4 | public constructor(message: String)
5 | }
6 |
7 | public expect open class EOFException(message: String) : IOException
8 |
--------------------------------------------------------------------------------
/src/commonMain/kotlin/io/ktor/io/NoPoolImpl.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | /**
4 | * A pool implementation of zero capacity that always creates new instances
5 | */
6 | public abstract class NoPoolImpl : ObjectPool {
7 | override val capacity: Int
8 | get() = 0
9 |
10 | override fun recycle(instance: T) {
11 | }
12 |
13 | override fun dispose() {
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/commonMain/kotlin/io/ktor/io/Pool.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | public interface ObjectPool : Closeable {
4 | /**
5 | * Pool capacity
6 | */
7 | public val capacity: Int
8 |
9 | /**
10 | * borrow an instance. Pool can recycle an old instance or create a new one
11 | */
12 | public fun borrow(): T
13 |
14 | /**
15 | * Recycle an instance. Should be recycled what was borrowed before otherwise could fail
16 | */
17 | public fun recycle(instance: T)
18 |
19 | /**
20 | * Dispose the whole pool. None of borrowed objects could be used after the pool gets disposed
21 | * otherwise it can result in undefined behaviour
22 | */
23 | public fun dispose()
24 |
25 | /**
26 | * Does pool dispose
27 | */
28 | override fun close() {
29 | dispose()
30 | }
31 | }
32 |
33 | /**
34 | * Borrows and instance of [T] from the pool, invokes [block] with it and finally recycles it
35 | */
36 | public inline fun ObjectPool.useInstance(block: (T) -> R): R {
37 | val instance = borrow()
38 | try {
39 | return block(instance)
40 | } finally {
41 | recycle(instance)
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/commonTest/kotlin/io/ktor/io/BufferTest.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | import kotlin.test.Test
4 | import kotlin.test.assertContentEquals
5 | import kotlin.test.assertEquals
6 | import kotlin.test.assertFailsWith
7 |
8 | abstract class BufferTest {
9 |
10 | abstract fun createBuffer(): Buffer
11 |
12 | @Test
13 | fun testWriteCanReadByte() {
14 | val buffer = createBuffer()
15 | buffer.writeIndex = 0
16 |
17 | buffer.writeByte(99)
18 | buffer.writeByte(-99)
19 |
20 | assertEquals(0, buffer.readIndex)
21 | assertEquals(2, buffer.writeIndex)
22 |
23 | assertEquals(99, buffer.readByte())
24 | assertEquals(-99, buffer.readByte())
25 |
26 | assertEquals(2, buffer.readIndex)
27 | assertEquals(2, buffer.writeIndex)
28 | }
29 |
30 | @Test
31 | fun testWriteCanReadShort() {
32 | val buffer = createBuffer()
33 | buffer.writeIndex = 0
34 |
35 | buffer.writeShort(999)
36 | buffer.writeShort(-999)
37 |
38 | assertEquals(0, buffer.readIndex)
39 | assertEquals(4, buffer.writeIndex)
40 |
41 | assertEquals(999, buffer.readShort())
42 | assertEquals(-999, buffer.readShort())
43 |
44 | assertEquals(4, buffer.readIndex)
45 | assertEquals(4, buffer.writeIndex)
46 | }
47 |
48 | @Test
49 | fun testWriteCanReadInt() {
50 | val buffer = createBuffer()
51 | buffer.writeIndex = 0
52 |
53 | buffer.writeInt(999_999)
54 | buffer.writeInt(-999_999)
55 |
56 | assertEquals(0, buffer.readIndex)
57 | assertEquals(8, buffer.writeIndex)
58 |
59 | assertEquals(999_999, buffer.readInt())
60 | assertEquals(-999_999, buffer.readInt())
61 |
62 | assertEquals(8, buffer.readIndex)
63 | assertEquals(8, buffer.writeIndex)
64 | }
65 |
66 | @Test
67 | fun testWriteCanReadLong() {
68 | val buffer = createBuffer()
69 | buffer.writeIndex = 0
70 |
71 | buffer.writeLong(9_999_999_999_999)
72 | buffer.writeLong(-9_999_999_999_999)
73 |
74 | assertEquals(0, buffer.readIndex)
75 | assertEquals(16, buffer.writeIndex)
76 |
77 | assertEquals(9_999_999_999_999, buffer.readLong())
78 | assertEquals(-9_999_999_999_999, buffer.readLong())
79 |
80 | assertEquals(16, buffer.readIndex)
81 | assertEquals(16, buffer.writeIndex)
82 | }
83 |
84 | @Test
85 | fun testWriteCanReadArray() {
86 | val buffer = createBuffer()
87 | buffer.writeIndex = 0
88 |
89 | val array = ByteArray(123) { it.toByte() }
90 | buffer.copyFromByteArray(array)
91 |
92 | assertEquals(0, buffer.readIndex)
93 | assertEquals(123, buffer.writeIndex)
94 |
95 | val newArray = ByteArray(123).also { buffer.copyToByteArray(it) }
96 | assertContentEquals(array, newArray)
97 |
98 | assertEquals(123, buffer.readIndex)
99 | assertEquals(123, buffer.writeIndex)
100 | }
101 |
102 | @Test
103 | fun testBoundsByte() {
104 | val buffer = createBuffer()
105 |
106 | assertFailsWith { buffer.readByte() }
107 | buffer.writeIndex = buffer.capacity - 1
108 | buffer.readIndex = buffer.writeIndex
109 | buffer.writeByte(1)
110 | assertEquals(1, buffer.readByte())
111 | assertFailsWith { buffer.writeByte(2) }
112 | }
113 |
114 | @Test
115 | fun testBoundsShort() {
116 | val buffer = createBuffer()
117 |
118 | assertFailsWith { buffer.readShort() }
119 | buffer.writeIndex = buffer.capacity - 2
120 | buffer.readIndex = buffer.writeIndex
121 | buffer.writeShort(1)
122 | assertEquals(1, buffer.readShort())
123 |
124 | buffer.writeIndex = buffer.capacity - 1
125 | assertFailsWith { buffer.writeShort(2) }
126 | }
127 |
128 | @Test
129 | fun testBoundsInt() {
130 | val buffer = createBuffer()
131 |
132 | assertFailsWith { buffer.readInt() }
133 | buffer.writeIndex = buffer.capacity - 4
134 | buffer.readIndex = buffer.writeIndex
135 | buffer.writeInt(1)
136 | assertEquals(1, buffer.readInt())
137 | buffer.writeIndex = buffer.capacity - 3
138 | assertFailsWith { buffer.writeInt(2) }
139 | }
140 |
141 | @Test
142 | fun testBoundsLong() {
143 | val buffer = createBuffer()
144 |
145 | assertFailsWith { buffer.readLong() }
146 | buffer.writeIndex = buffer.capacity - 8
147 | buffer.readIndex = buffer.writeIndex
148 | buffer.writeLong(1)
149 | assertEquals(1, buffer.readLong())
150 | buffer.writeIndex = buffer.capacity - 7
151 | assertFailsWith { buffer.writeLong(2) }
152 | }
153 |
154 | @Test
155 | fun testBoundsArray() {
156 | val buffer = createBuffer()
157 |
158 | val array = ByteArray(123)
159 | var count = buffer.copyToByteArray(array)
160 | assertEquals(0, count)
161 |
162 | buffer.writeIndex = buffer.capacity - 123
163 | buffer.readIndex = buffer.writeIndex
164 | buffer.copyFromByteArray(array)
165 |
166 | val newArray = ByteArray(123)
167 | assertContentEquals(array, newArray)
168 | buffer.writeIndex = buffer.capacity - 122
169 | count = buffer.copyFromByteArray(array)
170 | assertEquals(122, count)
171 | }
172 |
173 |
174 | @Test
175 | fun testWriteCanRead() {
176 | val buffer = createBuffer()
177 | buffer.writeIndex = 0
178 |
179 | buffer.writeByte(99)
180 | buffer.writeShort(999)
181 | buffer.writeInt(999_999)
182 | buffer.writeLong(9_999_999_999_999)
183 |
184 | val array = ByteArray(123) { it.toByte() }
185 | buffer.copyFromByteArray(array)
186 |
187 | assertEquals(0, buffer.readIndex)
188 | assertEquals(138, buffer.writeIndex)
189 |
190 | assertEquals(99, buffer.readByte())
191 | assertEquals(999, buffer.readShort())
192 | assertEquals(999_999, buffer.readInt())
193 | assertEquals(9_999_999_999_999, buffer.readLong())
194 | val newArray = ByteArray(123).also { buffer.copyToByteArray(it) }
195 | assertContentEquals(array, newArray)
196 |
197 | assertEquals(138, buffer.readIndex)
198 | assertEquals(138, buffer.writeIndex)
199 | }
200 | }
--------------------------------------------------------------------------------
/src/commonTest/kotlin/io/ktor/io/BufferedBytesDestinationTest.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | import io.ktor.io.utils.*
4 | import kotlin.test.Test
5 | import kotlin.test.assertEquals
6 |
7 | class BufferedBytesDestinationTest {
8 |
9 | @Test
10 | fun testWriteDoesNotFlush() {
11 | val destination = TestBytesDestination()
12 | val buffered = BufferedBytesDestination(destination, 1024)
13 |
14 | val buffer1 = ByteArrayBuffer(512)
15 | buffer1.copyFromByteArray(ByteArray(512) { it.toByte() })
16 |
17 | val buffer2 = ByteArrayBuffer(1024)
18 | buffer2.copyFromByteArray(ByteArray(1024) { it.toByte() })
19 |
20 | buffered.write(buffer1)
21 | buffered.write(buffer2)
22 |
23 | assertEquals(512, buffer1.readIndex)
24 | assertEquals(512, buffer2.readIndex)
25 | assertEquals(0, destination.writeCount)
26 | }
27 |
28 | @Test
29 | fun testAwaitFreeSpaceDoesNotWriteIfBufferIsNotFull() = testSuspend {
30 | val destination = TestBytesDestination()
31 | val buffered = BufferedBytesDestination(destination, 1024)
32 |
33 | val buffer1 = ByteArrayBuffer(1023)
34 | buffer1.copyFromByteArray(ByteArray(1023) { it.toByte() })
35 |
36 | buffered.write(buffer1)
37 | buffered.awaitFreeSpace()
38 |
39 | assertEquals(0, destination.writeCount)
40 | }
41 |
42 | @Test
43 | fun testAwaitFreeSpaceWritesIfBufferIsFull() = testSuspend {
44 | val destination = TestBytesDestination()
45 | val buffered = BufferedBytesDestination(destination, 1024)
46 |
47 | val buffer1 = ByteArrayBuffer(1024)
48 | buffer1.copyFromByteArray(ByteArray(1024) { it.toByte() })
49 |
50 | buffered.write(buffer1)
51 | buffered.awaitFreeSpace()
52 |
53 | assertEquals(1, destination.writeCount)
54 | }
55 |
56 | @Test
57 | fun testWriteByteFlushesIfBufferIsFull() = testSuspend {
58 | val destination = TestBytesDestination()
59 | val buffered = BufferedBytesDestination(destination, 1024)
60 |
61 | val buffer1 = ByteArrayBuffer(1023)
62 | buffer1.copyFromByteArray(ByteArray(1023) { it.toByte() })
63 |
64 | buffered.write(buffer1)
65 | assertEquals(0, destination.writeCount)
66 |
67 | buffered.writeByte(1)
68 | assertEquals(1, destination.writeCount)
69 | }
70 |
71 | @Test
72 | fun testWriteByteDoesNotFlushIfBufferIsNotFull() = testSuspend {
73 | val destination = TestBytesDestination()
74 | val buffered = BufferedBytesDestination(destination, 1024)
75 |
76 | val buffer1 = ByteArrayBuffer(1022)
77 | buffer1.copyFromByteArray(ByteArray(1022) { it.toByte() })
78 |
79 | buffered.write(buffer1)
80 | buffered.writeByte(1)
81 | assertEquals(0, destination.writeCount)
82 | }
83 |
84 | @Test
85 | fun testWriteShort() = testSuspend {
86 | val destination = TestBytesDestination()
87 | val buffered = BufferedBytesDestination(destination, 2)
88 |
89 | buffered.writeByte(1)
90 | buffered.writeShort(999)
91 | buffered.flush()
92 |
93 | assertEquals(2, destination.writeCount)
94 |
95 | val buffer1 = destination.buffers[0]
96 | val buffer2 = destination.buffers[1]
97 | buffer1.readByte()
98 | val highByte = buffer1.readByte()
99 | val lowByte = buffer2.readByte()
100 | val value = ((highByte.toInt() shl 8) or (lowByte.toInt() and 0xff)).toShort()
101 | assertEquals(999, value)
102 | }
103 |
104 | @Test
105 | fun testWriteInt() = testSuspend {
106 | val destination = TestBytesDestination()
107 | val buffered = BufferedBytesDestination(destination, 3)
108 |
109 | buffered.writeByte(1)
110 | buffered.writeInt(999999)
111 | buffered.flush()
112 |
113 | assertEquals(2, destination.writeCount)
114 |
115 | val buffer1 = destination.buffers[0]
116 | val buffer2 = destination.buffers[1]
117 | buffer1.readByte()
118 | val highShort = buffer1.readShort()
119 | val lowShort = buffer2.readShort()
120 | val value = (highShort.toInt() shl 16) or (lowShort.toInt() and 0xffff)
121 | assertEquals(999999, value)
122 | }
123 |
124 | @Test
125 | fun testWriteLong() = testSuspend {
126 | val destination = TestBytesDestination()
127 | val buffered = BufferedBytesDestination(destination, 5)
128 |
129 | buffered.writeByte(1)
130 | buffered.writeLong(999999999)
131 | buffered.flush()
132 |
133 | assertEquals(2, destination.writeCount)
134 |
135 | val buffer1 = destination.buffers[0]
136 | val buffer2 = destination.buffers[1]
137 | buffer1.readByte()
138 | val highInt = buffer1.readInt()
139 | val lowInt = buffer2.readInt()
140 | val value = (highInt.toLong() shl 32) or (lowInt.toLong() and 0xffffffffL)
141 | assertEquals(999999999, value)
142 | }
143 | }
144 |
145 |
--------------------------------------------------------------------------------
/src/commonTest/kotlin/io/ktor/io/BufferedBytesSourceTest.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | import io.ktor.io.utils.*
4 | import kotlin.test.*
5 |
6 | class BufferedBytesSourceTest {
7 |
8 | @Test
9 | fun testCanReadReadReturnsTrueWhenBufferHasContent() = testSuspend {
10 | val buffer1 = ByteArrayBuffer(1024)
11 | buffer1.writeByte(1)
12 |
13 | val source = TestBytesSource(buffer1)
14 | val buffered = BufferedBytesSource(source)
15 |
16 | assertTrue(buffered.canRead())
17 | buffered.read()
18 | assertTrue(buffered.canRead())
19 | buffered.readByte()
20 | assertFalse(buffered.canRead())
21 | }
22 |
23 | @Test
24 | fun testReadReturnsSameBufferIfHasContent() {
25 | val buffer1 = ByteArrayBuffer(1024)
26 | buffer1.copyFromByteArray(ByteArray(123) { it.toByte() })
27 |
28 | val buffer2 = ByteArrayBuffer(1024)
29 | buffer2.copyFromByteArray(ByteArray(123) { it.toByte() })
30 |
31 | val source = TestBytesSource(buffer1, buffer2)
32 | val buffered = BufferedBytesSource(source)
33 |
34 | val read1 = buffered.read()
35 | repeat(buffer1.writeIndex - 1) {
36 | buffer1.readByte()
37 | }
38 | val read2 = buffered.read()
39 | assertSame(read1, read2)
40 |
41 | read2.readByte()
42 | val read3 = buffered.read()
43 | assertNotSame(read2, read3)
44 | }
45 |
46 | @Test
47 | fun testReadByteWaitsUntilHasContent() = testSuspend {
48 | val buffer1 = ByteArrayBuffer(1024)
49 | val buffer2 = ByteArrayBuffer(1024)
50 | buffer2.writeByte(1)
51 |
52 | val source = TestBytesSource(buffer1, buffer2)
53 | val buffered = BufferedBytesSource(source)
54 |
55 | val value = buffered.readByte()
56 | assertEquals(1, value)
57 | assertEquals(2, source.readCount)
58 | }
59 |
60 | @Test
61 | fun testReadShort() = testSuspend {
62 | val buffer1 = ByteArrayBuffer(1)
63 | val buffer2 = ByteArrayBuffer(1)
64 | val value: Short = 999
65 | buffer1.writeByte(value.highByte)
66 | buffer2.writeByte(value.lowByte)
67 |
68 | val source = TestBytesSource(buffer1, buffer2)
69 | val buffered = BufferedBytesSource(source)
70 |
71 | assertEquals(999, buffered.readShort())
72 | assertEquals(2, source.readCount)
73 | }
74 |
75 | @Test
76 | fun testReadInt() = testSuspend {
77 | val buffer1 = ByteArrayBuffer(2)
78 | val buffer2 = ByteArrayBuffer(2)
79 | val value = 999
80 | buffer1.writeShort(value.highShort)
81 | buffer2.writeShort(value.lowShort)
82 |
83 | val source = TestBytesSource(buffer1, buffer2)
84 | val buffered = BufferedBytesSource(source)
85 |
86 | assertEquals(999, buffered.readInt())
87 | assertEquals(2, source.readCount)
88 | }
89 |
90 | @Test
91 | fun testReadLong() = testSuspend {
92 | val buffer1 = ByteArrayBuffer(4)
93 | val buffer2 = ByteArrayBuffer(4)
94 | val value = 999L
95 | buffer1.writeInt(value.highInt)
96 | buffer2.writeInt(value.lowInt)
97 |
98 | val source = TestBytesSource(buffer1, buffer2)
99 | val buffered = BufferedBytesSource(source)
100 |
101 | assertEquals(999, buffered.readLong())
102 | assertEquals(2, source.readCount)
103 | }
104 |
105 | @Test
106 | fun testReadLongAtOnce() = testSuspend {
107 | val buffer = ByteArrayBuffer(8)
108 | buffer.writeInt(Int.MAX_VALUE)
109 | buffer.writeInt(Int.MAX_VALUE)
110 |
111 | val source = TestBytesSource(buffer)
112 | val buffered = BufferedBytesSource(source)
113 |
114 | assertEquals(9223372034707292159, buffered.readLong())
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/src/commonTest/kotlin/io/ktor/io/ByteArrayBufferTest.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | import kotlin.test.Test
4 | import kotlin.test.assertEquals
5 |
6 | class ByteArrayWithDefaultPoolTest : BufferTest() {
7 | override fun createBuffer(): Buffer = ByteArrayBuffer(ByteArrayPool.Default)
8 | }
9 |
10 | class ByteArrayWithEmptyPoolTest : BufferTest() {
11 | override fun createBuffer(): Buffer = ByteArrayBuffer(ByteArrayPool.Empty)
12 | }
13 |
14 | class ByteArrayTest {
15 | @Test
16 | fun testConstructorFromArray() {
17 | val array = ByteArray(10)
18 | val buffer = ByteArrayBuffer(array)
19 |
20 | assertEquals(0, buffer.readIndex)
21 | assertEquals(array.size, buffer.writeIndex)
22 | }
23 |
24 | @Test
25 | fun testConstructorFromPool() {
26 | val buffer = ByteArrayBuffer()
27 | assertEquals(0, buffer.readIndex)
28 | assertEquals(0, buffer.writeIndex)
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/commonTest/kotlin/io/ktor/io/TestBytesSource.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | class TestBytesSource(private vararg val buffers: ByteArrayBuffer) : BytesSource() {
4 | internal var readCount = 0
5 | override val closedCause: Throwable? = null
6 | override fun canRead() = readCount < buffers.size
7 | override fun read(): Buffer = buffers[readCount++]
8 | override suspend fun awaitContent() = Unit
9 | override fun cancel(cause: Throwable) = Unit
10 | }
11 |
--------------------------------------------------------------------------------
/src/commonTest/kotlin/io/ktor/io/utils/TestBytesDestination.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io.utils
2 |
3 | import io.ktor.io.*
4 |
5 | class TestBytesDestination : BytesDestination() {
6 | internal val buffers = mutableListOf()
7 | internal val writeCount: Int get() = buffers.size
8 |
9 | override var closedCause: Throwable? = null
10 |
11 | override fun canWrite(): Boolean = closedCause != null
12 |
13 | override fun write(buffer: Buffer): Int {
14 | val copy = ByteArrayBuffer(buffer.availableForRead)
15 | val array = ByteArray(buffer.availableForRead)
16 | buffer.copyToByteArray(array)
17 | copy.copyFromByteArray(array)
18 | buffers.add(copy)
19 | buffer.readIndex = buffer.writeIndex
20 | return array.size
21 | }
22 |
23 | override suspend fun flush() = Unit
24 | override suspend fun awaitFreeSpace() = Unit
25 |
26 | override fun close(cause: Throwable?) {
27 | closedCause = cause ?: ClosedDestinationException()
28 | }
29 |
30 | override fun close() {
31 | close(null)
32 | }
33 |
34 | class ClosedDestinationException : IOException("closed")
35 | }
36 |
--------------------------------------------------------------------------------
/src/commonTest/kotlin/io/ktor/io/utils/testSuspend.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io.utils
2 |
3 | import kotlinx.coroutines.CoroutineScope
4 | import kotlin.coroutines.CoroutineContext
5 | import kotlin.coroutines.EmptyCoroutineContext
6 |
7 | expect fun testSuspend(
8 | context: CoroutineContext = EmptyCoroutineContext,
9 | timeoutMillis: Long = 60L * 1000L,
10 | block: suspend CoroutineScope.() -> Unit
11 | )
12 |
--------------------------------------------------------------------------------
/src/jsMain/kotlin/io/ktor/io/CloseableJs.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | public actual interface Closeable {
4 | public actual fun close()
5 | }
6 |
7 | @PublishedApi
8 | internal actual fun Throwable.addSuppressedInternal(other: Throwable) {
9 | }
10 |
--------------------------------------------------------------------------------
/src/jsMain/kotlin/io/ktor/io/DefaultPool.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | public actual abstract class DefaultPool actual constructor(
4 | actual final override val capacity: Int
5 | ) : ObjectPool {
6 |
7 | private val instances = arrayOfNulls(capacity)
8 | private var size = 0
9 |
10 | protected actual abstract fun produceInstance(): T
11 | protected actual open fun disposeInstance(instance: T) {}
12 |
13 | protected actual open fun clearInstance(instance: T): T = instance
14 | protected actual open fun validateInstance(instance: T) {}
15 |
16 | actual final override fun borrow(): T {
17 | if (size == 0) return produceInstance()
18 | val idx = --size
19 |
20 | @Suppress("UNCHECKED_CAST")
21 | val instance = instances[idx] as T
22 | instances[idx] = null
23 |
24 | return clearInstance(instance)
25 | }
26 |
27 | actual final override fun recycle(instance: T) {
28 | validateInstance(instance)
29 | if (size == capacity) {
30 | disposeInstance(instance)
31 | } else {
32 | instances[size++] = instance
33 | }
34 | }
35 |
36 | actual final override fun dispose() {
37 | for (i in 0 until size) {
38 | @Suppress("UNCHECKED_CAST")
39 | val instance = instances[i] as T
40 | instances[i] = null
41 | disposeInstance(instance)
42 | }
43 | size = 0
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/jsMain/kotlin/io/ktor/io/IOExceptionJs.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | public actual open class IOException actual constructor(message: String, cause: Throwable?) :
4 | Exception(message, cause) {
5 | public actual constructor(message: String) : this(message, null)
6 | }
7 |
8 | public actual open class EOFException actual constructor(message: String) : IOException(message)
9 |
--------------------------------------------------------------------------------
/src/jsTest/kotlin/io/ktor/io/utils/TestUtilsJs.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io.utils
2 |
3 | import kotlinx.coroutines.*
4 | import kotlin.coroutines.CoroutineContext
5 |
6 | @OptIn(DelicateCoroutinesApi::class)
7 | actual fun testSuspend(
8 | context: CoroutineContext,
9 | timeoutMillis: Long,
10 | block: suspend CoroutineScope.() -> Unit
11 | ): dynamic = GlobalScope.promise(block = {
12 | withTimeout(timeoutMillis, block)
13 | }, context = context)
14 |
--------------------------------------------------------------------------------
/src/jvmMain/kotlin/io/ktor/io/CloseableJvm.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | import java.lang.reflect.Method
4 |
5 | public actual typealias Closeable = java.io.Closeable
6 |
7 | @PublishedApi
8 | internal actual fun Throwable.addSuppressedInternal(other: Throwable) {
9 | AddSuppressedMethod?.invoke(this, other)
10 | }
11 |
12 | private val AddSuppressedMethod: Method? by lazy {
13 | try {
14 | Throwable::class.java.getMethod("addSuppressed", Throwable::class.java)
15 | } catch (t: Throwable) {
16 | null
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/jvmMain/kotlin/io/ktor/io/DefaultPool.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | import kotlinx.atomicfu.atomic
4 | import kotlinx.atomicfu.atomicArrayOfNulls
5 | import kotlinx.atomicfu.locks.SynchronizedObject
6 | import kotlinx.atomicfu.locks.synchronized
7 |
8 | public actual abstract class DefaultPool actual constructor(
9 | actual final override val capacity: Int
10 | ) : ObjectPool {
11 | protected val lock: SynchronizedObject = SynchronizedObject()
12 |
13 | private val instances = atomicArrayOfNulls(capacity)
14 | private var size by atomic(0)
15 |
16 | protected actual abstract fun produceInstance(): T
17 | protected actual open fun disposeInstance(instance: T) {}
18 |
19 | protected actual open fun clearInstance(instance: T): T = instance
20 | protected actual open fun validateInstance(instance: T) {}
21 |
22 | public actual final override fun borrow(): T = synchronized(lock) {
23 | if (size == 0) return produceInstance()
24 | val idx = --size
25 |
26 | @Suppress("UNCHECKED_CAST")
27 | val instance = instances[idx].value as T
28 | instances[idx].value = null
29 |
30 | return clearInstance(instance)
31 | }
32 |
33 | public actual final override fun recycle(instance: T) {
34 | synchronized(lock) {
35 | validateInstance(instance)
36 | if (size == capacity) {
37 | disposeInstance(instance)
38 | } else {
39 | instances[size++].value = instance
40 | }
41 | }
42 | }
43 |
44 | public actual final override fun dispose() {
45 | synchronized(lock) {
46 | for (i in 0 until size) {
47 | @Suppress("UNCHECKED_CAST")
48 | val instance = instances[i].value as T
49 | instances[i].value = null
50 | disposeInstance(instance)
51 | }
52 | size = 0
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/jvmMain/kotlin/io/ktor/io/DirectByteBufferPool.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | import java.nio.ByteBuffer
4 | import java.nio.ByteOrder
5 |
6 | public class ByteBufferPool(
7 | capacity: Int = DEFAULT_POOL_CAPACITY,
8 | public val direct: Boolean = true,
9 | public val bufferSize: Int = DEFAULT_BUFFER_SIZE
10 | ) : DefaultPool(capacity) {
11 |
12 | override fun produceInstance(): ByteBuffer = if (direct) {
13 | ByteBuffer.allocateDirect(bufferSize)!!
14 | } else {
15 | ByteBuffer.allocate(bufferSize)!!
16 | }
17 |
18 | override fun clearInstance(instance: ByteBuffer): ByteBuffer = instance.apply {
19 | clear()
20 | order(ByteOrder.BIG_ENDIAN)
21 | }
22 |
23 | override fun validateInstance(instance: ByteBuffer) {
24 | check(instance.capacity() == bufferSize)
25 | check(instance.isDirect)
26 | }
27 |
28 | public companion object {
29 | public val Default: ObjectPool get() = Direct
30 |
31 | public val Direct: ObjectPool = ByteBufferPool(direct = true)
32 |
33 | public val Heap: ObjectPool = ByteBufferPool(direct = false)
34 |
35 | public val Empty: ObjectPool = ByteBufferPool(capacity = 0)
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/jvmMain/kotlin/io/ktor/io/FileBytesDestination.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | import java.lang.Integer.min
4 | import java.nio.channels.ClosedChannelException
5 | import java.nio.channels.FileChannel
6 | import java.nio.file.OpenOption
7 | import java.nio.file.Path
8 | import java.nio.file.StandardOpenOption
9 | import java.nio.file.attribute.FileAttribute
10 |
11 | public fun FileBytesDestination(
12 | file: Path,
13 | options: Set = setOf(StandardOpenOption.CREATE, StandardOpenOption.WRITE),
14 | vararg attrs: FileAttribute
15 | ): FileBytesDestination = FileBytesDestination(FileChannel.open(file, options, *attrs))
16 |
17 | public class FileBytesDestination(private val channel: FileChannel) : BytesDestination() {
18 |
19 | @Volatile
20 | override var closedCause: Throwable? = null
21 | private set
22 |
23 | override fun canWrite(): Boolean {
24 | if (closedCause is ClosedChannelException) return false
25 | closedCause?.let { throw it }
26 | return true
27 | }
28 |
29 | override fun write(buffer: Buffer): Int {
30 | closedCause?.let { throw it }
31 |
32 | try {
33 | if (buffer is JvmBuffer) {
34 | return channel.write(buffer.buffer)
35 | }
36 | return slowWrite(buffer)
37 | } catch (cause: Throwable) {
38 | close(cause)
39 | throw cause
40 | }
41 | }
42 |
43 | private fun slowWrite(buffer: Buffer): Int {
44 | ByteBufferPool.Default.useInstance { byteBuffer ->
45 | val toWrite = min(buffer.availableForRead, byteBuffer.remaining())
46 | if (buffer is ByteArrayBuffer) {
47 | byteBuffer.put(buffer.array, buffer.readIndex, toWrite)
48 | buffer.readIndex += toWrite
49 | } else {
50 | repeat(toWrite) {
51 | byteBuffer.put(buffer.readByte())
52 | }
53 | }
54 | byteBuffer.flip()
55 | return channel.write(byteBuffer)
56 | }
57 | }
58 |
59 | public override suspend fun awaitFreeSpace() {
60 | closedCause?.let { throw it }
61 | }
62 |
63 | override suspend fun flush() {
64 | closedCause?.let { throw it }
65 | }
66 |
67 | override fun close(cause: Throwable?) {
68 | closedCause = cause ?: ClosedChannelException()
69 | channel.close()
70 | }
71 |
72 | override fun close() {
73 | close(null)
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/jvmMain/kotlin/io/ktor/io/FileBytesSource.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | import java.nio.ByteBuffer
4 | import java.nio.channels.AsynchronousCloseException
5 | import java.nio.channels.AsynchronousFileChannel
6 | import java.nio.channels.CompletionHandler
7 | import java.nio.file.OpenOption
8 | import java.nio.file.Path
9 | import java.nio.file.StandardOpenOption
10 | import java.util.concurrent.ExecutorService
11 | import kotlin.coroutines.Continuation
12 | import kotlin.coroutines.resume
13 | import kotlin.coroutines.resumeWithException
14 | import kotlin.coroutines.suspendCoroutine
15 |
16 | public fun FileBytesSource(
17 | file: Path,
18 | options: Set = setOf(StandardOpenOption.READ),
19 | executor: ExecutorService? = null
20 | ): FileBytesSource = FileBytesSource(AsynchronousFileChannel.open(file, options, executor))
21 |
22 | public class FileBytesSource(private val channel: AsynchronousFileChannel) : BytesSource() {
23 |
24 | @Volatile
25 | private var bytesRead = 0L
26 |
27 | @Volatile
28 | private var isClosedForRead = false
29 |
30 | @Volatile
31 | override var closedCause: Throwable? = null
32 | private set
33 |
34 | private var state: JvmBuffer? = null
35 |
36 | override fun canRead(): Boolean {
37 | closedCause?.let { throw it }
38 |
39 | return !isClosedForRead
40 | }
41 |
42 | override fun read(): Buffer {
43 | closedCause?.let { throw it }
44 |
45 | return state.also { state = null } ?: Buffer.Empty
46 | }
47 |
48 | override suspend fun awaitContent() {
49 | closedCause?.let { throw it }
50 |
51 | val buffer = ByteBufferPool.Direct.borrow()
52 | val count = channel.read(buffer)
53 | if (count == -1) {
54 | isClosedForRead = true
55 | ByteBufferPool.Direct.recycle(buffer)
56 | return
57 | }
58 |
59 | bytesRead += count
60 | state = JvmBuffer(buffer.flip(), ByteBufferPool.Direct)
61 | }
62 |
63 | override fun cancel(cause: Throwable) {
64 | if (closedCause != null) return
65 | closedCause = cause
66 | channel.close()
67 | }
68 |
69 | private lateinit var readCompletionContinuation: Continuation
70 |
71 | private val readCompletionHandler = object : CompletionHandler {
72 | override fun completed(result: Int, attachment: Unit) {
73 | readCompletionContinuation.resume(result)
74 | }
75 |
76 | override fun failed(cause: Throwable, attachment: Unit) {
77 | if (cause is AsynchronousCloseException) {
78 | check(closedCause != null)
79 | readCompletionContinuation.resumeWithException(closedCause!!)
80 | return
81 | }
82 |
83 | cancel(cause)
84 | readCompletionContinuation.resumeWithException(cause)
85 | }
86 | }
87 |
88 | private suspend fun AsynchronousFileChannel.read(
89 | byteBuffer: ByteBuffer
90 | ): Int = suspendCoroutine { continuation ->
91 | readCompletionContinuation = continuation
92 | read(byteBuffer, bytesRead, Unit, readCompletionHandler)
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/jvmMain/kotlin/io/ktor/io/IOExceptionJvm.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | public actual typealias IOException = java.io.IOException
4 |
5 | public actual typealias EOFException = java.io.EOFException
6 |
--------------------------------------------------------------------------------
/src/jvmMain/kotlin/io/ktor/io/JvmBuffer.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | import java.lang.Integer.min
4 | import java.nio.ByteBuffer
5 |
6 | /**
7 | * The [Buffer] implementation using [ByteBuffer] class on the JVM.
8 | *
9 | * @constructor creates buffer prepared for reading.
10 | */
11 | public class JvmBuffer(
12 | buffer: ByteBuffer,
13 | private val pool: ObjectPool = ByteBufferPool.Default
14 | ) : Buffer {
15 |
16 | /**
17 | * Creates a new [JvmBuffer] instance with the [ByteBuffer] instance from the [pool].
18 | *
19 | * The buffer is empty and prepared for write operations.
20 | */
21 | public constructor(capacity: Int) : this(
22 | ByteBuffer.allocateDirect(capacity).limit(0),
23 | ByteBufferPool.Empty
24 | )
25 |
26 | /**
27 | * Creates a new [JvmBuffer] instance with the [ByteBuffer] instance from the [pool].
28 | *
29 | * The buffer is empty and prepared for write operations.
30 | */
31 | public constructor(pool: ObjectPool = ByteBufferPool.Default) : this(pool.borrow().limit(0), pool)
32 |
33 | /**
34 | * Provides access to the underlying [ByteBuffer].
35 | *
36 | * The [buffer.position()] reflects [readIndex] and [buffer.limit()] reflects [writeIndex].
37 | *
38 | * All modifications of the [ByteBuffer] is reflected by the [JvmBuffer] itself.
39 | */
40 | @Suppress("CanBePrimaryConstructorProperty")
41 | public var buffer: ByteBuffer = buffer
42 | private set
43 |
44 | override var readIndex: Int
45 | get() = buffer.position()
46 | set(value) {
47 | buffer.position(value)
48 | }
49 |
50 | override var writeIndex: Int
51 | get() = buffer.limit()
52 | set(value) {
53 | buffer.limit(value)
54 | }
55 |
56 | override val capacity: Int
57 | get() = buffer.capacity()
58 |
59 | override fun copyToByteArrayAt(index: Int, destination: ByteArray, startIndex: Int, endIndex: Int): Int {
60 | require(startIndex >= 0) { "startIndex should be non-negative: $startIndex" }
61 | require(startIndex <= endIndex) { "startIndex should be less than or equal to endIndex: $startIndex, $endIndex" }
62 | require(endIndex <= destination.size) { "endIndex should be less than or equal to destination.size: $endIndex, ${destination.size}" }
63 | require(index < capacity) { "index should be less than capacity: $index, $capacity" }
64 |
65 | val count = min(endIndex - startIndex, capacity - index)
66 | randomAccess {
67 | it.position(index)
68 | buffer.get(destination, startIndex, count)
69 | }
70 |
71 | return count
72 | }
73 |
74 | override fun copyToByteArray(destination: ByteArray, startIndex: Int, endIndex: Int): Int {
75 | require(startIndex >= 0) { "startIndex should be non-negative: $startIndex" }
76 | require(startIndex <= endIndex) { "startIndex should be less than or equal to endIndex: $startIndex, $endIndex" }
77 | require(endIndex <= destination.size) { "endIndex should be less than or equal to destination.size: $endIndex, ${destination.size}" }
78 |
79 | val count = min(endIndex - startIndex, buffer.remaining())
80 | buffer.get(destination, startIndex, count)
81 | return count
82 | }
83 |
84 | /**
85 | * Return the underlying buffer to the pool.
86 | */
87 | override fun close() {
88 | pool.recycle(buffer)
89 | }
90 |
91 | override fun compact() {
92 | buffer.compact()
93 | }
94 |
95 | override fun getByteAt(index: Int): Byte = buffer.get(index)
96 |
97 | override fun getShortAt(index: Int): Short = buffer.getShort(index)
98 |
99 | override fun getIntAt(index: Int): Int = buffer.getInt(index)
100 |
101 | override fun getLongAt(index: Int): Long = buffer.getLong(index)
102 |
103 | override fun setByteAt(index: Int, value: Byte) {
104 | randomAccess {
105 | it.put(index, value)
106 | }
107 | }
108 |
109 | override fun setShortAt(index: Int, value: Short) {
110 | randomAccess {
111 | it.putShort(index, value)
112 | }
113 | }
114 |
115 | override fun setIntAt(index: Int, value: Int) {
116 | randomAccess {
117 | it.putInt(index, value)
118 | }
119 | }
120 |
121 | override fun setLongAt(index: Int, value: Long) {
122 | randomAccess {
123 | it.putLong(index, value)
124 | }
125 | }
126 |
127 | override fun copyFromBufferAt(index: Int, value: Buffer): Int {
128 | var current = index
129 | while (value.isNotEmpty) {
130 | setByteAt(current++, value.readByte())
131 | }
132 |
133 | return current - index
134 | }
135 |
136 | override fun copyFromByteArrayAt(index: Int, value: ByteArray, startIndex: Int, endIndex: Int): Int {
137 | check(index < capacity) { "Index should be less than capacity: $index, $capacity" }
138 | check(startIndex >= 0) { "startPosition should be non-negative: $startIndex" }
139 | check(startIndex <= endIndex) { "startPosition should be less than or equal to endPosition: $startIndex, $endIndex" }
140 | check(endIndex <= value.size) { "endPosition should be less than or equal to value.size: $endIndex, ${value.size}" }
141 |
142 |
143 | val count = min(endIndex - startIndex, capacity - index)
144 |
145 | randomAccess {
146 | it.position(index)
147 | buffer.put(value, startIndex, count)
148 | }
149 |
150 | return count
151 | }
152 |
153 | private fun randomAccess(block: (ByteBuffer) -> Unit) {
154 | val oldPosition = buffer.position()
155 | val oldLimit = buffer.limit()
156 | try {
157 | buffer.position(0)
158 | buffer.limit(capacity)
159 | block(buffer)
160 | } finally {
161 | buffer.position(oldPosition)
162 | buffer.limit(oldLimit)
163 | }
164 | }
165 | }
166 |
167 |
--------------------------------------------------------------------------------
/src/jvmMain/kotlin/io/ktor/io/JvmBufferPool.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | import java.nio.ByteBuffer
4 |
5 | public class JvmBufferPool(
6 | capacity: Int = DEFAULT_POOL_CAPACITY,
7 | public val byteBufferPool: ObjectPool = ByteBufferPool.Default
8 | ) : DefaultPool(capacity) {
9 |
10 | override fun produceInstance(): JvmBuffer = JvmBuffer(byteBufferPool)
11 |
12 | public companion object {
13 | public val Default: ObjectPool = JvmBufferPool()
14 |
15 | public val Empty: ObjectPool = JvmBufferPool(
16 | capacity = 0,
17 | byteBufferPool = ByteBufferPool.Empty
18 | )
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/jvmTest/kotlin/io/ktor/io/FilesTest.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | import kotlinx.coroutines.runBlocking
4 | import java.nio.file.Files
5 | import kotlin.io.path.deleteIfExists
6 | import kotlin.io.path.readText
7 | import kotlin.io.path.writeText
8 | import kotlin.test.Test
9 | import kotlin.test.assertEquals
10 |
11 | class FilesTest {
12 |
13 | @Test
14 | fun testCopyingFile(): Unit = runBlocking {
15 | val content = buildString { repeat(100000) { append("testString$it") } }
16 |
17 | val originalFile = Files.createTempFile("test", "origin")
18 | originalFile.writeText(content)
19 | val fileCopy = Files.createTempFile("test", "copy")
20 |
21 | val source = FileBytesSource(originalFile)
22 | val destination = FileBytesDestination(fileCopy)
23 |
24 | while (source.canRead()) {
25 | val buffer = source.read()
26 | destination.write(buffer)
27 | destination.awaitFreeSpace()
28 | source.awaitContent()
29 | }
30 | destination.flush()
31 | source.cancel()
32 | destination.close()
33 |
34 | val copiedContent = fileCopy.readText()
35 |
36 | originalFile.deleteIfExists()
37 | fileCopy.deleteIfExists()
38 |
39 | assertEquals(content, copiedContent)
40 | }
41 |
42 | @Test
43 | fun testCopyingFileBuffered(): Unit = runBlocking {
44 | val content = buildString { repeat(100000) { append("testString$it") } }
45 |
46 | val originalFile = Files.createTempFile("tmp", "original")
47 | originalFile.writeText(content)
48 | val fileCopy = Files.createTempFile("tmp", "copy")
49 |
50 | val source = BufferedBytesSource(FileBytesSource(originalFile))
51 | val destination = BufferedBytesDestination(FileBytesDestination(fileCopy), 12 * 1024)
52 |
53 | var writeCount = 0
54 | while (source.canRead()) {
55 | val buffer = source.read()
56 | val count = destination.write(buffer)
57 | writeCount += count
58 |
59 | println("Written $buffer $count/$writeCount/${content.length} bytes")
60 |
61 | destination.awaitFreeSpace()
62 | source.awaitContent()
63 | }
64 |
65 | destination.flush()
66 | source.cancel()
67 | destination.close()
68 |
69 | val copiedContent = fileCopy.readText()
70 |
71 | originalFile.deleteIfExists()
72 | fileCopy.deleteIfExists()
73 |
74 | assertEquals(content, copiedContent)
75 | }
76 | }
--------------------------------------------------------------------------------
/src/jvmTest/kotlin/io/ktor/io/JvmBufferTest.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | import org.junit.jupiter.api.Test
4 | import java.nio.ByteBuffer
5 | import kotlin.test.assertEquals
6 |
7 | class JvmBufferWithDefaultPoolTest : BufferTest() {
8 | override fun createBuffer(): Buffer = JvmBuffer(ByteBufferPool.Default)
9 | }
10 |
11 | class JvmBufferWithEmptyPoolTest : BufferTest() {
12 | override fun createBuffer(): Buffer = JvmBuffer(ByteBufferPool.Empty)
13 | }
14 |
15 | class JvmBufferTest {
16 |
17 | @Test
18 | fun testConstructorFromByteBuffer() {
19 | val data = ByteBuffer.allocateDirect(1024)
20 | data.position(21)
21 | data.limit(42)
22 |
23 | val buffer = JvmBuffer(data)
24 | assertEquals(21, buffer.readIndex)
25 | assertEquals(42, buffer.writeIndex)
26 | }
27 |
28 | @Test
29 | fun testConstructorFromPool() {
30 | val buffer = JvmBuffer(ByteBufferPool.Default)
31 | assertEquals(0, buffer.readIndex)
32 | assertEquals(0, buffer.writeIndex)
33 | }
34 | }
--------------------------------------------------------------------------------
/src/jvmTest/kotlin/io/ktor/io/utils/TestUtilsJvm.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io.utils
2 |
3 | import kotlinx.coroutines.CoroutineScope
4 | import kotlinx.coroutines.runBlocking
5 | import kotlinx.coroutines.withTimeout
6 | import kotlin.coroutines.CoroutineContext
7 |
8 | actual fun testSuspend(
9 | context: CoroutineContext,
10 | timeoutMillis: Long,
11 | block: suspend CoroutineScope.() -> Unit
12 | ): Unit = runBlocking(context) {
13 | withTimeout(timeoutMillis, block)
14 | }
15 |
--------------------------------------------------------------------------------
/src/nativeMain/kotlin/io/ktor/io/Closeable.native.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | public actual interface Closeable {
4 | public actual fun close()
5 | }
6 |
7 | @PublishedApi
8 | internal actual fun Throwable.addSuppressedInternal(other: Throwable) {
9 | }
10 |
--------------------------------------------------------------------------------
/src/nativeMain/kotlin/io/ktor/io/DefaultPool.native.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | import kotlinx.atomicfu.atomic
4 | import kotlinx.atomicfu.atomicArrayOfNulls
5 | import kotlinx.atomicfu.locks.SynchronizedObject
6 | import kotlinx.atomicfu.locks.synchronized
7 |
8 | public actual abstract class DefaultPool actual constructor(
9 | actual final override val capacity: Int
10 | ) : ObjectPool {
11 | private val lock: SynchronizedObject = SynchronizedObject()
12 |
13 | private val instances = atomicArrayOfNulls(capacity)
14 | private var size by atomic(0)
15 |
16 | protected actual abstract fun produceInstance(): T
17 | protected actual open fun disposeInstance(instance: T) {}
18 |
19 | protected actual open fun clearInstance(instance: T): T = instance
20 | protected actual open fun validateInstance(instance: T) {}
21 |
22 | public actual final override fun borrow(): T = synchronized(lock) {
23 | if (size == 0) return produceInstance()
24 | val idx = --size
25 |
26 | @Suppress("UNCHECKED_CAST")
27 | val instance = instances[idx].value as T
28 | instances[idx].value = null
29 |
30 | return clearInstance(instance)
31 | }
32 |
33 | public actual final override fun recycle(instance: T) {
34 | synchronized(lock) {
35 | validateInstance(instance)
36 | if (size == capacity) {
37 | disposeInstance(instance)
38 | } else {
39 | instances[size++].value = instance
40 | }
41 | }
42 | }
43 |
44 | public actual final override fun dispose() {
45 | synchronized(lock) {
46 | for (i in 0 until size) {
47 | @Suppress("UNCHECKED_CAST")
48 | val instance = instances[i].value as T
49 | instances[i].value = null
50 | disposeInstance(instance)
51 | }
52 | size = 0
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/nativeMain/kotlin/io/ktor/io/IOException.native.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io
2 |
3 | public actual open class IOException
4 | actual constructor(message: String, cause: Throwable?) : Exception(message, cause) {
5 | public actual constructor(message: String) : this(message, null)
6 | }
7 |
8 | public actual open class EOFException actual constructor(message: String) : IOException(message)
9 |
--------------------------------------------------------------------------------
/src/nativeTest/kotlin/io/ktor/io/utils/TestUtilsNative.kt:
--------------------------------------------------------------------------------
1 | package io.ktor.io.utils
2 |
3 | import kotlinx.coroutines.CoroutineScope
4 | import kotlinx.coroutines.runBlocking
5 | import platform.posix.usleep
6 | import kotlin.coroutines.CoroutineContext
7 | import kotlin.native.concurrent.FutureState
8 | import kotlin.native.concurrent.TransferMode
9 | import kotlin.native.concurrent.Worker
10 | import kotlin.system.getTimeMillis
11 | import kotlin.time.Duration.Companion.milliseconds
12 |
13 | actual fun testSuspend(
14 | context: CoroutineContext,
15 | timeoutMillis: Long,
16 | block: suspend CoroutineScope.() -> Unit
17 | ) {
18 | executeInWorker(timeoutMillis) {
19 | runBlocking {
20 | block()
21 | }
22 | }
23 | }
24 |
25 | private var TEST_WORKER: Worker = createTestWorker()
26 | private val SLEEP_TIME: UInt = 10.milliseconds.inWholeMicroseconds.toUInt()
27 |
28 | internal fun executeInWorker(timeout: Long, block: () -> Unit) {
29 | val result = TEST_WORKER.execute(TransferMode.UNSAFE, { block }) {
30 | it()
31 | }
32 |
33 | val endTime = getTimeMillis() + timeout
34 | while (result.state == FutureState.SCHEDULED && endTime > getTimeMillis()) {
35 | usleep(SLEEP_TIME)
36 | }
37 |
38 | when (result.state) {
39 | FutureState.SCHEDULED -> {
40 | TEST_WORKER.requestTermination(processScheduledJobs = false)
41 | TEST_WORKER = createTestWorker()
42 | error("Test is timed out")
43 | }
44 | else -> {
45 | result.consume { }
46 | }
47 | }
48 | }
49 |
50 | private fun createTestWorker(): Worker = Worker.start(
51 | name = "Ktor Test Worker",
52 | errorReporting = true
53 | )
54 |
--------------------------------------------------------------------------------