@exode-team/react-recorder 1.1.0 → 1.1.2
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.
- package/README.md +84 -2
- package/dist/components/AudioRecorder.d.ts +1 -24
- package/dist/components/AudioRecorder.d.ts.map +1 -1
- package/dist/components/AudioRecorder.messages.d.ts +32 -0
- package/dist/components/AudioRecorder.messages.d.ts.map +1 -0
- package/dist/components/AudioRecorder.styled.d.ts +7 -0
- package/dist/components/AudioRecorder.styled.d.ts.map +1 -0
- package/dist/components/VoiceMessagePlayer/VoiceMessagePlayer.d.ts +4 -8
- package/dist/components/VoiceMessagePlayer/VoiceMessagePlayer.d.ts.map +1 -1
- package/dist/components/VoiceRecorderInput/PreviewBars.d.ts +17 -0
- package/dist/components/VoiceRecorderInput/PreviewBars.d.ts.map +1 -0
- package/dist/components/VoiceRecorderInput/TimelineBars.d.ts +12 -0
- package/dist/components/VoiceRecorderInput/TimelineBars.d.ts.map +1 -0
- package/dist/components/VoiceRecorderInput/VoiceRecorderInput.d.ts +2 -2
- package/dist/components/VoiceRecorderInput/VoiceRecorderInput.d.ts.map +1 -1
- package/dist/constants.d.ts +5 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/useAudioBlobLoader.d.ts +23 -0
- package/dist/hooks/useAudioBlobLoader.d.ts.map +1 -0
- package/dist/hooks/useAudioPlayback.d.ts.map +1 -1
- package/dist/hooks/useAudioRecorderHandlers.d.ts +22 -0
- package/dist/hooks/useAudioRecorderHandlers.d.ts.map +1 -0
- package/dist/hooks/useMediaRecorder.d.ts +1 -10
- package/dist/hooks/useMediaRecorder.d.ts.map +1 -1
- package/dist/hooks/useRecorderVisualization.d.ts.map +1 -1
- package/dist/hooks/useRecordingSender.d.ts +23 -0
- package/dist/hooks/useRecordingSender.d.ts.map +1 -0
- package/dist/hooks/useVoiceMessagePlayer.d.ts +1 -18
- package/dist/hooks/useVoiceMessagePlayer.d.ts.map +1 -1
- package/dist/hooks/useVoiceRecorder.d.ts.map +1 -1
- package/dist/hooks/useVoiceRecorderInput.d.ts +31 -0
- package/dist/hooks/useVoiceRecorderInput.d.ts.map +1 -0
- package/dist/index.cjs +1185 -862
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1086 -764
- package/dist/index.js.map +1 -1
- package/dist/platform/audio-blob-fetcher.d.ts +7 -0
- package/dist/platform/audio-blob-fetcher.d.ts.map +1 -0
- package/dist/platform/index.d.ts +1 -0
- package/dist/platform/index.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/recorder.d.ts +31 -0
- package/dist/types/recorder.d.ts.map +1 -1
- package/dist/utils/voice-blob-cache.d.ts +20 -0
- package/dist/utils/voice-blob-cache.d.ts.map +1 -0
- package/dist/utils/voice-playback-chain.d.ts +20 -0
- package/dist/utils/voice-playback-chain.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio-blob-fetcher.d.ts","sourceRoot":"","sources":["../../src/platform/audio-blob-fetcher.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,eAAO,MAAM,cAAc,GAAU,KAAK,MAAM,EAAE,SAAS,WAAW,KAAG,OAAO,CAAC,IAAI,CAIpF,CAAC"}
|
package/dist/platform/index.d.ts
CHANGED
|
@@ -11,5 +11,6 @@ export { createAudioPlayback, cleanupAudio, createObjectURL, revokeObjectURL } f
|
|
|
11
11
|
export type { AudioPlayback, PlaybackCallbacks } from './audio-playback-adapter';
|
|
12
12
|
export { createStreamAnalyzer, readFrequencyLevels, decodeAudioLevels } from './audio-analyzer-adapter';
|
|
13
13
|
export type { StreamAnalyzer } from './audio-analyzer-adapter';
|
|
14
|
+
export { fetchAudioBlob } from './audio-blob-fetcher';
|
|
14
15
|
export { scheduleFrame, cancelFrame } from './animation-frame-adapter';
|
|
15
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/platform/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC7E,YAAY,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAE1F,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC/G,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAEjF,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACxG,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/platform/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC7E,YAAY,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAE1F,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC/G,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAEjF,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACxG,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export type { StorageFileEntity, StorageSpace, UploadStrategy } from './upload';
|
|
7
7
|
export { StorageSpaceEnum } from './upload';
|
|
8
|
-
export type { UseVoiceRecorderOptions, UseVoiceRecorderResult } from './recorder';
|
|
8
|
+
export type { UseVoiceRecorderOptions, UseVoiceRecorderResult, UseVoiceMessagePlayerOptions, UseVoiceMessagePlayerResult, MediaRecorderCallbacks, } from './recorder';
|
|
9
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,YAAY,EACR,uBAAuB,EACvB,sBAAsB,EACtB,4BAA4B,EAC5B,2BAA2B,EAC3B,sBAAsB,GACzB,MAAM,YAAY,CAAC"}
|
package/dist/types/recorder.d.ts
CHANGED
|
@@ -39,4 +39,35 @@ export interface UseVoiceRecorderResult {
|
|
|
39
39
|
sendRecording: () => Promise<void>;
|
|
40
40
|
formatTime: (seconds: number) => string;
|
|
41
41
|
}
|
|
42
|
+
export interface UseVoiceMessagePlayerOptions {
|
|
43
|
+
src: string;
|
|
44
|
+
duration?: number;
|
|
45
|
+
waveformData?: number[];
|
|
46
|
+
preloadedBlob?: Blob | null;
|
|
47
|
+
onEnded?: () => void;
|
|
48
|
+
}
|
|
49
|
+
export interface UseVoiceMessagePlayerResult {
|
|
50
|
+
isPlaying: boolean;
|
|
51
|
+
isLoading: boolean;
|
|
52
|
+
isLoaded: boolean;
|
|
53
|
+
currentTime: number;
|
|
54
|
+
duration: number;
|
|
55
|
+
progress: number;
|
|
56
|
+
waveformLevels: number[];
|
|
57
|
+
play: () => void;
|
|
58
|
+
preload: () => void;
|
|
59
|
+
togglePlayback: () => void;
|
|
60
|
+
seekTo: (progress: number) => void;
|
|
61
|
+
formatTime: (seconds: number) => string;
|
|
62
|
+
}
|
|
63
|
+
export interface MediaRecorderCallbacks {
|
|
64
|
+
onDataChunk: (chunk: Blob) => void;
|
|
65
|
+
onNeedsPreview: (chunks: Blob[]) => void;
|
|
66
|
+
onStopped: (chunks: Blob[], discarded: boolean) => void;
|
|
67
|
+
onPaused: () => void;
|
|
68
|
+
onResumed: () => void;
|
|
69
|
+
onStreamAcquired: (stream: MediaStream) => void;
|
|
70
|
+
onPermissionDenied: (error: unknown) => void;
|
|
71
|
+
onError: (error: unknown) => void;
|
|
72
|
+
}
|
|
42
73
|
//# sourceMappingURL=recorder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../src/types/recorder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG7D,MAAM,WAAW,uBAAuB,CAAC,KAAK,GAAG,OAAO;IACpD,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACvC,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,QAAQ,CAAC,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,sBAAsB;IACnC,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,oBAAoB,EAAE,MAAM,IAAI,CAAC;IACjC,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;CAC3C"}
|
|
1
|
+
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../src/types/recorder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG7D,MAAM,WAAW,uBAAuB,CAAC,KAAK,GAAG,OAAO;IACpD,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACvC,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,QAAQ,CAAC,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,sBAAsB;IACnC,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,oBAAoB,EAAE,MAAM,IAAI,CAAC;IACjC,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;CAC3C;AAED,MAAM,WAAW,4BAA4B;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,2BAA2B;IACxC,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;CAC3C;AAED,MAAM,WAAW,sBAAsB;IACnC,WAAW,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,IAAI,CAAC;IACnC,cAAc,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACzC,SAAS,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IACxD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,gBAAgB,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;IAChD,kBAAkB,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACrC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VoiceBlobCache
|
|
3
|
+
*
|
|
4
|
+
* @description In-memory cache for voice message blobs.
|
|
5
|
+
* Allows instant playback of just-sent voice messages
|
|
6
|
+
* before the server URL becomes available.
|
|
7
|
+
*
|
|
8
|
+
* @author: exode <hello@exode.ru>
|
|
9
|
+
*/
|
|
10
|
+
declare class VoiceBlobCacheClass {
|
|
11
|
+
private cache;
|
|
12
|
+
set: (messageId: number, blob: Blob) => void;
|
|
13
|
+
get: (messageId: number) => Blob | undefined;
|
|
14
|
+
delete: (messageId: number) => void;
|
|
15
|
+
/** Transfer blob from optimistic ID to real server ID */
|
|
16
|
+
transfer: (fromId: number, toId: number) => void;
|
|
17
|
+
}
|
|
18
|
+
export declare const VoiceBlobCache: VoiceBlobCacheClass;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=voice-blob-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice-blob-cache.d.ts","sourceRoot":"","sources":["../../src/utils/voice-blob-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,cAAM,mBAAmB;IAErB,OAAO,CAAC,KAAK,CAA2B;IAExC,GAAG,GAAI,WAAW,MAAM,EAAE,MAAM,IAAI,UAElC;IAEF,GAAG,GAAI,WAAW,MAAM,KAAG,IAAI,GAAG,SAAS,CAEzC;IAEF,MAAM,GAAI,WAAW,MAAM,UAEzB;IAEF,yDAAyD;IACzD,QAAQ,GAAI,QAAQ,MAAM,EAAE,MAAM,MAAM,UAOtC;CAEL;AAGD,eAAO,MAAM,cAAc,qBAA4B,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VoicePlaybackChain
|
|
3
|
+
*
|
|
4
|
+
* @description Sequential voice message playback chain (like Telegram).
|
|
5
|
+
* Registers voice players by media ID and plays the next one when current ends.
|
|
6
|
+
*
|
|
7
|
+
* @author: exode <hello@exode.ru>
|
|
8
|
+
*/
|
|
9
|
+
declare class VoicePlaybackChainClass {
|
|
10
|
+
private entries;
|
|
11
|
+
/** Register a voice player. Returns cleanup function for useEffect. */
|
|
12
|
+
register: (id: number, play: () => void) => () => void;
|
|
13
|
+
/** Unregister a voice player by media ID */
|
|
14
|
+
unregister: (id: number) => void;
|
|
15
|
+
/** Play the next voice message after the given media ID */
|
|
16
|
+
playNext: (currentId: number) => void;
|
|
17
|
+
}
|
|
18
|
+
export declare const VoicePlaybackChain: VoicePlaybackChainClass;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=voice-playback-chain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice-playback-chain.d.ts","sourceRoot":"","sources":["../../src/utils/voice-playback-chain.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,cAAM,uBAAuB;IAEzB,OAAO,CAAC,OAAO,CAAoB;IAEnC,uEAAuE;IACvE,QAAQ,GAAI,IAAI,MAAM,EAAE,MAAM,MAAM,IAAI,gBAMtC;IAEF,4CAA4C;IAC5C,UAAU,GAAI,IAAI,MAAM,UAEtB;IAEF,2DAA2D;IAC3D,QAAQ,GAAI,WAAW,MAAM,UAM3B;CAEL;AAGD,eAAO,MAAM,kBAAkB,yBAAgC,CAAC"}
|