@yume-chan/adb 0.0.19 → 0.0.20

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 (181) hide show
  1. package/CHANGELOG.json +33 -0
  2. package/CHANGELOG.md +15 -1
  3. package/README.md +220 -103
  4. package/esm/adb.d.ts +24 -44
  5. package/esm/adb.d.ts.map +1 -1
  6. package/esm/adb.js +14 -203
  7. package/esm/adb.js.map +1 -1
  8. package/esm/banner.d.ts +17 -0
  9. package/esm/banner.d.ts.map +1 -0
  10. package/esm/banner.js +67 -0
  11. package/esm/banner.js.map +1 -0
  12. package/esm/commands/power.d.ts +1 -1
  13. package/esm/commands/power.js +2 -2
  14. package/esm/commands/reverse.d.ts +17 -18
  15. package/esm/commands/reverse.d.ts.map +1 -1
  16. package/esm/commands/reverse.js +53 -48
  17. package/esm/commands/reverse.js.map +1 -1
  18. package/esm/commands/subprocess/protocols/none.d.ts +3 -8
  19. package/esm/commands/subprocess/protocols/none.d.ts.map +1 -1
  20. package/esm/commands/subprocess/protocols/none.js +16 -16
  21. package/esm/commands/subprocess/protocols/none.js.map +1 -1
  22. package/esm/commands/subprocess/protocols/shell.d.ts +3 -9
  23. package/esm/commands/subprocess/protocols/shell.d.ts.map +1 -1
  24. package/esm/commands/subprocess/protocols/shell.js +48 -42
  25. package/esm/commands/subprocess/protocols/shell.js.map +1 -1
  26. package/esm/commands/subprocess/protocols/types.d.ts +1 -2
  27. package/esm/commands/subprocess/protocols/types.d.ts.map +1 -1
  28. package/esm/commands/sync/list.js +2 -2
  29. package/esm/commands/sync/push.d.ts +14 -3
  30. package/esm/commands/sync/push.d.ts.map +1 -1
  31. package/esm/commands/sync/push.js +8 -8
  32. package/esm/commands/sync/push.js.map +1 -1
  33. package/esm/commands/sync/request.js +1 -1
  34. package/esm/commands/sync/response.d.ts +3 -3
  35. package/esm/commands/sync/response.d.ts.map +1 -1
  36. package/esm/commands/sync/response.js +3 -3
  37. package/esm/commands/sync/response.js.map +1 -1
  38. package/esm/commands/sync/socket.d.ts +8 -13
  39. package/esm/commands/sync/socket.d.ts.map +1 -1
  40. package/esm/commands/sync/socket.js +32 -29
  41. package/esm/commands/sync/socket.js.map +1 -1
  42. package/esm/commands/sync/stat.js +2 -2
  43. package/esm/commands/sync/stat.js.map +1 -1
  44. package/esm/commands/sync/sync.d.ts +11 -18
  45. package/esm/commands/sync/sync.d.ts.map +1 -1
  46. package/esm/commands/sync/sync.js +19 -23
  47. package/esm/commands/sync/sync.js.map +1 -1
  48. package/esm/commands/tcpip.d.ts +2 -2
  49. package/esm/commands/tcpip.d.ts.map +1 -1
  50. package/esm/commands/tcpip.js +4 -2
  51. package/esm/commands/tcpip.js.map +1 -1
  52. package/esm/{auth.d.ts → daemon/auth.d.ts} +1 -2
  53. package/esm/daemon/auth.d.ts.map +1 -0
  54. package/esm/{auth.js → daemon/auth.js} +14 -14
  55. package/esm/daemon/auth.js.map +1 -0
  56. package/esm/daemon/connection.d.ts +11 -0
  57. package/esm/daemon/connection.d.ts.map +1 -0
  58. package/esm/daemon/connection.js +2 -0
  59. package/esm/daemon/connection.js.map +1 -0
  60. package/esm/{crypto.d.ts → daemon/crypto.d.ts} +5 -5
  61. package/esm/daemon/crypto.d.ts.map +1 -0
  62. package/esm/{crypto.js → daemon/crypto.js} +23 -27
  63. package/esm/daemon/crypto.js.map +1 -0
  64. package/esm/{backend.d.ts → daemon/device.d.ts} +2 -2
  65. package/esm/daemon/device.d.ts.map +1 -0
  66. package/esm/daemon/device.js +2 -0
  67. package/esm/daemon/device.js.map +1 -0
  68. package/esm/{socket → daemon}/dispatcher.d.ts +8 -26
  69. package/esm/daemon/dispatcher.d.ts.map +1 -0
  70. package/esm/{socket → daemon}/dispatcher.js +65 -63
  71. package/esm/daemon/dispatcher.js.map +1 -0
  72. package/esm/daemon/index.d.ts +8 -0
  73. package/esm/daemon/index.d.ts.map +1 -0
  74. package/esm/daemon/index.js +8 -0
  75. package/esm/daemon/index.js.map +1 -0
  76. package/esm/{packet.d.ts → daemon/packet.d.ts} +4 -4
  77. package/esm/daemon/packet.d.ts.map +1 -0
  78. package/esm/{packet.js → daemon/packet.js} +1 -1
  79. package/esm/daemon/packet.js.map +1 -0
  80. package/esm/{socket → daemon}/socket.d.ts +15 -17
  81. package/esm/daemon/socket.d.ts.map +1 -0
  82. package/esm/{socket → daemon}/socket.js +38 -35
  83. package/esm/daemon/socket.js.map +1 -0
  84. package/esm/daemon/transport.d.ts +45 -0
  85. package/esm/daemon/transport.d.ts.map +1 -0
  86. package/esm/daemon/transport.js +184 -0
  87. package/esm/daemon/transport.js.map +1 -0
  88. package/esm/index.d.ts +3 -5
  89. package/esm/index.d.ts.map +1 -1
  90. package/esm/index.js +3 -5
  91. package/esm/index.js.map +1 -1
  92. package/esm/server/client.d.ts +78 -0
  93. package/esm/server/client.d.ts.map +1 -0
  94. package/esm/server/client.js +329 -0
  95. package/esm/server/client.js.map +1 -0
  96. package/esm/server/index.d.ts +3 -0
  97. package/esm/server/index.d.ts.map +1 -0
  98. package/esm/server/index.js +3 -0
  99. package/esm/server/index.js.map +1 -0
  100. package/esm/server/transport.d.ts +19 -0
  101. package/esm/server/transport.d.ts.map +1 -0
  102. package/esm/server/transport.js +44 -0
  103. package/esm/server/transport.js.map +1 -0
  104. package/esm/utils/auto-reset-event.d.ts +1 -2
  105. package/esm/utils/auto-reset-event.d.ts.map +1 -1
  106. package/esm/utils/auto-reset-event.js +12 -12
  107. package/esm/utils/auto-reset-event.js.map +1 -1
  108. package/esm/utils/base64.js +5 -5
  109. package/esm/utils/base64.js.map +1 -1
  110. package/esm/utils/conditional-variable.d.ts +1 -2
  111. package/esm/utils/conditional-variable.d.ts.map +1 -1
  112. package/esm/utils/conditional-variable.js +10 -10
  113. package/esm/utils/conditional-variable.js.map +1 -1
  114. package/esm/utils/hex.d.ts +3 -0
  115. package/esm/utils/hex.d.ts.map +1 -0
  116. package/esm/utils/hex.js +55 -0
  117. package/esm/utils/hex.js.map +1 -0
  118. package/esm/utils/index.d.ts +2 -0
  119. package/esm/utils/index.d.ts.map +1 -1
  120. package/esm/utils/index.js +2 -0
  121. package/esm/utils/index.js.map +1 -1
  122. package/esm/utils/no-op.d.ts +7 -0
  123. package/esm/utils/no-op.d.ts.map +1 -0
  124. package/esm/utils/no-op.js +12 -0
  125. package/esm/utils/no-op.js.map +1 -0
  126. package/package.json +11 -10
  127. package/src/adb.ts +41 -252
  128. package/src/banner.ts +82 -0
  129. package/src/commands/power.ts +2 -2
  130. package/src/commands/reverse.ts +68 -73
  131. package/src/commands/subprocess/protocols/none.ts +17 -18
  132. package/src/commands/subprocess/protocols/shell.ts +54 -56
  133. package/src/commands/subprocess/protocols/types.ts +1 -2
  134. package/src/commands/sync/list.ts +2 -2
  135. package/src/commands/sync/push.ts +22 -10
  136. package/src/commands/sync/request.ts +1 -1
  137. package/src/commands/sync/response.ts +6 -6
  138. package/src/commands/sync/socket.ts +37 -35
  139. package/src/commands/sync/sync.ts +25 -28
  140. package/src/commands/tcpip.ts +6 -4
  141. package/src/{auth.ts → daemon/auth.ts} +17 -17
  142. package/src/{crypto.ts → daemon/crypto.ts} +25 -33
  143. package/src/{backend.ts → daemon/device.ts} +1 -1
  144. package/src/{socket → daemon}/dispatcher.ts +71 -78
  145. package/src/daemon/index.ts +7 -0
  146. package/src/{packet.ts → daemon/packet.ts} +5 -5
  147. package/src/{socket → daemon}/socket.ts +50 -44
  148. package/src/daemon/transport.ts +269 -0
  149. package/src/index.ts +3 -5
  150. package/src/server/client.ts +476 -0
  151. package/src/server/index.ts +2 -0
  152. package/src/server/transport.ts +77 -0
  153. package/src/utils/auto-reset-event.ts +12 -12
  154. package/src/utils/conditional-variable.ts +10 -10
  155. package/src/utils/hex.ts +58 -0
  156. package/src/utils/index.ts +2 -0
  157. package/src/utils/no-op.ts +12 -0
  158. package/tsconfig.build.json +12 -1
  159. package/tsconfig.build.tsbuildinfo +1 -1
  160. package/esm/auth.d.ts.map +0 -1
  161. package/esm/auth.js.map +0 -1
  162. package/esm/backend.d.ts.map +0 -1
  163. package/esm/backend.js +0 -2
  164. package/esm/backend.js.map +0 -1
  165. package/esm/commands/install.d.ts +0 -10
  166. package/esm/commands/install.d.ts.map +0 -1
  167. package/esm/commands/install.js +0 -29
  168. package/esm/commands/install.js.map +0 -1
  169. package/esm/crypto.d.ts.map +0 -1
  170. package/esm/crypto.js.map +0 -1
  171. package/esm/packet.d.ts.map +0 -1
  172. package/esm/packet.js.map +0 -1
  173. package/esm/socket/dispatcher.d.ts.map +0 -1
  174. package/esm/socket/dispatcher.js.map +0 -1
  175. package/esm/socket/index.d.ts +0 -3
  176. package/esm/socket/index.d.ts.map +0 -1
  177. package/esm/socket/index.js +0 -3
  178. package/esm/socket/index.js.map +0 -1
  179. package/esm/socket/socket.d.ts.map +0 -1
  180. package/esm/socket/socket.js.map +0 -1
  181. package/src/socket/index.ts +0 -2
package/CHANGELOG.json CHANGED
@@ -1,6 +1,39 @@
1
1
  {
2
2
  "name": "@yume-chan/adb",
3
3
  "entries": [
4
+ {
5
+ "version": "0.0.20",
6
+ "tag": "@yume-chan/adb_v0.0.20",
7
+ "date": "Mon, 05 Jun 2023 02:51:41 GMT",
8
+ "comments": {
9
+ "none": [
10
+ {
11
+ "comment": "Use ECMAScript private class fields syntax (supported by Chrome 74, Firefox 90, Safari 14.1 and Node.js 12.0.0)."
12
+ },
13
+ {
14
+ "comment": "Refactor `AdbSubprocessShellProtocol` class, this should improve some performance."
15
+ },
16
+ {
17
+ "comment": "Split `mode` parameter in `AdbSync#write()` into `type` and `permission` for ease of use."
18
+ },
19
+ {
20
+ "comment": "Add `AdbReverseCommand#addExternal()`. This only register the reverse tunnel to the device, the handler should already exists (for example you are adding a reverse tunnel for an external program that's already listening on the port). In ADB direct connection, this should do nothing, because the reverse tunnel is handled by this library and there is no mean of \"external\" handler."
21
+ },
22
+ {
23
+ "comment": "Change `AdbTcpIpCommand#setPort` and `AdbTcpIpCommand#disable` to return or throw the response text. This can be displayed to the user to know what's wrong."
24
+ },
25
+ {
26
+ "comment": "Add support for connecting to ADB servers. Because a USB device can only be used by one process at a time, the ADB server is the process that manages all connected devices. The server proxies and multiplexes connections from ADB clients so multiple adb commands can be executed on one device at the same time. The `Adb` class is no longer responsible for connecting and authenticating with ADB daemons. The `AdbTransport` interface and its two implementations `AdbDaemonTransport` and `AdbServerTransport` was added to connect to either ADB daemons or servers in compatible environments. Read the PR for details, migration paths, and examples. ([#549](https://github.com/yume-chan/ya-webadb/pull/549))"
27
+ },
28
+ {
29
+ "comment": "Add `serial` field to `Adb` class."
30
+ },
31
+ {
32
+ "comment": "Group `product`, `model`, `device` and `features` fields on `Adb` class to the `banner` field with type of `AdbBanner`."
33
+ }
34
+ ]
35
+ }
36
+ },
4
37
  {
5
38
  "version": "0.0.19",
6
39
  "tag": "@yume-chan/adb_v0.0.19",
package/CHANGELOG.md CHANGED
@@ -1,6 +1,20 @@
1
1
  # Change Log - @yume-chan/adb
2
2
 
3
- This log was last generated on Sun, 09 Apr 2023 05:55:33 GMT and should not be manually modified.
3
+ This log was last generated on Mon, 05 Jun 2023 02:51:41 GMT and should not be manually modified.
4
+
5
+ ## 0.0.20
6
+ Mon, 05 Jun 2023 02:51:41 GMT
7
+
8
+ ### Updates
9
+
10
+ - Use ECMAScript private class fields syntax (supported by Chrome 74, Firefox 90, Safari 14.1 and Node.js 12.0.0).
11
+ - Refactor `AdbSubprocessShellProtocol` class, this should improve some performance.
12
+ - Split `mode` parameter in `AdbSync#write()` into `type` and `permission` for ease of use.
13
+ - Add `AdbReverseCommand#addExternal()`. This only register the reverse tunnel to the device, the handler should already exists (for example you are adding a reverse tunnel for an external program that's already listening on the port). In ADB direct connection, this should do nothing, because the reverse tunnel is handled by this library and there is no mean of "external" handler.
14
+ - Change `AdbTcpIpCommand#setPort` and `AdbTcpIpCommand#disable` to return or throw the response text. This can be displayed to the user to know what's wrong.
15
+ - Add support for connecting to ADB servers. Because a USB device can only be used by one process at a time, the ADB server is the process that manages all connected devices. The server proxies and multiplexes connections from ADB clients so multiple adb commands can be executed on one device at the same time. The `Adb` class is no longer responsible for connecting and authenticating with ADB daemons. The `AdbTransport` interface and its two implementations `AdbDaemonTransport` and `AdbServerTransport` was added to connect to either ADB daemons or servers in compatible environments. Read the PR for details, migration paths, and examples. ([#549](https://github.com/yume-chan/ya-webadb/pull/549))
16
+ - Add `serial` field to `Adb` class.
17
+ - Group `product`, `model`, `device` and `features` fields on `Adb` class to the `banner` field with type of `AdbBanner`.
4
18
 
5
19
  ## 0.0.19
6
20
  Sun, 09 Apr 2023 05:55:33 GMT
package/README.md CHANGED
@@ -2,39 +2,41 @@
2
2
 
3
3
  TypeScript implementation of Android Debug Bridge (ADB) protocol.
4
4
 
5
- **WARNING:** The public API is UNSTABLE. If you have any questions, please open an issue.
6
-
7
- - [Compatibility](#compatibility)
8
- - [Basic usage](#basic-usage)
9
- - [Use without bundlers](#use-without-bundlers)
10
- - [Connection](#connection)
11
- - [Backend](#backend)
12
- - [`connect`](#connect)
13
- - [Authentication](#authentication)
14
- - [AdbCredentialStore](#adbcredentialstore)
15
- - [`generateKey`](#generatekey)
16
- - [`iterateKeys`](#iteratekeys)
17
- - [Implementations](#implementations)
18
- - [AdbAuthenticator](#adbauthenticator)
19
- - [`authenticate`](#authenticate)
20
- - [Stream multiplex](#stream-multiplex)
21
- - [Commands](#commands)
22
- - [subprocess](#subprocess)
23
- - [raw mode](#raw-mode)
24
- - [pty mode](#pty-mode)
25
- - [usb](#usb)
26
- - [tcpip](#tcpip)
27
- - [sync](#sync)
28
- - [LIST](#list)
29
- - [LIS2](#lis2)
30
- - [STAT](#stat)
31
- - [LST2](#lst2)
32
- - [STA2](#sta2)
33
- - [RECV](#recv)
34
- - [RCV2](#rcv2)
35
- - [SEND](#send)
36
- - [SND2](#snd2)
37
- - [Useful links](#useful-links)
5
+ **WARNING:** The public API is UNSTABLE. Open a GitHub discussion if you have any questions.
6
+
7
+ - [Compatibility](#compatibility)
8
+ - [Basic usage](#basic-usage)
9
+ - [Use without bundlers](#use-without-bundlers)
10
+ - [Transport](#transport)
11
+ - [`AdbDaemonTransport`](#adbdaemontransport)
12
+ - [`AdbCredentialStore`](#adbcredentialstore)
13
+ - [`generateKey`](#generatekey)
14
+ - [`iterateKeys`](#iteratekeys)
15
+ - [`AdbAuthenticator`](#adbauthenticator)
16
+ - [`authenticate`](#authenticate)
17
+ - [`addReverseTunnel`](#addreversetunnel)
18
+ - [`AdbServerTransport`](#adbservertransport)
19
+ - [`AdbServerClient`](#adbserverclient)
20
+ - [`getVersion`](#getversion)
21
+ - [`kill`](#kill)
22
+ - [`getServerFeatures`](#getserverfeatures)
23
+ - [`getDevices`](#getdevices)
24
+ - [`AdbServerDeviceSelector`](#adbserverdeviceselector)
25
+ - [`getDeviceFeatures`](#getdevicefeatures)
26
+ - [`waitFor`](#waitfor)
27
+ - [Commands](#commands)
28
+ - [subprocess](#subprocess)
29
+ - [raw mode](#raw-mode)
30
+ - [pty mode](#pty-mode)
31
+ - [usb](#usb)
32
+ - [tcpip](#tcpip)
33
+ - [sync](#sync)
34
+ - [`lstat`](#lstat)
35
+ - [`stat`](#stat)
36
+ - [`isDirectory`](#isdirectory)
37
+ - [`opendir`](#opendir)
38
+ - [`readdir`](#readdir)
39
+ - [Useful links](#useful-links)
38
40
 
39
41
  ## Compatibility
40
42
 
@@ -42,52 +44,56 @@ Here is a list of features, their used APIs, and their compatibilities. If an op
42
44
 
43
45
  Some features can be polyfilled to support older runtimes, but this library doesn't ship with any polyfills.
44
46
 
45
- Each backend may have different requirements.
47
+ Each transport and connection may have different requirements.
46
48
 
47
49
  ### Basic usage
48
50
 
49
- | | Chrome | Edge | Firefox | Internet Explorer | Safari | Node.js |
50
- | ------------------------------- | ------ | ---- | ------- | ----------------- | ------ | ------------------- |
51
- | `@yume-chan/struct`<sup>1</sup> | 67 | 79 | 68 | No | 14 | 8.3<sup>2</sup>, 11 |
52
- | *Overall* | 67 | 79 | No | No | 14.1 | 16.5 |
51
+ | | Chrome | Edge | Firefox | Internet Explorer | Safari | Node.js |
52
+ | -------------------------------- | ------ | ---- | ------- | ----------------- | ------ | ------------------- |
53
+ | `@yume-chan/struct`<sup>1</sup> | 67 | 79 | 68 | No | 14 | 8.3<sup>2</sup>, 11 |
54
+ | Private class fields<sup>3</sup> | 74 | 79 | 90 | No | 14.1 | 12.0.0 |
55
+ | _Overall_ | 74 | 79 | 90 | No | 14.1 | 16.5 |
53
56
 
54
57
  <sup>1</sup> `uint64` and `string` are used.
55
58
 
56
59
  <sup>2</sup> `TextEncoder` and `TextDecoder` are only available in `util` module. Need to be assigned to `globalThis`.
57
60
 
61
+ <sup>3</sup> Can be down-level compiled using Babel.
62
+
58
63
  ### Use without bundlers
59
64
 
60
65
  | | Chrome | Edge | Firefox | Internet Explorer | Safari | Node.js |
61
66
  | --------------- | ------ | ---- | ------- | ----------------- | ------ | ------- |
62
67
  | Top-level await | 89 | 89 | 89 | No | 15 | 14.8 |
63
68
 
64
- ## Connection
69
+ ## Transport
65
70
 
66
71
  This library doesn't tie to a specific transportation method.
67
72
 
68
- Instead, a `Backend` is responsible for transferring data in its own way (USB, WebSocket, TCP, etc).
73
+ Instead, an implementation of the `AdbTransport` interface is responsible for creating ADB sockets when requested. Each implementation might have different methods to discover, connect and authenticate devices.
69
74
 
70
- ### Backend
75
+ ### `AdbDaemonTransport`
71
76
 
72
- #### `connect`
77
+ `AdbDaemonTransport` connects to an ADB daemon directly.
73
78
 
74
- ```ts
75
- connect(): ValueOrPromise<ReadableWritablePair<AdbPacketCore, AdbPacketInit>>
76
- ```
79
+ It requires a `ReadableWritablePair<AdbPacketData, Consumable<AdbPacketInit>>` to send and receive ADB packets to the daemon.
77
80
 
78
- Connect to a device and create a pair of `AdbPacket` streams.
81
+ Usually an implementation of `AdbDaemonConnection` will provide that along with other useful information about the device. Possible implementations includes:
79
82
 
80
- The backend, instead of the core library, is responsible for serializing and deserializing the packets. Because it's extreme slow for WebUSB backend (`@yume-chan/adb-backend-webusb`) to read packets with unknown size.
83
+ - WebUSB API
84
+ - `usb` package for Node.js
85
+ - Node.js' `net` module (for ADB over WiFi)
86
+ - Though a WebSockify wrapper (also for ADB over WiFi).
81
87
 
82
- ## Authentication
88
+ ADB daemon requires authentication unless built in debug mode. For how ADB authentication work, see https://chensi.moe/blog/2020/09/30/webadb-part2-connection/#auth.
83
89
 
84
- For how does ADB authentication work, see https://chensi.moe/blog/2020/09/30/webadb-part2-connection/#auth.
90
+ Authentication requires two extra components:
85
91
 
86
- In this library, authentication comes in two parts:
92
+ #### `AdbCredentialStore`
87
93
 
88
- #### AdbCredentialStore
94
+ An interface to generate, store and iterate ADB private keys on each runtime. (Because Node.js and Browsers have different APIs to do that)
89
95
 
90
- An interface to generate, store and iterate ADB private keys on each runtime. (Because Node.js and Browsers have different APIs to do this)
96
+ The `@yume-chan/adb-credential-web` package contains a `AdbWebCredentialStore` implementation using Web Crypto API for generating keys and IndexedDB for storing keys.
91
97
 
92
98
  ##### `generateKey`
93
99
 
@@ -109,48 +115,128 @@ Synchronously or asynchronously iterate through all stored RSA private keys.
109
115
 
110
116
  Each call to `iterateKeys` must return a different iterator that iterate through all stored keys.
111
117
 
112
- ##### Implementations
113
-
114
- The `@yume-chan/adb-credential-web` package contains a `AdbWebCredentialStore` implementation using Web Crypto API for generating keys and Web Storage API for storing keys.
115
-
116
- #### AdbAuthenticator
118
+ #### `AdbAuthenticator`
117
119
 
118
120
  An `AdbAuthenticator` generates `AUTH` responses for each `AUTH` request from server.
119
121
 
120
- This package contains `AdbSignatureAuthenticator` and `AdbPublicKeyAuthenticator`, the two basic modes.
122
+ This package contains `AdbSignatureAuthenticator` and `AdbPublicKeyAuthenticator` classes for the two basic modes, they all uses the `AdbCredentialStore` to get the private key.
121
123
 
122
124
  #### `authenticate`
123
125
 
124
126
  ```ts
125
- static async authenticate(
127
+ static async authenticate(options: {
126
128
  connection: ReadableWritablePair<AdbPacketCore, AdbPacketCore>,
127
129
  credentialStore: AdbCredentialStore,
128
- authenticators = AdbDefaultAuthenticators,
129
- ): Promise<Adb>
130
+ authenticators?: AdbAuthenticator[],
131
+ }): Promise<AdbDaemonTransport>
132
+ ```
133
+
134
+ Authenticates the connection and creates an `AdbDaemonTransport` instance that can be used by `Adb` class.
135
+
136
+ If an authentication process failed, it's possible to call `authenticate` again on the same connection. Because every time the device receives a `CNXN` packet, it resets all internal state, and starts a new authentication process.
137
+
138
+ #### `addReverseTunnel`
139
+
140
+ ```ts
141
+ public addReverseTunnel(
142
+ handler: AdbIncomingSocketHandler,
143
+ address?: string
144
+ ): string
130
145
  ```
131
146
 
132
- Call this method to authenticate the connection and create an `Adb` instance.
147
+ Adds a reverse tunnel handler to the transport. It doesn't register the reverse tunnel to the device, for that use `AdbReverseCommand#add` instead. Because the process for ADB to create a tunnel is same as calling a command, `address` can be any string that the ADB daemon might call as a command.
148
+
149
+ ### `AdbServerTransport`
150
+
151
+ `AdbServerTransport` connects to an ADB server. Because a USB device can only be used by one process at a time, the ADB server is the process that manages all connected devices. The server proxies and multiplexes connections from ADB clients so multiple adb commands can be executed on one device at the same time. `AdbServerTransport` instances can be retrieved from `AdbServerClient` class.
152
+
153
+ #### `AdbServerClient`
133
154
 
134
- If an authentication process failed, it's possible to call `authenticate` again on the same connection (`AdbPacket` stream pair). Every time the device receives a `CNXN` packet, it resets all internal state, and starts a new authentication process.
155
+ The `AdbServerClient` class implements the client-server protocol to interact with the ADB server. It can query the list of connected devices, detect device connections and disconnections, and invoke other server commands.
156
+
157
+ It needs an implementation of `AdbServerConnection` interface to actually connects to the ADB server using each runtime's API.
158
+
159
+ ##### `getVersion`
160
+
161
+ ```ts
162
+ public async getVersion(): Promise<string>;
163
+ ```
164
+
165
+ Get the version number of the ADB server. This version is not related to the ADB server-daemon protocol version nor device Android version, it increases when a breaking change is introduced into the client-server protocol.
166
+
167
+ ##### `kill`
168
+
169
+ ```ts
170
+ public async kill(): Promise<void>;
171
+ ```
172
+
173
+ Kill the ADB server, for example if you want to connect to the ADB daemon directly over USB.
174
+
175
+ ##### `getServerFeatures`
176
+
177
+ ```ts
178
+ public async getServerFeatures(): Promise<AdbFeature[]>;
179
+ ```
180
+
181
+ Get the list of ADB features supported by the server.
182
+
183
+ Generally it's not that useful because most ADB commands only cares about what features the device supports.
184
+
185
+ ##### `getDevices`
186
+
187
+ ```ts
188
+ public async getDevices(): Promise<AdbServerTransport[]>;
189
+ ```
135
190
 
136
- ## Stream multiplex
191
+ Get the list of connected devices.
137
192
 
138
- ADB commands are all based on streams. Multiple streams can send and receive at the same time in one connection.
193
+ The returned `AdbServerTransport` instance can be supplied to `new Adb` to operate on that device.
139
194
 
140
- 1. Client sends an `OPEN` packet to create a stream.
141
- 2. Server responds with `OKAY` or `FAIL`.
142
- 3. Client and server read/write on the stream.
143
- 4. Client/server sends a `CLSE` to close the stream.
195
+ ##### `AdbServerDeviceSelector`
196
+
197
+ Some commands target a specific device. `AdbServerDeviceSelector` chooses a device from the list of connected devices.
198
+
199
+ It can be one of:
200
+
201
+ - `undefined`: any one device, will throw an error if there are multiple devices connected. Same as no argument are given to `adb` command.
202
+ - `{ serial: string }`: a device with the given serial number. Note that multiple devices can have the same serial number (if the manufacturer is lazy), usually it's enough to identify a device. Same as the `-s` argument for the `adb` command.
203
+ - `{ transportId: number }`: a device with the given transport ID. The transport ID is from the order devices connect. It can be obtained from `getDevices` method. Same as the `-t` argument for the `adb` command.
204
+ - `{ usb: true }`: any one USB device, will throw an error if there are multiple devices connected via USB. Same as the `-d` argument for the `adb` command.
205
+ - `{ emulator: true }`: any one TCP device (including emulators and devices connected via ADB over WiFi), will throw an error if there are multiple TCP devices. Same as the `-e` argument for the `adb` command. Same as the `-e` argument for the `adb` command.
206
+
207
+ The selector will be sent to ADB server and resolved there.
208
+
209
+ ##### `getDeviceFeatures`
210
+
211
+ ```ts
212
+ public async getDeviceFeatures(
213
+ device: AdbServerDeviceSelector
214
+ ): Promise<AdbFeature[]>
215
+ ```
216
+
217
+ Gets the list of ADB features supported by the device. `Adb` class requires this information to choose the correct commands to use.
218
+
219
+ ##### `waitFor`
220
+
221
+ ```ts
222
+ public async waitFor(
223
+ device: AdbServerDeviceSelector,
224
+ state: "device" | "disconnect",
225
+ signal?: AbortSignal
226
+ ): Promise<void>
227
+ ```
228
+
229
+ Wait for a specific device to be connected or disconnected. The `AdbServerTransport` instance uses this method to detect device disconnects.
144
230
 
145
231
  ## Commands
146
232
 
147
233
  ### subprocess
148
234
 
149
- ADB has two subprocess invocation modes and two data protocols (4 combinations).
235
+ ADB has two subprocess invocation modes and two data protocols (4 combinations). The Shell protocol was added in Android 8 and can be identified by the `shell_v2` feature flag.
150
236
 
151
237
  #### raw mode
152
238
 
153
- In raw mode, Shell protocol transfers `stdout` and `stderr` separately. It also supports returning exit code.
239
+ In raw mode, Shell protocol transfers `stdout` and `stderr` separately, and supports returning exit code.
154
240
 
155
241
  | | Legacy protocol | Shell Protocol |
156
242
  | --------------------------- | --------------------------- | ---------------------------- |
@@ -163,13 +249,15 @@ Use `spawn` method to create a subprocess in raw mode.
163
249
 
164
250
  #### pty mode
165
251
 
166
- In PTY mode, the subprocess has a pseudo-terminal, so it can send special control sequences like clear screen and set cursor position. The two protocols both send data in `stdout`, but Shell Protocol also supports resizing the terminal from client.
252
+ In PTY mode, the subprocess has a pseudo-terminal, so it can send special control sequences like clear screen and set cursor position. The two protocols both send data in `stdout`, but Shell Protocol also supports resizing the terminal from client and returning the exit code.
167
253
 
168
254
  | | Legacy protocol | Shell Protocol |
169
255
  | --------------------------- | --------------------------- | ---------------------------- |
170
256
  | Feature flag | - | `shell_v2` |
171
257
  | Implementation | `AdbNoneSubprocessProtocol` | `AdbShellSubprocessProtocol` |
172
258
  | Resizing window | No | Yes |
259
+ | Splitting stdout and stderr | No | No |
260
+ | Returning exit code | No | Yes |
173
261
 
174
262
  Use `shell` method to create a subprocess in PTY mode.
175
263
 
@@ -183,65 +271,94 @@ Enable ADB over WiFi.
183
271
 
184
272
  ### sync
185
273
 
186
- Client and server will communicate with another protocol on the opened stream.
274
+ Sync protocol is a sub-protocol of the server-daemon protocol, it allows interacting with the device's filesystem.
275
+
276
+ ```ts
277
+ public async sync(): Promise<AdbSync>;
278
+ ```
187
279
 
188
- #### LIST
280
+ Creates an `AdbSync` client. The client can send multiple command in sequence, and multiple clients can be created to send commands in parallel.
189
281
 
190
- Request server to list the content of a folder.
282
+ #### `lstat`
191
283
 
192
- #### LIS2
284
+ ```ts
285
+ public async lstat(path: string): Promise<AdbSyncStat>;
286
+ ```
193
287
 
194
- Version 2 of the LIST command, contains more information.
288
+ Gets the information of a file or folder. If path is a symbolic link, the returned information is about the link itself.
195
289
 
196
- Supported on devices with `ls_v2` feature.
290
+ This uses the `STAT` or `LST2` (when supported) sync commands, notice that despite the name of `STAT`, it doesn't resolve symbolic links.
197
291
 
198
- #### STAT
292
+ Same as the [`lstat`](https://linux.die.net/man/2/lstat) system call in Linux.
199
293
 
200
- Request server to return the information of a file.
294
+ #### `stat`
201
295
 
202
- If path is a symbolic link, the returned information is about the link itself.
296
+ ```ts
297
+ public async stat(path: string): Promise<AdbSyncStat>;
298
+ ```
203
299
 
204
- So it's actually the [`lstat`](https://linux.die.net/man/2/lstat) system call.
300
+ Similar to `lstat`, but if path is a symbolic link, the information is about the file it refers to.
205
301
 
206
- #### LST2
302
+ Uses the `STA2` sync command, which requires the `stat_v2` feature flag. Will throw an error if device doesn't support that.
207
303
 
208
- Version 2 of the STAT command, contains more information.
304
+ Same as the `stat` system call in Linux.
209
305
 
210
- Supported on devices with `stat_v2` feature.
306
+ #### `isDirectory`
211
307
 
212
- #### STA2
308
+ ```ts
309
+ public async isDirectory(path: string): Promise<boolean>
310
+ ```
213
311
 
214
- Basically identical to LST2, but if path is a symbolic link, the information is about the file it refers to.
312
+ Uses `lstat` method to check if the given path is a directory.
215
313
 
216
- Supported on devices with `stat_v2` feature.
314
+ #### `opendir`
217
315
 
218
- #### RECV
316
+ ```ts
317
+ public opendir(path: string): AsyncGenerator<AdbSyncEntry, void, void>;
318
+ ```
219
319
 
220
- Request server to send the content of a file.
320
+ Returns an async generator that yields the content of a folder.
221
321
 
222
- #### RCV2
322
+ Example:
223
323
 
224
- *(Not Implemented)*
324
+ ```ts
325
+ for await (const entry of this.opendir(path)) {
326
+ console.log(entry.name, entry.size);
327
+ }
328
+ ```
225
329
 
226
- Version 2 of the RECV command.
330
+ #### `readdir`
227
331
 
228
- Supported on devices with `sendrecv_v2` feature.
332
+ ```ts
333
+ public async readdir(path: string): Promise<AdbSyncEntry>
334
+ ```
229
335
 
230
- #### SEND
336
+ Collects the result of `opendir` into an array. Useful if you want to send other commands using the same `AdbSync` instance while iterating the folder.
231
337
 
232
- *(Not Implemented)*
338
+ #### `read`
233
339
 
234
- Send a file onto server's file system.
340
+ ```ts
341
+ public read(filename: string): ReadableStream<Uint8Array>
342
+ ```
235
343
 
236
- #### SND2
344
+ Reads the content of a file on device.
237
345
 
238
- *(Not Implemented)*
346
+ #### `write`
239
347
 
240
- Version 2 of the SEND command.
348
+ ```ts
349
+ public async write(options: {
350
+ filename: string;
351
+ file: ReadableStream<Consumable<Uint8Array>>;
352
+ type?: LinuxFileType;
353
+ permission?: number;
354
+ mtime?: number;
355
+ dryRun?: boolean;
356
+ })
357
+ ```
241
358
 
242
- Supported on devices with `sendrecv_v2` feature.
359
+ Writes a file on device. If the file name already exists, it will be overwritten.
243
360
 
244
361
  ## Useful links
245
362
 
246
- * [ADB protocol overview](https://android.googlesource.com/platform/packages/modules/adb/+/2fd69306184634c6d90db3ed3be5349e71dcc471/OVERVIEW.TXT)
247
- * [ADB commands](https://android.googlesource.com/platform/packages/modules/adb/+/2fd69306184634c6d90db3ed3be5349e71dcc471/SERVICES.TXT#145)
363
+ - [ADB protocol overview](https://android.googlesource.com/platform/packages/modules/adb/+/2fd69306184634c6d90db3ed3be5349e71dcc471/OVERVIEW.TXT)
364
+ - [ADB commands](https://android.googlesource.com/platform/packages/modules/adb/+/2fd69306184634c6d90db3ed3be5349e71dcc471/SERVICES.TXT#145)
package/esm/adb.d.ts CHANGED
@@ -1,64 +1,44 @@
1
1
  import type { Consumable, ReadableWritablePair } from "@yume-chan/stream-extra";
2
- import type { AdbCredentialStore } from "./auth.js";
2
+ import type { ValueOrPromise } from "@yume-chan/struct";
3
+ import type { AdbBanner } from "./banner.js";
3
4
  import type { AdbFrameBuffer } from "./commands/index.js";
4
5
  import { AdbPower, AdbReverseCommand, AdbSubprocess, AdbSync, AdbTcpIpCommand } from "./commands/index.js";
5
- import { AdbFeature } from "./features.js";
6
- import type { AdbPacketData, AdbPacketInit } from "./packet.js";
7
- import type { AdbIncomingSocketHandler, AdbSocket, Closeable } from "./socket/index.js";
8
- export declare enum AdbPropKey {
9
- Product = "ro.product.name",
10
- Model = "ro.product.model",
11
- Device = "ro.product.device",
12
- Features = "features"
6
+ import type { AdbFeature } from "./features.js";
7
+ export interface AdbSocket extends ReadableWritablePair<Uint8Array, Consumable<Uint8Array>>, Closeable {
8
+ readonly service: string;
9
+ }
10
+ export type AdbIncomingSocketHandler = (socket: AdbSocket) => ValueOrPromise<void>;
11
+ export interface Closeable {
12
+ close(): ValueOrPromise<void>;
13
+ }
14
+ export interface AdbTransport extends Closeable {
15
+ readonly serial: string;
16
+ readonly maxPayloadSize: number;
17
+ readonly banner: AdbBanner;
18
+ readonly disconnected: Promise<void>;
19
+ connect(service: string): ValueOrPromise<AdbSocket>;
20
+ addReverseTunnel(handler: AdbIncomingSocketHandler, address?: string): ValueOrPromise<string>;
21
+ removeReverseTunnel(address: string): ValueOrPromise<void>;
22
+ clearReverseTunnels(): ValueOrPromise<void>;
13
23
  }
14
- export declare const VERSION_OMIT_CHECKSUM = 16777217;
15
24
  export declare class Adb implements Closeable {
16
- /**
17
- * It's possible to call `authenticate` multiple times on a single connection,
18
- * every time the device receives a `CNXN` packet, it resets its internal state,
19
- * and starts a new authentication process.
20
- */
21
- static authenticate(connection: ReadableWritablePair<AdbPacketData, Consumable<AdbPacketInit>>, credentialStore: AdbCredentialStore, authenticators?: import("./auth.js").AdbAuthenticator[]): Promise<Adb>;
22
- private readonly dispatcher;
23
- get disconnected(): Promise<void>;
24
- private _protocolVersion;
25
- get protocolVersion(): number;
26
- private _maxPayloadSize;
25
+ readonly transport: AdbTransport;
26
+ get serial(): string;
27
27
  get maxPayloadSize(): number;
28
- private _product;
29
- get product(): string | undefined;
30
- private _model;
31
- get model(): string | undefined;
32
- private _device;
33
- get device(): string | undefined;
34
- private _features;
35
- get features(): AdbFeature[];
28
+ get banner(): AdbBanner;
29
+ get disconnected(): Promise<void>;
36
30
  readonly subprocess: AdbSubprocess;
37
31
  readonly power: AdbPower;
38
32
  readonly reverse: AdbReverseCommand;
39
33
  readonly tcpip: AdbTcpIpCommand;
40
- constructor(connection: ReadableWritablePair<AdbPacketData, Consumable<AdbPacketInit>>, version: number, maxPayloadSize: number, banner: string);
41
- private parseBanner;
34
+ constructor(transport: AdbTransport);
42
35
  supportsFeature(feature: AdbFeature): boolean;
43
- /**
44
- * Add a handler for incoming socket.
45
- * @param handler A function to call with new incoming sockets. It must return `true` if it accepts the socket.
46
- * @returns A function to remove the handler.
47
- */
48
- onIncomingSocket(handler: AdbIncomingSocketHandler): import("@yume-chan/event").RemoveEventListener;
49
36
  createSocket(service: string): Promise<AdbSocket>;
50
37
  createSocketAndWait(service: string): Promise<string>;
51
38
  getProp(key: string): Promise<string>;
52
39
  rm(...filenames: string[]): Promise<string>;
53
40
  sync(): Promise<AdbSync>;
54
41
  framebuffer(): Promise<AdbFrameBuffer>;
55
- /**
56
- * Close the ADB connection.
57
- *
58
- * Note that it won't close the streams from backends.
59
- * The streams are both physically and logically intact,
60
- * and can be reused.
61
- */
62
42
  close(): Promise<void>;
63
43
  }
64
44
  //# sourceMappingURL=adb.d.ts.map
package/esm/adb.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"adb.d.ts","sourceRoot":"","sources":["../src/adb.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAShF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAKpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EACH,QAAQ,EACR,iBAAiB,EACjB,aAAa,EACb,OAAO,EACP,eAAe,EAGlB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEhE,OAAO,KAAK,EACR,wBAAwB,EACxB,SAAS,EACT,SAAS,EACZ,MAAM,mBAAmB,CAAC;AAI3B,oBAAY,UAAU;IAClB,OAAO,oBAAoB;IAC3B,KAAK,qBAAqB;IAC1B,MAAM,sBAAsB;IAC5B,QAAQ,aAAa;CACxB;AAED,eAAO,MAAM,qBAAqB,WAAa,CAAC;AAEhD,qBAAa,GAAI,YAAW,SAAS;IACjC;;;;OAIG;WACiB,YAAY,CAC5B,UAAU,EAAE,oBAAoB,CAC5B,aAAa,EACb,UAAU,CAAC,aAAa,CAAC,CAC5B,EACD,eAAe,EAAE,kBAAkB,EACnC,cAAc,yCAA6B,GAC5C,OAAO,CAAC,GAAG,CAAC;IAgHf,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsB;IAEjD,IAAW,YAAY,kBAEtB;IAED,OAAO,CAAC,gBAAgB,CAAS;IACjC,IAAW,eAAe,WAEzB;IAED,OAAO,CAAC,eAAe,CAAS;IAChC,IAAW,cAAc,WAExB;IAED,OAAO,CAAC,QAAQ,CAAqB;IACrC,IAAW,OAAO,uBAEjB;IAED,OAAO,CAAC,MAAM,CAAqB;IACnC,IAAW,KAAK,uBAEf;IAED,OAAO,CAAC,OAAO,CAAqB;IACpC,IAAW,MAAM,uBAEhB;IAED,OAAO,CAAC,SAAS,CAAoB;IACrC,IAAW,QAAQ,iBAElB;IAED,SAAgB,UAAU,EAAE,aAAa,CAAC;IAC1C,SAAgB,KAAK,EAAE,QAAQ,CAAC;IAChC,SAAgB,OAAO,EAAE,iBAAiB,CAAC;IAC3C,SAAgB,KAAK,EAAE,eAAe,CAAC;gBAGnC,UAAU,EAAE,oBAAoB,CAC5B,aAAa,EACb,UAAU,CAAC,aAAa,CAAC,CAC5B,EACD,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM;IA6BlB,OAAO,CAAC,WAAW;IAiCZ,eAAe,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO;IAIpD;;;;OAIG;IACI,gBAAgB,CAAC,OAAO,EAAE,wBAAwB;IAI5C,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAIjD,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IASrD,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQrC,EAAE,CAAC,GAAG,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAU3C,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;IAKxB,WAAW,IAAI,OAAO,CAAC,cAAc,CAAC;IAInD;;;;;;OAMG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAGtC"}
1
+ {"version":3,"file":"adb.d.ts","sourceRoot":"","sources":["../src/adb.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAEhF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EACH,QAAQ,EACR,iBAAiB,EACjB,aAAa,EACb,OAAO,EACP,eAAe,EAGlB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,WAAW,SACb,SAAQ,oBAAoB,CAAC,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC,EAC5D,SAAS;IACb,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,MAAM,wBAAwB,GAAG,CACnC,MAAM,EAAE,SAAS,KAChB,cAAc,CAAC,IAAI,CAAC,CAAC;AAE1B,MAAM,WAAW,SAAS;IACtB,KAAK,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,YAAa,SAAQ,SAAS;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAEhC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAE3B,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAErC,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IAEpD,gBAAgB,CACZ,OAAO,EAAE,wBAAwB,EACjC,OAAO,CAAC,EAAE,MAAM,GACjB,cAAc,CAAC,MAAM,CAAC,CAAC;IAE1B,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IAE3D,mBAAmB,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED,qBAAa,GAAI,YAAW,SAAS;IACjC,SAAgB,SAAS,EAAE,YAAY,CAAC;IAExC,IAAW,MAAM,WAEhB;IAED,IAAW,cAAc,WAExB;IAED,IAAW,MAAM,cAEhB;IAED,IAAW,YAAY,kBAEtB;IAED,SAAgB,UAAU,EAAE,aAAa,CAAC;IAC1C,SAAgB,KAAK,EAAE,QAAQ,CAAC;IAChC,SAAgB,OAAO,EAAE,iBAAiB,CAAC;IAC3C,SAAgB,KAAK,EAAE,eAAe,CAAC;gBAEpB,SAAS,EAAE,YAAY;IASnC,eAAe,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO;IAIvC,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAIjD,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IASrD,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQrC,EAAE,CAAC,GAAG,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAU3C,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;IAKxB,WAAW,IAAI,OAAO,CAAC,cAAc,CAAC;IAItC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAGtC"}