tirtc-react-native 2.3.1 → 2.4.0-alpha.4
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 +23 -7
- package/TiRtcReactNative.podspec +1 -1
- package/android/build.gradle +1 -1
- package/android/src/main/AndroidManifest.xml +2 -1
- package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcModule.kt +622 -28
- package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeCleanup.kt +115 -0
- package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeEventBinder.kt +32 -8
- package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeEventSink.kt +16 -0
- package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeMaps.kt +62 -0
- package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeModuleSupport.kt +6 -6
- package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeRegistry.kt +27 -0
- package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeStorageSupport.kt +64 -0
- package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcVideoOutputViewManager.kt +17 -2
- package/ios/TiRtcReactNative+Conn.mm +173 -2
- package/ios/TiRtcReactNative+Input.mm +18 -4
- package/ios/TiRtcReactNative+Output.mm +41 -4
- package/ios/TiRtcReactNative+Private.h +4 -0
- package/ios/TiRtcReactNative+Storage.mm +513 -0
- package/ios/TiRtcReactNative.h +2 -1
- package/ios/TiRtcReactNative.mm +109 -1
- package/ios/TiRtcReactNativeEventBinder.h +8 -0
- package/ios/TiRtcReactNativeEventBinder.mm +102 -0
- package/ios/TiRtcReactNativeEventSink.h +3 -0
- package/ios/TiRtcReactNativeEventSink.mm +16 -0
- package/ios/TiRtcReactNativeRegistry.h +5 -0
- package/ios/TiRtcReactNativeRegistry.mm +43 -0
- package/ios/TiRtcVideoOutputView.mm +11 -0
- package/lib/module/audio_input.js +33 -17
- package/lib/module/audio_input.js.map +1 -1
- package/lib/module/audio_output.js +27 -10
- package/lib/module/audio_output.js.map +1 -1
- package/lib/module/conn.js +31 -7
- package/lib/module/conn.js.map +1 -1
- package/lib/module/errors.js +4 -3
- package/lib/module/errors.js.map +1 -1
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/logging.js +9 -1
- package/lib/module/logging.js.map +1 -1
- package/lib/module/logging_internal.js +27 -0
- package/lib/module/logging_internal.js.map +1 -0
- package/lib/module/recording.js +210 -0
- package/lib/module/recording.js.map +1 -0
- package/lib/module/runtime.js +13 -5
- package/lib/module/runtime.js.map +1 -1
- package/lib/module/specs/NativeTiRtc.js.map +1 -1
- package/lib/module/storage.js +706 -0
- package/lib/module/storage.js.map +1 -0
- package/lib/module/video_input.js +40 -22
- package/lib/module/video_input.js.map +1 -1
- package/lib/module/video_output.js +51 -10
- package/lib/module/video_output.js.map +1 -1
- package/lib/typescript/audio_input.d.ts +1 -0
- package/lib/typescript/conn.d.ts +2 -0
- package/lib/typescript/errors.d.ts +3 -2
- package/lib/typescript/index.d.ts +4 -0
- package/lib/typescript/logging_internal.d.ts +2 -0
- package/lib/typescript/recording.d.ts +53 -0
- package/lib/typescript/runtime.d.ts +2 -0
- package/lib/typescript/specs/NativeTiRtc.d.ts +88 -0
- package/lib/typescript/storage.d.ts +204 -0
- package/lib/typescript/video_input.d.ts +1 -0
- package/lib/typescript/video_output.d.ts +3 -0
- package/package.json +1 -1
- package/src/audio_input.ts +85 -59
- package/src/audio_output.ts +30 -17
- package/src/conn.ts +46 -28
- package/src/errors.ts +4 -3
- package/src/index.ts +54 -0
- package/src/logging.ts +7 -1
- package/src/logging_internal.ts +23 -0
- package/src/recording.ts +271 -0
- package/src/runtime.ts +14 -5
- package/src/specs/NativeTiRtc.ts +123 -0
- package/src/storage.ts +769 -0
- package/src/video_input.ts +97 -62
- package/src/video_output.ts +54 -16
package/ios/TiRtcReactNative.mm
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
#import "TiRtcReactNative.h"
|
|
2
|
+
#import "TiRtcReactNative+Private.h"
|
|
2
3
|
|
|
3
4
|
#import <React/RCTBridgeModule.h>
|
|
4
5
|
|
|
6
|
+
#import <atomic>
|
|
5
7
|
#import <memory>
|
|
6
8
|
|
|
7
9
|
#import "TiRtcReactNativeErrors.h"
|
|
@@ -12,23 +14,51 @@
|
|
|
12
14
|
#import "TiRtcReactNativeOptions.h"
|
|
13
15
|
#import "TiRtcReactNativeRegistry.h"
|
|
14
16
|
|
|
17
|
+
@protocol TiRtcReactNativeMediaFile <NSObject>
|
|
18
|
+
- (void)deleteWithCompletion:(void (^)(int32_t code))completion;
|
|
19
|
+
@end
|
|
20
|
+
|
|
21
|
+
static void TiRtcReactNativeLogInvalidationFailure(NSString* operation, int32_t code) {
|
|
22
|
+
if (code == 0 || code == TiRtcReactNativeErrorObjectReleased) return;
|
|
23
|
+
[TiRtcLogging logWithLevel:TiRtcLogLevelWarning
|
|
24
|
+
tag:@"TIRTC_REACT_NATIVE"
|
|
25
|
+
message:[NSString stringWithFormat:
|
|
26
|
+
@"[module_invalidate] operation=%@ error_code=%d",
|
|
27
|
+
operation, code]];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static void TiRtcReactNativeDeleteForInvalidation(id file, dispatch_group_t group) {
|
|
31
|
+
if (file == nil || ![file respondsToSelector:@selector(deleteWithCompletion:)]) return;
|
|
32
|
+
dispatch_group_enter(group);
|
|
33
|
+
[(id<TiRtcReactNativeMediaFile>)file deleteWithCompletion:^(int32_t code) {
|
|
34
|
+
TiRtcReactNativeLogInvalidationFailure(@"media_delete", code);
|
|
35
|
+
dispatch_group_leave(group);
|
|
36
|
+
}];
|
|
37
|
+
}
|
|
38
|
+
|
|
15
39
|
#pragma clang diagnostic push
|
|
16
40
|
#pragma clang diagnostic ignored "-Wprotocol"
|
|
17
41
|
@implementation TiRtcReactNative {
|
|
18
42
|
TiRtcReactNativeRegistry* _registry;
|
|
19
43
|
TiRtcReactNativeEventSink* _eventSink;
|
|
20
44
|
TiRtcReactNativeEventBinder* _eventBinder;
|
|
45
|
+
std::atomic_bool _invalidated;
|
|
21
46
|
}
|
|
22
47
|
|
|
23
48
|
RCT_EXPORT_MODULE(TiRtc)
|
|
24
49
|
|
|
25
50
|
- (instancetype)init {
|
|
26
51
|
if (self = [super init]) {
|
|
52
|
+
_invalidated.store(false);
|
|
27
53
|
_registry = [TiRtcReactNativeRegistry sharedRegistry];
|
|
28
54
|
__weak TiRtcReactNative* weakSelf = self;
|
|
29
55
|
_eventSink = [[TiRtcReactNativeEventSink alloc] initWithRegistry:_registry
|
|
30
56
|
emitBlock:^(NSDictionary* event) {
|
|
31
|
-
|
|
57
|
+
TiRtcReactNative* strongSelf = weakSelf;
|
|
58
|
+
if (strongSelf != nil &&
|
|
59
|
+
!strongSelf->_invalidated.load()) {
|
|
60
|
+
[strongSelf emitOnTiRtcEvent:event];
|
|
61
|
+
}
|
|
32
62
|
}];
|
|
33
63
|
[_registry setEventSink:_eventSink];
|
|
34
64
|
_eventBinder = [[TiRtcReactNativeEventBinder alloc] initWithEventSink:_eventSink];
|
|
@@ -36,6 +66,84 @@ RCT_EXPORT_MODULE(TiRtc)
|
|
|
36
66
|
return self;
|
|
37
67
|
}
|
|
38
68
|
|
|
69
|
+
- (void)invalidate {
|
|
70
|
+
if (_invalidated.exchange(true)) return;
|
|
71
|
+
NSArray* objects = [_registry drainObjects];
|
|
72
|
+
NSArray* files = [_registry drainTransientObjects];
|
|
73
|
+
dispatch_group_t pending = dispatch_group_create();
|
|
74
|
+
for (id file in files) TiRtcReactNativeDeleteForInvalidation(file, pending);
|
|
75
|
+
for (id object in objects) {
|
|
76
|
+
if ([object isKindOfClass:[TiRtcRecordingTask class]]) {
|
|
77
|
+
dispatch_group_enter(pending);
|
|
78
|
+
[(TiRtcRecordingTask*)object stopWithCompletion:^(TiRtcRecordingResult* result) {
|
|
79
|
+
TiRtcReactNativeDeleteForInvalidation(result.file, pending);
|
|
80
|
+
dispatch_group_leave(pending);
|
|
81
|
+
}];
|
|
82
|
+
} else if ([object isKindOfClass:[TiCloudStorageRecordingTask class]]) {
|
|
83
|
+
dispatch_group_enter(pending);
|
|
84
|
+
[(TiCloudStorageRecordingTask*)object stopWithCompletion:^(TiCloudStorageRecordingResult* result) {
|
|
85
|
+
TiRtcReactNativeDeleteForInvalidation(result.file, pending);
|
|
86
|
+
dispatch_group_leave(pending);
|
|
87
|
+
}];
|
|
88
|
+
} else if ([object conformsToProtocol:@protocol(TiRtcReactNativeReloadTask)]) {
|
|
89
|
+
dispatch_group_enter(pending);
|
|
90
|
+
[(id<TiRtcReactNativeReloadTask>)object
|
|
91
|
+
stopForReactNativeInvalidation:^(id file) {
|
|
92
|
+
TiRtcReactNativeDeleteForInvalidation(file, pending);
|
|
93
|
+
dispatch_group_leave(pending);
|
|
94
|
+
}];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
dispatch_group_notify(pending, dispatch_get_main_queue(), ^{
|
|
98
|
+
for (TiCloudStorageAudioOutput* output in objects) {
|
|
99
|
+
if (![output isKindOfClass:[TiCloudStorageAudioOutput class]]) continue;
|
|
100
|
+
TiRtcReactNativeLogInvalidationFailure(@"ti-cloud-storage-audio-detach", [output detach]);
|
|
101
|
+
TiRtcReactNativeLogInvalidationFailure(@"ti-cloud-storage-audio-dispose", [output dispose]);
|
|
102
|
+
}
|
|
103
|
+
for (TiCloudStorageVideoOutput* output in objects) {
|
|
104
|
+
if (![output isKindOfClass:[TiCloudStorageVideoOutput class]]) continue;
|
|
105
|
+
TiRtcReactNativeLogInvalidationFailure(@"ti-cloud-storage-video-detach", [output detach]);
|
|
106
|
+
TiRtcReactNativeLogInvalidationFailure(@"ti-cloud-storage-video-view-detach", [output detachView]);
|
|
107
|
+
TiRtcReactNativeLogInvalidationFailure(@"ti-cloud-storage-video-dispose", [output dispose]);
|
|
108
|
+
}
|
|
109
|
+
for (TiRtcAudioOutput* output in objects) {
|
|
110
|
+
if ([output isKindOfClass:[TiRtcAudioOutput class]])
|
|
111
|
+
TiRtcReactNativeLogInvalidationFailure(@"audio_output_dispose", [output dispose]);
|
|
112
|
+
}
|
|
113
|
+
for (TiRtcVideoOutput* output in objects) {
|
|
114
|
+
if ([output isKindOfClass:[TiRtcVideoOutput class]])
|
|
115
|
+
TiRtcReactNativeLogInvalidationFailure(@"video_output_dispose", [output dispose]);
|
|
116
|
+
}
|
|
117
|
+
for (TiRtcAudioInput* input in objects) {
|
|
118
|
+
if ([input isKindOfClass:[TiRtcAudioInput class]])
|
|
119
|
+
TiRtcReactNativeLogInvalidationFailure(@"audio_input_dispose", [input dispose]);
|
|
120
|
+
}
|
|
121
|
+
for (TiRtcVideoInput* input in objects) {
|
|
122
|
+
if ([input isKindOfClass:[TiRtcVideoInput class]])
|
|
123
|
+
TiRtcReactNativeLogInvalidationFailure(@"video_input_dispose", [input dispose]);
|
|
124
|
+
}
|
|
125
|
+
for (TiCloudStorageReplay* replay in objects) {
|
|
126
|
+
if (![replay isKindOfClass:[TiCloudStorageReplay class]]) continue;
|
|
127
|
+
TiRtcReactNativeLogInvalidationFailure(@"ti-cloud-storage-replay-stop", [replay stop]);
|
|
128
|
+
TiRtcReactNativeLogInvalidationFailure(@"ti-cloud-storage-replay-dispose", [replay dispose]);
|
|
129
|
+
}
|
|
130
|
+
for (TiRtcConn* conn in objects) {
|
|
131
|
+
if (![conn isKindOfClass:[TiRtcConn class]]) continue;
|
|
132
|
+
TiRtcReactNativeLogInvalidationFailure(@"conn_disconnect", [conn disconnect]);
|
|
133
|
+
TiRtcReactNativeLogInvalidationFailure(@"conn_dispose", [conn dispose]);
|
|
134
|
+
}
|
|
135
|
+
for (TiCloudStorage* cloudStorage in objects) {
|
|
136
|
+
if ([cloudStorage isKindOfClass:[TiCloudStorage class]])
|
|
137
|
+
TiRtcReactNativeLogInvalidationFailure(@"ti-cloud-storage-dispose", [cloudStorage dispose]);
|
|
138
|
+
}
|
|
139
|
+
TiRtcReactNativeLogInvalidationFailure(@"ti-cloud-storage-shutdown", [TiCloudStorage shutdown]);
|
|
140
|
+
TiRtcReactNativeLogInvalidationFailure(@"runtime_shutdown", [TiRtc shutdown]);
|
|
141
|
+
[TiRtcLogging logWithLevel:TiRtcLogLevelInfo
|
|
142
|
+
tag:@"TIRTC_REACT_NATIVE"
|
|
143
|
+
message:@"[module_invalidate] native owners released"];
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
39
147
|
- (void)initialize:(JS::NativeTiRtc::NativeInitOptions&)options
|
|
40
148
|
resolve:(RCTPromiseResolveBlock)resolve
|
|
41
149
|
reject:(RCTPromiseRejectBlock)reject {
|
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
@class TiRtcReactNativeEventSink;
|
|
7
7
|
@class TiRtcVideoInput;
|
|
8
8
|
@class TiRtcVideoOutput;
|
|
9
|
+
@class TiCloudStorage;
|
|
10
|
+
@class TiCloudStorageAudioOutput;
|
|
11
|
+
@class TiCloudStorageReplay;
|
|
12
|
+
@class TiCloudStorageVideoOutput;
|
|
9
13
|
|
|
10
14
|
@interface TiRtcReactNativeEventBinder : NSObject
|
|
11
15
|
|
|
@@ -15,5 +19,9 @@
|
|
|
15
19
|
- (id)wireVideoOutput:(TiRtcVideoOutput*)output objectId:(NSInteger)objectId;
|
|
16
20
|
- (id)wireAudioInput:(TiRtcAudioInput*)input objectId:(NSInteger)objectId;
|
|
17
21
|
- (id)wireVideoInput:(TiRtcVideoInput*)input objectId:(NSInteger)objectId;
|
|
22
|
+
- (id)wireCloudStorage:(TiCloudStorage*)cloudStorage objectId:(NSInteger)objectId;
|
|
23
|
+
- (id)wireCloudStorageReplay:(TiCloudStorageReplay*)replay objectId:(NSInteger)objectId;
|
|
24
|
+
- (id)wireCloudStorageAudioOutput:(TiCloudStorageAudioOutput*)output objectId:(NSInteger)objectId;
|
|
25
|
+
- (id)wireCloudStorageVideoOutput:(TiCloudStorageVideoOutput*)output objectId:(NSInteger)objectId;
|
|
18
26
|
|
|
19
27
|
@end
|
|
@@ -116,6 +116,82 @@
|
|
|
116
116
|
eventSink:(TiRtcReactNativeEventSink*)eventSink;
|
|
117
117
|
@end
|
|
118
118
|
|
|
119
|
+
@interface TiRtcReactNativeCloudStorageAudioOutputDelegate : NSObject <TiCloudStorageAudioOutputDelegate>
|
|
120
|
+
- (instancetype)initWithObjectId:(NSInteger)objectId
|
|
121
|
+
eventSink:(TiRtcReactNativeEventSink*)eventSink;
|
|
122
|
+
@end
|
|
123
|
+
|
|
124
|
+
@implementation TiRtcReactNativeCloudStorageAudioOutputDelegate {
|
|
125
|
+
NSInteger _objectId;
|
|
126
|
+
TiRtcReactNativeEventSink* _eventSink;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
- (instancetype)initWithObjectId:(NSInteger)objectId
|
|
130
|
+
eventSink:(TiRtcReactNativeEventSink*)eventSink {
|
|
131
|
+
if (self = [super init]) {
|
|
132
|
+
_objectId = objectId;
|
|
133
|
+
_eventSink = eventSink;
|
|
134
|
+
}
|
|
135
|
+
return self;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
- (void)audioOutput:(TiCloudStorageAudioOutput*)output didChangeState:(TiCloudStorageAudioOutputState)state {
|
|
139
|
+
NSString* value;
|
|
140
|
+
switch (state) {
|
|
141
|
+
case TiCloudStorageAudioOutputStateIdle: value = @"idle"; break;
|
|
142
|
+
case TiCloudStorageAudioOutputStateBuffering: value = @"buffering"; break;
|
|
143
|
+
case TiCloudStorageAudioOutputStatePlaying: value = @"playing"; break;
|
|
144
|
+
case TiCloudStorageAudioOutputStatePaused: value = @"paused"; break;
|
|
145
|
+
case TiCloudStorageAudioOutputStateCompleted: value = @"completed"; break;
|
|
146
|
+
case TiCloudStorageAudioOutputStateFailed: default: value = @"failed"; break;
|
|
147
|
+
}
|
|
148
|
+
[_eventSink audioOutputStateChanged:_objectId state:value];
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
- (void)audioOutput:(TiCloudStorageAudioOutput*)output didFailWithCode:(int32_t)code {
|
|
152
|
+
[_eventSink audioOutputError:_objectId code:code message:nil];
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
@end
|
|
156
|
+
|
|
157
|
+
@interface TiRtcReactNativeCloudStorageVideoOutputDelegate : NSObject <TiCloudStorageVideoOutputDelegate>
|
|
158
|
+
- (instancetype)initWithObjectId:(NSInteger)objectId
|
|
159
|
+
eventSink:(TiRtcReactNativeEventSink*)eventSink;
|
|
160
|
+
@end
|
|
161
|
+
|
|
162
|
+
@implementation TiRtcReactNativeCloudStorageVideoOutputDelegate {
|
|
163
|
+
NSInteger _objectId;
|
|
164
|
+
TiRtcReactNativeEventSink* _eventSink;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
- (instancetype)initWithObjectId:(NSInteger)objectId
|
|
168
|
+
eventSink:(TiRtcReactNativeEventSink*)eventSink {
|
|
169
|
+
if (self = [super init]) {
|
|
170
|
+
_objectId = objectId;
|
|
171
|
+
_eventSink = eventSink;
|
|
172
|
+
}
|
|
173
|
+
return self;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
- (void)videoOutput:(TiCloudStorageVideoOutput*)output didChangeState:(TiCloudStorageVideoOutputState)state {
|
|
177
|
+
NSString* value;
|
|
178
|
+
switch (state) {
|
|
179
|
+
case TiCloudStorageVideoOutputStateIdle: value = @"idle"; break;
|
|
180
|
+
case TiCloudStorageVideoOutputStateBuffering: value = @"buffering"; break;
|
|
181
|
+
case TiCloudStorageVideoOutputStateRendering: value = @"rendering"; break;
|
|
182
|
+
case TiCloudStorageVideoOutputStatePaused: value = @"paused"; break;
|
|
183
|
+
case TiCloudStorageVideoOutputStateCompleted: value = @"completed"; break;
|
|
184
|
+
case TiCloudStorageVideoOutputStateFailed: default: value = @"failed"; break;
|
|
185
|
+
}
|
|
186
|
+
[_eventSink videoOutputStateChanged:_objectId state:value];
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
- (void)videoOutput:(TiCloudStorageVideoOutput*)output didFailWithCode:(int32_t)code {
|
|
190
|
+
[_eventSink videoOutputError:_objectId code:code message:nil];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
@end
|
|
194
|
+
|
|
119
195
|
@implementation TiRtcReactNativeAudioInputDelegate {
|
|
120
196
|
NSInteger _objectId;
|
|
121
197
|
TiRtcReactNativeEventSink* _eventSink;
|
|
@@ -223,4 +299,30 @@
|
|
|
223
299
|
return delegate;
|
|
224
300
|
}
|
|
225
301
|
|
|
302
|
+
- (id)wireCloudStorage:(TiCloudStorage*)cloudStorage objectId:(NSInteger)objectId {
|
|
303
|
+
return nil;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
- (id)wireCloudStorageReplay:(TiCloudStorageReplay*)replay objectId:(NSInteger)objectId {
|
|
307
|
+
TiRtcReactNativeEventSink* sink = _eventSink;
|
|
308
|
+
replay.onTimeChanged = ^(int64_t timeMs) { [sink tiCloudStorageReplayTimeChanged:objectId timestampMs:timeMs]; };
|
|
309
|
+
replay.onCompleted = ^{ [sink tiCloudStorageReplayCompleted:objectId]; };
|
|
310
|
+
replay.onError = ^(int32_t code) { [sink tiCloudStorageReplayError:objectId code:code]; };
|
|
311
|
+
return nil;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
- (id)wireCloudStorageAudioOutput:(TiCloudStorageAudioOutput*)output objectId:(NSInteger)objectId {
|
|
315
|
+
TiRtcReactNativeCloudStorageAudioOutputDelegate* delegate =
|
|
316
|
+
[[TiRtcReactNativeCloudStorageAudioOutputDelegate alloc] initWithObjectId:objectId eventSink:_eventSink];
|
|
317
|
+
output.delegate = delegate;
|
|
318
|
+
return delegate;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
- (id)wireCloudStorageVideoOutput:(TiCloudStorageVideoOutput*)output objectId:(NSInteger)objectId {
|
|
322
|
+
TiRtcReactNativeCloudStorageVideoOutputDelegate* delegate =
|
|
323
|
+
[[TiRtcReactNativeCloudStorageVideoOutputDelegate alloc] initWithObjectId:objectId eventSink:_eventSink];
|
|
324
|
+
output.delegate = delegate;
|
|
325
|
+
return delegate;
|
|
326
|
+
}
|
|
327
|
+
|
|
226
328
|
@end
|
|
@@ -15,6 +15,9 @@ typedef void (^TiRtcReactNativeEmitBlock)(NSDictionary* event);
|
|
|
15
15
|
streamId:(uint8_t)streamId
|
|
16
16
|
timestampMs:(uint32_t)timestampMs
|
|
17
17
|
data:(NSData*)data;
|
|
18
|
+
- (void)tiCloudStorageReplayTimeChanged:(NSInteger)objectId timestampMs:(int64_t)timestampMs;
|
|
19
|
+
- (void)tiCloudStorageReplayCompleted:(NSInteger)objectId;
|
|
20
|
+
- (void)tiCloudStorageReplayError:(NSInteger)objectId code:(int32_t)code;
|
|
18
21
|
- (void)audioOutputStateChanged:(NSInteger)objectId state:(NSString*)state;
|
|
19
22
|
- (void)audioOutputError:(NSInteger)objectId code:(int32_t)code message:(NSString*)message;
|
|
20
23
|
- (void)videoOutputStateChanged:(NSInteger)objectId state:(NSString*)state;
|
|
@@ -43,6 +43,22 @@
|
|
|
43
43
|
[self emit:event];
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
- (void)tiCloudStorageReplayTimeChanged:(NSInteger)objectId timestampMs:(int64_t)timestampMs {
|
|
47
|
+
NSMutableDictionary* event = [self base:@"tiCloudStorageReplayTimeChanged" objectId:objectId];
|
|
48
|
+
event[@"timestampMs"] = @(timestampMs);
|
|
49
|
+
[self emit:event];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
- (void)tiCloudStorageReplayCompleted:(NSInteger)objectId {
|
|
53
|
+
[self emit:[self base:@"tiCloudStorageReplayCompleted" objectId:objectId]];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
- (void)tiCloudStorageReplayError:(NSInteger)objectId code:(int32_t)code {
|
|
57
|
+
NSMutableDictionary* event = [self base:@"tiCloudStorageReplayError" objectId:objectId];
|
|
58
|
+
event[@"code"] = @(TiRtcReactNativeNormalizeDarwin(code));
|
|
59
|
+
[self emit:event];
|
|
60
|
+
}
|
|
61
|
+
|
|
46
62
|
- (void)audioOutputStateChanged:(NSInteger)objectId state:(NSString*)state {
|
|
47
63
|
NSMutableDictionary* event = [self base:@"audioOutputStateChanged" objectId:objectId];
|
|
48
64
|
event[@"state"] = state;
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
- (NSInteger)addObject:(id)object;
|
|
10
10
|
- (NSInteger)addObject:(id)object generation:(NSInteger*)generation;
|
|
11
|
+
- (NSInteger)addTransientObject:(id)object;
|
|
12
|
+
- (id)transientObjectForId:(NSInteger)objectId;
|
|
13
|
+
- (void)releaseTransientObject:(NSInteger)objectId;
|
|
11
14
|
- (void)setEventSink:(TiRtcReactNativeEventSink*)eventSink;
|
|
12
15
|
- (void)setDelegate:(id)delegate forObjectId:(NSInteger)objectId;
|
|
13
16
|
- (id)objectForId:(NSInteger)objectId;
|
|
@@ -15,6 +18,8 @@
|
|
|
15
18
|
- (void)reportVideoOutputError:(NSInteger)objectId code:(int32_t)code message:(NSString*)message;
|
|
16
19
|
- (void)reportVideoInputError:(NSInteger)objectId code:(int32_t)code message:(NSString*)message;
|
|
17
20
|
- (void)releaseObject:(NSInteger)objectId;
|
|
21
|
+
- (NSArray*)drainObjects;
|
|
22
|
+
- (NSArray*)drainTransientObjects;
|
|
18
23
|
- (BOOL)hasLiveObjects;
|
|
19
24
|
|
|
20
25
|
@end
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
@implementation TiRtcReactNativeRegistry {
|
|
15
15
|
NSLock* _lock;
|
|
16
16
|
NSMutableDictionary<NSNumber*, TiRtcReactNativeRegistryEntry*>* _entries;
|
|
17
|
+
NSMutableDictionary<NSNumber*, id>* _transientEntries;
|
|
17
18
|
__weak TiRtcReactNativeEventSink* _eventSink;
|
|
18
19
|
NSInteger _nextId;
|
|
19
20
|
NSInteger _nextGeneration;
|
|
@@ -32,12 +33,34 @@
|
|
|
32
33
|
if (self = [super init]) {
|
|
33
34
|
_lock = [NSLock new];
|
|
34
35
|
_entries = [NSMutableDictionary new];
|
|
36
|
+
_transientEntries = [NSMutableDictionary new];
|
|
35
37
|
_nextId = 1;
|
|
36
38
|
_nextGeneration = 1;
|
|
37
39
|
}
|
|
38
40
|
return self;
|
|
39
41
|
}
|
|
40
42
|
|
|
43
|
+
- (NSInteger)addTransientObject:(id)object {
|
|
44
|
+
[_lock lock];
|
|
45
|
+
NSInteger objectId = _nextId++;
|
|
46
|
+
_transientEntries[@(objectId)] = object;
|
|
47
|
+
[_lock unlock];
|
|
48
|
+
return objectId;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
- (id)transientObjectForId:(NSInteger)objectId {
|
|
52
|
+
[_lock lock];
|
|
53
|
+
id object = _transientEntries[@(objectId)];
|
|
54
|
+
[_lock unlock];
|
|
55
|
+
return object;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
- (void)releaseTransientObject:(NSInteger)objectId {
|
|
59
|
+
[_lock lock];
|
|
60
|
+
[_transientEntries removeObjectForKey:@(objectId)];
|
|
61
|
+
[_lock unlock];
|
|
62
|
+
}
|
|
63
|
+
|
|
41
64
|
- (NSInteger)addObject:(id)object {
|
|
42
65
|
return [self addObject:object generation:nil];
|
|
43
66
|
}
|
|
@@ -109,6 +132,26 @@
|
|
|
109
132
|
[_lock unlock];
|
|
110
133
|
}
|
|
111
134
|
|
|
135
|
+
- (NSArray*)drainObjects {
|
|
136
|
+
[_lock lock];
|
|
137
|
+
NSMutableArray* objects = [NSMutableArray arrayWithCapacity:_entries.count];
|
|
138
|
+
for (TiRtcReactNativeRegistryEntry* entry in _entries.allValues) {
|
|
139
|
+
if (entry.object != nil) [objects addObject:entry.object];
|
|
140
|
+
}
|
|
141
|
+
[_entries removeAllObjects];
|
|
142
|
+
_eventSink = nil;
|
|
143
|
+
[_lock unlock];
|
|
144
|
+
return objects;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
- (NSArray*)drainTransientObjects {
|
|
148
|
+
[_lock lock];
|
|
149
|
+
NSArray* objects = [_transientEntries.allValues copy];
|
|
150
|
+
[_transientEntries removeAllObjects];
|
|
151
|
+
[_lock unlock];
|
|
152
|
+
return objects;
|
|
153
|
+
}
|
|
154
|
+
|
|
112
155
|
- (BOOL)hasLiveObjects {
|
|
113
156
|
[_lock lock];
|
|
114
157
|
BOOL hasObjects = _entries.count > 0;
|
|
@@ -115,6 +115,15 @@ static AVLayerVideoGravity TiRtcVideoOutputGravityForResizeMode(
|
|
|
115
115
|
_attachedObjectId = _nativeObjectId;
|
|
116
116
|
_attachedGeneration = _generation;
|
|
117
117
|
[self applyVideoLayerGeometry];
|
|
118
|
+
} else if ([object isKindOfClass:[TiCloudStorageVideoOutput class]]) {
|
|
119
|
+
int32_t code = [(TiCloudStorageVideoOutput*)object attachView:self];
|
|
120
|
+
if (code != 0) {
|
|
121
|
+
[registry reportVideoOutputError:_nativeObjectId code:code message:@"view attach failed"];
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
_attachedObjectId = _nativeObjectId;
|
|
125
|
+
_attachedGeneration = _generation;
|
|
126
|
+
[self applyVideoLayerGeometry];
|
|
118
127
|
}
|
|
119
128
|
}
|
|
120
129
|
|
|
@@ -125,6 +134,8 @@ static AVLayerVideoGravity TiRtcVideoOutputGravityForResizeMode(
|
|
|
125
134
|
id object = [[TiRtcReactNativeRegistry sharedRegistry] objectForId:objectId];
|
|
126
135
|
if ([object isKindOfClass:[TiRtcVideoOutput class]]) {
|
|
127
136
|
__unused int32_t code = [(TiRtcVideoOutput*)object detachView];
|
|
137
|
+
} else if ([object isKindOfClass:[TiCloudStorageVideoOutput class]]) {
|
|
138
|
+
__unused int32_t code = [(TiCloudStorageVideoOutput*)object detachView];
|
|
128
139
|
}
|
|
129
140
|
}
|
|
130
141
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { isPlainObject, isUInt8, normalizeCreateResult,
|
|
1
|
+
import { isPlainObject, isUInt8, normalizeCreateResult, returnNotInitializedIfDisposed, TIRTC_ERROR_INVALID_ARGUMENT, TIRTC_ERROR_OK, TIRTC_ERROR_NOT_INITIALIZED, } from './errors';
|
|
2
2
|
import { registerNativeEventHandler, unregisterNativeEventHandler } from './events';
|
|
3
3
|
import { clearNativeIdentity, readNativeIdentity, setNativeIdentity } from './native_object_id';
|
|
4
4
|
import { NativeTiRtc } from './native';
|
|
5
|
+
import { logRtcOutcome, logRtcState } from './logging_internal';
|
|
5
6
|
export class TiRtcAudioInput {
|
|
6
7
|
constructor() {
|
|
7
8
|
this.identity = null;
|
|
@@ -22,8 +23,12 @@ export class TiRtcAudioInput {
|
|
|
22
23
|
const result = normalizeCreateResult(NativeTiRtc.createAudioInput());
|
|
23
24
|
this.createCode = result.code;
|
|
24
25
|
if (result.code === TIRTC_ERROR_OK) {
|
|
25
|
-
this.adoptIdentity({
|
|
26
|
+
this.adoptIdentity({
|
|
27
|
+
objectId: result.objectId,
|
|
28
|
+
generation: result.generation,
|
|
29
|
+
});
|
|
26
30
|
}
|
|
31
|
+
logRtcOutcome('audio_input_create', result.code);
|
|
27
32
|
}
|
|
28
33
|
get state() {
|
|
29
34
|
if (this.identity !== null && !this.disposed) {
|
|
@@ -66,48 +71,48 @@ export class TiRtcAudioInput {
|
|
|
66
71
|
if (connIdentity === null) {
|
|
67
72
|
return Promise.resolve(TIRTC_ERROR_INVALID_ARGUMENT);
|
|
68
73
|
}
|
|
69
|
-
return this.enqueue(async () => {
|
|
74
|
+
return this.logged('audio_input_attach', this.enqueue(async () => {
|
|
70
75
|
const identity = this.ensureIdentity();
|
|
71
76
|
if (typeof identity === 'number') {
|
|
72
77
|
return identity;
|
|
73
78
|
}
|
|
74
79
|
return NativeTiRtc.audioInputAttach(identity.objectId, connIdentity.objectId, streamId);
|
|
75
|
-
});
|
|
80
|
+
}));
|
|
76
81
|
}
|
|
77
82
|
start() {
|
|
78
|
-
return this.enqueue(async () => {
|
|
83
|
+
return this.logged('audio_input_start', this.enqueue(async () => {
|
|
79
84
|
const identity = this.ensureIdentity();
|
|
80
85
|
if (typeof identity === 'number') {
|
|
81
86
|
return identity;
|
|
82
87
|
}
|
|
83
88
|
return NativeTiRtc.audioInputStart(identity.objectId);
|
|
84
|
-
});
|
|
89
|
+
}));
|
|
85
90
|
}
|
|
86
91
|
stop() {
|
|
87
|
-
return this.enqueue(async () => {
|
|
92
|
+
return this.logged('audio_input_stop', this.enqueue(async () => {
|
|
88
93
|
if (this.identity === null) {
|
|
89
94
|
return TIRTC_ERROR_OK;
|
|
90
95
|
}
|
|
91
96
|
return NativeTiRtc.audioInputStop(this.identity.objectId);
|
|
92
|
-
});
|
|
97
|
+
}));
|
|
93
98
|
}
|
|
94
99
|
detach(connection) {
|
|
95
100
|
const connIdentity = readNativeIdentity(connection);
|
|
96
101
|
if (connIdentity === null) {
|
|
97
102
|
return Promise.resolve(TIRTC_ERROR_INVALID_ARGUMENT);
|
|
98
103
|
}
|
|
99
|
-
return this.enqueue(async () => {
|
|
104
|
+
return this.logged('audio_input_detach', this.enqueue(async () => {
|
|
100
105
|
if (this.identity === null) {
|
|
101
106
|
return TIRTC_ERROR_OK;
|
|
102
107
|
}
|
|
103
108
|
return NativeTiRtc.audioInputDetach(this.identity.objectId, connIdentity.objectId);
|
|
104
|
-
});
|
|
109
|
+
}));
|
|
105
110
|
}
|
|
106
111
|
dispose() {
|
|
107
112
|
if (this.disposed) {
|
|
108
113
|
return Promise.resolve(TIRTC_ERROR_OK);
|
|
109
114
|
}
|
|
110
|
-
return this.enqueue(async () => {
|
|
115
|
+
return this.logged('audio_input_dispose', this.enqueue(async () => {
|
|
111
116
|
if (this.identity === null) {
|
|
112
117
|
this.disposed = true;
|
|
113
118
|
this.clearCallbacks();
|
|
@@ -125,24 +130,30 @@ export class TiRtcAudioInput {
|
|
|
125
130
|
this.currentState = 'stopped';
|
|
126
131
|
}
|
|
127
132
|
return code;
|
|
128
|
-
}, true);
|
|
133
|
+
}, true));
|
|
129
134
|
}
|
|
130
135
|
enqueue(operation, allowDisposed = false) {
|
|
131
|
-
const released =
|
|
136
|
+
const released = returnNotInitializedIfDisposed(this.disposed);
|
|
132
137
|
if (released !== null && !allowDisposed) {
|
|
133
138
|
return Promise.resolve(released);
|
|
134
139
|
}
|
|
135
140
|
const next = this.queue.then(async () => {
|
|
136
141
|
if (this.disposed && !allowDisposed) {
|
|
137
|
-
return
|
|
142
|
+
return TIRTC_ERROR_NOT_INITIALIZED;
|
|
138
143
|
}
|
|
139
144
|
return operation();
|
|
140
145
|
});
|
|
141
146
|
this.queue = next.catch(() => undefined);
|
|
142
147
|
return next;
|
|
143
148
|
}
|
|
149
|
+
logged(operation, result) {
|
|
150
|
+
return result.then((code) => {
|
|
151
|
+
logRtcOutcome(operation, code);
|
|
152
|
+
return code;
|
|
153
|
+
});
|
|
154
|
+
}
|
|
144
155
|
ensureIdentity() {
|
|
145
|
-
const released =
|
|
156
|
+
const released = returnNotInitializedIfDisposed(this.disposed);
|
|
146
157
|
if (released !== null) {
|
|
147
158
|
return released;
|
|
148
159
|
}
|
|
@@ -166,11 +177,16 @@ export class TiRtcAudioInput {
|
|
|
166
177
|
return;
|
|
167
178
|
}
|
|
168
179
|
if (event.type === 'audioInputStateChanged' && event.state !== undefined) {
|
|
169
|
-
|
|
180
|
+
const nextState = event.state;
|
|
181
|
+
if (this.currentState !== nextState)
|
|
182
|
+
logRtcState('audio_input_state', nextState);
|
|
183
|
+
this.currentState = nextState;
|
|
170
184
|
this.onStateChanged?.(this.currentState);
|
|
171
185
|
}
|
|
172
186
|
else if (event.type === 'audioInputError') {
|
|
173
|
-
|
|
187
|
+
const code = event.code ?? TIRTC_ERROR_INVALID_ARGUMENT;
|
|
188
|
+
logRtcOutcome('audio_input', code);
|
|
189
|
+
this.onError?.(code, event.message ?? null);
|
|
174
190
|
}
|
|
175
191
|
}
|
|
176
192
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio_input.js","sourceRoot":"","sources":["../../src/audio_input.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,OAAO,EACP,qBAAqB,EACrB,
|
|
1
|
+
{"version":3,"file":"audio_input.js","sourceRoot":"","sources":["../../src/audio_input.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,OAAO,EACP,qBAAqB,EACrB,8BAA8B,EAC9B,4BAA4B,EAC5B,cAAc,EACd,2BAA2B,GAC5B,MAAM,UAAU,CAAC;AAClB,OAAO,EAAC,0BAA0B,EAAE,4BAA4B,EAAC,MAAM,UAAU,CAAC;AAClF,OAAO,EAAC,mBAAmB,EAAE,kBAAkB,EAAE,iBAAiB,EAAsB,MAAM,oBAAoB,CAAC;AACnH,OAAO,EAAC,WAAW,EAAwB,MAAM,UAAU,CAAC;AAC5D,OAAO,EAAC,aAAa,EAAE,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAI9D,MAAM,OAAO,eAAe;IAkB1B;QAjBQ,aAAQ,GAA0B,IAAI,CAAC;QACvC,aAAQ,GAAG,KAAK,CAAC;QACjB,eAAU,GAAW,cAAc,CAAC;QACpC,UAAK,GAAqB,OAAO,CAAC,OAAO,EAAE,CAAC;QAC5C,iBAAY,GAAoB,MAAM,CAAC;QACvC,YAAO,GAAqC;YAClD,KAAK,EAAE,OAAO;YACd,UAAU,EAAE,SAAS;YACrB,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,UAAU;YACnB,QAAQ,EAAE,UAAU;YACpB,QAAQ,EAAE,UAAU;SACrB,CAAC;QAEF,mBAAc,GAAoC,IAAI,CAAC;QACvD,YAAO,GAA6B,IAAI,CAAC;QAGvC,MAAM,MAAM,GAAG,qBAAqB,CAAC,WAAW,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACrE,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC;QAC9B,IAAI,MAAM,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YACnC,IAAI,CAAC,aAAa,CAAC;gBACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,UAAU,EAAE,MAAM,CAAC,UAAU;aAC9B,CAAC,CAAC;QACL,CAAC;QACD,aAAa,CAAC,oBAAoB,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,KAAK;QACP,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC7C,MAAM,MAAM,GAAG,WAAW,CAAC,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACtE,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;gBAC1B,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,KAAwB,CAAC;YACtD,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,UAAU,CAAC,OAA+B;QACxC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,OAAO,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC;QACvD,CAAC;QACD,MAAM,UAAU,GAAG;YACjB,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,OAAO;YAC/B,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,SAAS;YAC3C,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,MAAM;YACpC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,UAAU;YACtC,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,UAAU;YACxC,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,UAAU;SACzC,CAAC;QACF,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE;YAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YACvC,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBACjC,OAAO,QAAQ,CAAC;YAClB,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,oBAAoB,CAAC,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YACnF,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;gBAC5B,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC;YAC5B,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,UAAqB,EAAE,QAAgB;QAC5C,MAAM,YAAY,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;QACpD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvB,OAAO,OAAO,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO,OAAO,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC;QACvD,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAChB,oBAAoB,EACpB,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE;YACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YACvC,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBACjC,OAAO,QAAQ,CAAC;YAClB,CAAC;YACD,OAAO,WAAW,CAAC,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC1F,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAED,KAAK;QACH,OAAO,IAAI,CAAC,MAAM,CAChB,mBAAmB,EACnB,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE;YACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YACvC,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBACjC,OAAO,QAAQ,CAAC;YAClB,CAAC;YACD,OAAO,WAAW,CAAC,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACxD,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,MAAM,CAChB,kBAAkB,EAClB,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE;YACtB,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;gBAC3B,OAAO,cAAc,CAAC;YACxB,CAAC;YACD,OAAO,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC5D,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,UAAqB;QAC1B,MAAM,YAAY,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;QACpD,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO,OAAO,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC;QACvD,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAChB,oBAAoB,EACpB,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE;YACtB,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;gBAC3B,OAAO,cAAc,CAAC;YACxB,CAAC;YACD,OAAO,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;QACrF,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,OAAO,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAChB,qBAAqB,EACrB,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE;YACtB,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;gBAC3B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACrB,IAAI,CAAC,cAAc,EAAE,CAAC;gBACtB,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;gBAC9B,OAAO,cAAc,CAAC;YACxB,CAAC;YACD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;YAC/B,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,iBAAiB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACpE,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;gBAC5B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACrB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACrB,4BAA4B,CAAC,QAAQ,CAAC,CAAC;gBACvC,mBAAmB,CAAC,IAAI,CAAC,CAAC;gBAC1B,IAAI,CAAC,cAAc,EAAE,CAAC;gBACtB,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;YAChC,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,EAAE,IAAI,CAAC,CACT,CAAC;IACJ,CAAC;IAEO,OAAO,CAAC,SAAgC,EAAE,aAAa,GAAG,KAAK;QACrE,MAAM,QAAQ,GAAG,8BAA8B,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC/D,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACxC,OAAO,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YACtC,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,aAAa,EAAE,CAAC;gBACpC,OAAO,2BAA2B,CAAC;YACrC,CAAC;YACD,OAAO,SAAS,EAAE,CAAC;QACrB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,MAAM,CAAC,SAAiB,EAAE,MAAuB;QACvD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YAC1B,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAC/B,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,cAAc;QACpB,MAAM,QAAQ,GAAG,8BAA8B,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC/D,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtB,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC,QAAQ,CAAC;QACvB,CAAC;QACD,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAEO,aAAa,CAAC,QAAwB;QAC5C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAClC,0BAA0B,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACzE,KAAK,WAAW,CAAC,oBAAoB,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACzE,CAAC;IAEO,cAAc;QACpB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACtB,CAAC;IAEO,WAAW,CAAC,KAAuB;QACzC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,wBAAwB,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YACzE,MAAM,SAAS,GAAG,KAAK,CAAC,KAAwB,CAAC;YACjD,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS;gBAAE,WAAW,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAC;YACjF,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;YAC9B,IAAI,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC3C,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,4BAA4B,CAAC;YACxD,aAAa,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;YACnC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;CACF"}
|