@yume-chan/scrcpy 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +3 -0
  3. package/esm/1_15/impl/clipboard-stream.d.ts +2 -1
  4. package/esm/1_15/impl/clipboard-stream.d.ts.map +1 -1
  5. package/esm/1_15/impl/clipboard-stream.js +4 -7
  6. package/esm/1_15/impl/clipboard-stream.js.map +1 -1
  7. package/esm/1_15/impl/scroll-controller.d.ts.map +1 -1
  8. package/esm/1_15/impl/scroll-controller.js +22 -21
  9. package/esm/1_15/impl/scroll-controller.js.map +1 -1
  10. package/esm/1_15/options.d.ts +2 -3
  11. package/esm/1_15/options.d.ts.map +1 -1
  12. package/esm/1_15/options.js +6 -15
  13. package/esm/1_15/options.js.map +1 -1
  14. package/esm/1_17/options.d.ts +2 -3
  15. package/esm/1_17/options.d.ts.map +1 -1
  16. package/esm/1_17/options.js +6 -15
  17. package/esm/1_17/options.js.map +1 -1
  18. package/esm/1_18/options.d.ts +2 -3
  19. package/esm/1_18/options.d.ts.map +1 -1
  20. package/esm/1_18/options.js +6 -15
  21. package/esm/1_18/options.js.map +1 -1
  22. package/esm/1_21/impl/set-clipboard.d.ts +2 -1
  23. package/esm/1_21/impl/set-clipboard.d.ts.map +1 -1
  24. package/esm/1_21/impl/set-clipboard.js +2 -5
  25. package/esm/1_21/impl/set-clipboard.js.map +1 -1
  26. package/esm/1_21/options.d.ts +2 -3
  27. package/esm/1_21/options.d.ts.map +1 -1
  28. package/esm/1_21/options.js +7 -21
  29. package/esm/1_21/options.js.map +1 -1
  30. package/esm/1_22/options.d.ts +2 -3
  31. package/esm/1_22/options.d.ts.map +1 -1
  32. package/esm/1_22/options.js +7 -21
  33. package/esm/1_22/options.js.map +1 -1
  34. package/esm/1_23/options.d.ts +2 -3
  35. package/esm/1_23/options.d.ts.map +1 -1
  36. package/esm/1_23/options.js +7 -21
  37. package/esm/1_23/options.js.map +1 -1
  38. package/esm/1_24/options.d.ts +2 -3
  39. package/esm/1_24/options.d.ts.map +1 -1
  40. package/esm/1_24/options.js +7 -21
  41. package/esm/1_24/options.js.map +1 -1
  42. package/esm/1_25/options.d.ts +2 -3
  43. package/esm/1_25/options.d.ts.map +1 -1
  44. package/esm/1_25/options.js +7 -21
  45. package/esm/1_25/options.js.map +1 -1
  46. package/esm/2_0/options.d.ts +2 -3
  47. package/esm/2_0/options.d.ts.map +1 -1
  48. package/esm/2_0/options.js +7 -21
  49. package/esm/2_0/options.js.map +1 -1
  50. package/esm/2_1/options.d.ts +2 -3
  51. package/esm/2_1/options.d.ts.map +1 -1
  52. package/esm/2_1/options.js +7 -21
  53. package/esm/2_1/options.js.map +1 -1
  54. package/esm/2_2/options.d.ts +2 -3
  55. package/esm/2_2/options.d.ts.map +1 -1
  56. package/esm/2_2/options.js +7 -21
  57. package/esm/2_2/options.js.map +1 -1
  58. package/esm/2_3/options.d.ts +2 -3
  59. package/esm/2_3/options.d.ts.map +1 -1
  60. package/esm/2_3/options.js +7 -21
  61. package/esm/2_3/options.js.map +1 -1
  62. package/esm/2_4/impl/uhid-output-stream.d.ts +2 -1
  63. package/esm/2_4/impl/uhid-output-stream.d.ts.map +1 -1
  64. package/esm/2_4/impl/uhid-output-stream.js +2 -5
  65. package/esm/2_4/impl/uhid-output-stream.js.map +1 -1
  66. package/esm/2_4/options.d.ts +2 -3
  67. package/esm/2_4/options.d.ts.map +1 -1
  68. package/esm/2_4/options.js +8 -27
  69. package/esm/2_4/options.js.map +1 -1
  70. package/esm/2_6/options.d.ts +2 -3
  71. package/esm/2_6/options.d.ts.map +1 -1
  72. package/esm/2_6/options.js +8 -22
  73. package/esm/2_6/options.js.map +1 -1
  74. package/esm/2_7/impl/serialize-uhid-create.d.ts +2 -2
  75. package/esm/2_7/impl/serialize-uhid-create.d.ts.map +1 -1
  76. package/esm/2_7/impl/serialize-uhid-create.js +3 -4
  77. package/esm/2_7/impl/serialize-uhid-create.js.map +1 -1
  78. package/esm/2_7/options.d.ts +2 -3
  79. package/esm/2_7/options.d.ts.map +1 -1
  80. package/esm/2_7/options.js +8 -22
  81. package/esm/2_7/options.js.map +1 -1
  82. package/esm/3_0/options.d.ts +2 -3
  83. package/esm/3_0/options.d.ts.map +1 -1
  84. package/esm/3_0/options.js +8 -22
  85. package/esm/3_0/options.js.map +1 -1
  86. package/esm/3_1/impl/serialize-uhid-create.d.ts +2 -2
  87. package/esm/3_1/impl/serialize-uhid-create.d.ts.map +1 -1
  88. package/esm/3_1/impl/serialize-uhid-create.js +3 -4
  89. package/esm/3_1/impl/serialize-uhid-create.js.map +1 -1
  90. package/esm/3_1/options.d.ts +2 -3
  91. package/esm/3_1/options.d.ts.map +1 -1
  92. package/esm/3_1/options.js +8 -22
  93. package/esm/3_1/options.js.map +1 -1
  94. package/esm/3_2/options.d.ts +2 -3
  95. package/esm/3_2/options.d.ts.map +1 -1
  96. package/esm/3_2/options.js +8 -22
  97. package/esm/3_2/options.js.map +1 -1
  98. package/esm/3_3.d.ts +8 -0
  99. package/esm/3_3.d.ts.map +1 -0
  100. package/esm/3_3.js +7 -0
  101. package/esm/3_3.js.map +1 -0
  102. package/esm/3_3_1/impl/index.d.ts +3 -0
  103. package/esm/3_3_1/impl/index.d.ts.map +1 -0
  104. package/esm/3_3_1/impl/index.js +3 -0
  105. package/esm/3_3_1/impl/index.js.map +1 -0
  106. package/esm/3_3_1/impl/prev.d.ts +2 -0
  107. package/esm/3_3_1/impl/prev.d.ts.map +1 -0
  108. package/esm/3_3_1/impl/prev.js +2 -0
  109. package/esm/3_3_1/impl/prev.js.map +1 -0
  110. package/esm/3_3_1/impl/scroll-controller.d.ts +7 -0
  111. package/esm/3_3_1/impl/scroll-controller.d.ts.map +1 -0
  112. package/esm/3_3_1/impl/scroll-controller.js +15 -0
  113. package/esm/3_3_1/impl/scroll-controller.js.map +1 -0
  114. package/esm/3_3_1/index.d.ts +2 -0
  115. package/esm/3_3_1/index.d.ts.map +1 -0
  116. package/esm/3_3_1/index.js +2 -0
  117. package/esm/3_3_1/index.js.map +1 -0
  118. package/esm/3_3_1/options.d.ts +90 -0
  119. package/esm/3_3_1/options.d.ts.map +1 -0
  120. package/esm/3_3_1/options.js +78 -0
  121. package/esm/3_3_1/options.js.map +1 -0
  122. package/esm/3_3_2.d.ts +8 -0
  123. package/esm/3_3_2.d.ts.map +1 -0
  124. package/esm/3_3_2.js +7 -0
  125. package/esm/3_3_2.js.map +1 -0
  126. package/esm/base/device-message.d.ts +10 -1
  127. package/esm/base/device-message.d.ts.map +1 -1
  128. package/esm/base/device-message.js +40 -1
  129. package/esm/base/device-message.js.map +1 -1
  130. package/esm/base/options.d.ts +2 -3
  131. package/esm/base/options.d.ts.map +1 -1
  132. package/esm/control/message-type-map.d.ts +2 -2
  133. package/esm/control/message-type-map.d.ts.map +1 -1
  134. package/esm/control/message-type-map.js.map +1 -1
  135. package/esm/index.d.ts +3 -0
  136. package/esm/index.d.ts.map +1 -1
  137. package/esm/index.js +3 -0
  138. package/esm/index.js.map +1 -1
  139. package/esm/latest.d.ts +5 -5
  140. package/esm/latest.d.ts.map +1 -1
  141. package/esm/latest.js +3 -3
  142. package/esm/latest.js.map +1 -1
  143. package/package.json +4 -4
  144. package/src/1_15/impl/clipboard-stream.ts +5 -7
  145. package/src/1_15/impl/scroll-controller.ts +22 -19
  146. package/src/1_15/options.ts +9 -21
  147. package/src/1_17/options.ts +9 -21
  148. package/src/1_18/options.ts +9 -21
  149. package/src/1_21/impl/set-clipboard.ts +2 -5
  150. package/src/1_21/options.ts +13 -28
  151. package/src/1_22/options.ts +13 -28
  152. package/src/1_23/options.ts +13 -28
  153. package/src/1_24/options.ts +13 -28
  154. package/src/1_25/options.ts +13 -28
  155. package/src/2_0/options.ts +13 -28
  156. package/src/2_1/options.ts +13 -28
  157. package/src/2_2/options.ts +13 -28
  158. package/src/2_3/options.ts +13 -28
  159. package/src/2_4/impl/uhid-output-stream.ts +3 -6
  160. package/src/2_4/options.ts +16 -35
  161. package/src/2_6/options.ts +16 -29
  162. package/src/2_7/impl/serialize-uhid-create.ts +9 -11
  163. package/src/2_7/options.ts +16 -29
  164. package/src/3_0/options.ts +16 -29
  165. package/src/3_1/impl/serialize-uhid-create.ts +11 -13
  166. package/src/3_1/options.ts +16 -29
  167. package/src/3_2/options.ts +16 -29
  168. package/src/3_3.ts +14 -0
  169. package/src/3_3_1/impl/index.ts +6 -0
  170. package/src/3_3_1/impl/prev.ts +1 -0
  171. package/src/3_3_1/impl/scroll-controller.ts +21 -0
  172. package/src/3_3_1/index.ts +1 -0
  173. package/src/3_3_1/options.ts +177 -0
  174. package/src/3_3_2.ts +14 -0
  175. package/src/base/device-message.ts +50 -1
  176. package/src/base/options.ts +3 -8
  177. package/src/control/message-type-map.ts +3 -3
  178. package/src/index.ts +3 -0
  179. package/src/latest.ts +5 -5
  180. package/tsconfig.build.tsbuildinfo +1 -1
@@ -0,0 +1,177 @@
1
+ import type { MaybePromiseLike } from "@yume-chan/async";
2
+ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
3
+
4
+ import type {
5
+ ScrcpyAudioStreamMetadata,
6
+ ScrcpyControlMessageType,
7
+ ScrcpyDisplay,
8
+ ScrcpyEncoder,
9
+ ScrcpyMediaStreamPacket,
10
+ ScrcpyOptions,
11
+ ScrcpyOptionsListEncoders,
12
+ ScrcpyScrollController,
13
+ ScrcpyVideoStream,
14
+ } from "../base/index.js";
15
+ import { ScrcpyDeviceMessageParsers } from "../base/index.js";
16
+ import type {
17
+ ScrcpyBackOrScreenOnControlMessage,
18
+ ScrcpyInjectTouchControlMessage,
19
+ ScrcpySetClipboardControlMessage,
20
+ ScrcpyUHidCreateControlMessage,
21
+ ScrcpyUHidOutputDeviceMessage,
22
+ } from "../latest.js";
23
+
24
+ import type { Init } from "./impl/index.js";
25
+ import {
26
+ AckClipboardHandler,
27
+ ClipboardStream,
28
+ ControlMessageTypes,
29
+ createMediaStreamTransformer,
30
+ createScrollController,
31
+ Defaults,
32
+ parseAudioStreamMetadata,
33
+ parseDisplay,
34
+ parseEncoder,
35
+ parseVideoStreamMetadata,
36
+ serialize,
37
+ serializeBackOrScreenOnControlMessage,
38
+ serializeInjectTouchControlMessage,
39
+ serializeUHidCreateControlMessage,
40
+ setListDisplays,
41
+ setListEncoders,
42
+ UHidOutputStream,
43
+ } from "./impl/index.js";
44
+
45
+ export class ScrcpyOptions3_3_1<TVideo extends boolean>
46
+ implements ScrcpyOptions<Init<TVideo>>, ScrcpyOptionsListEncoders
47
+ {
48
+ static readonly Defaults = Defaults;
49
+
50
+ readonly value: Required<Init<TVideo>>;
51
+
52
+ get controlMessageTypes(): readonly ScrcpyControlMessageType[] {
53
+ return ControlMessageTypes;
54
+ }
55
+
56
+ #clipboard: ClipboardStream | undefined;
57
+ get clipboard(): ReadableStream<string> | undefined {
58
+ return this.#clipboard;
59
+ }
60
+
61
+ #ackClipboardHandler: AckClipboardHandler | undefined;
62
+
63
+ #uHidOutput: UHidOutputStream | undefined;
64
+ get uHidOutput():
65
+ | ReadableStream<ScrcpyUHidOutputDeviceMessage>
66
+ | undefined {
67
+ return this.#uHidOutput;
68
+ }
69
+
70
+ #deviceMessageParsers = new ScrcpyDeviceMessageParsers();
71
+ get deviceMessageParsers() {
72
+ return this.#deviceMessageParsers;
73
+ }
74
+
75
+ constructor(init: Init<TVideo>) {
76
+ this.value = { ...Defaults, ...init } as never;
77
+
78
+ if (this.value.videoSource === "camera") {
79
+ this.value.control = false;
80
+ }
81
+
82
+ if (this.value.audioDup) {
83
+ this.value.audioSource = "playback";
84
+ }
85
+
86
+ if (this.value.control) {
87
+ if (this.value.clipboardAutosync) {
88
+ this.#clipboard = this.#deviceMessageParsers.add(
89
+ new ClipboardStream(),
90
+ );
91
+
92
+ this.#ackClipboardHandler = this.#deviceMessageParsers.add(
93
+ new AckClipboardHandler(),
94
+ );
95
+ }
96
+
97
+ this.#uHidOutput = this.#deviceMessageParsers.add(
98
+ new UHidOutputStream(),
99
+ );
100
+ }
101
+ }
102
+
103
+ serialize(): string[] {
104
+ return serialize<Init<boolean>>(this.value, Defaults);
105
+ }
106
+
107
+ setListDisplays(): void {
108
+ setListDisplays(this.value);
109
+ }
110
+
111
+ parseDisplay(line: string): ScrcpyDisplay | undefined {
112
+ return parseDisplay(line);
113
+ }
114
+
115
+ setListEncoders() {
116
+ setListEncoders(this.value);
117
+ }
118
+
119
+ parseEncoder(line: string): ScrcpyEncoder | undefined {
120
+ return parseEncoder(line);
121
+ }
122
+
123
+ parseVideoStreamMetadata(
124
+ stream: ReadableStream<Uint8Array>,
125
+ ): MaybePromiseLike<ScrcpyVideoStream> {
126
+ return parseVideoStreamMetadata(this.value, stream);
127
+ }
128
+
129
+ parseAudioStreamMetadata(
130
+ stream: ReadableStream<Uint8Array>,
131
+ ): MaybePromiseLike<ScrcpyAudioStreamMetadata> {
132
+ return parseAudioStreamMetadata(stream, this.value);
133
+ }
134
+
135
+ createMediaStreamTransformer(): TransformStream<
136
+ Uint8Array,
137
+ ScrcpyMediaStreamPacket
138
+ > {
139
+ return createMediaStreamTransformer(this.value);
140
+ }
141
+
142
+ serializeInjectTouchControlMessage(
143
+ message: ScrcpyInjectTouchControlMessage,
144
+ ): Uint8Array {
145
+ return serializeInjectTouchControlMessage(message);
146
+ }
147
+
148
+ serializeBackOrScreenOnControlMessage(
149
+ message: ScrcpyBackOrScreenOnControlMessage,
150
+ ): Uint8Array | undefined {
151
+ return serializeBackOrScreenOnControlMessage(message);
152
+ }
153
+
154
+ serializeSetClipboardControlMessage(
155
+ message: ScrcpySetClipboardControlMessage,
156
+ ): Uint8Array | [Uint8Array, Promise<void>] {
157
+ return this.#ackClipboardHandler!.serializeSetClipboardControlMessage(
158
+ message,
159
+ );
160
+ }
161
+
162
+ createScrollController(): ScrcpyScrollController {
163
+ return createScrollController();
164
+ }
165
+
166
+ serializeUHidCreateControlMessage(
167
+ message: ScrcpyUHidCreateControlMessage,
168
+ ): Uint8Array {
169
+ return serializeUHidCreateControlMessage(message);
170
+ }
171
+ }
172
+
173
+ type Init_<TVideo extends boolean> = Init<TVideo>;
174
+
175
+ export namespace ScrcpyOptions3_3_1 {
176
+ export type Init<TVideo extends boolean = boolean> = Init_<TVideo>;
177
+ }
package/src/3_3_2.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { ScrcpyOptions3_3_1 } from "./3_3_1/index.js";
2
+
3
+ export class ScrcpyOptions3_3_2<
4
+ TVideo extends boolean,
5
+ > extends ScrcpyOptions3_3_1<TVideo> {
6
+ constructor(init: ScrcpyOptions3_3_1.Init<TVideo>) {
7
+ super(init);
8
+ }
9
+ }
10
+
11
+ export namespace ScrcpyOptions3_3_2 {
12
+ export type Init<TVideo extends boolean = boolean> =
13
+ ScrcpyOptions3_3_1.Init<TVideo>;
14
+ }
@@ -1,9 +1,58 @@
1
1
  import type { AsyncExactReadable } from "@yume-chan/struct";
2
2
 
3
3
  export interface ScrcpyDeviceMessageParser {
4
- parse(id: number, stream: AsyncExactReadable): Promise<boolean>;
4
+ readonly id: number | readonly number[];
5
+
6
+ parse(id: number, stream: AsyncExactReadable): Promise<undefined>;
5
7
 
6
8
  close(): void;
7
9
 
8
10
  error(e?: unknown): void;
9
11
  }
12
+
13
+ export class ScrcpyDeviceMessageParsers {
14
+ #parsers: ScrcpyDeviceMessageParser[] = [];
15
+ get parsers(): readonly ScrcpyDeviceMessageParser[] {
16
+ return this.#parsers;
17
+ }
18
+
19
+ #add(id: number, parser: ScrcpyDeviceMessageParser) {
20
+ if (this.#parsers[id]) {
21
+ throw new Error(`Duplicate parser for id ${id}`);
22
+ }
23
+ this.#parsers[id] = parser;
24
+ }
25
+
26
+ add<T extends ScrcpyDeviceMessageParser>(parser: T): T {
27
+ if (Array.isArray(parser.id)) {
28
+ for (const id of parser.id) {
29
+ this.#add(id as number, parser);
30
+ }
31
+ } else {
32
+ this.#add(parser.id as number, parser);
33
+ }
34
+
35
+ return parser;
36
+ }
37
+
38
+ async parse(id: number, stream: AsyncExactReadable): Promise<undefined> {
39
+ const parser = this.#parsers[id];
40
+ if (!parser) {
41
+ throw new Error(`Unknown device message id ${id}`);
42
+ }
43
+
44
+ return parser.parse(id, stream);
45
+ }
46
+
47
+ close() {
48
+ for (const parser of this.#parsers) {
49
+ parser.close();
50
+ }
51
+ }
52
+
53
+ error(e?: unknown) {
54
+ for (const parser of this.#parsers) {
55
+ parser.error(e);
56
+ }
57
+ }
58
+ }
@@ -1,6 +1,5 @@
1
1
  import type { MaybePromiseLike } from "@yume-chan/async";
2
2
  import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
3
- import type { AsyncExactReadable, ExactReadable } from "@yume-chan/struct";
4
3
 
5
4
  import type {
6
5
  ScrcpyBackOrScreenOnControlMessage,
@@ -12,6 +11,7 @@ import type {
12
11
 
13
12
  import type { ScrcpyAudioStreamMetadata } from "./audio.js";
14
13
  import type { ScrcpyControlMessageType } from "./control-message-type.js";
14
+ import type { ScrcpyDeviceMessageParsers } from "./device-message.js";
15
15
  import type { ScrcpyDisplay } from "./display.js";
16
16
  import type { ScrcpyEncoder } from "./encoder.js";
17
17
  import type { ScrcpyMediaStreamPacket } from "./media.js";
@@ -29,6 +29,8 @@ export interface ScrcpyOptions<T extends object> {
29
29
  | ReadableStream<ScrcpyUHidOutputDeviceMessage>
30
30
  | undefined;
31
31
 
32
+ readonly deviceMessageParsers: ScrcpyDeviceMessageParsers;
33
+
32
34
  serialize(): string[];
33
35
 
34
36
  setListDisplays(): void;
@@ -43,13 +45,6 @@ export interface ScrcpyOptions<T extends object> {
43
45
  stream: ReadableStream<Uint8Array>,
44
46
  ): MaybePromiseLike<ScrcpyAudioStreamMetadata>;
45
47
 
46
- parseDeviceMessage(
47
- id: number,
48
- stream: ExactReadable | AsyncExactReadable,
49
- ): Promise<void>;
50
-
51
- endDeviceMessageStream(e?: unknown): void;
52
-
53
48
  createMediaStreamTransformer(): TransformStream<
54
49
  Uint8Array,
55
50
  ScrcpyMediaStreamPacket
@@ -20,11 +20,11 @@ export class ScrcpyControlMessageTypeMap {
20
20
  return value;
21
21
  }
22
22
 
23
- fillMessageType<T extends { type: ScrcpyControlMessageType }>(
23
+ fillMessageType<T extends { type: number }>(
24
24
  message: Omit<T, "type">,
25
- type: T["type"],
25
+ type: ScrcpyControlMessageType,
26
26
  ): T {
27
- (message as T).type = this.get(type) as ScrcpyControlMessageType;
27
+ (message as T).type = this.get(type);
28
28
  return message as T;
29
29
  }
30
30
  }
package/src/index.ts CHANGED
@@ -26,6 +26,9 @@ export * from "./3_0_1.js";
26
26
  export * from "./3_0_2.js";
27
27
  export * from "./3_1/index.js";
28
28
  export * from "./3_2/index.js";
29
+ export * from "./3_3.js";
30
+ export * from "./3_3_1/index.js";
31
+ export * from "./3_3_2.js";
29
32
  export * from "./android/index.js";
30
33
  export * from "./base/index.js";
31
34
  export * from "./codec/index.js";
package/src/latest.ts CHANGED
@@ -1,16 +1,16 @@
1
- import { ScrcpyOptions3_2 } from "./3_2/options.js";
1
+ import { ScrcpyOptions3_3_2 } from "./3_3_2.js";
2
2
 
3
3
  export class ScrcpyOptionsLatest<
4
4
  TVideo extends boolean,
5
- > extends ScrcpyOptions3_2<TVideo> {
6
- constructor(init: ScrcpyOptions3_2.Init<TVideo>) {
5
+ > extends ScrcpyOptions3_3_2<TVideo> {
6
+ constructor(init: ScrcpyOptions3_3_2.Init<TVideo>) {
7
7
  super(init);
8
8
  }
9
9
  }
10
10
 
11
11
  export namespace ScrcpyOptionsLatest {
12
12
  export type Init<TVideo extends boolean = boolean> =
13
- ScrcpyOptions3_2.Init<TVideo>;
13
+ ScrcpyOptions3_3_2.Init<TVideo>;
14
14
  }
15
15
 
16
16
  export {
@@ -28,4 +28,4 @@ export {
28
28
  SetClipboardControlMessage as ScrcpySetClipboardControlMessage,
29
29
  UHidCreateControlMessage as ScrcpyUHidCreateControlMessage,
30
30
  UHidOutputDeviceMessage as ScrcpyUHidOutputDeviceMessage,
31
- } from "./3_2/impl/index.js";
31
+ } from "./3_3_1/impl/index.js";