@digitalsamba/embedded-sdk 0.0.21 → 0.0.25

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.
@@ -8,6 +8,8 @@
8
8
  <!-- <script src="https://unpkg.com/@digitalsamba/embedded-sdk"></script>-->
9
9
  <script src="./index.js"></script>
10
10
  <script src="./helper.js"></script>
11
+ <script defer data-domain="digitalsamba.github.io" src="https://plausible.wbcnf.net/js/script.js"></script>
12
+ <script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
11
13
  <link rel="stylesheet" href="./style.css">
12
14
  </head>
13
15
 
@@ -96,6 +98,7 @@
96
98
 
97
99
  // load samba frame
98
100
  sambaEmbedded.load();
101
+ logRoomLoad();
99
102
 
100
103
  addJoiningHint(ROOM_URL);
101
104
  initializeParticipantList();
@@ -228,6 +231,67 @@
228
231
  }
229
232
  }
230
233
 
234
+ if(sambaEmbedded.featureEnabled('pin')) {
235
+ const pinControl = document.createElement('button');
236
+ pinControl.innerHTML = 'pin';
237
+ pinControl.style.margin = '0 4px';
238
+ pinControl.className = 'pin-' + user.id;
239
+
240
+ pinControl.onclick = () => {
241
+ sambaEmbedded.pinUser(user.id)
242
+ }
243
+
244
+ row.appendChild(pinControl);
245
+ }
246
+
247
+ if(sambaEmbedded.featureEnabled('fullScreen')) {
248
+ const fsControl = document.createElement('button');
249
+ fsControl.innerHTML = 'maximize';
250
+ fsControl.style.margin = '0 4px';
251
+ fsControl.className = 'fs-' + user.id;
252
+
253
+ fsControl.onclick = () => {
254
+ sambaEmbedded.maximizeUser(user.id)
255
+ }
256
+
257
+ row.appendChild(fsControl);
258
+ }
259
+
260
+ const ssControls = document.createElement('div');
261
+ ssControls.className = 'screenshare-buttons-' + user.id;
262
+ ssControls.style.opacity = 0;
263
+
264
+ row.appendChild(ssControls);
265
+
266
+ if(sambaEmbedded.featureEnabled('screenshare')) {
267
+ if(sambaEmbedded.featureEnabled('pin')) {
268
+ const ssPinControl = document.createElement('button');
269
+ ssPinControl.innerHTML = 'pin screenshare';
270
+ ssPinControl.style.margin = '0 4px';
271
+ ssPinControl.className = 'ss-pin-' + user.id;
272
+
273
+ ssPinControl.onclick = () => {
274
+ sambaEmbedded.pinUser(user.id, 'screenshare')
275
+ }
276
+
277
+ ssControls.appendChild(ssPinControl);
278
+ }
279
+
280
+ if(sambaEmbedded.featureEnabled('fullScreen')) {
281
+ const ssFsControl = document.createElement('button');
282
+ ssFsControl.innerHTML = 'maximize screenshare';
283
+ ssFsControl.style.margin = '0 4px';
284
+ ssFsControl.className = 'ss-fs-' + user.id;
285
+
286
+ ssFsControl.onclick = () => {
287
+ sambaEmbedded.maximizeUser(user.id, 'screenshare')
288
+ }
289
+
290
+ ssControls.appendChild(ssFsControl);
291
+ }
292
+ }
293
+
294
+
231
295
  const raisedHandControl = document.createElement('button');
232
296
  raisedHandControl.id = 'lower-hand-' + user.id;
233
297
  raisedHandControl.innerHTML = 'lower hand'
@@ -271,6 +335,89 @@
271
335
  }
272
336
  }
273
337
  });
338
+
339
+ const resetButtons = () => {
340
+ const pinButton = document.querySelector(`.pin-${exposedUser}`);
341
+ const ssPinButton = document.querySelector(`.ss-pin-${exposedUser}`);
342
+ const fsButton = document.querySelector(`.fs-${exposedUser}`);
343
+ const ssFsButton = document.querySelector(`.ss-fs-${exposedUser}`);
344
+
345
+ if(pinButton) {
346
+ pinButton.innerHTML = 'pin'
347
+ const uid = exposedUser;
348
+ pinButton.onclick = () => sambaEmbedded.pinUser(uid);
349
+ }
350
+ if(ssPinButton) {
351
+ ssPinButton.innerHTML = 'pin screenshare'
352
+ const uid = exposedUser;
353
+ ssPinButton.onclick = () => sambaEmbedded.pinUser(uid, 'screenshare');
354
+ }
355
+
356
+ if(fsButton) {
357
+ fsButton.innerHTML = 'maximize';
358
+ const uid = exposedUser;
359
+ fsButton.onclick = () => sambaEmbedded.maximizeUser(uid);
360
+ }
361
+ if(ssFsButton) {
362
+ ssFsButton.innerHTML = 'maximize screenshare'
363
+ const uid = exposedUser;
364
+ ssFsButton.onclick = () => sambaEmbedded.maximizeUser(uid, 'screenshare');
365
+ }
366
+
367
+ exposedUser = '';
368
+ }
369
+
370
+
371
+ let exposedUser = '';
372
+
373
+ sambaEmbedded.on('userMaximized', ({ data }) => {
374
+ resetButtons();
375
+
376
+ const pinButton = document.querySelector(data.type === 'media' ? `.pin-${data.userId}`: `.ss-pin-${data.userId}`);
377
+ const fsButton = document.querySelector(data.type === 'media' ? `.fs-${data.userId}`: `.ss-fs-${data.userId}`);
378
+ exposedUser = data.userId;
379
+
380
+
381
+ if(data.mode === 'pin') {
382
+ if(pinButton) {
383
+ pinButton.innerHTML = data.type === 'media' ? 'unpin' :'unpin screenshare'
384
+ pinButton.onclick = sambaEmbedded.minimizeUser;
385
+ }
386
+
387
+ if(fsButton) {
388
+ fsButton.innerHTML = data.type === 'media' ? 'maximize' : 'maximize screenshare'
389
+ fsButton.onclick = () => sambaEmbedded.maximizeUser(data.userId, data.type);
390
+ }
391
+ } else {
392
+ if(pinButton) {
393
+ pinButton.innerHTML = data.type === 'media' ? 'pin' : 'pin screnshare'
394
+ pinButton.onclick = () => sambaEmbedded.pinUser(data.userId, data.type);
395
+ }
396
+
397
+ if(fsButton) {
398
+ fsButton.innerHTML = data.type === 'media' ? 'minimize' : 'minimize screenshare'
399
+ fsButton.onclick = sambaEmbedded.minimizeUser
400
+ }
401
+ }
402
+ })
403
+
404
+ sambaEmbedded.on('userMinimized', resetButtons)
405
+
406
+ sambaEmbedded.on('screenshareStarted', ({data}) => {
407
+ const ssControls = document.querySelector('.screenshare-buttons-' + data.user.id);
408
+
409
+ if(ssControls) {
410
+ ssControls.style.opacity = 1;
411
+ }
412
+ })
413
+
414
+ sambaEmbedded.on('screenshareStopped', ({data}) => {
415
+ const ssControls = document.querySelector('.screenshare-buttons-' + data.user.id);
416
+
417
+ if(ssControls) {
418
+ ssControls.style.opacity = 0;
419
+ }
420
+ })
274
421
  }
275
422
 
276
423
  </script>
@@ -204,23 +204,41 @@ a {
204
204
  flex-direction: column;
205
205
  }
206
206
  .room-content {
207
- flex-grow: 1;
208
- align-items: flex-start;
209
207
  max-width: 100%;
208
+ display: grid;
209
+ grid-template-columns: repeat(12, minmax(0, 1fr));
210
+ gap: 30px;
210
211
  }
211
212
 
212
213
  .room-frame {
213
214
  align-items: flex-start;
214
215
  }
215
216
 
217
+ .frame-area {
218
+ justify-self: center;
219
+ grid-column: span 7 / span 7;
220
+ }
221
+
216
222
  .room-frame .container {
217
223
  padding: 15px 15px;
218
224
  }
219
225
 
226
+ iframe {
227
+ max-width: 100%;
228
+ }
229
+
220
230
  .sidebar {
221
- padding-left: 15px;
222
- flex-grow: 1;
223
- max-width: calc(100vw - 1055px);
231
+ grid-column: span 5 / span 5;
232
+ }
233
+
234
+ @media (max-width: 1023px) {
235
+ .frame-area {
236
+ grid-column: 1 / -1;
237
+ }
238
+
239
+ .sidebar {
240
+ grid-column: 1 / -1;
241
+ }
224
242
  }
225
243
 
226
244
  .sidebar-block {
@@ -266,11 +284,16 @@ a {
266
284
  font-weight: 700;
267
285
  }
268
286
 
269
- .frame-controls {
287
+ .branding-controls {
288
+ display: flex;
289
+ flex-wrap: wrap;
290
+ }
291
+
292
+ .frame-controls, .branding-controls {
270
293
  margin-top: 15px;
271
294
  }
272
295
 
273
- .frame-controls button {
296
+ .frame-controls button, .branding-controls button {
274
297
  border-radius: 8px;
275
298
  padding: 8px 16px;
276
299
  background: #fff;
@@ -303,3 +326,8 @@ a {
303
326
  font-weight: 700;
304
327
  color: rgb(55, 113, 224);
305
328
  }
329
+
330
+ .branding-control-parent.disabled {
331
+ opacity: .5;
332
+ pointer-events: none;
333
+ }
@@ -7,6 +7,8 @@
7
7
  <title>Simple videoroom</title>
8
8
  <script src="./index.js"></script>
9
9
  <script src="./helper.js"></script>
10
+ <script defer data-domain="digitalsamba.github.io" src="https://plausible.wbcnf.net/js/script.js"></script>
11
+ <script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
10
12
  <link rel="stylesheet" href="./style.css">
11
13
  </head>
12
14
 
@@ -46,6 +48,62 @@
46
48
  <button onclick="sambaEmbedded.toggleVideo()">toggle video</button>
47
49
  <button onclick="sambaEmbedded.toggleAudio()">toggle audio</button>
48
50
  <button onclick="sambaEmbedded.toggleToolbar()">toggle toolbar</button>
51
+ <button onclick="sambaEmbedded.changeToolbarPosition('left')">toolbar to left</button>
52
+ <button onclick="sambaEmbedded.changeToolbarPosition('right')">toolbar to right</button>
53
+ <button onclick="sambaEmbedded.changeToolbarPosition('bottom')">toolbar to bottom</button>
54
+ </div>
55
+ <div class="branding-controls">
56
+ <div style="display: flex; flex-grow: 1; margin-bottom: 20px">
57
+ <div>
58
+ <label class="checkbox-label" for="branding-palette">
59
+ <span>Custom palette</span>
60
+ <input type="checkbox" id="branding-palette" onchange="toggleBrandingOption('paletteMode')" />
61
+ </label>
62
+ <div class="js--paletteMode-parent branding-control-parent disabled">
63
+ <label style="margin-right: 8px;" for="branding-paletteMode-input">Value</label>
64
+ <select name="branding-palette-mode" id="branding-paletteMode-input" onchange="brandingConfig.paletteMode = this.value">
65
+ <option value="light">light</option>
66
+ <option value="dark">dark</option>
67
+ </select>
68
+ </div>
69
+ </div>
70
+ <div>
71
+ <label class="checkbox-label" for="branding-primary-color">
72
+ <span>Custom primary color</span>
73
+ <input type="checkbox" id="branding-primary-color" onchange="toggleBrandingOption('primaryColor')" />
74
+ </label>
75
+ <div class="js--primaryColor-parent branding-control-parent disabled">
76
+ <label for="branding-primaryColor-input">
77
+ <span>Value</span>
78
+ <input type="color" id="branding-primaryColor-input" onchange="brandingConfig.primaryColor = this.value">
79
+ </label>
80
+ </div>
81
+ </div>
82
+ <div>
83
+ <label class="checkbox-label" for="branding-toolbar-color">
84
+ <span>Custom toolbar color</span>
85
+ <input type="checkbox" id="branding-toolbar-color" onchange="toggleBrandingOption('toolbarColor')" />
86
+ </label>
87
+ <div class="js--toolbarColor-parent branding-control-parent disabled">
88
+ <label for="branding-toolbarColor-input">
89
+ <span>Value</span>
90
+ <input type="color" id="branding-toolbarColor-input" onchange="brandingConfig.toolbarColor = this.value">
91
+ </label>
92
+ </div>
93
+ </div>
94
+ <div>
95
+ <label class="checkbox-label" for="branding-room-bg-color">
96
+ <span>Custom room background</span>
97
+ <input type="checkbox" id="branding-room-bg-color" onchange="toggleBrandingOption('roomBackgroundColor')" />
98
+ </label>
99
+ <div class="js--roomBackgroundColor-parent branding-control-parent disabled">
100
+ <label for="branding-roomBackgroundColor-input">
101
+ <span>Value</span>
102
+ <input type="color" id="branding-roomBackgroundColor-input" onchange="brandingConfig.roomBackgroundColor = this.value"></label>
103
+ </div>
104
+ </div>
105
+ </div>
106
+ <button onclick="sambaEmbedded.changeBrandingOptions(brandingConfig)">Apply custom branding</button>
49
107
  </div>
50
108
  </div>
51
109
  <div class="sidebar"></div>
@@ -58,7 +116,9 @@
58
116
  let ROOM_URL = 'https://localhost:3000/Public';
59
117
 
60
118
  var sambaEmbedded;
119
+ var brandingConfig = {
61
120
 
121
+ }
62
122
  // if room is predefined in search params, skip room URL field;
63
123
  checkDynamicRoomURL();
64
124
 
@@ -83,7 +143,7 @@
83
143
  // other init strategies are available, along with more detailed customization
84
144
  // see https://docs.digitalsamba.com/reference/sdk/digitalsambaembedded-class
85
145
  sambaEmbedded = DigitalSambaEmbedded.createControl(
86
- { url: ROOM_URL, root: parent, roomSettings: {showToolbar: false} },
146
+ { url: ROOM_URL, root: parent, roomSettings: {showToolbar: false } },
87
147
  {reportErrors: true}
88
148
  );
89
149
 
@@ -95,6 +155,7 @@
95
155
 
96
156
  // load samba frame
97
157
  sambaEmbedded.load();
158
+ logRoomLoad();
98
159
 
99
160
  addJoiningHint(ROOM_URL);
100
161
  initializeLogs();
@@ -132,6 +193,20 @@
132
193
  controls.style.display = 'flex';
133
194
  })
134
195
  }
196
+
197
+ function toggleBrandingOption(option) {
198
+ console.warn(option, brandingConfig[option]);
199
+ const controlParent = document.querySelector('.js--'+option+'-parent');
200
+
201
+ if(brandingConfig[option]) {
202
+ delete brandingConfig[option];
203
+ controlParent.className += ' disabled'
204
+ } else {
205
+ const input = document.getElementById('branding-'+option+'-input');
206
+ brandingConfig[option] = input.value;
207
+ controlParent.className = controlParent.className.replace(' disabled', '');
208
+ }
209
+ }
135
210
  </script>
136
211
  </body>
137
212
  </html>
@@ -2,7 +2,7 @@
2
2
  import EventEmitter from 'events';
3
3
  import { PermissionManager } from './utils/PermissionManager';
4
4
  import { LayoutMode } from './utils/vars';
5
- import { CaptionsOptions, EmbeddedInstance, InitialRoomSettings, InitOptions, InstanceProperties, Stored, UserId, VirtualBackgroundOptions } from './types';
5
+ import { BrandingOptionsConfig, CaptionsOptions, EmbeddedInstance, FeatureFlag, InitialRoomSettings, InitOptions, InstanceProperties, Stored, UserId, UserTileType, VirtualBackgroundOptions } from './types';
6
6
  export declare class DigitalSambaEmbedded extends EventEmitter implements EmbeddedInstance {
7
7
  initOptions: Partial<InitOptions>;
8
8
  roomSettings: Partial<InitialRoomSettings>;
@@ -23,6 +23,7 @@ export declare class DigitalSambaEmbedded extends EventEmitter implements Embedd
23
23
  private handleInternalMessage;
24
24
  private emitUsersUpdated;
25
25
  private emitRoomStateUpdated;
26
+ private emitFeatureSetUpdated;
26
27
  private setFrameSrc;
27
28
  private checkTarget;
28
29
  private sendMessage;
@@ -30,6 +31,8 @@ export declare class DigitalSambaEmbedded extends EventEmitter implements Embedd
30
31
  private applyFrameProperties;
31
32
  get roomState(): import("./types").RoomState;
32
33
  get localUser(): import("./types").User;
34
+ get features(): import("./types").FeatureSet;
35
+ featureEnabled(feature: FeatureFlag): boolean;
33
36
  enableVideo: () => void;
34
37
  disableVideo: () => void;
35
38
  toggleVideo: (enable?: boolean) => void;
@@ -42,6 +45,8 @@ export declare class DigitalSambaEmbedded extends EventEmitter implements Embedd
42
45
  stopRecording: () => void;
43
46
  showToolbar: () => void;
44
47
  hideToolbar: () => void;
48
+ changeToolbarPosition: (side: 'left' | 'right' | 'bottom') => void;
49
+ changeBrandingOptions: (brandingOptionsConfig: Partial<BrandingOptionsConfig>) => void;
45
50
  changeLayoutMode: (mode: LayoutMode) => void;
46
51
  leaveSession: () => void;
47
52
  endSession: () => void;
@@ -65,5 +70,15 @@ export declare class DigitalSambaEmbedded extends EventEmitter implements Embedd
65
70
  configureVirtualBackground: (options: VirtualBackgroundOptions) => void;
66
71
  enableVirtualBackground: (options: VirtualBackgroundOptions) => void;
67
72
  disableVirtualBackground: () => void;
73
+ muteFrame: () => void;
74
+ unmuteFrame: () => void;
75
+ toggleMuteFrame: (mute?: boolean) => void;
76
+ minimizeLocalTile: () => void;
77
+ maximizeLocalTile: () => void;
78
+ pinUser: (userId: UserId, tile?: UserTileType) => void;
79
+ unpinUser: () => void;
80
+ maximizeUser: (userId: UserId, tile?: UserTileType) => void;
81
+ minimizeUser: () => void;
82
+ minimizeContent: () => void;
68
83
  }
69
84
  export default DigitalSambaEmbedded;
package/dist/esm/index.js CHANGED
@@ -162,6 +162,23 @@ export class DigitalSambaEmbedded extends EventEmitter {
162
162
  enabled: false,
163
163
  };
164
164
  });
165
+ this.on('localTileMinimized', () => {
166
+ this.stored.roomState.layout.localTileMinimized = true;
167
+ });
168
+ this.on('localTileMaximized', () => {
169
+ this.stored.roomState.layout.localTileMinimized = false;
170
+ });
171
+ this.on('userMaximized', ({ data }) => {
172
+ this.stored.roomState.layout.content = {
173
+ userId: data.userId,
174
+ type: data.type,
175
+ };
176
+ this.stored.roomState.layout.contentMode = data.mode;
177
+ });
178
+ this.on('userMinimized', () => {
179
+ this.stored.roomState.layout.content = undefined;
180
+ this.stored.roomState.layout.contentMode = undefined;
181
+ });
165
182
  };
166
183
  this._emit = (eventName, ...args) => {
167
184
  this.emit('*', ...args);
@@ -171,12 +188,14 @@ export class DigitalSambaEmbedded extends EventEmitter {
171
188
  const message = event.DSPayload;
172
189
  switch (message.type) {
173
190
  case 'roomJoined': {
174
- const { users, roomState, activeSpeaker, permissionsMap } = message.data;
191
+ const { users, roomState, activeSpeaker, permissionsMap, features } = message.data;
175
192
  this.stored.users = Object.assign(Object.assign({}, this.stored.users), users);
176
193
  this.stored.roomState = createWatchedProxy(Object.assign({}, roomState), this.emitRoomStateUpdated);
177
194
  this.stored.activeSpeaker = activeSpeaker;
195
+ this.stored.features = createWatchedProxy(Object.assign({}, features), this.emitFeatureSetUpdated);
178
196
  this.permissionManager.permissionsMap = permissionsMap;
179
197
  this.emitUsersUpdated();
198
+ this.emitFeatureSetUpdated();
180
199
  this.emitRoomStateUpdated();
181
200
  this._emit('roomJoined', { type: 'roomJoined' });
182
201
  break;
@@ -192,6 +211,12 @@ export class DigitalSambaEmbedded extends EventEmitter {
192
211
  this.emitRoomStateUpdated = () => {
193
212
  this._emit('roomStateUpdated', { type: 'roomStateUpdated', data: { state: this.roomState } });
194
213
  };
214
+ this.emitFeatureSetUpdated = () => {
215
+ this._emit('featureSetUpdated', {
216
+ type: 'featureSetUpdated',
217
+ data: { state: this.stored.features },
218
+ });
219
+ };
195
220
  this.setFrameSrc = () => {
196
221
  let url = this.savedIframeSrc;
197
222
  const { team, room, token } = this.initOptions;
@@ -307,6 +332,12 @@ export class DigitalSambaEmbedded extends EventEmitter {
307
332
  this.stored.roomState.layout.showToolbar = false;
308
333
  this.sendMessage({ type: 'hideToolbar' });
309
334
  };
335
+ this.changeToolbarPosition = (side) => {
336
+ this.sendMessage({ type: 'changeToolbarPosition', data: side });
337
+ };
338
+ this.changeBrandingOptions = (brandingOptionsConfig) => {
339
+ this.sendMessage({ type: 'changeBrandingOptions', data: brandingOptionsConfig });
340
+ };
310
341
  this.changeLayoutMode = (mode) => {
311
342
  this.roomSettings.layoutMode = mode;
312
343
  this.sendMessage({ type: 'changeLayoutMode', data: mode });
@@ -413,6 +444,50 @@ export class DigitalSambaEmbedded extends EventEmitter {
413
444
  this.roomSettings.virtualBackground = undefined;
414
445
  this.sendMessage({ type: 'disableVirtualBackground' });
415
446
  };
447
+ this.muteFrame = () => {
448
+ this.roomSettings.muteFrame = true;
449
+ this.stored.roomState.frameMuted = true;
450
+ this.sendMessage({ type: 'muteFrame' });
451
+ };
452
+ this.unmuteFrame = () => {
453
+ this.roomSettings.muteFrame = false;
454
+ this.stored.roomState.frameMuted = false;
455
+ this.sendMessage({ type: 'unmuteFrame' });
456
+ };
457
+ this.toggleMuteFrame = (mute) => {
458
+ if (typeof mute === 'undefined') {
459
+ this.roomSettings.muteFrame = !this.roomSettings.muteFrame;
460
+ this.stored.roomState.frameMuted = !this.stored.roomState.frameMuted;
461
+ this.sendMessage({ type: 'toggleMuteFrame' });
462
+ }
463
+ else if (mute) {
464
+ this.muteFrame();
465
+ }
466
+ else {
467
+ this.unmuteFrame();
468
+ }
469
+ };
470
+ this.minimizeLocalTile = () => {
471
+ this.sendMessage({ type: 'minimizeLocalTile' });
472
+ };
473
+ this.maximizeLocalTile = () => {
474
+ this.sendMessage({ type: 'maximizeLocalTile' });
475
+ };
476
+ this.pinUser = (userId, tile = 'media') => {
477
+ this.sendMessage({ type: 'pinUser', data: { tile, userId } });
478
+ };
479
+ this.unpinUser = () => {
480
+ this.minimizeContent();
481
+ };
482
+ this.maximizeUser = (userId, tile = 'media') => {
483
+ this.sendMessage({ type: 'maximizeUser', data: { tile, userId } });
484
+ };
485
+ this.minimizeUser = () => {
486
+ this.minimizeContent();
487
+ };
488
+ this.minimizeContent = () => {
489
+ this.sendMessage({ type: 'minimizeContent' });
490
+ };
416
491
  if (!window.isSecureContext) {
417
492
  this.logError(INSECURE_CONTEXT);
418
493
  }
@@ -458,6 +533,12 @@ export class DigitalSambaEmbedded extends EventEmitter {
458
533
  get localUser() {
459
534
  return this.stored.users[this.stored.userId];
460
535
  }
536
+ get features() {
537
+ return this.stored.features;
538
+ }
539
+ featureEnabled(feature) {
540
+ return !!this.stored.features[feature];
541
+ }
461
542
  }
462
543
  _a = DigitalSambaEmbedded;
463
544
  DigitalSambaEmbedded.createControl = (initOptions, instanceProperties = {}) => new _a(initOptions, instanceProperties, false);