@3dsource/angular-unreal-module 0.0.185 → 0.0.187-dev.0

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.
@@ -36,10 +36,10 @@ class UnrealButtonComponent {
36
36
  event.preventDefault();
37
37
  this.clicked.emit(event);
38
38
  }
39
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
40
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: UnrealButtonComponent, isStandalone: true, selector: "app-unreal-button", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, weight: { classPropertyName: "weight", publicName: "weight", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, isDisabled: { classPropertyName: "isDisabled", publicName: "isDisabled", isSignal: true, isRequired: false, transformFunction: null }, testID: { classPropertyName: "testID", publicName: "data-testid", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, ngImport: i0, template: "<button\n (click)=\"handleClick($event)\"\n [attr.data-testid]=\"testID() || null\"\n [attr.aria-label]=\"ariaLabel()\"\n [class.unreal-button--primary]=\"weight() === 'primary'\"\n [class.unreal-button--lg]=\"size() === 'lg'\"\n [class.unreal-button--full-width]=\"fullWidth()\"\n [disabled]=\"isDisabled()\"\n [type]=\"type()\"\n class=\"unreal-button\"\n>\n <span><ng-content></ng-content></span>\n</button>\n", styles: [".unreal-button{--unrealButtonHeight: 36px;--unrealButtonPaddings: 0 12px;--unrealButtonBorderRadius: 6px;--unrealButtonFontSize: var(--src-font-size-sm, 14px);--unrealButtonLineHeight: var(--src-font-line-sm, 20px);--unrealButtonWidth: auto;--unrealButtonBgColor: transparent;--unrealButtonBorderColor: var(--src-border-button-basic, #e5e7eb);--unrealButtonBorder: 1px solid var(--unrealButtonBorderColor);--unrealButtonFontColor: var(--src-text-ui-secondary-main, #111827);--unrealButtonFontWeight: var(--src-font-weight-medium, 500);--unrealButtonFocusRingSize: 4px;--unrealButtonFocusRingColor: var( --src-shadow-light, rgba(148, 163, 184, .16) );--unrealButtonBoxShadow: 0 -1px 0 0 var(--src-shadow-hard, rgba(71, 85, 105, .24)) inset, 0 1px 0 0 var(--src-shadow-light, rgba(148, 163, 184, .16));position:relative;display:flex;justify-content:center;align-items:center;width:var(--unrealButtonWidth);height:var(--unrealButtonHeight);padding:var(--unrealButtonPaddings);font-weight:var(--unrealButtonFontWeight);font-size:var(--unrealButtonFontSize);font-style:normal;line-height:var(--unrealButtonLineHeight);text-align:center;color:var(--unrealButtonFontColor);letter-spacing:0;white-space:nowrap;border:none;background-color:var(--unrealButtonBgColor);border-radius:var(--unrealButtonBorderRadius);box-shadow:var(--unrealButtonBoxShadow);cursor:pointer}.unreal-button:after{content:\"\";position:absolute;inset:0;border-radius:var(--unrealButtonBorderRadius);border:var(--unrealButtonBorder)}.unreal-button>span{display:flex;justify-content:center;align-items:center;gap:var(--src-gap-md, 6px);width:auto;font-size:inherit;line-height:inherit;color:inherit;font-weight:inherit}.unreal-button:disabled{--unrealButtonBgColor: var( --src-ui-accent-disabled, rgba(148, 163, 184, .24) );--unrealButtonFontColor: var(--src-text-ui-secondary-disabled, #9ca3af);--unrealButtonBoxShadow: none;--unrealButtonBorder: none;--unrealButtonBorderColor: transparent;cursor:default;pointer-events:none}.unreal-button:focus-visible{--unrealButtonBorderColor: var(--src-border-button-basic-hover, #9ca3af);outline:none;box-shadow:0 0 0 var(--unrealButtonFocusRingSize) var(--unrealButtonFocusRingColor)}@media(pointer:fine){.unreal-button:hover{--unrealButtonBgColor: var( --src-ui-secondary-default-hover, rgba(148, 163, 184, .08) );--unrealButtonBorderColor: var(--src-border-button-basic-hover, #9ca3af)}}.unreal-button--primary{--unrealButtonBgColor: var(--unreal-accent, var(--src-ui-accent-default, #017bff));--unrealButtonBorder: none;--unrealButtonFontColor: var(--unreal-accent-text, var(--src-text-ui-primary-main, #fff));--unrealButtonFocusRingColor: var( --src-shadow-accent-light, rgba(1, 123, 255, .16) )}@media(pointer:fine){.unreal-button--primary:hover{--unrealButtonBgColor: var(--unreal-accent-hover, var(--src-ui-accent-default-hover, #016fe6));--unrealButtonFontColor: var(--unreal-accent-text, var(--src-text-ui-primary-main, #fff))}}.unreal-button--lg{--unrealButtonHeight: 44px;--unrealButtonPaddings: 0 16px;--unrealButtonBorderRadius: 8px;--unrealButtonFontSize: var(--src-font-size-base, 16px);--unrealButtonLineHeight: var(--src-font-line-base, 24px);--unrealButtonFocusRingSize: 6px;--unrealButtonBoxShadow: 0 -1px 0 0 var(--src-shadow-hard, rgba(71, 85, 105, .24)) inset, 0 2px 0 0 var(--src-shadow-light, rgba(148, 163, 184, .16))}.unreal-button--lg>span{gap:var(--src-gap-md, 8px)}.unreal-button--full-width{--unrealButtonWidth: 100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
39
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
40
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: UnrealButtonComponent, isStandalone: true, selector: "app-unreal-button", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, weight: { classPropertyName: "weight", publicName: "weight", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, isDisabled: { classPropertyName: "isDisabled", publicName: "isDisabled", isSignal: true, isRequired: false, transformFunction: null }, testID: { classPropertyName: "testID", publicName: "data-testid", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, ngImport: i0, template: "<button\n (click)=\"handleClick($event)\"\n [attr.data-testid]=\"testID() || null\"\n [attr.aria-label]=\"ariaLabel()\"\n [class.unreal-button--primary]=\"weight() === 'primary'\"\n [class.unreal-button--lg]=\"size() === 'lg'\"\n [class.unreal-button--full-width]=\"fullWidth()\"\n [disabled]=\"isDisabled()\"\n [type]=\"type()\"\n class=\"unreal-button\"\n>\n <span><ng-content></ng-content></span>\n</button>\n", styles: [".unreal-button{--unrealButtonHeight: 36px;--unrealButtonPaddings: 0 12px;--unrealButtonBorderRadius: 6px;--unrealButtonFontSize: var(--src-font-size-sm, 14px);--unrealButtonLineHeight: var(--src-font-line-sm, 20px);--unrealButtonWidth: auto;--unrealButtonBgColor: transparent;--unrealButtonBorderColor: var(--src-border-button-basic, #e5e7eb);--unrealButtonBorder: 1px solid var(--unrealButtonBorderColor);--unrealButtonFontColor: var(--src-text-ui-secondary-main, #111827);--unrealButtonFontWeight: var(--src-font-weight-medium, 500);--unrealButtonFocusRingSize: 4px;--unrealButtonFocusRingColor: var( --src-shadow-light, rgba(148, 163, 184, .16) );--unrealButtonBoxShadow: 0 -1px 0 0 var(--src-shadow-hard, rgba(71, 85, 105, .24)) inset, 0 1px 0 0 var(--src-shadow-light, rgba(148, 163, 184, .16));position:relative;display:flex;justify-content:center;align-items:center;width:var(--unrealButtonWidth);height:var(--unrealButtonHeight);padding:var(--unrealButtonPaddings);font-weight:var(--unrealButtonFontWeight);font-size:var(--unrealButtonFontSize);font-style:normal;line-height:var(--unrealButtonLineHeight);text-align:center;color:var(--unrealButtonFontColor);letter-spacing:0;white-space:nowrap;border:none;background-color:var(--unrealButtonBgColor);border-radius:var(--unrealButtonBorderRadius);box-shadow:var(--unrealButtonBoxShadow);cursor:pointer}.unreal-button:after{content:\"\";position:absolute;inset:0;border-radius:var(--unrealButtonBorderRadius);border:var(--unrealButtonBorder)}.unreal-button>span{display:flex;justify-content:center;align-items:center;gap:var(--src-gap-md, 6px);width:auto;font-size:inherit;line-height:inherit;color:inherit;font-weight:inherit}.unreal-button:disabled{--unrealButtonBgColor: var( --src-ui-accent-disabled, rgba(148, 163, 184, .24) );--unrealButtonFontColor: var(--src-text-ui-secondary-disabled, #9ca3af);--unrealButtonBoxShadow: none;--unrealButtonBorder: none;--unrealButtonBorderColor: transparent;cursor:default;pointer-events:none}.unreal-button:focus-visible{--unrealButtonBorderColor: var(--src-border-button-basic-hover, #9ca3af);outline:none;box-shadow:0 0 0 var(--unrealButtonFocusRingSize) var(--unrealButtonFocusRingColor)}@media(pointer:fine){.unreal-button:hover{--unrealButtonBgColor: var( --src-ui-secondary-default-hover, rgba(148, 163, 184, .08) );--unrealButtonBorderColor: var(--src-border-button-basic-hover, #9ca3af)}}.unreal-button--primary{--unrealButtonBgColor: var(--unreal-accent, var(--src-ui-accent-default, #017bff));--unrealButtonBorder: none;--unrealButtonFontColor: var(--unreal-accent-text, var(--src-text-ui-primary-main, #fff));--unrealButtonFocusRingColor: var( --src-shadow-accent-light, rgba(1, 123, 255, .16) )}@media(pointer:fine){.unreal-button--primary:hover{--unrealButtonBgColor: var(--unreal-accent-hover, var(--src-ui-accent-default-hover, #016fe6));--unrealButtonFontColor: var(--unreal-accent-text, var(--src-text-ui-primary-main, #fff))}}.unreal-button--lg{--unrealButtonHeight: 44px;--unrealButtonPaddings: 0 16px;--unrealButtonBorderRadius: 8px;--unrealButtonFontSize: var(--src-font-size-base, 16px);--unrealButtonLineHeight: var(--src-font-line-base, 24px);--unrealButtonFocusRingSize: 6px;--unrealButtonBoxShadow: 0 -1px 0 0 var(--src-shadow-hard, rgba(71, 85, 105, .24)) inset, 0 2px 0 0 var(--src-shadow-light, rgba(148, 163, 184, .16))}.unreal-button--lg>span{gap:var(--src-gap-md, 8px)}.unreal-button--full-width{--unrealButtonWidth: 100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
41
41
  }
42
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealButtonComponent, decorators: [{
42
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealButtonComponent, decorators: [{
43
43
  type: Component,
44
44
  args: [{ selector: 'app-unreal-button', changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n (click)=\"handleClick($event)\"\n [attr.data-testid]=\"testID() || null\"\n [attr.aria-label]=\"ariaLabel()\"\n [class.unreal-button--primary]=\"weight() === 'primary'\"\n [class.unreal-button--lg]=\"size() === 'lg'\"\n [class.unreal-button--full-width]=\"fullWidth()\"\n [disabled]=\"isDisabled()\"\n [type]=\"type()\"\n class=\"unreal-button\"\n>\n <span><ng-content></ng-content></span>\n</button>\n", styles: [".unreal-button{--unrealButtonHeight: 36px;--unrealButtonPaddings: 0 12px;--unrealButtonBorderRadius: 6px;--unrealButtonFontSize: var(--src-font-size-sm, 14px);--unrealButtonLineHeight: var(--src-font-line-sm, 20px);--unrealButtonWidth: auto;--unrealButtonBgColor: transparent;--unrealButtonBorderColor: var(--src-border-button-basic, #e5e7eb);--unrealButtonBorder: 1px solid var(--unrealButtonBorderColor);--unrealButtonFontColor: var(--src-text-ui-secondary-main, #111827);--unrealButtonFontWeight: var(--src-font-weight-medium, 500);--unrealButtonFocusRingSize: 4px;--unrealButtonFocusRingColor: var( --src-shadow-light, rgba(148, 163, 184, .16) );--unrealButtonBoxShadow: 0 -1px 0 0 var(--src-shadow-hard, rgba(71, 85, 105, .24)) inset, 0 1px 0 0 var(--src-shadow-light, rgba(148, 163, 184, .16));position:relative;display:flex;justify-content:center;align-items:center;width:var(--unrealButtonWidth);height:var(--unrealButtonHeight);padding:var(--unrealButtonPaddings);font-weight:var(--unrealButtonFontWeight);font-size:var(--unrealButtonFontSize);font-style:normal;line-height:var(--unrealButtonLineHeight);text-align:center;color:var(--unrealButtonFontColor);letter-spacing:0;white-space:nowrap;border:none;background-color:var(--unrealButtonBgColor);border-radius:var(--unrealButtonBorderRadius);box-shadow:var(--unrealButtonBoxShadow);cursor:pointer}.unreal-button:after{content:\"\";position:absolute;inset:0;border-radius:var(--unrealButtonBorderRadius);border:var(--unrealButtonBorder)}.unreal-button>span{display:flex;justify-content:center;align-items:center;gap:var(--src-gap-md, 6px);width:auto;font-size:inherit;line-height:inherit;color:inherit;font-weight:inherit}.unreal-button:disabled{--unrealButtonBgColor: var( --src-ui-accent-disabled, rgba(148, 163, 184, .24) );--unrealButtonFontColor: var(--src-text-ui-secondary-disabled, #9ca3af);--unrealButtonBoxShadow: none;--unrealButtonBorder: none;--unrealButtonBorderColor: transparent;cursor:default;pointer-events:none}.unreal-button:focus-visible{--unrealButtonBorderColor: var(--src-border-button-basic-hover, #9ca3af);outline:none;box-shadow:0 0 0 var(--unrealButtonFocusRingSize) var(--unrealButtonFocusRingColor)}@media(pointer:fine){.unreal-button:hover{--unrealButtonBgColor: var( --src-ui-secondary-default-hover, rgba(148, 163, 184, .08) );--unrealButtonBorderColor: var(--src-border-button-basic-hover, #9ca3af)}}.unreal-button--primary{--unrealButtonBgColor: var(--unreal-accent, var(--src-ui-accent-default, #017bff));--unrealButtonBorder: none;--unrealButtonFontColor: var(--unreal-accent-text, var(--src-text-ui-primary-main, #fff));--unrealButtonFocusRingColor: var( --src-shadow-accent-light, rgba(1, 123, 255, .16) )}@media(pointer:fine){.unreal-button--primary:hover{--unrealButtonBgColor: var(--unreal-accent-hover, var(--src-ui-accent-default-hover, #016fe6));--unrealButtonFontColor: var(--unreal-accent-text, var(--src-text-ui-primary-main, #fff))}}.unreal-button--lg{--unrealButtonHeight: 44px;--unrealButtonPaddings: 0 16px;--unrealButtonBorderRadius: 8px;--unrealButtonFontSize: var(--src-font-size-base, 16px);--unrealButtonLineHeight: var(--src-font-line-base, 24px);--unrealButtonFocusRingSize: 6px;--unrealButtonBoxShadow: 0 -1px 0 0 var(--src-shadow-hard, rgba(71, 85, 105, .24)) inset, 0 2px 0 0 var(--src-shadow-light, rgba(148, 163, 184, .16))}.unreal-button--lg>span{gap:var(--src-gap-md, 8px)}.unreal-button--full-width{--unrealButtonWidth: 100%}\n"] }]
45
45
  }], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], weight: [{ type: i0.Input, args: [{ isSignal: true, alias: "weight", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], isDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDisabled", required: false }] }], testID: [{ type: i0.Input, args: [{ isSignal: true, alias: "data-testid", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }] } });
@@ -586,8 +586,18 @@ const DESTROY_DISCONNECT_REASONS = [
586
586
  const DEBOUNCE_TO_MANY_RESIZE_CALLS = 100;
587
587
  const AUTO_HIGH_RESOLUTION_IDLE_MS = 5000;
588
588
  const SAME_SIZE_THRESHOLD = 1.01;
589
- // Minimum container dimension in px — prevents division by zero in resize calculations
590
- const MIN_CONTAINER_SIZE = 2;
589
+ // Hard bounds for every FChangeResolutionCommand that leaves the player.
590
+ // NVENC H.264 accepts 145..4096 px wide and 49..4096 px tall; a size outside
591
+ // that range fails encoder creation (NV_ENC_ERR_INVALID_PARAM) on every frame
592
+ // and the stream stays frozen until the next valid size arrives. The floor is
593
+ // raised above the H.264 minimum to leave headroom for AV1. The Unreal side
594
+ // clamps to the same range — keep both in sync.
595
+ const STREAM_RESOLUTION_LIMITS = {
596
+ minWidth: 160,
597
+ minHeight: 64,
598
+ maxWidth: 4096,
599
+ maxHeight: 4096,
600
+ };
591
601
  const MINIMAL_FPS = 6;
592
602
  const STREAMING_VIDEO_ID = 'streamingVideo';
593
603
  const STREAMING_AUDIO_ID = 'streamingAudio';
@@ -1617,10 +1627,10 @@ class WebrtcErrorModalComponent {
1617
1627
  close() {
1618
1628
  this.#dialogRef.close();
1619
1629
  }
1620
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WebrtcErrorModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1621
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.4", type: WebrtcErrorModalComponent, isStandalone: true, selector: "app-webrtc-error-modal", ngImport: i0, template: "<div [attr.data-testid]=\"'webrtc-error-modal'\" class=\"unreal-modal\">\n <header class=\"unreal-modal__header\"></header>\n <section class=\"unreal-modal__body\">\n <div [attr.data-testid]=\"'title'\" class=\"unreal-modal__title\">\n WebRTC error\n </div>\n <div style=\"text-align: left\">\n An internet connection type (WebRTC) appears to be blocked either by your\n browser settings or your current network. If WebRTC is blocked on your\n browser you may be able to adjust these settings yourself based on\n instructions here:\n <a href=\"https://myownconference.com/blog/en/webrtc/\" target=\"blank\"\n >https://myownconference.com/blog/en/webrtc/</a\n >\n <br /><br />\n Trying a different web browser may help confirm this as well. If WebRTC is\n blocked by your network, try switching to a different network if possible\n or contact your network administrator.<br /><br />\n WebRTC is common, safe and increasingly utilised method for streaming real\n time 3D experiences via a web browser. It typically consumes no more\n bandwidth than streaming an HD video.\n </div>\n </section>\n <footer class=\"unreal-modal__footer\">\n <app-unreal-button\n (clicked)=\"closeModalWithCirrusDisconnect()\"\n [data-testid]=\"'close-webrtc-error-modal'\"\n weight=\"primary\"\n >\n Ok\n </app-unreal-button>\n </footer>\n</div>\n", styles: [".unreal-modal{--unrealModalWidth: 422px;--unrealModalMaxWidth: calc(100% - 16px) ;--unrealModalMaxHeight: 80vh;--unrealModalBg: var(--src-surface-container-main, #fff);--unrealModalBoxShadow: 0 16px 36px 4px var(--src-shadow-hard, rgba(71, 85, 105, .24)), 0 1px 4px 0 var(--src-shadow-light, rgba(148, 163, 184, .16));--unrealModalBorderRadius: var(--src-layout-radius-const-rounded-md, 12px);--unrealModalTitleSize: var(--src-font-size-base, 16px);--unrealModalTitleLineHeight: var(--src-font-line-base, 24px);--unrealModalTitleColor: var(--src-text-body-main, #111827);--unrealModalBodyPadding: var(--src-layout-padding-const-lg, 16px) var(--src-layout-padding-const-xl, 24px) var(--src-layout-padding-const-2xl, 32px) var(--src-layout-padding-const-xl, 24px);--unrealModalTitleBorder: none;--unrealModalFooterBorder: 1px solid var(--src-border-container-light, rgba(148, 163, 184, .16));display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr) auto;width:var(--unrealModalWidth);max-width:var(--unrealModalMaxWidth);max-height:var(--unrealModalMaxHeight);margin:auto;background-color:var(--unrealModalBg);border-radius:var(--unrealModalBorderRadius);box-shadow:var(--unrealModalBoxShadow);color:var(--src-text-body-secondary, #4b5563);font-family:var(--src-font-family-header, Inter);font-size:var(--src-font-size-sm, 14px);font-style:normal;font-weight:400;line-height:var(--src-font-line-sm, 20px)}.unreal-modal .unreal-modal__header{position:relative;display:flex;padding:0;width:100%;border-bottom:var(--unrealModalTitleBorder)}.unreal-modal .unreal-modal__body{display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr);gap:var(--src-layout-gap-const-md, 12px);padding:var(--unrealModalBodyPadding);overflow:auto;scrollbar-width:thin;scrollbar-color:var(--src-border-container-basic, rgba(148, 163, 184, .24)) transparent}.unreal-modal .unreal-modal__body .unreal-modal__title{grid-column:1/-1}.unreal-modal .unreal-modal__body::-webkit-scrollbar{width:4px}.unreal-modal .unreal-modal__body::-webkit-scrollbar-track{background:transparent}.unreal-modal .unreal-modal__body::-webkit-scrollbar-thumb{background-color:var(--src-border-container-basic, rgba(148, 163, 184, .24));border-radius:10px}.unreal-modal .unreal-modal__footer{display:flex;justify-content:flex-end;align-items:center;padding:var(--src-layout-padding-const-md, 12px) var(--src-layout-padding-const-xl, 24px) var(--src-layout-padding-const-lg, 16px) var(--src-layout-padding-const-xl, 24px);width:100%;border-top:var(--unrealModalFooterBorder);gap:var(--src-layout-gap-const-sm, 8px)}.unreal-modal .unreal-modal__title{font-size:var(--unrealModalTitleSize);font-weight:600;line-height:var(--unrealModalTitleLineHeight);color:var(--unrealModalTitleColor);word-break:break-word}.unreal-modal .unreal-modal__body{width:100%}.unreal-modal .unreal-modal__body p{color:var(--src-text-body-main, #1f2937);font-size:14px;font-style:normal;font-weight:400;line-height:24px;margin-top:0}.unreal-modal .unreal-modal__body a{word-wrap:break-word;white-space:normal}\n"], dependencies: [{ kind: "component", type: UnrealButtonComponent, selector: "app-unreal-button", inputs: ["type", "weight", "size", "fullWidth", "isDisabled", "data-testid", "ariaLabel"], outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1630
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WebrtcErrorModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1631
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.7", type: WebrtcErrorModalComponent, isStandalone: true, selector: "app-webrtc-error-modal", ngImport: i0, template: "<div [attr.data-testid]=\"'webrtc-error-modal'\" class=\"unreal-modal\">\n <header class=\"unreal-modal__header\"></header>\n <section class=\"unreal-modal__body\">\n <div [attr.data-testid]=\"'title'\" class=\"unreal-modal__title\">\n WebRTC error\n </div>\n <div style=\"text-align: left\">\n An internet connection type (WebRTC) appears to be blocked either by your\n browser settings or your current network. If WebRTC is blocked on your\n browser you may be able to adjust these settings yourself based on\n instructions here:\n <a href=\"https://myownconference.com/blog/en/webrtc/\" target=\"blank\"\n >https://myownconference.com/blog/en/webrtc/</a\n >\n <br /><br />\n Trying a different web browser may help confirm this as well. If WebRTC is\n blocked by your network, try switching to a different network if possible\n or contact your network administrator.<br /><br />\n WebRTC is common, safe and increasingly utilised method for streaming real\n time 3D experiences via a web browser. It typically consumes no more\n bandwidth than streaming an HD video.\n </div>\n </section>\n <footer class=\"unreal-modal__footer\">\n <app-unreal-button\n (clicked)=\"closeModalWithCirrusDisconnect()\"\n [data-testid]=\"'close-webrtc-error-modal'\"\n weight=\"primary\"\n >\n Ok\n </app-unreal-button>\n </footer>\n</div>\n", styles: [".unreal-modal{--unrealModalWidth: 422px;--unrealModalMaxWidth: calc(100% - 16px) ;--unrealModalMaxHeight: 80vh;--unrealModalBg: var(--src-surface-container-main, #fff);--unrealModalBoxShadow: 0 16px 36px 4px var(--src-shadow-hard, rgba(71, 85, 105, .24)), 0 1px 4px 0 var(--src-shadow-light, rgba(148, 163, 184, .16));--unrealModalBorderRadius: var(--src-layout-radius-const-rounded-md, 12px);--unrealModalTitleSize: var(--src-font-size-base, 16px);--unrealModalTitleLineHeight: var(--src-font-line-base, 24px);--unrealModalTitleColor: var(--src-text-body-main, #111827);--unrealModalBodyPadding: var(--src-layout-padding-const-lg, 16px) var(--src-layout-padding-const-xl, 24px) var(--src-layout-padding-const-2xl, 32px) var(--src-layout-padding-const-xl, 24px);--unrealModalTitleBorder: none;--unrealModalFooterBorder: 1px solid var(--src-border-container-light, rgba(148, 163, 184, .16));display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr) auto;width:var(--unrealModalWidth);max-width:var(--unrealModalMaxWidth);max-height:var(--unrealModalMaxHeight);margin:auto;background-color:var(--unrealModalBg);border-radius:var(--unrealModalBorderRadius);box-shadow:var(--unrealModalBoxShadow);color:var(--src-text-body-secondary, #4b5563);font-family:var(--src-font-family-header, Inter);font-size:var(--src-font-size-sm, 14px);font-style:normal;font-weight:400;line-height:var(--src-font-line-sm, 20px)}.unreal-modal .unreal-modal__header{position:relative;display:flex;padding:0;width:100%;border-bottom:var(--unrealModalTitleBorder)}.unreal-modal .unreal-modal__body{display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr);gap:var(--src-layout-gap-const-md, 12px);padding:var(--unrealModalBodyPadding);overflow:auto;scrollbar-width:thin;scrollbar-color:var(--src-border-container-basic, rgba(148, 163, 184, .24)) transparent}.unreal-modal .unreal-modal__body .unreal-modal__title{grid-column:1/-1}.unreal-modal .unreal-modal__body::-webkit-scrollbar{width:4px}.unreal-modal .unreal-modal__body::-webkit-scrollbar-track{background:transparent}.unreal-modal .unreal-modal__body::-webkit-scrollbar-thumb{background-color:var(--src-border-container-basic, rgba(148, 163, 184, .24));border-radius:10px}.unreal-modal .unreal-modal__footer{display:flex;justify-content:flex-end;align-items:center;padding:var(--src-layout-padding-const-md, 12px) var(--src-layout-padding-const-xl, 24px) var(--src-layout-padding-const-lg, 16px) var(--src-layout-padding-const-xl, 24px);width:100%;border-top:var(--unrealModalFooterBorder);gap:var(--src-layout-gap-const-sm, 8px)}.unreal-modal .unreal-modal__title{font-size:var(--unrealModalTitleSize);font-weight:600;line-height:var(--unrealModalTitleLineHeight);color:var(--unrealModalTitleColor);word-break:break-word}.unreal-modal .unreal-modal__body{width:100%}.unreal-modal .unreal-modal__body p{color:var(--src-text-body-main, #1f2937);font-size:14px;font-style:normal;font-weight:400;line-height:24px;margin-top:0}.unreal-modal .unreal-modal__body a{word-wrap:break-word;white-space:normal}\n"], dependencies: [{ kind: "component", type: UnrealButtonComponent, selector: "app-unreal-button", inputs: ["type", "weight", "size", "fullWidth", "isDisabled", "data-testid", "ariaLabel"], outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1622
1632
  }
1623
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WebrtcErrorModalComponent, decorators: [{
1633
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WebrtcErrorModalComponent, decorators: [{
1624
1634
  type: Component,
1625
1635
  args: [{ selector: 'app-webrtc-error-modal', changeDetection: ChangeDetectionStrategy.OnPush, imports: [UnrealButtonComponent], template: "<div [attr.data-testid]=\"'webrtc-error-modal'\" class=\"unreal-modal\">\n <header class=\"unreal-modal__header\"></header>\n <section class=\"unreal-modal__body\">\n <div [attr.data-testid]=\"'title'\" class=\"unreal-modal__title\">\n WebRTC error\n </div>\n <div style=\"text-align: left\">\n An internet connection type (WebRTC) appears to be blocked either by your\n browser settings or your current network. If WebRTC is blocked on your\n browser you may be able to adjust these settings yourself based on\n instructions here:\n <a href=\"https://myownconference.com/blog/en/webrtc/\" target=\"blank\"\n >https://myownconference.com/blog/en/webrtc/</a\n >\n <br /><br />\n Trying a different web browser may help confirm this as well. If WebRTC is\n blocked by your network, try switching to a different network if possible\n or contact your network administrator.<br /><br />\n WebRTC is common, safe and increasingly utilised method for streaming real\n time 3D experiences via a web browser. It typically consumes no more\n bandwidth than streaming an HD video.\n </div>\n </section>\n <footer class=\"unreal-modal__footer\">\n <app-unreal-button\n (clicked)=\"closeModalWithCirrusDisconnect()\"\n [data-testid]=\"'close-webrtc-error-modal'\"\n weight=\"primary\"\n >\n Ok\n </app-unreal-button>\n </footer>\n</div>\n", styles: [".unreal-modal{--unrealModalWidth: 422px;--unrealModalMaxWidth: calc(100% - 16px) ;--unrealModalMaxHeight: 80vh;--unrealModalBg: var(--src-surface-container-main, #fff);--unrealModalBoxShadow: 0 16px 36px 4px var(--src-shadow-hard, rgba(71, 85, 105, .24)), 0 1px 4px 0 var(--src-shadow-light, rgba(148, 163, 184, .16));--unrealModalBorderRadius: var(--src-layout-radius-const-rounded-md, 12px);--unrealModalTitleSize: var(--src-font-size-base, 16px);--unrealModalTitleLineHeight: var(--src-font-line-base, 24px);--unrealModalTitleColor: var(--src-text-body-main, #111827);--unrealModalBodyPadding: var(--src-layout-padding-const-lg, 16px) var(--src-layout-padding-const-xl, 24px) var(--src-layout-padding-const-2xl, 32px) var(--src-layout-padding-const-xl, 24px);--unrealModalTitleBorder: none;--unrealModalFooterBorder: 1px solid var(--src-border-container-light, rgba(148, 163, 184, .16));display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr) auto;width:var(--unrealModalWidth);max-width:var(--unrealModalMaxWidth);max-height:var(--unrealModalMaxHeight);margin:auto;background-color:var(--unrealModalBg);border-radius:var(--unrealModalBorderRadius);box-shadow:var(--unrealModalBoxShadow);color:var(--src-text-body-secondary, #4b5563);font-family:var(--src-font-family-header, Inter);font-size:var(--src-font-size-sm, 14px);font-style:normal;font-weight:400;line-height:var(--src-font-line-sm, 20px)}.unreal-modal .unreal-modal__header{position:relative;display:flex;padding:0;width:100%;border-bottom:var(--unrealModalTitleBorder)}.unreal-modal .unreal-modal__body{display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr);gap:var(--src-layout-gap-const-md, 12px);padding:var(--unrealModalBodyPadding);overflow:auto;scrollbar-width:thin;scrollbar-color:var(--src-border-container-basic, rgba(148, 163, 184, .24)) transparent}.unreal-modal .unreal-modal__body .unreal-modal__title{grid-column:1/-1}.unreal-modal .unreal-modal__body::-webkit-scrollbar{width:4px}.unreal-modal .unreal-modal__body::-webkit-scrollbar-track{background:transparent}.unreal-modal .unreal-modal__body::-webkit-scrollbar-thumb{background-color:var(--src-border-container-basic, rgba(148, 163, 184, .24));border-radius:10px}.unreal-modal .unreal-modal__footer{display:flex;justify-content:flex-end;align-items:center;padding:var(--src-layout-padding-const-md, 12px) var(--src-layout-padding-const-xl, 24px) var(--src-layout-padding-const-lg, 16px) var(--src-layout-padding-const-xl, 24px);width:100%;border-top:var(--unrealModalFooterBorder);gap:var(--src-layout-gap-const-sm, 8px)}.unreal-modal .unreal-modal__title{font-size:var(--unrealModalTitleSize);font-weight:600;line-height:var(--unrealModalTitleLineHeight);color:var(--unrealModalTitleColor);word-break:break-word}.unreal-modal .unreal-modal__body{width:100%}.unreal-modal .unreal-modal__body p{color:var(--src-text-body-main, #1f2937);font-size:14px;font-style:normal;font-weight:400;line-height:24px;margin-top:0}.unreal-modal .unreal-modal__body a{word-wrap:break-word;white-space:normal}\n"] }]
1626
1636
  }] });
@@ -1843,10 +1853,10 @@ class CommandTelemetryService extends SubService {
1843
1853
  this.trackTime(out);
1844
1854
  funcToDecorate(out);
1845
1855
  }
1846
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: CommandTelemetryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1847
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: CommandTelemetryService, providedIn: 'root' }); }
1856
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: CommandTelemetryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1857
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: CommandTelemetryService, providedIn: 'root' }); }
1848
1858
  }
1849
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: CommandTelemetryService, decorators: [{
1859
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: CommandTelemetryService, decorators: [{
1850
1860
  type: Injectable,
1851
1861
  args: [{ providedIn: 'root' }]
1852
1862
  }], ctorParameters: () => [] });
@@ -1867,10 +1877,10 @@ class DevModeService {
1867
1877
  localStorage.removeItem('devMode');
1868
1878
  }
1869
1879
  }
1870
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: DevModeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1871
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: DevModeService, providedIn: 'root' }); }
1880
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: DevModeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1881
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: DevModeService, providedIn: 'root' }); }
1872
1882
  }
1873
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: DevModeService, decorators: [{
1883
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: DevModeService, decorators: [{
1874
1884
  type: Injectable,
1875
1885
  args: [{
1876
1886
  providedIn: 'root',
@@ -2189,10 +2199,10 @@ class RegionsPingService {
2189
2199
  }
2190
2200
  }
2191
2201
  }
2192
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: RegionsPingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2193
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: RegionsPingService, providedIn: 'root' }); }
2202
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: RegionsPingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2203
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: RegionsPingService, providedIn: 'root' }); }
2194
2204
  }
2195
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: RegionsPingService, decorators: [{
2205
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: RegionsPingService, decorators: [{
2196
2206
  type: Injectable,
2197
2207
  args: [{ providedIn: 'root' }]
2198
2208
  }], ctorParameters: () => [] });
@@ -2951,10 +2961,10 @@ class SignallingService extends SubService {
2951
2961
  Logger.log('Start Getting Region');
2952
2962
  return this.regionsPingService.getFastest().pipe(take(1));
2953
2963
  }
2954
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: SignallingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2955
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: SignallingService, providedIn: 'root' }); }
2964
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SignallingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2965
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SignallingService, providedIn: 'root' }); }
2956
2966
  }
2957
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: SignallingService, decorators: [{
2967
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SignallingService, decorators: [{
2958
2968
  type: Injectable,
2959
2969
  args: [{ providedIn: 'root' }]
2960
2970
  }], ctorParameters: () => [] });
@@ -3369,10 +3379,10 @@ class VideoService extends SubService {
3369
3379
  this.armGestureRetry(audio);
3370
3380
  }
3371
3381
  }
3372
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: VideoService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3373
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: VideoService, providedIn: 'root' }); }
3382
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: VideoService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3383
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: VideoService, providedIn: 'root' }); }
3374
3384
  }
3375
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: VideoService, decorators: [{
3385
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: VideoService, decorators: [{
3376
3386
  type: Injectable,
3377
3387
  args: [{ providedIn: 'root' }]
3378
3388
  }], ctorParameters: () => [] });
@@ -4038,10 +4048,10 @@ class WebRtcPlayerService extends SubService {
4038
4048
  Logger.error("Couldn't create answer", e);
4039
4049
  }
4040
4050
  }
4041
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WebRtcPlayerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4042
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WebRtcPlayerService, providedIn: 'root' }); }
4051
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WebRtcPlayerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4052
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WebRtcPlayerService, providedIn: 'root' }); }
4043
4053
  }
4044
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WebRtcPlayerService, decorators: [{
4054
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WebRtcPlayerService, decorators: [{
4045
4055
  type: Injectable,
4046
4056
  args: [{ providedIn: 'root' }]
4047
4057
  }], ctorParameters: () => [] });
@@ -4211,10 +4221,10 @@ class StreamAdoptionService {
4211
4221
  this.webRtc.adopt(parked.pc, parked.dc, parked.stream, parked.config ?? {}, parked.dcBuffer);
4212
4222
  return true;
4213
4223
  }
4214
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StreamAdoptionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4215
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StreamAdoptionService, providedIn: 'root' }); }
4224
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: StreamAdoptionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4225
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: StreamAdoptionService, providedIn: 'root' }); }
4216
4226
  }
4217
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StreamAdoptionService, decorators: [{
4227
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: StreamAdoptionService, decorators: [{
4218
4228
  type: Injectable,
4219
4229
  args: [{ providedIn: 'root' }]
4220
4230
  }] });
@@ -4282,10 +4292,10 @@ class UnrealCallbackService {
4282
4292
  return observable;
4283
4293
  });
4284
4294
  }
4285
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealCallbackService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4286
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealCallbackService, providedIn: 'root' }); }
4295
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealCallbackService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4296
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealCallbackService, providedIn: 'root' }); }
4287
4297
  }
4288
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealCallbackService, decorators: [{
4298
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealCallbackService, decorators: [{
4289
4299
  type: Injectable,
4290
4300
  args: [{ providedIn: 'root' }]
4291
4301
  }] });
@@ -4402,10 +4412,10 @@ class UnrealCommunicatorService extends SubService {
4402
4412
  requestQualityControl() {
4403
4413
  this.sendInputData(new Uint8Array([MessageType.RequestQualityControl]).buffer);
4404
4414
  }
4405
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealCommunicatorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4406
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealCommunicatorService, providedIn: 'root' }); }
4415
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealCommunicatorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4416
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealCommunicatorService, providedIn: 'root' }); }
4407
4417
  }
4408
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealCommunicatorService, decorators: [{
4418
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealCommunicatorService, decorators: [{
4409
4419
  type: Injectable,
4410
4420
  args: [{ providedIn: 'root' }]
4411
4421
  }], ctorParameters: () => [] });
@@ -4419,10 +4429,10 @@ class UnrealErrorModalComponent {
4419
4429
  close() {
4420
4430
  this.#dialogRef.close();
4421
4431
  }
4422
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealErrorModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4423
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.4", type: UnrealErrorModalComponent, isStandalone: true, selector: "app-unreal-error-modal", ngImport: i0, template: "<div class=\"unreal-modal\">\n <header class=\"unreal-modal__header\">\n <div\n [attr.data-testid]=\"'unreal-error-header-title'\"\n class=\"unreal-modal__title\"\n >\n Warning\n </div>\n </header>\n <div class=\"unreal-modal__body\">\n <div>{{ dialogData.content }}</div>\n </div>\n <div class=\"unreal-modal__footer\">\n <app-unreal-button (clicked)=\"close()\">Ok</app-unreal-button>\n </div>\n</div>\n", styles: [".unreal-modal{--unrealModalWidth: 422px;--unrealModalMaxWidth: calc(100% - 16px) ;--unrealModalMaxHeight: 80vh;--unrealModalBg: var(--src-surface-container-main, #fff);--unrealModalBoxShadow: 0 16px 36px 4px var(--src-shadow-hard, rgba(71, 85, 105, .24)), 0 1px 4px 0 var(--src-shadow-light, rgba(148, 163, 184, .16));--unrealModalBorderRadius: var(--src-layout-radius-const-rounded-md, 12px);--unrealModalTitleSize: var(--src-font-size-base, 16px);--unrealModalTitleLineHeight: var(--src-font-line-base, 24px);--unrealModalTitleColor: var(--src-text-body-main, #111827);--unrealModalBodyPadding: var(--src-layout-padding-const-lg, 16px) var(--src-layout-padding-const-xl, 24px) var(--src-layout-padding-const-2xl, 32px) var(--src-layout-padding-const-xl, 24px);--unrealModalTitleBorder: none;--unrealModalFooterBorder: 1px solid var(--src-border-container-light, rgba(148, 163, 184, .16));display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr) auto;width:var(--unrealModalWidth);max-width:var(--unrealModalMaxWidth);max-height:var(--unrealModalMaxHeight);margin:auto;background-color:var(--unrealModalBg);border-radius:var(--unrealModalBorderRadius);box-shadow:var(--unrealModalBoxShadow);color:var(--src-text-body-secondary, #4b5563);font-family:var(--src-font-family-header, Inter);font-size:var(--src-font-size-sm, 14px);font-style:normal;font-weight:400;line-height:var(--src-font-line-sm, 20px)}.unreal-modal .unreal-modal__header{position:relative;display:flex;padding:0;width:100%;border-bottom:var(--unrealModalTitleBorder)}.unreal-modal .unreal-modal__body{display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr);gap:var(--src-layout-gap-const-md, 12px);padding:var(--unrealModalBodyPadding);overflow:auto;scrollbar-width:thin;scrollbar-color:var(--src-border-container-basic, rgba(148, 163, 184, .24)) transparent}.unreal-modal .unreal-modal__body .unreal-modal__title{grid-column:1/-1}.unreal-modal .unreal-modal__body::-webkit-scrollbar{width:4px}.unreal-modal .unreal-modal__body::-webkit-scrollbar-track{background:transparent}.unreal-modal .unreal-modal__body::-webkit-scrollbar-thumb{background-color:var(--src-border-container-basic, rgba(148, 163, 184, .24));border-radius:10px}.unreal-modal .unreal-modal__footer{display:flex;justify-content:flex-end;align-items:center;padding:var(--src-layout-padding-const-md, 12px) var(--src-layout-padding-const-xl, 24px) var(--src-layout-padding-const-lg, 16px) var(--src-layout-padding-const-xl, 24px);width:100%;border-top:var(--unrealModalFooterBorder);gap:var(--src-layout-gap-const-sm, 8px)}.unreal-modal .unreal-modal__title{font-size:var(--unrealModalTitleSize);font-weight:600;line-height:var(--unrealModalTitleLineHeight);color:var(--unrealModalTitleColor);word-break:break-word}.unreal-modal .unreal-modal__header{padding:16px 24px 0}\n"], dependencies: [{ kind: "component", type: UnrealButtonComponent, selector: "app-unreal-button", inputs: ["type", "weight", "size", "fullWidth", "isDisabled", "data-testid", "ariaLabel"], outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4432
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealErrorModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4433
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.7", type: UnrealErrorModalComponent, isStandalone: true, selector: "app-unreal-error-modal", ngImport: i0, template: "<div class=\"unreal-modal\">\n <header class=\"unreal-modal__header\">\n <div\n [attr.data-testid]=\"'unreal-error-header-title'\"\n class=\"unreal-modal__title\"\n >\n Warning\n </div>\n </header>\n <div class=\"unreal-modal__body\">\n <div>{{ dialogData.content }}</div>\n </div>\n <div class=\"unreal-modal__footer\">\n <app-unreal-button (clicked)=\"close()\">Ok</app-unreal-button>\n </div>\n</div>\n", styles: [".unreal-modal{--unrealModalWidth: 422px;--unrealModalMaxWidth: calc(100% - 16px) ;--unrealModalMaxHeight: 80vh;--unrealModalBg: var(--src-surface-container-main, #fff);--unrealModalBoxShadow: 0 16px 36px 4px var(--src-shadow-hard, rgba(71, 85, 105, .24)), 0 1px 4px 0 var(--src-shadow-light, rgba(148, 163, 184, .16));--unrealModalBorderRadius: var(--src-layout-radius-const-rounded-md, 12px);--unrealModalTitleSize: var(--src-font-size-base, 16px);--unrealModalTitleLineHeight: var(--src-font-line-base, 24px);--unrealModalTitleColor: var(--src-text-body-main, #111827);--unrealModalBodyPadding: var(--src-layout-padding-const-lg, 16px) var(--src-layout-padding-const-xl, 24px) var(--src-layout-padding-const-2xl, 32px) var(--src-layout-padding-const-xl, 24px);--unrealModalTitleBorder: none;--unrealModalFooterBorder: 1px solid var(--src-border-container-light, rgba(148, 163, 184, .16));display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr) auto;width:var(--unrealModalWidth);max-width:var(--unrealModalMaxWidth);max-height:var(--unrealModalMaxHeight);margin:auto;background-color:var(--unrealModalBg);border-radius:var(--unrealModalBorderRadius);box-shadow:var(--unrealModalBoxShadow);color:var(--src-text-body-secondary, #4b5563);font-family:var(--src-font-family-header, Inter);font-size:var(--src-font-size-sm, 14px);font-style:normal;font-weight:400;line-height:var(--src-font-line-sm, 20px)}.unreal-modal .unreal-modal__header{position:relative;display:flex;padding:0;width:100%;border-bottom:var(--unrealModalTitleBorder)}.unreal-modal .unreal-modal__body{display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr);gap:var(--src-layout-gap-const-md, 12px);padding:var(--unrealModalBodyPadding);overflow:auto;scrollbar-width:thin;scrollbar-color:var(--src-border-container-basic, rgba(148, 163, 184, .24)) transparent}.unreal-modal .unreal-modal__body .unreal-modal__title{grid-column:1/-1}.unreal-modal .unreal-modal__body::-webkit-scrollbar{width:4px}.unreal-modal .unreal-modal__body::-webkit-scrollbar-track{background:transparent}.unreal-modal .unreal-modal__body::-webkit-scrollbar-thumb{background-color:var(--src-border-container-basic, rgba(148, 163, 184, .24));border-radius:10px}.unreal-modal .unreal-modal__footer{display:flex;justify-content:flex-end;align-items:center;padding:var(--src-layout-padding-const-md, 12px) var(--src-layout-padding-const-xl, 24px) var(--src-layout-padding-const-lg, 16px) var(--src-layout-padding-const-xl, 24px);width:100%;border-top:var(--unrealModalFooterBorder);gap:var(--src-layout-gap-const-sm, 8px)}.unreal-modal .unreal-modal__title{font-size:var(--unrealModalTitleSize);font-weight:600;line-height:var(--unrealModalTitleLineHeight);color:var(--unrealModalTitleColor);word-break:break-word}.unreal-modal .unreal-modal__header{padding:16px 24px 0}\n"], dependencies: [{ kind: "component", type: UnrealButtonComponent, selector: "app-unreal-button", inputs: ["type", "weight", "size", "fullWidth", "isDisabled", "data-testid", "ariaLabel"], outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4424
4434
  }
4425
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealErrorModalComponent, decorators: [{
4435
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealErrorModalComponent, decorators: [{
4426
4436
  type: Component,
4427
4437
  args: [{ selector: 'app-unreal-error-modal', changeDetection: ChangeDetectionStrategy.OnPush, imports: [UnrealButtonComponent], template: "<div class=\"unreal-modal\">\n <header class=\"unreal-modal__header\">\n <div\n [attr.data-testid]=\"'unreal-error-header-title'\"\n class=\"unreal-modal__title\"\n >\n Warning\n </div>\n </header>\n <div class=\"unreal-modal__body\">\n <div>{{ dialogData.content }}</div>\n </div>\n <div class=\"unreal-modal__footer\">\n <app-unreal-button (clicked)=\"close()\">Ok</app-unreal-button>\n </div>\n</div>\n", styles: [".unreal-modal{--unrealModalWidth: 422px;--unrealModalMaxWidth: calc(100% - 16px) ;--unrealModalMaxHeight: 80vh;--unrealModalBg: var(--src-surface-container-main, #fff);--unrealModalBoxShadow: 0 16px 36px 4px var(--src-shadow-hard, rgba(71, 85, 105, .24)), 0 1px 4px 0 var(--src-shadow-light, rgba(148, 163, 184, .16));--unrealModalBorderRadius: var(--src-layout-radius-const-rounded-md, 12px);--unrealModalTitleSize: var(--src-font-size-base, 16px);--unrealModalTitleLineHeight: var(--src-font-line-base, 24px);--unrealModalTitleColor: var(--src-text-body-main, #111827);--unrealModalBodyPadding: var(--src-layout-padding-const-lg, 16px) var(--src-layout-padding-const-xl, 24px) var(--src-layout-padding-const-2xl, 32px) var(--src-layout-padding-const-xl, 24px);--unrealModalTitleBorder: none;--unrealModalFooterBorder: 1px solid var(--src-border-container-light, rgba(148, 163, 184, .16));display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr) auto;width:var(--unrealModalWidth);max-width:var(--unrealModalMaxWidth);max-height:var(--unrealModalMaxHeight);margin:auto;background-color:var(--unrealModalBg);border-radius:var(--unrealModalBorderRadius);box-shadow:var(--unrealModalBoxShadow);color:var(--src-text-body-secondary, #4b5563);font-family:var(--src-font-family-header, Inter);font-size:var(--src-font-size-sm, 14px);font-style:normal;font-weight:400;line-height:var(--src-font-line-sm, 20px)}.unreal-modal .unreal-modal__header{position:relative;display:flex;padding:0;width:100%;border-bottom:var(--unrealModalTitleBorder)}.unreal-modal .unreal-modal__body{display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr);gap:var(--src-layout-gap-const-md, 12px);padding:var(--unrealModalBodyPadding);overflow:auto;scrollbar-width:thin;scrollbar-color:var(--src-border-container-basic, rgba(148, 163, 184, .24)) transparent}.unreal-modal .unreal-modal__body .unreal-modal__title{grid-column:1/-1}.unreal-modal .unreal-modal__body::-webkit-scrollbar{width:4px}.unreal-modal .unreal-modal__body::-webkit-scrollbar-track{background:transparent}.unreal-modal .unreal-modal__body::-webkit-scrollbar-thumb{background-color:var(--src-border-container-basic, rgba(148, 163, 184, .24));border-radius:10px}.unreal-modal .unreal-modal__footer{display:flex;justify-content:flex-end;align-items:center;padding:var(--src-layout-padding-const-md, 12px) var(--src-layout-padding-const-xl, 24px) var(--src-layout-padding-const-lg, 16px) var(--src-layout-padding-const-xl, 24px);width:100%;border-top:var(--unrealModalFooterBorder);gap:var(--src-layout-gap-const-sm, 8px)}.unreal-modal .unreal-modal__title{font-size:var(--unrealModalTitleSize);font-weight:600;line-height:var(--unrealModalTitleLineHeight);color:var(--unrealModalTitleColor);word-break:break-word}.unreal-modal .unreal-modal__header{padding:16px 24px 0}\n"] }]
4428
4438
  }] });
@@ -4818,10 +4828,10 @@ class UnrealEffects {
4818
4828
  // Fails silently if cross-origin
4819
4829
  }
4820
4830
  }
4821
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealEffects, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4822
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealEffects }); }
4831
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealEffects, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4832
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealEffects }); }
4823
4833
  }
4824
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealEffects, decorators: [{
4834
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealEffects, decorators: [{
4825
4835
  type: Injectable
4826
4836
  }] });
4827
4837
 
@@ -5210,6 +5220,19 @@ function getResizeValuesUniversal(params) {
5210
5220
  return { w: makeEven(w), h: makeEven(h), x: 0, y: 0, scale: w / maxSpace.w };
5211
5221
  }
5212
5222
 
5223
+ /**
5224
+ * Pulls a stream size into {@link STREAM_RESOLUTION_LIMITS} and keeps both
5225
+ * sides even. Every resolution sent to Unreal goes through here, so an encoder
5226
+ * failing size can never leave the player.
5227
+ */
5228
+ function clampStreamResolution({ w, h }) {
5229
+ const { minWidth, minHeight, maxWidth, maxHeight } = STREAM_RESOLUTION_LIMITS;
5230
+ return {
5231
+ w: makeEven(clampf(minWidth, maxWidth, w)),
5232
+ h: makeEven(clampf(minHeight, maxHeight, h)),
5233
+ };
5234
+ }
5235
+
5213
5236
  /**
5214
5237
  * Picks the class that carries the decoration of a UI part: the host class when
5215
5238
  * one is supplied, the built-in one otherwise. An empty string counts as "not
@@ -5337,10 +5360,10 @@ class AFKService extends SubService {
5337
5360
  }
5338
5361
  }, 1000);
5339
5362
  }
5340
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: AFKService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5341
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: AFKService, providedIn: 'root' }); }
5363
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: AFKService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5364
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: AFKService, providedIn: 'root' }); }
5342
5365
  }
5343
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: AFKService, decorators: [{
5366
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: AFKService, decorators: [{
5344
5367
  type: Injectable,
5345
5368
  args: [{ providedIn: 'root' }]
5346
5369
  }], ctorParameters: () => [] });
@@ -5390,10 +5413,10 @@ class LoadingProgressService {
5390
5413
  // `switchMap` cancels the inner subscription on every visibility change
5391
5414
  // so stale emissions can't leak through.
5392
5415
  #boundedProgress$;
5393
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LoadingProgressService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5394
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LoadingProgressService, providedIn: 'root' }); }
5416
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: LoadingProgressService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5417
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: LoadingProgressService, providedIn: 'root' }); }
5395
5418
  }
5396
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LoadingProgressService, decorators: [{
5419
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: LoadingProgressService, decorators: [{
5397
5420
  type: Injectable,
5398
5421
  args: [{ providedIn: 'root' }]
5399
5422
  }] });
@@ -5479,10 +5502,10 @@ class FreezeFrameService extends SubService {
5479
5502
  progress: 1,
5480
5503
  }));
5481
5504
  }
5482
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: FreezeFrameService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5483
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: FreezeFrameService, providedIn: 'root' }); }
5505
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: FreezeFrameService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5506
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: FreezeFrameService, providedIn: 'root' }); }
5484
5507
  }
5485
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: FreezeFrameService, decorators: [{
5508
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: FreezeFrameService, decorators: [{
5486
5509
  type: Injectable,
5487
5510
  args: [{ providedIn: 'root' }]
5488
5511
  }], ctorParameters: () => [] });
@@ -5634,10 +5657,10 @@ class FileReceiverService extends SubService {
5634
5657
  this.reset();
5635
5658
  }
5636
5659
  }
5637
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: FileReceiverService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5638
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: FileReceiverService, providedIn: 'root' }); }
5660
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: FileReceiverService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5661
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: FileReceiverService, providedIn: 'root' }); }
5639
5662
  }
5640
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: FileReceiverService, decorators: [{
5663
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: FileReceiverService, decorators: [{
5641
5664
  type: Injectable,
5642
5665
  args: [{ providedIn: 'root' }]
5643
5666
  }], ctorParameters: () => [] });
@@ -5822,10 +5845,10 @@ class AggregatorService extends SubService {
5822
5845
  Logger.warn(`unrecognized data received, packet ID ${view[0]}`);
5823
5846
  }
5824
5847
  }
5825
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: AggregatorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5826
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: AggregatorService, providedIn: 'root' }); }
5848
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: AggregatorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5849
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: AggregatorService, providedIn: 'root' }); }
5827
5850
  }
5828
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: AggregatorService, decorators: [{
5851
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: AggregatorService, decorators: [{
5829
5852
  type: Injectable,
5830
5853
  args: [{ providedIn: 'root' }]
5831
5854
  }], ctorParameters: () => [] });
@@ -5986,10 +6009,10 @@ class ConsoleExtensionsService extends SubService {
5986
6009
  Logger.info('emitCommand(command) => send command to Unreal Engine.');
5987
6010
  Logger.info('stressTest({iterations}) => hammer reconnect: repeatedly drop DC/PC and assert recovery.');
5988
6011
  }
5989
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ConsoleExtensionsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5990
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ConsoleExtensionsService, providedIn: 'root' }); }
6012
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: ConsoleExtensionsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
6013
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: ConsoleExtensionsService, providedIn: 'root' }); }
5991
6014
  }
5992
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ConsoleExtensionsService, decorators: [{
6015
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: ConsoleExtensionsService, decorators: [{
5993
6016
  type: Injectable,
5994
6017
  args: [{ providedIn: 'root' }]
5995
6018
  }], ctorParameters: () => [] });
@@ -6600,10 +6623,10 @@ class InputService extends SubService {
6600
6623
  this.sendInputData(data.buffer);
6601
6624
  });
6602
6625
  }
6603
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: InputService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
6604
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: InputService, providedIn: 'root' }); }
6626
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: InputService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
6627
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: InputService, providedIn: 'root' }); }
6605
6628
  }
6606
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: InputService, decorators: [{
6629
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: InputService, decorators: [{
6607
6630
  type: Injectable,
6608
6631
  args: [{ providedIn: 'root' }]
6609
6632
  }], ctorParameters: () => [] });
@@ -6672,14 +6695,76 @@ class StreamStatusTelemetryService extends SubService {
6672
6695
  VideoEncoderQP,
6673
6696
  };
6674
6697
  }
6675
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StreamStatusTelemetryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
6676
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StreamStatusTelemetryService, providedIn: 'root' }); }
6698
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: StreamStatusTelemetryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
6699
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: StreamStatusTelemetryService, providedIn: 'root' }); }
6677
6700
  }
6678
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StreamStatusTelemetryService, decorators: [{
6701
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: StreamStatusTelemetryService, decorators: [{
6679
6702
  type: Injectable,
6680
6703
  args: [{ providedIn: 'root' }]
6681
6704
  }], ctorParameters: () => [] });
6682
6705
 
6706
+ /**
6707
+ * Reads a cumulative counter as per-window increments.
6708
+ *
6709
+ * Deliberately NOT in `helpers/index.ts`: that barrel is re-exported by
6710
+ * `public-api.ts`, and this exists for one caller
6711
+ * (`services/stream-status-telemetry2.service.ts`). It is exported only so
6712
+ * its spec can reach it — importing it by path is the point, not an
6713
+ * oversight, and `create-websocket.ts` next door is kept out of the barrel
6714
+ * for the same reason.
6715
+ *
6716
+ * WebRTC reports totals — `bytesReceived` is everything since the peer
6717
+ * connection opened — while a windowed report wants "how much arrived during
6718
+ * THIS window". That is a subtraction, and the only thing it needs is the
6719
+ * counter's position when the previous window closed.
6720
+ *
6721
+ * Owning that position here, rather than keeping it in a field beside the
6722
+ * emitter, is what makes the mistake impossible: an instance belongs to one
6723
+ * session, so the first window of a new session can never subtract the last
6724
+ * window of the previous one and report a huge negative jump.
6725
+ */
6726
+ class CounterWindow {
6727
+ constructor() {
6728
+ /** Counter position when the previous window closed. `null` until the
6729
+ * first window is taken. */
6730
+ this.previous = null;
6731
+ }
6732
+ /**
6733
+ * The increment since the previous window, and `undefined` when there
6734
+ * isn't one to be had.
6735
+ *
6736
+ * `baseline` is where the FIRST window measures from — for WebRTC, the
6737
+ * value pinned when the connection's first stats report arrived. Without
6738
+ * it the first window would report every byte since the counter began,
6739
+ * which for a resumed connection is not this window at all. It is ignored
6740
+ * on every later call.
6741
+ *
6742
+ * `undefined` comes back in the two cases where a number would be a lie:
6743
+ *
6744
+ * - the counter is missing or not finite — nothing was measured;
6745
+ * - the counter went BACKWARDS, which means it was restarted (a
6746
+ * renegotiation, a new peer connection). The new position is remembered
6747
+ * so the next window is correct again, but this one has no honest answer:
6748
+ * the increment is somewhere between zero and the new total and nothing
6749
+ * here can say where.
6750
+ *
6751
+ * A consumer treats the gap as "estimate this window some other way" — a
6752
+ * missing figure it can label is worth more than a spike that never
6753
+ * happened.
6754
+ */
6755
+ delta(total, baseline) {
6756
+ if (typeof total !== 'number' || !Number.isFinite(total))
6757
+ return undefined;
6758
+ const from = this.previous ??
6759
+ (typeof baseline === 'number' && Number.isFinite(baseline)
6760
+ ? baseline
6761
+ : 0);
6762
+ this.previous = total;
6763
+ const increment = total - from;
6764
+ return increment >= 0 ? increment : undefined;
6765
+ }
6766
+ }
6767
+
6683
6768
  /**
6684
6769
  * Telemetry for the WebRTC stream lifecycle.
6685
6770
  *
@@ -7097,6 +7182,7 @@ class StreamStatusTelemetryService2 {
7097
7182
  lastMilestonePerf: anchorPerf,
7098
7183
  seq: 0,
7099
7184
  sub,
7185
+ bytes: new CounterWindow(),
7100
7186
  qpBad: false,
7101
7187
  fpsLow: false,
7102
7188
  maxFpsTarget: UNLIMITED_REFERENCE_FPS,
@@ -7493,6 +7579,15 @@ class StreamStatusTelemetryService2 {
7493
7579
  const jitter = this.aggregate(nonNegative((a) => a.jitter));
7494
7580
  const rtt = this.aggregate(positive((a) => a.currentRoundTripTime));
7495
7581
  const latest = samples[samples.length - 1]?.aggregatedStats;
7582
+ // Bytes of THIS window, read off the cumulative counter the last report
7583
+ // carried. Taken exactly once per window — `delta` moves the position it
7584
+ // measures from, so a second call would report zero.
7585
+ //
7586
+ // The first window of a session measures from `bytesReceivedStart`, the
7587
+ // baseline the video service pins on the connection's first report, so
7588
+ // the bytes that arrived before the first sample landed are counted here
7589
+ // rather than lost.
7590
+ const bytes = s.bytes.delta(latest?.bytesReceived, latest?.bytesReceivedStart);
7496
7591
  // Periodic sample event.
7497
7592
  this.track('stream.sample', {
7498
7593
  sessionId: s.id,
@@ -7509,6 +7604,10 @@ class StreamStatusTelemetryService2 {
7509
7604
  jitter,
7510
7605
  rtt,
7511
7606
  packetsLost: latest?.packetsLost,
7607
+ // Dropped from the JSON when undefined, exactly like `packetsLost`: a
7608
+ // window whose bytes could not be measured must arrive with the key
7609
+ // ABSENT, never as a zero a consumer would add to a total.
7610
+ bytes,
7512
7611
  viewPort: {
7513
7612
  width: latest?.frameWidth,
7514
7613
  height: latest?.frameHeight,
@@ -7761,10 +7860,10 @@ class StreamStatusTelemetryService2 {
7761
7860
  emit(event, data) {
7762
7861
  this.store.dispatch(trackTelemetryData({ event, data }));
7763
7862
  }
7764
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StreamStatusTelemetryService2, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
7765
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StreamStatusTelemetryService2, providedIn: 'root' }); }
7863
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: StreamStatusTelemetryService2, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
7864
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: StreamStatusTelemetryService2, providedIn: 'root' }); }
7766
7865
  }
7767
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StreamStatusTelemetryService2, decorators: [{
7866
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: StreamStatusTelemetryService2, decorators: [{
7768
7867
  type: Injectable,
7769
7868
  args: [{ providedIn: 'root' }]
7770
7869
  }], ctorParameters: () => [] });
@@ -7850,10 +7949,10 @@ class FileHandlerService {
7850
7949
  return observable;
7851
7950
  });
7852
7951
  }
7853
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: FileHandlerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
7854
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: FileHandlerService, providedIn: 'root' }); }
7952
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: FileHandlerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
7953
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: FileHandlerService, providedIn: 'root' }); }
7855
7954
  }
7856
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: FileHandlerService, decorators: [{
7955
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: FileHandlerService, decorators: [{
7857
7956
  type: Injectable,
7858
7957
  args: [{ providedIn: 'root' }]
7859
7958
  }] });
@@ -7942,10 +8041,10 @@ class AnalyticsService extends SubService {
7942
8041
  Logger.log('Analytics Event:', name, params);
7943
8042
  this.store.dispatch(saveAnalyticsEvent({ event: { name, params } }));
7944
8043
  }
7945
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: AnalyticsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
7946
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: AnalyticsService, providedIn: 'root' }); }
8044
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: AnalyticsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
8045
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: AnalyticsService, providedIn: 'root' }); }
7947
8046
  }
7948
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: AnalyticsService, decorators: [{
8047
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: AnalyticsService, decorators: [{
7949
8048
  type: Injectable,
7950
8049
  args: [{ providedIn: 'root' }]
7951
8050
  }], ctorParameters: () => [] });
@@ -8216,10 +8315,10 @@ class FpsMonitorService extends SubService {
8216
8315
  }
8217
8316
  return { fps: fps / len, bitrate: bitrate / len, qp: qp / len };
8218
8317
  }
8219
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: FpsMonitorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
8220
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: FpsMonitorService, providedIn: 'root' }); }
8318
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: FpsMonitorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
8319
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: FpsMonitorService, providedIn: 'root' }); }
8221
8320
  }
8222
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: FpsMonitorService, decorators: [{
8321
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: FpsMonitorService, decorators: [{
8223
8322
  type: Injectable,
8224
8323
  args: [{ providedIn: 'root' }]
8225
8324
  }], ctorParameters: () => [] });
@@ -8254,10 +8353,10 @@ class AfkTimeoutModalComponent {
8254
8353
  resetAfk() {
8255
8354
  this.#afkService.reset();
8256
8355
  }
8257
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: AfkTimeoutModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8258
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: AfkTimeoutModalComponent, isStandalone: true, selector: "app-afk-timeout-modal", inputs: { uiClasses: { classPropertyName: "uiClasses", publicName: "uiClasses", isSignal: true, isRequired: false, transformFunction: null }, contentTemplate: { classPropertyName: "contentTemplate", publicName: "contentTemplate", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (isShowAfkPopup()) {\n <div\n (click)=\"resetAfk()\"\n [class]=\"scrimSkin()\"\n class=\"afk-anchor clickableState\"\n id=\"videoPlayOverlay\"\n >\n <div [class]=\"cardSkin()\">\n @if (contentTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: slotContext }\"\n />\n } @else {\n <div aria-hidden=\"true\" class=\"resume-box__pic\" role=\"presentation\">\n <div [innerHTML]=\"afkCountdown()\" class=\"text-number\"></div>\n </div>\n <div class=\"resume-box__text\">\n <h3 class=\"resume-box__heading\">Session will time out soon</h3>\n <p>\n No activity detected. Press 'Continue' if you wish to keep your\n session active\n </p>\n </div>\n <app-unreal-button\n [fullWidth]=\"true\"\n [data-testid]=\"'continue-session'\"\n [class]=\"buttonSkin()\"\n weight=\"primary\"\n size=\"lg\"\n >\n Continue\n </app-unreal-button>\n }\n </div>\n </div>\n}\n", styles: [".afk-anchor{position:absolute;z-index:30;top:0;width:100%;height:100%}.afk-scrim{font-size:1.8em;font-family:var(--unreal-font-family, var(--src-font-family-body, system-ui, sans-serif));background-color:var(--unreal-surface-scrim, rgba(100, 100, 100, .7))}.clickableState{display:flex;justify-content:center;align-items:center;cursor:pointer}.textDisplayState{display:flex}.hiddenState{display:none}.resume-box{width:340px;padding:32px 20px 20px;flex-direction:column;align-items:center;border-radius:var(--unreal-radius-card, var(--src-border-rounded-parent, 8px));background:var(--unreal-surface-card, var(--src-surface-container-main, #fff));box-shadow:var(--unreal-shadow-card, 0 26px 80px 0 rgba(0, 0, 0, .2), 0 0 1px 0 rgba(0, 0, 0, .2))}.resume-box__pic{width:72px;height:72px;margin:0 auto 22px;border-radius:48px;background:#ecf0f2;padding:12px;display:flex;align-items:center;justify-content:center}.text-number{color:var(--unreal-text-main, #1f2937);text-align:center;font-family:var(--unreal-font-family, var(--src-font-family-body, system-ui, sans-serif));font-size:30px;font-style:normal;font-weight:400;line-height:24px}.resume-box__text{margin-bottom:18px}.resume-box__text p{text-align:center;font-family:var(--unreal-font-family, var(--src-font-family-body, system-ui, sans-serif));font-size:var(--src-font-size-sm, 14px);font-style:normal;font-weight:400;line-height:24px;color:var(--unreal-text-secondary, var(--src-text-body-secondary, #6b7280))}.resume-box__text .resume-box__heading{color:var(--unreal-text-main, var(--src-text-body-main, #1f2937));text-align:center;font-family:var(--unreal-font-family, var(--src-font-family-body, system-ui, sans-serif));font-size:18px;font-style:normal;font-weight:500;line-height:26px;margin-bottom:8px}\n"], dependencies: [{ kind: "component", type: UnrealButtonComponent, selector: "app-unreal-button", inputs: ["type", "weight", "size", "fullWidth", "isDisabled", "data-testid", "ariaLabel"], outputs: ["clicked"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8356
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: AfkTimeoutModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8357
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: AfkTimeoutModalComponent, isStandalone: true, selector: "app-afk-timeout-modal", inputs: { uiClasses: { classPropertyName: "uiClasses", publicName: "uiClasses", isSignal: true, isRequired: false, transformFunction: null }, contentTemplate: { classPropertyName: "contentTemplate", publicName: "contentTemplate", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (isShowAfkPopup()) {\n <div\n (click)=\"resetAfk()\"\n [class]=\"scrimSkin()\"\n class=\"afk-anchor clickableState\"\n id=\"videoPlayOverlay\"\n >\n <div [class]=\"cardSkin()\">\n @if (contentTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: slotContext }\"\n />\n } @else {\n <div aria-hidden=\"true\" class=\"resume-box__pic\" role=\"presentation\">\n <div [innerHTML]=\"afkCountdown()\" class=\"text-number\"></div>\n </div>\n <div class=\"resume-box__text\">\n <h3 class=\"resume-box__heading\">Session will time out soon</h3>\n <p>\n No activity detected. Press 'Continue' if you wish to keep your\n session active\n </p>\n </div>\n <app-unreal-button\n [fullWidth]=\"true\"\n [data-testid]=\"'continue-session'\"\n [class]=\"buttonSkin()\"\n weight=\"primary\"\n size=\"lg\"\n >\n Continue\n </app-unreal-button>\n }\n </div>\n </div>\n}\n", styles: [".afk-anchor{position:absolute;z-index:30;top:0;width:100%;height:100%}.afk-scrim{font-size:1.8em;font-family:var(--unreal-font-family, var(--src-font-family-body, system-ui, sans-serif));background-color:var(--unreal-surface-scrim, rgba(100, 100, 100, .7))}.clickableState{display:flex;justify-content:center;align-items:center;cursor:pointer}.textDisplayState{display:flex}.hiddenState{display:none}.resume-box{width:340px;padding:32px 20px 20px;flex-direction:column;align-items:center;border-radius:var(--unreal-radius-card, var(--src-border-rounded-parent, 8px));background:var(--unreal-surface-card, var(--src-surface-container-main, #fff));box-shadow:var(--unreal-shadow-card, 0 26px 80px 0 rgba(0, 0, 0, .2), 0 0 1px 0 rgba(0, 0, 0, .2))}.resume-box__pic{width:72px;height:72px;margin:0 auto 22px;border-radius:48px;background:#ecf0f2;padding:12px;display:flex;align-items:center;justify-content:center}.text-number{color:var(--unreal-text-main, #1f2937);text-align:center;font-family:var(--unreal-font-family, var(--src-font-family-body, system-ui, sans-serif));font-size:30px;font-style:normal;font-weight:400;line-height:24px}.resume-box__text{margin-bottom:18px}.resume-box__text p{text-align:center;font-family:var(--unreal-font-family, var(--src-font-family-body, system-ui, sans-serif));font-size:var(--src-font-size-sm, 14px);font-style:normal;font-weight:400;line-height:24px;color:var(--unreal-text-secondary, var(--src-text-body-secondary, #6b7280))}.resume-box__text .resume-box__heading{color:var(--unreal-text-main, var(--src-text-body-main, #1f2937));text-align:center;font-family:var(--unreal-font-family, var(--src-font-family-body, system-ui, sans-serif));font-size:18px;font-style:normal;font-weight:500;line-height:26px;margin-bottom:8px}\n"], dependencies: [{ kind: "component", type: UnrealButtonComponent, selector: "app-unreal-button", inputs: ["type", "weight", "size", "fullWidth", "isDisabled", "data-testid", "ariaLabel"], outputs: ["clicked"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8259
8358
  }
8260
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: AfkTimeoutModalComponent, decorators: [{
8359
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: AfkTimeoutModalComponent, decorators: [{
8261
8360
  type: Component,
8262
8361
  args: [{ selector: 'app-afk-timeout-modal', changeDetection: ChangeDetectionStrategy.OnPush, imports: [UnrealButtonComponent, NgTemplateOutlet], template: "@if (isShowAfkPopup()) {\n <div\n (click)=\"resetAfk()\"\n [class]=\"scrimSkin()\"\n class=\"afk-anchor clickableState\"\n id=\"videoPlayOverlay\"\n >\n <div [class]=\"cardSkin()\">\n @if (contentTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: slotContext }\"\n />\n } @else {\n <div aria-hidden=\"true\" class=\"resume-box__pic\" role=\"presentation\">\n <div [innerHTML]=\"afkCountdown()\" class=\"text-number\"></div>\n </div>\n <div class=\"resume-box__text\">\n <h3 class=\"resume-box__heading\">Session will time out soon</h3>\n <p>\n No activity detected. Press 'Continue' if you wish to keep your\n session active\n </p>\n </div>\n <app-unreal-button\n [fullWidth]=\"true\"\n [data-testid]=\"'continue-session'\"\n [class]=\"buttonSkin()\"\n weight=\"primary\"\n size=\"lg\"\n >\n Continue\n </app-unreal-button>\n }\n </div>\n </div>\n}\n", styles: [".afk-anchor{position:absolute;z-index:30;top:0;width:100%;height:100%}.afk-scrim{font-size:1.8em;font-family:var(--unreal-font-family, var(--src-font-family-body, system-ui, sans-serif));background-color:var(--unreal-surface-scrim, rgba(100, 100, 100, .7))}.clickableState{display:flex;justify-content:center;align-items:center;cursor:pointer}.textDisplayState{display:flex}.hiddenState{display:none}.resume-box{width:340px;padding:32px 20px 20px;flex-direction:column;align-items:center;border-radius:var(--unreal-radius-card, var(--src-border-rounded-parent, 8px));background:var(--unreal-surface-card, var(--src-surface-container-main, #fff));box-shadow:var(--unreal-shadow-card, 0 26px 80px 0 rgba(0, 0, 0, .2), 0 0 1px 0 rgba(0, 0, 0, .2))}.resume-box__pic{width:72px;height:72px;margin:0 auto 22px;border-radius:48px;background:#ecf0f2;padding:12px;display:flex;align-items:center;justify-content:center}.text-number{color:var(--unreal-text-main, #1f2937);text-align:center;font-family:var(--unreal-font-family, var(--src-font-family-body, system-ui, sans-serif));font-size:30px;font-style:normal;font-weight:400;line-height:24px}.resume-box__text{margin-bottom:18px}.resume-box__text p{text-align:center;font-family:var(--unreal-font-family, var(--src-font-family-body, system-ui, sans-serif));font-size:var(--src-font-size-sm, 14px);font-style:normal;font-weight:400;line-height:24px;color:var(--unreal-text-secondary, var(--src-text-body-secondary, #6b7280))}.resume-box__text .resume-box__heading{color:var(--unreal-text-main, var(--src-text-body-main, #1f2937));text-align:center;font-family:var(--unreal-font-family, var(--src-font-family-body, system-ui, sans-serif));font-size:18px;font-style:normal;font-weight:500;line-height:26px;margin-bottom:8px}\n"] }]
8263
8362
  }], propDecorators: { uiClasses: [{ type: i0.Input, args: [{ isSignal: true, alias: "uiClasses", required: false }] }], contentTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentTemplate", required: false }] }] } });
@@ -8269,10 +8368,10 @@ class FreezeFrameComponent {
8269
8368
  this.combinedFreeze = this.#store.selectSignal(selectFreezeFrameCombinedDataUrl);
8270
8369
  }
8271
8370
  #store;
8272
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: FreezeFrameComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8273
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: FreezeFrameComponent, isStandalone: true, selector: "app-freeze-frame", ngImport: i0, template: "@let image = combinedFreeze();\n@let progress = freezeFrameProgressMessageFromVideo();\n\n<div class=\"freeze-images\">\n @if (image) {\n <img [src]=\"image\" class=\"videoStillImage\" alt=\"freezeFrameImage\" />\n }\n\n @if (progress) {\n <div class=\"progress-status\">\n {{ progress }}\n </div>\n }\n</div>\n", styles: [".freeze-images{pointer-events:none;position:absolute;left:0;top:0;width:100%;height:100%;z-index:1}.freeze-images .freezeFrameOverlay{top:0;left:0;width:100%;height:100%;position:absolute;object-fit:cover;object-position:center}.freeze-images .videoStillImage{position:absolute;z-index:1;top:0;left:0;width:100%;height:100%;object-fit:cover}.freeze-images .progress-status{position:absolute;top:50%;left:50%;z-index:1;display:flex;flex-direction:column;justify-content:center;align-items:center;width:auto;height:auto;margin:0;padding:10px;background-color:#ffffffb3;border:1px solid grey;transform:translate(-50%,-50%)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8371
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: FreezeFrameComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8372
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: FreezeFrameComponent, isStandalone: true, selector: "app-freeze-frame", ngImport: i0, template: "@let image = combinedFreeze();\n@let progress = freezeFrameProgressMessageFromVideo();\n\n<div class=\"freeze-images\">\n @if (image) {\n <img [src]=\"image\" class=\"videoStillImage\" alt=\"freezeFrameImage\" />\n }\n\n @if (progress) {\n <div class=\"progress-status\">\n {{ progress }}\n </div>\n }\n</div>\n", styles: [".freeze-images{pointer-events:none;position:absolute;left:0;top:0;width:100%;height:100%;z-index:1}.freeze-images .freezeFrameOverlay{top:0;left:0;width:100%;height:100%;position:absolute;object-fit:cover;object-position:center}.freeze-images .videoStillImage{position:absolute;z-index:1;top:0;left:0;width:100%;height:100%;object-fit:cover}.freeze-images .progress-status{position:absolute;top:50%;left:50%;z-index:1;display:flex;flex-direction:column;justify-content:center;align-items:center;width:auto;height:auto;margin:0;padding:10px;background-color:#ffffffb3;border:1px solid grey;transform:translate(-50%,-50%)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8274
8373
  }
8275
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: FreezeFrameComponent, decorators: [{
8374
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: FreezeFrameComponent, decorators: [{
8276
8375
  type: Component,
8277
8376
  args: [{ selector: 'app-freeze-frame', changeDetection: ChangeDetectionStrategy.OnPush, template: "@let image = combinedFreeze();\n@let progress = freezeFrameProgressMessageFromVideo();\n\n<div class=\"freeze-images\">\n @if (image) {\n <img [src]=\"image\" class=\"videoStillImage\" alt=\"freezeFrameImage\" />\n }\n\n @if (progress) {\n <div class=\"progress-status\">\n {{ progress }}\n </div>\n }\n</div>\n", styles: [".freeze-images{pointer-events:none;position:absolute;left:0;top:0;width:100%;height:100%;z-index:1}.freeze-images .freezeFrameOverlay{top:0;left:0;width:100%;height:100%;position:absolute;object-fit:cover;object-position:center}.freeze-images .videoStillImage{position:absolute;z-index:1;top:0;left:0;width:100%;height:100%;object-fit:cover}.freeze-images .progress-status{position:absolute;top:50%;left:50%;z-index:1;display:flex;flex-direction:column;justify-content:center;align-items:center;width:auto;height:auto;margin:0;padding:10px;background-color:#ffffffb3;border:1px solid grey;transform:translate(-50%,-50%)}\n"] }]
8278
8377
  }] });
@@ -8287,10 +8386,10 @@ class ImageLoadingSrcComponent {
8287
8386
  loadingImageError() {
8288
8387
  this.#store.dispatch(setLoadingImageSrc({ src: '' }));
8289
8388
  }
8290
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ImageLoadingSrcComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8291
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: ImageLoadingSrcComponent, isStandalone: true, selector: "app-image-loading-src", ngImport: i0, template: "@let image = imageLoadingSrc();\n@if (isLoaderScreenVisible()) {\n <div class=\"preload\">\n <div class=\"back\">\n @if (image) {\n <img\n (error)=\"loadingImageError()\"\n [ngSrc]=\"image\"\n fill\n loading=\"lazy\"\n alt=\"image loading src\"\n />\n }\n </div>\n </div>\n}\n", styles: [".preload{position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}.preload .back{position:absolute;top:0;left:0;display:flex;justify-content:center;align-items:center;width:100%;height:100%}.preload .back img{width:100%;height:100%;object-fit:cover}.preload .back{background-color:var(--unreal-surface-screen, #fff)}\n"], dependencies: [{ kind: "directive", type: NgOptimizedImage, selector: "img[ngSrc]", inputs: ["ngSrc", "ngSrcset", "sizes", "width", "height", "decoding", "loading", "priority", "loaderParams", "disableOptimizedSrcset", "fill", "placeholder", "placeholderConfig", "src", "srcset"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8389
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: ImageLoadingSrcComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8390
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: ImageLoadingSrcComponent, isStandalone: true, selector: "app-image-loading-src", ngImport: i0, template: "@let image = imageLoadingSrc();\n@if (isLoaderScreenVisible()) {\n <div class=\"preload\">\n <div class=\"back\">\n @if (image) {\n <img\n (error)=\"loadingImageError()\"\n [ngSrc]=\"image\"\n fill\n loading=\"lazy\"\n alt=\"image loading src\"\n />\n }\n </div>\n </div>\n}\n", styles: [".preload{position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}.preload .back{position:absolute;top:0;left:0;display:flex;justify-content:center;align-items:center;width:100%;height:100%}.preload .back img{width:100%;height:100%;object-fit:cover}.preload .back{background-color:var(--unreal-surface-screen, #fff)}\n"], dependencies: [{ kind: "directive", type: NgOptimizedImage, selector: "img[ngSrc]", inputs: ["ngSrc", "ngSrcset", "sizes", "width", "height", "decoding", "loading", "priority", "loaderParams", "disableOptimizedSrcset", "fill", "placeholder", "placeholderConfig", "src", "srcset"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8292
8391
  }
8293
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ImageLoadingSrcComponent, decorators: [{
8392
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: ImageLoadingSrcComponent, decorators: [{
8294
8393
  type: Component,
8295
8394
  args: [{ selector: 'app-image-loading-src', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgOptimizedImage], template: "@let image = imageLoadingSrc();\n@if (isLoaderScreenVisible()) {\n <div class=\"preload\">\n <div class=\"back\">\n @if (image) {\n <img\n (error)=\"loadingImageError()\"\n [ngSrc]=\"image\"\n fill\n loading=\"lazy\"\n alt=\"image loading src\"\n />\n }\n </div>\n </div>\n}\n", styles: [".preload{position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}.preload .back{position:absolute;top:0;left:0;display:flex;justify-content:center;align-items:center;width:100%;height:100%}.preload .back img{width:100%;height:100%;object-fit:cover}.preload .back{background-color:var(--unreal-surface-screen, #fff)}\n"] }]
8296
8395
  }] });
@@ -8373,10 +8472,10 @@ class StatGraphComponent {
8373
8472
  }
8374
8473
  this.draw();
8375
8474
  }
8376
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StatGraphComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8377
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.4", type: StatGraphComponent, isStandalone: true, selector: "app-stat-graph", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, stat: { classPropertyName: "stat", publicName: "stat", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, tickStep: { classPropertyName: "tickStep", publicName: "tickStep", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "window:resize": "resize()" } }, viewQueries: [{ propertyName: "graph", first: true, predicate: ["graph"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"content\">\n <p>{{ label() }}: {{ current() }} | Min:{{ min() }} | Max:{{ max() }}</p>\n <canvas #graph class=\"graph\"></canvas>\n</div>\n", styles: [".content{width:100%;height:100%}.content p{color:#fff;margin:5px 0 0;height:25px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8475
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: StatGraphComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8476
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.7", type: StatGraphComponent, isStandalone: true, selector: "app-stat-graph", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, stat: { classPropertyName: "stat", publicName: "stat", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, tickStep: { classPropertyName: "tickStep", publicName: "tickStep", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "window:resize": "resize()" } }, viewQueries: [{ propertyName: "graph", first: true, predicate: ["graph"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"content\">\n <p>{{ label() }}: {{ current() }} | Min:{{ min() }} | Max:{{ max() }}</p>\n <canvas #graph class=\"graph\"></canvas>\n</div>\n", styles: [".content{width:100%;height:100%}.content p{color:#fff;margin:5px 0 0;height:25px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8378
8477
  }
8379
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StatGraphComponent, decorators: [{
8478
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: StatGraphComponent, decorators: [{
8380
8479
  type: Component,
8381
8480
  args: [{ selector: 'app-stat-graph', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"content\">\n <p>{{ label() }}: {{ current() }} | Min:{{ min() }} | Max:{{ max() }}</p>\n <canvas #graph class=\"graph\"></canvas>\n</div>\n", styles: [".content{width:100%;height:100%}.content p{color:#fff;margin:5px 0 0;height:25px}\n"] }]
8382
8481
  }], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], stat: [{ type: i0.Input, args: [{ isSignal: true, alias: "stat", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], tickStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "tickStep", required: false }] }], graph: [{ type: i0.ViewChild, args: ['graph', { isSignal: true }] }], resize: [{
@@ -8391,10 +8490,10 @@ class UnrealResumeSlotDirective {
8391
8490
  static ngTemplateContextGuard(_dir, _ctx) {
8392
8491
  return true;
8393
8492
  }
8394
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealResumeSlotDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
8395
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.4", type: UnrealResumeSlotDirective, isStandalone: true, selector: "ng-template[unrealResumeSlot]", ngImport: i0 }); }
8493
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealResumeSlotDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
8494
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.7", type: UnrealResumeSlotDirective, isStandalone: true, selector: "ng-template[unrealResumeSlot]", ngImport: i0 }); }
8396
8495
  }
8397
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealResumeSlotDirective, decorators: [{
8496
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealResumeSlotDirective, decorators: [{
8398
8497
  type: Directive,
8399
8498
  args: [{ selector: 'ng-template[unrealResumeSlot]' }]
8400
8499
  }] });
@@ -8405,10 +8504,10 @@ class UnrealAfkSlotDirective {
8405
8504
  static ngTemplateContextGuard(_dir, _ctx) {
8406
8505
  return true;
8407
8506
  }
8408
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealAfkSlotDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
8409
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.4", type: UnrealAfkSlotDirective, isStandalone: true, selector: "ng-template[unrealAfkSlot]", ngImport: i0 }); }
8507
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealAfkSlotDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
8508
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.7", type: UnrealAfkSlotDirective, isStandalone: true, selector: "ng-template[unrealAfkSlot]", ngImport: i0 }); }
8410
8509
  }
8411
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealAfkSlotDirective, decorators: [{
8510
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealAfkSlotDirective, decorators: [{
8412
8511
  type: Directive,
8413
8512
  args: [{ selector: 'ng-template[unrealAfkSlot]' }]
8414
8513
  }] });
@@ -8419,10 +8518,10 @@ class UnrealStatusSlotDirective {
8419
8518
  static ngTemplateContextGuard(_dir, _ctx) {
8420
8519
  return true;
8421
8520
  }
8422
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealStatusSlotDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
8423
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.4", type: UnrealStatusSlotDirective, isStandalone: true, selector: "ng-template[unrealStatusSlot]", ngImport: i0 }); }
8521
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealStatusSlotDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
8522
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.7", type: UnrealStatusSlotDirective, isStandalone: true, selector: "ng-template[unrealStatusSlot]", ngImport: i0 }); }
8424
8523
  }
8425
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealStatusSlotDirective, decorators: [{
8524
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealStatusSlotDirective, decorators: [{
8426
8525
  type: Directive,
8427
8526
  args: [{ selector: 'ng-template[unrealStatusSlot]' }]
8428
8527
  }] });
@@ -8445,10 +8544,10 @@ class UnrealSpinnerComponent {
8445
8544
  this.viewBox = computed(() => `0 0 ${this.size()} ${this.size()}`, /* @ts-ignore */
8446
8545
  ...(ngDevMode ? [{ debugName: "viewBox" }] : /* istanbul ignore next */ []));
8447
8546
  }
8448
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealSpinnerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8449
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: UnrealSpinnerComponent, isStandalone: true, selector: "app-unreal-spinner", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, strokeWidth: { classPropertyName: "strokeWidth", publicName: "strokeWidth", isSignal: true, isRequired: false, transformFunction: null }, strokeColor: { classPropertyName: "strokeColor", publicName: "strokeColor", isSignal: true, isRequired: false, transformFunction: null }, testID: { classPropertyName: "testID", publicName: "data-testid", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n [attr.data-testid]=\"testID() || null\"\n [attr.aria-label]=\"ariaLabel()\"\n class=\"unreal-spinner-container\"\n role=\"status\"\n>\n <svg\n [attr.width]=\"size()\"\n [attr.height]=\"size()\"\n [attr.viewBox]=\"viewBox()\"\n [style.--unrealSpinnerSize]=\"size()\"\n class=\"unreal-spinner unreal-spinner--animation\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style=\"transform: rotate(-90deg)\"\n aria-hidden=\"true\"\n >\n <circle\n [attr.r]=\"radius()\"\n [attr.cx]=\"center()\"\n [attr.cy]=\"center()\"\n [attr.stroke]=\"strokeColor()\"\n [attr.stroke-width]=\"strokeWidth()\"\n fill=\"transparent\"\n stroke-linecap=\"round\"\n ></circle>\n </svg>\n</div>\n", styles: [":host{display:block}.unreal-spinner-container{position:relative;display:flex;justify-content:center;align-items:center;width:100%;height:100%}.unreal-spinner{position:relative;display:inline-block}.unreal-spinner--animation{animation:1.4s linear 0s infinite normal none running unrealSpinnerRotate}.unreal-spinner--animation circle{transform-origin:50% 50%;stroke-dasharray:calc(var(--unrealSpinnerSize) * 2 * 1px),calc(var(--unrealSpinnerSize) * 5 * 1px);stroke-dashoffset:0;animation:1.6s ease-in-out 0s infinite normal none running unrealSpinnerDash}@keyframes unrealSpinnerRotate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes unrealSpinnerDash{0%{stroke-dasharray:1px,calc(var(--unrealSpinnerSize) * 5 * 1px);stroke-dashoffset:0}50%{stroke-dasharray:calc(var(--unrealSpinnerSize) * 2.5 * 1px),calc(var(--unrealSpinnerSize) * 5 * 1px);stroke-dashoffset:calc(var(--unrealSpinnerSize) * .4 * -1px)}to{stroke-dasharray:calc(var(--unrealSpinnerSize) * 2.5 * 1px),calc(var(--unrealSpinnerSize) * 5 * 1px);stroke-dashoffset:calc(var(--unrealSpinnerSize) * 3 * -1px)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8547
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealSpinnerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8548
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: UnrealSpinnerComponent, isStandalone: true, selector: "app-unreal-spinner", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, strokeWidth: { classPropertyName: "strokeWidth", publicName: "strokeWidth", isSignal: true, isRequired: false, transformFunction: null }, strokeColor: { classPropertyName: "strokeColor", publicName: "strokeColor", isSignal: true, isRequired: false, transformFunction: null }, testID: { classPropertyName: "testID", publicName: "data-testid", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n [attr.data-testid]=\"testID() || null\"\n [attr.aria-label]=\"ariaLabel()\"\n class=\"unreal-spinner-container\"\n role=\"status\"\n>\n <svg\n [attr.width]=\"size()\"\n [attr.height]=\"size()\"\n [attr.viewBox]=\"viewBox()\"\n [style.--unrealSpinnerSize]=\"size()\"\n class=\"unreal-spinner unreal-spinner--animation\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style=\"transform: rotate(-90deg)\"\n aria-hidden=\"true\"\n >\n <circle\n [attr.r]=\"radius()\"\n [attr.cx]=\"center()\"\n [attr.cy]=\"center()\"\n [attr.stroke]=\"strokeColor()\"\n [attr.stroke-width]=\"strokeWidth()\"\n fill=\"transparent\"\n stroke-linecap=\"round\"\n ></circle>\n </svg>\n</div>\n", styles: [":host{display:block}.unreal-spinner-container{position:relative;display:flex;justify-content:center;align-items:center;width:100%;height:100%}.unreal-spinner{position:relative;display:inline-block}.unreal-spinner--animation{animation:1.4s linear 0s infinite normal none running unrealSpinnerRotate}.unreal-spinner--animation circle{transform-origin:50% 50%;stroke-dasharray:calc(var(--unrealSpinnerSize) * 2 * 1px),calc(var(--unrealSpinnerSize) * 5 * 1px);stroke-dashoffset:0;animation:1.6s ease-in-out 0s infinite normal none running unrealSpinnerDash}@keyframes unrealSpinnerRotate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes unrealSpinnerDash{0%{stroke-dasharray:1px,calc(var(--unrealSpinnerSize) * 5 * 1px);stroke-dashoffset:0}50%{stroke-dasharray:calc(var(--unrealSpinnerSize) * 2.5 * 1px),calc(var(--unrealSpinnerSize) * 5 * 1px);stroke-dashoffset:calc(var(--unrealSpinnerSize) * .4 * -1px)}to{stroke-dasharray:calc(var(--unrealSpinnerSize) * 2.5 * 1px),calc(var(--unrealSpinnerSize) * 5 * 1px);stroke-dashoffset:calc(var(--unrealSpinnerSize) * 3 * -1px)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8450
8549
  }
8451
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealSpinnerComponent, decorators: [{
8550
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealSpinnerComponent, decorators: [{
8452
8551
  type: Component,
8453
8552
  args: [{ selector: 'app-unreal-spinner', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n [attr.data-testid]=\"testID() || null\"\n [attr.aria-label]=\"ariaLabel()\"\n class=\"unreal-spinner-container\"\n role=\"status\"\n>\n <svg\n [attr.width]=\"size()\"\n [attr.height]=\"size()\"\n [attr.viewBox]=\"viewBox()\"\n [style.--unrealSpinnerSize]=\"size()\"\n class=\"unreal-spinner unreal-spinner--animation\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style=\"transform: rotate(-90deg)\"\n aria-hidden=\"true\"\n >\n <circle\n [attr.r]=\"radius()\"\n [attr.cx]=\"center()\"\n [attr.cy]=\"center()\"\n [attr.stroke]=\"strokeColor()\"\n [attr.stroke-width]=\"strokeWidth()\"\n fill=\"transparent\"\n stroke-linecap=\"round\"\n ></circle>\n </svg>\n</div>\n", styles: [":host{display:block}.unreal-spinner-container{position:relative;display:flex;justify-content:center;align-items:center;width:100%;height:100%}.unreal-spinner{position:relative;display:inline-block}.unreal-spinner--animation{animation:1.4s linear 0s infinite normal none running unrealSpinnerRotate}.unreal-spinner--animation circle{transform-origin:50% 50%;stroke-dasharray:calc(var(--unrealSpinnerSize) * 2 * 1px),calc(var(--unrealSpinnerSize) * 5 * 1px);stroke-dashoffset:0;animation:1.6s ease-in-out 0s infinite normal none running unrealSpinnerDash}@keyframes unrealSpinnerRotate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes unrealSpinnerDash{0%{stroke-dasharray:1px,calc(var(--unrealSpinnerSize) * 5 * 1px);stroke-dashoffset:0}50%{stroke-dasharray:calc(var(--unrealSpinnerSize) * 2.5 * 1px),calc(var(--unrealSpinnerSize) * 5 * 1px);stroke-dashoffset:calc(var(--unrealSpinnerSize) * .4 * -1px)}to{stroke-dasharray:calc(var(--unrealSpinnerSize) * 2.5 * 1px),calc(var(--unrealSpinnerSize) * 5 * 1px);stroke-dashoffset:calc(var(--unrealSpinnerSize) * 3 * -1px)}}\n"] }]
8454
8553
  }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], strokeWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "strokeWidth", required: false }] }], strokeColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "strokeColor", required: false }] }], testID: [{ type: i0.Input, args: [{ isSignal: true, alias: "data-testid", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
@@ -8479,10 +8578,10 @@ class UnrealStatusComponent {
8479
8578
  }
8480
8579
  #store;
8481
8580
  #loadingProgress;
8482
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealStatusComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8483
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: UnrealStatusComponent, isStandalone: true, selector: "app-unreal-status", inputs: { uiClasses: { classPropertyName: "uiClasses", publicName: "uiClasses", isSignal: true, isRequired: false, transformFunction: null }, contentTemplate: { classPropertyName: "contentTemplate", publicName: "contentTemplate", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (isShowLoadingPercentsPopup()) {\n @let _awsInstance = awsInstance();\n <div [class]=\"cardSkin()\" class=\"status-anchor\">\n @if (contentTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: slotContext }\"\n />\n } @else if (_awsInstance?.message) {\n <p>{{ _awsInstance?.message }}</p>\n } @else {\n <div [class]=\"messageSkin()\">\n <app-unreal-spinner [size]=\"30\" [strokeColor]=\"'#1F2937'\" />\n {{ smoothPercents() }}%\n </div>\n }\n </div>\n}\n", styles: ["app-stat-graph{height:30px;width:100%}.status-anchor{position:absolute;top:80%;left:50%;transform:translate(-50%,-50%);z-index:5;pointer-events:none}.status-box{display:flex;justify-content:center;align-items:center;width:auto;max-width:500px;margin:0;background:var(--unreal-surface-card, var(--src-surface-container-main, #fff));border:none;border-radius:var(--unreal-radius-pill, var(--src-border-rounded-full, 9999px));box-shadow:0 8px 20px #1718181f,0 3px 6px #17181814}.status-anchor p{padding:10px 15px;margin:0;text-align:center}.status-box__message{display:flex;align-items:center;padding:12px 20px 12px 16px;color:var(--unreal-text-main, var(--src-text-body-main, #1f2937));font-size:16px;font-weight:400;line-height:24px}.status-box__message .status-box__message_text{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}.status-box__message app-unreal-spinner{margin-right:12px}\n"], dependencies: [{ kind: "component", type: UnrealSpinnerComponent, selector: "app-unreal-spinner", inputs: ["size", "strokeWidth", "strokeColor", "data-testid", "ariaLabel"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8581
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealStatusComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8582
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UnrealStatusComponent, isStandalone: true, selector: "app-unreal-status", inputs: { uiClasses: { classPropertyName: "uiClasses", publicName: "uiClasses", isSignal: true, isRequired: false, transformFunction: null }, contentTemplate: { classPropertyName: "contentTemplate", publicName: "contentTemplate", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (isShowLoadingPercentsPopup()) {\n @let _awsInstance = awsInstance();\n <div [class]=\"cardSkin()\" class=\"status-anchor\">\n @if (contentTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: slotContext }\"\n />\n } @else if (_awsInstance?.message) {\n <p>{{ _awsInstance?.message }}</p>\n } @else {\n <div [class]=\"messageSkin()\">\n <app-unreal-spinner [size]=\"30\" [strokeColor]=\"'#1F2937'\" />\n {{ smoothPercents() }}%\n </div>\n }\n </div>\n}\n", styles: ["app-stat-graph{height:30px;width:100%}.status-anchor{position:absolute;top:80%;left:50%;transform:translate(-50%,-50%);z-index:5;pointer-events:none}.status-box{display:flex;justify-content:center;align-items:center;width:auto;max-width:500px;margin:0;background:var(--unreal-surface-card, var(--src-surface-container-main, #fff));border:none;border-radius:var(--unreal-radius-pill, var(--src-border-rounded-full, 9999px));box-shadow:0 8px 20px #1718181f,0 3px 6px #17181814}.status-anchor p{padding:10px 15px;margin:0;text-align:center}.status-box__message{display:flex;align-items:center;padding:12px 20px 12px 16px;color:var(--unreal-text-main, var(--src-text-body-main, #1f2937));font-size:16px;font-weight:400;line-height:24px}.status-box__message .status-box__message_text{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}.status-box__message app-unreal-spinner{margin-right:12px}\n"], dependencies: [{ kind: "component", type: UnrealSpinnerComponent, selector: "app-unreal-spinner", inputs: ["size", "strokeWidth", "strokeColor", "data-testid", "ariaLabel"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8484
8583
  }
8485
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealStatusComponent, decorators: [{
8584
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealStatusComponent, decorators: [{
8486
8585
  type: Component,
8487
8586
  args: [{ selector: 'app-unreal-status', changeDetection: ChangeDetectionStrategy.OnPush, imports: [UnrealSpinnerComponent, NgTemplateOutlet], template: "@if (isShowLoadingPercentsPopup()) {\n @let _awsInstance = awsInstance();\n <div [class]=\"cardSkin()\" class=\"status-anchor\">\n @if (contentTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: slotContext }\"\n />\n } @else if (_awsInstance?.message) {\n <p>{{ _awsInstance?.message }}</p>\n } @else {\n <div [class]=\"messageSkin()\">\n <app-unreal-spinner [size]=\"30\" [strokeColor]=\"'#1F2937'\" />\n {{ smoothPercents() }}%\n </div>\n }\n </div>\n}\n", styles: ["app-stat-graph{height:30px;width:100%}.status-anchor{position:absolute;top:80%;left:50%;transform:translate(-50%,-50%);z-index:5;pointer-events:none}.status-box{display:flex;justify-content:center;align-items:center;width:auto;max-width:500px;margin:0;background:var(--unreal-surface-card, var(--src-surface-container-main, #fff));border:none;border-radius:var(--unreal-radius-pill, var(--src-border-rounded-full, 9999px));box-shadow:0 8px 20px #1718181f,0 3px 6px #17181814}.status-anchor p{padding:10px 15px;margin:0;text-align:center}.status-box__message{display:flex;align-items:center;padding:12px 20px 12px 16px;color:var(--unreal-text-main, var(--src-text-body-main, #1f2937));font-size:16px;font-weight:400;line-height:24px}.status-box__message .status-box__message_text{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}.status-box__message app-unreal-spinner{margin-right:12px}\n"] }]
8488
8587
  }], propDecorators: { uiClasses: [{ type: i0.Input, args: [{ isSignal: true, alias: "uiClasses", required: false }] }], contentTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentTemplate", required: false }] }] } });
@@ -8515,10 +8614,10 @@ class SafePipe {
8515
8614
  // content instead of disabling framework security checks.
8516
8615
  return (this.sanitizer.sanitize(context, value) ?? '');
8517
8616
  }
8518
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: SafePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
8519
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.4", ngImport: i0, type: SafePipe, isStandalone: true, name: "safe" }); }
8617
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SafePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
8618
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.7", ngImport: i0, type: SafePipe, isStandalone: true, name: "safe" }); }
8520
8619
  }
8521
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: SafePipe, decorators: [{
8620
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SafePipe, decorators: [{
8522
8621
  type: Pipe,
8523
8622
  args: [{
8524
8623
  name: 'safe',
@@ -8631,10 +8730,10 @@ class VideoStatsComponent {
8631
8730
  elements: this.elementsToShow(),
8632
8731
  }));
8633
8732
  }
8634
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: VideoStatsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8635
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: VideoStatsComponent, isStandalone: true, selector: "app-video-stats", ngImport: i0, template: "@if (videoStatus() && viewportReady()) {\n <div class=\"settings-container\">\n <button (click)=\"toggle()\" class=\"gear-button\">Stats</button>\n <div (click)=\"toggle()\" [class.min]=\"collapsed()\" id=\"aggregatedStats\">\n <div class=\"forNerds\">\n <div (click)=\"$event.stopPropagation()\" class=\"static\">\n <li>\n <app-stat-graph\n [stat]=\"fpsTick()!\"\n label=\"FPS (higher is better)\"\n />\n </li>\n <li>\n <app-stat-graph\n [stat]=\"videoQP()!\"\n label=\"QP (lower is better)\"\n color=\"#D5ff07\"\n />\n </li>\n <li>\n <app-stat-graph\n [stat]=\"bitrateTick()!\"\n label=\"Bitrate\"\n color=\"#D57F07\"\n />\n </li>\n </div>\n <div>\n @for (graph of graphList(); track graph.key) {\n <li (click)=\"toggleGraph($event, graph.key, 0)\" class=\"graph\">\n <app-stat-graph\n [label]=\"graph.key\"\n [stat]=\"graph.stat()\"\n [color]=\"graph.color\"\n />\n </li>\n }\n </div>\n </div>\n\n @for (el of videoStatus(); track el.key + $index) {\n <div (click)=\"toggleGraph($event, el.key, el.value)\" class=\"stat\">\n <span>{{ el.key }}: </span>{{ el.value | json }}\n </div>\n }\n </div>\n </div>\n @if (!collapsed()) {\n <div [innerHTML]=\"ssData() | safe: 'html'\" class=\"ssInfo\"></div>\n }\n}\n", styles: [".settings-container{position:absolute;top:65px;left:10px;z-index:1000;bottom:10px}.gear-button{left:0;width:50px;position:absolute;background:none;cursor:pointer;font-size:10px;font-weight:500;border:1px solid;border-radius:9px;background:#0162cc;color:#fff;padding:4px}.gear-button>*{color:#fff;filter:drop-shadow(1px 1px 1px rgb(0,0,0))}#aggregatedStats{max-height:calc(100% - 25px);overflow-y:auto;margin-top:25px;left:20px;z-index:31;max-width:400px;padding:10px;background-color:#fff3;border:1px solid grey}#aggregatedStats>*{color:#fff;text-shadow:-1px -1px 0 #000,1px -1px 0 #000,-1px 1px 0 #000,1px 1px 0 #000}#aggregatedStats:empty{display:none}#aggregatedStats button{position:absolute;right:5px;top:5px}#aggregatedStats.min{display:none}#aggregatedStats .forNerds{width:100%}#aggregatedStats .forNerds li{list-style-type:none;height:60px}#aggregatedStats .forNerds li app-stat-graph{display:block;width:100%;height:100%}#aggregatedStats .stat span{font-weight:700}#aggregatedStats .stat,#aggregatedStats .graph{cursor:pointer}#aggregatedStats .static{pointer-events:all}.ssInfo{position:absolute;top:0;left:50%;transform:translate(-50%);color:#fff;text-shadow:-1px -1px 0 #000,1px -1px 0 #000,-1px 1px 0 #000,1px 1px 0 #000;text-align:center;width:80%;pointer-events:none}\n"], dependencies: [{ kind: "component", type: StatGraphComponent, selector: "app-stat-graph", inputs: ["label", "stat", "color", "tickStep"] }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "pipe", type: SafePipe, name: "safe" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8733
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: VideoStatsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8734
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: VideoStatsComponent, isStandalone: true, selector: "app-video-stats", ngImport: i0, template: "@if (videoStatus() && viewportReady()) {\n <div class=\"settings-container\">\n <button (click)=\"toggle()\" class=\"gear-button\">Stats</button>\n <div (click)=\"toggle()\" [class.min]=\"collapsed()\" id=\"aggregatedStats\">\n <div class=\"forNerds\">\n <div (click)=\"$event.stopPropagation()\" class=\"static\">\n <li>\n <app-stat-graph\n [stat]=\"fpsTick()!\"\n label=\"FPS (higher is better)\"\n />\n </li>\n <li>\n <app-stat-graph\n [stat]=\"videoQP()!\"\n label=\"QP (lower is better)\"\n color=\"#D5ff07\"\n />\n </li>\n <li>\n <app-stat-graph\n [stat]=\"bitrateTick()!\"\n label=\"Bitrate\"\n color=\"#D57F07\"\n />\n </li>\n </div>\n <div>\n @for (graph of graphList(); track graph.key) {\n <li (click)=\"toggleGraph($event, graph.key, 0)\" class=\"graph\">\n <app-stat-graph\n [label]=\"graph.key\"\n [stat]=\"graph.stat()\"\n [color]=\"graph.color\"\n />\n </li>\n }\n </div>\n </div>\n\n @for (el of videoStatus(); track el.key + $index) {\n <div (click)=\"toggleGraph($event, el.key, el.value)\" class=\"stat\">\n <span>{{ el.key }}: </span>{{ el.value | json }}\n </div>\n }\n </div>\n </div>\n @if (!collapsed()) {\n <div [innerHTML]=\"ssData() | safe: 'html'\" class=\"ssInfo\"></div>\n }\n}\n", styles: [".settings-container{position:absolute;top:65px;left:10px;z-index:1000;bottom:10px}.gear-button{left:0;width:50px;position:absolute;background:none;cursor:pointer;font-size:10px;font-weight:500;border:1px solid;border-radius:9px;background:#0162cc;color:#fff;padding:4px}.gear-button>*{color:#fff;filter:drop-shadow(1px 1px 1px rgb(0,0,0))}#aggregatedStats{max-height:calc(100% - 25px);overflow-y:auto;margin-top:25px;left:20px;z-index:31;max-width:400px;padding:10px;background-color:#fff3;border:1px solid grey}#aggregatedStats>*{color:#fff;text-shadow:-1px -1px 0 #000,1px -1px 0 #000,-1px 1px 0 #000,1px 1px 0 #000}#aggregatedStats:empty{display:none}#aggregatedStats button{position:absolute;right:5px;top:5px}#aggregatedStats.min{display:none}#aggregatedStats .forNerds{width:100%}#aggregatedStats .forNerds li{list-style-type:none;height:60px}#aggregatedStats .forNerds li app-stat-graph{display:block;width:100%;height:100%}#aggregatedStats .stat span{font-weight:700}#aggregatedStats .stat,#aggregatedStats .graph{cursor:pointer}#aggregatedStats .static{pointer-events:all}.ssInfo{position:absolute;top:0;left:50%;transform:translate(-50%);color:#fff;text-shadow:-1px -1px 0 #000,1px -1px 0 #000,-1px 1px 0 #000,1px 1px 0 #000;text-align:center;width:80%;pointer-events:none}\n"], dependencies: [{ kind: "component", type: StatGraphComponent, selector: "app-stat-graph", inputs: ["label", "stat", "color", "tickStep"] }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "pipe", type: SafePipe, name: "safe" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8636
8735
  }
8637
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: VideoStatsComponent, decorators: [{
8736
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: VideoStatsComponent, decorators: [{
8638
8737
  type: Component,
8639
8738
  args: [{ selector: 'app-video-stats', changeDetection: ChangeDetectionStrategy.OnPush, imports: [StatGraphComponent, JsonPipe, SafePipe], template: "@if (videoStatus() && viewportReady()) {\n <div class=\"settings-container\">\n <button (click)=\"toggle()\" class=\"gear-button\">Stats</button>\n <div (click)=\"toggle()\" [class.min]=\"collapsed()\" id=\"aggregatedStats\">\n <div class=\"forNerds\">\n <div (click)=\"$event.stopPropagation()\" class=\"static\">\n <li>\n <app-stat-graph\n [stat]=\"fpsTick()!\"\n label=\"FPS (higher is better)\"\n />\n </li>\n <li>\n <app-stat-graph\n [stat]=\"videoQP()!\"\n label=\"QP (lower is better)\"\n color=\"#D5ff07\"\n />\n </li>\n <li>\n <app-stat-graph\n [stat]=\"bitrateTick()!\"\n label=\"Bitrate\"\n color=\"#D57F07\"\n />\n </li>\n </div>\n <div>\n @for (graph of graphList(); track graph.key) {\n <li (click)=\"toggleGraph($event, graph.key, 0)\" class=\"graph\">\n <app-stat-graph\n [label]=\"graph.key\"\n [stat]=\"graph.stat()\"\n [color]=\"graph.color\"\n />\n </li>\n }\n </div>\n </div>\n\n @for (el of videoStatus(); track el.key + $index) {\n <div (click)=\"toggleGraph($event, el.key, el.value)\" class=\"stat\">\n <span>{{ el.key }}: </span>{{ el.value | json }}\n </div>\n }\n </div>\n </div>\n @if (!collapsed()) {\n <div [innerHTML]=\"ssData() | safe: 'html'\" class=\"ssInfo\"></div>\n }\n}\n", styles: [".settings-container{position:absolute;top:65px;left:10px;z-index:1000;bottom:10px}.gear-button{left:0;width:50px;position:absolute;background:none;cursor:pointer;font-size:10px;font-weight:500;border:1px solid;border-radius:9px;background:#0162cc;color:#fff;padding:4px}.gear-button>*{color:#fff;filter:drop-shadow(1px 1px 1px rgb(0,0,0))}#aggregatedStats{max-height:calc(100% - 25px);overflow-y:auto;margin-top:25px;left:20px;z-index:31;max-width:400px;padding:10px;background-color:#fff3;border:1px solid grey}#aggregatedStats>*{color:#fff;text-shadow:-1px -1px 0 #000,1px -1px 0 #000,-1px 1px 0 #000,1px 1px 0 #000}#aggregatedStats:empty{display:none}#aggregatedStats button{position:absolute;right:5px;top:5px}#aggregatedStats.min{display:none}#aggregatedStats .forNerds{width:100%}#aggregatedStats .forNerds li{list-style-type:none;height:60px}#aggregatedStats .forNerds li app-stat-graph{display:block;width:100%;height:100%}#aggregatedStats .stat span{font-weight:700}#aggregatedStats .stat,#aggregatedStats .graph{cursor:pointer}#aggregatedStats .static{pointer-events:all}.ssInfo{position:absolute;top:0;left:50%;transform:translate(-50%);color:#fff;text-shadow:-1px -1px 0 #000,1px -1px 0 #000,-1px 1px 0 #000,1px 1px 0 #000;text-align:center;width:80%;pointer-events:none}\n"] }]
8640
8739
  }], ctorParameters: () => [] });
@@ -8696,10 +8795,10 @@ class ResumeStreamButtonComponent {
8696
8795
  disconnect() {
8697
8796
  this.isSecondStart.set(true);
8698
8797
  }
8699
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ResumeStreamButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8700
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: ResumeStreamButtonComponent, isStandalone: true, selector: "app-resume-stream-button", inputs: { uiClasses: { classPropertyName: "uiClasses", publicName: "uiClasses", isSignal: true, isRequired: false, transformFunction: null }, contentTemplate: { classPropertyName: "contentTemplate", publicName: "contentTemplate", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (isShowResumeButton()) {\n <div [class]=\"cardSkin()\" class=\"resume-anchor\">\n @if (contentTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: slotContext }\"\n />\n } @else {\n @if (isSecondStart()) {\n <div [class]=\"textSkin()\">\n Your stream {{ isAfkDisconnect() ? 'has been' : 'is' }} paused due to\n inactivity\n </div>\n }\n\n <app-unreal-button\n (clicked)=\"connect()\"\n [fullWidth]=\"true\"\n [data-testid]=\"'connect-button'\"\n [class]=\"buttonSkin()\"\n size=\"lg\"\n weight=\"primary\"\n >\n {{ isSecondStart() ? 'Resume' : 'Start' }}\n </app-unreal-button>\n }\n </div>\n}\n", styles: [".resume-anchor{position:absolute;bottom:0;left:50%;transform:translate(-50%,-50%);z-index:6}.resume-box{padding:16px;gap:12px;display:flex;flex-direction:column;align-items:center;border-radius:var(--unreal-radius-card, var(--src-border-rounded-parent, 8px));background:var(--unreal-surface-card, var(--src-surface-container-main, #fff));box-shadow:var(--unreal-shadow-card, 0 26px 80px 0 rgba(0, 0, 0, .2), 0 0 1px 0 rgba(0, 0, 0, .2))}.connect-button{width:100%}.resume-box__text{color:var(--unreal-text-secondary, var(--src-color-grey-500, #6b7280));text-align:center;font-family:var(--unreal-font-family, var(--src-font-family-body, system-ui, sans-serif));font-size:14px;font-style:normal;font-weight:400;line-height:24px}\n"], dependencies: [{ kind: "component", type: UnrealButtonComponent, selector: "app-unreal-button", inputs: ["type", "weight", "size", "fullWidth", "isDisabled", "data-testid", "ariaLabel"], outputs: ["clicked"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8798
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: ResumeStreamButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8799
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: ResumeStreamButtonComponent, isStandalone: true, selector: "app-resume-stream-button", inputs: { uiClasses: { classPropertyName: "uiClasses", publicName: "uiClasses", isSignal: true, isRequired: false, transformFunction: null }, contentTemplate: { classPropertyName: "contentTemplate", publicName: "contentTemplate", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (isShowResumeButton()) {\n <div [class]=\"cardSkin()\" class=\"resume-anchor\">\n @if (contentTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: slotContext }\"\n />\n } @else {\n @if (isSecondStart()) {\n <div [class]=\"textSkin()\">\n Your stream {{ isAfkDisconnect() ? 'has been' : 'is' }} paused due to\n inactivity\n </div>\n }\n\n <app-unreal-button\n (clicked)=\"connect()\"\n [fullWidth]=\"true\"\n [data-testid]=\"'connect-button'\"\n [class]=\"buttonSkin()\"\n size=\"lg\"\n weight=\"primary\"\n >\n {{ isSecondStart() ? 'Resume' : 'Start' }}\n </app-unreal-button>\n }\n </div>\n}\n", styles: [".resume-anchor{position:absolute;bottom:0;left:50%;transform:translate(-50%,-50%);z-index:6}.resume-box{padding:16px;gap:12px;display:flex;flex-direction:column;align-items:center;border-radius:var(--unreal-radius-card, var(--src-border-rounded-parent, 8px));background:var(--unreal-surface-card, var(--src-surface-container-main, #fff));box-shadow:var(--unreal-shadow-card, 0 26px 80px 0 rgba(0, 0, 0, .2), 0 0 1px 0 rgba(0, 0, 0, .2))}.connect-button{width:100%}.resume-box__text{color:var(--unreal-text-secondary, var(--src-color-grey-500, #6b7280));text-align:center;font-family:var(--unreal-font-family, var(--src-font-family-body, system-ui, sans-serif));font-size:14px;font-style:normal;font-weight:400;line-height:24px}\n"], dependencies: [{ kind: "component", type: UnrealButtonComponent, selector: "app-unreal-button", inputs: ["type", "weight", "size", "fullWidth", "isDisabled", "data-testid", "ariaLabel"], outputs: ["clicked"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8701
8800
  }
8702
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ResumeStreamButtonComponent, decorators: [{
8801
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: ResumeStreamButtonComponent, decorators: [{
8703
8802
  type: Component,
8704
8803
  args: [{ selector: 'app-resume-stream-button', changeDetection: ChangeDetectionStrategy.OnPush, imports: [UnrealButtonComponent, NgTemplateOutlet], template: "@if (isShowResumeButton()) {\n <div [class]=\"cardSkin()\" class=\"resume-anchor\">\n @if (contentTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: slotContext }\"\n />\n } @else {\n @if (isSecondStart()) {\n <div [class]=\"textSkin()\">\n Your stream {{ isAfkDisconnect() ? 'has been' : 'is' }} paused due to\n inactivity\n </div>\n }\n\n <app-unreal-button\n (clicked)=\"connect()\"\n [fullWidth]=\"true\"\n [data-testid]=\"'connect-button'\"\n [class]=\"buttonSkin()\"\n size=\"lg\"\n weight=\"primary\"\n >\n {{ isSecondStart() ? 'Resume' : 'Start' }}\n </app-unreal-button>\n }\n </div>\n}\n", styles: [".resume-anchor{position:absolute;bottom:0;left:50%;transform:translate(-50%,-50%);z-index:6}.resume-box{padding:16px;gap:12px;display:flex;flex-direction:column;align-items:center;border-radius:var(--unreal-radius-card, var(--src-border-rounded-parent, 8px));background:var(--unreal-surface-card, var(--src-surface-container-main, #fff));box-shadow:var(--unreal-shadow-card, 0 26px 80px 0 rgba(0, 0, 0, .2), 0 0 1px 0 rgba(0, 0, 0, .2))}.connect-button{width:100%}.resume-box__text{color:var(--unreal-text-secondary, var(--src-color-grey-500, #6b7280));text-align:center;font-family:var(--unreal-font-family, var(--src-font-family-body, system-ui, sans-serif));font-size:14px;font-style:normal;font-weight:400;line-height:24px}\n"] }]
8705
8804
  }], ctorParameters: () => [], propDecorators: { uiClasses: [{ type: i0.Input, args: [{ isSignal: true, alias: "uiClasses", required: false }] }], contentTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentTemplate", required: false }] }] } });
@@ -8766,21 +8865,38 @@ class IntroSrcComponent {
8766
8865
  sourceElement.addEventListener('error', () => this.#store.dispatch(resetIntroSrc()));
8767
8866
  videoContainer.appendChild(videoElement);
8768
8867
  }
8769
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: IntroSrcComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8770
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: IntroSrcComponent, isStandalone: true, selector: "app-intro-src", viewQueries: [{ propertyName: "videoElement", first: true, predicate: ["videoPlayerCover"], descendants: true, isSignal: true }], ngImport: i0, template: "@let image = imageIntroSrc();\n@if (image) {\n <div class=\"backImage\">\n <img (error)=\"loadingImageError()\" [ngSrc]=\"image\" fill alt=\"imageSrc\" />\n </div>\n} @else if (videoIntroSrc()) {\n <div #videoPlayerCover class=\"backVideo\"></div>\n}\n", styles: [".backVideo{position:absolute;top:0;left:0;display:flex;justify-content:center;align-items:center;width:100%;height:100%;z-index:1}.backVideo video{position:absolute;width:100%;height:100%;object-fit:cover}.backImage{position:absolute;top:0;left:0;display:flex;justify-content:center;align-items:center;width:100%;height:100%;z-index:1}.backImage img{position:absolute;width:100%;height:100%;object-fit:cover}\n"], dependencies: [{ kind: "directive", type: NgOptimizedImage, selector: "img[ngSrc]", inputs: ["ngSrc", "ngSrcset", "sizes", "width", "height", "decoding", "loading", "priority", "loaderParams", "disableOptimizedSrcset", "fill", "placeholder", "placeholderConfig", "src", "srcset"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8868
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: IntroSrcComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8869
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: IntroSrcComponent, isStandalone: true, selector: "app-intro-src", viewQueries: [{ propertyName: "videoElement", first: true, predicate: ["videoPlayerCover"], descendants: true, isSignal: true }], ngImport: i0, template: "@let image = imageIntroSrc();\n@if (image) {\n <div class=\"backImage\">\n <img (error)=\"loadingImageError()\" [ngSrc]=\"image\" fill alt=\"imageSrc\" />\n </div>\n} @else if (videoIntroSrc()) {\n <div #videoPlayerCover class=\"backVideo\"></div>\n}\n", styles: [".backVideo{position:absolute;top:0;left:0;display:flex;justify-content:center;align-items:center;width:100%;height:100%;z-index:1}.backVideo video{position:absolute;width:100%;height:100%;object-fit:cover}.backImage{position:absolute;top:0;left:0;display:flex;justify-content:center;align-items:center;width:100%;height:100%;z-index:1}.backImage img{position:absolute;width:100%;height:100%;object-fit:cover}\n"], dependencies: [{ kind: "directive", type: NgOptimizedImage, selector: "img[ngSrc]", inputs: ["ngSrc", "ngSrcset", "sizes", "width", "height", "decoding", "loading", "priority", "loaderParams", "disableOptimizedSrcset", "fill", "placeholder", "placeholderConfig", "src", "srcset"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8771
8870
  }
8772
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: IntroSrcComponent, decorators: [{
8871
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: IntroSrcComponent, decorators: [{
8773
8872
  type: Component,
8774
8873
  args: [{ selector: 'app-intro-src', imports: [NgOptimizedImage], changeDetection: ChangeDetectionStrategy.OnPush, template: "@let image = imageIntroSrc();\n@if (image) {\n <div class=\"backImage\">\n <img (error)=\"loadingImageError()\" [ngSrc]=\"image\" fill alt=\"imageSrc\" />\n </div>\n} @else if (videoIntroSrc()) {\n <div #videoPlayerCover class=\"backVideo\"></div>\n}\n", styles: [".backVideo{position:absolute;top:0;left:0;display:flex;justify-content:center;align-items:center;width:100%;height:100%;z-index:1}.backVideo video{position:absolute;width:100%;height:100%;object-fit:cover}.backImage{position:absolute;top:0;left:0;display:flex;justify-content:center;align-items:center;width:100%;height:100%;z-index:1}.backImage img{position:absolute;width:100%;height:100%;object-fit:cover}\n"] }]
8775
8874
  }], ctorParameters: () => [], propDecorators: { videoElement: [{ type: i0.ViewChild, args: ['videoPlayerCover', { isSignal: true }] }] } });
8776
8875
 
8777
8876
  class UnrealSceneComponent {
8778
8877
  #store;
8878
+ /**
8879
+ * Stream geometry for the current container, or `null` while the container
8880
+ * has no layout yet (0 px in either dimension). A zero container used to be
8881
+ * substituted with a 2 px stub and shipped to Unreal as 2×2·devicePixelRatio;
8882
+ * now nothing is sent until layout settles.
8883
+ */
8779
8884
  get resizeValues() {
8885
+ const container = this.containerSize;
8886
+ if (!container) {
8887
+ return null;
8888
+ }
8780
8889
  if (this.isStudio()) {
8781
- return this.getResizeStudioValues();
8890
+ return this.getResizeStudioValues(container);
8782
8891
  }
8783
- return this.getResizeValuesUniversal();
8892
+ return this.getResizeValuesUniversal(container);
8893
+ }
8894
+ get containerSize() {
8895
+ const element = this.videoElement()?.nativeElement;
8896
+ const fromContainer = this.isStudio() || this.useContainerAsSizeProvider();
8897
+ const w = fromContainer ? (element?.offsetWidth ?? 0) : window.innerWidth;
8898
+ const h = fromContainer ? (element?.offsetHeight ?? 0) : window.innerHeight;
8899
+ return w > 0 && h > 0 ? { w, h } : null;
8784
8900
  }
8785
8901
  get pixelRatio() {
8786
8902
  return window.devicePixelRatio;
@@ -8831,6 +8947,7 @@ class UnrealSceneComponent {
8831
8947
  this.destroyRef = inject(DestroyRef);
8832
8948
  this.unrealConfig = inject(UNREAL_CONFIG);
8833
8949
  this.autoHighResolution = false;
8950
+ this.lastSentResolution = null;
8834
8951
  this.destroyRef.onDestroy(() => {
8835
8952
  // Release the remote connection synchronously, independent of the
8836
8953
  // route-scoped UnrealEffects. provideUnrealModule (effects) is registered
@@ -8875,7 +8992,7 @@ class UnrealSceneComponent {
8875
8992
  const videoElement = this.videoElement();
8876
8993
  if (videoElement) {
8877
8994
  this.videoService.setContainer(videoElement.nativeElement);
8878
- this.listenResizeValues();
8995
+ this.listenResizeValues(videoElement.nativeElement);
8879
8996
  this.listenInteractivityForAutoHighResolution(videoElement.nativeElement);
8880
8997
  }
8881
8998
  },
@@ -8905,48 +9022,71 @@ class UnrealSceneComponent {
8905
9022
  this.#store.dispatch(forceResizeViewport());
8906
9023
  });
8907
9024
  }
8908
- listenResizeValues() {
9025
+ listenResizeValues(container) {
8909
9026
  const customSizeInputChanged$ = this.resolutionValues$.pipe(filter(({ width, height }) => this.width !== width || this.height !== height), tap(({ width, height }) => {
8910
9027
  this.width = width;
8911
9028
  this.height = height;
8912
9029
  }));
8913
- const resizeRequired$ = merge(this.actions$.pipe(ofType(videoStreamInitialized)), fromEvent(window, 'resize'));
9030
+ // The container observer is what ends the "not laid out yet" wait: a
9031
+ // 0×0 container is skipped below, and this fires once it gets a size.
9032
+ const resizeRequired$ = merge(this.actions$.pipe(ofType(videoStreamInitialized)), fromEvent(window, 'resize'), fromResizeObserver(container));
8914
9033
  const videoStreamSizeChanged$ = this.videoService.videoStats$.pipe(filter(() => !this.isFreezeFrameLoading()), map((stats) => ({
8915
9034
  w: stats.aggregatedStats.frameWidth || 0,
8916
9035
  h: stats.aggregatedStats.frameHeight || 0,
8917
9036
  })), distinctUntilChanged((previous, current) => fpIsASameAsB(previous.w, current.w, SAME_SIZE_THRESHOLD) &&
8918
9037
  fpIsASameAsB(previous.h, current.h, SAME_SIZE_THRESHOLD)));
8919
- merge(customSizeInputChanged$, resizeRequired$, videoStreamSizeChanged$)
8920
- .pipe(debounceTime(DEBOUNCE_TO_MANY_RESIZE_CALLS), switchMap(() => {
9038
+ const layoutSettled$ = merge(customSizeInputChanged$, resizeRequired$, videoStreamSizeChanged$).pipe(debounceTime(DEBOUNCE_TO_MANY_RESIZE_CALLS), switchMap(() => {
8921
9039
  const key = Math.random();
8922
9040
  // Poll 3 times to capture late-arriving DOM measurements after layout settles
8923
9041
  return timer(0, 300).pipe(take(3), map(() => key));
8924
- }), map((key) => ({ key, ...this.resizeValues })), distinctUntilChanged((previous, current) => fpIsASameAsB(previous.w, current.w, SAME_SIZE_THRESHOLD) &&
8925
- fpIsASameAsB(previous.h, current.h, SAME_SIZE_THRESHOLD) &&
8926
- previous.key === current.key), tap((size) => this.adaptVideo(size)),
8927
- // Key excluded: only dispatch when actual pixel dimensions change
8928
- distinctUntilChanged((previous, current) => fpIsASameAsB(previous.w, current.w, SAME_SIZE_THRESHOLD) &&
8929
- fpIsASameAsB(previous.h, current.h, SAME_SIZE_THRESHOLD)),
8930
- // Holds dispatch until data channel is up; retains true after disconnect
8931
- // so resizes still reach Unreal — cleanup is handled by destroyUnrealScene
8932
- combineLatestWith(this.#store
8933
- .select(unrealFeature.selectDataChannelConnected)
8934
- .pipe(filter(Truthy))), takeUntilDestroyed(this.destroyRef))
8935
- .subscribe(([size]) => {
8936
- this.#store.dispatch(changeStreamResolutionAction({ width: size.w, height: size.h }));
8937
- this.sendResize(size);
8938
- });
9042
+ }), map((key) => {
9043
+ const area = this.resizeValues;
9044
+ return area && { key, area };
9045
+ }),
9046
+ // Container not laid out yet — wait for the next trigger instead of
9047
+ // sending a degenerate size.
9048
+ filter(Truthy), distinctUntilChanged((previous, current) => fpIsASameAsB(previous.area.w, current.area.w, SAME_SIZE_THRESHOLD) &&
9049
+ fpIsASameAsB(previous.area.h, current.area.h, SAME_SIZE_THRESHOLD) &&
9050
+ previous.key === current.key), tap(({ area }) => this.adaptVideo(area)));
9051
+ layoutSettled$
9052
+ .pipe(
9053
+ // The video element keeps the true geometry; only the size that leaves
9054
+ // for the encoder is clamped.
9055
+ map(({ area }) => clampStreamResolution(area)),
9056
+ // Holds dispatch until data channel is up. A drop re-arms the send so
9057
+ // the same size reaches Unreal again on reconnect; the
9058
+ // `dataChannelConnected` flag itself stays true after a plain
9059
+ // disconnect — cleanup is handled by destroyUnrealScene.
9060
+ combineLatestWith(this.#store.select(unrealFeature.selectDataChannelConnected).pipe(distinctUntilChanged(), tap((connected) => {
9061
+ if (!connected) {
9062
+ this.lastSentResolution = null;
9063
+ }
9064
+ }), filter(Truthy))), takeUntilDestroyed(this.destroyRef))
9065
+ .subscribe(([size]) => this.applyResolution(size));
8939
9066
  this.actions$
8940
- .pipe(ofType(forceResizeViewport), takeUntilDestroyed(this.destroyRef))
8941
- .subscribe(() => this.sendResize(this.resizeValues));
9067
+ .pipe(ofType(forceResizeViewport), map(() => this.resizeValues), filter(Truthy), takeUntilDestroyed(this.destroyRef))
9068
+ .subscribe((area) => this.sendResize(clampStreamResolution(area)));
9069
+ }
9070
+ /**
9071
+ * Dedupes on what actually left the player, not on what was computed: a
9072
+ * size that `sendResize` could not deliver (no <video> yet — the prefetch
9073
+ * adoption path opens the data channel before the element exists) is
9074
+ * retried on the next layout tick instead of being swallowed.
9075
+ */
9076
+ applyResolution(size) {
9077
+ const last = this.lastSentResolution;
9078
+ if (last && last.w === size.w && last.h === size.h) {
9079
+ return;
9080
+ }
9081
+ this.#store.dispatch(changeStreamResolutionAction({ width: size.w, height: size.h }));
9082
+ this.sendResize(size);
8942
9083
  }
8943
- adaptVideo(size) {
9084
+ adaptVideo(area) {
8944
9085
  const video = this.videoService.video;
8945
- const areaSize = this.resizeValues;
8946
9086
  if (video?.style) {
8947
9087
  const pR = this.pixelRatio;
8948
- video.width = makeEven(size.w / pR / areaSize.scale);
8949
- video.height = makeEven(size.h / pR / areaSize.scale);
9088
+ video.width = makeEven(area.w / pR / area.scale);
9089
+ video.height = makeEven(area.h / pR / area.scale);
8950
9090
  if (!this.isStudio()) {
8951
9091
  video.style.overflow = 'hidden';
8952
9092
  video.style.objectFit = 'cover';
@@ -8956,29 +9096,19 @@ class UnrealSceneComponent {
8956
9096
  }
8957
9097
  this.#store.dispatch(videoAdaptedToContainer());
8958
9098
  }
8959
- getResizeValuesUniversal() {
8960
- let containerWidth = window.innerWidth || MIN_CONTAINER_SIZE;
8961
- let containerHeight = window.innerHeight || MIN_CONTAINER_SIZE;
8962
- if (this.useContainerAsSizeProvider()) {
8963
- containerWidth =
8964
- this.videoElement()?.nativeElement.offsetWidth || MIN_CONTAINER_SIZE;
8965
- containerHeight =
8966
- this.videoElement()?.nativeElement.offsetHeight || MIN_CONTAINER_SIZE;
8967
- }
8968
- const pixelRatio = this.pixelRatio;
9099
+ getResizeValuesUniversal(container) {
8969
9100
  return getResizeValuesUniversal({
8970
- pixelRatio,
8971
- containerWidth,
8972
- containerHeight,
9101
+ pixelRatio: this.pixelRatio,
9102
+ containerWidth: container.w,
9103
+ containerHeight: container.h,
8973
9104
  maxResolution: this.maxResolution || this.autoHighResolution,
8974
9105
  });
8975
9106
  }
8976
- getResizeStudioValues() {
8977
- const videoElement = this.videoElement()?.nativeElement;
9107
+ getResizeStudioValues(container) {
8978
9108
  return getResizeStudioValues({
8979
9109
  pixelRatio: this.pixelRatio,
8980
- containerWidth: videoElement?.offsetWidth || MIN_CONTAINER_SIZE,
8981
- containerHeight: videoElement?.offsetHeight || MIN_CONTAINER_SIZE,
9110
+ containerWidth: container.w,
9111
+ containerHeight: container.h,
8982
9112
  studioWidth: this.width,
8983
9113
  studioHeight: this.height,
8984
9114
  maxResolution: this.maxResolution || this.autoHighResolution,
@@ -8990,6 +9120,7 @@ class UnrealSceneComponent {
8990
9120
  if (!video || !isMetaboxMode(this.unrealConfig)) {
8991
9121
  return;
8992
9122
  }
9123
+ this.lastSentResolution = size;
8993
9124
  this.commandsSender.sendCommandToUnreal({
8994
9125
  command: MetaBoxCommand.FChangeResolutionCommand,
8995
9126
  payload: {
@@ -9000,10 +9131,10 @@ class UnrealSceneComponent {
9000
9131
  },
9001
9132
  });
9002
9133
  }
9003
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealSceneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9004
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: UnrealSceneComponent, isStandalone: true, selector: "app-unreal-scene", inputs: { useContainerAsSizeProvider: { classPropertyName: "useContainerAsSizeProvider", publicName: "useContainerAsSizeProvider", isSignal: true, isRequired: false, transformFunction: null }, isStudio: { classPropertyName: "isStudio", publicName: "isStudio", isSignal: true, isRequired: false, transformFunction: null }, resolutionSize: { classPropertyName: "resolutionSize", publicName: "resolutionSize", isSignal: true, isRequired: false, transformFunction: null }, uiClasses: { classPropertyName: "uiClasses", publicName: "uiClasses", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { changeMouseOverScene: "changeMouseOverScene" }, host: { listeners: { "mouseover": "onMouseOver()", "mouseout": "onMouseOut()", "contextmenu": "onContextMenu($event)" } }, queries: [{ propertyName: "resumeSlot", first: true, predicate: UnrealResumeSlotDirective, descendants: true, isSignal: true }, { propertyName: "afkSlot", first: true, predicate: UnrealAfkSlotDirective, descendants: true, isSignal: true }, { propertyName: "statusSlot", first: true, predicate: UnrealStatusSlotDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "videoElement", first: true, predicate: ["videoContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"frame unreal-container\">\n <div #videoContainer id=\"player\"></div>\n\n <app-intro-src />\n <app-image-loading-src />\n <app-freeze-frame />\n <app-resume-stream-button\n [uiClasses]=\"uiClasses()\"\n [contentTemplate]=\"resumeSlot()?.template ?? null\"\n />\n <app-unreal-status\n [uiClasses]=\"uiClasses()\"\n [contentTemplate]=\"statusSlot()?.template ?? null\"\n />\n <app-afk-timeout-modal\n [uiClasses]=\"uiClasses()\"\n [contentTemplate]=\"afkSlot()?.template ?? null\"\n />\n\n <ng-content select=\"app-pdf\"></ng-content>\n <ng-content select=\"app-show-case\"></ng-content>\n\n @if (isDevMode) {\n <app-video-stats />\n }\n</div>\n", styles: [".unreal-container{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#fff}.unreal-container #player{position:absolute;width:100%;height:100%;display:flex;justify-content:center;align-items:center;overflow:hidden}.unreal-container.select{cursor:url('data:image/svg+xml,<svg width=\"24\" height=\"24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M15.15 21.375a1.423 1.423 0 0 1-1.15.063 1.487 1.487 0 0 1-.85-.788l-3-6.45-2.325 3.25c-.283.4-.658.525-1.125.375-.467-.15-.7-.466-.7-.95V4.05c0-.417.188-.717.563-.9.375-.183.729-.142 1.062.125l10.1 7.95c.383.284.496.65.337 1.1-.158.45-.479.675-.962.675h-4.2l2.975 6.375c.183.384.204.767.063 1.15a1.487 1.487 0 0 1-.788.85Z\" fill=\"%23000\"/><path d=\"m12.697 20.861.002.005c.237.495.617.852 1.128 1.04.515.191 1.039.16 1.539-.08a1.987 1.987 0 0 0 1.04-1.128 1.922 1.922 0 0 0-.079-1.536v-.003L13.684 13.5H17.1c.32 0 .628-.075.89-.26.263-.184.438-.447.544-.749.106-.3.135-.617.04-.925a1.458 1.458 0 0 0-.545-.738L7.936 2.883a1.51 1.51 0 0 0-.768-.336 1.471 1.471 0 0 0-.825.154 1.495 1.495 0 0 0-.626.547 1.492 1.492 0 0 0-.217.802v12.825c0 .324.08.634.272.897.193.261.467.43.775.53.31.099.632.12.942.016.31-.103.555-.313.743-.578h.001l1.825-2.552 2.639 5.673Z\" stroke=\"%23fff\" stroke-opacity=\".7\"/></svg>') 6 2,auto}.unreal-container.orbit{cursor:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\"><path fill=\"%23000\" d=\"M11.998 21.6c-1.966 0-3.737-.53-5.312-1.588-1.575-1.058-2.738-2.437-3.488-4.137a.852.852 0 0 1 .013-.713.867.867 0 0 1 .512-.487.86.86 0 0 1 .688.037c.225.109.387.28.487.513.617 1.35 1.559 2.45 2.825 3.3 1.267.85 2.692 1.275 4.275 1.275 1.384 0 2.646-.33 3.788-.988a7.985 7.985 0 0 0 2.762-2.612h-.85a.873.873 0 0 1-.64-.257.863.863 0 0 1-.26-.638.88.88 0 0 1 .26-.643.864.864 0 0 1 .64-.262h3c.255 0 .47.086.642.259a.87.87 0 0 1 .258.64v3a.874.874 0 0 1-.257.642.863.863 0 0 1-.637.259.88.88 0 0 1-.643-.259.865.865 0 0 1-.263-.641v-.725a9.95 9.95 0 0 1-3.35 2.925c-1.35.733-2.833 1.1-4.45 1.1Zm0-17.4c-1.383 0-2.645.33-3.787.987A7.985 7.985 0 0 0 5.448 7.8h.85c.255 0 .47.086.642.257a.863.863 0 0 1 .258.638.88.88 0 0 1-.258.642.864.864 0 0 1-.642.263h-3a.87.87 0 0 1-.64-.259.87.87 0 0 1-.26-.641v-3c0-.255.086-.469.258-.641a.863.863 0 0 1 .637-.26.88.88 0 0 1 .643.26.864.864 0 0 1 .262.64v.726A9.95 9.95 0 0 1 7.548 3.5c1.35-.733 2.834-1.1 4.45-1.1 2 0 3.788.542 5.363 1.625 1.575 1.083 2.736 2.49 3.482 4.22a.724.724 0 0 1-.045.646.926.926 0 0 1-.525.437.87.87 0 0 1-.687-.04.977.977 0 0 1-.488-.513c-.616-1.35-1.558-2.45-2.825-3.3-1.266-.85-2.691-1.275-4.275-1.275Zm0 10.8a2.893 2.893 0 0 1-2.125-.875A2.893 2.893 0 0 1 8.998 12c0-.833.292-1.542.875-2.125A2.893 2.893 0 0 1 11.998 9c.834 0 1.542.292 2.125.875.584.583.875 1.292.875 2.125s-.291 1.542-.875 2.125a2.893 2.893 0 0 1-2.125.875Z\"/><path stroke=\"%23fff\" stroke-opacity=\".7\" d=\"m2.739 16.072.002.005c.789 1.788 2.014 3.24 3.666 4.35 1.66 1.116 3.53 1.673 5.591 1.673 1.696 0 3.262-.386 4.69-1.16a10.54 10.54 0 0 0 2.714-2.097c.069.167.171.32.308.454.272.268.613.403.994.403.38 0 .722-.135.992-.406s.402-.614.402-.994v-3c0-.381-.134-.724-.405-.995a1.37 1.37 0 0 0-.995-.405h-3c-.383 0-.727.137-.997.411a1.38 1.38 0 0 0-.403.994c0 .38.135.723.407.992.238.237.532.369.858.397a7.552 7.552 0 0 1-2.027 1.685c-1.062.613-2.237.92-3.538.92-1.488 0-2.815-.397-3.996-1.19-1.19-.798-2.07-1.826-2.647-3.087-.147-.34-.393-.6-.727-.76a1.36 1.36 0 0 0-1.073-.058c-.37.133-.64.397-.8.754a1.351 1.351 0 0 0-.016 1.114Zm4.553-8.37a1.36 1.36 0 0 0-.858-.396A7.552 7.552 0 0 1 8.46 5.62c1.062-.613 2.237-.921 3.537-.921 1.489 0 2.816.398 3.997 1.19 1.19.8 2.07 1.827 2.646 3.088.148.34.394.6.728.76a1.37 1.37 0 0 0 1.068.063c.347-.12.62-.346.799-.668.187-.338.215-.71.072-1.072l-.003-.007-.003-.007c-.784-1.818-2.006-3.298-3.658-4.434C15.982 2.47 14.094 1.9 11.998 1.9c-1.695 0-3.261.385-4.688 1.16a10.536 10.536 0 0 0-2.715 2.096 1.364 1.364 0 0 0-.308-.453 1.38 1.38 0 0 0-.994-.403c-.38 0-.722.135-.992.406s-.403.614-.403.994v3c0 .38.135.724.406.995.27.27.614.405.994.405h3c.384 0 .727-.137.998-.412a1.38 1.38 0 0 0 .402-.993c0-.38-.135-.723-.406-.992ZM9.52 14.48a3.393 3.393 0 0 0 2.478 1.02c.965 0 1.8-.342 2.479-1.02a3.392 3.392 0 0 0 1.021-2.48c0-.963-.343-1.8-1.021-2.478A3.392 3.392 0 0 0 11.998 8.5c-.964 0-1.8.343-2.478 1.021A3.392 3.392 0 0 0 8.498 12c0 .964.344 1.8 1.022 2.479Z\"/></svg>') 12 12,auto}.unreal-container.pan{cursor:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\"><path fill=\"%23000\" d=\"M11.997 10.075a1.01 1.01 0 0 1-.738-.313 1.008 1.008 0 0 1-.312-.737V6.15l-.95.95a.998.998 0 0 1-.763.312 1.09 1.09 0 0 1-.763-.337 1.06 1.06 0 0 1-.324-.775c0-.3.108-.558.324-.775l2.776-2.775c.117-.116.237-.2.362-.25a1.04 1.04 0 0 1 .775 0c.125.05.246.134.363.25l2.8 2.8c.216.217.32.47.313.762a1.096 1.096 0 0 1-.338.763 1.058 1.058 0 0 1-.775.325c-.3 0-.558-.108-.775-.325l-.925-.925v2.875c0 .283-.104.53-.312.737a1.01 1.01 0 0 1-.738.313Zm0 11.5a1.04 1.04 0 0 1-.388-.075 1.103 1.103 0 0 1-.362-.25l-2.8-2.8a1.002 1.002 0 0 1-.313-.762c.009-.292.121-.546.337-.763.217-.217.475-.325.775-.325.3 0 .559.108.775.325l.926.925v-2.875c0-.283.104-.529.312-.737a1.01 1.01 0 0 1 .738-.313c.283 0 .529.104.738.313.208.208.312.454.312.737v2.875l.95-.95a.998.998 0 0 1 .762-.312c.292.008.546.12.763.337.216.217.324.475.324.775 0 .3-.108.559-.324.775l-2.775 2.775c-.117.116-.238.2-.363.25a1.04 1.04 0 0 1-.387.075Zm4.925-6.05a1.058 1.058 0 0 1-.326-.774c0-.3.109-.559.326-.776l.925-.925H14.97c-.283 0-.528-.104-.736-.312a1.01 1.01 0 0 1-.313-.738c0-.283.104-.53.313-.738.208-.208.453-.312.737-.312h2.875l-.95-.95a.998.998 0 0 1-.313-.762 1.09 1.09 0 0 1 .338-.764 1.06 1.06 0 0 1 .775-.324c.3 0 .558.108.775.324l2.774 2.776c.117.117.2.238.251.363a1.04 1.04 0 0 1 0 .775c-.05.124-.134.245-.25.362l-2.8 2.8c-.217.216-.471.32-.762.313a1.096 1.096 0 0 1-.763-.337Zm-11.4 0L2.746 12.75a1.103 1.103 0 0 1-.25-.362 1.04 1.04 0 0 1 0-.775c.05-.125.133-.246.25-.363l2.8-2.8c.216-.216.47-.32.762-.313.292.01.546.121.763.337.217.217.325.476.325.776 0 .3-.108.558-.325.775l-.925.925h2.875c.283 0 .529.104.737.312.208.209.313.455.313.738s-.105.53-.313.738a1.008 1.008 0 0 1-.737.312H6.147l.95.95c.217.217.32.471.312.762a1.09 1.09 0 0 1-.337.764 1.06 1.06 0 0 1-.775.324c-.3 0-.559-.108-.776-.324Z\"/><path stroke=\"%23fff\" stroke-opacity=\".7\" d=\"M9.22 7.912c.436.013.821-.15 1.13-.458l.097-.097v1.668c0 .422.16.793.458 1.09.298.299.67.46 1.092.46.422 0 .793-.161 1.091-.46.298-.297.459-.668.459-1.09V7.357l.071.072c.309.308.693.471 1.13.471.435 0 .82-.163 1.128-.471.301-.303.47-.676.483-1.102v-.001a1.501 1.501 0 0 0-.46-1.13l-2.799-2.8a1.6 1.6 0 0 0-.528-.36l-.003-.001a1.54 1.54 0 0 0-1.145 0l-.002.001a1.6 1.6 0 0 0-.529.36L8.118 5.172l-.001.001a1.56 1.56 0 0 0-.47 1.128c0 .435.163.82.47 1.128.303.303.676.472 1.103.484Zm0 0 .014-.5-.015.5Zm-1.311 6.865a1.497 1.497 0 0 0-.458-1.13l-.097-.097h1.668c.421 0 .793-.16 1.09-.458.298-.299.46-.67.46-1.092a1.51 1.51 0 0 0-.46-1.091 1.507 1.507 0 0 0-1.09-.459H7.354l.071-.072c.309-.308.472-.692.472-1.128 0-.436-.163-.82-.472-1.13a1.596 1.596 0 0 0-1.101-.482h-.002a1.501 1.501 0 0 0-1.129.459l-2.8 2.8a1.6 1.6 0 0 0-.36.528l-.001.003a1.54 1.54 0 0 0 0 1.144v.003c.081.2.208.375.362.529l2.774 2.775c.309.308.693.47 1.129.47.435 0 .82-.162 1.128-.47.303-.302.472-.676.484-1.102Zm0 0-.5-.014.5.015v-.001Zm3.038-8.627-.5.5.5.207V6.15Zm.475 15.814.002.001a1.54 1.54 0 0 0 1.145 0h.002c.2-.081.375-.208.53-.362l2.775-2.774a1.56 1.56 0 0 0 .47-1.129c0-.435-.162-.82-.47-1.128a1.589 1.589 0 0 0-1.103-.484 1.497 1.497 0 0 0-1.13.458l-.096.097v-1.668c0-.421-.161-.793-.459-1.09a1.509 1.509 0 0 0-1.091-.46c-.422 0-.794.161-1.092.46a1.507 1.507 0 0 0-.458 1.09v1.668l-.072-.072a1.558 1.558 0 0 0-1.129-.471c-.436 0-.82.163-1.128.471l-.001.001c-.301.302-.47.675-.483 1.101v.001c-.012.437.151.821.46 1.13l2.8 2.8c.153.153.328.28.528.36Zm5.146-6.085c.303.302.676.47 1.102.484a1.5 1.5 0 0 0 1.13-.46l2.8-2.8a1.6 1.6 0 0 0 .36-.528l.002-.003a1.54 1.54 0 0 0 0-1.144l-.001-.003a1.6 1.6 0 0 0-.361-.529l-2.774-2.775h-.001a1.56 1.56 0 0 0-1.128-.47c-.436 0-.82.162-1.128.47h-.001a1.59 1.59 0 0 0-.484 1.102c-.012.437.15.822.459 1.13l.097.097h-1.668c-.422 0-.793.16-1.09.459-.299.298-.46.67-.46 1.091 0 .422.161.793.46 1.092.297.297.668.458 1.09.458h1.668l-.072.072a1.558 1.558 0 0 0-.472 1.129c0 .435.164.82.472 1.128ZM6.147 13.05l.5.5.207-.5h-.707Z\"/></svg>') 12 12,auto}.unreal-container.dolly{cursor:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\"><mask id=\"a\" width=\"24\" height=\"24\" x=\"0\" y=\"0\" maskUnits=\"userSpaceOnUse\" style=\"mask-type:alpha\"><path fill=\"%23127392\" d=\"M0 0h24v24H0z\"/></mask><g mask=\"url(%23a)\"><path fill=\"%23000\" d=\"M12.002 20.575a1.026 1.026 0 0 1-.75-.325l-2.55-2.55a.933.933 0 0 1-.287-.713c.008-.275.113-.513.313-.713.2-.2.441-.3.725-.3.283 0 .524.1.724.3l.776.776V6.95l-.8.8c-.2.2-.438.296-.712.288a1.018 1.018 0 0 1-.713-.312c-.2-.2-.3-.442-.3-.726s.1-.525.3-.725l2.524-2.525a1.026 1.026 0 0 1 1.5 0l2.55 2.55c.2.2.296.438.289.713a1.023 1.023 0 0 1-.314.713c-.2.2-.441.3-.724.3a.988.988 0 0 1-.725-.3l-.775-.776v10.1l.8-.8c.2-.2.437-.296.712-.288.275.008.512.112.712.312.2.2.3.442.3.726s-.1.525-.3.725l-2.524 2.525a1.026 1.026 0 0 1-.75.325Z\"/><path stroke=\"%23fff\" stroke-opacity=\".7\" d=\"M13.553 8.153c.28.245.62.373 1 .373.415 0 .784-.153 1.078-.447.287-.287.446-.644.46-1.05v-.002a1.432 1.432 0 0 0-.435-1.08l-2.55-2.55-.354.353.354-.354a1.526 1.526 0 0 0-2.207 0L8.374 5.921A1.487 1.487 0 0 0 7.928 7c0 .416.152.785.446 1.08.288.287.645.446 1.052.457l4.127-.384Zm0 0v7.693m0-7.693a1.667 1.667 0 0 1-.079-.074l-3.021.075v7.693a1.482 1.482 0 0 0-1-.373c-.416 0-.785.153-1.079.447a1.522 1.522 0 0 0-.46 1.05v.002c-.011.417.14.786.435 1.08l2.55 2.55a1.527 1.527 0 0 0 2.207 0l2.525-2.524c.294-.294.446-.663.446-1.079 0-.416-.152-.785-.446-1.08a1.518 1.518 0 0 0-1.052-.457m0 0-.014.5.014-.5Zm0 0a1.424 1.424 0 0 0-1.027.383m0 0a1.583 1.583 0 0 0-.053.05l.354.354m-.3-.404v.104l.3.3m0 0-.3-.3v.6l.3-.3Z\"/></g></svg>%0A') 12 12,auto}.unreal-container.disabled:before{content:\"\";position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}#playerUI{position:absolute;z-index:10;width:100%}#statsContainer{display:none;text-align:left;background-color:#000c}#stats{padding:6px;font-weight:700;font-size:14px;color:#0f0}canvas{position:absolute;image-rendering:crisp-edges}#overlay{position:absolute;top:0;right:2%;z-index:100;padding:4px;border-top-width:0;-webkit-border-bottom-right-radius:5px;-moz-border-radius-bottomright:5px;border-bottom-right-radius:5px;-webkit-border-bottom-left-radius:5px;-moz-border-radius-bottomleft:5px;border-bottom-left-radius:5px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-touch-callout:none}.overlay{font-weight:lighter;font-family:var(--src-font-family-body, system-ui, sans-serif)}#overlayButton:hover{cursor:pointer}#overlayButton{font-size:40px;text-align:right}#overlaySettings{display:none;width:300px;padding:4px}#videoMessageOverlay{position:absolute;z-index:20;width:100%;margin:auto;font-size:1.8em;font-family:var(--src-font-family-body, system-ui, sans-serif)}#playButton{display:inline-block;height:auto}img#playButton{width:10%;max-width:241px}#UIInteraction{position:fixed}#UIInteractionButtonBoundary{padding:2px}#UIInteractionButton{cursor:pointer}#hiddenInput{position:absolute;left:-10%;width:0;opacity:0}#editTextButton{position:absolute;width:40px;height:40px}\n"], dependencies: [{ kind: "component", type: AfkTimeoutModalComponent, selector: "app-afk-timeout-modal", inputs: ["uiClasses", "contentTemplate"] }, { kind: "component", type: UnrealStatusComponent, selector: "app-unreal-status", inputs: ["uiClasses", "contentTemplate"] }, { kind: "component", type: FreezeFrameComponent, selector: "app-freeze-frame" }, { kind: "component", type: VideoStatsComponent, selector: "app-video-stats" }, { kind: "component", type: ResumeStreamButtonComponent, selector: "app-resume-stream-button", inputs: ["uiClasses", "contentTemplate"] }, { kind: "component", type: ImageLoadingSrcComponent, selector: "app-image-loading-src" }, { kind: "component", type: IntroSrcComponent, selector: "app-intro-src" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9134
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealSceneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9135
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UnrealSceneComponent, isStandalone: true, selector: "app-unreal-scene", inputs: { useContainerAsSizeProvider: { classPropertyName: "useContainerAsSizeProvider", publicName: "useContainerAsSizeProvider", isSignal: true, isRequired: false, transformFunction: null }, isStudio: { classPropertyName: "isStudio", publicName: "isStudio", isSignal: true, isRequired: false, transformFunction: null }, resolutionSize: { classPropertyName: "resolutionSize", publicName: "resolutionSize", isSignal: true, isRequired: false, transformFunction: null }, uiClasses: { classPropertyName: "uiClasses", publicName: "uiClasses", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { changeMouseOverScene: "changeMouseOverScene" }, host: { listeners: { "mouseover": "onMouseOver()", "mouseout": "onMouseOut()", "contextmenu": "onContextMenu($event)" } }, queries: [{ propertyName: "resumeSlot", first: true, predicate: UnrealResumeSlotDirective, descendants: true, isSignal: true }, { propertyName: "afkSlot", first: true, predicate: UnrealAfkSlotDirective, descendants: true, isSignal: true }, { propertyName: "statusSlot", first: true, predicate: UnrealStatusSlotDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "videoElement", first: true, predicate: ["videoContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"frame unreal-container\">\n <div #videoContainer id=\"player\"></div>\n\n <app-intro-src />\n <app-image-loading-src />\n <app-freeze-frame />\n <app-resume-stream-button\n [uiClasses]=\"uiClasses()\"\n [contentTemplate]=\"resumeSlot()?.template ?? null\"\n />\n <app-unreal-status\n [uiClasses]=\"uiClasses()\"\n [contentTemplate]=\"statusSlot()?.template ?? null\"\n />\n <app-afk-timeout-modal\n [uiClasses]=\"uiClasses()\"\n [contentTemplate]=\"afkSlot()?.template ?? null\"\n />\n\n <ng-content select=\"app-pdf\"></ng-content>\n <ng-content select=\"app-show-case\"></ng-content>\n\n @if (isDevMode) {\n <app-video-stats />\n }\n</div>\n", styles: [".unreal-container{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#fff}.unreal-container #player{position:absolute;width:100%;height:100%;display:flex;justify-content:center;align-items:center;overflow:hidden}.unreal-container.select{cursor:url('data:image/svg+xml,<svg width=\"24\" height=\"24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M15.15 21.375a1.423 1.423 0 0 1-1.15.063 1.487 1.487 0 0 1-.85-.788l-3-6.45-2.325 3.25c-.283.4-.658.525-1.125.375-.467-.15-.7-.466-.7-.95V4.05c0-.417.188-.717.563-.9.375-.183.729-.142 1.062.125l10.1 7.95c.383.284.496.65.337 1.1-.158.45-.479.675-.962.675h-4.2l2.975 6.375c.183.384.204.767.063 1.15a1.487 1.487 0 0 1-.788.85Z\" fill=\"%23000\"/><path d=\"m12.697 20.861.002.005c.237.495.617.852 1.128 1.04.515.191 1.039.16 1.539-.08a1.987 1.987 0 0 0 1.04-1.128 1.922 1.922 0 0 0-.079-1.536v-.003L13.684 13.5H17.1c.32 0 .628-.075.89-.26.263-.184.438-.447.544-.749.106-.3.135-.617.04-.925a1.458 1.458 0 0 0-.545-.738L7.936 2.883a1.51 1.51 0 0 0-.768-.336 1.471 1.471 0 0 0-.825.154 1.495 1.495 0 0 0-.626.547 1.492 1.492 0 0 0-.217.802v12.825c0 .324.08.634.272.897.193.261.467.43.775.53.31.099.632.12.942.016.31-.103.555-.313.743-.578h.001l1.825-2.552 2.639 5.673Z\" stroke=\"%23fff\" stroke-opacity=\".7\"/></svg>') 6 2,auto}.unreal-container.orbit{cursor:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\"><path fill=\"%23000\" d=\"M11.998 21.6c-1.966 0-3.737-.53-5.312-1.588-1.575-1.058-2.738-2.437-3.488-4.137a.852.852 0 0 1 .013-.713.867.867 0 0 1 .512-.487.86.86 0 0 1 .688.037c.225.109.387.28.487.513.617 1.35 1.559 2.45 2.825 3.3 1.267.85 2.692 1.275 4.275 1.275 1.384 0 2.646-.33 3.788-.988a7.985 7.985 0 0 0 2.762-2.612h-.85a.873.873 0 0 1-.64-.257.863.863 0 0 1-.26-.638.88.88 0 0 1 .26-.643.864.864 0 0 1 .64-.262h3c.255 0 .47.086.642.259a.87.87 0 0 1 .258.64v3a.874.874 0 0 1-.257.642.863.863 0 0 1-.637.259.88.88 0 0 1-.643-.259.865.865 0 0 1-.263-.641v-.725a9.95 9.95 0 0 1-3.35 2.925c-1.35.733-2.833 1.1-4.45 1.1Zm0-17.4c-1.383 0-2.645.33-3.787.987A7.985 7.985 0 0 0 5.448 7.8h.85c.255 0 .47.086.642.257a.863.863 0 0 1 .258.638.88.88 0 0 1-.258.642.864.864 0 0 1-.642.263h-3a.87.87 0 0 1-.64-.259.87.87 0 0 1-.26-.641v-3c0-.255.086-.469.258-.641a.863.863 0 0 1 .637-.26.88.88 0 0 1 .643.26.864.864 0 0 1 .262.64v.726A9.95 9.95 0 0 1 7.548 3.5c1.35-.733 2.834-1.1 4.45-1.1 2 0 3.788.542 5.363 1.625 1.575 1.083 2.736 2.49 3.482 4.22a.724.724 0 0 1-.045.646.926.926 0 0 1-.525.437.87.87 0 0 1-.687-.04.977.977 0 0 1-.488-.513c-.616-1.35-1.558-2.45-2.825-3.3-1.266-.85-2.691-1.275-4.275-1.275Zm0 10.8a2.893 2.893 0 0 1-2.125-.875A2.893 2.893 0 0 1 8.998 12c0-.833.292-1.542.875-2.125A2.893 2.893 0 0 1 11.998 9c.834 0 1.542.292 2.125.875.584.583.875 1.292.875 2.125s-.291 1.542-.875 2.125a2.893 2.893 0 0 1-2.125.875Z\"/><path stroke=\"%23fff\" stroke-opacity=\".7\" d=\"m2.739 16.072.002.005c.789 1.788 2.014 3.24 3.666 4.35 1.66 1.116 3.53 1.673 5.591 1.673 1.696 0 3.262-.386 4.69-1.16a10.54 10.54 0 0 0 2.714-2.097c.069.167.171.32.308.454.272.268.613.403.994.403.38 0 .722-.135.992-.406s.402-.614.402-.994v-3c0-.381-.134-.724-.405-.995a1.37 1.37 0 0 0-.995-.405h-3c-.383 0-.727.137-.997.411a1.38 1.38 0 0 0-.403.994c0 .38.135.723.407.992.238.237.532.369.858.397a7.552 7.552 0 0 1-2.027 1.685c-1.062.613-2.237.92-3.538.92-1.488 0-2.815-.397-3.996-1.19-1.19-.798-2.07-1.826-2.647-3.087-.147-.34-.393-.6-.727-.76a1.36 1.36 0 0 0-1.073-.058c-.37.133-.64.397-.8.754a1.351 1.351 0 0 0-.016 1.114Zm4.553-8.37a1.36 1.36 0 0 0-.858-.396A7.552 7.552 0 0 1 8.46 5.62c1.062-.613 2.237-.921 3.537-.921 1.489 0 2.816.398 3.997 1.19 1.19.8 2.07 1.827 2.646 3.088.148.34.394.6.728.76a1.37 1.37 0 0 0 1.068.063c.347-.12.62-.346.799-.668.187-.338.215-.71.072-1.072l-.003-.007-.003-.007c-.784-1.818-2.006-3.298-3.658-4.434C15.982 2.47 14.094 1.9 11.998 1.9c-1.695 0-3.261.385-4.688 1.16a10.536 10.536 0 0 0-2.715 2.096 1.364 1.364 0 0 0-.308-.453 1.38 1.38 0 0 0-.994-.403c-.38 0-.722.135-.992.406s-.403.614-.403.994v3c0 .38.135.724.406.995.27.27.614.405.994.405h3c.384 0 .727-.137.998-.412a1.38 1.38 0 0 0 .402-.993c0-.38-.135-.723-.406-.992ZM9.52 14.48a3.393 3.393 0 0 0 2.478 1.02c.965 0 1.8-.342 2.479-1.02a3.392 3.392 0 0 0 1.021-2.48c0-.963-.343-1.8-1.021-2.478A3.392 3.392 0 0 0 11.998 8.5c-.964 0-1.8.343-2.478 1.021A3.392 3.392 0 0 0 8.498 12c0 .964.344 1.8 1.022 2.479Z\"/></svg>') 12 12,auto}.unreal-container.pan{cursor:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\"><path fill=\"%23000\" d=\"M11.997 10.075a1.01 1.01 0 0 1-.738-.313 1.008 1.008 0 0 1-.312-.737V6.15l-.95.95a.998.998 0 0 1-.763.312 1.09 1.09 0 0 1-.763-.337 1.06 1.06 0 0 1-.324-.775c0-.3.108-.558.324-.775l2.776-2.775c.117-.116.237-.2.362-.25a1.04 1.04 0 0 1 .775 0c.125.05.246.134.363.25l2.8 2.8c.216.217.32.47.313.762a1.096 1.096 0 0 1-.338.763 1.058 1.058 0 0 1-.775.325c-.3 0-.558-.108-.775-.325l-.925-.925v2.875c0 .283-.104.53-.312.737a1.01 1.01 0 0 1-.738.313Zm0 11.5a1.04 1.04 0 0 1-.388-.075 1.103 1.103 0 0 1-.362-.25l-2.8-2.8a1.002 1.002 0 0 1-.313-.762c.009-.292.121-.546.337-.763.217-.217.475-.325.775-.325.3 0 .559.108.775.325l.926.925v-2.875c0-.283.104-.529.312-.737a1.01 1.01 0 0 1 .738-.313c.283 0 .529.104.738.313.208.208.312.454.312.737v2.875l.95-.95a.998.998 0 0 1 .762-.312c.292.008.546.12.763.337.216.217.324.475.324.775 0 .3-.108.559-.324.775l-2.775 2.775c-.117.116-.238.2-.363.25a1.04 1.04 0 0 1-.387.075Zm4.925-6.05a1.058 1.058 0 0 1-.326-.774c0-.3.109-.559.326-.776l.925-.925H14.97c-.283 0-.528-.104-.736-.312a1.01 1.01 0 0 1-.313-.738c0-.283.104-.53.313-.738.208-.208.453-.312.737-.312h2.875l-.95-.95a.998.998 0 0 1-.313-.762 1.09 1.09 0 0 1 .338-.764 1.06 1.06 0 0 1 .775-.324c.3 0 .558.108.775.324l2.774 2.776c.117.117.2.238.251.363a1.04 1.04 0 0 1 0 .775c-.05.124-.134.245-.25.362l-2.8 2.8c-.217.216-.471.32-.762.313a1.096 1.096 0 0 1-.763-.337Zm-11.4 0L2.746 12.75a1.103 1.103 0 0 1-.25-.362 1.04 1.04 0 0 1 0-.775c.05-.125.133-.246.25-.363l2.8-2.8c.216-.216.47-.32.762-.313.292.01.546.121.763.337.217.217.325.476.325.776 0 .3-.108.558-.325.775l-.925.925h2.875c.283 0 .529.104.737.312.208.209.313.455.313.738s-.105.53-.313.738a1.008 1.008 0 0 1-.737.312H6.147l.95.95c.217.217.32.471.312.762a1.09 1.09 0 0 1-.337.764 1.06 1.06 0 0 1-.775.324c-.3 0-.559-.108-.776-.324Z\"/><path stroke=\"%23fff\" stroke-opacity=\".7\" d=\"M9.22 7.912c.436.013.821-.15 1.13-.458l.097-.097v1.668c0 .422.16.793.458 1.09.298.299.67.46 1.092.46.422 0 .793-.161 1.091-.46.298-.297.459-.668.459-1.09V7.357l.071.072c.309.308.693.471 1.13.471.435 0 .82-.163 1.128-.471.301-.303.47-.676.483-1.102v-.001a1.501 1.501 0 0 0-.46-1.13l-2.799-2.8a1.6 1.6 0 0 0-.528-.36l-.003-.001a1.54 1.54 0 0 0-1.145 0l-.002.001a1.6 1.6 0 0 0-.529.36L8.118 5.172l-.001.001a1.56 1.56 0 0 0-.47 1.128c0 .435.163.82.47 1.128.303.303.676.472 1.103.484Zm0 0 .014-.5-.015.5Zm-1.311 6.865a1.497 1.497 0 0 0-.458-1.13l-.097-.097h1.668c.421 0 .793-.16 1.09-.458.298-.299.46-.67.46-1.092a1.51 1.51 0 0 0-.46-1.091 1.507 1.507 0 0 0-1.09-.459H7.354l.071-.072c.309-.308.472-.692.472-1.128 0-.436-.163-.82-.472-1.13a1.596 1.596 0 0 0-1.101-.482h-.002a1.501 1.501 0 0 0-1.129.459l-2.8 2.8a1.6 1.6 0 0 0-.36.528l-.001.003a1.54 1.54 0 0 0 0 1.144v.003c.081.2.208.375.362.529l2.774 2.775c.309.308.693.47 1.129.47.435 0 .82-.162 1.128-.47.303-.302.472-.676.484-1.102Zm0 0-.5-.014.5.015v-.001Zm3.038-8.627-.5.5.5.207V6.15Zm.475 15.814.002.001a1.54 1.54 0 0 0 1.145 0h.002c.2-.081.375-.208.53-.362l2.775-2.774a1.56 1.56 0 0 0 .47-1.129c0-.435-.162-.82-.47-1.128a1.589 1.589 0 0 0-1.103-.484 1.497 1.497 0 0 0-1.13.458l-.096.097v-1.668c0-.421-.161-.793-.459-1.09a1.509 1.509 0 0 0-1.091-.46c-.422 0-.794.161-1.092.46a1.507 1.507 0 0 0-.458 1.09v1.668l-.072-.072a1.558 1.558 0 0 0-1.129-.471c-.436 0-.82.163-1.128.471l-.001.001c-.301.302-.47.675-.483 1.101v.001c-.012.437.151.821.46 1.13l2.8 2.8c.153.153.328.28.528.36Zm5.146-6.085c.303.302.676.47 1.102.484a1.5 1.5 0 0 0 1.13-.46l2.8-2.8a1.6 1.6 0 0 0 .36-.528l.002-.003a1.54 1.54 0 0 0 0-1.144l-.001-.003a1.6 1.6 0 0 0-.361-.529l-2.774-2.775h-.001a1.56 1.56 0 0 0-1.128-.47c-.436 0-.82.162-1.128.47h-.001a1.59 1.59 0 0 0-.484 1.102c-.012.437.15.822.459 1.13l.097.097h-1.668c-.422 0-.793.16-1.09.459-.299.298-.46.67-.46 1.091 0 .422.161.793.46 1.092.297.297.668.458 1.09.458h1.668l-.072.072a1.558 1.558 0 0 0-.472 1.129c0 .435.164.82.472 1.128ZM6.147 13.05l.5.5.207-.5h-.707Z\"/></svg>') 12 12,auto}.unreal-container.dolly{cursor:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\"><mask id=\"a\" width=\"24\" height=\"24\" x=\"0\" y=\"0\" maskUnits=\"userSpaceOnUse\" style=\"mask-type:alpha\"><path fill=\"%23127392\" d=\"M0 0h24v24H0z\"/></mask><g mask=\"url(%23a)\"><path fill=\"%23000\" d=\"M12.002 20.575a1.026 1.026 0 0 1-.75-.325l-2.55-2.55a.933.933 0 0 1-.287-.713c.008-.275.113-.513.313-.713.2-.2.441-.3.725-.3.283 0 .524.1.724.3l.776.776V6.95l-.8.8c-.2.2-.438.296-.712.288a1.018 1.018 0 0 1-.713-.312c-.2-.2-.3-.442-.3-.726s.1-.525.3-.725l2.524-2.525a1.026 1.026 0 0 1 1.5 0l2.55 2.55c.2.2.296.438.289.713a1.023 1.023 0 0 1-.314.713c-.2.2-.441.3-.724.3a.988.988 0 0 1-.725-.3l-.775-.776v10.1l.8-.8c.2-.2.437-.296.712-.288.275.008.512.112.712.312.2.2.3.442.3.726s-.1.525-.3.725l-2.524 2.525a1.026 1.026 0 0 1-.75.325Z\"/><path stroke=\"%23fff\" stroke-opacity=\".7\" d=\"M13.553 8.153c.28.245.62.373 1 .373.415 0 .784-.153 1.078-.447.287-.287.446-.644.46-1.05v-.002a1.432 1.432 0 0 0-.435-1.08l-2.55-2.55-.354.353.354-.354a1.526 1.526 0 0 0-2.207 0L8.374 5.921A1.487 1.487 0 0 0 7.928 7c0 .416.152.785.446 1.08.288.287.645.446 1.052.457l4.127-.384Zm0 0v7.693m0-7.693a1.667 1.667 0 0 1-.079-.074l-3.021.075v7.693a1.482 1.482 0 0 0-1-.373c-.416 0-.785.153-1.079.447a1.522 1.522 0 0 0-.46 1.05v.002c-.011.417.14.786.435 1.08l2.55 2.55a1.527 1.527 0 0 0 2.207 0l2.525-2.524c.294-.294.446-.663.446-1.079 0-.416-.152-.785-.446-1.08a1.518 1.518 0 0 0-1.052-.457m0 0-.014.5.014-.5Zm0 0a1.424 1.424 0 0 0-1.027.383m0 0a1.583 1.583 0 0 0-.053.05l.354.354m-.3-.404v.104l.3.3m0 0-.3-.3v.6l.3-.3Z\"/></g></svg>%0A') 12 12,auto}.unreal-container.disabled:before{content:\"\";position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}#playerUI{position:absolute;z-index:10;width:100%}#statsContainer{display:none;text-align:left;background-color:#000c}#stats{padding:6px;font-weight:700;font-size:14px;color:#0f0}canvas{position:absolute;image-rendering:crisp-edges}#overlay{position:absolute;top:0;right:2%;z-index:100;padding:4px;border-top-width:0;-webkit-border-bottom-right-radius:5px;-moz-border-radius-bottomright:5px;border-bottom-right-radius:5px;-webkit-border-bottom-left-radius:5px;-moz-border-radius-bottomleft:5px;border-bottom-left-radius:5px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-touch-callout:none}.overlay{font-weight:lighter;font-family:var(--src-font-family-body, system-ui, sans-serif)}#overlayButton:hover{cursor:pointer}#overlayButton{font-size:40px;text-align:right}#overlaySettings{display:none;width:300px;padding:4px}#videoMessageOverlay{position:absolute;z-index:20;width:100%;margin:auto;font-size:1.8em;font-family:var(--src-font-family-body, system-ui, sans-serif)}#playButton{display:inline-block;height:auto}img#playButton{width:10%;max-width:241px}#UIInteraction{position:fixed}#UIInteractionButtonBoundary{padding:2px}#UIInteractionButton{cursor:pointer}#hiddenInput{position:absolute;left:-10%;width:0;opacity:0}#editTextButton{position:absolute;width:40px;height:40px}\n"], dependencies: [{ kind: "component", type: AfkTimeoutModalComponent, selector: "app-afk-timeout-modal", inputs: ["uiClasses", "contentTemplate"] }, { kind: "component", type: UnrealStatusComponent, selector: "app-unreal-status", inputs: ["uiClasses", "contentTemplate"] }, { kind: "component", type: FreezeFrameComponent, selector: "app-freeze-frame" }, { kind: "component", type: VideoStatsComponent, selector: "app-video-stats" }, { kind: "component", type: ResumeStreamButtonComponent, selector: "app-resume-stream-button", inputs: ["uiClasses", "contentTemplate"] }, { kind: "component", type: ImageLoadingSrcComponent, selector: "app-image-loading-src" }, { kind: "component", type: IntroSrcComponent, selector: "app-intro-src" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9005
9136
  }
9006
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: UnrealSceneComponent, decorators: [{
9137
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UnrealSceneComponent, decorators: [{
9007
9138
  type: Component,
9008
9139
  args: [{ selector: 'app-unreal-scene', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
9009
9140
  AfkTimeoutModalComponent,
@@ -9073,5 +9204,5 @@ function provideUnrealModule() {
9073
9204
  * Generated bundle index. Do not edit.
9074
9205
  */
9075
9206
 
9076
- export { AFKService, ALL_KEYBOARD_KEYS, AUTO_HIGH_RESOLUTION_IDLE_MS, AfkTimeoutModalComponent, AggregatorService, AnalyticsService, AnswerHandler, COLOR_CODES, CommandTelemetryService, ConfigHandler, ConsoleExtensionsService, ControlScheme, DATA_CHANNEL_CONNECTION_TIMEOUT, DEBOUNCE_TO_MANY_RESIZE_CALLS, DEFAULT_AFK_TIMEOUT, DEFAULT_AFK_TIMEOUT_PERIOD, DESTROY_DISCONNECT_REASONS, DevModeService, DisconnectReason, FULL_HD_HEIGHT, FULL_HD_WIDTH, Falsy, FileHandlerService, FileReceiverService, FpsMonitorService, FreezeFrameComponent, FreezeFrameService, HEXtoRGB, HSVtoRGB, IME_PROCESS_KEY, INNER_RETRY_LIMIT, INSTANCE_READY_TIMEOUT, IceCandidateHandler, ImageLoadingSrcComponent, InputOptions, InputService, InstanceReadyHandler, InstanceReservedHandler, IntroSrcComponent, LatencyTimings, LoadingProgressService, Logger, MINIMAL_FPS, MIN_CONTAINER_SIZE, MODIFIER_KEY_CODES, MessageType, MouseButton, MouseButtonsMask, OUTER_RETRY_DELAY, OnCloseHandler, OnErrorHandler, OnMessageHandler, OnOpenHandler, OrchestrationMessageTypes, POLLING_TIME, PlayerCountHandler, RECONNECT_CONFIG, REGION_PING_ACCURATE_SAMPLES, REGION_PING_BACKGROUND_REFRESH_DELAY_MS, REGION_PING_CACHE_KEY, REGION_PING_CACHE_TTL_MS, REGION_PING_WARMUP_DEADLINE_MS, RGBtoHEX, RGBtoHSV, RegionsPingService, SAME_SIZE_THRESHOLD, SCREEN_LOCKER_CONTAINER_ID, SIGNALLING_PERCENT_VALUE, SSInfoHandler, STREAMING_AUDIO_ID, STREAMING_VIDEO_ID, SafePipe, Semaphore, SignallingService, StatGraphComponent, StreamAdoptionService, StreamStatusTelemetryService, StreamStatusTelemetryService2, SubService, ToClientMessage, Truthy, UnrealAfkSlotDirective, UnrealCallbackService, UnrealCommunicatorService, UnrealEffects, UnrealKeyCode, UnrealResumeSlotDirective, UnrealSceneComponent, UnrealStatusMessage, UnrealStatusSlotDirective, VideoService, VideoStatsComponent, WSCloseCode_CIRRUS_ABNORMAL_CLOSURE, WSCloseCode_CIRRUS_MAX_PLAYERS_ERROR, WSCloseCode_CIRRUS_PLAYER_DISCONNECTED, WSCloseCode_CIRRUS_STREAMER_KIKED_PLAYER, WSCloseCode_FORCE_CIRRUS_CLOSE, WSCloseCode_NORMAL_AFK_TIMEOUT, WSCloseCode_NORMAL_CLOSURE, WSCloseCode_NORMAL_MANUAL_DISCONNECT, WSCloseCode_UNKNOWN, WSCloseCodes, WS_OPEN_STATE, WS_RETRY_PER_INSTANCE, WS_TIMEOUT, WebRtcPlayerService, WebrtcErrorModalComponent, abortEstablishingConnection, answerSent, changeStatusMainVideoOnScene, changeStreamResolutionAction, clampf, commandCompleted, commandStarted, dataChannelConnected, dataChannelReady, decodeData, destroyRemoteConnections, destroyUnrealScene, disconnectStream, dispatchResize, dropConnection, dropDC, dropPC, fitIntoRectangle, floatToPercents, floatToSmoothPercents, forceResizeViewport, fpIsASameAsB, fromResizeObserver, generateUuid, getActiveUrl, getCanvasCached, getImageFromVideoStream, getResizeStudioValues, getResizeValuesUniversal, getRtcErrorMessage, getSnapshot, iceConnectionFailed, initSignalling, instanceReady, inverseLerp, isAppOwned, isMetaboxMode, keepMaxUntilReset, lerp, makeEven, pollingEnded, pollingStarted, provideUnrealModule, provideUnrealState, qpToQuality, reconnectPeer, reconnectPeerFailed, reconnectPeerSuccess, regionPingFetchEnd, regionPingFetchStart, regionResolved, resetAfk, resetConfig, resetDataChannelForReconnect, resetIntroSrc, resetUserInactivityTimeout, resetWarnTimeout, resolveSkin, saveAnalyticsEvent, selectCirrusConnectionId, selectClientAndViewIds, selectCommandProgress, selectFreezeFrameCombinedDataUrl, selectFreezeFrameDataUrl, selectFreezeFrameDataUrlFromVideo, selectFreezeFrameProgressMessageFromVideo, selectIsAutostart, selectIsExistMatchUrls, selectIsFreezeFrameLoading, selectIsFullyConnected, selectIsLoaderScreenVisible, selectIsVideoPlayingAndDataChannelConnected, selectShowLoader, selectShowReconnectPopup, selectSignalingParameters, selectStreamConfig, selectTotalProgress, selectUserInactivityDetected, selectWarnTimeout, setAfkTimerCountdown, setAfkTimerHide, setAfkTimerVisible, setAwsInstance, setCirrusConnected, setCirrusDisconnected, setConfig, setEstablishingConnection, setFreezeFrame, setFreezeFrameFromVideo, setIntroImageSrc, setIntroVideoSrc, setLoadingImageSrc, setLoopBackCommandIsCompleted, setMaxFps, setOrchestrationContext, setOrchestrationMessage, setOrchestrationParameters, setOrchestrationProgress, setSignalingName, setStatusMessage, setStatusPercentSignallingServer, setStreamClientCompanyId, setStreamViewId, setUnrealPlaywrightConfig, setUserInactivityTimeout, setViewportNotReady, setViewportReady, showLoadingProgress, showResumeStreamPopup, showUnrealErrorMessage, showUserInactivityTimeoutPopup, signalingRetryAttempted, startStream, streamAdopted, tapLog, trackMixpanelEvent, trackTelemetryData, uint8ToBase64, unrealCommandCallback, unrealFeature, unrealReducer, updateCirrusInfo, videoAdaptedToContainer, videoStreamInitialized };
9207
+ export { AFKService, ALL_KEYBOARD_KEYS, AUTO_HIGH_RESOLUTION_IDLE_MS, AfkTimeoutModalComponent, AggregatorService, AnalyticsService, AnswerHandler, COLOR_CODES, CommandTelemetryService, ConfigHandler, ConsoleExtensionsService, ControlScheme, DATA_CHANNEL_CONNECTION_TIMEOUT, DEBOUNCE_TO_MANY_RESIZE_CALLS, DEFAULT_AFK_TIMEOUT, DEFAULT_AFK_TIMEOUT_PERIOD, DESTROY_DISCONNECT_REASONS, DevModeService, DisconnectReason, FULL_HD_HEIGHT, FULL_HD_WIDTH, Falsy, FileHandlerService, FileReceiverService, FpsMonitorService, FreezeFrameComponent, FreezeFrameService, HEXtoRGB, HSVtoRGB, IME_PROCESS_KEY, INNER_RETRY_LIMIT, INSTANCE_READY_TIMEOUT, IceCandidateHandler, ImageLoadingSrcComponent, InputOptions, InputService, InstanceReadyHandler, InstanceReservedHandler, IntroSrcComponent, LatencyTimings, LoadingProgressService, Logger, MINIMAL_FPS, MODIFIER_KEY_CODES, MessageType, MouseButton, MouseButtonsMask, OUTER_RETRY_DELAY, OnCloseHandler, OnErrorHandler, OnMessageHandler, OnOpenHandler, OrchestrationMessageTypes, POLLING_TIME, PlayerCountHandler, RECONNECT_CONFIG, REGION_PING_ACCURATE_SAMPLES, REGION_PING_BACKGROUND_REFRESH_DELAY_MS, REGION_PING_CACHE_KEY, REGION_PING_CACHE_TTL_MS, REGION_PING_WARMUP_DEADLINE_MS, RGBtoHEX, RGBtoHSV, RegionsPingService, SAME_SIZE_THRESHOLD, SCREEN_LOCKER_CONTAINER_ID, SIGNALLING_PERCENT_VALUE, SSInfoHandler, STREAMING_AUDIO_ID, STREAMING_VIDEO_ID, STREAM_RESOLUTION_LIMITS, SafePipe, Semaphore, SignallingService, StatGraphComponent, StreamAdoptionService, StreamStatusTelemetryService, StreamStatusTelemetryService2, SubService, ToClientMessage, Truthy, UnrealAfkSlotDirective, UnrealCallbackService, UnrealCommunicatorService, UnrealEffects, UnrealKeyCode, UnrealResumeSlotDirective, UnrealSceneComponent, UnrealStatusMessage, UnrealStatusSlotDirective, VideoService, VideoStatsComponent, WSCloseCode_CIRRUS_ABNORMAL_CLOSURE, WSCloseCode_CIRRUS_MAX_PLAYERS_ERROR, WSCloseCode_CIRRUS_PLAYER_DISCONNECTED, WSCloseCode_CIRRUS_STREAMER_KIKED_PLAYER, WSCloseCode_FORCE_CIRRUS_CLOSE, WSCloseCode_NORMAL_AFK_TIMEOUT, WSCloseCode_NORMAL_CLOSURE, WSCloseCode_NORMAL_MANUAL_DISCONNECT, WSCloseCode_UNKNOWN, WSCloseCodes, WS_OPEN_STATE, WS_RETRY_PER_INSTANCE, WS_TIMEOUT, WebRtcPlayerService, WebrtcErrorModalComponent, abortEstablishingConnection, answerSent, changeStatusMainVideoOnScene, changeStreamResolutionAction, clampStreamResolution, clampf, commandCompleted, commandStarted, dataChannelConnected, dataChannelReady, decodeData, destroyRemoteConnections, destroyUnrealScene, disconnectStream, dispatchResize, dropConnection, dropDC, dropPC, fitIntoRectangle, floatToPercents, floatToSmoothPercents, forceResizeViewport, fpIsASameAsB, fromResizeObserver, generateUuid, getActiveUrl, getCanvasCached, getImageFromVideoStream, getResizeStudioValues, getResizeValuesUniversal, getRtcErrorMessage, getSnapshot, iceConnectionFailed, initSignalling, instanceReady, inverseLerp, isAppOwned, isMetaboxMode, keepMaxUntilReset, lerp, makeEven, pollingEnded, pollingStarted, provideUnrealModule, provideUnrealState, qpToQuality, reconnectPeer, reconnectPeerFailed, reconnectPeerSuccess, regionPingFetchEnd, regionPingFetchStart, regionResolved, resetAfk, resetConfig, resetDataChannelForReconnect, resetIntroSrc, resetUserInactivityTimeout, resetWarnTimeout, resolveSkin, saveAnalyticsEvent, selectCirrusConnectionId, selectClientAndViewIds, selectCommandProgress, selectFreezeFrameCombinedDataUrl, selectFreezeFrameDataUrl, selectFreezeFrameDataUrlFromVideo, selectFreezeFrameProgressMessageFromVideo, selectIsAutostart, selectIsExistMatchUrls, selectIsFreezeFrameLoading, selectIsFullyConnected, selectIsLoaderScreenVisible, selectIsVideoPlayingAndDataChannelConnected, selectShowLoader, selectShowReconnectPopup, selectSignalingParameters, selectStreamConfig, selectTotalProgress, selectUserInactivityDetected, selectWarnTimeout, setAfkTimerCountdown, setAfkTimerHide, setAfkTimerVisible, setAwsInstance, setCirrusConnected, setCirrusDisconnected, setConfig, setEstablishingConnection, setFreezeFrame, setFreezeFrameFromVideo, setIntroImageSrc, setIntroVideoSrc, setLoadingImageSrc, setLoopBackCommandIsCompleted, setMaxFps, setOrchestrationContext, setOrchestrationMessage, setOrchestrationParameters, setOrchestrationProgress, setSignalingName, setStatusMessage, setStatusPercentSignallingServer, setStreamClientCompanyId, setStreamViewId, setUnrealPlaywrightConfig, setUserInactivityTimeout, setViewportNotReady, setViewportReady, showLoadingProgress, showResumeStreamPopup, showUnrealErrorMessage, showUserInactivityTimeoutPopup, signalingRetryAttempted, startStream, streamAdopted, tapLog, trackMixpanelEvent, trackTelemetryData, uint8ToBase64, unrealCommandCallback, unrealFeature, unrealReducer, updateCirrusInfo, videoAdaptedToContainer, videoStreamInitialized };
9077
9208
  //# sourceMappingURL=3dsource-angular-unreal-module.mjs.map