@simplysm/capacitor-plugin-file-system 12.16.27 → 13.0.0-beta.10

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 (100) hide show
  1. package/README.md +226 -0
  2. package/android/src/main/java/kr/co/simplysm/capacitor/filesystem/FileSystemPlugin.java +17 -1
  3. package/dist/FileSystem.js +104 -106
  4. package/dist/FileSystem.js.map +7 -0
  5. package/dist/IFileSystemPlugin.js +1 -1
  6. package/dist/IFileSystemPlugin.js.map +7 -0
  7. package/dist/{FileSystem.d.ts → capacitor-plugin-file-system/src/FileSystem.d.ts} +15 -13
  8. package/dist/capacitor-plugin-file-system/src/FileSystem.d.ts.map +1 -0
  9. package/dist/{IFileSystemPlugin.d.ts → capacitor-plugin-file-system/src/IFileSystemPlugin.d.ts} +2 -1
  10. package/dist/capacitor-plugin-file-system/src/IFileSystemPlugin.d.ts.map +1 -0
  11. package/dist/{index.d.ts → capacitor-plugin-file-system/src/index.d.ts} +1 -0
  12. package/dist/capacitor-plugin-file-system/src/index.d.ts.map +1 -0
  13. package/dist/{web → capacitor-plugin-file-system/src/web}/FileSystemWeb.d.ts +10 -2
  14. package/dist/capacitor-plugin-file-system/src/web/FileSystemWeb.d.ts.map +1 -0
  15. package/dist/capacitor-plugin-file-system/src/web/IndexedDbStore.d.ts +16 -0
  16. package/dist/capacitor-plugin-file-system/src/web/IndexedDbStore.d.ts.map +1 -0
  17. package/dist/capacitor-plugin-file-system/src/web/VirtualFileSystem.d.ts +26 -0
  18. package/dist/capacitor-plugin-file-system/src/web/VirtualFileSystem.d.ts.map +1 -0
  19. package/dist/core-common/src/common.types.d.ts +74 -0
  20. package/dist/core-common/src/common.types.d.ts.map +1 -0
  21. package/dist/core-common/src/env.d.ts +6 -0
  22. package/dist/core-common/src/env.d.ts.map +1 -0
  23. package/dist/core-common/src/errors/argument-error.d.ts +25 -0
  24. package/dist/core-common/src/errors/argument-error.d.ts.map +1 -0
  25. package/dist/core-common/src/errors/not-implemented-error.d.ts +29 -0
  26. package/dist/core-common/src/errors/not-implemented-error.d.ts.map +1 -0
  27. package/dist/core-common/src/errors/sd-error.d.ts +27 -0
  28. package/dist/core-common/src/errors/sd-error.d.ts.map +1 -0
  29. package/dist/core-common/src/errors/timeout-error.d.ts +31 -0
  30. package/dist/core-common/src/errors/timeout-error.d.ts.map +1 -0
  31. package/dist/core-common/src/extensions/arr-ext.d.ts +15 -0
  32. package/dist/core-common/src/extensions/arr-ext.d.ts.map +1 -0
  33. package/dist/core-common/src/extensions/arr-ext.helpers.d.ts +19 -0
  34. package/dist/core-common/src/extensions/arr-ext.helpers.d.ts.map +1 -0
  35. package/dist/core-common/src/extensions/arr-ext.types.d.ts +215 -0
  36. package/dist/core-common/src/extensions/arr-ext.types.d.ts.map +1 -0
  37. package/dist/core-common/src/extensions/map-ext.d.ts +57 -0
  38. package/dist/core-common/src/extensions/map-ext.d.ts.map +1 -0
  39. package/dist/core-common/src/extensions/set-ext.d.ts +36 -0
  40. package/dist/core-common/src/extensions/set-ext.d.ts.map +1 -0
  41. package/dist/core-common/src/features/debounce-queue.d.ts +53 -0
  42. package/dist/core-common/src/features/debounce-queue.d.ts.map +1 -0
  43. package/dist/core-common/src/features/event-emitter.d.ts +66 -0
  44. package/dist/core-common/src/features/event-emitter.d.ts.map +1 -0
  45. package/dist/core-common/src/features/serial-queue.d.ts +47 -0
  46. package/dist/core-common/src/features/serial-queue.d.ts.map +1 -0
  47. package/dist/core-common/src/index.d.ts +32 -0
  48. package/dist/core-common/src/index.d.ts.map +1 -0
  49. package/dist/core-common/src/types/date-only.d.ts +152 -0
  50. package/dist/core-common/src/types/date-only.d.ts.map +1 -0
  51. package/dist/core-common/src/types/date-time.d.ts +96 -0
  52. package/dist/core-common/src/types/date-time.d.ts.map +1 -0
  53. package/dist/core-common/src/types/lazy-gc-map.d.ts +80 -0
  54. package/dist/core-common/src/types/lazy-gc-map.d.ts.map +1 -0
  55. package/dist/core-common/src/types/time.d.ts +68 -0
  56. package/dist/core-common/src/types/time.d.ts.map +1 -0
  57. package/dist/core-common/src/types/uuid.d.ts +35 -0
  58. package/dist/core-common/src/types/uuid.d.ts.map +1 -0
  59. package/dist/core-common/src/utils/bytes.d.ts +51 -0
  60. package/dist/core-common/src/utils/bytes.d.ts.map +1 -0
  61. package/dist/core-common/src/utils/date-format.d.ts +90 -0
  62. package/dist/core-common/src/utils/date-format.d.ts.map +1 -0
  63. package/dist/core-common/src/utils/json.d.ts +34 -0
  64. package/dist/core-common/src/utils/json.d.ts.map +1 -0
  65. package/dist/core-common/src/utils/num.d.ts +60 -0
  66. package/dist/core-common/src/utils/num.d.ts.map +1 -0
  67. package/dist/core-common/src/utils/obj.d.ts +258 -0
  68. package/dist/core-common/src/utils/obj.d.ts.map +1 -0
  69. package/dist/core-common/src/utils/path.d.ts +23 -0
  70. package/dist/core-common/src/utils/path.d.ts.map +1 -0
  71. package/dist/core-common/src/utils/primitive.d.ts +18 -0
  72. package/dist/core-common/src/utils/primitive.d.ts.map +1 -0
  73. package/dist/core-common/src/utils/str.d.ts +103 -0
  74. package/dist/core-common/src/utils/str.d.ts.map +1 -0
  75. package/dist/core-common/src/utils/template-strings.d.ts +84 -0
  76. package/dist/core-common/src/utils/template-strings.d.ts.map +1 -0
  77. package/dist/core-common/src/utils/transferable.d.ts +47 -0
  78. package/dist/core-common/src/utils/transferable.d.ts.map +1 -0
  79. package/dist/core-common/src/utils/wait.d.ts +19 -0
  80. package/dist/core-common/src/utils/wait.d.ts.map +1 -0
  81. package/dist/core-common/src/utils/xml.d.ts +36 -0
  82. package/dist/core-common/src/utils/xml.d.ts.map +1 -0
  83. package/dist/core-common/src/zip/sd-zip.d.ts +80 -0
  84. package/dist/core-common/src/zip/sd-zip.d.ts.map +1 -0
  85. package/dist/index.js +1 -0
  86. package/dist/index.js.map +7 -0
  87. package/dist/web/FileSystemWeb.js +90 -83
  88. package/dist/web/FileSystemWeb.js.map +7 -0
  89. package/dist/web/IndexedDbStore.js +76 -0
  90. package/dist/web/IndexedDbStore.js.map +7 -0
  91. package/dist/web/VirtualFileSystem.js +91 -115
  92. package/dist/web/VirtualFileSystem.js.map +7 -0
  93. package/package.json +9 -2
  94. package/dist/web/VirtualFileSystem.d.ts +0 -20
  95. package/src/FileSystem.ts +0 -123
  96. package/src/IFileSystemPlugin.ts +0 -26
  97. package/src/index.ts +0 -2
  98. package/src/web/FileSystemWeb.ts +0 -107
  99. package/src/web/VirtualFileSystem.ts +0 -138
  100. package/tsconfig.json +0 -8
package/README.md ADDED
@@ -0,0 +1,226 @@
1
+ # @simplysm/capacitor-plugin-file-system
2
+
3
+ A Capacitor-based file system access plugin. On Android, it provides direct access to the native file system, while in web environments it operates as an IndexedDB-based virtual file system.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @simplysm/capacitor-plugin-file-system
9
+ npx cap sync
10
+ ```
11
+
12
+ ### Peer Dependencies
13
+
14
+ | Package | Version |
15
+ |--------|------|
16
+ | `@capacitor/core` | `^7.4.4` |
17
+
18
+ ### Internal Dependencies
19
+
20
+ | Package | Description |
21
+ |--------|------|
22
+ | `@simplysm/core-common` | Common utilities such as base64 conversion, `Bytes` type |
23
+
24
+ ## Supported Platforms
25
+
26
+ | Platform | Supported | Implementation |
27
+ |--------|----------|----------|
28
+ | Android | Yes | Native Java (API 23+) |
29
+ | Web | Yes | IndexedDB-based virtual file system |
30
+ | iOS | No | - |
31
+
32
+ ### Android Permissions
33
+
34
+ Different permission models are used depending on the Android version.
35
+
36
+ | Android Version | Permission | Behavior |
37
+ |-------------|------|------|
38
+ | Android 11+ (API 30+) | `MANAGE_EXTERNAL_STORAGE` | Navigate to settings screen to grant full file access permission |
39
+ | Android 10 and below | `READ_EXTERNAL_STORAGE`, `WRITE_EXTERNAL_STORAGE` | Display runtime permission dialog |
40
+
41
+ The plugin automatically declares the necessary permissions in `AndroidManifest.xml`, so you don't need to add them separately in your app's manifest.
42
+
43
+ ## Main API
44
+
45
+ All APIs are provided as static methods of the `FileSystem` class.
46
+
47
+ ```typescript
48
+ import { FileSystem } from "@simplysm/capacitor-plugin-file-system";
49
+ ```
50
+
51
+ ### Method List
52
+
53
+ | Method | Return Type | Description |
54
+ |--------|----------|------|
55
+ | `hasPermission()` | `Promise<boolean>` | Check if file system access permission is granted |
56
+ | `requestPermission()` | `Promise<void>` | Request file system access permission |
57
+ | `readdir(dirPath)` | `Promise<IFileInfo[]>` | List files/folders in directory |
58
+ | `getStoragePath(type)` | `Promise<string>` | Return absolute path by storage type |
59
+ | `getFileUri(filePath)` | `Promise<string>` | Return FileProvider URI (Android) / Blob URL (Web) |
60
+ | `writeFile(filePath, data)` | `Promise<void>` | Write file (string or binary) |
61
+ | `readFileString(filePath)` | `Promise<string>` | Read file as UTF-8 string |
62
+ | `readFileBytes(filePath)` | `Promise<Bytes>` | Read file as binary (`Uint8Array`) |
63
+ | `remove(targetPath)` | `Promise<void>` | Recursively delete file or directory |
64
+ | `mkdir(targetPath)` | `Promise<void>` | Recursively create directory |
65
+ | `exists(targetPath)` | `Promise<boolean>` | Check if file or directory exists |
66
+
67
+ ### Type Definitions
68
+
69
+ #### `TStorage`
70
+
71
+ A string literal type representing storage types.
72
+
73
+ | Value | Android Path | Description |
74
+ |----|-------------|------|
75
+ | `"external"` | `Environment.getExternalStorageDirectory()` | External storage root |
76
+ | `"externalFiles"` | `Context.getExternalFilesDir(null)` | App-specific external files directory |
77
+ | `"externalCache"` | `Context.getExternalCacheDir()` | App-specific external cache directory |
78
+ | `"externalMedia"` | `Context.getExternalMediaDirs()[0]` | App-specific external media directory |
79
+ | `"appData"` | `ApplicationInfo.dataDir` | App data directory |
80
+ | `"appFiles"` | `Context.getFilesDir()` | App internal files directory |
81
+ | `"appCache"` | `Context.getCacheDir()` | App internal cache directory |
82
+
83
+ #### `IFileInfo`
84
+
85
+ ```typescript
86
+ interface IFileInfo {
87
+ name: string; // File or directory name
88
+ isDirectory: boolean; // Whether it's a directory
89
+ }
90
+ ```
91
+
92
+ ## Usage Examples
93
+
94
+ ### Check and Request Permission
95
+
96
+ ```typescript
97
+ import { FileSystem } from "@simplysm/capacitor-plugin-file-system";
98
+
99
+ async function ensurePermission(): Promise<boolean> {
100
+ const granted = await FileSystem.hasPermission();
101
+ if (!granted) {
102
+ await FileSystem.requestPermission();
103
+ // On Android 11+, it navigates to settings screen,
104
+ // so you need to check again after returning to the app.
105
+ return await FileSystem.hasPermission();
106
+ }
107
+ return true;
108
+ }
109
+ ```
110
+
111
+ ### Read/Write Text Files
112
+
113
+ ```typescript
114
+ import { FileSystem } from "@simplysm/capacitor-plugin-file-system";
115
+
116
+ async function textFileExample(): Promise<void> {
117
+ const storagePath = await FileSystem.getStoragePath("appFiles");
118
+ const filePath = storagePath + "/config.json";
119
+
120
+ // Write file
121
+ const config = { theme: "dark", lang: "ko" };
122
+ await FileSystem.writeFile(filePath, JSON.stringify(config, null, 2));
123
+
124
+ // Read file
125
+ const content = await FileSystem.readFileString(filePath);
126
+ const parsed = JSON.parse(content);
127
+ console.log(parsed.theme); // "dark"
128
+ }
129
+ ```
130
+
131
+ ### Read/Write Binary Files
132
+
133
+ ```typescript
134
+ import { FileSystem } from "@simplysm/capacitor-plugin-file-system";
135
+
136
+ async function binaryFileExample(): Promise<void> {
137
+ const storagePath = await FileSystem.getStoragePath("appFiles");
138
+ const filePath = storagePath + "/data.bin";
139
+
140
+ // Write as Uint8Array
141
+ const bytes = new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f]);
142
+ await FileSystem.writeFile(filePath, bytes);
143
+
144
+ // Read as binary
145
+ const readBytes = await FileSystem.readFileBytes(filePath);
146
+ console.log(readBytes.length); // 5
147
+ }
148
+ ```
149
+
150
+ ### Directory Management
151
+
152
+ ```typescript
153
+ import { FileSystem } from "@simplysm/capacitor-plugin-file-system";
154
+
155
+ async function directoryExample(): Promise<void> {
156
+ const storagePath = await FileSystem.getStoragePath("appFiles");
157
+ const dirPath = storagePath + "/logs/2024";
158
+
159
+ // Recursively create directory
160
+ await FileSystem.mkdir(dirPath);
161
+
162
+ // Create file
163
+ await FileSystem.writeFile(dirPath + "/app.log", "Started\n");
164
+
165
+ // List directory contents
166
+ const files = await FileSystem.readdir(dirPath);
167
+ for (const file of files) {
168
+ console.log(`${file.name} (directory: ${file.isDirectory})`);
169
+ }
170
+
171
+ // Check existence
172
+ const dirExists = await FileSystem.exists(dirPath);
173
+ console.log(dirExists); // true
174
+
175
+ // Recursively delete directory
176
+ await FileSystem.remove(dirPath);
177
+ }
178
+ ```
179
+
180
+ ### Get FileProvider URI
181
+
182
+ On Android, a `content://` URI is needed when sharing files with other apps.
183
+
184
+ ```typescript
185
+ import { FileSystem } from "@simplysm/capacitor-plugin-file-system";
186
+
187
+ async function shareFile(filePath: string): Promise<string> {
188
+ // Android: returns content:// URI
189
+ // Web: returns blob: URL (must call URL.revokeObjectURL() after use)
190
+ const uri = await FileSystem.getFileUri(filePath);
191
+ return uri;
192
+ }
193
+ ```
194
+
195
+ > **Warning**: In web environments, the Blob URL returned by `getFileUri()` must be released by calling `URL.revokeObjectURL(uri)` after use to free memory.
196
+
197
+ ## Android Configuration
198
+
199
+ ### FileProvider
200
+
201
+ The plugin includes its own `FileSystemProvider`, and the authority is automatically set in the format `${applicationId}.filesystem.provider`. Shareable paths are:
202
+
203
+ - External storage (`external-path`)
204
+ - App-specific external files (`external-files-path`)
205
+ - App-specific external cache (`external-cache-path`)
206
+ - App internal files (`files-path`)
207
+ - App internal cache (`cache-path`)
208
+
209
+ ### Minimum SDK Version
210
+
211
+ - `minSdkVersion`: 23 (Android 6.0)
212
+ - `compileSdkVersion`: 35
213
+
214
+ ## Web Environment Behavior
215
+
216
+ In web environments, it operates as an IndexedDB-based virtual file system (`VirtualFileSystem`).
217
+
218
+ - Database name: `capacitor_web_virtual_fs`
219
+ - Permission-related methods (`hasPermission`, `requestPermission`) always succeed.
220
+ - `getStoragePath()` returns virtual paths in the format `/webfs/{type}`.
221
+ - `getFileUri()` returns a Blob URL, which must be released with `URL.revokeObjectURL()` after use.
222
+ - File data is base64-encoded and stored in IndexedDB.
223
+
224
+ ## License
225
+
226
+ MIT
@@ -11,6 +11,7 @@ import android.provider.Settings;
11
11
  import android.util.Base64;
12
12
  import android.util.Log;
13
13
 
14
+ import androidx.core.app.ActivityCompat;
14
15
  import androidx.core.content.ContextCompat;
15
16
  import androidx.core.content.FileProvider;
16
17
 
@@ -28,9 +29,10 @@ import java.nio.charset.StandardCharsets;
28
29
  public class FileSystemPlugin extends Plugin {
29
30
 
30
31
  private static final String TAG = "FileSystemPlugin";
32
+ private static final int PERMISSION_REQUEST_CODE = 1001;
31
33
 
32
34
  @PluginMethod
33
- public void checkPermission(PluginCall call) {
35
+ public void hasPermission(PluginCall call) {
34
36
  boolean granted;
35
37
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
36
38
  granted = Environment.isExternalStorageManager();
@@ -52,6 +54,20 @@ public class FileSystemPlugin extends Plugin {
52
54
  intent.setData(Uri.parse("package:" + getContext().getPackageName()));
53
55
  getActivity().startActivity(intent);
54
56
  }
57
+ } else {
58
+ boolean readGranted = ContextCompat.checkSelfPermission(getContext(),
59
+ Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
60
+ boolean writeGranted = ContextCompat.checkSelfPermission(getContext(),
61
+ Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
62
+
63
+ if (!readGranted || !writeGranted) {
64
+ ActivityCompat.requestPermissions(getActivity(),
65
+ new String[]{
66
+ Manifest.permission.READ_EXTERNAL_STORAGE,
67
+ Manifest.permission.WRITE_EXTERNAL_STORAGE
68
+ },
69
+ PERMISSION_REQUEST_CODE);
70
+ }
55
71
  }
56
72
  call.resolve();
57
73
  }
@@ -1,111 +1,109 @@
1
1
  import { registerPlugin } from "@capacitor/core";
2
+ import { bytesToBase64, bytesFromBase64 } from "@simplysm/core-common";
2
3
  const FileSystemPlugin = registerPlugin("FileSystem", {
3
- web: async () => {
4
- const { FileSystemWeb } = await import("./web/FileSystemWeb");
5
- return new FileSystemWeb();
6
- },
4
+ web: async () => {
5
+ const { FileSystemWeb } = await import("./web/FileSystemWeb");
6
+ return new FileSystemWeb();
7
+ }
7
8
  });
8
- /**
9
- * 파일 시스템 접근 플러그인
10
- * - Android 11+: MANAGE_EXTERNAL_STORAGE 권한으로 전체 파일 시스템 접근
11
- * - Android 10-: READ/WRITE_EXTERNAL_STORAGE 권한
12
- * - Browser: IndexedDB 기반 에뮬레이션
13
- */
14
- export class FileSystem {
15
- /**
16
- * 권한 확인
17
- */
18
- static async checkPermissionAsync() {
19
- const result = await FileSystemPlugin.checkPermission();
20
- return result.granted;
21
- }
22
- /**
23
- * 권한 요청
24
- * - Android 11+: 설정 화면으로 이동
25
- * - Android 10-: 권한 다이얼로그 표시
26
- */
27
- static async requestPermissionAsync() {
28
- await FileSystemPlugin.requestPermission();
29
- }
30
- /**
31
- * 디렉토리 읽기
32
- */
33
- static async readdirAsync(dirPath) {
34
- const result = await FileSystemPlugin.readdir({ path: dirPath });
35
- return result.files;
36
- }
37
- /**
38
- * 저장소 경로 얻기
39
- * @param type 저장소 타입
40
- * - external: 외부 저장소 루트 (Environment.getExternalStorageDirectory)
41
- * - externalFiles: 앱 전용 외부 파일 디렉토리
42
- * - externalCache: 앱 전용 외부 캐시 디렉토리
43
- * - externalMedia: 전용 외부 미디어 디렉토리
44
- * - appData: 앱 데이터 디렉토리
45
- * - appFiles: 앱 파일 디렉토리
46
- * - appCache: 앱 캐시 디렉토리
47
- */
48
- static async getStoragePathAsync(type) {
49
- const result = await FileSystemPlugin.getStoragePath({ type });
50
- return result.path;
51
- }
52
- /**
53
- * 파일 URI 얻기 (FileProvider)
54
- */
55
- static async getFileUriAsync(filePath) {
56
- const result = await FileSystemPlugin.getFileUri({ path: filePath });
57
- return result.uri;
58
- }
59
- /**
60
- * 파일 쓰기
61
- */
62
- static async writeFileAsync(filePath, data) {
63
- if (Buffer.isBuffer(data)) {
64
- await FileSystemPlugin.writeFile({
65
- path: filePath,
66
- data: data.toString("base64"),
67
- encoding: "base64",
68
- });
69
- }
70
- else {
71
- await FileSystemPlugin.writeFile({
72
- path: filePath,
73
- data,
74
- encoding: "utf8",
75
- });
76
- }
77
- }
78
- /**
79
- * 파일 읽기 (UTF-8 문자열)
80
- */
81
- static async readFileStringAsync(filePath) {
82
- const result = await FileSystemPlugin.readFile({ path: filePath, encoding: "utf8" });
83
- return result.data;
84
- }
85
- /**
86
- * 파일 읽기 (Buffer)
87
- */
88
- static async readFileBufferAsync(filePath) {
89
- const result = await FileSystemPlugin.readFile({ path: filePath, encoding: "base64" });
90
- return Buffer.from(result.data, "base64");
91
- }
92
- /**
93
- * 파일/디렉토리 삭제 (재귀)
94
- */
95
- static async removeAsync(targetPath) {
96
- await FileSystemPlugin.remove({ path: targetPath });
97
- }
98
- /**
99
- * 디렉토리 생성 (재귀)
100
- */
101
- static async mkdirsAsync(targetPath) {
102
- await FileSystemPlugin.mkdir({ path: targetPath });
103
- }
104
- /**
105
- * 존재 여부 확인
106
- */
107
- static async existsAsync(targetPath) {
108
- const result = await FileSystemPlugin.exists({ path: targetPath });
109
- return result.exists;
9
+ class FileSystem {
10
+ /**
11
+ * 권한 확인
12
+ */
13
+ static async hasPermission() {
14
+ const result = await FileSystemPlugin.hasPermission();
15
+ return result.granted;
16
+ }
17
+ /**
18
+ * 권한 요청
19
+ * - Android 11+: 설정 화면으로 이동
20
+ * - Android 10-: 권한 다이얼로그 표시
21
+ */
22
+ static async requestPermission() {
23
+ await FileSystemPlugin.requestPermission();
24
+ }
25
+ /**
26
+ * 디렉토리 읽기
27
+ */
28
+ static async readdir(dirPath) {
29
+ const result = await FileSystemPlugin.readdir({ path: dirPath });
30
+ return result.files;
31
+ }
32
+ /**
33
+ * 저장소 경로 얻기
34
+ * @param type 저장소 타입
35
+ * - external: 외부 저장소 루트 (Environment.getExternalStorageDirectory)
36
+ * - externalFiles: 앱 전용 외부 파일 디렉토리
37
+ * - externalCache: 앱 전용 외부 캐시 디렉토리
38
+ * - externalMedia: 앱 전용 외부 미디어 디렉토리
39
+ * - appData: 앱 데이터 디렉토리
40
+ * - appFiles: 파일 디렉토리
41
+ * - appCache: 캐시 디렉토리
42
+ */
43
+ static async getStoragePath(type) {
44
+ const result = await FileSystemPlugin.getStoragePath({ type });
45
+ return result.path;
46
+ }
47
+ /**
48
+ * 파일 URI 얻기 (FileProvider)
49
+ */
50
+ static async getFileUri(filePath) {
51
+ const result = await FileSystemPlugin.getFileUri({ path: filePath });
52
+ return result.uri;
53
+ }
54
+ /**
55
+ * 파일 쓰기
56
+ */
57
+ static async writeFile(filePath, data) {
58
+ if (typeof data !== "string") {
59
+ await FileSystemPlugin.writeFile({
60
+ path: filePath,
61
+ data: bytesToBase64(data),
62
+ encoding: "base64"
63
+ });
64
+ } else {
65
+ await FileSystemPlugin.writeFile({
66
+ path: filePath,
67
+ data,
68
+ encoding: "utf8"
69
+ });
110
70
  }
71
+ }
72
+ /**
73
+ * 파일 읽기 (UTF-8 문자열)
74
+ */
75
+ static async readFileString(filePath) {
76
+ const result = await FileSystemPlugin.readFile({ path: filePath, encoding: "utf8" });
77
+ return result.data;
78
+ }
79
+ /**
80
+ * 파일 읽기 (Bytes)
81
+ */
82
+ static async readFileBytes(filePath) {
83
+ const result = await FileSystemPlugin.readFile({ path: filePath, encoding: "base64" });
84
+ return bytesFromBase64(result.data);
85
+ }
86
+ /**
87
+ * 파일/디렉토리 삭제 (재귀)
88
+ */
89
+ static async remove(targetPath) {
90
+ await FileSystemPlugin.remove({ path: targetPath });
91
+ }
92
+ /**
93
+ * 디렉토리 생성 (재귀)
94
+ */
95
+ static async mkdir(targetPath) {
96
+ await FileSystemPlugin.mkdir({ path: targetPath });
97
+ }
98
+ /**
99
+ * 존재 여부 확인
100
+ */
101
+ static async exists(targetPath) {
102
+ const result = await FileSystemPlugin.exists({ path: targetPath });
103
+ return result.exists;
104
+ }
111
105
  }
106
+ export {
107
+ FileSystem
108
+ };
109
+ //# sourceMappingURL=FileSystem.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/FileSystem.ts"],
4
+ "sourcesContent": ["import { registerPlugin } from \"@capacitor/core\";\nimport type { IFileInfo, IFileSystemPlugin, TStorage } from \"./IFileSystemPlugin\";\nimport type { Bytes } from \"@simplysm/core-common\";\nimport { bytesToBase64, bytesFromBase64 } from \"@simplysm/core-common\";\n\nconst FileSystemPlugin = registerPlugin<IFileSystemPlugin>(\"FileSystem\", {\n web: async () => {\n const { FileSystemWeb } = await import(\"./web/FileSystemWeb\");\n return new FileSystemWeb();\n },\n});\n\n/**\n * \uD30C\uC77C \uC2DC\uC2A4\uD15C \uC811\uADFC \uD50C\uB7EC\uADF8\uC778\n * - Android 11+: MANAGE_EXTERNAL_STORAGE \uAD8C\uD55C\uC73C\uB85C \uC804\uCCB4 \uD30C\uC77C \uC2DC\uC2A4\uD15C \uC811\uADFC\n * - Android 10-: READ/WRITE_EXTERNAL_STORAGE \uAD8C\uD55C\n * - Browser: IndexedDB \uAE30\uBC18 \uC5D0\uBBAC\uB808\uC774\uC158\n */\nexport abstract class FileSystem {\n /**\n * \uAD8C\uD55C \uD655\uC778\n */\n static async hasPermission(): Promise<boolean> {\n const result = await FileSystemPlugin.hasPermission();\n return result.granted;\n }\n\n /**\n * \uAD8C\uD55C \uC694\uCCAD\n * - Android 11+: \uC124\uC815 \uD654\uBA74\uC73C\uB85C \uC774\uB3D9\n * - Android 10-: \uAD8C\uD55C \uB2E4\uC774\uC5BC\uB85C\uADF8 \uD45C\uC2DC\n */\n static async requestPermission(): Promise<void> {\n await FileSystemPlugin.requestPermission();\n }\n\n /**\n * \uB514\uB809\uD1A0\uB9AC \uC77D\uAE30\n */\n static async readdir(dirPath: string): Promise<IFileInfo[]> {\n const result = await FileSystemPlugin.readdir({ path: dirPath });\n return result.files;\n }\n\n /**\n * \uC800\uC7A5\uC18C \uACBD\uB85C \uC5BB\uAE30\n * @param type \uC800\uC7A5\uC18C \uD0C0\uC785\n * - external: \uC678\uBD80 \uC800\uC7A5\uC18C \uB8E8\uD2B8 (Environment.getExternalStorageDirectory)\n * - externalFiles: \uC571 \uC804\uC6A9 \uC678\uBD80 \uD30C\uC77C \uB514\uB809\uD1A0\uB9AC\n * - externalCache: \uC571 \uC804\uC6A9 \uC678\uBD80 \uCE90\uC2DC \uB514\uB809\uD1A0\uB9AC\n * - externalMedia: \uC571 \uC804\uC6A9 \uC678\uBD80 \uBBF8\uB514\uC5B4 \uB514\uB809\uD1A0\uB9AC\n * - appData: \uC571 \uB370\uC774\uD130 \uB514\uB809\uD1A0\uB9AC\n * - appFiles: \uC571 \uD30C\uC77C \uB514\uB809\uD1A0\uB9AC\n * - appCache: \uC571 \uCE90\uC2DC \uB514\uB809\uD1A0\uB9AC\n */\n static async getStoragePath(type: TStorage): Promise<string> {\n const result = await FileSystemPlugin.getStoragePath({ type });\n return result.path;\n }\n\n /**\n * \uD30C\uC77C URI \uC5BB\uAE30 (FileProvider)\n */\n static async getFileUri(filePath: string): Promise<string> {\n const result = await FileSystemPlugin.getFileUri({ path: filePath });\n return result.uri;\n }\n\n /**\n * \uD30C\uC77C \uC4F0\uAE30\n */\n static async writeFile(filePath: string, data: string | Bytes): Promise<void> {\n if (typeof data !== \"string\") {\n // Bytes (Uint8Array) - cross-realm \uD658\uACBD\uC5D0\uC11C\uB3C4 \uC548\uC804\uD558\uAC8C \uB3D9\uC791\n await FileSystemPlugin.writeFile({\n path: filePath,\n data: bytesToBase64(data),\n encoding: \"base64\",\n });\n } else {\n await FileSystemPlugin.writeFile({\n path: filePath,\n data,\n encoding: \"utf8\",\n });\n }\n }\n\n /**\n * \uD30C\uC77C \uC77D\uAE30 (UTF-8 \uBB38\uC790\uC5F4)\n */\n static async readFileString(filePath: string): Promise<string> {\n const result = await FileSystemPlugin.readFile({ path: filePath, encoding: \"utf8\" });\n return result.data;\n }\n\n /**\n * \uD30C\uC77C \uC77D\uAE30 (Bytes)\n */\n static async readFileBytes(filePath: string): Promise<Bytes> {\n const result = await FileSystemPlugin.readFile({ path: filePath, encoding: \"base64\" });\n return bytesFromBase64(result.data);\n }\n\n /**\n * \uD30C\uC77C/\uB514\uB809\uD1A0\uB9AC \uC0AD\uC81C (\uC7AC\uADC0)\n */\n static async remove(targetPath: string): Promise<void> {\n await FileSystemPlugin.remove({ path: targetPath });\n }\n\n /**\n * \uB514\uB809\uD1A0\uB9AC \uC0DD\uC131 (\uC7AC\uADC0)\n */\n static async mkdir(targetPath: string): Promise<void> {\n await FileSystemPlugin.mkdir({ path: targetPath });\n }\n\n /**\n * \uC874\uC7AC \uC5EC\uBD80 \uD655\uC778\n */\n static async exists(targetPath: string): Promise<boolean> {\n const result = await FileSystemPlugin.exists({ path: targetPath });\n return result.exists;\n }\n}\n"],
5
+ "mappings": "AAAA,SAAS,sBAAsB;AAG/B,SAAS,eAAe,uBAAuB;AAE/C,MAAM,mBAAmB,eAAkC,cAAc;AAAA,EACvE,KAAK,YAAY;AACf,UAAM,EAAE,cAAc,IAAI,MAAM,OAAO,qBAAqB;AAC5D,WAAO,IAAI,cAAc;AAAA,EAC3B;AACF,CAAC;AAQM,MAAe,WAAW;AAAA;AAAA;AAAA;AAAA,EAI/B,aAAa,gBAAkC;AAC7C,UAAM,SAAS,MAAM,iBAAiB,cAAc;AACpD,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,oBAAmC;AAC9C,UAAM,iBAAiB,kBAAkB;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,QAAQ,SAAuC;AAC1D,UAAM,SAAS,MAAM,iBAAiB,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAC/D,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,aAAa,eAAe,MAAiC;AAC3D,UAAM,SAAS,MAAM,iBAAiB,eAAe,EAAE,KAAK,CAAC;AAC7D,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,WAAW,UAAmC;AACzD,UAAM,SAAS,MAAM,iBAAiB,WAAW,EAAE,MAAM,SAAS,CAAC;AACnE,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,UAAU,UAAkB,MAAqC;AAC5E,QAAI,OAAO,SAAS,UAAU;AAE5B,YAAM,iBAAiB,UAAU;AAAA,QAC/B,MAAM;AAAA,QACN,MAAM,cAAc,IAAI;AAAA,QACxB,UAAU;AAAA,MACZ,CAAC;AAAA,IACH,OAAO;AACL,YAAM,iBAAiB,UAAU;AAAA,QAC/B,MAAM;AAAA,QACN;AAAA,QACA,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,eAAe,UAAmC;AAC7D,UAAM,SAAS,MAAM,iBAAiB,SAAS,EAAE,MAAM,UAAU,UAAU,OAAO,CAAC;AACnF,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,cAAc,UAAkC;AAC3D,UAAM,SAAS,MAAM,iBAAiB,SAAS,EAAE,MAAM,UAAU,UAAU,SAAS,CAAC;AACrF,WAAO,gBAAgB,OAAO,IAAI;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,OAAO,YAAmC;AACrD,UAAM,iBAAiB,OAAO,EAAE,MAAM,WAAW,CAAC;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,MAAM,YAAmC;AACpD,UAAM,iBAAiB,MAAM,EAAE,MAAM,WAAW,CAAC;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,OAAO,YAAsC;AACxD,UAAM,SAAS,MAAM,iBAAiB,OAAO,EAAE,MAAM,WAAW,CAAC;AACjE,WAAO,OAAO;AAAA,EAChB;AACF;",
6
+ "names": []
7
+ }
@@ -1 +1 @@
1
- export {};
1
+ //# sourceMappingURL=IFileSystemPlugin.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -1,4 +1,5 @@
1
- import { IFileInfo, TStorage } from "./IFileSystemPlugin";
1
+ import type { IFileInfo, TStorage } from "./IFileSystemPlugin";
2
+ import type { Bytes } from "@simplysm/core-common";
2
3
  /**
3
4
  * 파일 시스템 접근 플러그인
4
5
  * - Android 11+: MANAGE_EXTERNAL_STORAGE 권한으로 전체 파일 시스템 접근
@@ -9,17 +10,17 @@ export declare abstract class FileSystem {
9
10
  /**
10
11
  * 권한 확인
11
12
  */
12
- static checkPermissionAsync(): Promise<boolean>;
13
+ static hasPermission(): Promise<boolean>;
13
14
  /**
14
15
  * 권한 요청
15
16
  * - Android 11+: 설정 화면으로 이동
16
17
  * - Android 10-: 권한 다이얼로그 표시
17
18
  */
18
- static requestPermissionAsync(): Promise<void>;
19
+ static requestPermission(): Promise<void>;
19
20
  /**
20
21
  * 디렉토리 읽기
21
22
  */
22
- static readdirAsync(dirPath: string): Promise<IFileInfo[]>;
23
+ static readdir(dirPath: string): Promise<IFileInfo[]>;
23
24
  /**
24
25
  * 저장소 경로 얻기
25
26
  * @param type 저장소 타입
@@ -31,33 +32,34 @@ export declare abstract class FileSystem {
31
32
  * - appFiles: 앱 파일 디렉토리
32
33
  * - appCache: 앱 캐시 디렉토리
33
34
  */
34
- static getStoragePathAsync(type: TStorage): Promise<string>;
35
+ static getStoragePath(type: TStorage): Promise<string>;
35
36
  /**
36
37
  * 파일 URI 얻기 (FileProvider)
37
38
  */
38
- static getFileUriAsync(filePath: string): Promise<string>;
39
+ static getFileUri(filePath: string): Promise<string>;
39
40
  /**
40
41
  * 파일 쓰기
41
42
  */
42
- static writeFileAsync(filePath: string, data: string | Buffer): Promise<void>;
43
+ static writeFile(filePath: string, data: string | Bytes): Promise<void>;
43
44
  /**
44
45
  * 파일 읽기 (UTF-8 문자열)
45
46
  */
46
- static readFileStringAsync(filePath: string): Promise<string>;
47
+ static readFileString(filePath: string): Promise<string>;
47
48
  /**
48
- * 파일 읽기 (Buffer)
49
+ * 파일 읽기 (Bytes)
49
50
  */
50
- static readFileBufferAsync(filePath: string): Promise<Buffer>;
51
+ static readFileBytes(filePath: string): Promise<Bytes>;
51
52
  /**
52
53
  * 파일/디렉토리 삭제 (재귀)
53
54
  */
54
- static removeAsync(targetPath: string): Promise<void>;
55
+ static remove(targetPath: string): Promise<void>;
55
56
  /**
56
57
  * 디렉토리 생성 (재귀)
57
58
  */
58
- static mkdirsAsync(targetPath: string): Promise<void>;
59
+ static mkdir(targetPath: string): Promise<void>;
59
60
  /**
60
61
  * 존재 여부 확인
61
62
  */
62
- static existsAsync(targetPath: string): Promise<boolean>;
63
+ static exists(targetPath: string): Promise<boolean>;
63
64
  }
65
+ //# sourceMappingURL=FileSystem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileSystem.d.ts","sourceRoot":"","sources":["../../../src/FileSystem.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAqB,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAUnD;;;;;GAKG;AACH,8BAAsB,UAAU;IAC9B;;OAEG;WACU,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC;IAK9C;;;;OAIG;WACU,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/C;;OAEG;WACU,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAK3D;;;;;;;;;;OAUG;WACU,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAK5D;;OAEG;WACU,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK1D;;OAEG;WACU,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB7E;;OAEG;WACU,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK9D;;OAEG;WACU,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAK5D;;OAEG;WACU,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD;;OAEG;WACU,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD;;OAEG;WACU,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAI1D"}
@@ -4,7 +4,7 @@ export interface IFileInfo {
4
4
  isDirectory: boolean;
5
5
  }
6
6
  export interface IFileSystemPlugin {
7
- checkPermission(): Promise<{
7
+ hasPermission(): Promise<{
8
8
  granted: boolean;
9
9
  }>;
10
10
  requestPermission(): Promise<void>;
@@ -46,3 +46,4 @@ export interface IFileSystemPlugin {
46
46
  exists: boolean;
47
47
  }>;
48
48
  }
49
+ //# sourceMappingURL=IFileSystemPlugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IFileSystemPlugin.d.ts","sourceRoot":"","sources":["../../../src/IFileSystemPlugin.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAChB,UAAU,GACV,eAAe,GACf,eAAe,GACf,eAAe,GACf,SAAS,GACT,UAAU,GACV,UAAU,CAAC;AAEf,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC/C,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,OAAO,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,SAAS,EAAE,CAAA;KAAE,CAAC,CAAC;IACpE,cAAc,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvE,UAAU,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChE,SAAS,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChG,QAAQ,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7F,MAAM,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,KAAK,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACjE"}
@@ -1,2 +1,3 @@
1
1
  export * from "./FileSystem";
2
2
  export * from "./IFileSystemPlugin";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC"}
@@ -1,8 +1,10 @@
1
1
  import { WebPlugin } from "@capacitor/core";
2
- import { IFileInfo, IFileSystemPlugin, TStorage } from "../IFileSystemPlugin";
2
+ import type { IFileInfo, IFileSystemPlugin, TStorage } from "../IFileSystemPlugin";
3
3
  export declare class FileSystemWeb extends WebPlugin implements IFileSystemPlugin {
4
4
  private readonly _fs;
5
- checkPermission(): Promise<{
5
+ private readonly _textEncoder;
6
+ private readonly _textDecoder;
7
+ hasPermission(): Promise<{
6
8
  granted: boolean;
7
9
  }>;
8
10
  requestPermission(): Promise<void>;
@@ -16,6 +18,11 @@ export declare class FileSystemWeb extends WebPlugin implements IFileSystemPlugi
16
18
  }): Promise<{
17
19
  path: string;
18
20
  }>;
21
+ /**
22
+ * 파일의 Blob URL을 반환합니다.
23
+ * @warning 반환된 URI는 사용 후 반드시 `URL.revokeObjectURL(uri)`를 호출하여 해제해야 합니다.
24
+ * 해제하지 않으면 메모리 누수가 발생할 수 있습니다.
25
+ */
19
26
  getFileUri(options: {
20
27
  path: string;
21
28
  }): Promise<{
@@ -44,3 +51,4 @@ export declare class FileSystemWeb extends WebPlugin implements IFileSystemPlugi
44
51
  exists: boolean;
45
52
  }>;
46
53
  }
54
+ //# sourceMappingURL=FileSystemWeb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileSystemWeb.d.ts","sourceRoot":"","sources":["../../../../src/web/FileSystemWeb.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAInF,qBAAa,aAAc,SAAQ,SAAU,YAAW,iBAAiB;IACvE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAqD;IACzE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAE5C,aAAa,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAI9C,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAElC,OAAO,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,SAAS,EAAE,CAAA;KAAE,CAAC;IASnE,cAAc,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAgC5E;;;;OAIG;IACG,UAAU,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAU/D,SAAS,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAS/F,QAAQ,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAU5F,MAAM,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAOhD,KAAK,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,MAAM,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC;CAItE"}