@webex/plugin-meetings 3.12.0-next.8 → 3.12.0-task-refactor.1
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/dist/annotation/index.js +5 -14
- package/dist/annotation/index.js.map +1 -1
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/config.js +2 -8
- package/dist/config.js.map +1 -1
- package/dist/constants.js +6 -29
- package/dist/constants.js.map +1 -1
- package/dist/hashTree/hashTreeParser.js +29 -1563
- package/dist/hashTree/hashTreeParser.js.map +1 -1
- package/dist/hashTree/types.js +3 -13
- package/dist/hashTree/types.js.map +1 -1
- package/dist/index.js +2 -11
- package/dist/index.js.map +1 -1
- package/dist/interceptors/index.js +0 -7
- package/dist/interceptors/index.js.map +1 -1
- package/dist/interceptors/locusRouteToken.js +5 -27
- package/dist/interceptors/locusRouteToken.js.map +1 -1
- package/dist/interpretation/index.js +2 -2
- package/dist/interpretation/index.js.map +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +3 -7
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +247 -642
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/selfUtils.js +0 -1
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/locus-info/types.js.map +1 -1
- package/dist/media/MediaConnectionAwaiter.js +1 -57
- package/dist/media/MediaConnectionAwaiter.js.map +1 -1
- package/dist/media/properties.js +2 -4
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +1 -7
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +1036 -1481
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +0 -50
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js.map +1 -1
- package/dist/meeting/util.js +3 -133
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.js +59 -142
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/util.js +7 -11
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +0 -10
- package/dist/member/index.js.map +1 -1
- package/dist/member/util.js +0 -10
- package/dist/member/util.js.map +1 -1
- package/dist/metrics/constants.js +1 -7
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +60 -9
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +0 -11
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +2 -116
- package/dist/multistream/sendSlotManager.js.map +1 -1
- package/dist/reachability/clusterReachability.js +18 -171
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/reachability/index.js +11 -21
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/reachabilityPeerConnection.js +1 -1
- package/dist/reachability/reachabilityPeerConnection.js.map +1 -1
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/reconnection-manager/index.js +1 -0
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/types/common/browser-detection.d.ts +0 -1
- package/dist/types/common/events/events-scope.d.ts +0 -1
- package/dist/types/common/events/events.d.ts +0 -1
- package/dist/types/config.d.ts +0 -5
- package/dist/types/constants.d.ts +1 -24
- package/dist/types/hashTree/hashTreeParser.d.ts +11 -260
- package/dist/types/hashTree/types.d.ts +0 -20
- package/dist/types/index.d.ts +0 -1
- package/dist/types/interceptors/index.d.ts +1 -2
- package/dist/types/interceptors/locusRouteToken.d.ts +0 -2
- package/dist/types/locus-info/index.d.ts +47 -68
- package/dist/types/locus-info/types.d.ts +12 -28
- package/dist/types/media/MediaConnectionAwaiter.d.ts +1 -10
- package/dist/types/media/properties.d.ts +1 -2
- package/dist/types/meeting/in-meeting-actions.d.ts +0 -6
- package/dist/types/meeting/index.d.ts +7 -86
- package/dist/types/meeting/request.d.ts +1 -16
- package/dist/types/meeting/request.type.d.ts +0 -5
- package/dist/types/meeting/util.d.ts +0 -31
- package/dist/types/meeting-info/util.d.ts +0 -1
- package/dist/types/meeting-info/utilv2.d.ts +0 -1
- package/dist/types/meetings/index.d.ts +2 -4
- package/dist/types/member/index.d.ts +0 -1
- package/dist/types/member/types.d.ts +4 -4
- package/dist/types/member/util.d.ts +0 -5
- package/dist/types/metrics/constants.d.ts +0 -6
- package/dist/types/multistream/mediaRequestManager.d.ts +23 -0
- package/dist/types/multistream/sendSlotManager.d.ts +1 -23
- package/dist/types/reachability/clusterReachability.d.ts +3 -30
- package/dist/types/reactions/reactions.type.d.ts +0 -1
- package/dist/types/recording-controller/util.d.ts +5 -5
- package/dist/types/roap/index.d.ts +1 -1
- package/dist/webinar/index.js +163 -438
- package/dist/webinar/index.js.map +1 -1
- package/package.json +24 -26
- package/src/annotation/index.ts +7 -27
- package/src/config.ts +0 -5
- package/src/constants.ts +1 -30
- package/src/hashTree/hashTreeParser.ts +25 -1523
- package/src/hashTree/types.ts +1 -24
- package/src/index.ts +1 -8
- package/src/interceptors/index.ts +1 -2
- package/src/interceptors/locusRouteToken.ts +5 -22
- package/src/interpretation/index.ts +2 -2
- package/src/locus-info/controlsUtils.ts +0 -17
- package/src/locus-info/index.ts +213 -707
- package/src/locus-info/selfUtils.ts +0 -1
- package/src/locus-info/types.ts +12 -27
- package/src/media/MediaConnectionAwaiter.ts +1 -41
- package/src/media/properties.ts +1 -3
- package/src/meeting/in-meeting-actions.ts +0 -12
- package/src/meeting/index.ts +84 -461
- package/src/meeting/request.ts +0 -42
- package/src/meeting/request.type.ts +0 -6
- package/src/meeting/util.ts +2 -160
- package/src/meetings/index.ts +60 -180
- package/src/meetings/util.ts +9 -10
- package/src/member/index.ts +0 -10
- package/src/member/util.ts +0 -12
- package/src/metrics/constants.ts +0 -7
- package/src/multistream/mediaRequestManager.ts +54 -4
- package/src/multistream/remoteMediaManager.ts +0 -13
- package/src/multistream/sendSlotManager.ts +3 -97
- package/src/reachability/clusterReachability.ts +27 -153
- package/src/reachability/index.ts +1 -15
- package/src/reachability/reachabilityPeerConnection.ts +1 -3
- package/src/reactions/reactions.type.ts +0 -1
- package/src/reconnection-manager/index.ts +1 -0
- package/src/webinar/index.ts +6 -265
- package/test/unit/spec/annotation/index.ts +7 -69
- package/test/unit/spec/interceptors/locusRouteToken.ts +0 -44
- package/test/unit/spec/locus-info/controlsUtils.js +1 -56
- package/test/unit/spec/locus-info/index.js +90 -1457
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +1 -41
- package/test/unit/spec/media/properties.ts +3 -12
- package/test/unit/spec/meeting/in-meeting-actions.ts +2 -8
- package/test/unit/spec/meeting/index.js +128 -981
- package/test/unit/spec/meeting/request.js +0 -70
- package/test/unit/spec/meeting/utils.js +26 -438
- package/test/unit/spec/meetings/index.js +33 -845
- package/test/unit/spec/meetings/utils.js +1 -51
- package/test/unit/spec/member/index.js +4 -28
- package/test/unit/spec/member/util.js +27 -65
- package/test/unit/spec/multistream/mediaRequestManager.ts +85 -2
- package/test/unit/spec/multistream/remoteMediaManager.ts +0 -30
- package/test/unit/spec/multistream/sendSlotManager.ts +36 -135
- package/test/unit/spec/reachability/clusterReachability.ts +1 -125
- package/test/unit/spec/reachability/index.ts +3 -26
- package/test/unit/spec/reconnection-manager/index.js +8 -4
- package/test/unit/spec/webinar/index.ts +37 -534
- package/dist/aiEnableRequest/index.js +0 -184
- package/dist/aiEnableRequest/index.js.map +0 -1
- package/dist/aiEnableRequest/utils.js +0 -36
- package/dist/aiEnableRequest/utils.js.map +0 -1
- package/dist/hashTree/constants.js +0 -22
- package/dist/hashTree/constants.js.map +0 -1
- package/dist/hashTree/hashTree.js +0 -533
- package/dist/hashTree/hashTree.js.map +0 -1
- package/dist/hashTree/utils.js +0 -69
- package/dist/hashTree/utils.js.map +0 -1
- package/dist/interceptors/constant.js +0 -12
- package/dist/interceptors/constant.js.map +0 -1
- package/dist/interceptors/dataChannelAuthToken.js +0 -290
- package/dist/interceptors/dataChannelAuthToken.js.map +0 -1
- package/dist/interceptors/utils.js +0 -27
- package/dist/interceptors/utils.js.map +0 -1
- package/dist/types/aiEnableRequest/index.d.ts +0 -5
- package/dist/types/aiEnableRequest/utils.d.ts +0 -2
- package/dist/types/hashTree/constants.d.ts +0 -9
- package/dist/types/hashTree/hashTree.d.ts +0 -136
- package/dist/types/hashTree/utils.d.ts +0 -22
- package/dist/types/interceptors/constant.d.ts +0 -5
- package/dist/types/interceptors/dataChannelAuthToken.d.ts +0 -43
- package/dist/types/interceptors/utils.d.ts +0 -1
- package/dist/types/webinar/utils.d.ts +0 -6
- package/dist/webinar/utils.js +0 -25
- package/dist/webinar/utils.js.map +0 -1
- package/src/aiEnableRequest/README.md +0 -84
- package/src/aiEnableRequest/index.ts +0 -170
- package/src/aiEnableRequest/utils.ts +0 -25
- package/src/hashTree/constants.ts +0 -10
- package/src/hashTree/hashTree.ts +0 -480
- package/src/hashTree/utils.ts +0 -62
- package/src/interceptors/constant.ts +0 -6
- package/src/interceptors/dataChannelAuthToken.ts +0 -170
- package/src/interceptors/utils.ts +0 -16
- package/src/webinar/utils.ts +0 -16
- package/test/unit/spec/aiEnableRequest/index.ts +0 -981
- package/test/unit/spec/aiEnableRequest/utils.ts +0 -130
- package/test/unit/spec/hashTree/hashTree.ts +0 -721
- package/test/unit/spec/hashTree/hashTreeParser.ts +0 -3670
- package/test/unit/spec/hashTree/utils.ts +0 -140
- package/test/unit/spec/interceptors/dataChannelAuthToken.ts +0 -210
- package/test/unit/spec/interceptors/utils.ts +0 -75
- package/test/unit/spec/webinar/utils.ts +0 -39
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import HashTree from './hashTree';
|
|
2
1
|
import { Enum } from '../constants';
|
|
3
|
-
import { HtMeta
|
|
2
|
+
import { HtMeta } from './types';
|
|
4
3
|
import { LocusDTO } from '../locus-info/types';
|
|
5
4
|
export interface DataSet {
|
|
6
5
|
url: string;
|
|
@@ -14,6 +13,10 @@ export interface DataSet {
|
|
|
14
13
|
exponent: number;
|
|
15
14
|
};
|
|
16
15
|
}
|
|
16
|
+
export interface HashTreeObject {
|
|
17
|
+
htMeta: HtMeta;
|
|
18
|
+
data: Record<string, any>;
|
|
19
|
+
}
|
|
17
20
|
export interface RootHashMessage {
|
|
18
21
|
dataSets: Array<DataSet>;
|
|
19
22
|
}
|
|
@@ -23,21 +26,9 @@ export interface HashTreeMessage {
|
|
|
23
26
|
locusStateElements?: Array<HashTreeObject>;
|
|
24
27
|
locusSessionId?: string;
|
|
25
28
|
locusUrl: string;
|
|
26
|
-
heartbeatIntervalMs?: number;
|
|
27
|
-
}
|
|
28
|
-
export interface VisibleDataSetInfo {
|
|
29
|
-
name: string;
|
|
30
|
-
url: string;
|
|
31
|
-
dataChannelUrl?: string;
|
|
32
|
-
}
|
|
33
|
-
export interface Metadata {
|
|
34
|
-
htMeta: HtMeta;
|
|
35
|
-
visibleDataSets: VisibleDataSetInfo[];
|
|
36
29
|
}
|
|
37
30
|
interface InternalDataSet extends DataSet {
|
|
38
|
-
hashTree?: HashTree;
|
|
39
31
|
timer?: ReturnType<typeof setTimeout>;
|
|
40
|
-
heartbeatWatchdogTimer?: ReturnType<typeof setTimeout>;
|
|
41
32
|
}
|
|
42
33
|
type WebexRequestMethod = (options: Record<string, any>) => Promise<any>;
|
|
43
34
|
export declare const LocusInfoUpdateType: {
|
|
@@ -49,11 +40,11 @@ export type LocusInfoUpdateCallback = (updateType: LocusInfoUpdateType, data?: {
|
|
|
49
40
|
updatedObjects: HashTreeObject[];
|
|
50
41
|
}) => void;
|
|
51
42
|
/**
|
|
52
|
-
*
|
|
53
|
-
*
|
|
43
|
+
* Checks if the given hash tree object is of type "self"
|
|
44
|
+
* @param {HashTreeObject} object object to check
|
|
45
|
+
* @returns {boolean} True if the object is of type "self", false otherwise
|
|
54
46
|
*/
|
|
55
|
-
export declare
|
|
56
|
-
}
|
|
47
|
+
export declare function isSelf(object: HashTreeObject): boolean;
|
|
57
48
|
/**
|
|
58
49
|
* Parses hash tree eventing locus data
|
|
59
50
|
*/
|
|
@@ -62,11 +53,8 @@ declare class HashTreeParser {
|
|
|
62
53
|
visibleDataSetsUrl: string;
|
|
63
54
|
webexRequest: WebexRequestMethod;
|
|
64
55
|
locusInfoUpdateCallback: LocusInfoUpdateCallback;
|
|
65
|
-
visibleDataSets:
|
|
56
|
+
visibleDataSets: string[];
|
|
66
57
|
debugId: string;
|
|
67
|
-
heartbeatIntervalMs?: number;
|
|
68
|
-
private excludedDataSets;
|
|
69
|
-
state: 'active' | 'stopped';
|
|
70
58
|
/**
|
|
71
59
|
* Constructor for HashTreeParser
|
|
72
60
|
* @param {Object} options
|
|
@@ -77,63 +65,10 @@ declare class HashTreeParser {
|
|
|
77
65
|
dataSets: Array<DataSet>;
|
|
78
66
|
locus: any;
|
|
79
67
|
};
|
|
80
|
-
metadata: Metadata | null;
|
|
81
68
|
webexRequest: WebexRequestMethod;
|
|
82
69
|
locusInfoUpdateCallback: LocusInfoUpdateCallback;
|
|
83
70
|
debugId: string;
|
|
84
|
-
excludedDataSets?: string[];
|
|
85
71
|
});
|
|
86
|
-
/**
|
|
87
|
-
* Sets the visible data sets list for the HashTreeParser. This method should be called only at the start, to initialize
|
|
88
|
-
* the visible data sets, before any message processsing, so for example from the constructor or when resuming the parser.
|
|
89
|
-
*
|
|
90
|
-
* @param {Array<VisibleDataSetInfo>} visibleDataSets - The visible data sets to set
|
|
91
|
-
* @param {Array<DataSet>} dataSets - The "dataSets" list from Locus (yes, Locus sends visibleDataSets and dataSets as separate lists and they can differ)
|
|
92
|
-
* @returns {void}
|
|
93
|
-
*/
|
|
94
|
-
private setVisibleDataSets;
|
|
95
|
-
/**
|
|
96
|
-
* Checks if the given data set name is in the list of visible data sets
|
|
97
|
-
* @param {string} dataSetName data set name to check
|
|
98
|
-
* @returns {Boolean} True if the data set is visible, false otherwise
|
|
99
|
-
*/
|
|
100
|
-
private isVisibleDataSet;
|
|
101
|
-
/**
|
|
102
|
-
* Checks if the given data set name is in the excluded list
|
|
103
|
-
* @param {string} dataSetName data set name to check
|
|
104
|
-
* @returns {boolean} True if the data set is excluded, false otherwise
|
|
105
|
-
*/
|
|
106
|
-
private isExcludedDataSet;
|
|
107
|
-
/**
|
|
108
|
-
* Adds a data set to the visible data sets list, unless it is in the excluded list.
|
|
109
|
-
* @param {VisibleDataSetInfo} dataSetInfo data set info to add
|
|
110
|
-
* @returns {boolean} True if the data set was added, false if it was excluded
|
|
111
|
-
*/
|
|
112
|
-
private addToVisibleDataSetsList;
|
|
113
|
-
/**
|
|
114
|
-
* Initializes a new visible data set by creating a hash tree for it, adding it to all the internal structures,
|
|
115
|
-
* and sending an initial sync request to Locus with empty leaf data - that will trigger Locus to gives us all the data
|
|
116
|
-
* from that dataset (in the response or via messages).
|
|
117
|
-
*
|
|
118
|
-
* @param {VisibleDataSetInfo} visibleDataSetInfo Information about the new visible data set
|
|
119
|
-
* @param {DataSet} dataSetInfo The new data set to be added
|
|
120
|
-
* @returns {Promise}
|
|
121
|
-
*/
|
|
122
|
-
private initializeNewVisibleDataSet;
|
|
123
|
-
/**
|
|
124
|
-
* Sends a special sync request to Locus with all leaves empty - this is a way to get all the data for a given dataset.
|
|
125
|
-
*
|
|
126
|
-
* @param {string} datasetName - name of the dataset for which to send the request
|
|
127
|
-
* @param {string} debugText - text to include in logs
|
|
128
|
-
* @returns {Promise}
|
|
129
|
-
*/
|
|
130
|
-
private sendInitializationSyncRequestToLocus;
|
|
131
|
-
/**
|
|
132
|
-
* Queries Locus for all up-to-date information about all visible data sets
|
|
133
|
-
*
|
|
134
|
-
* @returns {Promise}
|
|
135
|
-
*/
|
|
136
|
-
private getAllVisibleDataSetsFromLocus;
|
|
137
72
|
/**
|
|
138
73
|
* Initializes the hash tree parser from a message received from Locus.
|
|
139
74
|
*
|
|
@@ -151,64 +86,6 @@ declare class HashTreeParser {
|
|
|
151
86
|
* @returns {Promise}
|
|
152
87
|
*/
|
|
153
88
|
initializeFromGetLociResponse(locus: LocusDTO): Promise<void>;
|
|
154
|
-
/**
|
|
155
|
-
* Initializes data sets by doing an initialization sync on each visible data set that doesn't have a hash tree yet.
|
|
156
|
-
*
|
|
157
|
-
* @param {DataSet[]} visibleDataSets Array of visible DataSet objects to initialize
|
|
158
|
-
* @param {string} debugText Text to include in logs for debugging purposes
|
|
159
|
-
* @returns {Promise}
|
|
160
|
-
*/
|
|
161
|
-
private initializeDataSets;
|
|
162
|
-
/**
|
|
163
|
-
* Each dataset exists at a different place in the dto
|
|
164
|
-
* iterate recursively over the locus and if it has a htMeta key,
|
|
165
|
-
* create an object with the type, id and version and add it to the appropriate leafData array
|
|
166
|
-
*
|
|
167
|
-
* @param {any} locus - The current part of the locus being processed
|
|
168
|
-
* @param {Object} [options]
|
|
169
|
-
* @param {boolean} [options.copyData=false] - Whether to copy the data for each leaf into returned result
|
|
170
|
-
* @returns {any} - An object mapping dataset names to arrays of leaf data
|
|
171
|
-
*/
|
|
172
|
-
private analyzeLocusHtMeta;
|
|
173
|
-
/**
|
|
174
|
-
* Analyzes the Metadata object that is sent outside of Locus object, and appends its data to passed in leafInfo
|
|
175
|
-
* structure.
|
|
176
|
-
*
|
|
177
|
-
* @param {Record<string, LeafInfo[]>} leafInfo the structure to which the Metadata info will be appended
|
|
178
|
-
* @param {Metadata} metadata Metadata object
|
|
179
|
-
* @returns {void}
|
|
180
|
-
*/
|
|
181
|
-
private analyzeMetadata;
|
|
182
|
-
/**
|
|
183
|
-
* Checks if the provided hash tree message indicates the end of the meeting and that there won't be any more updates.
|
|
184
|
-
*
|
|
185
|
-
* @param {HashTreeMessage} message - The hash tree message to check
|
|
186
|
-
* @returns {boolean} - Returns true if the message indicates the end of the meeting, false otherwise
|
|
187
|
-
*/
|
|
188
|
-
private isEndMessage;
|
|
189
|
-
/**
|
|
190
|
-
* Handles the root hash heartbeat message
|
|
191
|
-
*
|
|
192
|
-
* @param {RootHashMessage} message - The root hash heartbeat message
|
|
193
|
-
* @returns {void}
|
|
194
|
-
*/
|
|
195
|
-
private handleRootHashHeartBeatMessage;
|
|
196
|
-
/**
|
|
197
|
-
* Asynchronously initializes new visible data sets
|
|
198
|
-
*
|
|
199
|
-
* @param {VisibleDataSetInfo[]} dataSetsRequiringInitialization list of datasets to initialize
|
|
200
|
-
* @returns {void}
|
|
201
|
-
*/
|
|
202
|
-
private queueInitForNewVisibleDataSets;
|
|
203
|
-
/**
|
|
204
|
-
* Handles updates to Metadata object that we receive from Locus via other means than messages. Right now
|
|
205
|
-
* that means only in the API response alongside locus object.
|
|
206
|
-
*
|
|
207
|
-
* @param {Metadata} metadata received in Locus update other than a message (for example in an API response)
|
|
208
|
-
* @param {HashTreeObject[]} updatedObjects a list of updated hash tree objects to which any updates resulting from new Metadata will be added
|
|
209
|
-
* @returns {void}
|
|
210
|
-
*/
|
|
211
|
-
handleMetadataUpdate(metadata: Metadata, updatedObjects: HashTreeObject[]): void;
|
|
212
89
|
/**
|
|
213
90
|
* This method should be called when we receive a partial locus DTO that contains dataSets and htMeta information
|
|
214
91
|
* It updates the hash trees with the new leaf data based on the received Locus
|
|
@@ -219,59 +96,7 @@ declare class HashTreeParser {
|
|
|
219
96
|
handleLocusUpdate(update: {
|
|
220
97
|
dataSets?: Array<DataSet>;
|
|
221
98
|
locus: any;
|
|
222
|
-
metadata?: Metadata;
|
|
223
99
|
}): void;
|
|
224
|
-
/**
|
|
225
|
-
* Updates the internal data set information based on the received data set from Locus.
|
|
226
|
-
*
|
|
227
|
-
* @param {DataSet} receivedDataSet - The latest data set information received from Locus to update the internal state.
|
|
228
|
-
* @returns {void}
|
|
229
|
-
*/
|
|
230
|
-
private updateDataSetInfo;
|
|
231
|
-
/**
|
|
232
|
-
* Checks for changes in the visible data sets based on the updated objects.
|
|
233
|
-
* @param {HashTreeObject[]} updatedObjects - The list of updated hash tree objects.
|
|
234
|
-
* @returns {Object} An object containing the removed and added visible data sets.
|
|
235
|
-
*/
|
|
236
|
-
private checkForVisibleDataSetChanges;
|
|
237
|
-
/**
|
|
238
|
-
* Deletes the hash tree for the specified data set.
|
|
239
|
-
*
|
|
240
|
-
* @param {string} dataSetName name of the data set to delete
|
|
241
|
-
* @returns {void}
|
|
242
|
-
*/
|
|
243
|
-
private deleteHashTree;
|
|
244
|
-
/**
|
|
245
|
-
* Adds entries to the passed in updateObjects array
|
|
246
|
-
* for the changes that result from removing visible data sets and creates hash
|
|
247
|
-
* trees for the new visible data sets, but without populating the hash trees.
|
|
248
|
-
*
|
|
249
|
-
* This function is synchronous. If we are missing information about some new
|
|
250
|
-
* visible data sets and they require async initialization, the names of these data sets
|
|
251
|
-
* are returned in an array.
|
|
252
|
-
*
|
|
253
|
-
* @param {VisibleDataSetInfo[]} removedDataSets - The list of removed data sets.
|
|
254
|
-
* @param {VisibleDataSetInfo[]} addedDataSets - The list of added data sets.
|
|
255
|
-
* @param {HashTreeObject[]} updatedObjects - The list of updated hash tree objects to which changes will be added.
|
|
256
|
-
* @returns {VisibleDataSetInfo[]} list of data sets that couldn't be initialized synchronously
|
|
257
|
-
*/
|
|
258
|
-
private processVisibleDataSetChanges;
|
|
259
|
-
/**
|
|
260
|
-
* Adds entries to the passed in updateObjects array
|
|
261
|
-
* for the changes that result from adding and removing visible data sets.
|
|
262
|
-
*
|
|
263
|
-
* @param {VisibleDataSetInfo[]} addedDataSets - The list of added data sets.
|
|
264
|
-
* @returns {Promise<void>}
|
|
265
|
-
*/
|
|
266
|
-
private initializeNewVisibleDataSets;
|
|
267
|
-
/**
|
|
268
|
-
* Parses incoming hash tree messages, updates the hash trees and returns information about the changes
|
|
269
|
-
*
|
|
270
|
-
* @param {HashTreeMessage} message - The hash tree message containing data sets and objects to be processed
|
|
271
|
-
* @param {string} [debugText] - Optional debug text to include in logs
|
|
272
|
-
* @returns {HashTreeObject[]} list of hash tree objects that were updated as a result of processing the message
|
|
273
|
-
*/
|
|
274
|
-
private parseMessage;
|
|
275
100
|
/**
|
|
276
101
|
* Handles incoming hash tree messages, updates the hash trees and calls locusInfoUpdateCallback
|
|
277
102
|
*
|
|
@@ -279,80 +104,6 @@ declare class HashTreeParser {
|
|
|
279
104
|
* @param {string} [debugText] - Optional debug text to include in logs
|
|
280
105
|
* @returns {void}
|
|
281
106
|
*/
|
|
282
|
-
handleMessage(message: HashTreeMessage, debugText?: string): void
|
|
283
|
-
/**
|
|
284
|
-
* Calls the updateInfo callback if there are any updates to report
|
|
285
|
-
*
|
|
286
|
-
* @param {Object} updates parsed from a Locus message
|
|
287
|
-
* @returns {void}
|
|
288
|
-
*/
|
|
289
|
-
private callLocusInfoUpdateCallback;
|
|
290
|
-
/**
|
|
291
|
-
* Calculates a weighted backoff time that should be used for syncs
|
|
292
|
-
*
|
|
293
|
-
* @param {Object} backoff - The backoff configuration containing maxMs and exponent
|
|
294
|
-
* @returns {number} - A weighted backoff time based on the provided configuration, using algorithm supplied by Locus team
|
|
295
|
-
*/
|
|
296
|
-
private getWeightedBackoffTime;
|
|
297
|
-
/**
|
|
298
|
-
* Performs a sync for the given data set.
|
|
299
|
-
*
|
|
300
|
-
* @param {InternalDataSet} dataSet - The data set to sync
|
|
301
|
-
* @param {string} rootHash - Our current root hash for this data set
|
|
302
|
-
* @param {string} reason - The reason for the sync (used for logging)
|
|
303
|
-
* @returns {Promise<void>}
|
|
304
|
-
*/
|
|
305
|
-
private performSync;
|
|
306
|
-
/**
|
|
307
|
-
* Runs the sync algorithm for the given data set.
|
|
308
|
-
*
|
|
309
|
-
* @param {DataSet} receivedDataSet - The data set to run the sync algorithm for.
|
|
310
|
-
* @returns {void}
|
|
311
|
-
*/
|
|
312
|
-
private runSyncAlgorithm;
|
|
313
|
-
/**
|
|
314
|
-
* Resets the heartbeat watchdog timers for the specified data sets. Each data set has its own
|
|
315
|
-
* watchdog timer that monitors whether heartbeats are being received within the expected interval.
|
|
316
|
-
* If a heartbeat is not received for a specific data set within heartbeatIntervalMs plus
|
|
317
|
-
* a backoff-calculated time, the sync algorithm is initiated for that data set
|
|
318
|
-
*
|
|
319
|
-
* @param {Array<DataSet>} receivedDataSets - The data sets from the received message for which watchdog timers should be reset
|
|
320
|
-
* @returns {void}
|
|
321
|
-
*/
|
|
322
|
-
private resetHeartbeatWatchdogs;
|
|
323
|
-
/**
|
|
324
|
-
* Stops all timers for the data sets to prevent any further sync attempts.
|
|
325
|
-
* @returns {void}
|
|
326
|
-
*/
|
|
327
|
-
private stopAllTimers;
|
|
328
|
-
/**
|
|
329
|
-
* Stops the HashTreeParser, preventing it from processing any further messages and clearing all timers.
|
|
330
|
-
* It also clears all the hash trees, so if the parser is resumed later, it will need to do a sync
|
|
331
|
-
* to be up-to-date.
|
|
332
|
-
* @returns {void}
|
|
333
|
-
*/
|
|
334
|
-
stop(): void;
|
|
335
|
-
/**
|
|
336
|
-
* Resumes the HashTreeParser that was previously stopped.
|
|
337
|
-
* @param {HashTreeMessage} message - The message to resume with, it must contain metadata with visible data sets info
|
|
338
|
-
* @returns {void}
|
|
339
|
-
*/
|
|
340
|
-
resume(message: HashTreeMessage): void;
|
|
341
|
-
private checkForSentinelHttpResponse;
|
|
342
|
-
/**
|
|
343
|
-
* Gets the current hashes from the locus for a specific data set.
|
|
344
|
-
* @param {string} dataSetName
|
|
345
|
-
* @param {string} currentRootHash
|
|
346
|
-
* @returns {string[]}
|
|
347
|
-
*/
|
|
348
|
-
private getHashesFromLocus;
|
|
349
|
-
/**
|
|
350
|
-
* Sends a sync request to Locus for the specified data set.
|
|
351
|
-
*
|
|
352
|
-
* @param {InternalDataSet} dataSet The data set to sync.
|
|
353
|
-
* @param {Record<number, LeafDataItem[]>} mismatchedLeavesData The mismatched leaves data to include in the sync request.
|
|
354
|
-
* @returns {Promise<HashTreeMessage|null>}
|
|
355
|
-
*/
|
|
356
|
-
private sendSyncRequestToLocus;
|
|
107
|
+
handleMessage(message: HashTreeMessage, debugText?: string): Promise<void>;
|
|
357
108
|
}
|
|
358
109
|
export default HashTreeParser;
|
|
@@ -4,24 +4,8 @@ export declare const ObjectType: {
|
|
|
4
4
|
readonly self: "self";
|
|
5
5
|
readonly locus: "locus";
|
|
6
6
|
readonly mediaShare: "mediashare";
|
|
7
|
-
readonly info: "info";
|
|
8
|
-
readonly fullState: "fullstate";
|
|
9
|
-
readonly links: "links";
|
|
10
|
-
readonly control: "controlentry";
|
|
11
|
-
readonly metadata: "metadata";
|
|
12
|
-
readonly embeddedApp: "embeddedapp";
|
|
13
7
|
};
|
|
14
8
|
export type ObjectType = Enum<typeof ObjectType>;
|
|
15
|
-
export declare const ObjectTypeToLocusKeyMap: {
|
|
16
|
-
links: string;
|
|
17
|
-
info: string;
|
|
18
|
-
fullstate: string;
|
|
19
|
-
self: string;
|
|
20
|
-
participant: string;
|
|
21
|
-
mediashare: string;
|
|
22
|
-
controlentry: string;
|
|
23
|
-
embeddedapp: string;
|
|
24
|
-
};
|
|
25
9
|
export interface HtMeta {
|
|
26
10
|
elementId: {
|
|
27
11
|
type: ObjectType;
|
|
@@ -30,7 +14,3 @@ export interface HtMeta {
|
|
|
30
14
|
};
|
|
31
15
|
dataSetNames: string[];
|
|
32
16
|
}
|
|
33
|
-
export interface HashTreeObject {
|
|
34
|
-
htMeta: HtMeta;
|
|
35
|
-
data: Record<string, any>;
|
|
36
|
-
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -19,4 +19,3 @@ export { type Reaction } from './reactions/reactions.type';
|
|
|
19
19
|
export { CaptchaError, IntentToJoinError, JoinMeetingError, PasswordError, PermissionError, ReclaimHostIsHostAlreadyError, ReclaimHostNotAllowedError, ReclaimHostNotSupportedError, ReclaimHostEmptyWrongKeyError, Meeting, MeetingInfoUtil, JoinWebinarError, SdpResponseTimeoutError, };
|
|
20
20
|
export { RemoteMedia } from './multistream/remoteMedia';
|
|
21
21
|
export { default as TriggerProxy } from './common/events/trigger-proxy';
|
|
22
|
-
export { getAIEnablementApprover } from './aiEnableRequest/utils';
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
import LocusRetryStatusInterceptor from './locusRetry';
|
|
2
2
|
import LocusRouteTokenInterceptor from './locusRouteToken';
|
|
3
|
-
|
|
4
|
-
export { LocusRetryStatusInterceptor, LocusRouteTokenInterceptor, DataChannelAuthTokenInterceptor };
|
|
3
|
+
export { LocusRetryStatusInterceptor, LocusRouteTokenInterceptor };
|
|
@@ -11,8 +11,6 @@ export default class LocusRouteTokenInterceptor extends Interceptor {
|
|
|
11
11
|
*/
|
|
12
12
|
static create(): LocusRouteTokenInterceptor;
|
|
13
13
|
getLocusIdByRequestUrl(url: string): string;
|
|
14
|
-
getLocusIdByResponseBody(body: any): any;
|
|
15
|
-
getHeader(headers: Record<string, string>, name: string): string;
|
|
16
14
|
/**
|
|
17
15
|
* @param {Object} options
|
|
18
16
|
* @param {HttpResponse} response
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import EventsScope from '../common/events/events-scope';
|
|
2
2
|
import { LOCUSEVENT } from '../constants';
|
|
3
|
-
import HashTreeParser, { DataSet, HashTreeMessage,
|
|
4
|
-
import {
|
|
5
|
-
import { Links, LocusDTO } from './types';
|
|
6
|
-
import MeetingCollection from '../meetings/collection';
|
|
3
|
+
import HashTreeParser, { DataSet, HashTreeMessage, HashTreeObject } from '../hashTree/hashTreeParser';
|
|
4
|
+
import { LocusDTO } from './types';
|
|
7
5
|
export type LocusLLMEvent = {
|
|
8
6
|
data: {
|
|
9
7
|
eventType: typeof LOCUSEVENT.HASH_TREE_DATA_UPDATED;
|
|
@@ -13,33 +11,6 @@ export type LocusLLMEvent = {
|
|
|
13
11
|
export type LocusApiResponseBody = {
|
|
14
12
|
dataSets?: DataSet[];
|
|
15
13
|
locus: LocusDTO;
|
|
16
|
-
metadata?: Metadata;
|
|
17
|
-
} | LocusDTO;
|
|
18
|
-
export type HashTreeParserEntry = {
|
|
19
|
-
parser: HashTreeParser;
|
|
20
|
-
replacedAt?: string;
|
|
21
|
-
initializedFromHashTree: boolean;
|
|
22
|
-
};
|
|
23
|
-
/**
|
|
24
|
-
* Finds a meeting for a given hash tree message.
|
|
25
|
-
*
|
|
26
|
-
* @param {HashTreeMessage} message - The hash tree message to find the meeting for
|
|
27
|
-
* @param {MeetingCollection} meetingCollection - The collection of meetings to search
|
|
28
|
-
* @param {string} deviceUrl - The URL of the user's device
|
|
29
|
-
* @returns {any} The meeting if found, otherwise undefined
|
|
30
|
-
*/
|
|
31
|
-
export declare function findMeetingForHashTreeMessage(message: HashTreeMessage, meetingCollection: MeetingCollection, deviceUrl: string): any;
|
|
32
|
-
/**
|
|
33
|
-
* Creates a locus object from the objects received in a hash tree message. It usually will be
|
|
34
|
-
* incomplete, because hash tree messages only contain the parts of locus that have changed,
|
|
35
|
-
* and some updates come separately over Mercury or LLM in separate messages.
|
|
36
|
-
*
|
|
37
|
-
* @param {HashTreeMessage} message hash tree message to created the locus from
|
|
38
|
-
* @returns {Object} the created locus object and metadata if present
|
|
39
|
-
*/
|
|
40
|
-
export declare function createLocusFromHashTreeMessage(message: HashTreeMessage): {
|
|
41
|
-
locus: LocusDTO;
|
|
42
|
-
metadata?: Metadata;
|
|
43
14
|
};
|
|
44
15
|
/**
|
|
45
16
|
* @description LocusInfo extends ChildEmitter to convert locusInfo info a private emitter to parent object
|
|
@@ -58,7 +29,10 @@ export default class LocusInfo extends EventsScope {
|
|
|
58
29
|
aclUrl: any;
|
|
59
30
|
baseSequence: any;
|
|
60
31
|
created: any;
|
|
32
|
+
identities: any;
|
|
33
|
+
membership: any;
|
|
61
34
|
participants: any;
|
|
35
|
+
participantsUrl: any;
|
|
62
36
|
replaces: any;
|
|
63
37
|
scheduledMeeting: any;
|
|
64
38
|
sequence: any;
|
|
@@ -70,11 +44,13 @@ export default class LocusInfo extends EventsScope {
|
|
|
70
44
|
info: any;
|
|
71
45
|
roles: any;
|
|
72
46
|
mediaShares: any;
|
|
47
|
+
replace: any;
|
|
73
48
|
url: any;
|
|
74
|
-
|
|
49
|
+
services: any;
|
|
50
|
+
resources: any;
|
|
75
51
|
mainSessionLocusCache: any;
|
|
76
52
|
self: any;
|
|
77
|
-
|
|
53
|
+
hashTreeParser?: HashTreeParser;
|
|
78
54
|
hashTreeObjectId2ParticipantId: Map<number, string>;
|
|
79
55
|
classicVsHashTreeMismatchMetricCounter: number;
|
|
80
56
|
/**
|
|
@@ -119,13 +95,9 @@ export default class LocusInfo extends EventsScope {
|
|
|
119
95
|
*/
|
|
120
96
|
init(locus?: any): void;
|
|
121
97
|
/**
|
|
122
|
-
* Creates
|
|
123
|
-
* @param {Object}
|
|
124
|
-
* @
|
|
125
|
-
* @param {Object} params.initialLocus - initial locus data
|
|
126
|
-
* @param {Object} params.metadata - hash tree metadata
|
|
127
|
-
* @param {string} params.replacedAt - timestamp from Locus indicating when the replacement happened
|
|
128
|
-
* @returns {HashTreeParser} the newly created parser
|
|
98
|
+
* Creates the HashTreeParser instance.
|
|
99
|
+
* @param {Object} initial locus data
|
|
100
|
+
* @returns {void}
|
|
129
101
|
*/
|
|
130
102
|
private createHashTreeParser;
|
|
131
103
|
/**
|
|
@@ -137,7 +109,6 @@ export default class LocusInfo extends EventsScope {
|
|
|
137
109
|
trigger: 'join-response';
|
|
138
110
|
locus: LocusDTO;
|
|
139
111
|
dataSets?: DataSet[];
|
|
140
|
-
metadata?: Metadata;
|
|
141
112
|
} | {
|
|
142
113
|
trigger: 'locus-message';
|
|
143
114
|
locus?: LocusDTO;
|
|
@@ -154,6 +125,7 @@ export default class LocusInfo extends EventsScope {
|
|
|
154
125
|
*/
|
|
155
126
|
handleLocusAPIResponse(meeting: any, responseBody: LocusApiResponseBody): void;
|
|
156
127
|
/**
|
|
128
|
+
*
|
|
157
129
|
* @param {HashTreeObject} object data set object
|
|
158
130
|
* @param {any} locus
|
|
159
131
|
* @returns {void}
|
|
@@ -167,13 +139,6 @@ export default class LocusInfo extends EventsScope {
|
|
|
167
139
|
* @returns {void}
|
|
168
140
|
*/
|
|
169
141
|
sendClassicVsHashTreeMismatchMetric(meeting: any, message: string): void;
|
|
170
|
-
/**
|
|
171
|
-
* Checks if the hash tree message should trigger a switch to a different HashTreeParser
|
|
172
|
-
*
|
|
173
|
-
* @param {HashTreeMessage} message incoming hash tree message
|
|
174
|
-
* @returns {boolean} true if the message was handled as a parser switch, false otherwise
|
|
175
|
-
*/
|
|
176
|
-
private handleHashTreeParserSwitch;
|
|
177
142
|
/**
|
|
178
143
|
* Handles a hash tree message received from Locus.
|
|
179
144
|
*
|
|
@@ -187,7 +152,6 @@ export default class LocusInfo extends EventsScope {
|
|
|
187
152
|
* Callback registered with HashTreeParser to receive locus info updates.
|
|
188
153
|
* Updates our locus info based on the data parsed by the hash tree parser.
|
|
189
154
|
*
|
|
190
|
-
* @param {string} locusUrl - the locus URL for which the update is received
|
|
191
155
|
* @param {LocusInfoUpdateType} updateType - The type of update received.
|
|
192
156
|
* @param {Object} [data] - Additional data for the update, if applicable.
|
|
193
157
|
* @returns {void}
|
|
@@ -211,9 +175,7 @@ export default class LocusInfo extends EventsScope {
|
|
|
211
175
|
/**
|
|
212
176
|
* Function for handling full locus when it's using hash trees (so not the "classic" one).
|
|
213
177
|
*
|
|
214
|
-
* @param {string} debugText string explaining the trigger for this call, added to logs for debugging purposes
|
|
215
178
|
* @param {object} locus locus object
|
|
216
|
-
* @param {object} metadata locus hash trees metadata
|
|
217
179
|
* @param {string} eventType locus event
|
|
218
180
|
* @param {DataSet[]} dataSets
|
|
219
181
|
* @returns {void}
|
|
@@ -222,7 +184,6 @@ export default class LocusInfo extends EventsScope {
|
|
|
222
184
|
/**
|
|
223
185
|
* Function for handling full locus when it's the "classic" one (not hash trees)
|
|
224
186
|
*
|
|
225
|
-
* @param {string} debugText string explaining the trigger for this call, added to logs for debugging purposes
|
|
226
187
|
* @param {object} locus locus object
|
|
227
188
|
* @param {string} eventType locus event
|
|
228
189
|
* @returns {void}
|
|
@@ -230,15 +191,13 @@ export default class LocusInfo extends EventsScope {
|
|
|
230
191
|
private onFullLocusClassic;
|
|
231
192
|
/**
|
|
232
193
|
* updates the locus with full locus object
|
|
233
|
-
* @param {string} debugText string explaining the trigger for this call, added to logs for debugging purposes
|
|
234
194
|
* @param {object} locus locus object
|
|
235
195
|
* @param {string} eventType locus event
|
|
236
196
|
* @param {DataSet[]} dataSets
|
|
237
|
-
* @param {object} metadata locus hash trees metadata
|
|
238
197
|
* @returns {object} null
|
|
239
198
|
* @memberof LocusInfo
|
|
240
199
|
*/
|
|
241
|
-
onFullLocus(
|
|
200
|
+
onFullLocus(locus: any, eventType?: string, dataSets?: Array<DataSet>): void;
|
|
242
201
|
/**
|
|
243
202
|
* Common part of handling full locus, used by both classic and hash tree based locus handling
|
|
244
203
|
* @param {object} locus locus object
|
|
@@ -252,13 +211,6 @@ export default class LocusInfo extends EventsScope {
|
|
|
252
211
|
* @memberof LocusInfo
|
|
253
212
|
*/
|
|
254
213
|
handleOneOnOneEvent(eventType: string): void;
|
|
255
|
-
/**
|
|
256
|
-
* Makes sure that passed in locus object has a participant object for self.
|
|
257
|
-
*
|
|
258
|
-
* @param {LocusDTO} locus The locus object to check and modify if needed
|
|
259
|
-
* @returns {void}
|
|
260
|
-
*/
|
|
261
|
-
ensureSelfParticipantExists(locus: any): void;
|
|
262
214
|
/**
|
|
263
215
|
* @param {Object} locus
|
|
264
216
|
* @returns {undefined}
|
|
@@ -270,7 +222,7 @@ export default class LocusInfo extends EventsScope {
|
|
|
270
222
|
* @returns {undefined}
|
|
271
223
|
* @memberof LocusInfo
|
|
272
224
|
*/
|
|
273
|
-
updateLocusInfo(locus: any):
|
|
225
|
+
updateLocusInfo(locus: any): void;
|
|
274
226
|
/**
|
|
275
227
|
* @param {Array} participants
|
|
276
228
|
* @param {Object} self
|
|
@@ -326,12 +278,21 @@ export default class LocusInfo extends EventsScope {
|
|
|
326
278
|
*/
|
|
327
279
|
updateCreated(created: object): void;
|
|
328
280
|
/**
|
|
329
|
-
*
|
|
330
|
-
* @param {Object} links
|
|
281
|
+
* @param {Object} services
|
|
331
282
|
* @returns {undefined}
|
|
332
283
|
* @memberof LocusInfo
|
|
333
284
|
*/
|
|
334
|
-
|
|
285
|
+
updateServices(services: Record<'breakout' | 'record', {
|
|
286
|
+
url: string;
|
|
287
|
+
}>): void;
|
|
288
|
+
/**
|
|
289
|
+
* @param {Object} resources
|
|
290
|
+
* @returns {undefined}
|
|
291
|
+
* @memberof LocusInfo
|
|
292
|
+
*/
|
|
293
|
+
updateResources(resources: Record<'webcastInstance', {
|
|
294
|
+
url: string;
|
|
295
|
+
}>): void;
|
|
335
296
|
/**
|
|
336
297
|
* @param {Object} fullState
|
|
337
298
|
* @returns {undefined}
|
|
@@ -369,11 +330,17 @@ export default class LocusInfo extends EventsScope {
|
|
|
369
330
|
*/
|
|
370
331
|
updateMediaShares(mediaShares: object, forceUpdate?: boolean): void;
|
|
371
332
|
/**
|
|
372
|
-
* @param {
|
|
333
|
+
* @param {String} participantsUrl
|
|
334
|
+
* @returns {undefined}
|
|
335
|
+
* @memberof LocusInfo
|
|
336
|
+
*/
|
|
337
|
+
updateParticipantsUrl(participantsUrl: string): void;
|
|
338
|
+
/**
|
|
339
|
+
* @param {Object} replace
|
|
373
340
|
* @returns {undefined}
|
|
374
341
|
* @memberof LocusInfo
|
|
375
342
|
*/
|
|
376
|
-
|
|
343
|
+
updateReplace(replace: object): void;
|
|
377
344
|
/**
|
|
378
345
|
* handles when the locus.self is updated
|
|
379
346
|
* @param {Object} self the new locus.self
|
|
@@ -408,6 +375,18 @@ export default class LocusInfo extends EventsScope {
|
|
|
408
375
|
* @memberof LocusInfo
|
|
409
376
|
*/
|
|
410
377
|
updateSequence(sequence: number): void;
|
|
378
|
+
/**
|
|
379
|
+
* @param {Object} membership
|
|
380
|
+
* @returns {undefined}
|
|
381
|
+
* @memberof LocusInfo
|
|
382
|
+
*/
|
|
383
|
+
updateMemberShip(membership: object): void;
|
|
384
|
+
/**
|
|
385
|
+
* @param {Array} identities
|
|
386
|
+
* @returns {undefined}
|
|
387
|
+
* @memberof LocusInfo
|
|
388
|
+
*/
|
|
389
|
+
updateIdentifiers(identities: Array<any>): void;
|
|
411
390
|
/**
|
|
412
391
|
* check the locus is main session's one or not, if is main session's, update main session cache
|
|
413
392
|
* @param {Object} locus
|