@rocketshow/designer 1.58.0 → 1.60.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.
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Injectable, HostListener, ViewChild, Component, Pipe, EventEmitter, Output, Input, Directive, ChangeDetectionStrategy, ViewEncapsulation, NgModule } from '@angular/core';
3
- import * as i4 from '@ngx-translate/core';
3
+ import * as i2 from '@ngx-translate/core';
4
4
  import { TranslateModule } from '@ngx-translate/core';
5
5
  import * as i1$1 from 'ngx-bootstrap/modal';
6
6
  import { map, mergeMap, finalize, catchError } from 'rxjs/operators';
@@ -24,15 +24,15 @@ import * as i5 from 'ngx-dropzone-wrapper';
24
24
  import { DropzoneModule } from 'ngx-dropzone-wrapper';
25
25
  import * as i3$2 from '@angular/forms';
26
26
  import { FormsModule } from '@angular/forms';
27
- import * as i11 from 'ngx-bootstrap/popover';
27
+ import * as i12 from 'ngx-bootstrap/popover';
28
28
  import { PopoverModule } from 'ngx-bootstrap/popover';
29
29
  import Sortable from 'sortablejs';
30
30
  import * as i10 from 'ngx-bootstrap/typeahead';
31
31
  import { TypeaheadModule } from 'ngx-bootstrap/typeahead';
32
- import * as i3$3 from 'ngx-bootstrap-slider';
32
+ import * as i4 from 'ngx-bootstrap-slider';
33
33
  import { NgxBootstrapSliderModule } from 'ngx-bootstrap-slider';
34
- import * as i9 from '@angular/common';
35
- import * as i5$1 from 'ngx-bootstrap/accordion';
34
+ import * as i10$1 from '@angular/common';
35
+ import * as i6 from 'ngx-bootstrap/accordion';
36
36
  import { AccordionModule } from 'ngx-bootstrap/accordion';
37
37
  import { KEYS, TREE_ACTIONS, TreeModule } from '@ali-hm/angular-tree-component';
38
38
  import { BrowserModule } from '@angular/platform-browser';
@@ -1022,7 +1022,7 @@ class ProjectService {
1022
1022
  return project;
1023
1023
  }));
1024
1024
  }
1025
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProjectService, deps: [{ token: i1.HttpClient }, { token: UserService }, { token: i3.Router }, { token: i3.ActivatedRoute }, { token: i4.TranslateService }, { token: i3$1.ToastrService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1025
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProjectService, deps: [{ token: i1.HttpClient }, { token: UserService }, { token: i3.Router }, { token: i3.ActivatedRoute }, { token: i2.TranslateService }, { token: i3$1.ToastrService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1026
1026
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProjectService, providedIn: 'root' }); }
1027
1027
  }
1028
1028
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProjectService, decorators: [{
@@ -1030,7 +1030,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
1030
1030
  args: [{
1031
1031
  providedIn: 'root',
1032
1032
  }]
1033
- }], ctorParameters: () => [{ type: i1.HttpClient }, { type: UserService }, { type: i3.Router }, { type: i3.ActivatedRoute }, { type: i4.TranslateService }, { type: i3$1.ToastrService }] });
1033
+ }], ctorParameters: () => [{ type: i1.HttpClient }, { type: UserService }, { type: i3.Router }, { type: i3.ActivatedRoute }, { type: i2.TranslateService }, { type: i3$1.ToastrService }] });
1034
1034
 
1035
1035
  class UuidService {
1036
1036
  constructor() { }
@@ -1940,7 +1940,7 @@ class FixtureService {
1940
1940
  });
1941
1941
  }
1942
1942
  }
1943
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureService, deps: [{ token: i1.HttpClient }, { token: ProjectService }, { token: i4.TranslateService }, { token: i3$1.ToastrService }, { token: UuidService }, { token: FixturePixelGroupResolveService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1943
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureService, deps: [{ token: i1.HttpClient }, { token: ProjectService }, { token: i2.TranslateService }, { token: i3$1.ToastrService }, { token: UuidService }, { token: FixturePixelGroupResolveService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1944
1944
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureService, providedIn: 'root' }); }
1945
1945
  }
1946
1946
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureService, decorators: [{
@@ -1948,7 +1948,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
1948
1948
  args: [{
1949
1949
  providedIn: 'root',
1950
1950
  }]
1951
- }], ctorParameters: () => [{ type: i1.HttpClient }, { type: ProjectService }, { type: i4.TranslateService }, { type: i3$1.ToastrService }, { type: UuidService }, { type: FixturePixelGroupResolveService }] });
1951
+ }], ctorParameters: () => [{ type: i1.HttpClient }, { type: ProjectService }, { type: i2.TranslateService }, { type: i3$1.ToastrService }, { type: UuidService }, { type: FixturePixelGroupResolveService }] });
1952
1952
 
1953
1953
  class PreviewMeshService {
1954
1954
  constructor() {
@@ -2010,6 +2010,22 @@ class PresetRegionScene {
2010
2010
  }
2011
2011
  }
2012
2012
 
2013
+ class EffectService {
2014
+ constructor() {
2015
+ // The effects are currently being edited
2016
+ this.effectsOpen = false;
2017
+ this.effectsOpenChanged = new Subject();
2018
+ }
2019
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: EffectService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2020
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: EffectService, providedIn: 'root' }); }
2021
+ }
2022
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: EffectService, decorators: [{
2023
+ type: Injectable,
2024
+ args: [{
2025
+ providedIn: 'root',
2026
+ }]
2027
+ }], ctorParameters: () => [] });
2028
+
2013
2029
  class AnimationService {
2014
2030
  constructor() {
2015
2031
  this.timeMillis = 0;
@@ -2048,31 +2064,87 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
2048
2064
  }]
2049
2065
  }], ctorParameters: () => [] });
2050
2066
 
2051
- class EffectService {
2067
+ class TimelineStateService {
2052
2068
  constructor() {
2053
- // The effects are currently being edited
2054
- this.effectsOpen = false;
2055
- this.effectsOpenChanged = new Subject();
2069
+ this.playState = 'paused';
2056
2070
  }
2057
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: EffectService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2058
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: EffectService, providedIn: 'root' }); }
2071
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TimelineStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2072
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TimelineStateService, providedIn: 'root' }); }
2059
2073
  }
2060
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: EffectService, decorators: [{
2074
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TimelineStateService, decorators: [{
2061
2075
  type: Injectable,
2062
2076
  args: [{
2063
2077
  providedIn: 'root',
2064
2078
  }]
2065
2079
  }], ctorParameters: () => [] });
2066
2080
 
2081
+ class LivePreviewService {
2082
+ constructor(configService, http, projectService, animationService, timelineStateService) {
2083
+ this.configService = configService;
2084
+ this.http = http;
2085
+ this.projectService = projectService;
2086
+ this.animationService = animationService;
2087
+ this.timelineStateService = timelineStateService;
2088
+ this.liveChangePending = false;
2089
+ }
2090
+ previewLive(compositionName = '', positionMillis) {
2091
+ if (!this.configService.livePreview) {
2092
+ return;
2093
+ }
2094
+ if (!compositionName && this.timelineStateService.playState === 'playing' && this.timelineStateService.selectedComposition) {
2095
+ compositionName = this.timelineStateService.selectedComposition.name;
2096
+ }
2097
+ let position = positionMillis;
2098
+ if (position === undefined) {
2099
+ position = Math.round(this.animationService.timeMillis);
2100
+ }
2101
+ // collect all changes and delay them to not flood the backend
2102
+ // (except composition-bound updates. they need to be delivered always)
2103
+ if (this.livePreviewTimer && !compositionName) {
2104
+ this.livePreviewPendingPositionMillis = position;
2105
+ this.liveChangePending = true;
2106
+ return;
2107
+ }
2108
+ this.http
2109
+ .post('preview?positionMillis=' + position + '&compositionName=' + compositionName, JSON.stringify(this.projectService.project))
2110
+ .subscribe();
2111
+ this.liveChangePending = false;
2112
+ if (!compositionName) {
2113
+ this.livePreviewTimer = setTimeout(() => {
2114
+ this.livePreviewTimer = undefined;
2115
+ if (this.liveChangePending) {
2116
+ const pendingPosition = this.livePreviewPendingPositionMillis !== undefined ? this.livePreviewPendingPositionMillis : position;
2117
+ this.livePreviewPendingPositionMillis = undefined;
2118
+ this.http
2119
+ .post('preview?positionMillis=' + pendingPosition + '&compositionName=' + compositionName, JSON.stringify(this.projectService.project))
2120
+ .subscribe();
2121
+ }
2122
+ }, 50);
2123
+ }
2124
+ }
2125
+ stopPreviewPlay() {
2126
+ if (!this.configService.livePreview) {
2127
+ return;
2128
+ }
2129
+ this.http.post('stop-preview-play', null).subscribe();
2130
+ }
2131
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: LivePreviewService, deps: [{ token: ConfigService }, { token: i1.HttpClient }, { token: ProjectService }, { token: AnimationService }, { token: TimelineStateService }], target: i0.ɵɵFactoryTarget.Injectable }); }
2132
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: LivePreviewService, providedIn: 'root' }); }
2133
+ }
2134
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: LivePreviewService, decorators: [{
2135
+ type: Injectable,
2136
+ args: [{
2137
+ providedIn: 'root',
2138
+ }]
2139
+ }], ctorParameters: () => [{ type: ConfigService }, { type: i1.HttpClient }, { type: ProjectService }, { type: AnimationService }, { type: TimelineStateService }] });
2140
+
2067
2141
  class PresetService {
2068
- constructor(effectService, uuidService, projectService, fixtureService, configService, http, animationService) {
2142
+ constructor(effectService, uuidService, projectService, fixtureService, livePreviewService) {
2069
2143
  this.effectService = effectService;
2070
2144
  this.uuidService = uuidService;
2071
2145
  this.projectService = projectService;
2072
2146
  this.fixtureService = fixtureService;
2073
- this.configService = configService;
2074
- this.http = http;
2075
- this.animationService = animationService;
2147
+ this.livePreviewService = livePreviewService;
2076
2148
  // fires, when the current preview element has changed (scene/preset)
2077
2149
  this.previewSelectionChanged = new Subject();
2078
2150
  // fires, when the fixture selection has changed
@@ -2082,7 +2154,6 @@ class PresetService {
2082
2154
  // fires, when the selected color has changed. This is required,
2083
2155
  // because detectChanges is not enough to trigger different components.
2084
2156
  this.fixtureColorChanged = new Subject();
2085
- this.liveChangePending = false;
2086
2157
  }
2087
2158
  getPresetByUuid(uuid) {
2088
2159
  for (const preset of this.projectService.project.presets) {
@@ -2376,7 +2447,7 @@ class PresetService {
2376
2447
  this.projectService.project.selectedPresetUuid = this.projectService.project.presets[index].uuid;
2377
2448
  this.autoOpenFirstEffect();
2378
2449
  this.previewSelectionChanged.next();
2379
- this.previewLive();
2450
+ this.livePreviewService.previewLive();
2380
2451
  }
2381
2452
  autoOpenFirstEffect() {
2382
2453
  // open the first effect, if the preset only has one
@@ -2457,42 +2528,7 @@ class PresetService {
2457
2528
  });
2458
2529
  return availableChannels;
2459
2530
  }
2460
- previewLive(compositionName = '', positionMillis) {
2461
- if (!this.configService.livePreview) {
2462
- return;
2463
- }
2464
- // collect all changes and delay them to not flood the backend
2465
- // (except play events. they need to be delivered always)
2466
- if (this.livePreviewTimer && !compositionName) {
2467
- this.liveChangePending = true;
2468
- return;
2469
- }
2470
- let position = positionMillis;
2471
- if (position === undefined) {
2472
- position = Math.round(this.animationService.timeMillis);
2473
- }
2474
- this.http
2475
- .post('preview?positionMillis=' + position + '&compositionName=' + compositionName, JSON.stringify(this.projectService.project))
2476
- .subscribe();
2477
- this.liveChangePending = false;
2478
- if (!compositionName) {
2479
- this.livePreviewTimer = setTimeout(() => {
2480
- this.livePreviewTimer = undefined;
2481
- if (this.liveChangePending) {
2482
- this.http
2483
- .post('preview?positionMillis=' + position + '&compositionName=' + compositionName, JSON.stringify(this.projectService.project))
2484
- .subscribe();
2485
- }
2486
- }, 50);
2487
- }
2488
- }
2489
- stopPreviewPlay() {
2490
- if (!this.configService.livePreview) {
2491
- return;
2492
- }
2493
- this.http.post('stop-preview-play', null).subscribe();
2494
- }
2495
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PresetService, deps: [{ token: EffectService }, { token: UuidService }, { token: ProjectService }, { token: FixtureService }, { token: ConfigService }, { token: i1.HttpClient }, { token: AnimationService }], target: i0.ɵɵFactoryTarget.Injectable }); }
2531
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PresetService, deps: [{ token: EffectService }, { token: UuidService }, { token: ProjectService }, { token: FixtureService }, { token: LivePreviewService }], target: i0.ɵɵFactoryTarget.Injectable }); }
2496
2532
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PresetService, providedIn: 'root' }); }
2497
2533
  }
2498
2534
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PresetService, decorators: [{
@@ -2500,14 +2536,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
2500
2536
  args: [{
2501
2537
  providedIn: 'root',
2502
2538
  }]
2503
- }], ctorParameters: () => [{ type: EffectService }, { type: UuidService }, { type: ProjectService }, { type: FixtureService }, { type: ConfigService }, { type: i1.HttpClient }, { type: AnimationService }] });
2539
+ }], ctorParameters: () => [{ type: EffectService }, { type: UuidService }, { type: ProjectService }, { type: FixtureService }, { type: LivePreviewService }] });
2504
2540
 
2505
2541
  class SceneService {
2506
- constructor(uuidService, effectService, presetService, projectService) {
2542
+ constructor(uuidService, effectService, presetService, projectService, livePreviewService) {
2507
2543
  this.uuidService = uuidService;
2508
2544
  this.effectService = effectService;
2509
2545
  this.presetService = presetService;
2510
2546
  this.projectService = projectService;
2547
+ this.livePreviewService = livePreviewService;
2511
2548
  this.selectedScenes = [];
2512
2549
  this.sceneColors = ['#945fda', '#61da5f', '#5fc3da', '#dad65f', '#da5f5f', '#246db7'];
2513
2550
  this.multipleSelection = false;
@@ -2596,7 +2633,7 @@ class SceneService {
2596
2633
  this.projectService.project.selectedSceneUuids.push(scene.uuid);
2597
2634
  }
2598
2635
  this.presetService.previewSelectionChanged.next();
2599
- this.presetService.previewLive();
2636
+ this.livePreviewService.previewLive();
2600
2637
  this.sceneSelected.next();
2601
2638
  }
2602
2639
  addScene(name) {
@@ -2644,7 +2681,7 @@ class SceneService {
2644
2681
  }
2645
2682
  }
2646
2683
  }
2647
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: SceneService, deps: [{ token: UuidService }, { token: EffectService }, { token: PresetService }, { token: ProjectService }], target: i0.ɵɵFactoryTarget.Injectable }); }
2684
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: SceneService, deps: [{ token: UuidService }, { token: EffectService }, { token: PresetService }, { token: ProjectService }, { token: LivePreviewService }], target: i0.ɵɵFactoryTarget.Injectable }); }
2648
2685
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: SceneService, providedIn: 'root' }); }
2649
2686
  }
2650
2687
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: SceneService, decorators: [{
@@ -2652,17 +2689,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
2652
2689
  args: [{
2653
2690
  providedIn: 'root',
2654
2691
  }]
2655
- }], ctorParameters: () => [{ type: UuidService }, { type: EffectService }, { type: PresetService }, { type: ProjectService }] });
2692
+ }], ctorParameters: () => [{ type: UuidService }, { type: EffectService }, { type: PresetService }, { type: ProjectService }, { type: LivePreviewService }] });
2656
2693
 
2657
2694
  class TimelineService {
2658
- constructor(sceneService, presetService, projectService, http, configService, ngZone) {
2695
+ constructor(sceneService, presetService, projectService, http, configService, ngZone, timelineStateService, livePreviewService) {
2659
2696
  this.sceneService = sceneService;
2660
2697
  this.presetService = presetService;
2661
2698
  this.projectService = projectService;
2662
2699
  this.http = http;
2663
2700
  this.configService = configService;
2664
2701
  this.ngZone = ngZone;
2665
- this.playState = 'paused';
2702
+ this.timelineStateService = timelineStateService;
2703
+ this.livePreviewService = livePreviewService;
2666
2704
  this.zoom = 0;
2667
2705
  this.timelineClicking = false;
2668
2706
  this.intensity = 0.2;
@@ -2685,6 +2723,24 @@ class TimelineService {
2685
2723
  this.redrawAllRegions();
2686
2724
  });
2687
2725
  }
2726
+ get playState() {
2727
+ return this.timelineStateService.playState;
2728
+ }
2729
+ set playState(playState) {
2730
+ this.timelineStateService.playState = playState;
2731
+ }
2732
+ get selectedComposition() {
2733
+ return this.timelineStateService.selectedComposition;
2734
+ }
2735
+ set selectedComposition(selectedComposition) {
2736
+ this.timelineStateService.selectedComposition = selectedComposition;
2737
+ }
2738
+ get selectedCompositionIndex() {
2739
+ return this.timelineStateService.selectedCompositionIndex;
2740
+ }
2741
+ set selectedCompositionIndex(selectedCompositionIndex) {
2742
+ this.timelineStateService.selectedCompositionIndex = selectedCompositionIndex;
2743
+ }
2688
2744
  redrawAllRegions() {
2689
2745
  // remove all regions from wavesurver
2690
2746
  if (this.waveSurfer) {
@@ -2837,7 +2893,7 @@ class TimelineService {
2837
2893
  return 2;
2838
2894
  }
2839
2895
  }
2840
- seeekWithTimeline(e) {
2896
+ seekWithTimeline(e) {
2841
2897
  // taken from wavesurfer -> drawer -> handleEvent
2842
2898
  const clientX = e.targetTouches ? e.targetTouches[0].clientX : e.clientX;
2843
2899
  const bbox = this.waveSurfer.timeline.wrapper.getBoundingClientRect();
@@ -2862,6 +2918,7 @@ class TimelineService {
2862
2918
  setTimeout(() => {
2863
2919
  this.waveSurfer.seekTo(progress);
2864
2920
  this.detectChanges.next();
2921
+ this.livePreviewService.previewLive(this.selectedComposition.name, Math.round(progress * this.waveSurfer.backend.getDuration() * 1000));
2865
2922
  }, 0);
2866
2923
  }
2867
2924
  applyZoom(zoom) {
@@ -2925,7 +2982,7 @@ class TimelineService {
2925
2982
  else {
2926
2983
  this.drawRegion(scenePlaybackRegion, this.sceneService.selectedScenes[0]);
2927
2984
  }
2928
- this.presetService.previewLive();
2985
+ this.livePreviewService.previewLive();
2929
2986
  }
2930
2987
  getSnapToGridInterval() {
2931
2988
  if (this.selectedComposition.snapToGrid) {
@@ -3063,11 +3120,11 @@ class TimelineService {
3063
3120
  // seek on timeline-click
3064
3121
  this.waveSurfer.timeline.wrapper.addEventListener('mousedown', (e) => {
3065
3122
  this.timelineClicking = true;
3066
- this.seeekWithTimeline(e);
3123
+ this.seekWithTimeline(e);
3067
3124
  });
3068
3125
  this.waveSurfer.timeline.wrapper.addEventListener('mousemove', (e) => {
3069
3126
  if (this.timelineClicking) {
3070
- this.seeekWithTimeline(e);
3127
+ this.seekWithTimeline(e);
3071
3128
  }
3072
3129
  });
3073
3130
  this.waveSurfer.timeline.wrapper.addEventListener('mouseup', (e) => {
@@ -3107,7 +3164,7 @@ class TimelineService {
3107
3164
  });
3108
3165
  this.waveSurfer.on('region-updated', (region) => {
3109
3166
  this.detectChanges.next();
3110
- this.presetService.previewLive();
3167
+ this.livePreviewService.previewLive();
3111
3168
  });
3112
3169
  }, 0);
3113
3170
  }
@@ -3266,7 +3323,7 @@ class TimelineService {
3266
3323
  return;
3267
3324
  }
3268
3325
  }
3269
- this.presetService.previewLive();
3326
+ this.livePreviewService.previewLive();
3270
3327
  }
3271
3328
  getPresetsInTime(timeMillis) {
3272
3329
  // Return all presets which should be active during the specified time
@@ -3352,7 +3409,7 @@ class TimelineService {
3352
3409
  this.waveSurferReady.next();
3353
3410
  this.applyZoom(0);
3354
3411
  }
3355
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TimelineService, deps: [{ token: SceneService }, { token: PresetService }, { token: ProjectService }, { token: i1.HttpClient }, { token: ConfigService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); }
3412
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TimelineService, deps: [{ token: SceneService }, { token: PresetService }, { token: ProjectService }, { token: i1.HttpClient }, { token: ConfigService }, { token: i0.NgZone }, { token: TimelineStateService }, { token: LivePreviewService }], target: i0.ɵɵFactoryTarget.Injectable }); }
3356
3413
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TimelineService, providedIn: 'root' }); }
3357
3414
  }
3358
3415
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TimelineService, decorators: [{
@@ -3360,7 +3417,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
3360
3417
  args: [{
3361
3418
  providedIn: 'root',
3362
3419
  }]
3363
- }], ctorParameters: () => [{ type: SceneService }, { type: PresetService }, { type: ProjectService }, { type: i1.HttpClient }, { type: ConfigService }, { type: i0.NgZone }] });
3420
+ }], ctorParameters: () => [{ type: SceneService }, { type: PresetService }, { type: ProjectService }, { type: i1.HttpClient }, { type: ConfigService }, { type: i0.NgZone }, { type: TimelineStateService }, { type: LivePreviewService }] });
3364
3421
 
3365
3422
  class PreviewService {
3366
3423
  constructor(presetService, fixtureService, sceneService, timelineService, projectService) {
@@ -3748,6 +3805,7 @@ class PreviewService {
3748
3805
  return false;
3749
3806
  }
3750
3807
  updateFixtureSetup() {
3808
+ this.stageAndPositionsDirty = true;
3751
3809
  this.doUpdateFixtureSetup.next();
3752
3810
  }
3753
3811
  prepareStageMesh(mesh) {
@@ -4127,14 +4185,21 @@ class ColorChanger3d extends Fixture3d {
4127
4185
  this.fixtureService = fixtureService;
4128
4186
  this.previewService = previewService;
4129
4187
  this.objectGroup = new THREE.Object3D();
4188
+ this.destroyed = false;
4130
4189
  forkJoin([previewMeshService.getMesh('color-changer')])
4131
4190
  .pipe(map(([colorChanger]) => {
4191
+ if (this.destroyed) {
4192
+ return;
4193
+ }
4132
4194
  this.mesh = colorChanger;
4133
4195
  this.createObjects();
4134
4196
  }))
4135
4197
  .subscribe();
4136
4198
  }
4137
4199
  createObjects() {
4200
+ if (this.destroyed) {
4201
+ return;
4202
+ }
4138
4203
  super.createObjects();
4139
4204
  this.mesh.material = this.previewService.fixtureMaterial;
4140
4205
  if (this.hasSpotLight) {
@@ -4173,24 +4238,31 @@ class ColorChanger3d extends Fixture3d {
4173
4238
  }
4174
4239
  }
4175
4240
  destroy() {
4176
- this.scene.remove(this.objectGroup);
4241
+ this.destroyed = true;
4242
+ if (this.objectGroup.parent) {
4243
+ this.objectGroup.parent.remove(this.objectGroup);
4244
+ }
4177
4245
  }
4178
4246
  }
4179
4247
 
4180
4248
  class MovingHead3d extends Fixture3d {
4181
4249
  constructor(fixtureService, previewService, previewMeshService, fixture, scene, fixtureGroup) {
4182
- super(fixtureService, previewService, fixture, scene, fixtureGroup, true, true);
4250
+ super(fixtureService, previewService, fixture, scene, fixtureGroup, true, false);
4183
4251
  this.fixtureService = fixtureService;
4184
4252
  this.previewService = previewService;
4185
4253
  this.headGroup = new THREE.Object3D();
4186
4254
  this.armGroup = new THREE.Object3D();
4187
4255
  this.objectGroup = new THREE.Object3D();
4256
+ this.destroyed = false;
4188
4257
  forkJoin([
4189
4258
  previewMeshService.getMesh('moving_head_socket'),
4190
4259
  previewMeshService.getMesh('moving_head_arm'),
4191
4260
  previewMeshService.getMesh('moving_head_head'),
4192
4261
  ])
4193
4262
  .pipe(map(([socket, arm, head]) => {
4263
+ if (this.destroyed) {
4264
+ return;
4265
+ }
4194
4266
  this.socket = socket;
4195
4267
  this.arm = arm;
4196
4268
  this.head = head;
@@ -4199,6 +4271,9 @@ class MovingHead3d extends Fixture3d {
4199
4271
  .subscribe();
4200
4272
  }
4201
4273
  createObjects() {
4274
+ if (this.destroyed) {
4275
+ return;
4276
+ }
4202
4277
  super.createObjects();
4203
4278
  this.socket.material = this.previewService.fixtureMaterial;
4204
4279
  this.arm.material = this.previewService.fixtureMaterial;
@@ -4289,7 +4364,10 @@ class MovingHead3d extends Fixture3d {
4289
4364
  }
4290
4365
  }
4291
4366
  destroy() {
4292
- this.scene.remove(this.objectGroup);
4367
+ this.destroyed = true;
4368
+ if (this.objectGroup.parent) {
4369
+ this.objectGroup.parent.remove(this.objectGroup);
4370
+ }
4293
4371
  }
4294
4372
  }
4295
4373
 
@@ -4322,6 +4400,9 @@ class PreviewComponent {
4322
4400
  }
4323
4401
  this.fixtures3d = [];
4324
4402
  // destroy all groups
4403
+ for (const fixtureGroup of this.fixtureGroups.values()) {
4404
+ this.scene.remove(fixtureGroup);
4405
+ }
4325
4406
  this.fixtureGroups.clear();
4326
4407
  // add all fixtures from the project
4327
4408
  const fixture3dMap = {
@@ -4521,7 +4602,7 @@ class WaitDialogComponent {
4521
4602
  constructor() { }
4522
4603
  ngOnInit() { }
4523
4604
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: WaitDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4524
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: WaitDialogComponent, isStandalone: false, selector: "lib-wait-dialog", ngImport: i0, template: "<div class=\"card-modal\">\n <div class=\"card\">\n <div class=\"card-body\">\n <p class=\"card-text\">{{ 'designer.misc.please-wait' | translate }}</p>\n <div class=\"progress\">\n <div\n class=\"progress-bar progress-bar-striped progress-bar-animated\"\n role=\"progressbar\"\n style=\"width: 100%\"\n aria-valuenow=\"10\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n ></div>\n </div>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
4605
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: WaitDialogComponent, isStandalone: false, selector: "lib-wait-dialog", ngImport: i0, template: "<div class=\"card-modal\">\n <div class=\"card\">\n <div class=\"card-body\">\n <p class=\"card-text\">{{ 'designer.misc.please-wait' | translate }}</p>\n <div class=\"progress\">\n <div\n class=\"progress-bar progress-bar-striped progress-bar-animated\"\n role=\"progressbar\"\n style=\"width: 100%\"\n aria-valuenow=\"10\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n ></div>\n </div>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
4525
4606
  }
4526
4607
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: WaitDialogComponent, decorators: [{
4527
4608
  type: Component,
@@ -4547,7 +4628,7 @@ class WarningDialogComponent {
4547
4628
  this.ok();
4548
4629
  }
4549
4630
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: WarningDialogComponent, deps: [{ token: i1$1.BsModalRef }], target: i0.ɵɵFactoryTarget.Component }); }
4550
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: WarningDialogComponent, isStandalone: false, selector: "lib-app-warning-dialog", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"card-modal\">\n <div class=\"card\">\n <div class=\"card-header\">\n {{ 'designer.misc.warning' | translate }}\n </div>\n\n <div class=\"card-body\">\n <div class=\"row\">\n <div class=\"col-auto\">\n <h2 class=\"mb-0\">\n <i class=\"fa fa-exclamation-triangle text-primary\" aria-hidden=\"true\"></i>\n </h2>\n </div>\n <div class=\"col pl-0\">\n <p class=\"mb-0\">{{ message }}</p>\n </div>\n </div>\n </div>\n\n <div class=\"card-footer\">\n <div class=\"d-flex float-right\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"ok(); (false)\">\n {{ 'designer.misc.ok' | translate }}\n </button>\n </div>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
4631
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: WarningDialogComponent, isStandalone: false, selector: "lib-app-warning-dialog", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"card-modal\">\n <div class=\"card\">\n <div class=\"card-header\">\n {{ 'designer.misc.warning' | translate }}\n </div>\n\n <div class=\"card-body\">\n <div class=\"row\">\n <div class=\"col-auto\">\n <h2 class=\"mb-0\">\n <i class=\"fa fa-exclamation-triangle text-primary\" aria-hidden=\"true\"></i>\n </h2>\n </div>\n <div class=\"col pl-0\">\n <p class=\"mb-0\">{{ message }}</p>\n </div>\n </div>\n </div>\n\n <div class=\"card-footer\">\n <div class=\"d-flex float-right\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"ok(); (false)\">\n {{ 'designer.misc.ok' | translate }}\n </button>\n </div>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
4551
4632
  }
4552
4633
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: WarningDialogComponent, decorators: [{
4553
4634
  type: Component,
@@ -4577,7 +4658,7 @@ class WarningDialogService {
4577
4658
  }));
4578
4659
  }));
4579
4660
  }
4580
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: WarningDialogService, deps: [{ token: i1$1.BsModalService }, { token: i4.TranslateService }], target: i0.ɵɵFactoryTarget.Injectable }); }
4661
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: WarningDialogService, deps: [{ token: i1$1.BsModalService }, { token: i2.TranslateService }], target: i0.ɵɵFactoryTarget.Injectable }); }
4581
4662
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: WarningDialogService, providedIn: 'root' }); }
4582
4663
  }
4583
4664
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: WarningDialogService, decorators: [{
@@ -4585,10 +4666,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
4585
4666
  args: [{
4586
4667
  providedIn: 'root',
4587
4668
  }]
4588
- }], ctorParameters: () => [{ type: i1$1.BsModalService }, { type: i4.TranslateService }] });
4669
+ }], ctorParameters: () => [{ type: i1$1.BsModalService }, { type: i2.TranslateService }] });
4589
4670
 
4590
4671
  class ProjectLoadService {
4591
- constructor(projectService, previewService, fixtureService, presetService, sceneService, modalService, uuidService, timelineService, router, activatedRoute, warningDialogService) {
4672
+ constructor(projectService, previewService, fixtureService, presetService, sceneService, modalService, uuidService, timelineService, router, activatedRoute, warningDialogService, livePreviewService) {
4592
4673
  this.projectService = projectService;
4593
4674
  this.previewService = previewService;
4594
4675
  this.fixtureService = fixtureService;
@@ -4600,6 +4681,7 @@ class ProjectLoadService {
4600
4681
  this.router = router;
4601
4682
  this.activatedRoute = activatedRoute;
4602
4683
  this.warningDialogService = warningDialogService;
4684
+ this.livePreviewService = livePreviewService;
4603
4685
  }
4604
4686
  migrateToVersion2() {
4605
4687
  for (let fixture of this.projectService.project.fixtures) {
@@ -4655,7 +4737,7 @@ class ProjectLoadService {
4655
4737
  this.presetService.fixtureSelectionChanged.next();
4656
4738
  this.presetService.autoOpenFirstEffect();
4657
4739
  this.previewService.updateStage();
4658
- this.presetService.previewLive();
4740
+ this.livePreviewService.previewLive();
4659
4741
  this.sceneService.selectPresetFromSelectedScene();
4660
4742
  }
4661
4743
  selectScenesPresetComposition() {
@@ -4756,7 +4838,7 @@ class ProjectLoadService {
4756
4838
  this.selectScenesPresetComposition();
4757
4839
  this.afterLoad();
4758
4840
  }
4759
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProjectLoadService, deps: [{ token: ProjectService }, { token: PreviewService }, { token: FixtureService }, { token: PresetService }, { token: SceneService }, { token: i1$1.BsModalService }, { token: UuidService }, { token: TimelineService }, { token: i3.Router }, { token: i3.ActivatedRoute }, { token: WarningDialogService }], target: i0.ɵɵFactoryTarget.Injectable }); }
4841
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProjectLoadService, deps: [{ token: ProjectService }, { token: PreviewService }, { token: FixtureService }, { token: PresetService }, { token: SceneService }, { token: i1$1.BsModalService }, { token: UuidService }, { token: TimelineService }, { token: i3.Router }, { token: i3.ActivatedRoute }, { token: WarningDialogService }, { token: LivePreviewService }], target: i0.ɵɵFactoryTarget.Injectable }); }
4760
4842
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProjectLoadService, providedIn: 'root' }); }
4761
4843
  }
4762
4844
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProjectLoadService, decorators: [{
@@ -4764,7 +4846,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
4764
4846
  args: [{
4765
4847
  providedIn: 'root',
4766
4848
  }]
4767
- }], ctorParameters: () => [{ type: ProjectService }, { type: PreviewService }, { type: FixtureService }, { type: PresetService }, { type: SceneService }, { type: i1$1.BsModalService }, { type: UuidService }, { type: TimelineService }, { type: i3.Router }, { type: i3.ActivatedRoute }, { type: WarningDialogService }] });
4849
+ }], ctorParameters: () => [{ type: ProjectService }, { type: PreviewService }, { type: FixtureService }, { type: PresetService }, { type: SceneService }, { type: i1$1.BsModalService }, { type: UuidService }, { type: TimelineService }, { type: i3.Router }, { type: i3.ActivatedRoute }, { type: WarningDialogService }, { type: LivePreviewService }] });
4768
4850
 
4769
4851
  class ArraySortPipe {
4770
4852
  transform(array, field) {
@@ -4836,7 +4918,7 @@ class ProjectBrowserComponent {
4836
4918
  .subscribe();
4837
4919
  }
4838
4920
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProjectBrowserComponent, deps: [{ token: i1$1.BsModalRef }, { token: ProjectService }, { token: ProjectLoadService }, { token: UserService }, { token: WarningDialogService }, { token: ConfigService }], target: i0.ɵɵFactoryTarget.Component }); }
4839
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: ProjectBrowserComponent, isStandalone: false, selector: "lib-project-browser", ngImport: i0, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ 'designer.project.browser-title' | translate }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"cancel(); (false)\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body p-0\">\n @if (loading) {\n <div class=\"m-2 d-flex w-100\">\n <p class=\"w-100\" style=\"text-align: center\"><i class=\"fa fa-spinner fa-pulse fa-fw\"></i></p>\n </div>\n } @if (projects.length == 0 && !loading) {\n <div class=\"m-2 d-flex w-100\">\n <p class=\"w-100\" style=\"text-align: center\">\n {{ 'designer.project.browser-empty' | translate }}\n </p>\n </div>\n } @if (!loading) {\n <div class=\"list-group list-group-flush\" style=\"max-height: 500px; overflow-y: scroll\">\n @for (project of projects | sort: 'name'; track project) {\n <div class=\"list-group-item\">\n <div class=\"row\">\n <div class=\"col-auto my-auto flex-grow\">\n <a href=\"#\" (click)=\"openProject(project); (false)\">\n <p class=\"mb-0 w-100\">{{ project.name }}</p>\n </a>\n </div>\n <div class=\"my-auto\">\n <div class=\"col-auto my-auto pl-0 text-danger float-right\" style=\"cursor: pointer\" (click)=\"deleteProject(project); (false)\">\n <i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n</div>\n<div class=\"modal-footer\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button (click)=\"cancel(); (false)\" type=\"button\" class=\"btn btn-primary\">{{ 'designer.misc.ok' | translate }}</button>\n</div>\n", styles: [""], dependencies: [{ kind: "pipe", type: i4.TranslatePipe, name: "translate" }, { kind: "pipe", type: ArraySortPipe, name: "sort" }] }); }
4921
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: ProjectBrowserComponent, isStandalone: false, selector: "lib-project-browser", ngImport: i0, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ 'designer.project.browser-title' | translate }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"cancel(); (false)\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body p-0\">\n @if (loading) {\n <div class=\"m-2 d-flex w-100\">\n <p class=\"w-100\" style=\"text-align: center\"><i class=\"fa fa-spinner fa-pulse fa-fw\"></i></p>\n </div>\n } @if (projects.length == 0 && !loading) {\n <div class=\"m-2 d-flex w-100\">\n <p class=\"w-100\" style=\"text-align: center\">\n {{ 'designer.project.browser-empty' | translate }}\n </p>\n </div>\n } @if (!loading) {\n <div class=\"list-group list-group-flush\" style=\"max-height: 500px; overflow-y: scroll\">\n @for (project of projects | sort: 'name'; track project) {\n <div class=\"list-group-item\">\n <div class=\"row\">\n <div class=\"col-auto my-auto flex-grow\">\n <a href=\"#\" (click)=\"openProject(project); (false)\">\n <p class=\"mb-0 w-100\">{{ project.name }}</p>\n </a>\n </div>\n <div class=\"my-auto\">\n <div class=\"col-auto my-auto pl-0 text-danger float-right\" style=\"cursor: pointer\" (click)=\"deleteProject(project); (false)\">\n <i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n</div>\n<div class=\"modal-footer\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button (click)=\"cancel(); (false)\" type=\"button\" class=\"btn btn-primary\">{{ 'designer.misc.ok' | translate }}</button>\n</div>\n", styles: [""], dependencies: [{ kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "pipe", type: ArraySortPipe, name: "sort" }] }); }
4840
4922
  }
4841
4923
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProjectBrowserComponent, decorators: [{
4842
4924
  type: Component,
@@ -4899,13 +4981,13 @@ class ProjectImportComponent {
4899
4981
  handleKeyboardEvent(event) {
4900
4982
  this.ok();
4901
4983
  }
4902
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProjectImportComponent, deps: [{ token: i1$1.BsModalRef }, { token: i4.TranslateService }, { token: i3$1.ToastrService }, { token: ProjectLoadService }], target: i0.ɵɵFactoryTarget.Component }); }
4903
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: ProjectImportComponent, isStandalone: false, selector: "lib-project-import", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ 'designer.project.import-title' | translate }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"bsModalRef.hide()\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <!-- Dropzone -->\n <dropzone [config]=\"dropzoneConfig\" [useDropzoneClass]=\"'false'\" [message]=\"uploadMessage\" (error)=\"onUploadError($event)\"></dropzone>\n</div>\n<div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"ok()\">{{ 'designer.misc.ok' | translate }}</button>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: i5.DropzoneComponent, selector: "dropzone", inputs: ["disabled", "config", "message", "placeholder", "useDropzoneClass"], outputs: ["init", "error", "success", "sending", "canceled", "complete", "processing", "drop", "dragStart", "dragEnd", "dragEnter", "dragOver", "dragLeave", "thumbnail", "addedFile", "addedFiles", "removedFile", "uploadProgress", "maxFilesReached", "maxFilesExceeded", "errorMultiple", "successMultiple", "sendingMultiple", "canceledMultiple", "completeMultiple", "processingMultiple", "reset", "queueComplete", "totalUploadProgress"], exportAs: ["ngxDropzone"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
4984
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProjectImportComponent, deps: [{ token: i1$1.BsModalRef }, { token: i2.TranslateService }, { token: i3$1.ToastrService }, { token: ProjectLoadService }], target: i0.ɵɵFactoryTarget.Component }); }
4985
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: ProjectImportComponent, isStandalone: false, selector: "lib-project-import", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ 'designer.project.import-title' | translate }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"bsModalRef.hide()\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <!-- Dropzone -->\n <dropzone [config]=\"dropzoneConfig\" [useDropzoneClass]=\"'false'\" [message]=\"uploadMessage\" (error)=\"onUploadError($event)\"></dropzone>\n</div>\n<div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"ok()\">{{ 'designer.misc.ok' | translate }}</button>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: i5.DropzoneComponent, selector: "dropzone", inputs: ["disabled", "config", "message", "placeholder", "useDropzoneClass"], outputs: ["init", "error", "success", "sending", "canceled", "complete", "processing", "drop", "dragStart", "dragEnd", "dragEnter", "dragOver", "dragLeave", "thumbnail", "addedFile", "addedFiles", "removedFile", "uploadProgress", "maxFilesReached", "maxFilesExceeded", "errorMultiple", "successMultiple", "sendingMultiple", "canceledMultiple", "completeMultiple", "processingMultiple", "reset", "queueComplete", "totalUploadProgress"], exportAs: ["ngxDropzone"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
4904
4986
  }
4905
4987
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProjectImportComponent, decorators: [{
4906
4988
  type: Component,
4907
4989
  args: [{ selector: 'lib-project-import', standalone: false, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ 'designer.project.import-title' | translate }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"bsModalRef.hide()\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <!-- Dropzone -->\n <dropzone [config]=\"dropzoneConfig\" [useDropzoneClass]=\"'false'\" [message]=\"uploadMessage\" (error)=\"onUploadError($event)\"></dropzone>\n</div>\n<div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"ok()\">{{ 'designer.misc.ok' | translate }}</button>\n</div>\n" }]
4908
- }], ctorParameters: () => [{ type: i1$1.BsModalRef }, { type: i4.TranslateService }, { type: i3$1.ToastrService }, { type: ProjectLoadService }], propDecorators: { handleKeyboardEvent: [{
4990
+ }], ctorParameters: () => [{ type: i1$1.BsModalRef }, { type: i2.TranslateService }, { type: i3$1.ToastrService }, { type: ProjectLoadService }], propDecorators: { handleKeyboardEvent: [{
4909
4991
  type: HostListener,
4910
4992
  args: ['document:keydown.enter', ['$event']]
4911
4993
  }] } });
@@ -4983,7 +5065,7 @@ class ProjectSaveComponent {
4983
5065
  this.saveProject();
4984
5066
  }
4985
5067
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProjectSaveComponent, deps: [{ token: i1$1.BsModalRef }, { token: ProjectService }, { token: WarningDialogService }, { token: ConfigService }], target: i0.ɵɵFactoryTarget.Component }); }
4986
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: ProjectSaveComponent, isStandalone: false, selector: "lib-project-save", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ 'designer.project.save-title' | translate }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"cancel(); (false)\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body p-0\">\n <!-- The name of the current project -->\n <div class=\"form-group row p-3 mb-0\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.project.name' | translate }}</label>\n <div class=\"col-lg-8\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"projectName\" (ngModelChange)=\"projectName = $event\" />\n </div>\n </div>\n\n <!-- List existing projects -->\n @if (loading) {\n <div class=\"m-2 d-flex w-100\">\n <p class=\"w-100\" style=\"text-align: center\"><i class=\"fa fa-spinner fa-pulse fa-fw\"></i></p>\n </div>\n } @if (!loading) {\n <div class=\"list-group list-group-flush\" style=\"max-height: 500px; overflow-y: scroll\">\n @for (project of projects | sort: 'name'; track project) {\n <div class=\"list-group-item\">\n <div class=\"row\">\n <div class=\"col-auto my-auto flex-grow\">\n <a href=\"#\" (click)=\"selectProject(project); (false)\">\n <p class=\"mb-0 w-100\">{{ project.name }}</p>\n </a>\n </div>\n <div class=\"my-auto\">\n <div class=\"col-auto my-auto pl-0 text-danger float-right\" style=\"cursor: pointer\" (click)=\"deleteProject(project); (false)\">\n <i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n</div>\n<div class=\"modal-footer\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button [disabled]=\"loading || !projectName\" (click)=\"saveProject(); (false)\" type=\"button\" class=\"btn btn-primary\">\n {{ 'designer.misc.ok' | translate }}\n </button>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }, { kind: "pipe", type: ArraySortPipe, name: "sort" }] }); }
5068
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: ProjectSaveComponent, isStandalone: false, selector: "lib-project-save", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ 'designer.project.save-title' | translate }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"cancel(); (false)\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body p-0\">\n <!-- The name of the current project -->\n <div class=\"form-group row p-3 mb-0\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.project.name' | translate }}</label>\n <div class=\"col-lg-8\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"projectName\" (ngModelChange)=\"projectName = $event\" />\n </div>\n </div>\n\n <!-- List existing projects -->\n @if (loading) {\n <div class=\"m-2 d-flex w-100\">\n <p class=\"w-100\" style=\"text-align: center\"><i class=\"fa fa-spinner fa-pulse fa-fw\"></i></p>\n </div>\n } @if (!loading) {\n <div class=\"list-group list-group-flush\" style=\"max-height: 500px; overflow-y: scroll\">\n @for (project of projects | sort: 'name'; track project) {\n <div class=\"list-group-item\">\n <div class=\"row\">\n <div class=\"col-auto my-auto flex-grow\">\n <a href=\"#\" (click)=\"selectProject(project); (false)\">\n <p class=\"mb-0 w-100\">{{ project.name }}</p>\n </a>\n </div>\n <div class=\"my-auto\">\n <div class=\"col-auto my-auto pl-0 text-danger float-right\" style=\"cursor: pointer\" (click)=\"deleteProject(project); (false)\">\n <i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n</div>\n<div class=\"modal-footer\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button [disabled]=\"loading || !projectName\" (click)=\"saveProject(); (false)\" type=\"button\" class=\"btn btn-primary\">\n {{ 'designer.misc.ok' | translate }}\n </button>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "pipe", type: ArraySortPipe, name: "sort" }] }); }
4987
5069
  }
4988
5070
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProjectSaveComponent, decorators: [{
4989
5071
  type: Component,
@@ -5012,7 +5094,7 @@ class ProjectShareComponent {
5012
5094
  this.ok();
5013
5095
  }
5014
5096
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProjectShareComponent, deps: [{ token: i1$1.BsModalRef }, { token: ProjectService }], target: i0.ɵɵFactoryTarget.Component }); }
5015
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: ProjectShareComponent, isStandalone: false, selector: "lib-project-share", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ 'designer.project.share-title' | translate }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"bsModalRef.hide()\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.project.share-link' | translate }}</label>\n <div class=\"col-lg-8 d-flex\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"shareLink\" readonly />\n </div>\n </div>\n</div>\n<div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"ok()\">{{ 'designer.misc.ok' | translate }}</button>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
5097
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: ProjectShareComponent, isStandalone: false, selector: "lib-project-share", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ 'designer.project.share-title' | translate }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"bsModalRef.hide()\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.project.share-link' | translate }}</label>\n <div class=\"col-lg-8 d-flex\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"shareLink\" readonly />\n </div>\n </div>\n</div>\n<div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"ok()\">{{ 'designer.misc.ok' | translate }}</button>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
5016
5098
  }
5017
5099
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProjectShareComponent, decorators: [{
5018
5100
  type: Component,
@@ -5041,7 +5123,7 @@ class ErrorDialogComponent {
5041
5123
  this.ok();
5042
5124
  }
5043
5125
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ErrorDialogComponent, deps: [{ token: i1$1.BsModalRef }], target: i0.ɵɵFactoryTarget.Component }); }
5044
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: ErrorDialogComponent, isStandalone: false, selector: "lib-error-dialog", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"card-modal\">\n <div class=\"card\">\n <div class=\"card-header\">\n {{ 'designer.misc.error' | translate }}\n </div>\n\n <div class=\"card-body\">\n <div class=\"row\">\n <div class=\"col-auto\">\n <h2 class=\"mb-0\">\n <i class=\"fa fa-exclamation-circle text-danger\" aria-hidden=\"true\"></i>\n </h2>\n </div>\n <div class=\"col pl-0\">\n <p class=\"mb-0\">{{ message }}</p>\n @if (details) {\n <p class=\"mt-1 mb-0\">({{ details }})</p>\n }\n </div>\n </div>\n </div>\n\n <div class=\"card-footer\">\n <div class=\"d-flex float-right\">\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"ok(); (false)\">\n {{ 'designer.misc.ok' | translate }}\n </button>\n </div>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
5126
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: ErrorDialogComponent, isStandalone: false, selector: "lib-error-dialog", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"card-modal\">\n <div class=\"card\">\n <div class=\"card-header\">\n {{ 'designer.misc.error' | translate }}\n </div>\n\n <div class=\"card-body\">\n <div class=\"row\">\n <div class=\"col-auto\">\n <h2 class=\"mb-0\">\n <i class=\"fa fa-exclamation-circle text-danger\" aria-hidden=\"true\"></i>\n </h2>\n </div>\n <div class=\"col pl-0\">\n <p class=\"mb-0\">{{ message }}</p>\n @if (details) {\n <p class=\"mt-1 mb-0\">({{ details }})</p>\n }\n </div>\n </div>\n </div>\n\n <div class=\"card-footer\">\n <div class=\"d-flex float-right\">\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"ok(); (false)\">\n {{ 'designer.misc.ok' | translate }}\n </button>\n </div>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
5045
5127
  }
5046
5128
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ErrorDialogComponent, decorators: [{
5047
5129
  type: Component,
@@ -5072,7 +5154,7 @@ class ErrorDialogService {
5072
5154
  }));
5073
5155
  }));
5074
5156
  }
5075
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ErrorDialogService, deps: [{ token: i1$1.BsModalService }, { token: i4.TranslateService }], target: i0.ɵɵFactoryTarget.Injectable }); }
5157
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ErrorDialogService, deps: [{ token: i1$1.BsModalService }, { token: i2.TranslateService }], target: i0.ɵɵFactoryTarget.Injectable }); }
5076
5158
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ErrorDialogService, providedIn: 'root' }); }
5077
5159
  }
5078
5160
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ErrorDialogService, decorators: [{
@@ -5080,7 +5162,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
5080
5162
  args: [{
5081
5163
  providedIn: 'root',
5082
5164
  }]
5083
- }], ctorParameters: () => [{ type: i1$1.BsModalService }, { type: i4.TranslateService }] });
5165
+ }], ctorParameters: () => [{ type: i1$1.BsModalService }, { type: i2.TranslateService }] });
5084
5166
 
5085
5167
  class FixturePoolCreateFromFileComponent {
5086
5168
  constructor(bsModalRef, translateService, toastrService, fixtureService, projectService) {
@@ -5172,13 +5254,13 @@ class FixturePoolCreateFromFileComponent {
5172
5254
  handleKeyboardEvent(event) {
5173
5255
  this.ok();
5174
5256
  }
5175
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixturePoolCreateFromFileComponent, deps: [{ token: i1$1.BsModalRef }, { token: i4.TranslateService }, { token: i3$1.ToastrService }, { token: FixtureService }, { token: ProjectService }], target: i0.ɵɵFactoryTarget.Component }); }
5176
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: FixturePoolCreateFromFileComponent, isStandalone: false, selector: "lib-fixture-pool-create-from-file", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ 'designer.fixture-pool.create-fixture-from-profile-file-dialog-title' | translate }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"bsModalRef.hide()\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <!-- Dropzone -->\n <dropzone [config]=\"dropzoneConfig\" [useDropzoneClass]=\"'false'\" [message]=\"uploadMessage\" (error)=\"onUploadError($event)\"></dropzone>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"ok()\">{{ 'designer.misc.ok' | translate }}</button>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: i5.DropzoneComponent, selector: "dropzone", inputs: ["disabled", "config", "message", "placeholder", "useDropzoneClass"], outputs: ["init", "error", "success", "sending", "canceled", "complete", "processing", "drop", "dragStart", "dragEnd", "dragEnter", "dragOver", "dragLeave", "thumbnail", "addedFile", "addedFiles", "removedFile", "uploadProgress", "maxFilesReached", "maxFilesExceeded", "errorMultiple", "successMultiple", "sendingMultiple", "canceledMultiple", "completeMultiple", "processingMultiple", "reset", "queueComplete", "totalUploadProgress"], exportAs: ["ngxDropzone"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
5257
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixturePoolCreateFromFileComponent, deps: [{ token: i1$1.BsModalRef }, { token: i2.TranslateService }, { token: i3$1.ToastrService }, { token: FixtureService }, { token: ProjectService }], target: i0.ɵɵFactoryTarget.Component }); }
5258
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: FixturePoolCreateFromFileComponent, isStandalone: false, selector: "lib-fixture-pool-create-from-file", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ 'designer.fixture-pool.create-fixture-from-profile-file-dialog-title' | translate }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"bsModalRef.hide()\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <!-- Dropzone -->\n <dropzone [config]=\"dropzoneConfig\" [useDropzoneClass]=\"'false'\" [message]=\"uploadMessage\" (error)=\"onUploadError($event)\"></dropzone>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"ok()\">{{ 'designer.misc.ok' | translate }}</button>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: i5.DropzoneComponent, selector: "dropzone", inputs: ["disabled", "config", "message", "placeholder", "useDropzoneClass"], outputs: ["init", "error", "success", "sending", "canceled", "complete", "processing", "drop", "dragStart", "dragEnd", "dragEnter", "dragOver", "dragLeave", "thumbnail", "addedFile", "addedFiles", "removedFile", "uploadProgress", "maxFilesReached", "maxFilesExceeded", "errorMultiple", "successMultiple", "sendingMultiple", "canceledMultiple", "completeMultiple", "processingMultiple", "reset", "queueComplete", "totalUploadProgress"], exportAs: ["ngxDropzone"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
5177
5259
  }
5178
5260
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixturePoolCreateFromFileComponent, decorators: [{
5179
5261
  type: Component,
5180
5262
  args: [{ selector: 'lib-fixture-pool-create-from-file', standalone: false, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ 'designer.fixture-pool.create-fixture-from-profile-file-dialog-title' | translate }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"bsModalRef.hide()\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <!-- Dropzone -->\n <dropzone [config]=\"dropzoneConfig\" [useDropzoneClass]=\"'false'\" [message]=\"uploadMessage\" (error)=\"onUploadError($event)\"></dropzone>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"ok()\">{{ 'designer.misc.ok' | translate }}</button>\n </div>\n</div>\n" }]
5181
- }], ctorParameters: () => [{ type: i1$1.BsModalRef }, { type: i4.TranslateService }, { type: i3$1.ToastrService }, { type: FixtureService }, { type: ProjectService }], propDecorators: { handleKeyboardEvent: [{
5263
+ }], ctorParameters: () => [{ type: i1$1.BsModalRef }, { type: i2.TranslateService }, { type: i3$1.ToastrService }, { type: FixtureService }, { type: ProjectService }], propDecorators: { handleKeyboardEvent: [{
5182
5264
  type: HostListener,
5183
5265
  args: ['document:keydown.enter', ['$event']]
5184
5266
  }] } });
@@ -5294,7 +5376,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
5294
5376
  }] } });
5295
5377
 
5296
5378
  class FixturePoolComponent {
5297
- constructor(bsModalRef, fixtureService, uuidService, projectService, previewService, translateService, toastrService, presetService, configService, modalService) {
5379
+ constructor(bsModalRef, fixtureService, uuidService, projectService, previewService, translateService, toastrService, presetService, configService, modalService, livePreviewService) {
5298
5380
  this.bsModalRef = bsModalRef;
5299
5381
  this.fixtureService = fixtureService;
5300
5382
  this.uuidService = uuidService;
@@ -5305,6 +5387,7 @@ class FixturePoolComponent {
5305
5387
  this.presetService = presetService;
5306
5388
  this.configService = configService;
5307
5389
  this.modalService = modalService;
5390
+ this.livePreviewService = livePreviewService;
5308
5391
  this.loadingProfiles = false;
5309
5392
  this.dmxChannels = [];
5310
5393
  this.showChannelNumbers = false;
@@ -5588,7 +5671,7 @@ class FixturePoolComponent {
5588
5671
  this.previewService.updateFixtureSetup();
5589
5672
  this.presetService.updateFixtureSelection();
5590
5673
  this.presetService.fixtureSelectionChanged.next();
5591
- this.presetService.previewLive();
5674
+ this.livePreviewService.previewLive();
5592
5675
  this.onClose.next(1);
5593
5676
  this.bsModalRef.hide();
5594
5677
  }
@@ -5630,13 +5713,13 @@ class FixturePoolComponent {
5630
5713
  handleKeyboardEvent(event) {
5631
5714
  this.ok();
5632
5715
  }
5633
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixturePoolComponent, deps: [{ token: i1$1.BsModalRef }, { token: FixtureService }, { token: UuidService }, { token: ProjectService }, { token: PreviewService }, { token: i4.TranslateService }, { token: i3$1.ToastrService }, { token: PresetService }, { token: ConfigService }, { token: i1$1.BsModalService }], target: i0.ɵɵFactoryTarget.Component }); }
5634
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: FixturePoolComponent, isStandalone: false, selector: "lib-app-fixture-pool", host: { listeners: { "window:mouseup": "mouseUp($event)", "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ 'designer.fixture-pool.title' | translate }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"cancel(); (false)\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <div class=\"row\">\n <div class=\"col-6\">\n <!-- Search for profiles -->\n <input\n type=\"text\"\n class=\"form-control input-block mb-3\"\n id=\"searchSet\"\n placeholder=\"{{ 'designer.fixture-pool.search-profiles' | translate }}\"\n (input)=\"searchExpression = $event.target.value; filterProfiles()\"\n />\n\n <!-- Profiles -->\n <div class=\"card border-secondary w-100\" style=\"height: 200px\">\n <div class=\"card-body p-0 w-100\">\n <div class=\"list-group list-group-flush w-100\">\n @if (loadingProfiles) {\n <a class=\"list-group-item flex-column align-items-start d-flex\">\n <p class=\"mb-0 mx-auto\">\n <i class=\"fa fa-spinner fa-pulse fa-fw\"></i>\n </p>\n </a>\n } @for (profile of filteredProfiles | sort : 'uuid'; track profile) {\n <div class=\"list-group-item\">\n <div class=\"row\">\n <div class=\"col-10 col-auto my-auto pl-2\">\n <p class=\"mb-0\">\n <span class=\"icon-{{ fixtureService.getFixtureIconClass(profile) }} mr-1\"></span> {{ profile.manufacturerName }} -\n {{ profile.name }}\n </p>\n </div>\n <div class=\"col-2 my-auto\">\n <a class=\"btn btn-primary btn-sm float-right\" href=\"#\" role=\"button\" (click)=\"addFixture(profile); (false)\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i>\n </a>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n <div>\n <p class=\"d-inline-block mb-0 mt-2\">\n Powered by the <a href=\"https://open-fixture-library.org/\" target=\"_blank\">Open Fixture Library</a>\n </p>\n <a\n class=\"mt-2 btn btn-secondary btn-sm float-right\"\n href=\"https://open-fixture-library.org/fixture-editor\"\n target=\"_blank\"\n role=\"button\"\n >\n <i class=\"fa fa-file-o\" aria-hidden=\"true\"></i> {{ 'designer.fixture-pool.add-profile' | translate }}\n </a>\n @if (configService.localProfiles) {\n <button\n type=\"button\"\n class=\"mr-2 mt-2 btn btn-secondary btn-sm float-right\"\n (click)=\"updateProfiles(); (false)\"\n [disabled]=\"updatingProfiles\"\n role=\"button\"\n >\n @if (updatingProfiles) {\n <i class=\"fa fa-spinner fa-pulse fa-fw\" aria-hidden=\"true\"></i>\n } @if (!updatingProfiles) {\n <i class=\"fa fa-download fa-fw\" aria-hidden=\"true\"></i>\n }\n {{ 'designer.fixture-pool.update-profiles' | translate }}\n </button>\n }\n </div>\n </div>\n <div class=\"col-6\">\n <div class=\"row\">\n <!-- Add fixture from local profile -->\n <div class=\"col-6\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"createFixtureFromProfileFile()\" role=\"button\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i> {{ 'designer.fixture-pool.create-fixture-from-profile-file' | translate }}\n </button>\n </div>\n\n <!-- Universe -->\n <div class=\"col-6\">\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.fixture-pool.universe' | translate }}</label>\n <div class=\"col-lg-8\">\n <select class=\"custom-select\">\n <option>Universe 1</option>\n </select>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Fixtures -->\n <div class=\"card border-secondary\" style=\"height: 235px\">\n <div class=\"card-body p-0\">\n <div class=\"list-group list-group-flush\" [sortablejs]=\"fixturePool\">\n @for (fixture of fixturePool; track fixture) {\n <div\n class=\"list-group-item\"\n [class.active]=\"fixture == selectedFixture\"\n (click)=\"selectFixture(fixture)\"\n style=\"cursor: pointer\"\n >\n <div class=\"row\">\n <div class=\"col-auto list-sort-handle my-auto\" style=\"cursor: move; cursor: -webkit-grabbing\">\n <i class=\"fa fa-bars\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"col-auto flex-grow pl-0 my-auto\">\n <p class=\"mb-0\">\n <span class=\"icon-{{ fixtureService.getFixtureIconClass(fixtureService.getProfileByUuid(fixture.profileUuid)) }} mr-1\">\n </span\n >{{ fixture.name }}\n </p>\n </div>\n <div class=\"col-auto my-auto\">\n <a class=\"btn btn-primary btn-sm float-right\" href=\"#\" role=\"button\" (click)=\"removeFixture(fixture); (false)\">\n <i class=\"fa fa-minus\" aria-hidden=\"true\"></i>\n </a>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"row mt-3\">\n <div class=\"col\">\n <!-- Tab navigation -->\n <ul class=\"nav nav-tabs mb-4\" id=\"myTab\" role=\"tablist\">\n <li class=\"nav-item\">\n <a class=\"nav-link active\" id=\"sets-tab\" data-toggle=\"tab\" href=\"#dmx\" role=\"tab\">\n <i class=\"icon-ola\" aria-hidden=\"true\"></i> {{ 'designer.fixture-pool.dmx' | translate }}\n </a>\n </li>\n <li class=\"nav-item\">\n <a class=\"nav-link\" id=\"compositions-tab\" data-toggle=\"tab\" href=\"#settings\" role=\"tab\">\n <i class=\"fa fa-cog\" aria-hidden=\"true\"></i> {{ 'designer.fixture-pool.settings' | translate }}\n </a>\n </li>\n </ul>\n\n <!-- Tab content -->\n <div class=\"tab-content\" id=\"myTabContent\">\n <!-- DMX universe overview-->\n <div class=\"tab-pane show active\" id=\"dmx\" role=\"tabpanel\">\n <!-- Show all channel numbers -->\n <!-- <div class=\"form-group row\">\n <div class=\"col-auto flex-grow\"></div>\n <div class=\"col-lg-3 d-flex\">\n <div class=\"form-check my-auto ml-auto\">\n <input type=\"checkbox\" class=\"form-check-input\" id=\"showChannelNumbers\" [ngModel]=\"showChannelNumbers\"\n (ngModelChange)=\"showChannelNumbers = $event\">\n <label class=\"form-check-label\" for=\"showChannelNumbers\">Show channels</label>\n </div>\n </div>\n </div> -->\n\n <!-- List of DMX channels -->\n <div>\n @for (channel of dmxChannels; track $index; let i = $index) {\n <div\n class=\"dmx-channel\"\n [class.dmx-channel-occupied]=\"channelOccupied(i)\"\n [class.dmx-channel-occupied-start]=\"channelOccupiedStart(i)\"\n [class.dmx-channel-occupied-end]=\"channelOccupiedEnd(i)\"\n [class.dmx-channel-selected]=\"channelSelected(i)\"\n [class.dmx-channel-overlapped]=\"channelOverlapped(i)\"\n (mousedown)=\"channelMouseDown($event)\"\n (mouseover)=\"channelMouseOver($event)\"\n [attr.data-index]=\"i\"\n popover=\"{{ i + 1 }}\"\n placement=\"top\"\n triggers=\"mouseenter:mouseleave\"\n >\n <div class=\"d-flex w-100 dmx-channel-text\" [attr.data-index]=\"i\" [class.dmx-channel-text-visible]=\"showChannelNumbers\">\n <div class=\"m-auto\" style=\"font-size: 11px\" [attr.data-index]=\"i\"><small [attr.data-index]=\"i\">&nbsp;</small></div>\n </div>\n </div>\n }\n </div>\n </div>\n\n <!-- Fixture settings -->\n <div class=\"tab-pane\" id=\"settings\" role=\"tabpanel\">\n @if (selectedFixture && selectedFixtureProfile) {\n <div>\n <div class=\"form-group row\">\n <label class=\"col-lg-3 col-form-label\" for=\"fixtureName\">{{ 'designer.fixture-pool.fixture-name' | translate }}</label>\n <div class=\"col-lg-9\">\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"selectedFixture.name\" maxlength=\"200\" id=\"fixtureName\" />\n </div>\n </div>\n <div class=\"form-group row\">\n <label class=\"col-lg-3 col-form-label\">{{ 'designer.fixture-pool.mode' | translate }}</label>\n <div class=\"col-lg-9\">\n <select\n class=\"custom-select\"\n [ngModel]=\"selectedFixture.modeShortName\"\n (ngModelChange)=\"selectedFixture.modeShortName = $event\"\n >\n @for (mode of selectedFixtureProfile.modes; track mode) {\n <option [ngValue]=\"mode.shortName || mode.name\">\n {{ mode.name }}\n - {{ fixtureService.getModeChannelCount(selectedFixtureProfile, mode) }}\n {{ 'designer.fixture-pool.channels' | translate }}\n </option>\n }\n </select>\n </div>\n </div>\n <div class=\"form-group row\">\n <label class=\"col-lg-3 col-form-label\">{{ 'designer.fixture-pool.first-channel' | translate }}</label>\n <div class=\"col-lg-9\">\n <select\n class=\"custom-select\"\n [ngModel]=\"selectedFixture.dmxFirstChannel\"\n (ngModelChange)=\"selectedFixture.dmxFirstChannel = $event\"\n >\n @for (channel of dmxChannels; track $index; let i = $index) {\n <option [ngValue]=\"i\">\n {{ i + 1 }}\n </option>\n }\n </select>\n </div>\n </div>\n <div class=\"form-group row\">\n <label class=\"col-lg-3 col-form-label\"></label>\n <div class=\"col-lg-9\">\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"addCopy(selectedFixture)\">\n {{ 'designer.fixture.add-copy' | translate }}\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</div>\n<div class=\"modal-footer\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"ok()\">{{ 'designer.misc.ok' | translate }}</button>\n</div>\n", styles: [".list-group-item{padding:.3rem 1.25rem}.dmx-channel{display:flex;float:left;width:28px;border:1px solid white;margin-left:-1px;margin-bottom:-1px;padding-bottom:2px}.dmx-channel-occupied{background-color:#63462e;border-left:none;border-right:none;cursor:move}.dmx-channel-occupied-start{border-left:1px solid white;border-top-left-radius:8px;border-bottom-left-radius:8px}.dmx-channel-occupied-end{border-right:1px solid white;border-top-right-radius:8px;border-bottom-right-radius:8px}.dmx-channel-selected{background-color:#fd7e14}.dmx-channel-overlapped{background-color:red;border:1px solid red;cursor:move}.card{overflow:auto}\n"], dependencies: [{ kind: "directive", type: i3$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i11.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "directive", type: SortablejsDirective, selector: "[sortablejs]", inputs: ["sortablejs", "sortablejsContainer", "sortablejsOptions"], outputs: ["sortablejsInit"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }, { kind: "pipe", type: ArraySortPipe, name: "sort" }] }); }
5716
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixturePoolComponent, deps: [{ token: i1$1.BsModalRef }, { token: FixtureService }, { token: UuidService }, { token: ProjectService }, { token: PreviewService }, { token: i2.TranslateService }, { token: i3$1.ToastrService }, { token: PresetService }, { token: ConfigService }, { token: i1$1.BsModalService }, { token: LivePreviewService }], target: i0.ɵɵFactoryTarget.Component }); }
5717
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: FixturePoolComponent, isStandalone: false, selector: "lib-app-fixture-pool", host: { listeners: { "window:mouseup": "mouseUp($event)", "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ 'designer.fixture-pool.title' | translate }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"cancel(); (false)\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <div class=\"row\">\n <div class=\"col-6\">\n <!-- Search for profiles -->\n <input\n type=\"text\"\n class=\"form-control input-block mb-3\"\n id=\"searchSet\"\n placeholder=\"{{ 'designer.fixture-pool.search-profiles' | translate }}\"\n (input)=\"searchExpression = $event.target.value; filterProfiles()\"\n />\n\n <!-- Profiles -->\n <div class=\"card border-secondary w-100\" style=\"height: 200px\">\n <div class=\"card-body p-0 w-100\">\n <div class=\"list-group list-group-flush w-100\">\n @if (loadingProfiles) {\n <a class=\"list-group-item flex-column align-items-start d-flex\">\n <p class=\"mb-0 mx-auto\">\n <i class=\"fa fa-spinner fa-pulse fa-fw\"></i>\n </p>\n </a>\n } @for (profile of filteredProfiles | sort : 'uuid'; track profile) {\n <div class=\"list-group-item\">\n <div class=\"row\">\n <div class=\"col-10 col-auto my-auto pl-2\">\n <p class=\"mb-0\">\n <span class=\"icon-{{ fixtureService.getFixtureIconClass(profile) }} mr-1\"></span> {{ profile.manufacturerName }} -\n {{ profile.name }}\n </p>\n </div>\n <div class=\"col-2 my-auto\">\n <a class=\"btn btn-primary btn-sm float-right\" href=\"#\" role=\"button\" (click)=\"addFixture(profile); (false)\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i>\n </a>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n <div>\n <p class=\"d-inline-block mb-0 mt-2\">\n Powered by the <a href=\"https://open-fixture-library.org/\" target=\"_blank\">Open Fixture Library</a>\n </p>\n <a\n class=\"mt-2 btn btn-secondary btn-sm float-right\"\n href=\"https://open-fixture-library.org/fixture-editor\"\n target=\"_blank\"\n role=\"button\"\n >\n <i class=\"fa fa-file-o\" aria-hidden=\"true\"></i> {{ 'designer.fixture-pool.add-profile' | translate }}\n </a>\n @if (configService.localProfiles) {\n <button\n type=\"button\"\n class=\"mr-2 mt-2 btn btn-secondary btn-sm float-right\"\n (click)=\"updateProfiles(); (false)\"\n [disabled]=\"updatingProfiles\"\n role=\"button\"\n >\n @if (updatingProfiles) {\n <i class=\"fa fa-spinner fa-pulse fa-fw\" aria-hidden=\"true\"></i>\n } @if (!updatingProfiles) {\n <i class=\"fa fa-download fa-fw\" aria-hidden=\"true\"></i>\n }\n {{ 'designer.fixture-pool.update-profiles' | translate }}\n </button>\n }\n </div>\n </div>\n <div class=\"col-6\">\n <div class=\"row\">\n <!-- Add fixture from local profile -->\n <div class=\"col-6\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"createFixtureFromProfileFile()\" role=\"button\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i> {{ 'designer.fixture-pool.create-fixture-from-profile-file' | translate }}\n </button>\n </div>\n\n <!-- Universe -->\n <div class=\"col-6\">\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.fixture-pool.universe' | translate }}</label>\n <div class=\"col-lg-8\">\n <select class=\"custom-select\">\n <option>Universe 1</option>\n </select>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Fixtures -->\n <div class=\"card border-secondary\" style=\"height: 235px\">\n <div class=\"card-body p-0\">\n <div class=\"list-group list-group-flush\" [sortablejs]=\"fixturePool\">\n @for (fixture of fixturePool; track fixture) {\n <div\n class=\"list-group-item\"\n [class.active]=\"fixture == selectedFixture\"\n (click)=\"selectFixture(fixture)\"\n style=\"cursor: pointer\"\n >\n <div class=\"row\">\n <div class=\"col-auto list-sort-handle my-auto\" style=\"cursor: move; cursor: -webkit-grabbing\">\n <i class=\"fa fa-bars\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"col-auto flex-grow pl-0 my-auto\">\n <p class=\"mb-0\">\n <span class=\"icon-{{ fixtureService.getFixtureIconClass(fixtureService.getProfileByUuid(fixture.profileUuid)) }} mr-1\">\n </span\n >{{ fixture.name }}\n </p>\n </div>\n <div class=\"col-auto my-auto\">\n <a class=\"btn btn-primary btn-sm float-right\" href=\"#\" role=\"button\" (click)=\"removeFixture(fixture); (false)\">\n <i class=\"fa fa-minus\" aria-hidden=\"true\"></i>\n </a>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"row mt-3\">\n <div class=\"col\">\n <!-- Tab navigation -->\n <ul class=\"nav nav-tabs mb-4\" id=\"myTab\" role=\"tablist\">\n <li class=\"nav-item\">\n <a class=\"nav-link active\" id=\"sets-tab\" data-toggle=\"tab\" href=\"#dmx\" role=\"tab\">\n <i class=\"icon-ola\" aria-hidden=\"true\"></i> {{ 'designer.fixture-pool.dmx' | translate }}\n </a>\n </li>\n <li class=\"nav-item\">\n <a class=\"nav-link\" id=\"compositions-tab\" data-toggle=\"tab\" href=\"#settings\" role=\"tab\">\n <i class=\"fa fa-cog\" aria-hidden=\"true\"></i> {{ 'designer.fixture-pool.settings' | translate }}\n </a>\n </li>\n </ul>\n\n <!-- Tab content -->\n <div class=\"tab-content\" id=\"myTabContent\">\n <!-- DMX universe overview-->\n <div class=\"tab-pane show active\" id=\"dmx\" role=\"tabpanel\">\n <!-- Show all channel numbers -->\n <!-- <div class=\"form-group row\">\n <div class=\"col-auto flex-grow\"></div>\n <div class=\"col-lg-3 d-flex\">\n <div class=\"form-check my-auto ml-auto\">\n <input type=\"checkbox\" class=\"form-check-input\" id=\"showChannelNumbers\" [ngModel]=\"showChannelNumbers\"\n (ngModelChange)=\"showChannelNumbers = $event\">\n <label class=\"form-check-label\" for=\"showChannelNumbers\">Show channels</label>\n </div>\n </div>\n </div> -->\n\n <!-- List of DMX channels -->\n <div>\n @for (channel of dmxChannels; track $index; let i = $index) {\n <div\n class=\"dmx-channel\"\n [class.dmx-channel-occupied]=\"channelOccupied(i)\"\n [class.dmx-channel-occupied-start]=\"channelOccupiedStart(i)\"\n [class.dmx-channel-occupied-end]=\"channelOccupiedEnd(i)\"\n [class.dmx-channel-selected]=\"channelSelected(i)\"\n [class.dmx-channel-overlapped]=\"channelOverlapped(i)\"\n (mousedown)=\"channelMouseDown($event)\"\n (mouseover)=\"channelMouseOver($event)\"\n [attr.data-index]=\"i\"\n popover=\"{{ i + 1 }}\"\n placement=\"top\"\n triggers=\"mouseenter:mouseleave\"\n >\n <div class=\"d-flex w-100 dmx-channel-text\" [attr.data-index]=\"i\" [class.dmx-channel-text-visible]=\"showChannelNumbers\">\n <div class=\"m-auto\" style=\"font-size: 11px\" [attr.data-index]=\"i\"><small [attr.data-index]=\"i\">&nbsp;</small></div>\n </div>\n </div>\n }\n </div>\n </div>\n\n <!-- Fixture settings -->\n <div class=\"tab-pane\" id=\"settings\" role=\"tabpanel\">\n @if (selectedFixture && selectedFixtureProfile) {\n <div>\n <div class=\"form-group row\">\n <label class=\"col-lg-3 col-form-label\" for=\"fixtureName\">{{ 'designer.fixture-pool.fixture-name' | translate }}</label>\n <div class=\"col-lg-9\">\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"selectedFixture.name\" maxlength=\"200\" id=\"fixtureName\" />\n </div>\n </div>\n <div class=\"form-group row\">\n <label class=\"col-lg-3 col-form-label\">{{ 'designer.fixture-pool.mode' | translate }}</label>\n <div class=\"col-lg-9\">\n <select\n class=\"custom-select\"\n [ngModel]=\"selectedFixture.modeShortName\"\n (ngModelChange)=\"selectedFixture.modeShortName = $event\"\n >\n @for (mode of selectedFixtureProfile.modes; track mode) {\n <option [ngValue]=\"mode.shortName || mode.name\">\n {{ mode.name }}\n - {{ fixtureService.getModeChannelCount(selectedFixtureProfile, mode) }}\n {{ 'designer.fixture-pool.channels' | translate }}\n </option>\n }\n </select>\n </div>\n </div>\n <div class=\"form-group row\">\n <label class=\"col-lg-3 col-form-label\">{{ 'designer.fixture-pool.first-channel' | translate }}</label>\n <div class=\"col-lg-9\">\n <select\n class=\"custom-select\"\n [ngModel]=\"selectedFixture.dmxFirstChannel\"\n (ngModelChange)=\"selectedFixture.dmxFirstChannel = $event\"\n >\n @for (channel of dmxChannels; track $index; let i = $index) {\n <option [ngValue]=\"i\">\n {{ i + 1 }}\n </option>\n }\n </select>\n </div>\n </div>\n <div class=\"form-group row\">\n <label class=\"col-lg-3 col-form-label\"></label>\n <div class=\"col-lg-9\">\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"addCopy(selectedFixture)\">\n {{ 'designer.fixture.add-copy' | translate }}\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</div>\n<div class=\"modal-footer\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"ok()\">{{ 'designer.misc.ok' | translate }}</button>\n</div>\n", styles: [".list-group-item{padding:.3rem 1.25rem}.dmx-channel{display:flex;float:left;width:28px;border:1px solid white;margin-left:-1px;margin-bottom:-1px;padding-bottom:2px}.dmx-channel-occupied{background-color:#63462e;border-left:none;border-right:none;cursor:move}.dmx-channel-occupied-start{border-left:1px solid white;border-top-left-radius:8px;border-bottom-left-radius:8px}.dmx-channel-occupied-end{border-right:1px solid white;border-top-right-radius:8px;border-bottom-right-radius:8px}.dmx-channel-selected{background-color:#fd7e14}.dmx-channel-overlapped{background-color:red;border:1px solid red;cursor:move}.card{overflow:auto}\n"], dependencies: [{ kind: "directive", type: i3$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i12.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "directive", type: SortablejsDirective, selector: "[sortablejs]", inputs: ["sortablejs", "sortablejsContainer", "sortablejsOptions"], outputs: ["sortablejsInit"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "pipe", type: ArraySortPipe, name: "sort" }] }); }
5635
5718
  }
5636
5719
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixturePoolComponent, decorators: [{
5637
5720
  type: Component,
5638
5721
  args: [{ selector: 'lib-app-fixture-pool', standalone: false, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ 'designer.fixture-pool.title' | translate }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"cancel(); (false)\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <div class=\"row\">\n <div class=\"col-6\">\n <!-- Search for profiles -->\n <input\n type=\"text\"\n class=\"form-control input-block mb-3\"\n id=\"searchSet\"\n placeholder=\"{{ 'designer.fixture-pool.search-profiles' | translate }}\"\n (input)=\"searchExpression = $event.target.value; filterProfiles()\"\n />\n\n <!-- Profiles -->\n <div class=\"card border-secondary w-100\" style=\"height: 200px\">\n <div class=\"card-body p-0 w-100\">\n <div class=\"list-group list-group-flush w-100\">\n @if (loadingProfiles) {\n <a class=\"list-group-item flex-column align-items-start d-flex\">\n <p class=\"mb-0 mx-auto\">\n <i class=\"fa fa-spinner fa-pulse fa-fw\"></i>\n </p>\n </a>\n } @for (profile of filteredProfiles | sort : 'uuid'; track profile) {\n <div class=\"list-group-item\">\n <div class=\"row\">\n <div class=\"col-10 col-auto my-auto pl-2\">\n <p class=\"mb-0\">\n <span class=\"icon-{{ fixtureService.getFixtureIconClass(profile) }} mr-1\"></span> {{ profile.manufacturerName }} -\n {{ profile.name }}\n </p>\n </div>\n <div class=\"col-2 my-auto\">\n <a class=\"btn btn-primary btn-sm float-right\" href=\"#\" role=\"button\" (click)=\"addFixture(profile); (false)\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i>\n </a>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n <div>\n <p class=\"d-inline-block mb-0 mt-2\">\n Powered by the <a href=\"https://open-fixture-library.org/\" target=\"_blank\">Open Fixture Library</a>\n </p>\n <a\n class=\"mt-2 btn btn-secondary btn-sm float-right\"\n href=\"https://open-fixture-library.org/fixture-editor\"\n target=\"_blank\"\n role=\"button\"\n >\n <i class=\"fa fa-file-o\" aria-hidden=\"true\"></i> {{ 'designer.fixture-pool.add-profile' | translate }}\n </a>\n @if (configService.localProfiles) {\n <button\n type=\"button\"\n class=\"mr-2 mt-2 btn btn-secondary btn-sm float-right\"\n (click)=\"updateProfiles(); (false)\"\n [disabled]=\"updatingProfiles\"\n role=\"button\"\n >\n @if (updatingProfiles) {\n <i class=\"fa fa-spinner fa-pulse fa-fw\" aria-hidden=\"true\"></i>\n } @if (!updatingProfiles) {\n <i class=\"fa fa-download fa-fw\" aria-hidden=\"true\"></i>\n }\n {{ 'designer.fixture-pool.update-profiles' | translate }}\n </button>\n }\n </div>\n </div>\n <div class=\"col-6\">\n <div class=\"row\">\n <!-- Add fixture from local profile -->\n <div class=\"col-6\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"createFixtureFromProfileFile()\" role=\"button\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i> {{ 'designer.fixture-pool.create-fixture-from-profile-file' | translate }}\n </button>\n </div>\n\n <!-- Universe -->\n <div class=\"col-6\">\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.fixture-pool.universe' | translate }}</label>\n <div class=\"col-lg-8\">\n <select class=\"custom-select\">\n <option>Universe 1</option>\n </select>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Fixtures -->\n <div class=\"card border-secondary\" style=\"height: 235px\">\n <div class=\"card-body p-0\">\n <div class=\"list-group list-group-flush\" [sortablejs]=\"fixturePool\">\n @for (fixture of fixturePool; track fixture) {\n <div\n class=\"list-group-item\"\n [class.active]=\"fixture == selectedFixture\"\n (click)=\"selectFixture(fixture)\"\n style=\"cursor: pointer\"\n >\n <div class=\"row\">\n <div class=\"col-auto list-sort-handle my-auto\" style=\"cursor: move; cursor: -webkit-grabbing\">\n <i class=\"fa fa-bars\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"col-auto flex-grow pl-0 my-auto\">\n <p class=\"mb-0\">\n <span class=\"icon-{{ fixtureService.getFixtureIconClass(fixtureService.getProfileByUuid(fixture.profileUuid)) }} mr-1\">\n </span\n >{{ fixture.name }}\n </p>\n </div>\n <div class=\"col-auto my-auto\">\n <a class=\"btn btn-primary btn-sm float-right\" href=\"#\" role=\"button\" (click)=\"removeFixture(fixture); (false)\">\n <i class=\"fa fa-minus\" aria-hidden=\"true\"></i>\n </a>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"row mt-3\">\n <div class=\"col\">\n <!-- Tab navigation -->\n <ul class=\"nav nav-tabs mb-4\" id=\"myTab\" role=\"tablist\">\n <li class=\"nav-item\">\n <a class=\"nav-link active\" id=\"sets-tab\" data-toggle=\"tab\" href=\"#dmx\" role=\"tab\">\n <i class=\"icon-ola\" aria-hidden=\"true\"></i> {{ 'designer.fixture-pool.dmx' | translate }}\n </a>\n </li>\n <li class=\"nav-item\">\n <a class=\"nav-link\" id=\"compositions-tab\" data-toggle=\"tab\" href=\"#settings\" role=\"tab\">\n <i class=\"fa fa-cog\" aria-hidden=\"true\"></i> {{ 'designer.fixture-pool.settings' | translate }}\n </a>\n </li>\n </ul>\n\n <!-- Tab content -->\n <div class=\"tab-content\" id=\"myTabContent\">\n <!-- DMX universe overview-->\n <div class=\"tab-pane show active\" id=\"dmx\" role=\"tabpanel\">\n <!-- Show all channel numbers -->\n <!-- <div class=\"form-group row\">\n <div class=\"col-auto flex-grow\"></div>\n <div class=\"col-lg-3 d-flex\">\n <div class=\"form-check my-auto ml-auto\">\n <input type=\"checkbox\" class=\"form-check-input\" id=\"showChannelNumbers\" [ngModel]=\"showChannelNumbers\"\n (ngModelChange)=\"showChannelNumbers = $event\">\n <label class=\"form-check-label\" for=\"showChannelNumbers\">Show channels</label>\n </div>\n </div>\n </div> -->\n\n <!-- List of DMX channels -->\n <div>\n @for (channel of dmxChannels; track $index; let i = $index) {\n <div\n class=\"dmx-channel\"\n [class.dmx-channel-occupied]=\"channelOccupied(i)\"\n [class.dmx-channel-occupied-start]=\"channelOccupiedStart(i)\"\n [class.dmx-channel-occupied-end]=\"channelOccupiedEnd(i)\"\n [class.dmx-channel-selected]=\"channelSelected(i)\"\n [class.dmx-channel-overlapped]=\"channelOverlapped(i)\"\n (mousedown)=\"channelMouseDown($event)\"\n (mouseover)=\"channelMouseOver($event)\"\n [attr.data-index]=\"i\"\n popover=\"{{ i + 1 }}\"\n placement=\"top\"\n triggers=\"mouseenter:mouseleave\"\n >\n <div class=\"d-flex w-100 dmx-channel-text\" [attr.data-index]=\"i\" [class.dmx-channel-text-visible]=\"showChannelNumbers\">\n <div class=\"m-auto\" style=\"font-size: 11px\" [attr.data-index]=\"i\"><small [attr.data-index]=\"i\">&nbsp;</small></div>\n </div>\n </div>\n }\n </div>\n </div>\n\n <!-- Fixture settings -->\n <div class=\"tab-pane\" id=\"settings\" role=\"tabpanel\">\n @if (selectedFixture && selectedFixtureProfile) {\n <div>\n <div class=\"form-group row\">\n <label class=\"col-lg-3 col-form-label\" for=\"fixtureName\">{{ 'designer.fixture-pool.fixture-name' | translate }}</label>\n <div class=\"col-lg-9\">\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"selectedFixture.name\" maxlength=\"200\" id=\"fixtureName\" />\n </div>\n </div>\n <div class=\"form-group row\">\n <label class=\"col-lg-3 col-form-label\">{{ 'designer.fixture-pool.mode' | translate }}</label>\n <div class=\"col-lg-9\">\n <select\n class=\"custom-select\"\n [ngModel]=\"selectedFixture.modeShortName\"\n (ngModelChange)=\"selectedFixture.modeShortName = $event\"\n >\n @for (mode of selectedFixtureProfile.modes; track mode) {\n <option [ngValue]=\"mode.shortName || mode.name\">\n {{ mode.name }}\n - {{ fixtureService.getModeChannelCount(selectedFixtureProfile, mode) }}\n {{ 'designer.fixture-pool.channels' | translate }}\n </option>\n }\n </select>\n </div>\n </div>\n <div class=\"form-group row\">\n <label class=\"col-lg-3 col-form-label\">{{ 'designer.fixture-pool.first-channel' | translate }}</label>\n <div class=\"col-lg-9\">\n <select\n class=\"custom-select\"\n [ngModel]=\"selectedFixture.dmxFirstChannel\"\n (ngModelChange)=\"selectedFixture.dmxFirstChannel = $event\"\n >\n @for (channel of dmxChannels; track $index; let i = $index) {\n <option [ngValue]=\"i\">\n {{ i + 1 }}\n </option>\n }\n </select>\n </div>\n </div>\n <div class=\"form-group row\">\n <label class=\"col-lg-3 col-form-label\"></label>\n <div class=\"col-lg-9\">\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"addCopy(selectedFixture)\">\n {{ 'designer.fixture.add-copy' | translate }}\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</div>\n<div class=\"modal-footer\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"ok()\">{{ 'designer.misc.ok' | translate }}</button>\n</div>\n", styles: [".list-group-item{padding:.3rem 1.25rem}.dmx-channel{display:flex;float:left;width:28px;border:1px solid white;margin-left:-1px;margin-bottom:-1px;padding-bottom:2px}.dmx-channel-occupied{background-color:#63462e;border-left:none;border-right:none;cursor:move}.dmx-channel-occupied-start{border-left:1px solid white;border-top-left-radius:8px;border-bottom-left-radius:8px}.dmx-channel-occupied-end{border-right:1px solid white;border-top-right-radius:8px;border-bottom-right-radius:8px}.dmx-channel-selected{background-color:#fd7e14}.dmx-channel-overlapped{background-color:red;border:1px solid red;cursor:move}.card{overflow:auto}\n"] }]
5639
- }], ctorParameters: () => [{ type: i1$1.BsModalRef }, { type: FixtureService }, { type: UuidService }, { type: ProjectService }, { type: PreviewService }, { type: i4.TranslateService }, { type: i3$1.ToastrService }, { type: PresetService }, { type: ConfigService }, { type: i1$1.BsModalService }], propDecorators: { mouseUp: [{
5722
+ }], ctorParameters: () => [{ type: i1$1.BsModalRef }, { type: FixtureService }, { type: UuidService }, { type: ProjectService }, { type: PreviewService }, { type: i2.TranslateService }, { type: i3$1.ToastrService }, { type: PresetService }, { type: ConfigService }, { type: i1$1.BsModalService }, { type: LivePreviewService }], propDecorators: { mouseUp: [{
5640
5723
  type: HostListener,
5641
5724
  args: ['window:mouseup', ['$event']]
5642
5725
  }], handleKeyboardEvent: [{
@@ -5866,7 +5949,7 @@ class UserLoginComponent {
5866
5949
  this.login();
5867
5950
  }
5868
5951
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: UserLoginComponent, deps: [{ token: i1$1.BsModalRef }, { token: UserService }], target: i0.ɵɵFactoryTarget.Component }); }
5869
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: UserLoginComponent, isStandalone: false, selector: "lib-user-login", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<form (ngSubmit)=\"login()\">\n <div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ 'designer.user.login-title' | translate }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"cancel(); (false)\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body\">\n <div class=\"form-group row\">\n <label for=\"email\" class=\"col-sm-4 col-form-label\">{{ 'designer.user.email' | translate }}</label>\n <div class=\"col-sm-8\">\n <div class=\"input-group\">\n <div class=\"input-group-prepend\">\n <div class=\"input-group-text\"><i class=\"fa fa-fw fa-envelope-o\" aria-hidden=\"true\"></i></div>\n </div>\n <input\n required\n [disabled]=\"loggingIn\"\n name=\"email\"\n [(ngModel)]=\"email\"\n type=\"email\"\n class=\"form-control\"\n id=\"email\"\n placeholder=\"email@example.com\"\n />\n </div>\n </div>\n </div>\n <div class=\"form-group row\">\n <label for=\"password\" class=\"col-sm-4 col-form-label\">{{ 'designer.user.password' | translate }}</label>\n <div class=\"col-sm-8\">\n <div class=\"input-group\">\n <div class=\"input-group-prepend\">\n <div class=\"input-group-text\"><i class=\"fa fa-fw fa-lock\" aria-hidden=\"true\"></i></div>\n </div>\n <input\n required\n [disabled]=\"loggingIn\"\n name=\"password\"\n [(ngModel)]=\"password\"\n type=\"password\"\n class=\"form-control\"\n id=\"password\"\n placeholder=\"{{ 'designer.user.password' | translate }}\"\n />\n </div>\n </div>\n </div>\n @if (error) {\n <div class=\"alert alert-primary\" role=\"alert\">\n {{ 'designer.user.error.' + error | translate }}\n </div>\n }\n </div>\n <div class=\"modal-footer\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button [disabled]=\"loggingIn\" type=\"submit\" class=\"btn btn-primary\">\n @if (loggingIn) {\n <i class=\"fa fa-spinner fa-pulse fa-fw\"></i>\n } {{ 'designer.user.login' | translate }}\n </button>\n </div>\n</form>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3$2.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
5952
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: UserLoginComponent, isStandalone: false, selector: "lib-user-login", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<form (ngSubmit)=\"login()\">\n <div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ 'designer.user.login-title' | translate }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"cancel(); (false)\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body\">\n <div class=\"form-group row\">\n <label for=\"email\" class=\"col-sm-4 col-form-label\">{{ 'designer.user.email' | translate }}</label>\n <div class=\"col-sm-8\">\n <div class=\"input-group\">\n <div class=\"input-group-prepend\">\n <div class=\"input-group-text\"><i class=\"fa fa-fw fa-envelope-o\" aria-hidden=\"true\"></i></div>\n </div>\n <input\n required\n [disabled]=\"loggingIn\"\n name=\"email\"\n [(ngModel)]=\"email\"\n type=\"email\"\n class=\"form-control\"\n id=\"email\"\n placeholder=\"email@example.com\"\n />\n </div>\n </div>\n </div>\n <div class=\"form-group row\">\n <label for=\"password\" class=\"col-sm-4 col-form-label\">{{ 'designer.user.password' | translate }}</label>\n <div class=\"col-sm-8\">\n <div class=\"input-group\">\n <div class=\"input-group-prepend\">\n <div class=\"input-group-text\"><i class=\"fa fa-fw fa-lock\" aria-hidden=\"true\"></i></div>\n </div>\n <input\n required\n [disabled]=\"loggingIn\"\n name=\"password\"\n [(ngModel)]=\"password\"\n type=\"password\"\n class=\"form-control\"\n id=\"password\"\n placeholder=\"{{ 'designer.user.password' | translate }}\"\n />\n </div>\n </div>\n </div>\n @if (error) {\n <div class=\"alert alert-primary\" role=\"alert\">\n {{ 'designer.user.error.' + error | translate }}\n </div>\n }\n </div>\n <div class=\"modal-footer\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button [disabled]=\"loggingIn\" type=\"submit\" class=\"btn btn-primary\">\n @if (loggingIn) {\n <i class=\"fa fa-spinner fa-pulse fa-fw\"></i>\n } {{ 'designer.user.login' | translate }}\n </button>\n </div>\n</form>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3$2.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
5870
5953
  }
5871
5954
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: UserLoginComponent, decorators: [{
5872
5955
  type: Component,
@@ -5939,7 +6022,7 @@ class UserRegisterComponent {
5939
6022
  this.register();
5940
6023
  }
5941
6024
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: UserRegisterComponent, deps: [{ token: i1$1.BsModalRef }, { token: i1$1.BsModalService }, { token: UserService }], target: i0.ɵɵFactoryTarget.Component }); }
5942
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: UserRegisterComponent, isStandalone: false, selector: "lib-user-register", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<form (ngSubmit)=\"register()\">\n <div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ 'designer.user.register-title' | translate }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"cancel(); (false)\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body\">\n @if (subject) {\n <div class=\"alert alert-success\" role=\"alert\">\n {{ 'designer.user.login-required' | translate }}\n </div>\n }\n <div class=\"form-group row\">\n <label for=\"username\" class=\"col-sm-4 col-form-label\">{{ 'designer.user.username' | translate }}</label>\n <div class=\"col-sm-8\">\n <div class=\"input-group\">\n <div class=\"input-group-prepend\">\n <div class=\"input-group-text\"><i class=\"fa fa-fw fa-user\" aria-hidden=\"true\"></i></div>\n </div>\n <input\n required\n [disabled]=\"registering\"\n name=\"username\"\n [(ngModel)]=\"username\"\n type=\"text\"\n class=\"form-control\"\n id=\"username\"\n placeholder=\"John Doe\"\n />\n </div>\n </div>\n </div>\n <div class=\"form-group row\">\n <label for=\"email\" class=\"col-sm-4 col-form-label\">{{ 'designer.user.email' | translate }}</label>\n <div class=\"col-sm-8\">\n <div class=\"input-group\">\n <div class=\"input-group-prepend\">\n <div class=\"input-group-text\"><i class=\"fa fa-fw fa-envelope-o\" aria-hidden=\"true\"></i></div>\n </div>\n <input\n required\n [disabled]=\"registering\"\n name=\"email\"\n [(ngModel)]=\"email\"\n type=\"email\"\n class=\"form-control\"\n id=\"email\"\n placeholder=\"email@example.com\"\n />\n </div>\n </div>\n </div>\n <div class=\"form-group row\">\n <label for=\"password\" class=\"col-sm-4 col-form-label\">{{ 'designer.user.password' | translate }}</label>\n <div class=\"col-sm-8\">\n <div class=\"input-group\">\n <div class=\"input-group-prepend\">\n <div class=\"input-group-text\"><i class=\"fa fa-fw fa-lock\" aria-hidden=\"true\"></i></div>\n </div>\n <input\n required\n [disabled]=\"registering\"\n name=\"password\"\n [(ngModel)]=\"password\"\n type=\"password\"\n class=\"form-control\"\n id=\"password\"\n placeholder=\"{{ 'designer.user.password' | translate }}\"\n />\n </div>\n </div>\n </div>\n <div class=\"form-group row\">\n <label for=\"passwordRepeat\" class=\"col-sm-4 col-form-label\">{{ 'designer.user.password-repeat' | translate }}</label>\n <div class=\"col-sm-8\">\n <div class=\"input-group\">\n <div class=\"input-group-prepend\">\n <div class=\"input-group-text\"><i class=\"fa fa-fw fa-lock\" aria-hidden=\"true\"></i></div>\n </div>\n <input\n required\n [disabled]=\"registering\"\n name=\"passwordRepeat\"\n [(ngModel)]=\"passwordRepeat\"\n type=\"password\"\n class=\"form-control\"\n id=\"passwordRepeat\"\n placeholder=\"{{ 'designer.user.password' | translate }}\"\n />\n </div>\n </div>\n </div>\n @if (error) {\n <div class=\"alert alert-primary\" role=\"alert\">\n {{ 'designer.user.error.' + error | translate }}\n </div>\n }\n <a href=\"#\" (click)=\"login(); (false)\">\n <p class=\"mt-3 mb-0\" style=\"text-align: center\">{{ 'designer.user.already-have-account' | translate }}</p>\n </a>\n </div>\n <div class=\"modal-footer\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button [disabled]=\"registering\" type=\"submit\" class=\"btn btn-primary\">\n @if (registering) {\n <i class=\"fa fa-spinner fa-pulse fa-fw\"> </i>\n }{{ 'designer.user.register' | translate }}\n </button>\n </div>\n</form>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3$2.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
6025
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: UserRegisterComponent, isStandalone: false, selector: "lib-user-register", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<form (ngSubmit)=\"register()\">\n <div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ 'designer.user.register-title' | translate }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"cancel(); (false)\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body\">\n @if (subject) {\n <div class=\"alert alert-success\" role=\"alert\">\n {{ 'designer.user.login-required' | translate }}\n </div>\n }\n <div class=\"form-group row\">\n <label for=\"username\" class=\"col-sm-4 col-form-label\">{{ 'designer.user.username' | translate }}</label>\n <div class=\"col-sm-8\">\n <div class=\"input-group\">\n <div class=\"input-group-prepend\">\n <div class=\"input-group-text\"><i class=\"fa fa-fw fa-user\" aria-hidden=\"true\"></i></div>\n </div>\n <input\n required\n [disabled]=\"registering\"\n name=\"username\"\n [(ngModel)]=\"username\"\n type=\"text\"\n class=\"form-control\"\n id=\"username\"\n placeholder=\"John Doe\"\n />\n </div>\n </div>\n </div>\n <div class=\"form-group row\">\n <label for=\"email\" class=\"col-sm-4 col-form-label\">{{ 'designer.user.email' | translate }}</label>\n <div class=\"col-sm-8\">\n <div class=\"input-group\">\n <div class=\"input-group-prepend\">\n <div class=\"input-group-text\"><i class=\"fa fa-fw fa-envelope-o\" aria-hidden=\"true\"></i></div>\n </div>\n <input\n required\n [disabled]=\"registering\"\n name=\"email\"\n [(ngModel)]=\"email\"\n type=\"email\"\n class=\"form-control\"\n id=\"email\"\n placeholder=\"email@example.com\"\n />\n </div>\n </div>\n </div>\n <div class=\"form-group row\">\n <label for=\"password\" class=\"col-sm-4 col-form-label\">{{ 'designer.user.password' | translate }}</label>\n <div class=\"col-sm-8\">\n <div class=\"input-group\">\n <div class=\"input-group-prepend\">\n <div class=\"input-group-text\"><i class=\"fa fa-fw fa-lock\" aria-hidden=\"true\"></i></div>\n </div>\n <input\n required\n [disabled]=\"registering\"\n name=\"password\"\n [(ngModel)]=\"password\"\n type=\"password\"\n class=\"form-control\"\n id=\"password\"\n placeholder=\"{{ 'designer.user.password' | translate }}\"\n />\n </div>\n </div>\n </div>\n <div class=\"form-group row\">\n <label for=\"passwordRepeat\" class=\"col-sm-4 col-form-label\">{{ 'designer.user.password-repeat' | translate }}</label>\n <div class=\"col-sm-8\">\n <div class=\"input-group\">\n <div class=\"input-group-prepend\">\n <div class=\"input-group-text\"><i class=\"fa fa-fw fa-lock\" aria-hidden=\"true\"></i></div>\n </div>\n <input\n required\n [disabled]=\"registering\"\n name=\"passwordRepeat\"\n [(ngModel)]=\"passwordRepeat\"\n type=\"password\"\n class=\"form-control\"\n id=\"passwordRepeat\"\n placeholder=\"{{ 'designer.user.password' | translate }}\"\n />\n </div>\n </div>\n </div>\n @if (error) {\n <div class=\"alert alert-primary\" role=\"alert\">\n {{ 'designer.user.error.' + error | translate }}\n </div>\n }\n <a href=\"#\" (click)=\"login(); (false)\">\n <p class=\"mt-3 mb-0\" style=\"text-align: center\">{{ 'designer.user.already-have-account' | translate }}</p>\n </a>\n </div>\n <div class=\"modal-footer\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button [disabled]=\"registering\" type=\"submit\" class=\"btn btn-primary\">\n @if (registering) {\n <i class=\"fa fa-spinner fa-pulse fa-fw\"> </i>\n }{{ 'designer.user.register' | translate }}\n </button>\n </div>\n</form>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3$2.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
5943
6026
  }
5944
6027
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: UserRegisterComponent, decorators: [{
5945
6028
  type: Component,
@@ -6035,13 +6118,13 @@ class DropzoneComponent {
6035
6118
  `,
6036
6119
  };
6037
6120
  }
6038
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DropzoneComponent, deps: [{ token: i4.TranslateService }, { token: ConfigService }], target: i0.ɵɵFactoryTarget.Component }); }
6121
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DropzoneComponent, deps: [{ token: i2.TranslateService }, { token: ConfigService }], target: i0.ɵɵFactoryTarget.Component }); }
6039
6122
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: DropzoneComponent, isStandalone: false, selector: "app-dropzone", inputs: { url: "url", acceptedFiles: "acceptedFiles", maxFiles: "maxFiles" }, outputs: { error: "error", success: "success", addedFile: "addedFile" }, ngImport: i0, template: "<dropzone\n [config]=\"dropzoneConfig\"\n [useDropzoneClass]=\"'false'\"\n [message]=\"uploadMessage\"\n (error)=\"error.emit($event)\"\n (success)=\"success.emit($event)\"\n (addedFile)=\"addedFile.emit($event)\"\n></dropzone>\n", styles: [""], dependencies: [{ kind: "component", type: i5.DropzoneComponent, selector: "dropzone", inputs: ["disabled", "config", "message", "placeholder", "useDropzoneClass"], outputs: ["init", "error", "success", "sending", "canceled", "complete", "processing", "drop", "dragStart", "dragEnd", "dragEnter", "dragOver", "dragLeave", "thumbnail", "addedFile", "addedFiles", "removedFile", "uploadProgress", "maxFilesReached", "maxFilesExceeded", "errorMultiple", "successMultiple", "sendingMultiple", "canceledMultiple", "completeMultiple", "processingMultiple", "reset", "queueComplete", "totalUploadProgress"], exportAs: ["ngxDropzone"] }] }); }
6040
6123
  }
6041
6124
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DropzoneComponent, decorators: [{
6042
6125
  type: Component,
6043
6126
  args: [{ selector: 'app-dropzone', standalone: false, template: "<dropzone\n [config]=\"dropzoneConfig\"\n [useDropzoneClass]=\"'false'\"\n [message]=\"uploadMessage\"\n (error)=\"error.emit($event)\"\n (success)=\"success.emit($event)\"\n (addedFile)=\"addedFile.emit($event)\"\n></dropzone>\n" }]
6044
- }], ctorParameters: () => [{ type: i4.TranslateService }, { type: ConfigService }], propDecorators: { error: [{
6127
+ }], ctorParameters: () => [{ type: i2.TranslateService }, { type: ConfigService }], propDecorators: { error: [{
6045
6128
  type: Output
6046
6129
  }], success: [{
6047
6130
  type: Output
@@ -6176,13 +6259,13 @@ class CompositionSettingsComponent {
6176
6259
  }))
6177
6260
  .subscribe();
6178
6261
  }
6179
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CompositionSettingsComponent, deps: [{ token: i1$1.BsModalRef }, { token: TimelineService }, { token: ConfigService }, { token: i4.TranslateService }, { token: i1.HttpClient }, { token: WarningDialogService }, { token: i3$1.ToastrService }, { token: ProjectService }], target: i0.ɵɵFactoryTarget.Component }); }
6180
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: CompositionSettingsComponent, isStandalone: false, selector: "lib-app-composition-settings", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ composition.name }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"bsModalRef.hide()\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.timeline.composition-name' | translate }}</label>\n <div class=\"col-lg-8 d-flex\">\n <input\n type=\"text\"\n class=\"form-control\"\n [ngModel]=\"composition.name\"\n (ngModelChange)=\"composition.name = $event\"\n [typeahead]=\"existingCompositionNames\"\n />\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.timeline.composition-sync-type' | translate }}</label>\n <div class=\"col-lg-8 d-flex\">\n <select class=\"custom-select\" [ngModel]=\"composition.syncType\" (ngModelChange)=\"composition.syncType = $event\">\n <!-- TODO -->\n <!-- <option value=\"none\">{{ 'designer.timeline.composition-sync-type-none' | translate }}</option> -->\n <option value=\"audio\">{{ 'designer.timeline.composition-sync-type-audio' | translate }}</option>\n </select>\n </div>\n </div>\n\n @if (composition.syncType == 'audio') {\n <div class=\"row\">\n <div class=\"px-3 w-100\">\n <!-- Selected file -->\n <div class=\"card border-secondary mb-3\">\n <div class=\"card-body\">\n <!-- No file selected -->\n @if (!composition.audioFileName) {\n <div>\n {{ 'designer.timeline.composition-no-file-selected' | translate }}\n </div>\n }\n <!-- A file is selected -->\n @if (composition.audioFileName) {\n <div>\n {{ composition.audioFileName }}\n </div>\n }\n </div>\n </div>\n <!-- Choose file -->\n @if (configService.enableMediaLibrary) {\n <ul class=\"nav nav-tabs mb-3\" id=\"myTab\" role=\"tablist\">\n <li class=\"nav-item\">\n <a class=\"nav-link active\" id=\"upload-tab\" data-toggle=\"tab\" href=\"#upload\" role=\"tab\">\n <i class=\"fa fa-upload\" aria-hidden=\"true\"></i>\n {{ 'designer.timeline.composition-file-upload' | translate }}\n </a>\n </li>\n <li class=\"nav-item\">\n <a class=\"nav-link\" id=\"media-library-tab\" data-toggle=\"tab\" href=\"#media-library\" role=\"tab\">\n <i class=\"fa fa-folder-o\" aria-hidden=\"true\"></i>\n {{ 'designer.timeline.composition-file-library' | translate }}\n </a>\n </li>\n </ul>\n }\n <div class=\"tab-content\" id=\"myTabContent\">\n <!-- Upload -->\n <div class=\"tab-pane fade show active\" id=\"upload\" role=\"tabpanel\">\n <app-dropzone\n [url]=\"getDropzoneUrl()\"\n [acceptedFiles]=\"'audio/*'\"\n (error)=\"onUploadError($event)\"\n (success)=\"onUploadSuccess($event)\"\n (queuecomplete)=\"onQueueComplete($event)\"\n (addedfile)=\"onAddedFile($event)\"\n ></app-dropzone>\n </div>\n <!-- Media library -->\n <div class=\"tab-pane fade\" id=\"media-library\" role=\"tabpanel\">\n <input\n type=\"text\"\n class=\"form-control input-block mb-3\"\n id=\"searchFileList\"\n placeholder=\"{{ 'designer.misc.search' | translate }}\"\n (input)=\"filterExistingFiles($event.target.value)\"\n />\n <div class=\"card border-secondary\" style=\"height: 200px; overflow-y: scroll\">\n <div class=\"card-body p-0\">\n <div class=\"list-group list-group-flush\">\n @for (existingFile of filteredExistingFiles | sort : 'name'; track existingFile) {\n <a\n class=\"list-group-item\"\n [class.active]=\"composition.audioFileName == existingFile\"\n href=\"#\"\n (click)=\"selectExistingFile(existingFile); (false)\"\n >\n <div class=\"row\">\n <div class=\"col-auto my-auto flex-grow text-break-word\">\n {{ existingFile }}\n </div>\n <div class=\"col-auto my-auto pl-0 text-danger float-right\" (click)=\"deleteFile(existingFile); (false)\">\n <i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </div>\n </div>\n </a>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n</div>\n<div class=\"modal-footer\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button [disabled]=\"uploading\" type=\"button\" class=\"btn btn-primary\" (click)=\"ok()\">{{ 'designer.misc.ok' | translate }}</button>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i10.TypeaheadDirective, selector: "[typeahead]", inputs: ["typeahead", "typeaheadMinLength", "adaptivePosition", "isAnimated", "typeaheadWaitMs", "typeaheadOptionsLimit", "typeaheadOptionField", "typeaheadGroupField", "typeaheadOrderBy", "typeaheadAsync", "typeaheadLatinize", "typeaheadSingleWords", "typeaheadWordDelimiters", "typeaheadMultipleSearch", "typeaheadMultipleSearchDelimiters", "typeaheadPhraseDelimiters", "typeaheadItemTemplate", "optionsListTemplate", "typeaheadScrollable", "typeaheadOptionsInScrollableView", "typeaheadHideResultsOnBlur", "typeaheadSelectFirstItem", "typeaheadIsFirstItemActive", "container", "dropup"], outputs: ["typeaheadLoading", "typeaheadNoResults", "typeaheadOnSelect", "typeaheadOnPreview", "typeaheadOnBlur"], exportAs: ["bs-typeahead"] }, { kind: "component", type: DropzoneComponent, selector: "app-dropzone", inputs: ["url", "acceptedFiles", "maxFiles"], outputs: ["error", "success", "addedFile"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }, { kind: "pipe", type: ArraySortPipe, name: "sort" }] }); }
6262
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CompositionSettingsComponent, deps: [{ token: i1$1.BsModalRef }, { token: TimelineService }, { token: ConfigService }, { token: i2.TranslateService }, { token: i1.HttpClient }, { token: WarningDialogService }, { token: i3$1.ToastrService }, { token: ProjectService }], target: i0.ɵɵFactoryTarget.Component }); }
6263
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: CompositionSettingsComponent, isStandalone: false, selector: "lib-app-composition-settings", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ composition.name }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"bsModalRef.hide()\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.timeline.composition-name' | translate }}</label>\n <div class=\"col-lg-8 d-flex\">\n <input\n type=\"text\"\n class=\"form-control\"\n [ngModel]=\"composition.name\"\n (ngModelChange)=\"composition.name = $event\"\n [typeahead]=\"existingCompositionNames\"\n />\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.timeline.composition-sync-type' | translate }}</label>\n <div class=\"col-lg-8 d-flex\">\n <select class=\"custom-select\" [ngModel]=\"composition.syncType\" (ngModelChange)=\"composition.syncType = $event\">\n <!-- TODO -->\n <!-- <option value=\"none\">{{ 'designer.timeline.composition-sync-type-none' | translate }}</option> -->\n <option value=\"audio\">{{ 'designer.timeline.composition-sync-type-audio' | translate }}</option>\n </select>\n </div>\n </div>\n\n @if (composition.syncType == 'audio') {\n <div class=\"row\">\n <div class=\"px-3 w-100\">\n <!-- Selected file -->\n <div class=\"card border-secondary mb-3\">\n <div class=\"card-body\">\n <!-- No file selected -->\n @if (!composition.audioFileName) {\n <div>\n {{ 'designer.timeline.composition-no-file-selected' | translate }}\n </div>\n }\n <!-- A file is selected -->\n @if (composition.audioFileName) {\n <div>\n {{ composition.audioFileName }}\n </div>\n }\n </div>\n </div>\n <!-- Choose file -->\n @if (configService.enableMediaLibrary) {\n <ul class=\"nav nav-tabs mb-3\" id=\"myTab\" role=\"tablist\">\n <li class=\"nav-item\">\n <a class=\"nav-link active\" id=\"upload-tab\" data-toggle=\"tab\" href=\"#upload\" role=\"tab\">\n <i class=\"fa fa-upload\" aria-hidden=\"true\"></i>\n {{ 'designer.timeline.composition-file-upload' | translate }}\n </a>\n </li>\n <li class=\"nav-item\">\n <a class=\"nav-link\" id=\"media-library-tab\" data-toggle=\"tab\" href=\"#media-library\" role=\"tab\">\n <i class=\"fa fa-folder-o\" aria-hidden=\"true\"></i>\n {{ 'designer.timeline.composition-file-library' | translate }}\n </a>\n </li>\n </ul>\n }\n <div class=\"tab-content\" id=\"myTabContent\">\n <!-- Upload -->\n <div class=\"tab-pane fade show active\" id=\"upload\" role=\"tabpanel\">\n <app-dropzone\n [url]=\"getDropzoneUrl()\"\n [acceptedFiles]=\"'audio/*'\"\n (error)=\"onUploadError($event)\"\n (success)=\"onUploadSuccess($event)\"\n (queuecomplete)=\"onQueueComplete($event)\"\n (addedfile)=\"onAddedFile($event)\"\n ></app-dropzone>\n </div>\n <!-- Media library -->\n <div class=\"tab-pane fade\" id=\"media-library\" role=\"tabpanel\">\n <input\n type=\"text\"\n class=\"form-control input-block mb-3\"\n id=\"searchFileList\"\n placeholder=\"{{ 'designer.misc.search' | translate }}\"\n (input)=\"filterExistingFiles($event.target.value)\"\n />\n <div class=\"card border-secondary\" style=\"height: 200px; overflow-y: scroll\">\n <div class=\"card-body p-0\">\n <div class=\"list-group list-group-flush\">\n @for (existingFile of filteredExistingFiles | sort : 'name'; track existingFile) {\n <a\n class=\"list-group-item\"\n [class.active]=\"composition.audioFileName == existingFile\"\n href=\"#\"\n (click)=\"selectExistingFile(existingFile); (false)\"\n >\n <div class=\"row\">\n <div class=\"col-auto my-auto flex-grow text-break-word\">\n {{ existingFile }}\n </div>\n <div class=\"col-auto my-auto pl-0 text-danger float-right\" (click)=\"deleteFile(existingFile); (false)\">\n <i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </div>\n </div>\n </a>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n</div>\n<div class=\"modal-footer\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button [disabled]=\"uploading\" type=\"button\" class=\"btn btn-primary\" (click)=\"ok()\">{{ 'designer.misc.ok' | translate }}</button>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i10.TypeaheadDirective, selector: "[typeahead]", inputs: ["typeahead", "typeaheadMinLength", "adaptivePosition", "isAnimated", "typeaheadWaitMs", "typeaheadOptionsLimit", "typeaheadOptionField", "typeaheadGroupField", "typeaheadOrderBy", "typeaheadAsync", "typeaheadLatinize", "typeaheadSingleWords", "typeaheadWordDelimiters", "typeaheadMultipleSearch", "typeaheadMultipleSearchDelimiters", "typeaheadPhraseDelimiters", "typeaheadItemTemplate", "optionsListTemplate", "typeaheadScrollable", "typeaheadOptionsInScrollableView", "typeaheadHideResultsOnBlur", "typeaheadSelectFirstItem", "typeaheadIsFirstItemActive", "container", "dropup"], outputs: ["typeaheadLoading", "typeaheadNoResults", "typeaheadOnSelect", "typeaheadOnPreview", "typeaheadOnBlur"], exportAs: ["bs-typeahead"] }, { kind: "component", type: DropzoneComponent, selector: "app-dropzone", inputs: ["url", "acceptedFiles", "maxFiles"], outputs: ["error", "success", "addedFile"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "pipe", type: ArraySortPipe, name: "sort" }] }); }
6181
6264
  }
6182
6265
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CompositionSettingsComponent, decorators: [{
6183
6266
  type: Component,
6184
6267
  args: [{ selector: 'lib-app-composition-settings', standalone: false, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ composition.name }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"bsModalRef.hide()\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.timeline.composition-name' | translate }}</label>\n <div class=\"col-lg-8 d-flex\">\n <input\n type=\"text\"\n class=\"form-control\"\n [ngModel]=\"composition.name\"\n (ngModelChange)=\"composition.name = $event\"\n [typeahead]=\"existingCompositionNames\"\n />\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.timeline.composition-sync-type' | translate }}</label>\n <div class=\"col-lg-8 d-flex\">\n <select class=\"custom-select\" [ngModel]=\"composition.syncType\" (ngModelChange)=\"composition.syncType = $event\">\n <!-- TODO -->\n <!-- <option value=\"none\">{{ 'designer.timeline.composition-sync-type-none' | translate }}</option> -->\n <option value=\"audio\">{{ 'designer.timeline.composition-sync-type-audio' | translate }}</option>\n </select>\n </div>\n </div>\n\n @if (composition.syncType == 'audio') {\n <div class=\"row\">\n <div class=\"px-3 w-100\">\n <!-- Selected file -->\n <div class=\"card border-secondary mb-3\">\n <div class=\"card-body\">\n <!-- No file selected -->\n @if (!composition.audioFileName) {\n <div>\n {{ 'designer.timeline.composition-no-file-selected' | translate }}\n </div>\n }\n <!-- A file is selected -->\n @if (composition.audioFileName) {\n <div>\n {{ composition.audioFileName }}\n </div>\n }\n </div>\n </div>\n <!-- Choose file -->\n @if (configService.enableMediaLibrary) {\n <ul class=\"nav nav-tabs mb-3\" id=\"myTab\" role=\"tablist\">\n <li class=\"nav-item\">\n <a class=\"nav-link active\" id=\"upload-tab\" data-toggle=\"tab\" href=\"#upload\" role=\"tab\">\n <i class=\"fa fa-upload\" aria-hidden=\"true\"></i>\n {{ 'designer.timeline.composition-file-upload' | translate }}\n </a>\n </li>\n <li class=\"nav-item\">\n <a class=\"nav-link\" id=\"media-library-tab\" data-toggle=\"tab\" href=\"#media-library\" role=\"tab\">\n <i class=\"fa fa-folder-o\" aria-hidden=\"true\"></i>\n {{ 'designer.timeline.composition-file-library' | translate }}\n </a>\n </li>\n </ul>\n }\n <div class=\"tab-content\" id=\"myTabContent\">\n <!-- Upload -->\n <div class=\"tab-pane fade show active\" id=\"upload\" role=\"tabpanel\">\n <app-dropzone\n [url]=\"getDropzoneUrl()\"\n [acceptedFiles]=\"'audio/*'\"\n (error)=\"onUploadError($event)\"\n (success)=\"onUploadSuccess($event)\"\n (queuecomplete)=\"onQueueComplete($event)\"\n (addedfile)=\"onAddedFile($event)\"\n ></app-dropzone>\n </div>\n <!-- Media library -->\n <div class=\"tab-pane fade\" id=\"media-library\" role=\"tabpanel\">\n <input\n type=\"text\"\n class=\"form-control input-block mb-3\"\n id=\"searchFileList\"\n placeholder=\"{{ 'designer.misc.search' | translate }}\"\n (input)=\"filterExistingFiles($event.target.value)\"\n />\n <div class=\"card border-secondary\" style=\"height: 200px; overflow-y: scroll\">\n <div class=\"card-body p-0\">\n <div class=\"list-group list-group-flush\">\n @for (existingFile of filteredExistingFiles | sort : 'name'; track existingFile) {\n <a\n class=\"list-group-item\"\n [class.active]=\"composition.audioFileName == existingFile\"\n href=\"#\"\n (click)=\"selectExistingFile(existingFile); (false)\"\n >\n <div class=\"row\">\n <div class=\"col-auto my-auto flex-grow text-break-word\">\n {{ existingFile }}\n </div>\n <div class=\"col-auto my-auto pl-0 text-danger float-right\" (click)=\"deleteFile(existingFile); (false)\">\n <i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </div>\n </div>\n </a>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n</div>\n<div class=\"modal-footer\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button [disabled]=\"uploading\" type=\"button\" class=\"btn btn-primary\" (click)=\"ok()\">{{ 'designer.misc.ok' | translate }}</button>\n</div>\n" }]
6185
- }], ctorParameters: () => [{ type: i1$1.BsModalRef }, { type: TimelineService }, { type: ConfigService }, { type: i4.TranslateService }, { type: i1.HttpClient }, { type: WarningDialogService }, { type: i3$1.ToastrService }, { type: ProjectService }], propDecorators: { handleKeyboardEvent: [{
6268
+ }], ctorParameters: () => [{ type: i1$1.BsModalRef }, { type: TimelineService }, { type: ConfigService }, { type: i2.TranslateService }, { type: i1.HttpClient }, { type: WarningDialogService }, { type: i3$1.ToastrService }, { type: ProjectService }], propDecorators: { handleKeyboardEvent: [{
6186
6269
  type: HostListener,
6187
6270
  args: ['document:keydown.enter', ['$event']]
6188
6271
  }] } });
@@ -6218,7 +6301,7 @@ class TimelineGridComponent {
6218
6301
  this.ok();
6219
6302
  }
6220
6303
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TimelineGridComponent, deps: [{ token: i1$1.BsModalRef }, { token: TimelineService }], target: i0.ɵɵFactoryTarget.Component }); }
6221
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: TimelineGridComponent, isStandalone: false, selector: "lib-app-timeline-grid", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ 'designer.timeline.grid' | translate }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"bsModalRef.hide()\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.timeline.grid-type' | translate }}</label>\n <div class=\"col-lg-8\">\n <select class=\"custom-select\" [ngModel]=\"gridType\" (ngModelChange)=\"gridType = $event\">\n <option value=\"time\">{{ 'designer.timeline.grid-type-time-based' | translate }}</option>\n <option value=\"musical\">{{ 'designer.timeline.grid-type-musical' | translate }}</option>\n </select>\n </div>\n </div>\n\n @if (gridType == 'musical') {\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.timeline.beats-per-minute' | translate }}</label>\n <div class=\"col-lg-8\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"beatsPerMinute\" (ngModelChange)=\"beatsPerMinute = $event\" />\n </div>\n </div>\n } @if (gridType == 'musical') {\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.timeline.time-signature' | translate }}</label>\n <div class=\"col-lg-8\">\n <input\n type=\"text\"\n class=\"form-control\"\n [ngModel]=\"timeSignatureUpper\"\n (ngModelChange)=\"timeSignatureUpper = $event\"\n style=\"float: left; width: 40px\"\n />\n <div class=\"d-flex px-2 h-100\" style=\"float: left\">\n <div class=\"m-auto\">/</div>\n </div>\n <input\n type=\"text\"\n class=\"form-control\"\n [ngModel]=\"timeSignatureLower\"\n (ngModelChange)=\"timeSignatureLower = $event\"\n style=\"width: 40px\"\n />\n </div>\n </div>\n } @if (gridType == 'musical') {\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.timeline.grid-resolution' | translate }}</label>\n <div class=\"col-lg-8\">\n <select class=\"custom-select\" [ngModel]=\"gridResolution\" (ngModelChange)=\"gridResolution = $event\">\n <option value=\"1\">1/1</option>\n <option value=\"2\">1/2</option>\n <option value=\"4\">1/4</option>\n <option value=\"8\">1/8</option>\n <option value=\"16\">1/16</option>\n <option value=\"32\">1/32</option>\n <option value=\"64\">1/64</option>\n </select>\n </div>\n </div>\n } @if (gridType == 'musical') {\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.timeline.grid-offset' | translate }}</label>\n <div class=\"col-lg-8\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"gridOffsetMillis\" (ngModelChange)=\"gridOffsetMillis = $event\" />\n </div>\n </div>\n }\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\"></label>\n <div class=\"col-lg-8\">\n <div class=\"form-check\">\n <input type=\"checkbox\" [ngModel]=\"snapToGrid\" (ngModelChange)=\"snapToGrid = $event\" class=\"form-check-input\" id=\"snapToGrid\" />\n\n <label class=\"form-check-label\" for=\"snapToGrid\">\n {{ 'designer.timeline.snap-to-grid' | translate }}\n </label>\n </div>\n </div>\n </div>\n</div>\n<div class=\"modal-footer\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"ok()\">{{ 'designer.misc.ok' | translate }}</button>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
6304
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: TimelineGridComponent, isStandalone: false, selector: "lib-app-timeline-grid", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ 'designer.timeline.grid' | translate }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"bsModalRef.hide()\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.timeline.grid-type' | translate }}</label>\n <div class=\"col-lg-8\">\n <select class=\"custom-select\" [ngModel]=\"gridType\" (ngModelChange)=\"gridType = $event\">\n <option value=\"time\">{{ 'designer.timeline.grid-type-time-based' | translate }}</option>\n <option value=\"musical\">{{ 'designer.timeline.grid-type-musical' | translate }}</option>\n </select>\n </div>\n </div>\n\n @if (gridType == 'musical') {\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.timeline.beats-per-minute' | translate }}</label>\n <div class=\"col-lg-8\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"beatsPerMinute\" (ngModelChange)=\"beatsPerMinute = $event\" />\n </div>\n </div>\n } @if (gridType == 'musical') {\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.timeline.time-signature' | translate }}</label>\n <div class=\"col-lg-8\">\n <input\n type=\"text\"\n class=\"form-control\"\n [ngModel]=\"timeSignatureUpper\"\n (ngModelChange)=\"timeSignatureUpper = $event\"\n style=\"float: left; width: 40px\"\n />\n <div class=\"d-flex px-2 h-100\" style=\"float: left\">\n <div class=\"m-auto\">/</div>\n </div>\n <input\n type=\"text\"\n class=\"form-control\"\n [ngModel]=\"timeSignatureLower\"\n (ngModelChange)=\"timeSignatureLower = $event\"\n style=\"width: 40px\"\n />\n </div>\n </div>\n } @if (gridType == 'musical') {\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.timeline.grid-resolution' | translate }}</label>\n <div class=\"col-lg-8\">\n <select class=\"custom-select\" [ngModel]=\"gridResolution\" (ngModelChange)=\"gridResolution = $event\">\n <option value=\"1\">1/1</option>\n <option value=\"2\">1/2</option>\n <option value=\"4\">1/4</option>\n <option value=\"8\">1/8</option>\n <option value=\"16\">1/16</option>\n <option value=\"32\">1/32</option>\n <option value=\"64\">1/64</option>\n </select>\n </div>\n </div>\n } @if (gridType == 'musical') {\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.timeline.grid-offset' | translate }}</label>\n <div class=\"col-lg-8\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"gridOffsetMillis\" (ngModelChange)=\"gridOffsetMillis = $event\" />\n </div>\n </div>\n }\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\"></label>\n <div class=\"col-lg-8\">\n <div class=\"form-check\">\n <input type=\"checkbox\" [ngModel]=\"snapToGrid\" (ngModelChange)=\"snapToGrid = $event\" class=\"form-check-input\" id=\"snapToGrid\" />\n\n <label class=\"form-check-label\" for=\"snapToGrid\">\n {{ 'designer.timeline.snap-to-grid' | translate }}\n </label>\n </div>\n </div>\n </div>\n</div>\n<div class=\"modal-footer\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"ok()\">{{ 'designer.misc.ok' | translate }}</button>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
6222
6305
  }
6223
6306
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TimelineGridComponent, decorators: [{
6224
6307
  type: Component,
@@ -6229,7 +6312,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
6229
6312
  }] } });
6230
6313
 
6231
6314
  class TimelineComponent {
6232
- constructor(timelineService, changeDetectorRef, modalService, uuidService, projectService, hotkeyTargetExcludeService, warningDialogService, http, configService, presetService, introService) {
6315
+ constructor(timelineService, changeDetectorRef, modalService, uuidService, projectService, hotkeyTargetExcludeService, warningDialogService, http, configService, introService, livePreviewService) {
6233
6316
  this.timelineService = timelineService;
6234
6317
  this.changeDetectorRef = changeDetectorRef;
6235
6318
  this.modalService = modalService;
@@ -6239,8 +6322,8 @@ class TimelineComponent {
6239
6322
  this.warningDialogService = warningDialogService;
6240
6323
  this.http = http;
6241
6324
  this.configService = configService;
6242
- this.presetService = presetService;
6243
6325
  this.introService = introService;
6326
+ this.livePreviewService = livePreviewService;
6244
6327
  this.timelineService.waveSurferReady.subscribe(() => {
6245
6328
  this.onResize();
6246
6329
  });
@@ -6271,12 +6354,12 @@ class TimelineComponent {
6271
6354
  }
6272
6355
  play() {
6273
6356
  this.timelineService.playState = 'playing';
6274
- this.presetService.previewLive(this.timelineService.selectedComposition.name, Math.round(this.timelineService.waveSurfer.getCurrentTime() * 1000));
6357
+ this.livePreviewService.previewLive(this.timelineService.selectedComposition.name, Math.round(this.timelineService.waveSurfer.getCurrentTime() * 1000));
6275
6358
  this.timelineService.waveSurfer.play();
6276
6359
  }
6277
6360
  pause() {
6278
6361
  this.timelineService.playState = 'paused';
6279
- this.presetService.stopPreviewPlay();
6362
+ this.livePreviewService.stopPreviewPlay();
6280
6363
  this.timelineService.waveSurfer.pause();
6281
6364
  }
6282
6365
  rewind() {
@@ -6397,13 +6480,13 @@ class TimelineComponent {
6397
6480
  this.timelineService.selectedPlaybackRegion.endMillis = +value;
6398
6481
  this.timelineService.updateSelectedRegion();
6399
6482
  }
6400
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TimelineComponent, deps: [{ token: TimelineService }, { token: i0.ChangeDetectorRef }, { token: i1$1.BsModalService }, { token: UuidService }, { token: ProjectService }, { token: HotkeyTargetExcludeService }, { token: WarningDialogService }, { token: i1.HttpClient }, { token: ConfigService }, { token: PresetService }, { token: IntroService }], target: i0.ɵɵFactoryTarget.Component }); }
6401
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: TimelineComponent, isStandalone: false, selector: "lib-app-timeline", host: { listeners: { "window:resize": "onResize()", "document:keydown": "handleKeyboardEvent($event)" } }, viewQueries: [{ propertyName: "waveWrapper", first: true, predicate: ["waveWrapper"], descendants: true }, { propertyName: "waveElement", first: true, predicate: ["waveElement"], descendants: true }], ngImport: i0, template: "<div class=\"card border-secondary h-100\" [class.card-intro-active]=\"introService.showStep('timeline')\">\n <div class=\"card-body h-100 d-flex\" style=\"flex-flow: column; overflow: unset\">\n <div class=\"d-flex pb-3\">\n <div class=\"btn-group mr-3 my-auto\" role=\"group\" style=\"float: left\">\n <a href=\"#\" class=\"btn btn-primary m-0 p-1 mr-3\" (click)=\"addComposition(); (false)\"\n ><i class=\"fa fa-plus-circle fa-fw\" aria-hidden=\"true\"></i\n ></a>\n\n @if (projectService.project.compositions.length > 0) {\n <select\n class=\"mr-3\"\n [ngModel]=\"timelineService.selectedCompositionIndex\"\n (ngModelChange)=\"selectComposition($event)\"\n style=\"width: 150px; height: 30px\"\n >\n @for (composition of projectService.project.compositions; track composition; let i = $index) {\n <option [value]=\"i\">\n {{ composition.name }}\n </option>\n }\n </select>\n } @if (timelineService.selectedComposition) {\n <div class=\"d-flex\">\n <a href=\"#\" class=\"btn btn-primary m-0 p-1\" (click)=\"rewind(); (false)\"\n ><i class=\"fa fa-step-backward fa-fw\" aria-hidden=\"true\"></i\n ></a>\n @if (timelineService.playState == 'paused') {\n <a href=\"#\" class=\"btn btn-primary m-0 p-1\" (click)=\"play(); (false)\"><i class=\"fa fa-play fa-fw\" aria-hidden=\"true\"></i></a>\n } @if (timelineService.playState == 'playing') {\n <a href=\"#\" class=\"btn btn-primary m-0 p-1\" (click)=\"pause(); (false)\"><i class=\"fa fa-pause fa-fw\" aria-hidden=\"true\"></i></a>\n }\n </div>\n }\n </div>\n\n @if (timelineService.selectedComposition) {\n <div class=\"d-flex w-100\">\n @if (timelineService.duration) {\n <div class=\"my-auto mr-3\">\n <span style=\"width: 78px; text-align: left; display: inline-block; margin-left: 5px\">{{ timelineService.currentTime }}</span>\n <span style=\"display: inline-block\"></span>- {{ timelineService.duration }}\n </div>\n }\n <div class=\"my-auto mr-3 ml-auto\" style=\"float: left\">\n <i (click)=\"timelineService.applyZoom(timelineService.zoom - 20)\" class=\"fa fa-search-minus mr-3\" aria-hidden=\"true\"></i>\n <mv-slider\n style=\"width: 80px\"\n [tooltip]=\"'hide'\"\n [value]=\"timelineService.zoom\"\n [min]=\"0\"\n [max]=\"200\"\n [step]=\"20\"\n (change)=\"timelineService.applyZoom($event.newValue)\"\n ></mv-slider>\n <i (click)=\"timelineService.applyZoom(timelineService.zoom + 20)\" class=\"fa fa-search-plus ml-3\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"my-auto mr-3\">\n <input\n type=\"text\"\n [ngModel]=\"timelineService.selectedPlaybackRegion?.startMillis\"\n (ngModelChange)=\"setRegionStartMillis($event)\"\n />\n - <input type=\"text\" [ngModel]=\"timelineService.selectedPlaybackRegion?.endMillis\" (ngModelChange)=\"setRegionEndMillis($event)\" />\n </div>\n <a\n href=\"#\"\n class=\"btn btn-secondary m-0 py-1 mr-3\"\n (click)=\"openGridSettings(); (false)\"\n popover=\"{{ 'designer.timeline.grid' | translate }}\"\n container=\"body\"\n placement=\"top\"\n triggers=\"mouseenter:mouseleave\"\n ><i class=\"fa fa-th\" aria-hidden=\"true\"></i\n ></a>\n <a\n href=\"#\"\n class=\"btn btn-secondary m-0 py-1 mr-3\"\n (click)=\"removeRegion(); (false)\"\n popover=\"{{ 'designer.timeline.remove-region' | translate }}\"\n container=\"body\"\n placement=\"top\"\n triggers=\"mouseenter:mouseleave\"\n ><i class=\"fa fa-minus-circle\" aria-hidden=\"true\"></i\n ></a>\n <a\n href=\"#\"\n class=\"btn btn-secondary m-0 py-1 mr-3\"\n (click)=\"addRegion(); (false)\"\n popover=\"{{ 'designer.timeline.add-region' | translate }}\"\n container=\"body\"\n placement=\"top\"\n triggers=\"mouseenter:mouseleave\"\n ><i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i\n ></a>\n <a\n href=\"#\"\n class=\"btn btn-secondary m-0 py-1 mr-3\"\n (click)=\"removeComposition(); (false)\"\n popover=\"{{ 'designer.timeline.remove-composition' | translate }}\"\n container=\"body\"\n placement=\"top\"\n triggers=\"mouseenter:mouseleave\"\n ><i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i\n ></a>\n <a\n href=\"#\"\n class=\"btn btn-secondary m-0 py-1\"\n (click)=\"compositionSettings(); (false)\"\n popover=\"{{ 'designer.timeline.composition-settings' | translate }}\"\n container=\"body\"\n placement=\"left\"\n triggers=\"mouseenter:mouseleave\"\n ><i class=\"fa fa-cog\" aria-hidden=\"true\"></i\n ></a>\n </div>\n }\n </div>\n\n @if (timelineService.loadingAudioFile) {\n <div class=\"w-100 d-flex\">\n <i class=\"fa fa-circle-o-notch fa-spin m-auto\" style=\"margin-top: -30px\"></i>\n </div>\n } @if (timelineService.selectedComposition) {\n <div>\n <div id=\"waveform-timeline\"></div>\n </div>\n } @if (timelineService.selectedComposition) {\n <div #waveWrapper class=\"h-100\" style=\"flex: 2; position: relative\">\n <div #waveElement id=\"waveform\"></div>\n </div>\n } @if (projectService.project.compositions.length == 0) {\n <div class=\"w-100 d-flex\">\n <a href=\"#\" class=\"m-auto\" (click)=\"addComposition(); (false)\"\n ><i class=\"fa fa-plus-circle fa-fw\" aria-hidden=\"true\"></i> {{ 'designer.timeline.no-compositions' | translate }}</a\n >\n </div>\n }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3$3.SliderComponent, selector: "mv-slider", inputs: ["style", "value", "min", "max", "step", "precision", "orientation", "range", "selection", "tooltip", "tooltipSplit", "tooltipPosition", "handle", "reversed", "rtl", "enabled", "naturalArrowKeys", "ticks", "ticksPositions", "ticksLabels", "ticksSnapBounds", "ticksTooltip", "scale", "labelledBy", "rangeHighlights", "formatter", "lockToTicks"], outputs: ["valueChange", "slide", "slideStart", "slideStop", "change"] }, { kind: "directive", type: i11.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
6483
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TimelineComponent, deps: [{ token: TimelineService }, { token: i0.ChangeDetectorRef }, { token: i1$1.BsModalService }, { token: UuidService }, { token: ProjectService }, { token: HotkeyTargetExcludeService }, { token: WarningDialogService }, { token: i1.HttpClient }, { token: ConfigService }, { token: IntroService }, { token: LivePreviewService }], target: i0.ɵɵFactoryTarget.Component }); }
6484
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: TimelineComponent, isStandalone: false, selector: "lib-app-timeline", host: { listeners: { "window:resize": "onResize()", "document:keydown": "handleKeyboardEvent($event)" } }, viewQueries: [{ propertyName: "waveWrapper", first: true, predicate: ["waveWrapper"], descendants: true }, { propertyName: "waveElement", first: true, predicate: ["waveElement"], descendants: true }], ngImport: i0, template: "<div class=\"card border-secondary h-100\" [class.card-intro-active]=\"introService.showStep('timeline')\">\n <div class=\"card-body h-100 d-flex\" style=\"flex-flow: column; overflow: unset\">\n <div class=\"d-flex pb-3\">\n <div class=\"btn-group mr-3 my-auto\" role=\"group\" style=\"float: left\">\n <a href=\"#\" class=\"btn btn-primary m-0 p-1 mr-3\" (click)=\"addComposition(); (false)\"\n ><i class=\"fa fa-plus-circle fa-fw\" aria-hidden=\"true\"></i\n ></a>\n\n @if (projectService.project.compositions.length > 0) {\n <select\n class=\"mr-3\"\n [ngModel]=\"timelineService.selectedCompositionIndex\"\n (ngModelChange)=\"selectComposition($event)\"\n style=\"width: 150px; height: 30px\"\n >\n @for (composition of projectService.project.compositions; track composition; let i = $index) {\n <option [value]=\"i\">\n {{ composition.name }}\n </option>\n }\n </select>\n } @if (timelineService.selectedComposition) {\n <div class=\"d-flex\">\n <a href=\"#\" class=\"btn btn-primary m-0 p-1\" (click)=\"rewind(); (false)\"\n ><i class=\"fa fa-step-backward fa-fw\" aria-hidden=\"true\"></i\n ></a>\n @if (timelineService.playState == 'paused') {\n <a href=\"#\" class=\"btn btn-primary m-0 p-1\" (click)=\"play(); (false)\"><i class=\"fa fa-play fa-fw\" aria-hidden=\"true\"></i></a>\n } @if (timelineService.playState == 'playing') {\n <a href=\"#\" class=\"btn btn-primary m-0 p-1\" (click)=\"pause(); (false)\"><i class=\"fa fa-pause fa-fw\" aria-hidden=\"true\"></i></a>\n }\n </div>\n }\n </div>\n\n @if (timelineService.selectedComposition) {\n <div class=\"d-flex w-100\">\n @if (timelineService.duration) {\n <div class=\"my-auto mr-3\">\n <span style=\"width: 78px; text-align: left; display: inline-block; margin-left: 5px\">{{ timelineService.currentTime }}</span>\n <span style=\"display: inline-block\"></span>- {{ timelineService.duration }}\n </div>\n }\n <div class=\"my-auto mr-3 ml-auto\" style=\"float: left\">\n <i (click)=\"timelineService.applyZoom(timelineService.zoom - 20)\" class=\"fa fa-search-minus mr-3\" aria-hidden=\"true\"></i>\n <mv-slider\n style=\"width: 80px\"\n [tooltip]=\"'hide'\"\n [value]=\"timelineService.zoom\"\n [min]=\"0\"\n [max]=\"200\"\n [step]=\"20\"\n (change)=\"timelineService.applyZoom($event.newValue)\"\n ></mv-slider>\n <i (click)=\"timelineService.applyZoom(timelineService.zoom + 20)\" class=\"fa fa-search-plus ml-3\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"my-auto mr-3\">\n <input\n type=\"text\"\n [ngModel]=\"timelineService.selectedPlaybackRegion?.startMillis\"\n (ngModelChange)=\"setRegionStartMillis($event)\"\n />\n - <input type=\"text\" [ngModel]=\"timelineService.selectedPlaybackRegion?.endMillis\" (ngModelChange)=\"setRegionEndMillis($event)\" />\n </div>\n <a\n href=\"#\"\n class=\"btn btn-secondary m-0 py-1 mr-3\"\n (click)=\"openGridSettings(); (false)\"\n popover=\"{{ 'designer.timeline.grid' | translate }}\"\n container=\"body\"\n placement=\"top\"\n triggers=\"mouseenter:mouseleave\"\n ><i class=\"fa fa-th\" aria-hidden=\"true\"></i\n ></a>\n <a\n href=\"#\"\n class=\"btn btn-secondary m-0 py-1 mr-3\"\n (click)=\"removeRegion(); (false)\"\n popover=\"{{ 'designer.timeline.remove-region' | translate }}\"\n container=\"body\"\n placement=\"top\"\n triggers=\"mouseenter:mouseleave\"\n ><i class=\"fa fa-minus-circle\" aria-hidden=\"true\"></i\n ></a>\n <a\n href=\"#\"\n class=\"btn btn-secondary m-0 py-1 mr-3\"\n (click)=\"addRegion(); (false)\"\n popover=\"{{ 'designer.timeline.add-region' | translate }}\"\n container=\"body\"\n placement=\"top\"\n triggers=\"mouseenter:mouseleave\"\n ><i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i\n ></a>\n <a\n href=\"#\"\n class=\"btn btn-secondary m-0 py-1 mr-3\"\n (click)=\"removeComposition(); (false)\"\n popover=\"{{ 'designer.timeline.remove-composition' | translate }}\"\n container=\"body\"\n placement=\"top\"\n triggers=\"mouseenter:mouseleave\"\n ><i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i\n ></a>\n <a\n href=\"#\"\n class=\"btn btn-secondary m-0 py-1\"\n (click)=\"compositionSettings(); (false)\"\n popover=\"{{ 'designer.timeline.composition-settings' | translate }}\"\n container=\"body\"\n placement=\"left\"\n triggers=\"mouseenter:mouseleave\"\n ><i class=\"fa fa-cog\" aria-hidden=\"true\"></i\n ></a>\n </div>\n }\n </div>\n\n @if (timelineService.loadingAudioFile) {\n <div class=\"w-100 d-flex\">\n <i class=\"fa fa-circle-o-notch fa-spin m-auto\" style=\"margin-top: -30px\"></i>\n </div>\n } @if (timelineService.selectedComposition) {\n <div>\n <div id=\"waveform-timeline\"></div>\n </div>\n } @if (timelineService.selectedComposition) {\n <div #waveWrapper class=\"h-100\" style=\"flex: 2; position: relative\">\n <div #waveElement id=\"waveform\"></div>\n </div>\n } @if (projectService.project.compositions.length == 0) {\n <div class=\"w-100 d-flex\">\n <a href=\"#\" class=\"m-auto\" (click)=\"addComposition(); (false)\"\n ><i class=\"fa fa-plus-circle fa-fw\" aria-hidden=\"true\"></i> {{ 'designer.timeline.no-compositions' | translate }}</a\n >\n </div>\n }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.SliderComponent, selector: "mv-slider", inputs: ["style", "value", "min", "max", "step", "precision", "orientation", "range", "selection", "tooltip", "tooltipSplit", "tooltipPosition", "handle", "reversed", "rtl", "enabled", "naturalArrowKeys", "ticks", "ticksPositions", "ticksLabels", "ticksSnapBounds", "ticksTooltip", "scale", "labelledBy", "rangeHighlights", "formatter", "lockToTicks"], outputs: ["valueChange", "slide", "slideStart", "slideStop", "change"] }, { kind: "directive", type: i12.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
6402
6485
  }
6403
6486
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TimelineComponent, decorators: [{
6404
6487
  type: Component,
6405
6488
  args: [{ selector: 'lib-app-timeline', standalone: false, template: "<div class=\"card border-secondary h-100\" [class.card-intro-active]=\"introService.showStep('timeline')\">\n <div class=\"card-body h-100 d-flex\" style=\"flex-flow: column; overflow: unset\">\n <div class=\"d-flex pb-3\">\n <div class=\"btn-group mr-3 my-auto\" role=\"group\" style=\"float: left\">\n <a href=\"#\" class=\"btn btn-primary m-0 p-1 mr-3\" (click)=\"addComposition(); (false)\"\n ><i class=\"fa fa-plus-circle fa-fw\" aria-hidden=\"true\"></i\n ></a>\n\n @if (projectService.project.compositions.length > 0) {\n <select\n class=\"mr-3\"\n [ngModel]=\"timelineService.selectedCompositionIndex\"\n (ngModelChange)=\"selectComposition($event)\"\n style=\"width: 150px; height: 30px\"\n >\n @for (composition of projectService.project.compositions; track composition; let i = $index) {\n <option [value]=\"i\">\n {{ composition.name }}\n </option>\n }\n </select>\n } @if (timelineService.selectedComposition) {\n <div class=\"d-flex\">\n <a href=\"#\" class=\"btn btn-primary m-0 p-1\" (click)=\"rewind(); (false)\"\n ><i class=\"fa fa-step-backward fa-fw\" aria-hidden=\"true\"></i\n ></a>\n @if (timelineService.playState == 'paused') {\n <a href=\"#\" class=\"btn btn-primary m-0 p-1\" (click)=\"play(); (false)\"><i class=\"fa fa-play fa-fw\" aria-hidden=\"true\"></i></a>\n } @if (timelineService.playState == 'playing') {\n <a href=\"#\" class=\"btn btn-primary m-0 p-1\" (click)=\"pause(); (false)\"><i class=\"fa fa-pause fa-fw\" aria-hidden=\"true\"></i></a>\n }\n </div>\n }\n </div>\n\n @if (timelineService.selectedComposition) {\n <div class=\"d-flex w-100\">\n @if (timelineService.duration) {\n <div class=\"my-auto mr-3\">\n <span style=\"width: 78px; text-align: left; display: inline-block; margin-left: 5px\">{{ timelineService.currentTime }}</span>\n <span style=\"display: inline-block\"></span>- {{ timelineService.duration }}\n </div>\n }\n <div class=\"my-auto mr-3 ml-auto\" style=\"float: left\">\n <i (click)=\"timelineService.applyZoom(timelineService.zoom - 20)\" class=\"fa fa-search-minus mr-3\" aria-hidden=\"true\"></i>\n <mv-slider\n style=\"width: 80px\"\n [tooltip]=\"'hide'\"\n [value]=\"timelineService.zoom\"\n [min]=\"0\"\n [max]=\"200\"\n [step]=\"20\"\n (change)=\"timelineService.applyZoom($event.newValue)\"\n ></mv-slider>\n <i (click)=\"timelineService.applyZoom(timelineService.zoom + 20)\" class=\"fa fa-search-plus ml-3\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"my-auto mr-3\">\n <input\n type=\"text\"\n [ngModel]=\"timelineService.selectedPlaybackRegion?.startMillis\"\n (ngModelChange)=\"setRegionStartMillis($event)\"\n />\n - <input type=\"text\" [ngModel]=\"timelineService.selectedPlaybackRegion?.endMillis\" (ngModelChange)=\"setRegionEndMillis($event)\" />\n </div>\n <a\n href=\"#\"\n class=\"btn btn-secondary m-0 py-1 mr-3\"\n (click)=\"openGridSettings(); (false)\"\n popover=\"{{ 'designer.timeline.grid' | translate }}\"\n container=\"body\"\n placement=\"top\"\n triggers=\"mouseenter:mouseleave\"\n ><i class=\"fa fa-th\" aria-hidden=\"true\"></i\n ></a>\n <a\n href=\"#\"\n class=\"btn btn-secondary m-0 py-1 mr-3\"\n (click)=\"removeRegion(); (false)\"\n popover=\"{{ 'designer.timeline.remove-region' | translate }}\"\n container=\"body\"\n placement=\"top\"\n triggers=\"mouseenter:mouseleave\"\n ><i class=\"fa fa-minus-circle\" aria-hidden=\"true\"></i\n ></a>\n <a\n href=\"#\"\n class=\"btn btn-secondary m-0 py-1 mr-3\"\n (click)=\"addRegion(); (false)\"\n popover=\"{{ 'designer.timeline.add-region' | translate }}\"\n container=\"body\"\n placement=\"top\"\n triggers=\"mouseenter:mouseleave\"\n ><i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i\n ></a>\n <a\n href=\"#\"\n class=\"btn btn-secondary m-0 py-1 mr-3\"\n (click)=\"removeComposition(); (false)\"\n popover=\"{{ 'designer.timeline.remove-composition' | translate }}\"\n container=\"body\"\n placement=\"top\"\n triggers=\"mouseenter:mouseleave\"\n ><i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i\n ></a>\n <a\n href=\"#\"\n class=\"btn btn-secondary m-0 py-1\"\n (click)=\"compositionSettings(); (false)\"\n popover=\"{{ 'designer.timeline.composition-settings' | translate }}\"\n container=\"body\"\n placement=\"left\"\n triggers=\"mouseenter:mouseleave\"\n ><i class=\"fa fa-cog\" aria-hidden=\"true\"></i\n ></a>\n </div>\n }\n </div>\n\n @if (timelineService.loadingAudioFile) {\n <div class=\"w-100 d-flex\">\n <i class=\"fa fa-circle-o-notch fa-spin m-auto\" style=\"margin-top: -30px\"></i>\n </div>\n } @if (timelineService.selectedComposition) {\n <div>\n <div id=\"waveform-timeline\"></div>\n </div>\n } @if (timelineService.selectedComposition) {\n <div #waveWrapper class=\"h-100\" style=\"flex: 2; position: relative\">\n <div #waveElement id=\"waveform\"></div>\n </div>\n } @if (projectService.project.compositions.length == 0) {\n <div class=\"w-100 d-flex\">\n <a href=\"#\" class=\"m-auto\" (click)=\"addComposition(); (false)\"\n ><i class=\"fa fa-plus-circle fa-fw\" aria-hidden=\"true\"></i> {{ 'designer.timeline.no-compositions' | translate }}</a\n >\n </div>\n }\n </div>\n</div>\n" }]
6406
- }], ctorParameters: () => [{ type: TimelineService }, { type: i0.ChangeDetectorRef }, { type: i1$1.BsModalService }, { type: UuidService }, { type: ProjectService }, { type: HotkeyTargetExcludeService }, { type: WarningDialogService }, { type: i1.HttpClient }, { type: ConfigService }, { type: PresetService }, { type: IntroService }], propDecorators: { waveWrapper: [{
6489
+ }], ctorParameters: () => [{ type: TimelineService }, { type: i0.ChangeDetectorRef }, { type: i1$1.BsModalService }, { type: UuidService }, { type: ProjectService }, { type: HotkeyTargetExcludeService }, { type: WarningDialogService }, { type: i1.HttpClient }, { type: ConfigService }, { type: IntroService }, { type: LivePreviewService }], propDecorators: { waveWrapper: [{
6407
6490
  type: ViewChild,
6408
6491
  args: ['waveWrapper']
6409
6492
  }], waveElement: [{
@@ -6447,7 +6530,7 @@ class SceneSettingsComponent {
6447
6530
  this.ok();
6448
6531
  }
6449
6532
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: SceneSettingsComponent, deps: [{ token: i1$1.BsModalRef }], target: i0.ɵɵFactoryTarget.Component }); }
6450
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: SceneSettingsComponent, isStandalone: false, selector: "lib-scene-settings", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ name }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"bsModalRef.hide()\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.preset.settings-name' | translate }}</label>\n <div class=\"col-lg-7\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"name\" (ngModelChange)=\"name = $event\" />\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.scene.settings-fade-in' | translate }}</label>\n <div class=\"col-lg-7\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"fadeInMillis\" (ngModelChange)=\"fadeInMillis = $event\" />\n </div>\n <div class=\"col-lg-1 d-flex p-0\">\n <div class=\"my-auto\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\"></label>\n <div class=\"col-lg-8 d-flex\">\n <div class=\"form-check my-auto\">\n <input type=\"checkbox\" [ngModel]=\"fadeInPre\" (ngModelChange)=\"fadeInPre = $event\" class=\"form-check-input\" id=\"fadeInPre\" />\n\n <label class=\"form-check-label\" for=\"fadeInPre\">\n {{ 'designer.scene.settings-fade-in-pre' | translate }}\n </label>\n </div>\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.scene.settings-fade-out' | translate }}</label>\n <div class=\"col-lg-7\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"fadeOutMillis\" (ngModelChange)=\"fadeOutMillis = $event\" />\n </div>\n <div class=\"col-lg-1 d-flex p-0\">\n <div class=\"my-auto\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\"></label>\n <div class=\"col-lg-8 d-flex\">\n <div class=\"form-check my-auto\">\n <input type=\"checkbox\" [ngModel]=\"fadeOutPost\" (ngModelChange)=\"fadeOutPost = $event\" class=\"form-check-input\" id=\"fadeOutPost\" />\n\n <label class=\"form-check-label\" for=\"fadeOutPost\">\n {{ 'designer.scene.settings-fade-out-post' | translate }}\n </label>\n </div>\n </div>\n </div>\n</div>\n<div class=\"modal-footer\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"ok()\">{{ 'designer.misc.ok' | translate }}</button>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
6533
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: SceneSettingsComponent, isStandalone: false, selector: "lib-scene-settings", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ name }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"bsModalRef.hide()\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.preset.settings-name' | translate }}</label>\n <div class=\"col-lg-7\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"name\" (ngModelChange)=\"name = $event\" />\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.scene.settings-fade-in' | translate }}</label>\n <div class=\"col-lg-7\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"fadeInMillis\" (ngModelChange)=\"fadeInMillis = $event\" />\n </div>\n <div class=\"col-lg-1 d-flex p-0\">\n <div class=\"my-auto\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\"></label>\n <div class=\"col-lg-8 d-flex\">\n <div class=\"form-check my-auto\">\n <input type=\"checkbox\" [ngModel]=\"fadeInPre\" (ngModelChange)=\"fadeInPre = $event\" class=\"form-check-input\" id=\"fadeInPre\" />\n\n <label class=\"form-check-label\" for=\"fadeInPre\">\n {{ 'designer.scene.settings-fade-in-pre' | translate }}\n </label>\n </div>\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.scene.settings-fade-out' | translate }}</label>\n <div class=\"col-lg-7\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"fadeOutMillis\" (ngModelChange)=\"fadeOutMillis = $event\" />\n </div>\n <div class=\"col-lg-1 d-flex p-0\">\n <div class=\"my-auto\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\"></label>\n <div class=\"col-lg-8 d-flex\">\n <div class=\"form-check my-auto\">\n <input type=\"checkbox\" [ngModel]=\"fadeOutPost\" (ngModelChange)=\"fadeOutPost = $event\" class=\"form-check-input\" id=\"fadeOutPost\" />\n\n <label class=\"form-check-label\" for=\"fadeOutPost\">\n {{ 'designer.scene.settings-fade-out-post' | translate }}\n </label>\n </div>\n </div>\n </div>\n</div>\n<div class=\"modal-footer\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"ok()\">{{ 'designer.misc.ok' | translate }}</button>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
6451
6534
  }
6452
6535
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: SceneSettingsComponent, decorators: [{
6453
6536
  type: Component,
@@ -6484,7 +6567,7 @@ class SceneComponent {
6484
6567
  });
6485
6568
  }
6486
6569
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: SceneComponent, deps: [{ token: SceneService }, { token: PresetService }, { token: ProjectService }, { token: i1$1.BsModalService }, { token: IntroService }], target: i0.ɵɵFactoryTarget.Component }); }
6487
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: SceneComponent, isStandalone: false, selector: "lib-app-scene", ngImport: i0, template: "<div class=\"card border-secondary panel h-100\" [class.card-intro-active]=\"introService.showStep('scenes')\">\n <div class=\"card-header d-flex\">\n <div>\n {{ 'designer.scene.title' | translate }}\n </div>\n <div class=\"ml-auto\">\n <a\n href=\"#\"\n class=\"d-none d-md-inline-block btn btn-secondary m-0 p-0\"\n [class.text-primary]=\"sceneService.multipleSelection == true\"\n (click)=\"sceneService.multipleSelection = !sceneService.multipleSelection; (false)\"\n ><i class=\"fa fa-object-group fa-fw\" aria-hidden=\"true\"></i\n ></a>\n <a href=\"#\" class=\"d-none d-md-inline-block btn btn-secondary m-0 p-0\" (click)=\"removeScene(); (false)\"\n ><i class=\"fa fa-minus-circle fa-fw\" aria-hidden=\"true\"></i\n ></a>\n <a href=\"#\" class=\"d-none d-md-inline-block btn btn-secondary m-0 p-0\" (click)=\"sceneService.addScene(); (false)\"\n ><i class=\"fa fa-plus-circle fa-fw\" aria-hidden=\"true\"></i\n ></a>\n </div>\n </div>\n <div class=\"card-body border-secondary p-0\">\n <!-- List of scenes -->\n <div class=\"list-group\" [sortablejs]=\"projectService.project.scenes\">\n @for (scene of projectService.project.scenes; track scene; let i = $index) {\n <div\n class=\"list-group-item\"\n [class.active-light]=\"projectService.project.previewPreset && sceneService.sceneIsSelected(scene)\"\n [class.active]=\"!projectService.project.previewPreset && sceneService.sceneIsSelected(scene)\"\n >\n <div class=\"row d-flex\" (click)=\"selectScene($event, i)\" style=\"cursor: pointer\">\n <div class=\"d-none d-md-block col-auto list-sort-handle my-auto\" style=\"cursor: move; cursor: -webkit-grabbing\">\n <i class=\"fa fa-bars\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"my-auto\">\n {{ scene.name }}\n </div>\n <div class=\"my-auto ml-auto mr-2 d-flex\">\n <svg class=\"my-auto\" height=\"20\" width=\"20\">\n <circle cx=\"10\" cy=\"10\" r=\"9\" stroke=\"white\" stroke-width=\"1\" [attr.fill]=\"scene.color\" />\n </svg>\n </div>\n <div class=\"d-none d-md-flex my-auto mr-2\">\n <button type=\"button\" class=\"btn btn-secondary btn-sm py-0 px-1\" (click)=\"openSettings(scene); (false)\">...</button>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: SortablejsDirective, selector: "[sortablejs]", inputs: ["sortablejs", "sortablejsContainer", "sortablejsOptions"], outputs: ["sortablejsInit"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
6570
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: SceneComponent, isStandalone: false, selector: "lib-app-scene", ngImport: i0, template: "<div class=\"card border-secondary panel h-100\" [class.card-intro-active]=\"introService.showStep('scenes')\">\n <div class=\"card-header d-flex\">\n <div>\n {{ 'designer.scene.title' | translate }}\n </div>\n <div class=\"ml-auto\">\n <a\n href=\"#\"\n class=\"d-none d-md-inline-block btn btn-secondary m-0 p-0\"\n [class.text-primary]=\"sceneService.multipleSelection == true\"\n (click)=\"sceneService.multipleSelection = !sceneService.multipleSelection; (false)\"\n ><i class=\"fa fa-object-group fa-fw\" aria-hidden=\"true\"></i\n ></a>\n <a href=\"#\" class=\"d-none d-md-inline-block btn btn-secondary m-0 p-0\" (click)=\"removeScene(); (false)\"\n ><i class=\"fa fa-minus-circle fa-fw\" aria-hidden=\"true\"></i\n ></a>\n <a href=\"#\" class=\"d-none d-md-inline-block btn btn-secondary m-0 p-0\" (click)=\"sceneService.addScene(); (false)\"\n ><i class=\"fa fa-plus-circle fa-fw\" aria-hidden=\"true\"></i\n ></a>\n </div>\n </div>\n <div class=\"card-body border-secondary p-0\">\n <!-- List of scenes -->\n <div class=\"list-group\" [sortablejs]=\"projectService.project.scenes\">\n @for (scene of projectService.project.scenes; track scene; let i = $index) {\n <div\n class=\"list-group-item\"\n [class.active-light]=\"projectService.project.previewPreset && sceneService.sceneIsSelected(scene)\"\n [class.active]=\"!projectService.project.previewPreset && sceneService.sceneIsSelected(scene)\"\n >\n <div class=\"row d-flex\" (click)=\"selectScene($event, i)\" style=\"cursor: pointer\">\n <div class=\"d-none d-md-block col-auto list-sort-handle my-auto\" style=\"cursor: move; cursor: -webkit-grabbing\">\n <i class=\"fa fa-bars\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"my-auto\">\n {{ scene.name }}\n </div>\n <div class=\"my-auto ml-auto mr-2 d-flex\">\n <svg class=\"my-auto\" height=\"20\" width=\"20\">\n <circle cx=\"10\" cy=\"10\" r=\"9\" stroke=\"white\" stroke-width=\"1\" [attr.fill]=\"scene.color\" />\n </svg>\n </div>\n <div class=\"d-none d-md-flex my-auto mr-2\">\n <button type=\"button\" class=\"btn btn-secondary btn-sm py-0 px-1\" (click)=\"openSettings(scene); (false)\">...</button>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: SortablejsDirective, selector: "[sortablejs]", inputs: ["sortablejs", "sortablejsContainer", "sortablejsOptions"], outputs: ["sortablejsInit"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
6488
6571
  }
6489
6572
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: SceneComponent, decorators: [{
6490
6573
  type: Component,
@@ -6492,12 +6575,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
6492
6575
  }], ctorParameters: () => [{ type: SceneService }, { type: PresetService }, { type: ProjectService }, { type: i1$1.BsModalService }, { type: IntroService }] });
6493
6576
 
6494
6577
  class FixtureComponent {
6495
- constructor(projectService, presetService, fixturePoolService, fixtureService, introService) {
6578
+ constructor(projectService, presetService, fixturePoolService, fixtureService, introService, livePreviewService) {
6496
6579
  this.projectService = projectService;
6497
6580
  this.presetService = presetService;
6498
6581
  this.fixturePoolService = fixturePoolService;
6499
6582
  this.fixtureService = fixtureService;
6500
6583
  this.introService = introService;
6584
+ this.livePreviewService = livePreviewService;
6585
+ this.fixtureSortableOptions = {
6586
+ onUpdate: () => this.fixtureListReordered(),
6587
+ };
6501
6588
  }
6502
6589
  ngOnInit() { }
6503
6590
  fixtureName(presetFixture) {
@@ -6528,7 +6615,7 @@ class FixtureComponent {
6528
6615
  // select fixtures for the current preset
6529
6616
  this.presetService.switchFixtureSelection(fixture, presetFixture.pixelKey);
6530
6617
  this.presetService.fixtureSelectionChanged.next();
6531
- this.presetService.previewLive();
6618
+ this.livePreviewService.previewLive();
6532
6619
  }
6533
6620
  }
6534
6621
  selectAll() {
@@ -6539,22 +6626,26 @@ class FixtureComponent {
6539
6626
  this.presetService.selectNoFixtures();
6540
6627
  this.presetService.fixtureSelectionChanged.next();
6541
6628
  }
6629
+ fixtureListReordered() {
6630
+ this.livePreviewService.previewLive();
6631
+ }
6542
6632
  openFixturePool() {
6543
6633
  this.fixturePoolService.open();
6544
6634
  }
6545
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureComponent, deps: [{ token: ProjectService }, { token: PresetService }, { token: FixturePoolService }, { token: FixtureService }, { token: IntroService }], target: i0.ɵɵFactoryTarget.Component }); }
6546
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: FixtureComponent, isStandalone: false, selector: "lib-app-fixture", ngImport: i0, template: "<div class=\"card border-secondary h-100 panel\" [class.card-intro-active]=\"introService.showStep('fixtures')\">\n <div class=\"card-header d-flex\">\n <div>Fixtures</div>\n <div class=\"ml-auto\">\n <a href=\"#\" class=\"btn btn-secondary m-0, p-0\" (click)=\"selectNone(); (false)\"\n ><i class=\"fa fa-square-o fa-fw\" aria-hidden=\"true\"></i\n ></a>\n <a href=\"#\" class=\"btn btn-secondary m-0, p-0\" (click)=\"selectAll(); (false)\"\n ><i class=\"fa fa-check-square-o fa-fw\" aria-hidden=\"true\"></i\n ></a>\n <a href=\"#\" class=\"btn btn-secondary m-0, p-0\" (click)=\"openFixturePool(); (false)\"\n ><i class=\"fa fa-cog fa-fw\" aria-hidden=\"true\"></i\n ></a>\n </div>\n </div>\n\n <div class=\"card-body h-100 p-0\">\n <!-- List of fixtures -->\n @if (presetService.selectedPreset) {\n <div class=\"list-group\" [sortablejs]=\"projectService.project.presetFixtures\">\n @for (presetFixture of projectService.project.presetFixtures; track presetFixture) {\n <div class=\"list-group-item\" [class.inactive-list-item]=\"!fixtureIsSelected(presetFixture)\">\n <div class=\"row d-flex\" (click)=\"selectFixture($event, presetFixture)\" style=\"cursor: pointer\">\n <div class=\"col-auto list-sort-handle my-auto\" style=\"cursor: move; cursor: -webkit-grabbing\">\n <i class=\"fa fa-bars\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"form-check\">\n <input type=\"checkbox\" class=\"form-check-input\" id=\"active\" [ngModel]=\"fixtureIsSelected(presetFixture)\" />\n </div>\n <div>\n <span\n class=\"icon-{{\n fixtureService.getFixtureIconClass(\n fixtureService.getProfileByUuid(fixtureService.getFixtureByUuid(presetFixture.fixtureUuid).profileUuid)\n )\n }} mr-1\"\n ></span>\n {{ fixtureName(presetFixture) }}\n </div>\n </div>\n </div>\n }\n </div>\n } @if (projectService.project.presetFixtures.length == 0) {\n <div class=\"w-100 h-100 d-flex p-3 text-center\">\n <a href=\"#\" class=\"m-auto\" (click)=\"openFixturePool(); (false)\"\n ><i class=\"fa fa-plus-circle fa-fw\" aria-hidden=\"true\"></i> {{ 'designer.fixture.no-fixtures' | translate }}</a\n >\n </div>\n }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: SortablejsDirective, selector: "[sortablejs]", inputs: ["sortablejs", "sortablejsContainer", "sortablejsOptions"], outputs: ["sortablejsInit"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
6635
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureComponent, deps: [{ token: ProjectService }, { token: PresetService }, { token: FixturePoolService }, { token: FixtureService }, { token: IntroService }, { token: LivePreviewService }], target: i0.ɵɵFactoryTarget.Component }); }
6636
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: FixtureComponent, isStandalone: false, selector: "lib-app-fixture", ngImport: i0, template: "<div class=\"card border-secondary h-100 panel\" [class.card-intro-active]=\"introService.showStep('fixtures')\">\n <div class=\"card-header d-flex\">\n <div>Fixtures</div>\n <div class=\"ml-auto\">\n <a href=\"#\" class=\"btn btn-secondary m-0, p-0\" (click)=\"selectNone(); (false)\"\n ><i class=\"fa fa-square-o fa-fw\" aria-hidden=\"true\"></i\n ></a>\n <a href=\"#\" class=\"btn btn-secondary m-0, p-0\" (click)=\"selectAll(); (false)\"\n ><i class=\"fa fa-check-square-o fa-fw\" aria-hidden=\"true\"></i\n ></a>\n <a href=\"#\" class=\"btn btn-secondary m-0, p-0\" (click)=\"openFixturePool(); (false)\"\n ><i class=\"fa fa-cog fa-fw\" aria-hidden=\"true\"></i\n ></a>\n </div>\n </div>\n\n <div class=\"card-body h-100 p-0\">\n <!-- List of fixtures -->\n @if (presetService.selectedPreset) {\n <div class=\"list-group\" [sortablejs]=\"projectService.project.presetFixtures\" [sortablejsOptions]=\"fixtureSortableOptions\">\n @for (presetFixture of projectService.project.presetFixtures; track presetFixture) {\n <div class=\"list-group-item\" [class.inactive-list-item]=\"!fixtureIsSelected(presetFixture)\">\n <div class=\"row d-flex\" (click)=\"selectFixture($event, presetFixture)\" style=\"cursor: pointer\">\n <div class=\"col-auto list-sort-handle my-auto\" style=\"cursor: move; cursor: -webkit-grabbing\">\n <i class=\"fa fa-bars\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"form-check\">\n <input type=\"checkbox\" class=\"form-check-input\" id=\"active\" [ngModel]=\"fixtureIsSelected(presetFixture)\" />\n </div>\n <div>\n <span\n class=\"icon-{{\n fixtureService.getFixtureIconClass(\n fixtureService.getProfileByUuid(fixtureService.getFixtureByUuid(presetFixture.fixtureUuid).profileUuid)\n )\n }} mr-1\"\n ></span>\n {{ fixtureName(presetFixture) }}\n </div>\n </div>\n </div>\n }\n </div>\n } @if (projectService.project.presetFixtures.length == 0) {\n <div class=\"w-100 h-100 d-flex p-3 text-center\">\n <a href=\"#\" class=\"m-auto\" (click)=\"openFixturePool(); (false)\"\n ><i class=\"fa fa-plus-circle fa-fw\" aria-hidden=\"true\"></i> {{ 'designer.fixture.no-fixtures' | translate }}</a\n >\n </div>\n }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: SortablejsDirective, selector: "[sortablejs]", inputs: ["sortablejs", "sortablejsContainer", "sortablejsOptions"], outputs: ["sortablejsInit"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
6547
6637
  }
6548
6638
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureComponent, decorators: [{
6549
6639
  type: Component,
6550
- args: [{ selector: 'lib-app-fixture', standalone: false, template: "<div class=\"card border-secondary h-100 panel\" [class.card-intro-active]=\"introService.showStep('fixtures')\">\n <div class=\"card-header d-flex\">\n <div>Fixtures</div>\n <div class=\"ml-auto\">\n <a href=\"#\" class=\"btn btn-secondary m-0, p-0\" (click)=\"selectNone(); (false)\"\n ><i class=\"fa fa-square-o fa-fw\" aria-hidden=\"true\"></i\n ></a>\n <a href=\"#\" class=\"btn btn-secondary m-0, p-0\" (click)=\"selectAll(); (false)\"\n ><i class=\"fa fa-check-square-o fa-fw\" aria-hidden=\"true\"></i\n ></a>\n <a href=\"#\" class=\"btn btn-secondary m-0, p-0\" (click)=\"openFixturePool(); (false)\"\n ><i class=\"fa fa-cog fa-fw\" aria-hidden=\"true\"></i\n ></a>\n </div>\n </div>\n\n <div class=\"card-body h-100 p-0\">\n <!-- List of fixtures -->\n @if (presetService.selectedPreset) {\n <div class=\"list-group\" [sortablejs]=\"projectService.project.presetFixtures\">\n @for (presetFixture of projectService.project.presetFixtures; track presetFixture) {\n <div class=\"list-group-item\" [class.inactive-list-item]=\"!fixtureIsSelected(presetFixture)\">\n <div class=\"row d-flex\" (click)=\"selectFixture($event, presetFixture)\" style=\"cursor: pointer\">\n <div class=\"col-auto list-sort-handle my-auto\" style=\"cursor: move; cursor: -webkit-grabbing\">\n <i class=\"fa fa-bars\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"form-check\">\n <input type=\"checkbox\" class=\"form-check-input\" id=\"active\" [ngModel]=\"fixtureIsSelected(presetFixture)\" />\n </div>\n <div>\n <span\n class=\"icon-{{\n fixtureService.getFixtureIconClass(\n fixtureService.getProfileByUuid(fixtureService.getFixtureByUuid(presetFixture.fixtureUuid).profileUuid)\n )\n }} mr-1\"\n ></span>\n {{ fixtureName(presetFixture) }}\n </div>\n </div>\n </div>\n }\n </div>\n } @if (projectService.project.presetFixtures.length == 0) {\n <div class=\"w-100 h-100 d-flex p-3 text-center\">\n <a href=\"#\" class=\"m-auto\" (click)=\"openFixturePool(); (false)\"\n ><i class=\"fa fa-plus-circle fa-fw\" aria-hidden=\"true\"></i> {{ 'designer.fixture.no-fixtures' | translate }}</a\n >\n </div>\n }\n </div>\n</div>\n" }]
6551
- }], ctorParameters: () => [{ type: ProjectService }, { type: PresetService }, { type: FixturePoolService }, { type: FixtureService }, { type: IntroService }] });
6640
+ args: [{ selector: 'lib-app-fixture', standalone: false, template: "<div class=\"card border-secondary h-100 panel\" [class.card-intro-active]=\"introService.showStep('fixtures')\">\n <div class=\"card-header d-flex\">\n <div>Fixtures</div>\n <div class=\"ml-auto\">\n <a href=\"#\" class=\"btn btn-secondary m-0, p-0\" (click)=\"selectNone(); (false)\"\n ><i class=\"fa fa-square-o fa-fw\" aria-hidden=\"true\"></i\n ></a>\n <a href=\"#\" class=\"btn btn-secondary m-0, p-0\" (click)=\"selectAll(); (false)\"\n ><i class=\"fa fa-check-square-o fa-fw\" aria-hidden=\"true\"></i\n ></a>\n <a href=\"#\" class=\"btn btn-secondary m-0, p-0\" (click)=\"openFixturePool(); (false)\"\n ><i class=\"fa fa-cog fa-fw\" aria-hidden=\"true\"></i\n ></a>\n </div>\n </div>\n\n <div class=\"card-body h-100 p-0\">\n <!-- List of fixtures -->\n @if (presetService.selectedPreset) {\n <div class=\"list-group\" [sortablejs]=\"projectService.project.presetFixtures\" [sortablejsOptions]=\"fixtureSortableOptions\">\n @for (presetFixture of projectService.project.presetFixtures; track presetFixture) {\n <div class=\"list-group-item\" [class.inactive-list-item]=\"!fixtureIsSelected(presetFixture)\">\n <div class=\"row d-flex\" (click)=\"selectFixture($event, presetFixture)\" style=\"cursor: pointer\">\n <div class=\"col-auto list-sort-handle my-auto\" style=\"cursor: move; cursor: -webkit-grabbing\">\n <i class=\"fa fa-bars\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"form-check\">\n <input type=\"checkbox\" class=\"form-check-input\" id=\"active\" [ngModel]=\"fixtureIsSelected(presetFixture)\" />\n </div>\n <div>\n <span\n class=\"icon-{{\n fixtureService.getFixtureIconClass(\n fixtureService.getProfileByUuid(fixtureService.getFixtureByUuid(presetFixture.fixtureUuid).profileUuid)\n )\n }} mr-1\"\n ></span>\n {{ fixtureName(presetFixture) }}\n </div>\n </div>\n </div>\n }\n </div>\n } @if (projectService.project.presetFixtures.length == 0) {\n <div class=\"w-100 h-100 d-flex p-3 text-center\">\n <a href=\"#\" class=\"m-auto\" (click)=\"openFixturePool(); (false)\"\n ><i class=\"fa fa-plus-circle fa-fw\" aria-hidden=\"true\"></i> {{ 'designer.fixture.no-fixtures' | translate }}</a\n >\n </div>\n }\n </div>\n</div>\n" }]
6641
+ }], ctorParameters: () => [{ type: ProjectService }, { type: PresetService }, { type: FixturePoolService }, { type: FixtureService }, { type: IntroService }, { type: LivePreviewService }] });
6552
6642
 
6553
6643
  class FixtureCapabilityColorComponent {
6554
- constructor(presetService, fixtureService, changeDetectorRef) {
6644
+ constructor(presetService, fixtureService, changeDetectorRef, livePreviewService) {
6555
6645
  this.presetService = presetService;
6556
6646
  this.fixtureService = fixtureService;
6557
6647
  this.changeDetectorRef = changeDetectorRef;
6648
+ this.livePreviewService = livePreviewService;
6558
6649
  this.color = '#ffffff';
6559
6650
  this.active = false;
6560
6651
  this.colorPickerMounted = false;
@@ -6634,7 +6725,7 @@ class FixtureCapabilityColorComponent {
6634
6725
  }
6635
6726
  this.changeDetectorRef.detectChanges();
6636
6727
  this.presetService.fixtureColorChanged.next();
6637
- this.presetService.previewLive();
6728
+ this.livePreviewService.previewLive();
6638
6729
  }
6639
6730
  }
6640
6731
  changeActive(active) {
@@ -6647,7 +6738,7 @@ class FixtureCapabilityColorComponent {
6647
6738
  this.setPickerColor(255, 255, 255);
6648
6739
  this.color = '#ffffff';
6649
6740
  }
6650
- this.presetService.previewLive();
6741
+ this.livePreviewService.previewLive();
6651
6742
  }
6652
6743
  changeColor(color) {
6653
6744
  if (!this.colorPickerMounted || this.updatingColor) {
@@ -6657,18 +6748,19 @@ class FixtureCapabilityColorComponent {
6657
6748
  this.color = color.hexString;
6658
6749
  this.updateFixtureColor(color);
6659
6750
  }
6660
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureCapabilityColorComponent, deps: [{ token: PresetService }, { token: FixtureService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
6661
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: FixtureCapabilityColorComponent, isStandalone: false, selector: "lib-app-fixture-capability-color", ngImport: i0, template: "<div class=\"card border-secondary h-100\" [class.capability-deactivated]=\"!active\">\n <div class=\"card-header\">\n <div class=\"my-auto\" style=\"float: left\">\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capabilityColorActive\"\n [ngModel]=\"active\"\n (ngModelChange)=\"changeActive($event)\"\n />\n <label class=\"form-check-label\" for=\"capabilityColorActive\">{{ 'designer.fixture.capability-color' | translate }}</label>\n </div>\n </div>\n <div class=\"pull-right\">\n <input type=\"text\" [(ngModel)]=\"color\" style=\"width: 58px; text-align: center; font-size: 12px; font-family: monospace\" />\n </div>\n </div>\n\n <div class=\"card-body h-100\">\n <div id=\"color-picker-container\"></div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
6751
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureCapabilityColorComponent, deps: [{ token: PresetService }, { token: FixtureService }, { token: i0.ChangeDetectorRef }, { token: LivePreviewService }], target: i0.ɵɵFactoryTarget.Component }); }
6752
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: FixtureCapabilityColorComponent, isStandalone: false, selector: "lib-app-fixture-capability-color", ngImport: i0, template: "<div class=\"card border-secondary h-100\" [class.capability-deactivated]=\"!active\">\n <div class=\"card-header\">\n <div class=\"my-auto\" style=\"float: left\">\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capabilityColorActive\"\n [ngModel]=\"active\"\n (ngModelChange)=\"changeActive($event)\"\n />\n <label class=\"form-check-label\" for=\"capabilityColorActive\">{{ 'designer.fixture.capability-color' | translate }}</label>\n </div>\n </div>\n <div class=\"pull-right\">\n <input type=\"text\" [(ngModel)]=\"color\" style=\"width: 58px; text-align: center; font-size: 12px; font-family: monospace\" />\n </div>\n </div>\n\n <div class=\"card-body h-100\">\n <div id=\"color-picker-container\"></div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
6662
6753
  }
6663
6754
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureCapabilityColorComponent, decorators: [{
6664
6755
  type: Component,
6665
6756
  args: [{ selector: 'lib-app-fixture-capability-color', standalone: false, template: "<div class=\"card border-secondary h-100\" [class.capability-deactivated]=\"!active\">\n <div class=\"card-header\">\n <div class=\"my-auto\" style=\"float: left\">\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capabilityColorActive\"\n [ngModel]=\"active\"\n (ngModelChange)=\"changeActive($event)\"\n />\n <label class=\"form-check-label\" for=\"capabilityColorActive\">{{ 'designer.fixture.capability-color' | translate }}</label>\n </div>\n </div>\n <div class=\"pull-right\">\n <input type=\"text\" [(ngModel)]=\"color\" style=\"width: 58px; text-align: center; font-size: 12px; font-family: monospace\" />\n </div>\n </div>\n\n <div class=\"card-body h-100\">\n <div id=\"color-picker-container\"></div>\n </div>\n</div>\n" }]
6666
- }], ctorParameters: () => [{ type: PresetService }, { type: FixtureService }, { type: i0.ChangeDetectorRef }] });
6757
+ }], ctorParameters: () => [{ type: PresetService }, { type: FixtureService }, { type: i0.ChangeDetectorRef }, { type: LivePreviewService }] });
6667
6758
 
6668
6759
  class FixtureCapabilityDimmerComponent {
6669
- constructor(presetService, changeDetectorRef) {
6760
+ constructor(presetService, changeDetectorRef, livePreviewService) {
6670
6761
  this.presetService = presetService;
6671
6762
  this.changeDetectorRef = changeDetectorRef;
6763
+ this.livePreviewService = livePreviewService;
6672
6764
  }
6673
6765
  ngOnInit() { }
6674
6766
  getValue() {
@@ -6694,7 +6786,7 @@ class FixtureCapabilityDimmerComponent {
6694
6786
  }
6695
6787
  this.presetService.setCapabilityValue(this.presetService.selectedPreset, FixtureCapabilityType.Intensity, value);
6696
6788
  this.changeDetectorRef.detectChanges();
6697
- this.presetService.previewLive();
6789
+ this.livePreviewService.previewLive();
6698
6790
  }
6699
6791
  changeActive(active) {
6700
6792
  if (active) {
@@ -6704,20 +6796,21 @@ class FixtureCapabilityDimmerComponent {
6704
6796
  this.presetService.deleteCapabilityValue(this.presetService.selectedPreset, FixtureCapabilityType.Intensity);
6705
6797
  this.changeDetectorRef.detectChanges();
6706
6798
  }
6707
- this.presetService.previewLive();
6799
+ this.livePreviewService.previewLive();
6708
6800
  }
6709
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureCapabilityDimmerComponent, deps: [{ token: PresetService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
6710
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: FixtureCapabilityDimmerComponent, isStandalone: false, selector: "lib-app-fixture-capability-dimmer", ngImport: i0, template: "<div class=\"card border-secondary h-100\" [class.capability-deactivated]=\"getValue() == undefined\" style=\"min-height: 200px\">\n <div class=\"card-header\">\n <div class=\"my-auto\">\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capabilityDimmerActive\"\n [ngModel]=\"getValue() != undefined\"\n (ngModelChange)=\"changeActive($event)\"\n />\n <label class=\"form-check-label\" for=\"capabilityDimmerActive\">\n <i class=\"icon-dimmer\"></i>\n </label>\n </div>\n </div>\n </div>\n\n <div class=\"card-body h-100 d-flex\" style=\"flex-direction: column\">\n <div class=\"mb-4 w-100 d-flex\">\n <input\n class=\"mx-auto\"\n type=\"text\"\n [ngModel]=\"getValueText() >= 0 ? getValueText() : 0\"\n (ngModelChange)=\"setValue($event / 100)\"\n style=\"width: 42px; height: 20px; text-align: center; font-size: 12px; font-family: monospace\"\n />\n </div>\n\n <div class=\"h-100 w-100 d-flex\">\n <mv-slider\n class=\"mx-auto\"\n [value]=\"getValue() >= 0 ? getValue() : 0\"\n (change)=\"setValue($event.newValue)\"\n [orientation]=\"'vertical'\"\n [reversed]=\"true\"\n style=\"height: 100%\"\n [tooltip]=\"'hide'\"\n [min]=\"0\"\n [max]=\"1\"\n [step]=\"0.001\"\n ></mv-slider>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3$3.SliderComponent, selector: "mv-slider", inputs: ["style", "value", "min", "max", "step", "precision", "orientation", "range", "selection", "tooltip", "tooltipSplit", "tooltipPosition", "handle", "reversed", "rtl", "enabled", "naturalArrowKeys", "ticks", "ticksPositions", "ticksLabels", "ticksSnapBounds", "ticksTooltip", "scale", "labelledBy", "rangeHighlights", "formatter", "lockToTicks"], outputs: ["valueChange", "slide", "slideStart", "slideStop", "change"] }] }); }
6801
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureCapabilityDimmerComponent, deps: [{ token: PresetService }, { token: i0.ChangeDetectorRef }, { token: LivePreviewService }], target: i0.ɵɵFactoryTarget.Component }); }
6802
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: FixtureCapabilityDimmerComponent, isStandalone: false, selector: "lib-app-fixture-capability-dimmer", ngImport: i0, template: "<div class=\"card border-secondary h-100\" [class.capability-deactivated]=\"getValue() == undefined\" style=\"min-height: 200px\">\n <div class=\"card-header\">\n <div class=\"my-auto\">\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capabilityDimmerActive\"\n [ngModel]=\"getValue() != undefined\"\n (ngModelChange)=\"changeActive($event)\"\n />\n <label class=\"form-check-label\" for=\"capabilityDimmerActive\">\n <i class=\"icon-dimmer\"></i>\n </label>\n </div>\n </div>\n </div>\n\n <div class=\"card-body h-100 d-flex\" style=\"flex-direction: column\">\n <div class=\"mb-4 w-100 d-flex\">\n <input\n class=\"mx-auto\"\n type=\"text\"\n [ngModel]=\"getValueText() >= 0 ? getValueText() : 0\"\n (ngModelChange)=\"setValue($event / 100)\"\n style=\"width: 42px; height: 20px; text-align: center; font-size: 12px; font-family: monospace\"\n />\n </div>\n\n <div class=\"h-100 w-100 d-flex\">\n <mv-slider\n class=\"mx-auto\"\n [value]=\"getValue() >= 0 ? getValue() : 0\"\n (change)=\"setValue($event.newValue)\"\n [orientation]=\"'vertical'\"\n [reversed]=\"true\"\n style=\"height: 100%\"\n [tooltip]=\"'hide'\"\n [min]=\"0\"\n [max]=\"1\"\n [step]=\"0.001\"\n ></mv-slider>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.SliderComponent, selector: "mv-slider", inputs: ["style", "value", "min", "max", "step", "precision", "orientation", "range", "selection", "tooltip", "tooltipSplit", "tooltipPosition", "handle", "reversed", "rtl", "enabled", "naturalArrowKeys", "ticks", "ticksPositions", "ticksLabels", "ticksSnapBounds", "ticksTooltip", "scale", "labelledBy", "rangeHighlights", "formatter", "lockToTicks"], outputs: ["valueChange", "slide", "slideStart", "slideStop", "change"] }] }); }
6711
6803
  }
6712
6804
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureCapabilityDimmerComponent, decorators: [{
6713
6805
  type: Component,
6714
6806
  args: [{ selector: 'lib-app-fixture-capability-dimmer', standalone: false, template: "<div class=\"card border-secondary h-100\" [class.capability-deactivated]=\"getValue() == undefined\" style=\"min-height: 200px\">\n <div class=\"card-header\">\n <div class=\"my-auto\">\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capabilityDimmerActive\"\n [ngModel]=\"getValue() != undefined\"\n (ngModelChange)=\"changeActive($event)\"\n />\n <label class=\"form-check-label\" for=\"capabilityDimmerActive\">\n <i class=\"icon-dimmer\"></i>\n </label>\n </div>\n </div>\n </div>\n\n <div class=\"card-body h-100 d-flex\" style=\"flex-direction: column\">\n <div class=\"mb-4 w-100 d-flex\">\n <input\n class=\"mx-auto\"\n type=\"text\"\n [ngModel]=\"getValueText() >= 0 ? getValueText() : 0\"\n (ngModelChange)=\"setValue($event / 100)\"\n style=\"width: 42px; height: 20px; text-align: center; font-size: 12px; font-family: monospace\"\n />\n </div>\n\n <div class=\"h-100 w-100 d-flex\">\n <mv-slider\n class=\"mx-auto\"\n [value]=\"getValue() >= 0 ? getValue() : 0\"\n (change)=\"setValue($event.newValue)\"\n [orientation]=\"'vertical'\"\n [reversed]=\"true\"\n style=\"height: 100%\"\n [tooltip]=\"'hide'\"\n [min]=\"0\"\n [max]=\"1\"\n [step]=\"0.001\"\n ></mv-slider>\n </div>\n </div>\n</div>\n" }]
6715
- }], ctorParameters: () => [{ type: PresetService }, { type: i0.ChangeDetectorRef }] });
6807
+ }], ctorParameters: () => [{ type: PresetService }, { type: i0.ChangeDetectorRef }, { type: LivePreviewService }] });
6716
6808
 
6717
6809
  class FixtureCapabilityPanTiltComponent {
6718
- constructor(presetService, changeDetectorRef) {
6810
+ constructor(presetService, changeDetectorRef, livePreviewService) {
6719
6811
  this.presetService = presetService;
6720
6812
  this.changeDetectorRef = changeDetectorRef;
6813
+ this.livePreviewService = livePreviewService;
6721
6814
  }
6722
6815
  ngOnInit() { }
6723
6816
  getValuePan() {
@@ -6743,7 +6836,7 @@ class FixtureCapabilityPanTiltComponent {
6743
6836
  }
6744
6837
  this.presetService.setCapabilityValue(this.presetService.selectedPreset, FixtureCapabilityType.Pan, value);
6745
6838
  this.changeDetectorRef.detectChanges();
6746
- this.presetService.previewLive();
6839
+ this.livePreviewService.previewLive();
6747
6840
  }
6748
6841
  getValueTilt() {
6749
6842
  const capabilityValue = this.presetService.getCapabilityValue(this.presetService.selectedPreset, FixtureCapabilityType.Tilt);
@@ -6768,7 +6861,7 @@ class FixtureCapabilityPanTiltComponent {
6768
6861
  }
6769
6862
  this.presetService.setCapabilityValue(this.presetService.selectedPreset, FixtureCapabilityType.Tilt, value);
6770
6863
  this.changeDetectorRef.detectChanges();
6771
- this.presetService.previewLive();
6864
+ this.livePreviewService.previewLive();
6772
6865
  }
6773
6866
  changeActive(active) {
6774
6867
  if (active) {
@@ -6780,15 +6873,15 @@ class FixtureCapabilityPanTiltComponent {
6780
6873
  this.presetService.deleteCapabilityValue(this.presetService.selectedPreset, FixtureCapabilityType.Tilt);
6781
6874
  this.changeDetectorRef.detectChanges();
6782
6875
  }
6783
- this.presetService.previewLive();
6876
+ this.livePreviewService.previewLive();
6784
6877
  }
6785
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureCapabilityPanTiltComponent, deps: [{ token: PresetService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
6786
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: FixtureCapabilityPanTiltComponent, isStandalone: false, selector: "lib-app-fixture-capability-pan-tilt", ngImport: i0, template: "<div class=\"card border-secondary h-100\" [class.capability-deactivated]=\"getValuePan() == undefined && getValueTilt() == undefined\">\n <div class=\"card-header\">\n <div class=\"my-auto\">\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capabilityColorWheelActive\"\n [ngModel]=\"getValuePan() != undefined || getValueTilt() != undefined\"\n (ngModelChange)=\"changeActive($event)\"\n />\n <label class=\"form-check-label\" for=\"capabilityColorWheelActive\">{{ 'designer.fixture.capability-pan-tilt' | translate }}</label>\n </div>\n </div>\n </div>\n\n <div class=\"card-body h-100 d-flex\" style=\"flex-direction: row\">\n <div class=\"d-flex h-100 mr-3\" style=\"flex-direction: column\">\n <div class=\"mb-4 w-100 d-flex\">\n <input\n class=\"mx-auto\"\n type=\"text\"\n [ngModel]=\"getValueTextPan() >= 0 ? getValueTextPan() : 0\"\n (ngModelChange)=\"setValuePan($event / 100)\"\n style=\"width: 42px; height: 20px; text-align: center; font-size: 12px; font-family: monospace\"\n />\n </div>\n\n <div class=\"h-100 w-100 d-flex\">\n <mv-slider\n class=\"mx-auto\"\n [value]=\"getValuePan() >= 0 ? getValuePan() : 0\"\n (change)=\"setValuePan($event.newValue)\"\n [orientation]=\"'vertical'\"\n [reversed]=\"true\"\n style=\"height: 100%\"\n [tooltip]=\"'hide'\"\n [min]=\"0\"\n [max]=\"1\"\n [step]=\"0.001\"\n ></mv-slider>\n </div>\n </div>\n\n <div class=\"d-flex h-100\" style=\"flex-direction: column\">\n <div class=\"mb-4 w-100 d-flex\">\n <input\n class=\"mx-auto\"\n type=\"text\"\n [ngModel]=\"getValueTextTilt() >= 0 ? getValueTextTilt() : 0\"\n (ngModelChange)=\"setValueTilt($event / 100)\"\n style=\"width: 42px; height: 20px; text-align: center; font-size: 12px; font-family: monospace\"\n />\n </div>\n\n <div class=\"h-100 w-100 d-flex\">\n <mv-slider\n class=\"mx-auto\"\n [value]=\"getValueTilt() >= 0 ? getValueTilt() : 0\"\n (change)=\"setValueTilt($event.newValue)\"\n [orientation]=\"'vertical'\"\n [reversed]=\"true\"\n style=\"height: 100%\"\n [tooltip]=\"'hide'\"\n [min]=\"0\"\n [max]=\"1\"\n [step]=\"0.001\"\n ></mv-slider>\n </div>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3$3.SliderComponent, selector: "mv-slider", inputs: ["style", "value", "min", "max", "step", "precision", "orientation", "range", "selection", "tooltip", "tooltipSplit", "tooltipPosition", "handle", "reversed", "rtl", "enabled", "naturalArrowKeys", "ticks", "ticksPositions", "ticksLabels", "ticksSnapBounds", "ticksTooltip", "scale", "labelledBy", "rangeHighlights", "formatter", "lockToTicks"], outputs: ["valueChange", "slide", "slideStart", "slideStop", "change"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
6878
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureCapabilityPanTiltComponent, deps: [{ token: PresetService }, { token: i0.ChangeDetectorRef }, { token: LivePreviewService }], target: i0.ɵɵFactoryTarget.Component }); }
6879
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: FixtureCapabilityPanTiltComponent, isStandalone: false, selector: "lib-app-fixture-capability-pan-tilt", ngImport: i0, template: "<div class=\"card border-secondary h-100\" [class.capability-deactivated]=\"getValuePan() == undefined && getValueTilt() == undefined\">\n <div class=\"card-header\">\n <div class=\"my-auto\">\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capabilityColorWheelActive\"\n [ngModel]=\"getValuePan() != undefined || getValueTilt() != undefined\"\n (ngModelChange)=\"changeActive($event)\"\n />\n <label class=\"form-check-label\" for=\"capabilityColorWheelActive\">{{ 'designer.fixture.capability-pan-tilt' | translate }}</label>\n </div>\n </div>\n </div>\n\n <div class=\"card-body h-100 d-flex\" style=\"flex-direction: row\">\n <div class=\"d-flex h-100 mr-3\" style=\"flex-direction: column\">\n <div class=\"mb-4 w-100 d-flex\">\n <input\n class=\"mx-auto\"\n type=\"text\"\n [ngModel]=\"getValueTextPan() >= 0 ? getValueTextPan() : 0\"\n (ngModelChange)=\"setValuePan($event / 100)\"\n style=\"width: 42px; height: 20px; text-align: center; font-size: 12px; font-family: monospace\"\n />\n </div>\n\n <div class=\"h-100 w-100 d-flex\">\n <mv-slider\n class=\"mx-auto\"\n [value]=\"getValuePan() >= 0 ? getValuePan() : 0\"\n (change)=\"setValuePan($event.newValue)\"\n [orientation]=\"'vertical'\"\n [reversed]=\"true\"\n style=\"height: 100%\"\n [tooltip]=\"'hide'\"\n [min]=\"0\"\n [max]=\"1\"\n [step]=\"0.001\"\n ></mv-slider>\n </div>\n </div>\n\n <div class=\"d-flex h-100\" style=\"flex-direction: column\">\n <div class=\"mb-4 w-100 d-flex\">\n <input\n class=\"mx-auto\"\n type=\"text\"\n [ngModel]=\"getValueTextTilt() >= 0 ? getValueTextTilt() : 0\"\n (ngModelChange)=\"setValueTilt($event / 100)\"\n style=\"width: 42px; height: 20px; text-align: center; font-size: 12px; font-family: monospace\"\n />\n </div>\n\n <div class=\"h-100 w-100 d-flex\">\n <mv-slider\n class=\"mx-auto\"\n [value]=\"getValueTilt() >= 0 ? getValueTilt() : 0\"\n (change)=\"setValueTilt($event.newValue)\"\n [orientation]=\"'vertical'\"\n [reversed]=\"true\"\n style=\"height: 100%\"\n [tooltip]=\"'hide'\"\n [min]=\"0\"\n [max]=\"1\"\n [step]=\"0.001\"\n ></mv-slider>\n </div>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.SliderComponent, selector: "mv-slider", inputs: ["style", "value", "min", "max", "step", "precision", "orientation", "range", "selection", "tooltip", "tooltipSplit", "tooltipPosition", "handle", "reversed", "rtl", "enabled", "naturalArrowKeys", "ticks", "ticksPositions", "ticksLabels", "ticksSnapBounds", "ticksTooltip", "scale", "labelledBy", "rangeHighlights", "formatter", "lockToTicks"], outputs: ["valueChange", "slide", "slideStart", "slideStop", "change"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
6787
6880
  }
6788
6881
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureCapabilityPanTiltComponent, decorators: [{
6789
6882
  type: Component,
6790
6883
  args: [{ selector: 'lib-app-fixture-capability-pan-tilt', standalone: false, template: "<div class=\"card border-secondary h-100\" [class.capability-deactivated]=\"getValuePan() == undefined && getValueTilt() == undefined\">\n <div class=\"card-header\">\n <div class=\"my-auto\">\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capabilityColorWheelActive\"\n [ngModel]=\"getValuePan() != undefined || getValueTilt() != undefined\"\n (ngModelChange)=\"changeActive($event)\"\n />\n <label class=\"form-check-label\" for=\"capabilityColorWheelActive\">{{ 'designer.fixture.capability-pan-tilt' | translate }}</label>\n </div>\n </div>\n </div>\n\n <div class=\"card-body h-100 d-flex\" style=\"flex-direction: row\">\n <div class=\"d-flex h-100 mr-3\" style=\"flex-direction: column\">\n <div class=\"mb-4 w-100 d-flex\">\n <input\n class=\"mx-auto\"\n type=\"text\"\n [ngModel]=\"getValueTextPan() >= 0 ? getValueTextPan() : 0\"\n (ngModelChange)=\"setValuePan($event / 100)\"\n style=\"width: 42px; height: 20px; text-align: center; font-size: 12px; font-family: monospace\"\n />\n </div>\n\n <div class=\"h-100 w-100 d-flex\">\n <mv-slider\n class=\"mx-auto\"\n [value]=\"getValuePan() >= 0 ? getValuePan() : 0\"\n (change)=\"setValuePan($event.newValue)\"\n [orientation]=\"'vertical'\"\n [reversed]=\"true\"\n style=\"height: 100%\"\n [tooltip]=\"'hide'\"\n [min]=\"0\"\n [max]=\"1\"\n [step]=\"0.001\"\n ></mv-slider>\n </div>\n </div>\n\n <div class=\"d-flex h-100\" style=\"flex-direction: column\">\n <div class=\"mb-4 w-100 d-flex\">\n <input\n class=\"mx-auto\"\n type=\"text\"\n [ngModel]=\"getValueTextTilt() >= 0 ? getValueTextTilt() : 0\"\n (ngModelChange)=\"setValueTilt($event / 100)\"\n style=\"width: 42px; height: 20px; text-align: center; font-size: 12px; font-family: monospace\"\n />\n </div>\n\n <div class=\"h-100 w-100 d-flex\">\n <mv-slider\n class=\"mx-auto\"\n [value]=\"getValueTilt() >= 0 ? getValueTilt() : 0\"\n (change)=\"setValueTilt($event.newValue)\"\n [orientation]=\"'vertical'\"\n [reversed]=\"true\"\n style=\"height: 100%\"\n [tooltip]=\"'hide'\"\n [min]=\"0\"\n [max]=\"1\"\n [step]=\"0.001\"\n ></mv-slider>\n </div>\n </div>\n </div>\n</div>\n" }]
6791
- }], ctorParameters: () => [{ type: PresetService }, { type: i0.ChangeDetectorRef }] });
6884
+ }], ctorParameters: () => [{ type: PresetService }, { type: i0.ChangeDetectorRef }, { type: LivePreviewService }] });
6792
6885
 
6793
6886
  class FixtureCapabilityColorWheelComponent {
6794
6887
  set profile(value) {
@@ -6799,10 +6892,11 @@ class FixtureCapabilityColorWheelComponent {
6799
6892
  this._channel = value;
6800
6893
  this.update();
6801
6894
  }
6802
- constructor(presetService, changeDetectorRef, fixtureService) {
6895
+ constructor(presetService, changeDetectorRef, fixtureService, livePreviewService) {
6803
6896
  this.presetService = presetService;
6804
6897
  this.changeDetectorRef = changeDetectorRef;
6805
6898
  this.fixtureService = fixtureService;
6899
+ this.livePreviewService = livePreviewService;
6806
6900
  this.showContainer = false;
6807
6901
  }
6808
6902
  ngOnInit() {
@@ -6906,19 +7000,19 @@ class FixtureCapabilityColorWheelComponent {
6906
7000
  else {
6907
7001
  this.presetService.deleteCapabilityValue(this.presetService.selectedPreset, FixtureCapabilityType.WheelSlot, undefined, this.wheelName, this._fixtureProfile.uuid);
6908
7002
  }
6909
- this.presetService.previewLive();
7003
+ this.livePreviewService.previewLive();
6910
7004
  }
6911
7005
  selectSlotNumber(slotNumber) {
6912
7006
  this.presetService.setCapabilityValue(this.presetService.selectedPreset, FixtureCapabilityType.WheelSlot, undefined, slotNumber, undefined, this.wheelName, this._fixtureProfile.uuid);
6913
- this.presetService.previewLive();
7007
+ this.livePreviewService.previewLive();
6914
7008
  }
6915
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureCapabilityColorWheelComponent, deps: [{ token: PresetService }, { token: i0.ChangeDetectorRef }, { token: FixtureService }], target: i0.ɵɵFactoryTarget.Component }); }
6916
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: FixtureCapabilityColorWheelComponent, isStandalone: false, selector: "lib-app-fixture-capability-color-wheel", inputs: { profile: "profile", channel: "channel", wheelIndex: "wheelIndex", showContainer: "showContainer" }, ngImport: i0, template: "<div class=\"card border-secondary h-100\" [class.capability-deactivated]=\"getCurrentSlotNumber() == undefined\" style=\"min-height: 200px\">\n <div class=\"card-header\">\n <div class=\"my-auto\">\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capabilityColorWheel{{ wheelIndex }}Active\"\n [ngModel]=\"getCurrentSlotNumber() != undefined\"\n (ngModelChange)=\"changeActive($event)\"\n />\n <label class=\"form-check-label\" for=\"capabilityColorWheel{{ wheelIndex }}Active\">\n {{ 'designer.fixture.capability-color' | translate }}\n </label>\n </div>\n </div>\n </div>\n\n <div class=\"card-body h-100\">\n @if (showContainer) {\n <div>{{ _fixtureProfile.name }} - {{ _channel.name }}</div>\n } @if (wheel) {\n <div class=\"d-flex\" style=\"max-width: 240px; flex-wrap: wrap\">\n @for (slot of slotCapabilities; track $index; let i = $index) {\n <div\n (click)=\"selectSlotNumber(slot.capability.slotNumber)\"\n class=\"m-1 color\"\n [class.color-selected]=\"slotCapabilityIsSelected(slot.capability.slotNumber)\"\n [ngStyle]=\"getCapabilityColorStyle(slot)\"\n >\n @if (slotCapabilityIsSelected(slot.capability.slotNumber)) {\n <div (click)=\"selectSlotNumber(slot.capability.slotNumber)\" class=\"color-selected-inner\"></div>\n }\n </div>\n }\n </div>\n }\n </div>\n</div>\n", styles: [".color{box-sizing:border-box;width:50px;height:50px;border:solid 1px #ced4da;cursor:pointer}.color-selected{border-width:3px;border-color:#fff}.color-selected-inner{border:solid 1px black;height:100%;width:100%}\n"], dependencies: [{ kind: "directive", type: i9.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
7009
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureCapabilityColorWheelComponent, deps: [{ token: PresetService }, { token: i0.ChangeDetectorRef }, { token: FixtureService }, { token: LivePreviewService }], target: i0.ɵɵFactoryTarget.Component }); }
7010
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: FixtureCapabilityColorWheelComponent, isStandalone: false, selector: "lib-app-fixture-capability-color-wheel", inputs: { profile: "profile", channel: "channel", wheelIndex: "wheelIndex", showContainer: "showContainer" }, ngImport: i0, template: "<div class=\"card border-secondary h-100\" [class.capability-deactivated]=\"getCurrentSlotNumber() == undefined\" style=\"min-height: 200px\">\n <div class=\"card-header\">\n <div class=\"my-auto\">\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capabilityColorWheel{{ wheelIndex }}Active\"\n [ngModel]=\"getCurrentSlotNumber() != undefined\"\n (ngModelChange)=\"changeActive($event)\"\n />\n <label class=\"form-check-label\" for=\"capabilityColorWheel{{ wheelIndex }}Active\">\n {{ 'designer.fixture.capability-color' | translate }}\n </label>\n </div>\n </div>\n </div>\n\n <div class=\"card-body h-100\">\n @if (showContainer) {\n <div>{{ _fixtureProfile.name }} - {{ _channel.name }}</div>\n } @if (wheel) {\n <div class=\"d-flex\" style=\"max-width: 240px; flex-wrap: wrap\">\n @for (slot of slotCapabilities; track $index; let i = $index) {\n <div\n (click)=\"selectSlotNumber(slot.capability.slotNumber)\"\n class=\"m-1 color\"\n [class.color-selected]=\"slotCapabilityIsSelected(slot.capability.slotNumber)\"\n [ngStyle]=\"getCapabilityColorStyle(slot)\"\n >\n @if (slotCapabilityIsSelected(slot.capability.slotNumber)) {\n <div (click)=\"selectSlotNumber(slot.capability.slotNumber)\" class=\"color-selected-inner\"></div>\n }\n </div>\n }\n </div>\n }\n </div>\n</div>\n", styles: [".color{box-sizing:border-box;width:50px;height:50px;border:solid 1px #ced4da;cursor:pointer}.color-selected{border-width:3px;border-color:#fff}.color-selected-inner{border:solid 1px black;height:100%;width:100%}\n"], dependencies: [{ kind: "directive", type: i10$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
6917
7011
  }
6918
7012
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureCapabilityColorWheelComponent, decorators: [{
6919
7013
  type: Component,
6920
7014
  args: [{ selector: 'lib-app-fixture-capability-color-wheel', standalone: false, template: "<div class=\"card border-secondary h-100\" [class.capability-deactivated]=\"getCurrentSlotNumber() == undefined\" style=\"min-height: 200px\">\n <div class=\"card-header\">\n <div class=\"my-auto\">\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capabilityColorWheel{{ wheelIndex }}Active\"\n [ngModel]=\"getCurrentSlotNumber() != undefined\"\n (ngModelChange)=\"changeActive($event)\"\n />\n <label class=\"form-check-label\" for=\"capabilityColorWheel{{ wheelIndex }}Active\">\n {{ 'designer.fixture.capability-color' | translate }}\n </label>\n </div>\n </div>\n </div>\n\n <div class=\"card-body h-100\">\n @if (showContainer) {\n <div>{{ _fixtureProfile.name }} - {{ _channel.name }}</div>\n } @if (wheel) {\n <div class=\"d-flex\" style=\"max-width: 240px; flex-wrap: wrap\">\n @for (slot of slotCapabilities; track $index; let i = $index) {\n <div\n (click)=\"selectSlotNumber(slot.capability.slotNumber)\"\n class=\"m-1 color\"\n [class.color-selected]=\"slotCapabilityIsSelected(slot.capability.slotNumber)\"\n [ngStyle]=\"getCapabilityColorStyle(slot)\"\n >\n @if (slotCapabilityIsSelected(slot.capability.slotNumber)) {\n <div (click)=\"selectSlotNumber(slot.capability.slotNumber)\" class=\"color-selected-inner\"></div>\n }\n </div>\n }\n </div>\n }\n </div>\n</div>\n", styles: [".color{box-sizing:border-box;width:50px;height:50px;border:solid 1px #ced4da;cursor:pointer}.color-selected{border-width:3px;border-color:#fff}.color-selected-inner{border:solid 1px black;height:100%;width:100%}\n"] }]
6921
- }], ctorParameters: () => [{ type: PresetService }, { type: i0.ChangeDetectorRef }, { type: FixtureService }], propDecorators: { profile: [{
7015
+ }], ctorParameters: () => [{ type: PresetService }, { type: i0.ChangeDetectorRef }, { type: FixtureService }, { type: LivePreviewService }], propDecorators: { profile: [{
6922
7016
  type: Input
6923
7017
  }], channel: [{
6924
7018
  type: Input
@@ -7007,7 +7101,7 @@ class FixtureCapabilityComponent {
7007
7101
  return false;
7008
7102
  }
7009
7103
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureCapabilityComponent, deps: [{ token: PresetService }, { token: FixtureService }, { token: i0.ChangeDetectorRef }, { token: ProjectService }, { token: IntroService }], target: i0.ɵɵFactoryTarget.Component }); }
7010
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: FixtureCapabilityComponent, isStandalone: false, selector: "lib-app-fixture-capability", ngImport: i0, template: "<div class=\"card border-secondary panel h-100\" [class.card-intro-active]=\"introService.showStep('capabilities')\">\n <div class=\"card-body capability-container d-flex h-100\" style=\"overflow-y: hidden\">\n <!-- h-100 needs to be applied in chrome to avoid performance issues with many layouts (reflows)\n during sliding. But the class must not be applied e.g. in Safari, because the bottom margin is not correct\n anymore afterwards. -->\n @if (presetService.selectedPreset) {\n <div class=\"row m-0 pl-3\" [class.h-100]=\"isChrome()\">\n <!-- Dimmer -->\n <!-- the height attribute is required to avoid performance issues with many layouts (reflows)\n in Chrome during sliding -->\n @if (hasCapabilityDimmer) {\n <div class=\"col col-auto p-0 my-3 mr-3\" style=\"height: calc(100% - 2rem)\">\n <lib-app-fixture-capability-dimmer></lib-app-fixture-capability-dimmer>\n </div>\n }\n <!-- Color -->\n <!-- Also show for color wheel fixtures to approx. the color -->\n @if (hasCapabilityColorOrColorWheel) {\n <div class=\"col col-auto p-0 my-3 mr-3\" style=\"height: calc(100% - 2rem)\">\n <lib-app-fixture-capability-color></lib-app-fixture-capability-color>\n </div>\n }\n <!-- Color wheels -->\n @for (entry of colorWheelChannels | keyvalue; track $index; let i = $index) {\n <div class=\"col col-auto p-0 my-3 mr-3\" style=\"height: calc(100% - 2rem)\">\n <lib-app-fixture-capability-color-wheel\n [profile]=\"entry.key\"\n [channel]=\"entry.value\"\n [wheelIndex]=\"i\"\n [showContainer]=\"colorWheelChannels.size > 1\"\n ></lib-app-fixture-capability-color-wheel>\n </div>\n }\n <!-- Pan/Tilt -->\n @if (hasCapabilityPanTilt) {\n <div class=\"col col-auto p-0 my-3 mr-3\" style=\"height: calc(100% - 2rem)\">\n <lib-app-fixture-capability-pan-tilt></lib-app-fixture-capability-pan-tilt>\n </div>\n }\n <!-- Fix spacing at the end -->\n <div class=\"col col-auto p-0 my-3 mr-3\">&nbsp;</div>\n </div>\n } @if (projectService.project.fixtures.length == 0) {\n <div class=\"m-auto\">\n <p class=\"m-auto\" style=\"color: #717171\">{{ 'designer.fixture.no-fixtures' | translate }}</p>\n </div>\n } @if ( projectService.project.fixtures.length > 0 && presetService.selectedPreset && presetService.selectedPreset.fixtures.length == 0\n ) {\n <div class=\"m-auto\">\n <p class=\"m-auto\" style=\"color: #717171\">{{ 'designer.fixture.no-fixtures-selected' | translate }}</p>\n </div>\n } @if ( projectService.project.fixtures.length > 0 && presetService.selectedPreset && presetService.selectedPreset.fixtures.length > 0\n && !hasCapabilityColorOrColorWheel && !hasCapabilityPanTilt ) {\n <div class=\"m-auto\">\n <p class=\"m-auto\" style=\"color: #717171\">{{ 'designer.fixture.no-capabilities-available' | translate }}</p>\n </div>\n }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: FixtureCapabilityColorComponent, selector: "lib-app-fixture-capability-color" }, { kind: "component", type: FixtureCapabilityDimmerComponent, selector: "lib-app-fixture-capability-dimmer" }, { kind: "component", type: FixtureCapabilityPanTiltComponent, selector: "lib-app-fixture-capability-pan-tilt" }, { kind: "component", type: FixtureCapabilityColorWheelComponent, selector: "lib-app-fixture-capability-color-wheel", inputs: ["profile", "channel", "wheelIndex", "showContainer"] }, { kind: "pipe", type: i9.KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7104
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: FixtureCapabilityComponent, isStandalone: false, selector: "lib-app-fixture-capability", ngImport: i0, template: "<div class=\"card border-secondary panel h-100\" [class.card-intro-active]=\"introService.showStep('capabilities')\">\n <div class=\"card-body capability-container d-flex h-100\" style=\"overflow-y: hidden\">\n <!-- h-100 needs to be applied in chrome to avoid performance issues with many layouts (reflows)\n during sliding. But the class must not be applied e.g. in Safari, because the bottom margin is not correct\n anymore afterwards. -->\n @if (presetService.selectedPreset) {\n <div class=\"row m-0 pl-3\" [class.h-100]=\"isChrome()\">\n <!-- Dimmer -->\n <!-- the height attribute is required to avoid performance issues with many layouts (reflows)\n in Chrome during sliding -->\n @if (hasCapabilityDimmer) {\n <div class=\"col col-auto p-0 my-3 mr-3\" style=\"height: calc(100% - 2rem)\">\n <lib-app-fixture-capability-dimmer></lib-app-fixture-capability-dimmer>\n </div>\n }\n <!-- Color -->\n <!-- Also show for color wheel fixtures to approx. the color -->\n @if (hasCapabilityColorOrColorWheel) {\n <div class=\"col col-auto p-0 my-3 mr-3\" style=\"height: calc(100% - 2rem)\">\n <lib-app-fixture-capability-color></lib-app-fixture-capability-color>\n </div>\n }\n <!-- Color wheels -->\n @for (entry of colorWheelChannels | keyvalue; track $index; let i = $index) {\n <div class=\"col col-auto p-0 my-3 mr-3\" style=\"height: calc(100% - 2rem)\">\n <lib-app-fixture-capability-color-wheel\n [profile]=\"entry.key\"\n [channel]=\"entry.value\"\n [wheelIndex]=\"i\"\n [showContainer]=\"colorWheelChannels.size > 1\"\n ></lib-app-fixture-capability-color-wheel>\n </div>\n }\n <!-- Pan/Tilt -->\n @if (hasCapabilityPanTilt) {\n <div class=\"col col-auto p-0 my-3 mr-3\" style=\"height: calc(100% - 2rem)\">\n <lib-app-fixture-capability-pan-tilt></lib-app-fixture-capability-pan-tilt>\n </div>\n }\n <!-- Fix spacing at the end -->\n <div class=\"col col-auto p-0 my-3 mr-3\">&nbsp;</div>\n </div>\n } @if (projectService.project.fixtures.length == 0) {\n <div class=\"m-auto\">\n <p class=\"m-auto\" style=\"color: #717171\">{{ 'designer.fixture.no-fixtures' | translate }}</p>\n </div>\n } @if ( projectService.project.fixtures.length > 0 && presetService.selectedPreset && presetService.selectedPreset.fixtures.length == 0\n ) {\n <div class=\"m-auto\">\n <p class=\"m-auto\" style=\"color: #717171\">{{ 'designer.fixture.no-fixtures-selected' | translate }}</p>\n </div>\n } @if ( projectService.project.fixtures.length > 0 && presetService.selectedPreset && presetService.selectedPreset.fixtures.length > 0\n && !hasCapabilityColorOrColorWheel && !hasCapabilityPanTilt ) {\n <div class=\"m-auto\">\n <p class=\"m-auto\" style=\"color: #717171\">{{ 'designer.fixture.no-capabilities-available' | translate }}</p>\n </div>\n }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: FixtureCapabilityColorComponent, selector: "lib-app-fixture-capability-color" }, { kind: "component", type: FixtureCapabilityDimmerComponent, selector: "lib-app-fixture-capability-dimmer" }, { kind: "component", type: FixtureCapabilityPanTiltComponent, selector: "lib-app-fixture-capability-pan-tilt" }, { kind: "component", type: FixtureCapabilityColorWheelComponent, selector: "lib-app-fixture-capability-color-wheel", inputs: ["profile", "channel", "wheelIndex", "showContainer"] }, { kind: "pipe", type: i10$1.KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7011
7105
  }
7012
7106
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureCapabilityComponent, decorators: [{
7013
7107
  type: Component,
@@ -7202,7 +7296,7 @@ class FixtureSettingsPositionComponent {
7202
7296
  this.updated();
7203
7297
  }
7204
7298
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureSettingsPositionComponent, deps: [{ token: FixtureService }, { token: PresetService }, { token: PreviewService }], target: i0.ɵɵFactoryTarget.Component }); }
7205
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: FixtureSettingsPositionComponent, isStandalone: false, selector: "lib-app-fixture-settings-position", ngImport: i0, template: "<div class=\"card border-secondary h-100\">\n <div class=\"card-header\">\n {{ 'designer.fixture.setting-position-title' | translate }}\n </div>\n\n @if (fixtureService.selectedSettingsFixtures.length > 0) {\n <div class=\"card-body h-100\">\n <div>\n <select class=\"mb-2\" style=\"width: 140px\" [(ngModel)]=\"selectedPositioning\" (change)=\"changePosition($event.target.value)\">\n <option [ngValue]=\"selectUndefinedOptionValue\"></option>\n <option value=\"topFront\">{{ 'designer.fixture.setting-position-front-top' | translate }}</option>\n <option value=\"bottomFront\">{{ 'designer.fixture.setting-position-front-bottom' | translate }}</option>\n <option value=\"topBack\">{{ 'designer.fixture.setting-position-back-top' | translate }}</option>\n <option value=\"bottomBack\">{{ 'designer.fixture.setting-position-back-bottom' | translate }}</option>\n <option value=\"manual\">{{ 'designer.fixture.setting-position-manual' | translate }}</option>\n </select>\n </div>\n @if (selectedPositioning == 'manual') {\n <div>\n <div>{{ 'designer.fixture.setting-position' | translate }}</div>\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 20px; float: left\">X</div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 80px\"\n [tooltip]=\"'hide'\"\n [value]=\"positionX ? positionX : (positionXMax + positionXMin) / 2\"\n [min]=\"positionXMin\"\n [max]=\"positionXMax\"\n [step]=\"1\"\n (change)=\"changePositionManual('x', $event.newValue)\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input [ngModel]=\"positionX\" (ngModelChange)=\"changePositionManual('x', $event)\" type=\"text\" class=\"slider-input\" />\n </div>\n </div>\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 20px; float: left\">Y</div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 80px; height: 18px\"\n [tooltip]=\"'hide'\"\n [value]=\"positionZ ? positionZ : (positionZMax + positionZMin) / 2\"\n [min]=\"positionZMin\"\n [max]=\"positionZMax\"\n [step]=\"1\"\n (change)=\"changePositionManual('z', $event.newValue)\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input [ngModel]=\"positionZ\" (ngModelChange)=\"changePositionManual('z', $event)\" type=\"text\" class=\"slider-input\" />\n </div>\n </div>\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 20px; float: left\">Z</div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 80px\"\n [tooltip]=\"'hide'\"\n [value]=\"positionY ? positionY : (positionYMax + positionYMin) / 2\"\n [min]=\"positionYMin\"\n [max]=\"positionYMax\"\n [step]=\"1\"\n (change)=\"changePositionManual('y', $event.newValue)\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input [ngModel]=\"positionY\" (ngModelChange)=\"changePositionManual('y', $event)\" type=\"text\" class=\"slider-input\" />\n </div>\n </div>\n <div class=\"mt-2\">{{ 'designer.fixture.setting-rotation' | translate }}</div>\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 20px; float: left\">X</div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 80px\"\n [tooltip]=\"'hide'\"\n [value]=\"rotationX ? rotationX : 0\"\n [min]=\"rotationMin\"\n [max]=\"rotationMax\"\n [step]=\"1\"\n (change)=\"changeRotationManual('x', $event.newValue)\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input [ngModel]=\"rotationX\" (ngModelChange)=\"changeRotationManual('x', $event)\" type=\"text\" class=\"slider-input\" />\n </div>\n </div>\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 20px; float: left\">Y</div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 80px\"\n [tooltip]=\"'hide'\"\n [value]=\"rotationY ? rotationY : 0\"\n [min]=\"rotationMin\"\n [max]=\"rotationMax\"\n [step]=\"1\"\n (change)=\"changeRotationManual('y', $event.newValue)\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input [ngModel]=\"rotationY\" (ngModelChange)=\"changeRotationManual('y', $event)\" type=\"text\" class=\"slider-input\" />\n </div>\n </div>\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 20px; float: left\">Z</div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 80px; height: 18px\"\n [tooltip]=\"'hide'\"\n [value]=\"rotationZ ? rotationZ : 0\"\n [min]=\"rotationMin\"\n [max]=\"rotationMax\"\n [step]=\"1\"\n (change)=\"changeRotationManual('z', $event.newValue)\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input [ngModel]=\"rotationZ\" (ngModelChange)=\"changeRotationManual('z', $event)\" type=\"text\" class=\"slider-input\" />\n </div>\n </div>\n </div>\n }\n </div>\n } @if (fixtureService.selectedSettingsFixtures.length == 0) {\n <div class=\"card-body h-100 d-flex\">\n <p class=\"m-auto\" style=\"color: #717171\">{{ 'designer.fixture.no-fixtures-settings-selected' | translate }}</p>\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3$3.SliderComponent, selector: "mv-slider", inputs: ["style", "value", "min", "max", "step", "precision", "orientation", "range", "selection", "tooltip", "tooltipSplit", "tooltipPosition", "handle", "reversed", "rtl", "enabled", "naturalArrowKeys", "ticks", "ticksPositions", "ticksLabels", "ticksSnapBounds", "ticksTooltip", "scale", "labelledBy", "rangeHighlights", "formatter", "lockToTicks"], outputs: ["valueChange", "slide", "slideStart", "slideStop", "change"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
7299
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: FixtureSettingsPositionComponent, isStandalone: false, selector: "lib-app-fixture-settings-position", ngImport: i0, template: "<div class=\"card border-secondary h-100\">\n <div class=\"card-header\">\n {{ 'designer.fixture.setting-position-title' | translate }}\n </div>\n\n @if (fixtureService.selectedSettingsFixtures.length > 0) {\n <div class=\"card-body h-100\">\n <div>\n <select class=\"mb-2\" style=\"width: 140px\" [(ngModel)]=\"selectedPositioning\" (change)=\"changePosition($event.target.value)\">\n <option [ngValue]=\"selectUndefinedOptionValue\"></option>\n <option value=\"topFront\">{{ 'designer.fixture.setting-position-front-top' | translate }}</option>\n <option value=\"bottomFront\">{{ 'designer.fixture.setting-position-front-bottom' | translate }}</option>\n <option value=\"topBack\">{{ 'designer.fixture.setting-position-back-top' | translate }}</option>\n <option value=\"bottomBack\">{{ 'designer.fixture.setting-position-back-bottom' | translate }}</option>\n <option value=\"manual\">{{ 'designer.fixture.setting-position-manual' | translate }}</option>\n </select>\n </div>\n @if (selectedPositioning == 'manual') {\n <div>\n <div>{{ 'designer.fixture.setting-position' | translate }}</div>\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 20px; float: left\">X</div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 80px\"\n [tooltip]=\"'hide'\"\n [value]=\"positionX ? positionX : (positionXMax + positionXMin) / 2\"\n [min]=\"positionXMin\"\n [max]=\"positionXMax\"\n [step]=\"1\"\n (change)=\"changePositionManual('x', $event.newValue)\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input [ngModel]=\"positionX\" (ngModelChange)=\"changePositionManual('x', $event)\" type=\"text\" class=\"slider-input\" />\n </div>\n </div>\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 20px; float: left\">Y</div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 80px; height: 18px\"\n [tooltip]=\"'hide'\"\n [value]=\"positionZ ? positionZ : (positionZMax + positionZMin) / 2\"\n [min]=\"positionZMin\"\n [max]=\"positionZMax\"\n [step]=\"1\"\n (change)=\"changePositionManual('z', $event.newValue)\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input [ngModel]=\"positionZ\" (ngModelChange)=\"changePositionManual('z', $event)\" type=\"text\" class=\"slider-input\" />\n </div>\n </div>\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 20px; float: left\">Z</div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 80px\"\n [tooltip]=\"'hide'\"\n [value]=\"positionY ? positionY : (positionYMax + positionYMin) / 2\"\n [min]=\"positionYMin\"\n [max]=\"positionYMax\"\n [step]=\"1\"\n (change)=\"changePositionManual('y', $event.newValue)\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input [ngModel]=\"positionY\" (ngModelChange)=\"changePositionManual('y', $event)\" type=\"text\" class=\"slider-input\" />\n </div>\n </div>\n <div class=\"mt-2\">{{ 'designer.fixture.setting-rotation' | translate }}</div>\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 20px; float: left\">X</div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 80px\"\n [tooltip]=\"'hide'\"\n [value]=\"rotationX ? rotationX : 0\"\n [min]=\"rotationMin\"\n [max]=\"rotationMax\"\n [step]=\"1\"\n (change)=\"changeRotationManual('x', $event.newValue)\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input [ngModel]=\"rotationX\" (ngModelChange)=\"changeRotationManual('x', $event)\" type=\"text\" class=\"slider-input\" />\n </div>\n </div>\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 20px; float: left\">Y</div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 80px\"\n [tooltip]=\"'hide'\"\n [value]=\"rotationY ? rotationY : 0\"\n [min]=\"rotationMin\"\n [max]=\"rotationMax\"\n [step]=\"1\"\n (change)=\"changeRotationManual('y', $event.newValue)\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input [ngModel]=\"rotationY\" (ngModelChange)=\"changeRotationManual('y', $event)\" type=\"text\" class=\"slider-input\" />\n </div>\n </div>\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 20px; float: left\">Z</div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 80px; height: 18px\"\n [tooltip]=\"'hide'\"\n [value]=\"rotationZ ? rotationZ : 0\"\n [min]=\"rotationMin\"\n [max]=\"rotationMax\"\n [step]=\"1\"\n (change)=\"changeRotationManual('z', $event.newValue)\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input [ngModel]=\"rotationZ\" (ngModelChange)=\"changeRotationManual('z', $event)\" type=\"text\" class=\"slider-input\" />\n </div>\n </div>\n </div>\n }\n </div>\n } @if (fixtureService.selectedSettingsFixtures.length == 0) {\n <div class=\"card-body h-100 d-flex\">\n <p class=\"m-auto\" style=\"color: #717171\">{{ 'designer.fixture.no-fixtures-settings-selected' | translate }}</p>\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.SliderComponent, selector: "mv-slider", inputs: ["style", "value", "min", "max", "step", "precision", "orientation", "range", "selection", "tooltip", "tooltipSplit", "tooltipPosition", "handle", "reversed", "rtl", "enabled", "naturalArrowKeys", "ticks", "ticksPositions", "ticksLabels", "ticksSnapBounds", "ticksTooltip", "scale", "labelledBy", "rangeHighlights", "formatter", "lockToTicks"], outputs: ["valueChange", "slide", "slideStart", "slideStop", "change"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
7206
7300
  }
7207
7301
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureSettingsPositionComponent, decorators: [{
7208
7302
  type: Component,
@@ -7222,7 +7316,7 @@ class FixtureSettingsStageComponent {
7222
7316
  this.previewService.doUpdateStageAndPositions.next();
7223
7317
  }
7224
7318
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureSettingsStageComponent, deps: [{ token: ProjectService }, { token: PreviewService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
7225
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: FixtureSettingsStageComponent, isStandalone: false, selector: "lib-app-fixture-settings-stage", ngImport: i0, template: "<div class=\"card border-secondary h-100\">\n <div class=\"card-header\">\n {{ 'designer.fixture.setting-stage' | translate }}\n </div>\n\n <div class=\"card-body h-100\">\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 120px; float: left\">\n {{ 'designer.fixture.setting-stage-width' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 140px\"\n [tooltip]=\"'hide'\"\n [value]=\"projectService.project.stageWidthCm\"\n [min]=\"100\"\n [max]=\"2000\"\n [step]=\"5\"\n (change)=\"projectService.project.stageWidthCm = $event.newValue; update()\"\n >\n </mv-slider>\n </div>\n <div class=\"my-auto\">\n <input\n type=\"text\"\n [ngModel]=\"projectService.project.stageWidthCm\"\n (ngModelChange)=\"projectService.project.stageWidthCm = $event; update()\"\n class=\"slider-input-readonly\"\n readonly\n />\n </div>\n <div class=\"my-auto ml-1\" style=\"color: darkgray\">cm</div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 120px; float: left\">\n {{ 'designer.fixture.setting-stage-height' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 140px\"\n [tooltip]=\"'hide'\"\n [value]=\"projectService.project.stageHeightCm\"\n [min]=\"100\"\n [max]=\"2000\"\n [step]=\"5\"\n (change)=\"projectService.project.stageHeightCm = $event.newValue; update()\"\n >\n </mv-slider>\n </div>\n <div class=\"my-auto\">\n <input\n type=\"text\"\n [ngModel]=\"projectService.project.stageHeightCm\"\n (ngModelChange)=\"projectService.project.stageHeightCm = $event; update()\"\n class=\"slider-input-readonly\"\n readonly\n />\n </div>\n <div class=\"my-auto ml-1\" style=\"color: darkgray\">cm</div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 120px; float: left\">\n {{ 'designer.fixture.setting-stage-depth' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 140px\"\n [tooltip]=\"'hide'\"\n [value]=\"projectService.project.stageDepthCm\"\n [min]=\"100\"\n [max]=\"2000\"\n [step]=\"5\"\n (change)=\"projectService.project.stageDepthCm = $event.newValue; update()\"\n >\n </mv-slider>\n </div>\n <div class=\"my-auto\">\n <input\n type=\"text\"\n [ngModel]=\"projectService.project.stageDepthCm\"\n (ngModelChange)=\"projectService.project.stageDepthCm = $event; update()\"\n class=\"slider-input-readonly\"\n readonly\n />\n </div>\n <div class=\"my-auto ml-1\" style=\"color: darkgray\">cm</div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 120px; float: left\">\n {{ 'designer.fixture.setting-stage-floor-height' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 140px\"\n [tooltip]=\"'hide'\"\n [value]=\"projectService.project.stageFloorHeightCm\"\n [min]=\"1\"\n [max]=\"1000\"\n [step]=\"5\"\n (change)=\"projectService.project.stageFloorHeightCm = $event.newValue; update()\"\n >\n </mv-slider>\n </div>\n <div class=\"my-auto\">\n <input\n type=\"text\"\n [ngModel]=\"projectService.project.stageFloorHeightCm\"\n (ngModelChange)=\"projectService.project.stageFloorHeightCm = $event; update()\"\n class=\"slider-input-readonly\"\n readonly\n />\n </div>\n <div class=\"my-auto ml-1\" style=\"color: darkgray\">cm</div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 120px; float: left\">\n {{ 'designer.fixture.setting-stage-ceiling-height' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 140px\"\n [tooltip]=\"'hide'\"\n [value]=\"projectService.project.stageCeilingHeightCm\"\n [min]=\"1\"\n [max]=\"1000\"\n [step]=\"5\"\n (change)=\"projectService.project.stageCeilingHeightCm = $event.newValue; update()\"\n >\n </mv-slider>\n </div>\n <div class=\"my-auto\">\n <input\n type=\"text\"\n [ngModel]=\"projectService.project.stageCeilingHeightCm\"\n (ngModelChange)=\"projectService.project.stageCeilingHeightCm = $event; update()\"\n class=\"slider-input-readonly\"\n readonly\n />\n </div>\n <div class=\"my-auto ml-1\" style=\"color: darkgray\">cm</div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 120px; float: left\">\n {{ 'designer.fixture.setting-stage-pillar-width' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 140px\"\n [tooltip]=\"'hide'\"\n [value]=\"projectService.project.stagePillarWidthCm\"\n [min]=\"1\"\n [max]=\"200\"\n [step]=\"5\"\n (change)=\"projectService.project.stagePillarWidthCm = $event.newValue; update()\"\n >\n </mv-slider>\n </div>\n <div class=\"my-auto\">\n <input\n type=\"text\"\n [ngModel]=\"projectService.project.stagePillarWidthCm\"\n (ngModelChange)=\"projectService.project.stagePillarWidthCm = $event; update()\"\n class=\"slider-input-readonly\"\n readonly\n />\n </div>\n <div class=\"my-auto ml-1\" style=\"color: darkgray\">cm</div>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3$3.SliderComponent, selector: "mv-slider", inputs: ["style", "value", "min", "max", "step", "precision", "orientation", "range", "selection", "tooltip", "tooltipSplit", "tooltipPosition", "handle", "reversed", "rtl", "enabled", "naturalArrowKeys", "ticks", "ticksPositions", "ticksLabels", "ticksSnapBounds", "ticksTooltip", "scale", "labelledBy", "rangeHighlights", "formatter", "lockToTicks"], outputs: ["valueChange", "slide", "slideStart", "slideStop", "change"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
7319
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: FixtureSettingsStageComponent, isStandalone: false, selector: "lib-app-fixture-settings-stage", ngImport: i0, template: "<div class=\"card border-secondary h-100\">\n <div class=\"card-header\">\n {{ 'designer.fixture.setting-stage' | translate }}\n </div>\n\n <div class=\"card-body h-100\">\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 120px; float: left\">\n {{ 'designer.fixture.setting-stage-width' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 140px\"\n [tooltip]=\"'hide'\"\n [value]=\"projectService.project.stageWidthCm\"\n [min]=\"100\"\n [max]=\"2000\"\n [step]=\"5\"\n (change)=\"projectService.project.stageWidthCm = $event.newValue; update()\"\n >\n </mv-slider>\n </div>\n <div class=\"my-auto\">\n <input\n type=\"text\"\n [ngModel]=\"projectService.project.stageWidthCm\"\n (ngModelChange)=\"projectService.project.stageWidthCm = $event; update()\"\n class=\"slider-input-readonly\"\n readonly\n />\n </div>\n <div class=\"my-auto ml-1\" style=\"color: darkgray\">cm</div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 120px; float: left\">\n {{ 'designer.fixture.setting-stage-height' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 140px\"\n [tooltip]=\"'hide'\"\n [value]=\"projectService.project.stageHeightCm\"\n [min]=\"100\"\n [max]=\"2000\"\n [step]=\"5\"\n (change)=\"projectService.project.stageHeightCm = $event.newValue; update()\"\n >\n </mv-slider>\n </div>\n <div class=\"my-auto\">\n <input\n type=\"text\"\n [ngModel]=\"projectService.project.stageHeightCm\"\n (ngModelChange)=\"projectService.project.stageHeightCm = $event; update()\"\n class=\"slider-input-readonly\"\n readonly\n />\n </div>\n <div class=\"my-auto ml-1\" style=\"color: darkgray\">cm</div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 120px; float: left\">\n {{ 'designer.fixture.setting-stage-depth' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 140px\"\n [tooltip]=\"'hide'\"\n [value]=\"projectService.project.stageDepthCm\"\n [min]=\"100\"\n [max]=\"2000\"\n [step]=\"5\"\n (change)=\"projectService.project.stageDepthCm = $event.newValue; update()\"\n >\n </mv-slider>\n </div>\n <div class=\"my-auto\">\n <input\n type=\"text\"\n [ngModel]=\"projectService.project.stageDepthCm\"\n (ngModelChange)=\"projectService.project.stageDepthCm = $event; update()\"\n class=\"slider-input-readonly\"\n readonly\n />\n </div>\n <div class=\"my-auto ml-1\" style=\"color: darkgray\">cm</div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 120px; float: left\">\n {{ 'designer.fixture.setting-stage-floor-height' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 140px\"\n [tooltip]=\"'hide'\"\n [value]=\"projectService.project.stageFloorHeightCm\"\n [min]=\"1\"\n [max]=\"1000\"\n [step]=\"5\"\n (change)=\"projectService.project.stageFloorHeightCm = $event.newValue; update()\"\n >\n </mv-slider>\n </div>\n <div class=\"my-auto\">\n <input\n type=\"text\"\n [ngModel]=\"projectService.project.stageFloorHeightCm\"\n (ngModelChange)=\"projectService.project.stageFloorHeightCm = $event; update()\"\n class=\"slider-input-readonly\"\n readonly\n />\n </div>\n <div class=\"my-auto ml-1\" style=\"color: darkgray\">cm</div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 120px; float: left\">\n {{ 'designer.fixture.setting-stage-ceiling-height' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 140px\"\n [tooltip]=\"'hide'\"\n [value]=\"projectService.project.stageCeilingHeightCm\"\n [min]=\"1\"\n [max]=\"1000\"\n [step]=\"5\"\n (change)=\"projectService.project.stageCeilingHeightCm = $event.newValue; update()\"\n >\n </mv-slider>\n </div>\n <div class=\"my-auto\">\n <input\n type=\"text\"\n [ngModel]=\"projectService.project.stageCeilingHeightCm\"\n (ngModelChange)=\"projectService.project.stageCeilingHeightCm = $event; update()\"\n class=\"slider-input-readonly\"\n readonly\n />\n </div>\n <div class=\"my-auto ml-1\" style=\"color: darkgray\">cm</div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 120px; float: left\">\n {{ 'designer.fixture.setting-stage-pillar-width' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n style=\"width: 140px\"\n [tooltip]=\"'hide'\"\n [value]=\"projectService.project.stagePillarWidthCm\"\n [min]=\"1\"\n [max]=\"200\"\n [step]=\"5\"\n (change)=\"projectService.project.stagePillarWidthCm = $event.newValue; update()\"\n >\n </mv-slider>\n </div>\n <div class=\"my-auto\">\n <input\n type=\"text\"\n [ngModel]=\"projectService.project.stagePillarWidthCm\"\n (ngModelChange)=\"projectService.project.stagePillarWidthCm = $event; update()\"\n class=\"slider-input-readonly\"\n readonly\n />\n </div>\n <div class=\"my-auto ml-1\" style=\"color: darkgray\">cm</div>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.SliderComponent, selector: "mv-slider", inputs: ["style", "value", "min", "max", "step", "precision", "orientation", "range", "selection", "tooltip", "tooltipSplit", "tooltipPosition", "handle", "reversed", "rtl", "enabled", "naturalArrowKeys", "ticks", "ticksPositions", "ticksLabels", "ticksSnapBounds", "ticksTooltip", "scale", "labelledBy", "rangeHighlights", "formatter", "lockToTicks"], outputs: ["valueChange", "slide", "slideStart", "slideStop", "change"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
7226
7320
  }
7227
7321
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureSettingsStageComponent, decorators: [{
7228
7322
  type: Component,
@@ -7263,13 +7357,14 @@ class EffectCurveComponent {
7263
7357
  this.stopUpdateTimer();
7264
7358
  }
7265
7359
  }
7266
- constructor(presetService, animationService, fixtureService, translate, effectService, ngZone) {
7360
+ constructor(presetService, animationService, fixtureService, translate, effectService, ngZone, livePreviewService) {
7267
7361
  this.presetService = presetService;
7268
7362
  this.animationService = animationService;
7269
7363
  this.fixtureService = fixtureService;
7270
7364
  this.translate = translate;
7271
7365
  this.effectService = effectService;
7272
7366
  this.ngZone = ngZone;
7367
+ this.livePreviewService = livePreviewService;
7273
7368
  this.lengthMillisMin = 20;
7274
7369
  this.lengthMillisMax = 8000;
7275
7370
  this.amplitudeMin = 0;
@@ -7488,7 +7583,7 @@ class EffectCurveComponent {
7488
7583
  }
7489
7584
  }
7490
7585
  }
7491
- this.presetService.previewLive();
7586
+ this.livePreviewService.previewLive();
7492
7587
  }
7493
7588
  getChannelName(profileName, channelName) {
7494
7589
  if (this.availableProfiles.length > 1) {
@@ -7534,45 +7629,45 @@ class EffectCurveComponent {
7534
7629
  break;
7535
7630
  }
7536
7631
  }
7537
- this.presetService.previewLive();
7632
+ this.livePreviewService.previewLive();
7538
7633
  }
7539
7634
  setLengthMillis(value) {
7540
7635
  if (!isNaN(value) && value >= this.lengthMillisMin && value <= this.lengthMillisMax) {
7541
7636
  this.curve.lengthMillis = +value;
7542
- this.presetService.previewLive();
7637
+ this.livePreviewService.previewLive();
7543
7638
  }
7544
7639
  }
7545
7640
  setAmplitude(value) {
7546
7641
  if (!isNaN(value) && value >= this.amplitudeMin && value <= this.amplitudeMax) {
7547
7642
  this.curve.amplitude = +value;
7548
- this.presetService.previewLive();
7643
+ this.livePreviewService.previewLive();
7549
7644
  }
7550
7645
  }
7551
7646
  setPosition(value) {
7552
7647
  if (!isNaN(value) && value >= this.percentageMin && value <= this.percentageMax) {
7553
7648
  this.curve.position = +value;
7554
- this.presetService.previewLive();
7649
+ this.livePreviewService.previewLive();
7555
7650
  }
7556
7651
  }
7557
7652
  setPhaseMillis(value) {
7558
7653
  if (!isNaN(value) && value >= this.phaseMillisMin && value <= this.phaseMillisMax) {
7559
7654
  this.curve.phaseMillis = +value;
7560
- this.presetService.previewLive();
7655
+ this.livePreviewService.previewLive();
7561
7656
  }
7562
7657
  }
7563
7658
  setPhasingMillis(value) {
7564
7659
  if (!isNaN(value) && value >= this.phasingMillisMin && value <= this.phasingMillisMax) {
7565
7660
  this.curve.phasingMillis = +value;
7566
- this.presetService.previewLive();
7661
+ this.livePreviewService.previewLive();
7567
7662
  }
7568
7663
  }
7569
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: EffectCurveComponent, deps: [{ token: PresetService }, { token: AnimationService }, { token: FixtureService }, { token: i4.TranslateService }, { token: EffectService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
7570
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: EffectCurveComponent, isStandalone: false, selector: "lib-app-effect-curve", inputs: { curve: "curve", isSelected: "isSelected" }, viewQueries: [{ propertyName: "curveGrid", first: true, predicate: ["curveGrid"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"mr-3\" style=\"float: left\">\n <div class=\"mb-2\">\n <select\n [ngModel]=\"curve.curveType\"\n (ngModelChange)=\"curve.curveType = $event; presetService.previewLive()\"\n style=\"width: 200px; height: 20px\"\n >\n <option [value]=\"'sine'\">\n {{ 'designer.effect.curve-sine' | translate }}\n </option>\n <option [value]=\"'square'\">\n {{ 'designer.effect.curve-square' | translate }}\n </option>\n <!-- <option [value]=\"'triangle'\">\n {{ 'designer.effect.curve-triangle' | translate }}</option>\n <option [value]=\"'sawtooth'\">\n {{ 'designer.effect.curve-sawtooth' | translate }}</option>\n <option [value]=\"'reverse-sawtooth'\">\n {{ 'designer.effect.curve-reverse-sawtooth' | translate }}</option> -->\n </select>\n </div>\n <div>\n <canvas #curveGrid class=\"curve-grid\" width=\"200\" height=\"100\" viewBox=\"150 -75 4850 5150\" preserveAspectRatio=\"none\"></canvas>\n </div>\n</div>\n\n<div class=\"mr-4\" style=\"float: left\">\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-length' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); presetService.previewLive()\"\n [(value)]=\"curve.lengthMillis\"\n style=\"width: 80px\"\n [tooltip]=\"'hide'\"\n [value]=\"0\"\n [min]=\"lengthMillisMin\"\n [max]=\"lengthMillisMax\"\n [step]=\"1\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.lengthMillis\" (ngModelChange)=\"setLengthMillis($event); redraw()\" />\n </div>\n <div class=\"my-auto ml-1\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-amplitude' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); presetService.previewLive()\"\n [(value)]=\"curve.amplitude\"\n style=\"width: 80px\"\n [tooltip]=\"'hide'\"\n [min]=\"amplitudeMin\"\n [max]=\"amplitudeMax\"\n [step]=\"0.01\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.amplitude\" (ngModelChange)=\"setAmplitude($event); redraw()\" />\n </div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-position' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); presetService.previewLive()\"\n [(value)]=\"curve.position\"\n style=\"width: 80px; height: 18px\"\n [tooltip]=\"'hide'\"\n [min]=\"percentageMin\"\n [max]=\"percentageMax\"\n [step]=\"0.01\"\n >\n </mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.position\" (ngModelChange)=\"setPosition($event); redraw()\" />\n </div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-phase' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); presetService.previewLive()\"\n [(value)]=\"curve.phaseMillis\"\n style=\"width: 80px; height: 18px\"\n [tooltip]=\"'hide'\"\n [min]=\"phaseMillisMin\"\n [max]=\"phaseMillisMax\"\n [step]=\"1\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.phaseMillis\" (ngModelChange)=\"setPhaseMillis($event); redraw()\" />\n </div>\n <div class=\"my-auto ml-1\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-chase' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); presetService.previewLive()\"\n [(value)]=\"curve.phasingMillis\"\n style=\"width: 80px; height: 18px\"\n [tooltip]=\"'hide'\"\n [min]=\"phasingMillisMin\"\n [max]=\"phasingMillisMax\"\n [step]=\"1\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.phasingMillis\" (ngModelChange)=\"setPhasingMillis($event); redraw()\" />\n </div>\n <div class=\"my-auto ml-1\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n</div>\n\n<!-- Menu for the capabilities and channels-->\n<div class=\"col col-auto p-0\" style=\"margin-right: 1px; width: 50px; float: left\">\n <div class=\"nav flex-column nav-pills\" id=\"v-pills-tab\" role=\"tablist\" aria-orientation=\"vertical\">\n <a\n class=\"nav-link px-3 active\"\n id=\"v-pills-effect-capabilities-tab\"\n popover=\"{{ 'designer.misc.capabilities' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-effect-capabilities-{{ curve?.uuid }}\"\n role=\"tab\"\n aria-controls=\"v-pills-capabilities\"\n aria-selected=\"true\"\n >\n <i class=\"fa fa-bolt fa-fw\" aria-hidden=\"true\"></i>\n </a>\n <a\n class=\"nav-link px-3\"\n id=\"v-pills-effect-channels-tab\"\n popover=\"{{ 'designer.misc.channels' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-effect-channels-{{ curve?.uuid }}\"\n role=\"tab\"\n aria-controls=\"v-pills-channels\"\n aria-selected=\"false\"\n >\n <i class=\"fa fa-sliders fa-fw\" aria-hidden=\"true\"></i>\n </a>\n </div>\n</div>\n\n<div class=\"h-100\" class=\"applying-to\">\n <div class=\"tab-content h-100\" id=\"v-pills-tabContent\">\n <div class=\"tab-pane h-100 show active\" id=\"v-pills-effect-capabilities-{{ curve?.uuid }}\" role=\"tabpanel\">\n <!-- Capabilities-->\n @for (capability of availableCapabilities; track $index; let i = $index) {\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capability_{{ curve?.uuid + '_' + i }}\"\n [ngModel]=\"capabilityChecked(capability)\"\n (change)=\"toggleCapability($event, capability)\"\n />\n <label class=\"form-check-label\" for=\"capability_{{ curve?.uuid + '_' + i }}\">{{ getCapabilityName(capability) | async }}</label>\n </div>\n }\n </div>\n <div class=\"tab-pane h-100 show\" id=\"v-pills-effect-channels-{{ curve?.uuid }}\" role=\"tabpanel\">\n <!-- channels -->\n\n <!-- profile selection -->\n @if (availableProfiles.length > 1) {\n <div>\n @for (profile of availableProfiles; track profile; let i = $index) {\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"channel_profile_{{ curve?.uuid }}_{{ profile.uuid }}\"\n [ngModel]=\"selectedProfiles.indexOf(profile) >= 0\"\n (change)=\"changeProfileSelection($event, profile)\"\n />\n <label class=\"form-check-label\" for=\"channel_profile_{{ curve?.uuid }}_{{ profile.uuid }}\">{{ profile.name }}</label>\n </div>\n }\n <hr class=\"my-1\" style=\"border-color: white\" />\n </div>\n }\n\n <!-- channels -->\n @for (entry of availableChannels | keyvalue; track entry; let i = $index) { @for (channel of entry.value; track channel; let j =\n $index) {\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"channel_{{ curve?.uuid }}_{{ i }}_{{ j }}\"\n [ngModel]=\"channelChecked(entry.key, channel)\"\n (change)=\"toggleChannel($event, entry.key, channel)\"\n />\n <label class=\"form-check-label\" for=\"channel_{{ curve?.uuid }}_{{ i }}_{{ j }}\">{{\n getChannelName(entry.key.name, channel.name)\n }}</label>\n </div>\n } }\n </div>\n </div>\n</div>\n", styles: [".curve-grid{background-color:#000;border:1px solid white}.applying-to{overflow-y:scroll;height:130px!important;background-color:#222;border:1px solid white;padding:.5rem}.applying-to .form-check:last-child{margin-bottom:.5rem}\n"], dependencies: [{ kind: "directive", type: i3$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3$3.SliderComponent, selector: "mv-slider", inputs: ["style", "value", "min", "max", "step", "precision", "orientation", "range", "selection", "tooltip", "tooltipSplit", "tooltipPosition", "handle", "reversed", "rtl", "enabled", "naturalArrowKeys", "ticks", "ticksPositions", "ticksLabels", "ticksSnapBounds", "ticksTooltip", "scale", "labelledBy", "rangeHighlights", "formatter", "lockToTicks"], outputs: ["valueChange", "slide", "slideStart", "slideStop", "change"] }, { kind: "directive", type: i11.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "pipe", type: i9.AsyncPipe, name: "async" }, { kind: "pipe", type: i9.KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
7664
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: EffectCurveComponent, deps: [{ token: PresetService }, { token: AnimationService }, { token: FixtureService }, { token: i2.TranslateService }, { token: EffectService }, { token: i0.NgZone }, { token: LivePreviewService }], target: i0.ɵɵFactoryTarget.Component }); }
7665
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: EffectCurveComponent, isStandalone: false, selector: "lib-app-effect-curve", inputs: { curve: "curve", isSelected: "isSelected" }, viewQueries: [{ propertyName: "curveGrid", first: true, predicate: ["curveGrid"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"mr-3\" style=\"float: left\">\n <div class=\"mb-2\">\n <select\n [ngModel]=\"curve.curveType\"\n (ngModelChange)=\"curve.curveType = $event; livePreviewService.previewLive()\"\n style=\"width: 200px; height: 20px\"\n >\n <option [value]=\"'sine'\">\n {{ 'designer.effect.curve-sine' | translate }}\n </option>\n <option [value]=\"'square'\">\n {{ 'designer.effect.curve-square' | translate }}\n </option>\n <!-- <option [value]=\"'triangle'\">\n {{ 'designer.effect.curve-triangle' | translate }}</option>\n <option [value]=\"'sawtooth'\">\n {{ 'designer.effect.curve-sawtooth' | translate }}</option>\n <option [value]=\"'reverse-sawtooth'\">\n {{ 'designer.effect.curve-reverse-sawtooth' | translate }}</option> -->\n </select>\n </div>\n <div>\n <canvas #curveGrid class=\"curve-grid\" width=\"200\" height=\"100\" viewBox=\"150 -75 4850 5150\" preserveAspectRatio=\"none\"></canvas>\n </div>\n</div>\n\n<div class=\"mr-4\" style=\"float: left\">\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-length' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); livePreviewService.previewLive()\"\n [(value)]=\"curve.lengthMillis\"\n style=\"width: 80px\"\n [tooltip]=\"'hide'\"\n [value]=\"0\"\n [min]=\"lengthMillisMin\"\n [max]=\"lengthMillisMax\"\n [step]=\"1\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.lengthMillis\" (ngModelChange)=\"setLengthMillis($event); redraw()\" />\n </div>\n <div class=\"my-auto ml-1\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-amplitude' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); livePreviewService.previewLive()\"\n [(value)]=\"curve.amplitude\"\n style=\"width: 80px\"\n [tooltip]=\"'hide'\"\n [min]=\"amplitudeMin\"\n [max]=\"amplitudeMax\"\n [step]=\"0.01\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.amplitude\" (ngModelChange)=\"setAmplitude($event); redraw()\" />\n </div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-position' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); livePreviewService.previewLive()\"\n [(value)]=\"curve.position\"\n style=\"width: 80px; height: 18px\"\n [tooltip]=\"'hide'\"\n [min]=\"percentageMin\"\n [max]=\"percentageMax\"\n [step]=\"0.01\"\n >\n </mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.position\" (ngModelChange)=\"setPosition($event); redraw()\" />\n </div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-phase' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); livePreviewService.previewLive()\"\n [(value)]=\"curve.phaseMillis\"\n style=\"width: 80px; height: 18px\"\n [tooltip]=\"'hide'\"\n [min]=\"phaseMillisMin\"\n [max]=\"phaseMillisMax\"\n [step]=\"1\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.phaseMillis\" (ngModelChange)=\"setPhaseMillis($event); redraw()\" />\n </div>\n <div class=\"my-auto ml-1\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-chase' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); livePreviewService.previewLive()\"\n [(value)]=\"curve.phasingMillis\"\n style=\"width: 80px; height: 18px\"\n [tooltip]=\"'hide'\"\n [min]=\"phasingMillisMin\"\n [max]=\"phasingMillisMax\"\n [step]=\"1\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.phasingMillis\" (ngModelChange)=\"setPhasingMillis($event); redraw()\" />\n </div>\n <div class=\"my-auto ml-1\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n</div>\n\n<!-- Menu for the capabilities and channels-->\n<div class=\"col col-auto p-0\" style=\"margin-right: 1px; width: 50px; float: left\">\n <div class=\"nav flex-column nav-pills\" id=\"v-pills-tab\" role=\"tablist\" aria-orientation=\"vertical\">\n <a\n class=\"nav-link px-3 active\"\n id=\"v-pills-effect-capabilities-tab\"\n popover=\"{{ 'designer.misc.capabilities' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-effect-capabilities-{{ curve?.uuid }}\"\n role=\"tab\"\n aria-controls=\"v-pills-capabilities\"\n aria-selected=\"true\"\n >\n <i class=\"fa fa-bolt fa-fw\" aria-hidden=\"true\"></i>\n </a>\n <a\n class=\"nav-link px-3\"\n id=\"v-pills-effect-channels-tab\"\n popover=\"{{ 'designer.misc.channels' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-effect-channels-{{ curve?.uuid }}\"\n role=\"tab\"\n aria-controls=\"v-pills-channels\"\n aria-selected=\"false\"\n >\n <i class=\"fa fa-sliders fa-fw\" aria-hidden=\"true\"></i>\n </a>\n </div>\n</div>\n\n<div class=\"h-100\" class=\"applying-to\">\n <div class=\"tab-content h-100\" id=\"v-pills-tabContent\">\n <div class=\"tab-pane h-100 show active\" id=\"v-pills-effect-capabilities-{{ curve?.uuid }}\" role=\"tabpanel\">\n <!-- Capabilities-->\n @for (capability of availableCapabilities; track $index; let i = $index) {\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capability_{{ curve?.uuid + '_' + i }}\"\n [ngModel]=\"capabilityChecked(capability)\"\n (change)=\"toggleCapability($event, capability)\"\n />\n <label class=\"form-check-label\" for=\"capability_{{ curve?.uuid + '_' + i }}\">{{ getCapabilityName(capability) | async }}</label>\n </div>\n }\n </div>\n <div class=\"tab-pane h-100 show\" id=\"v-pills-effect-channels-{{ curve?.uuid }}\" role=\"tabpanel\">\n <!-- channels -->\n\n <!-- profile selection -->\n @if (availableProfiles.length > 1) {\n <div>\n @for (profile of availableProfiles; track profile; let i = $index) {\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"channel_profile_{{ curve?.uuid }}_{{ profile.uuid }}\"\n [ngModel]=\"selectedProfiles.indexOf(profile) >= 0\"\n (change)=\"changeProfileSelection($event, profile)\"\n />\n <label class=\"form-check-label\" for=\"channel_profile_{{ curve?.uuid }}_{{ profile.uuid }}\">{{ profile.name }}</label>\n </div>\n }\n <hr class=\"my-1\" style=\"border-color: white\" />\n </div>\n }\n\n <!-- channels -->\n @for (entry of availableChannels | keyvalue; track entry; let i = $index) { @for (channel of entry.value; track channel; let j =\n $index) {\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"channel_{{ curve?.uuid }}_{{ i }}_{{ j }}\"\n [ngModel]=\"channelChecked(entry.key, channel)\"\n (change)=\"toggleChannel($event, entry.key, channel)\"\n />\n <label class=\"form-check-label\" for=\"channel_{{ curve?.uuid }}_{{ i }}_{{ j }}\">{{\n getChannelName(entry.key.name, channel.name)\n }}</label>\n </div>\n } }\n </div>\n </div>\n</div>\n", styles: [".curve-grid{background-color:#000;border:1px solid white}.applying-to{overflow-y:scroll;height:130px!important;background-color:#222;border:1px solid white;padding:.5rem}.applying-to .form-check:last-child{margin-bottom:.5rem}\n"], dependencies: [{ kind: "directive", type: i3$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.SliderComponent, selector: "mv-slider", inputs: ["style", "value", "min", "max", "step", "precision", "orientation", "range", "selection", "tooltip", "tooltipSplit", "tooltipPosition", "handle", "reversed", "rtl", "enabled", "naturalArrowKeys", "ticks", "ticksPositions", "ticksLabels", "ticksSnapBounds", "ticksTooltip", "scale", "labelledBy", "rangeHighlights", "formatter", "lockToTicks"], outputs: ["valueChange", "slide", "slideStart", "slideStop", "change"] }, { kind: "directive", type: i12.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "pipe", type: i10$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i10$1.KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
7571
7666
  }
7572
7667
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: EffectCurveComponent, decorators: [{
7573
7668
  type: Component,
7574
- args: [{ selector: 'lib-app-effect-curve', standalone: false, template: "<div class=\"mr-3\" style=\"float: left\">\n <div class=\"mb-2\">\n <select\n [ngModel]=\"curve.curveType\"\n (ngModelChange)=\"curve.curveType = $event; presetService.previewLive()\"\n style=\"width: 200px; height: 20px\"\n >\n <option [value]=\"'sine'\">\n {{ 'designer.effect.curve-sine' | translate }}\n </option>\n <option [value]=\"'square'\">\n {{ 'designer.effect.curve-square' | translate }}\n </option>\n <!-- <option [value]=\"'triangle'\">\n {{ 'designer.effect.curve-triangle' | translate }}</option>\n <option [value]=\"'sawtooth'\">\n {{ 'designer.effect.curve-sawtooth' | translate }}</option>\n <option [value]=\"'reverse-sawtooth'\">\n {{ 'designer.effect.curve-reverse-sawtooth' | translate }}</option> -->\n </select>\n </div>\n <div>\n <canvas #curveGrid class=\"curve-grid\" width=\"200\" height=\"100\" viewBox=\"150 -75 4850 5150\" preserveAspectRatio=\"none\"></canvas>\n </div>\n</div>\n\n<div class=\"mr-4\" style=\"float: left\">\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-length' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); presetService.previewLive()\"\n [(value)]=\"curve.lengthMillis\"\n style=\"width: 80px\"\n [tooltip]=\"'hide'\"\n [value]=\"0\"\n [min]=\"lengthMillisMin\"\n [max]=\"lengthMillisMax\"\n [step]=\"1\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.lengthMillis\" (ngModelChange)=\"setLengthMillis($event); redraw()\" />\n </div>\n <div class=\"my-auto ml-1\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-amplitude' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); presetService.previewLive()\"\n [(value)]=\"curve.amplitude\"\n style=\"width: 80px\"\n [tooltip]=\"'hide'\"\n [min]=\"amplitudeMin\"\n [max]=\"amplitudeMax\"\n [step]=\"0.01\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.amplitude\" (ngModelChange)=\"setAmplitude($event); redraw()\" />\n </div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-position' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); presetService.previewLive()\"\n [(value)]=\"curve.position\"\n style=\"width: 80px; height: 18px\"\n [tooltip]=\"'hide'\"\n [min]=\"percentageMin\"\n [max]=\"percentageMax\"\n [step]=\"0.01\"\n >\n </mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.position\" (ngModelChange)=\"setPosition($event); redraw()\" />\n </div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-phase' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); presetService.previewLive()\"\n [(value)]=\"curve.phaseMillis\"\n style=\"width: 80px; height: 18px\"\n [tooltip]=\"'hide'\"\n [min]=\"phaseMillisMin\"\n [max]=\"phaseMillisMax\"\n [step]=\"1\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.phaseMillis\" (ngModelChange)=\"setPhaseMillis($event); redraw()\" />\n </div>\n <div class=\"my-auto ml-1\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-chase' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); presetService.previewLive()\"\n [(value)]=\"curve.phasingMillis\"\n style=\"width: 80px; height: 18px\"\n [tooltip]=\"'hide'\"\n [min]=\"phasingMillisMin\"\n [max]=\"phasingMillisMax\"\n [step]=\"1\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.phasingMillis\" (ngModelChange)=\"setPhasingMillis($event); redraw()\" />\n </div>\n <div class=\"my-auto ml-1\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n</div>\n\n<!-- Menu for the capabilities and channels-->\n<div class=\"col col-auto p-0\" style=\"margin-right: 1px; width: 50px; float: left\">\n <div class=\"nav flex-column nav-pills\" id=\"v-pills-tab\" role=\"tablist\" aria-orientation=\"vertical\">\n <a\n class=\"nav-link px-3 active\"\n id=\"v-pills-effect-capabilities-tab\"\n popover=\"{{ 'designer.misc.capabilities' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-effect-capabilities-{{ curve?.uuid }}\"\n role=\"tab\"\n aria-controls=\"v-pills-capabilities\"\n aria-selected=\"true\"\n >\n <i class=\"fa fa-bolt fa-fw\" aria-hidden=\"true\"></i>\n </a>\n <a\n class=\"nav-link px-3\"\n id=\"v-pills-effect-channels-tab\"\n popover=\"{{ 'designer.misc.channels' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-effect-channels-{{ curve?.uuid }}\"\n role=\"tab\"\n aria-controls=\"v-pills-channels\"\n aria-selected=\"false\"\n >\n <i class=\"fa fa-sliders fa-fw\" aria-hidden=\"true\"></i>\n </a>\n </div>\n</div>\n\n<div class=\"h-100\" class=\"applying-to\">\n <div class=\"tab-content h-100\" id=\"v-pills-tabContent\">\n <div class=\"tab-pane h-100 show active\" id=\"v-pills-effect-capabilities-{{ curve?.uuid }}\" role=\"tabpanel\">\n <!-- Capabilities-->\n @for (capability of availableCapabilities; track $index; let i = $index) {\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capability_{{ curve?.uuid + '_' + i }}\"\n [ngModel]=\"capabilityChecked(capability)\"\n (change)=\"toggleCapability($event, capability)\"\n />\n <label class=\"form-check-label\" for=\"capability_{{ curve?.uuid + '_' + i }}\">{{ getCapabilityName(capability) | async }}</label>\n </div>\n }\n </div>\n <div class=\"tab-pane h-100 show\" id=\"v-pills-effect-channels-{{ curve?.uuid }}\" role=\"tabpanel\">\n <!-- channels -->\n\n <!-- profile selection -->\n @if (availableProfiles.length > 1) {\n <div>\n @for (profile of availableProfiles; track profile; let i = $index) {\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"channel_profile_{{ curve?.uuid }}_{{ profile.uuid }}\"\n [ngModel]=\"selectedProfiles.indexOf(profile) >= 0\"\n (change)=\"changeProfileSelection($event, profile)\"\n />\n <label class=\"form-check-label\" for=\"channel_profile_{{ curve?.uuid }}_{{ profile.uuid }}\">{{ profile.name }}</label>\n </div>\n }\n <hr class=\"my-1\" style=\"border-color: white\" />\n </div>\n }\n\n <!-- channels -->\n @for (entry of availableChannels | keyvalue; track entry; let i = $index) { @for (channel of entry.value; track channel; let j =\n $index) {\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"channel_{{ curve?.uuid }}_{{ i }}_{{ j }}\"\n [ngModel]=\"channelChecked(entry.key, channel)\"\n (change)=\"toggleChannel($event, entry.key, channel)\"\n />\n <label class=\"form-check-label\" for=\"channel_{{ curve?.uuid }}_{{ i }}_{{ j }}\">{{\n getChannelName(entry.key.name, channel.name)\n }}</label>\n </div>\n } }\n </div>\n </div>\n</div>\n", styles: [".curve-grid{background-color:#000;border:1px solid white}.applying-to{overflow-y:scroll;height:130px!important;background-color:#222;border:1px solid white;padding:.5rem}.applying-to .form-check:last-child{margin-bottom:.5rem}\n"] }]
7575
- }], ctorParameters: () => [{ type: PresetService }, { type: AnimationService }, { type: FixtureService }, { type: i4.TranslateService }, { type: EffectService }, { type: i0.NgZone }], propDecorators: { curve: [{
7669
+ args: [{ selector: 'lib-app-effect-curve', standalone: false, template: "<div class=\"mr-3\" style=\"float: left\">\n <div class=\"mb-2\">\n <select\n [ngModel]=\"curve.curveType\"\n (ngModelChange)=\"curve.curveType = $event; livePreviewService.previewLive()\"\n style=\"width: 200px; height: 20px\"\n >\n <option [value]=\"'sine'\">\n {{ 'designer.effect.curve-sine' | translate }}\n </option>\n <option [value]=\"'square'\">\n {{ 'designer.effect.curve-square' | translate }}\n </option>\n <!-- <option [value]=\"'triangle'\">\n {{ 'designer.effect.curve-triangle' | translate }}</option>\n <option [value]=\"'sawtooth'\">\n {{ 'designer.effect.curve-sawtooth' | translate }}</option>\n <option [value]=\"'reverse-sawtooth'\">\n {{ 'designer.effect.curve-reverse-sawtooth' | translate }}</option> -->\n </select>\n </div>\n <div>\n <canvas #curveGrid class=\"curve-grid\" width=\"200\" height=\"100\" viewBox=\"150 -75 4850 5150\" preserveAspectRatio=\"none\"></canvas>\n </div>\n</div>\n\n<div class=\"mr-4\" style=\"float: left\">\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-length' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); livePreviewService.previewLive()\"\n [(value)]=\"curve.lengthMillis\"\n style=\"width: 80px\"\n [tooltip]=\"'hide'\"\n [value]=\"0\"\n [min]=\"lengthMillisMin\"\n [max]=\"lengthMillisMax\"\n [step]=\"1\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.lengthMillis\" (ngModelChange)=\"setLengthMillis($event); redraw()\" />\n </div>\n <div class=\"my-auto ml-1\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-amplitude' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); livePreviewService.previewLive()\"\n [(value)]=\"curve.amplitude\"\n style=\"width: 80px\"\n [tooltip]=\"'hide'\"\n [min]=\"amplitudeMin\"\n [max]=\"amplitudeMax\"\n [step]=\"0.01\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.amplitude\" (ngModelChange)=\"setAmplitude($event); redraw()\" />\n </div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-position' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); livePreviewService.previewLive()\"\n [(value)]=\"curve.position\"\n style=\"width: 80px; height: 18px\"\n [tooltip]=\"'hide'\"\n [min]=\"percentageMin\"\n [max]=\"percentageMax\"\n [step]=\"0.01\"\n >\n </mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.position\" (ngModelChange)=\"setPosition($event); redraw()\" />\n </div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-phase' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); livePreviewService.previewLive()\"\n [(value)]=\"curve.phaseMillis\"\n style=\"width: 80px; height: 18px\"\n [tooltip]=\"'hide'\"\n [min]=\"phaseMillisMin\"\n [max]=\"phaseMillisMax\"\n [step]=\"1\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.phaseMillis\" (ngModelChange)=\"setPhaseMillis($event); redraw()\" />\n </div>\n <div class=\"my-auto ml-1\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-chase' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); livePreviewService.previewLive()\"\n [(value)]=\"curve.phasingMillis\"\n style=\"width: 80px; height: 18px\"\n [tooltip]=\"'hide'\"\n [min]=\"phasingMillisMin\"\n [max]=\"phasingMillisMax\"\n [step]=\"1\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.phasingMillis\" (ngModelChange)=\"setPhasingMillis($event); redraw()\" />\n </div>\n <div class=\"my-auto ml-1\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n</div>\n\n<!-- Menu for the capabilities and channels-->\n<div class=\"col col-auto p-0\" style=\"margin-right: 1px; width: 50px; float: left\">\n <div class=\"nav flex-column nav-pills\" id=\"v-pills-tab\" role=\"tablist\" aria-orientation=\"vertical\">\n <a\n class=\"nav-link px-3 active\"\n id=\"v-pills-effect-capabilities-tab\"\n popover=\"{{ 'designer.misc.capabilities' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-effect-capabilities-{{ curve?.uuid }}\"\n role=\"tab\"\n aria-controls=\"v-pills-capabilities\"\n aria-selected=\"true\"\n >\n <i class=\"fa fa-bolt fa-fw\" aria-hidden=\"true\"></i>\n </a>\n <a\n class=\"nav-link px-3\"\n id=\"v-pills-effect-channels-tab\"\n popover=\"{{ 'designer.misc.channels' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-effect-channels-{{ curve?.uuid }}\"\n role=\"tab\"\n aria-controls=\"v-pills-channels\"\n aria-selected=\"false\"\n >\n <i class=\"fa fa-sliders fa-fw\" aria-hidden=\"true\"></i>\n </a>\n </div>\n</div>\n\n<div class=\"h-100\" class=\"applying-to\">\n <div class=\"tab-content h-100\" id=\"v-pills-tabContent\">\n <div class=\"tab-pane h-100 show active\" id=\"v-pills-effect-capabilities-{{ curve?.uuid }}\" role=\"tabpanel\">\n <!-- Capabilities-->\n @for (capability of availableCapabilities; track $index; let i = $index) {\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capability_{{ curve?.uuid + '_' + i }}\"\n [ngModel]=\"capabilityChecked(capability)\"\n (change)=\"toggleCapability($event, capability)\"\n />\n <label class=\"form-check-label\" for=\"capability_{{ curve?.uuid + '_' + i }}\">{{ getCapabilityName(capability) | async }}</label>\n </div>\n }\n </div>\n <div class=\"tab-pane h-100 show\" id=\"v-pills-effect-channels-{{ curve?.uuid }}\" role=\"tabpanel\">\n <!-- channels -->\n\n <!-- profile selection -->\n @if (availableProfiles.length > 1) {\n <div>\n @for (profile of availableProfiles; track profile; let i = $index) {\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"channel_profile_{{ curve?.uuid }}_{{ profile.uuid }}\"\n [ngModel]=\"selectedProfiles.indexOf(profile) >= 0\"\n (change)=\"changeProfileSelection($event, profile)\"\n />\n <label class=\"form-check-label\" for=\"channel_profile_{{ curve?.uuid }}_{{ profile.uuid }}\">{{ profile.name }}</label>\n </div>\n }\n <hr class=\"my-1\" style=\"border-color: white\" />\n </div>\n }\n\n <!-- channels -->\n @for (entry of availableChannels | keyvalue; track entry; let i = $index) { @for (channel of entry.value; track channel; let j =\n $index) {\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"channel_{{ curve?.uuid }}_{{ i }}_{{ j }}\"\n [ngModel]=\"channelChecked(entry.key, channel)\"\n (change)=\"toggleChannel($event, entry.key, channel)\"\n />\n <label class=\"form-check-label\" for=\"channel_{{ curve?.uuid }}_{{ i }}_{{ j }}\">{{\n getChannelName(entry.key.name, channel.name)\n }}</label>\n </div>\n } }\n </div>\n </div>\n</div>\n", styles: [".curve-grid{background-color:#000;border:1px solid white}.applying-to{overflow-y:scroll;height:130px!important;background-color:#222;border:1px solid white;padding:.5rem}.applying-to .form-check:last-child{margin-bottom:.5rem}\n"] }]
7670
+ }], ctorParameters: () => [{ type: PresetService }, { type: AnimationService }, { type: FixtureService }, { type: i2.TranslateService }, { type: EffectService }, { type: i0.NgZone }, { type: LivePreviewService }], propDecorators: { curve: [{
7576
7671
  type: Input
7577
7672
  }], isSelected: [{
7578
7673
  type: Input
@@ -7606,11 +7701,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
7606
7701
  }] } });
7607
7702
 
7608
7703
  class EffectComponent {
7609
- constructor(uuidService, presetService, effectService, warningDialogService) {
7704
+ constructor(uuidService, presetService, effectService, warningDialogService, livePreviewService) {
7610
7705
  this.uuidService = uuidService;
7611
7706
  this.presetService = presetService;
7612
7707
  this.effectService = effectService;
7613
7708
  this.warningDialogService = warningDialogService;
7709
+ this.livePreviewService = livePreviewService;
7614
7710
  }
7615
7711
  ngOnInit() { }
7616
7712
  addEffect(effect) {
@@ -7623,7 +7719,7 @@ class EffectComponent {
7623
7719
  const effect = new EffectCurve();
7624
7720
  effect.uuid = this.uuidService.getUuid();
7625
7721
  this.addEffect(effect);
7626
- this.presetService.previewLive();
7722
+ this.livePreviewService.previewLive();
7627
7723
  }
7628
7724
  addPanTiltEffect() {
7629
7725
  this.addEffect(new EffectPanTilt());
@@ -7644,18 +7740,18 @@ class EffectComponent {
7644
7740
  .pipe(map((result) => {
7645
7741
  if (result) {
7646
7742
  this.presetService.selectedPreset.effects.splice(this.presetService.selectedPreset.effects.indexOf(effect), 1);
7647
- this.presetService.previewLive();
7743
+ this.livePreviewService.previewLive();
7648
7744
  }
7649
7745
  }))
7650
7746
  .subscribe();
7651
7747
  }
7652
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: EffectComponent, deps: [{ token: UuidService }, { token: PresetService }, { token: EffectService }, { token: WarningDialogService }], target: i0.ɵɵFactoryTarget.Component }); }
7653
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: EffectComponent, isStandalone: false, selector: "lib-app-effect", ngImport: i0, template: "<div class=\"card border-secondary panel h-100\">\n @if (presetService.selectedPreset) {\n <div class=\"card-body capability-container\">\n <div class=\"m-3\">\n <accordion [closeOthers]=\"true\">\n @for (item of presetService.selectedPreset.effects; track item; let i = $index) {\n <accordion-group [isOpen]=\"effectService.selectedEffect == item\" (isOpenChange)=\"openEffect(item, $event)\" style=\"margin-top: 1px\">\n <button class=\"btn btn-link btn-block clearfix\" accordion-heading>\n <div class=\"pull-left float-left d-flex w-100\">\n @if (item.type == 'curve') {\n <i class=\"fa fa-area-chart fa-fw my-auto\" aria-hidden=\"true\"></i>\n } @if (item.type == 'pan-tilt') {\n <i class=\"fa fa-arrows-alt fa-fw my-auto\" aria-hidden=\"true\"></i>\n }\n <span class=\"ml-2\">{{ 'designer.effect.type-' + item.type | translate }}</span>\n <div class=\"ml-auto mr-2\">\n <i\n (click)=\"item.visible = !item.visible; presetService.previewLive(); $event.stopPropagation()\"\n class=\"fa fa-eye fa-fw\"\n [class.text-primary]=\"item.visible\"\n aria-hidden=\"true\"\n ></i>\n </div>\n <div class=\"mr-2\">\n <i (click)=\"this.deleteEffect(item); $event.stopPropagation()\" class=\"fa fa-trash fa-fw\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"mr-2\">\n @if (item == effectService.selectedEffect) {\n <i class=\"fa fa-caret-down fa-fw\" aria-hidden=\"true\"></i>\n } @if (item != effectService.selectedEffect) {\n <i class=\"fa fa-caret-right fa-fw\" aria-hidden=\"true\"></i>\n }\n </div>\n </div>\n </button>\n @if (item.type == 'curve') {\n <div style=\"min-width: 670px\">\n <lib-app-effect-curve [curve]=\"item\" [isSelected]=\"item == effectService.selectedEffect\"></lib-app-effect-curve>\n </div>\n } @if (item.type == 'pan-tilt') {\n <div style=\"min-width: 500px\">\n <lib-app-effect-pan-tilt></lib-app-effect-pan-tilt>\n </div>\n }\n </accordion-group>\n }\n </accordion>\n <div class=\"d-flex mx-auto mt-3\">\n <div class=\"dropdown d-flex\">\n <a\n class=\"btn btn-secondary dropdown-toggle\"\n href=\"#\"\n role=\"button\"\n id=\"dropdownMenuLink\"\n data-toggle=\"dropdown\"\n aria-haspopup=\"true\"\n aria-expanded=\"false\"\n >\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i> {{ 'designer.effect.add-new' | translate }}\n </a>\n <div class=\"dropdown-menu\" aria-labelledby=\"dropdownMenuLink\">\n <a class=\"dropdown-item\" href=\"#\" (click)=\"addCurveEffect(); (false)\">\n <i class=\"fa fa-area-chart fa-fw\" aria-hidden=\"true\"></i> {{ 'designer.effect.curve' | translate }}</a\n >\n <!-- <a class=\"dropdown-item\" href=\"#\" (click)=\"addPanTiltEffect()\">\n <i class=\"fa fa-arrows-alt fa-fw\" aria-hidden=\"true\"></i> Pan/Tilt</a> -->\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: i5$1.AccordionComponent, selector: "accordion", inputs: ["isAnimated", "closeOthers"] }, { kind: "component", type: i5$1.AccordionPanelComponent, selector: "accordion-group, accordion-panel", inputs: ["heading", "panelClass", "isDisabled", "isOpen"], outputs: ["isOpenChange"] }, { kind: "component", type: EffectCurveComponent, selector: "lib-app-effect-curve", inputs: ["curve", "isSelected"] }, { kind: "component", type: EffectPanTiltComponent, selector: "lib-app-effect-pan-tilt" }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
7748
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: EffectComponent, deps: [{ token: UuidService }, { token: PresetService }, { token: EffectService }, { token: WarningDialogService }, { token: LivePreviewService }], target: i0.ɵɵFactoryTarget.Component }); }
7749
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: EffectComponent, isStandalone: false, selector: "lib-app-effect", ngImport: i0, template: "<div class=\"card border-secondary panel h-100\">\n @if (presetService.selectedPreset) {\n <div class=\"card-body capability-container\">\n <div class=\"m-3\">\n <accordion [closeOthers]=\"true\">\n @for (item of presetService.selectedPreset.effects; track item; let i = $index) {\n <accordion-group [isOpen]=\"effectService.selectedEffect == item\" (isOpenChange)=\"openEffect(item, $event)\" style=\"margin-top: 1px\">\n <button class=\"btn btn-link btn-block clearfix\" accordion-heading>\n <div class=\"pull-left float-left d-flex w-100\">\n @if (item.type == 'curve') {\n <i class=\"fa fa-area-chart fa-fw my-auto\" aria-hidden=\"true\"></i>\n } @if (item.type == 'pan-tilt') {\n <i class=\"fa fa-arrows-alt fa-fw my-auto\" aria-hidden=\"true\"></i>\n }\n <span class=\"ml-2\">{{ 'designer.effect.type-' + item.type | translate }}</span>\n <div class=\"ml-auto mr-2\">\n <i\n (click)=\"item.visible = !item.visible; livePreviewService.previewLive(); $event.stopPropagation()\"\n class=\"fa fa-eye fa-fw\"\n [class.text-primary]=\"item.visible\"\n aria-hidden=\"true\"\n ></i>\n </div>\n <div class=\"mr-2\">\n <i (click)=\"this.deleteEffect(item); $event.stopPropagation()\" class=\"fa fa-trash fa-fw\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"mr-2\">\n @if (item == effectService.selectedEffect) {\n <i class=\"fa fa-caret-down fa-fw\" aria-hidden=\"true\"></i>\n } @if (item != effectService.selectedEffect) {\n <i class=\"fa fa-caret-right fa-fw\" aria-hidden=\"true\"></i>\n }\n </div>\n </div>\n </button>\n @if (item.type == 'curve') {\n <div style=\"min-width: 670px\">\n <lib-app-effect-curve [curve]=\"item\" [isSelected]=\"item == effectService.selectedEffect\"></lib-app-effect-curve>\n </div>\n } @if (item.type == 'pan-tilt') {\n <div style=\"min-width: 500px\">\n <lib-app-effect-pan-tilt></lib-app-effect-pan-tilt>\n </div>\n }\n </accordion-group>\n }\n </accordion>\n <div class=\"d-flex mx-auto mt-3\">\n <div class=\"dropdown d-flex\">\n <a\n class=\"btn btn-secondary dropdown-toggle\"\n href=\"#\"\n role=\"button\"\n id=\"dropdownMenuLink\"\n data-toggle=\"dropdown\"\n aria-haspopup=\"true\"\n aria-expanded=\"false\"\n >\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i> {{ 'designer.effect.add-new' | translate }}\n </a>\n <div class=\"dropdown-menu\" aria-labelledby=\"dropdownMenuLink\">\n <a class=\"dropdown-item\" href=\"#\" (click)=\"addCurveEffect(); (false)\">\n <i class=\"fa fa-area-chart fa-fw\" aria-hidden=\"true\"></i> {{ 'designer.effect.curve' | translate }}</a\n >\n <!-- <a class=\"dropdown-item\" href=\"#\" (click)=\"addPanTiltEffect()\">\n <i class=\"fa fa-arrows-alt fa-fw\" aria-hidden=\"true\"></i> Pan/Tilt</a> -->\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: i6.AccordionComponent, selector: "accordion", inputs: ["isAnimated", "closeOthers"] }, { kind: "component", type: i6.AccordionPanelComponent, selector: "accordion-group, accordion-panel", inputs: ["heading", "panelClass", "isDisabled", "isOpen"], outputs: ["isOpenChange"] }, { kind: "component", type: EffectCurveComponent, selector: "lib-app-effect-curve", inputs: ["curve", "isSelected"] }, { kind: "component", type: EffectPanTiltComponent, selector: "lib-app-effect-pan-tilt" }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
7654
7750
  }
7655
7751
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: EffectComponent, decorators: [{
7656
7752
  type: Component,
7657
- args: [{ selector: 'lib-app-effect', standalone: false, template: "<div class=\"card border-secondary panel h-100\">\n @if (presetService.selectedPreset) {\n <div class=\"card-body capability-container\">\n <div class=\"m-3\">\n <accordion [closeOthers]=\"true\">\n @for (item of presetService.selectedPreset.effects; track item; let i = $index) {\n <accordion-group [isOpen]=\"effectService.selectedEffect == item\" (isOpenChange)=\"openEffect(item, $event)\" style=\"margin-top: 1px\">\n <button class=\"btn btn-link btn-block clearfix\" accordion-heading>\n <div class=\"pull-left float-left d-flex w-100\">\n @if (item.type == 'curve') {\n <i class=\"fa fa-area-chart fa-fw my-auto\" aria-hidden=\"true\"></i>\n } @if (item.type == 'pan-tilt') {\n <i class=\"fa fa-arrows-alt fa-fw my-auto\" aria-hidden=\"true\"></i>\n }\n <span class=\"ml-2\">{{ 'designer.effect.type-' + item.type | translate }}</span>\n <div class=\"ml-auto mr-2\">\n <i\n (click)=\"item.visible = !item.visible; presetService.previewLive(); $event.stopPropagation()\"\n class=\"fa fa-eye fa-fw\"\n [class.text-primary]=\"item.visible\"\n aria-hidden=\"true\"\n ></i>\n </div>\n <div class=\"mr-2\">\n <i (click)=\"this.deleteEffect(item); $event.stopPropagation()\" class=\"fa fa-trash fa-fw\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"mr-2\">\n @if (item == effectService.selectedEffect) {\n <i class=\"fa fa-caret-down fa-fw\" aria-hidden=\"true\"></i>\n } @if (item != effectService.selectedEffect) {\n <i class=\"fa fa-caret-right fa-fw\" aria-hidden=\"true\"></i>\n }\n </div>\n </div>\n </button>\n @if (item.type == 'curve') {\n <div style=\"min-width: 670px\">\n <lib-app-effect-curve [curve]=\"item\" [isSelected]=\"item == effectService.selectedEffect\"></lib-app-effect-curve>\n </div>\n } @if (item.type == 'pan-tilt') {\n <div style=\"min-width: 500px\">\n <lib-app-effect-pan-tilt></lib-app-effect-pan-tilt>\n </div>\n }\n </accordion-group>\n }\n </accordion>\n <div class=\"d-flex mx-auto mt-3\">\n <div class=\"dropdown d-flex\">\n <a\n class=\"btn btn-secondary dropdown-toggle\"\n href=\"#\"\n role=\"button\"\n id=\"dropdownMenuLink\"\n data-toggle=\"dropdown\"\n aria-haspopup=\"true\"\n aria-expanded=\"false\"\n >\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i> {{ 'designer.effect.add-new' | translate }}\n </a>\n <div class=\"dropdown-menu\" aria-labelledby=\"dropdownMenuLink\">\n <a class=\"dropdown-item\" href=\"#\" (click)=\"addCurveEffect(); (false)\">\n <i class=\"fa fa-area-chart fa-fw\" aria-hidden=\"true\"></i> {{ 'designer.effect.curve' | translate }}</a\n >\n <!-- <a class=\"dropdown-item\" href=\"#\" (click)=\"addPanTiltEffect()\">\n <i class=\"fa fa-arrows-alt fa-fw\" aria-hidden=\"true\"></i> Pan/Tilt</a> -->\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n</div>\n" }]
7658
- }], ctorParameters: () => [{ type: UuidService }, { type: PresetService }, { type: EffectService }, { type: WarningDialogService }] });
7753
+ args: [{ selector: 'lib-app-effect', standalone: false, template: "<div class=\"card border-secondary panel h-100\">\n @if (presetService.selectedPreset) {\n <div class=\"card-body capability-container\">\n <div class=\"m-3\">\n <accordion [closeOthers]=\"true\">\n @for (item of presetService.selectedPreset.effects; track item; let i = $index) {\n <accordion-group [isOpen]=\"effectService.selectedEffect == item\" (isOpenChange)=\"openEffect(item, $event)\" style=\"margin-top: 1px\">\n <button class=\"btn btn-link btn-block clearfix\" accordion-heading>\n <div class=\"pull-left float-left d-flex w-100\">\n @if (item.type == 'curve') {\n <i class=\"fa fa-area-chart fa-fw my-auto\" aria-hidden=\"true\"></i>\n } @if (item.type == 'pan-tilt') {\n <i class=\"fa fa-arrows-alt fa-fw my-auto\" aria-hidden=\"true\"></i>\n }\n <span class=\"ml-2\">{{ 'designer.effect.type-' + item.type | translate }}</span>\n <div class=\"ml-auto mr-2\">\n <i\n (click)=\"item.visible = !item.visible; livePreviewService.previewLive(); $event.stopPropagation()\"\n class=\"fa fa-eye fa-fw\"\n [class.text-primary]=\"item.visible\"\n aria-hidden=\"true\"\n ></i>\n </div>\n <div class=\"mr-2\">\n <i (click)=\"this.deleteEffect(item); $event.stopPropagation()\" class=\"fa fa-trash fa-fw\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"mr-2\">\n @if (item == effectService.selectedEffect) {\n <i class=\"fa fa-caret-down fa-fw\" aria-hidden=\"true\"></i>\n } @if (item != effectService.selectedEffect) {\n <i class=\"fa fa-caret-right fa-fw\" aria-hidden=\"true\"></i>\n }\n </div>\n </div>\n </button>\n @if (item.type == 'curve') {\n <div style=\"min-width: 670px\">\n <lib-app-effect-curve [curve]=\"item\" [isSelected]=\"item == effectService.selectedEffect\"></lib-app-effect-curve>\n </div>\n } @if (item.type == 'pan-tilt') {\n <div style=\"min-width: 500px\">\n <lib-app-effect-pan-tilt></lib-app-effect-pan-tilt>\n </div>\n }\n </accordion-group>\n }\n </accordion>\n <div class=\"d-flex mx-auto mt-3\">\n <div class=\"dropdown d-flex\">\n <a\n class=\"btn btn-secondary dropdown-toggle\"\n href=\"#\"\n role=\"button\"\n id=\"dropdownMenuLink\"\n data-toggle=\"dropdown\"\n aria-haspopup=\"true\"\n aria-expanded=\"false\"\n >\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i> {{ 'designer.effect.add-new' | translate }}\n </a>\n <div class=\"dropdown-menu\" aria-labelledby=\"dropdownMenuLink\">\n <a class=\"dropdown-item\" href=\"#\" (click)=\"addCurveEffect(); (false)\">\n <i class=\"fa fa-area-chart fa-fw\" aria-hidden=\"true\"></i> {{ 'designer.effect.curve' | translate }}</a\n >\n <!-- <a class=\"dropdown-item\" href=\"#\" (click)=\"addPanTiltEffect()\">\n <i class=\"fa fa-arrows-alt fa-fw\" aria-hidden=\"true\"></i> Pan/Tilt</a> -->\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n</div>\n" }]
7754
+ }], ctorParameters: () => [{ type: UuidService }, { type: PresetService }, { type: EffectService }, { type: WarningDialogService }, { type: LivePreviewService }] });
7659
7755
 
7660
7756
  class PresetSettingsComponent {
7661
7757
  constructor(bsModalRef) {
@@ -7701,7 +7797,7 @@ class PresetSettingsComponent {
7701
7797
  this.ok();
7702
7798
  }
7703
7799
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PresetSettingsComponent, deps: [{ token: i1$1.BsModalRef }], target: i0.ɵɵFactoryTarget.Component }); }
7704
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: PresetSettingsComponent, isStandalone: false, selector: "lib-preset-settings", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ name }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"bsModalRef.hide()\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.preset.settings-name' | translate }}</label>\n <div class=\"col-lg-7\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"name\" (ngModelChange)=\"name = $event\" />\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.preset.settings-start' | translate }}</label>\n <div class=\"col-lg-7\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"startMillis\" (ngModelChange)=\"startMillis = $event\" />\n </div>\n <div class=\"col-lg-1 d-flex p-0\">\n <div class=\"my-auto\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.preset.settings-end' | translate }}</label>\n <div class=\"col-lg-7\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"endMillis\" (ngModelChange)=\"endMillis = $event\" />\n </div>\n <div class=\"col-lg-1 d-flex p-0\">\n <div class=\"my-auto\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.preset.settings-fade-in' | translate }}</label>\n <div class=\"col-lg-7\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"fadeInMillis\" (ngModelChange)=\"fadeInMillis = $event\" />\n </div>\n <div class=\"col-lg-1 d-flex p-0\">\n <div class=\"my-auto\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\"></label>\n <div class=\"col-lg-8 d-flex\">\n <div class=\"form-check my-auto\">\n <input type=\"checkbox\" [ngModel]=\"fadeInPre\" (ngModelChange)=\"fadeInPre = $event\" class=\"form-check-input\" id=\"fadeInPre\" />\n\n <label class=\"form-check-label\" for=\"fadeInPre\">\n {{ 'designer.preset.settings-fade-in-pre' | translate }}\n </label>\n </div>\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.preset.settings-fade-out' | translate }}</label>\n <div class=\"col-lg-7\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"fadeOutMillis\" (ngModelChange)=\"fadeOutMillis = $event\" />\n </div>\n <div class=\"col-lg-1 d-flex p-0\">\n <div class=\"my-auto\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\"></label>\n <div class=\"col-lg-8 d-flex\">\n <div class=\"form-check my-auto\">\n <input type=\"checkbox\" [ngModel]=\"fadeOutPost\" (ngModelChange)=\"fadeOutPost = $event\" class=\"form-check-input\" id=\"fadeOutPost\" />\n\n <label class=\"form-check-label\" for=\"fadeOutPost\">\n {{ 'designer.preset.settings-fade-out-post' | translate }}\n </label>\n </div>\n </div>\n </div>\n</div>\n<div class=\"modal-footer\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"ok()\">{{ 'designer.misc.ok' | translate }}</button>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
7800
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: PresetSettingsComponent, isStandalone: false, selector: "lib-preset-settings", host: { listeners: { "document:keydown.enter": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\">{{ name }}</h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"bsModalRef.hide()\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.preset.settings-name' | translate }}</label>\n <div class=\"col-lg-7\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"name\" (ngModelChange)=\"name = $event\" />\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.preset.settings-start' | translate }}</label>\n <div class=\"col-lg-7\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"startMillis\" (ngModelChange)=\"startMillis = $event\" />\n </div>\n <div class=\"col-lg-1 d-flex p-0\">\n <div class=\"my-auto\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.preset.settings-end' | translate }}</label>\n <div class=\"col-lg-7\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"endMillis\" (ngModelChange)=\"endMillis = $event\" />\n </div>\n <div class=\"col-lg-1 d-flex p-0\">\n <div class=\"my-auto\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.preset.settings-fade-in' | translate }}</label>\n <div class=\"col-lg-7\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"fadeInMillis\" (ngModelChange)=\"fadeInMillis = $event\" />\n </div>\n <div class=\"col-lg-1 d-flex p-0\">\n <div class=\"my-auto\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\"></label>\n <div class=\"col-lg-8 d-flex\">\n <div class=\"form-check my-auto\">\n <input type=\"checkbox\" [ngModel]=\"fadeInPre\" (ngModelChange)=\"fadeInPre = $event\" class=\"form-check-input\" id=\"fadeInPre\" />\n\n <label class=\"form-check-label\" for=\"fadeInPre\">\n {{ 'designer.preset.settings-fade-in-pre' | translate }}\n </label>\n </div>\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\">{{ 'designer.preset.settings-fade-out' | translate }}</label>\n <div class=\"col-lg-7\">\n <input type=\"text\" class=\"form-control\" [ngModel]=\"fadeOutMillis\" (ngModelChange)=\"fadeOutMillis = $event\" />\n </div>\n <div class=\"col-lg-1 d-flex p-0\">\n <div class=\"my-auto\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n </div>\n\n <div class=\"form-group row\">\n <label class=\"col-lg-4 col-form-label\"></label>\n <div class=\"col-lg-8 d-flex\">\n <div class=\"form-check my-auto\">\n <input type=\"checkbox\" [ngModel]=\"fadeOutPost\" (ngModelChange)=\"fadeOutPost = $event\" class=\"form-check-input\" id=\"fadeOutPost\" />\n\n <label class=\"form-check-label\" for=\"fadeOutPost\">\n {{ 'designer.preset.settings-fade-out-post' | translate }}\n </label>\n </div>\n </div>\n </div>\n</div>\n<div class=\"modal-footer\">\n <a class=\"mr-3 my-auto\" href=\"#\" role=\"button\" (click)=\"cancel(); (false)\">\n {{ 'designer.misc.cancel' | translate }}\n </a>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"ok()\">{{ 'designer.misc.ok' | translate }}</button>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
7705
7801
  }
7706
7802
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PresetSettingsComponent, decorators: [{
7707
7803
  type: Component,
@@ -7848,7 +7944,7 @@ class PresetComponent {
7848
7944
  });
7849
7945
  }
7850
7946
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PresetComponent, deps: [{ token: PresetService }, { token: SceneService }, { token: ProjectService }, { token: IntroService }, { token: i1$1.BsModalService }], target: i0.ɵɵFactoryTarget.Component }); }
7851
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: PresetComponent, isStandalone: false, selector: "lib-app-preset", viewQueries: [{ propertyName: "tree", first: true, predicate: ["tree"], descendants: true }], ngImport: i0, template: "<div\n class=\"card border-secondary h-100 panel card-intro-preset card-intro-active\"\n [class.card-intro-active]=\"introService.showStep('presets')\"\n>\n <div class=\"card-header d-flex\">\n <div>\n {{ 'designer.preset.title' | translate }}\n </div>\n <div class=\"ml-auto\">\n <a href=\"#\" class=\"btn btn-secondary m-0, p-0\" (click)=\"removePreset(); (false)\"\n ><i class=\"fa fa-minus-circle fa-fw\" aria-hidden=\"true\"></i\n ></a>\n <a href=\"#\" class=\"btn btn-secondary m-0, p-0\" (click)=\"addPreset(); (false)\"\n ><i class=\"fa fa-plus-circle fa-fw\" aria-hidden=\"true\"></i\n ></a>\n </div>\n </div>\n\n <div class=\"card-body h-100 p-0\">\n <!-- List of presets -->\n <!-- <tree-root #tree [nodes]=\"treeNodes\" [options]=\"treeOptions\" (activate)=\"onActivate($event)\">\n <ng-template #treeNodeTemplate let-node let-index=\"index\">\n <span>{{ node.data.name }}</span>\n </ng-template>\n </tree-root> -->\n\n <div class=\"list-group\" [sortablejs]=\"projectService.project.presets\">\n @for (item of projectService.project.presets; track item; let i = $index) {\n <div\n class=\"list-group-item\"\n (click)=\"selectPreset(i)\"\n [class.active-light]=\"!projectService.project.previewPreset && item == presetService.selectedPreset\"\n [class.active]=\"projectService.project.previewPreset && item == presetService.selectedPreset\"\n [class.inactive-list-item]=\"!sceneService.presetIsSelected(item)\"\n >\n <div class=\"row d-flex\" style=\"cursor: pointer\">\n <div class=\"col-auto list-sort-handle my-auto\" style=\"cursor: move; cursor: -webkit-grabbing\">\n <i class=\"fa fa-bars\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n [disabled]=\"!enableCheckbox()\"\n class=\"form-check-input\"\n id=\"active\"\n [ngModel]=\"sceneService.presetIsSelected(item)\"\n (ngModelChange)=\"activatePreset($event, i)\"\n (click)=\"$event.stopPropagation()\"\n />\n </div>\n <div>\n {{ item.name }}\n </div>\n <div class=\"my-auto ml-auto mr-2 d-flex\">\n <button type=\"button\" class=\"btn btn-secondary btn-sm py-0 px-1\" (click)=\"openSettings(item); (false)\">...</button>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: SortablejsDirective, selector: "[sortablejs]", inputs: ["sortablejs", "sortablejsContainer", "sortablejsOptions"], outputs: ["sortablejsInit"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
7947
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: PresetComponent, isStandalone: false, selector: "lib-app-preset", viewQueries: [{ propertyName: "tree", first: true, predicate: ["tree"], descendants: true }], ngImport: i0, template: "<div\n class=\"card border-secondary h-100 panel card-intro-preset card-intro-active\"\n [class.card-intro-active]=\"introService.showStep('presets')\"\n>\n <div class=\"card-header d-flex\">\n <div>\n {{ 'designer.preset.title' | translate }}\n </div>\n <div class=\"ml-auto\">\n <a href=\"#\" class=\"btn btn-secondary m-0, p-0\" (click)=\"removePreset(); (false)\"\n ><i class=\"fa fa-minus-circle fa-fw\" aria-hidden=\"true\"></i\n ></a>\n <a href=\"#\" class=\"btn btn-secondary m-0, p-0\" (click)=\"addPreset(); (false)\"\n ><i class=\"fa fa-plus-circle fa-fw\" aria-hidden=\"true\"></i\n ></a>\n </div>\n </div>\n\n <div class=\"card-body h-100 p-0\">\n <!-- List of presets -->\n <!-- <tree-root #tree [nodes]=\"treeNodes\" [options]=\"treeOptions\" (activate)=\"onActivate($event)\">\n <ng-template #treeNodeTemplate let-node let-index=\"index\">\n <span>{{ node.data.name }}</span>\n </ng-template>\n </tree-root> -->\n\n <div class=\"list-group\" [sortablejs]=\"projectService.project.presets\">\n @for (item of projectService.project.presets; track item; let i = $index) {\n <div\n class=\"list-group-item\"\n (click)=\"selectPreset(i)\"\n [class.active-light]=\"!projectService.project.previewPreset && item == presetService.selectedPreset\"\n [class.active]=\"projectService.project.previewPreset && item == presetService.selectedPreset\"\n [class.inactive-list-item]=\"!sceneService.presetIsSelected(item)\"\n >\n <div class=\"row d-flex\" style=\"cursor: pointer\">\n <div class=\"col-auto list-sort-handle my-auto\" style=\"cursor: move; cursor: -webkit-grabbing\">\n <i class=\"fa fa-bars\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n [disabled]=\"!enableCheckbox()\"\n class=\"form-check-input\"\n id=\"active\"\n [ngModel]=\"sceneService.presetIsSelected(item)\"\n (ngModelChange)=\"activatePreset($event, i)\"\n (click)=\"$event.stopPropagation()\"\n />\n </div>\n <div>\n {{ item.name }}\n </div>\n <div class=\"my-auto ml-auto mr-2 d-flex\">\n <button type=\"button\" class=\"btn btn-secondary btn-sm py-0 px-1\" (click)=\"openSettings(item); (false)\">...</button>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: SortablejsDirective, selector: "[sortablejs]", inputs: ["sortablejs", "sortablejsContainer", "sortablejsOptions"], outputs: ["sortablejsInit"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
7852
7948
  }
7853
7949
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PresetComponent, decorators: [{
7854
7950
  type: Component,
@@ -7859,10 +7955,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
7859
7955
  }] } });
7860
7956
 
7861
7957
  class MasterDimmerComponent {
7862
- constructor(projectService, changeDetectorRef, presetService) {
7958
+ constructor(projectService, changeDetectorRef, livePreviewService) {
7863
7959
  this.projectService = projectService;
7864
7960
  this.changeDetectorRef = changeDetectorRef;
7865
- this.presetService = presetService;
7961
+ this.livePreviewService = livePreviewService;
7866
7962
  }
7867
7963
  ngOnInit() { }
7868
7964
  setValue(value) {
@@ -7874,26 +7970,27 @@ class MasterDimmerComponent {
7874
7970
  }
7875
7971
  this.projectService.project.masterDimmerValue = value;
7876
7972
  this.changeDetectorRef.detectChanges();
7877
- this.presetService.previewLive();
7973
+ this.livePreviewService.previewLive();
7878
7974
  }
7879
7975
  getValue() {
7880
7976
  return Math.round(this.projectService.project.masterDimmerValue * 100 * 100) / 100;
7881
7977
  }
7882
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MasterDimmerComponent, deps: [{ token: ProjectService }, { token: i0.ChangeDetectorRef }, { token: PresetService }], target: i0.ɵɵFactoryTarget.Component }); }
7883
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: MasterDimmerComponent, isStandalone: false, selector: "lib-app-master-dimmer", ngImport: i0, template: "<div class=\"card border-secondary h-100\">\n <!-- For larger screens vertically -->\n <div class=\"d-none d-md-flex card-body h-100\" style=\"flex-direction: column\">\n <div class=\"mb-3 w-100 d-flex\">\n <i class=\"icon-dimmer m-auto\" style=\"font-size: 2em\"></i>\n </div>\n\n <div class=\"mb-4 w-100 d-flex\">\n <input\n class=\"mx-auto\"\n type=\"text\"\n [ngModel]=\"getValue()\"\n (ngModelChange)=\"setValue($event / 100)\"\n style=\"width: 42px; height: 23px; text-align: center; font-size: 12px; font-family: monospace\"\n />\n </div>\n\n <div class=\"h-100 w-100 d-flex\">\n <mv-slider\n class=\"mx-auto\"\n [value]=\"projectService?.project?.masterDimmerValue\"\n (change)=\"setValue($event.newValue)\"\n [orientation]=\"'vertical'\"\n [reversed]=\"true\"\n style=\"height: 100%\"\n [tooltip]=\"'hide'\"\n [min]=\"0\"\n [max]=\"1\"\n [step]=\"0.001\"\n ></mv-slider>\n </div>\n </div>\n\n <!-- For smaller screens horizontally -->\n <div class=\"d-flex d-md-none card-body h-100\">\n <div class=\"mb-3 d-flex my-auto\">\n <i class=\"icon-dimmer m-auto\" style=\"font-size: 2em\"></i>\n </div>\n\n <div class=\"h-100 w-100 d-flex my-auto mx-3\">\n <mv-slider\n class=\"mx-auto\"\n [value]=\"projectService?.project?.masterDimmerValue\"\n (change)=\"setValue($event.newValue)\"\n [orientation]=\"'horizontal'\"\n style=\"width: 100%\"\n [tooltip]=\"'hide'\"\n [min]=\"0\"\n [max]=\"1\"\n [step]=\"0.001\"\n ></mv-slider>\n </div>\n\n <div class=\"mb-4 d-flex my-auto\">\n <input\n class=\"mx-auto\"\n type=\"text\"\n [ngModel]=\"getValue()\"\n (ngModelChange)=\"setValue($event / 100)\"\n style=\"width: 42px; height: 23px; text-align: center; font-size: 12px; font-family: monospace\"\n />\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3$3.SliderComponent, selector: "mv-slider", inputs: ["style", "value", "min", "max", "step", "precision", "orientation", "range", "selection", "tooltip", "tooltipSplit", "tooltipPosition", "handle", "reversed", "rtl", "enabled", "naturalArrowKeys", "ticks", "ticksPositions", "ticksLabels", "ticksSnapBounds", "ticksTooltip", "scale", "labelledBy", "rangeHighlights", "formatter", "lockToTicks"], outputs: ["valueChange", "slide", "slideStart", "slideStop", "change"] }] }); }
7978
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MasterDimmerComponent, deps: [{ token: ProjectService }, { token: i0.ChangeDetectorRef }, { token: LivePreviewService }], target: i0.ɵɵFactoryTarget.Component }); }
7979
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: MasterDimmerComponent, isStandalone: false, selector: "lib-app-master-dimmer", ngImport: i0, template: "<div class=\"card border-secondary h-100\">\n <!-- For larger screens vertically -->\n <div class=\"d-none d-md-flex card-body h-100\" style=\"flex-direction: column\">\n <div class=\"mb-3 w-100 d-flex\">\n <i class=\"icon-dimmer m-auto\" style=\"font-size: 2em\"></i>\n </div>\n\n <div class=\"mb-4 w-100 d-flex\">\n <input\n class=\"mx-auto\"\n type=\"text\"\n [ngModel]=\"getValue()\"\n (ngModelChange)=\"setValue($event / 100)\"\n style=\"width: 42px; height: 23px; text-align: center; font-size: 12px; font-family: monospace\"\n />\n </div>\n\n <div class=\"h-100 w-100 d-flex\">\n <mv-slider\n class=\"mx-auto\"\n [value]=\"projectService?.project?.masterDimmerValue\"\n (change)=\"setValue($event.newValue)\"\n [orientation]=\"'vertical'\"\n [reversed]=\"true\"\n style=\"height: 100%\"\n [tooltip]=\"'hide'\"\n [min]=\"0\"\n [max]=\"1\"\n [step]=\"0.001\"\n ></mv-slider>\n </div>\n </div>\n\n <!-- For smaller screens horizontally -->\n <div class=\"d-flex d-md-none card-body h-100\">\n <div class=\"mb-3 d-flex my-auto\">\n <i class=\"icon-dimmer m-auto\" style=\"font-size: 2em\"></i>\n </div>\n\n <div class=\"h-100 w-100 d-flex my-auto mx-3\">\n <mv-slider\n class=\"mx-auto\"\n [value]=\"projectService?.project?.masterDimmerValue\"\n (change)=\"setValue($event.newValue)\"\n [orientation]=\"'horizontal'\"\n style=\"width: 100%\"\n [tooltip]=\"'hide'\"\n [min]=\"0\"\n [max]=\"1\"\n [step]=\"0.001\"\n ></mv-slider>\n </div>\n\n <div class=\"mb-4 d-flex my-auto\">\n <input\n class=\"mx-auto\"\n type=\"text\"\n [ngModel]=\"getValue()\"\n (ngModelChange)=\"setValue($event / 100)\"\n style=\"width: 42px; height: 23px; text-align: center; font-size: 12px; font-family: monospace\"\n />\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.SliderComponent, selector: "mv-slider", inputs: ["style", "value", "min", "max", "step", "precision", "orientation", "range", "selection", "tooltip", "tooltipSplit", "tooltipPosition", "handle", "reversed", "rtl", "enabled", "naturalArrowKeys", "ticks", "ticksPositions", "ticksLabels", "ticksSnapBounds", "ticksTooltip", "scale", "labelledBy", "rangeHighlights", "formatter", "lockToTicks"], outputs: ["valueChange", "slide", "slideStart", "slideStop", "change"] }] }); }
7884
7980
  }
7885
7981
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MasterDimmerComponent, decorators: [{
7886
7982
  type: Component,
7887
7983
  args: [{ selector: 'lib-app-master-dimmer', standalone: false, template: "<div class=\"card border-secondary h-100\">\n <!-- For larger screens vertically -->\n <div class=\"d-none d-md-flex card-body h-100\" style=\"flex-direction: column\">\n <div class=\"mb-3 w-100 d-flex\">\n <i class=\"icon-dimmer m-auto\" style=\"font-size: 2em\"></i>\n </div>\n\n <div class=\"mb-4 w-100 d-flex\">\n <input\n class=\"mx-auto\"\n type=\"text\"\n [ngModel]=\"getValue()\"\n (ngModelChange)=\"setValue($event / 100)\"\n style=\"width: 42px; height: 23px; text-align: center; font-size: 12px; font-family: monospace\"\n />\n </div>\n\n <div class=\"h-100 w-100 d-flex\">\n <mv-slider\n class=\"mx-auto\"\n [value]=\"projectService?.project?.masterDimmerValue\"\n (change)=\"setValue($event.newValue)\"\n [orientation]=\"'vertical'\"\n [reversed]=\"true\"\n style=\"height: 100%\"\n [tooltip]=\"'hide'\"\n [min]=\"0\"\n [max]=\"1\"\n [step]=\"0.001\"\n ></mv-slider>\n </div>\n </div>\n\n <!-- For smaller screens horizontally -->\n <div class=\"d-flex d-md-none card-body h-100\">\n <div class=\"mb-3 d-flex my-auto\">\n <i class=\"icon-dimmer m-auto\" style=\"font-size: 2em\"></i>\n </div>\n\n <div class=\"h-100 w-100 d-flex my-auto mx-3\">\n <mv-slider\n class=\"mx-auto\"\n [value]=\"projectService?.project?.masterDimmerValue\"\n (change)=\"setValue($event.newValue)\"\n [orientation]=\"'horizontal'\"\n style=\"width: 100%\"\n [tooltip]=\"'hide'\"\n [min]=\"0\"\n [max]=\"1\"\n [step]=\"0.001\"\n ></mv-slider>\n </div>\n\n <div class=\"mb-4 d-flex my-auto\">\n <input\n class=\"mx-auto\"\n type=\"text\"\n [ngModel]=\"getValue()\"\n (ngModelChange)=\"setValue($event / 100)\"\n style=\"width: 42px; height: 23px; text-align: center; font-size: 12px; font-family: monospace\"\n />\n </div>\n </div>\n</div>\n" }]
7888
- }], ctorParameters: () => [{ type: ProjectService }, { type: i0.ChangeDetectorRef }, { type: PresetService }] });
7984
+ }], ctorParameters: () => [{ type: ProjectService }, { type: i0.ChangeDetectorRef }, { type: LivePreviewService }] });
7889
7985
 
7890
7986
  class FixtureCapabilityChannelComponent {
7891
7987
  set channel(value) {
7892
7988
  this._channel = value;
7893
7989
  this.updateChannel();
7894
7990
  }
7895
- constructor(presetService) {
7991
+ constructor(presetService, livePreviewService) {
7896
7992
  this.presetService = presetService;
7993
+ this.livePreviewService = livePreviewService;
7897
7994
  this.defaultValue = 0;
7898
7995
  this.value = 0;
7899
7996
  this.templateValue = 0;
@@ -8044,7 +8141,7 @@ class FixtureCapabilityChannelComponent {
8044
8141
  }, 30);
8045
8142
  }
8046
8143
  }
8047
- this.presetService.previewLive();
8144
+ this.livePreviewService.previewLive();
8048
8145
  }
8049
8146
  calculateTemplateValue() {
8050
8147
  this.templateValue = this.value ? this.value : this.getDefaultValue();
@@ -8065,7 +8162,7 @@ class FixtureCapabilityChannelComponent {
8065
8162
  this.value = undefined;
8066
8163
  this.calculateTemplateValue();
8067
8164
  }
8068
- this.presetService.previewLive();
8165
+ this.livePreviewService.previewLive();
8069
8166
  }
8070
8167
  capabilitySelected() {
8071
8168
  // select the center value of the selected capability
@@ -8077,13 +8174,13 @@ class FixtureCapabilityChannelComponent {
8077
8174
  }
8078
8175
  this.updateChannel();
8079
8176
  }
8080
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureCapabilityChannelComponent, deps: [{ token: PresetService }], target: i0.ɵɵFactoryTarget.Component }); }
8081
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: FixtureCapabilityChannelComponent, isStandalone: false, selector: "lib-app-fixture-capability-channel", inputs: { profile: "profile", channel: "channel", capabilityIndex: "capabilityIndex" }, viewQueries: [{ propertyName: "sliderValue", first: true, predicate: ["sliderValue"], descendants: true }], ngImport: i0, template: "<div class=\"card border-secondary h-100\" [class.capability-deactivated]=\"value == undefined\" style=\"min-height: 200px\">\n <div class=\"card-header\">\n <div class=\"my-auto\">\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capabilityGeneric{{ capabilityIndex }}Active\"\n [ngModel]=\"value != undefined\"\n (ngModelChange)=\"changeActive($event)\"\n />\n <label class=\"form-check-label\" for=\"capabilityGeneric{{ capabilityIndex }}Active\">\n {{ _channel?.name }}\n </label>\n </div>\n </div>\n </div>\n\n <div class=\"card-body h-100 d-flex\" style=\"flex-direction: column; overflow: hidden\">\n <div class=\"row h-100\">\n <!-- display all options, if there is more than one -->\n @if (_channel.capabilities?.length > 1) {\n <div class=\"col mr-3\" style=\"overflow-y: auto\">\n @for (capability of _channel.capabilities; track capability; let i = $index) {\n <div class=\"form-check\">\n <input\n [(ngModel)]=\"selectedCapability\"\n (change)=\"capabilitySelected()\"\n class=\"form-check-input\"\n type=\"radio\"\n name=\"capabilityGeneric{{ capabilityIndex }}Option\"\n id=\"capabilityGeneric{{ capabilityIndex }}Option{{ i }}\"\n [value]=\"capability\"\n />\n <label style=\"max-width: 200px\" class=\"form-check-label\" for=\"capabilityGeneric{{ capabilityIndex }}Option{{ i }}\">\n {{ 'designer.fixtureCapabilityType.' + capability.capability.type | translate }}@if (getDescription(capability)) {\n <span> ({{ getDescription(capability) }})</span>\n }<small\n >@for (color of capability.capability.colors; track color) {\n <div class=\"color\" [style.background-color]=\"color\"></div>\n } @if (getDescriptionStart(capability)) {\n <small> ({{ getDescriptionStart(capability) }} to {{ getDescriptionEnd(capability) }})</small>\n } @if (capability.capability.comment) {\n <span> - </span>\n } {{ capability.capability.comment }}</small\n >\n @if (capability.capability.soundControlled) {\n <i\n class=\"fa fa-microphone pl-1\"\n popover=\"{{ 'designer.fixture.capability-sound-controlled' | translate }}\"\n container=\"body\"\n placement=\"top\"\n triggers=\"mouseenter:mouseleave\"\n aria-hidden=\"true\"\n ></i>\n } @if (capability.capability.randomTiming) {\n <i\n class=\"fa fa-random pl-1\"\n popover=\"{{ 'designer.fixture.capability-random-timing' | translate }}\"\n container=\"body\"\n placement=\"top\"\n triggers=\"mouseenter:mouseleave\"\n aria-hidden=\"true\"\n ></i>\n }\n </label>\n </div>\n }\n </div>\n }\n\n <!-- display a slider to select the value for the currently selected capability, if it has a range -->\n @if (hasRange) {\n <div class=\"col col-auto d-flex mx-auto\" [class.pl-0]=\"_channel.capabilities?.length > 1\" style=\"flex-direction: column\">\n <div class=\"mb-2 w-100 d-flex\">\n <input\n #sliderValue\n class=\"mx-auto\"\n type=\"text\"\n [ngModel]=\"templateValue\"\n (ngModelChange)=\"setValue($event)\"\n style=\"width: 45px; height: 20px; text-align: center; font-size: 12px; font-family: monospace\"\n />\n </div>\n <div class=\"mx-auto mb-2\">{{ descriptionEnd }}</div>\n <div class=\"h-100 w-100 d-flex\">\n <mv-slider\n #slider\n class=\"mx-auto\"\n [value]=\"templateValue\"\n (change)=\"setValue($event.newValue)\"\n [orientation]=\"'vertical'\"\n [reversed]=\"true\"\n style=\"height: 100%\"\n [tooltip]=\"'hide'\"\n [min]=\"rangeMin\"\n [max]=\"rangeMax\"\n [step]=\"1\"\n ></mv-slider>\n </div>\n <div class=\"mx-auto mt-2\">{{ descriptionStart }}</div>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".color{display:inline-block;margin-left:5px;border-radius:50%;width:12px;height:12px;border:1px white solid;vertical-align:middle}\n"], dependencies: [{ kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3$3.SliderComponent, selector: "mv-slider", inputs: ["style", "value", "min", "max", "step", "precision", "orientation", "range", "selection", "tooltip", "tooltipSplit", "tooltipPosition", "handle", "reversed", "rtl", "enabled", "naturalArrowKeys", "ticks", "ticksPositions", "ticksLabels", "ticksSnapBounds", "ticksTooltip", "scale", "labelledBy", "rangeHighlights", "formatter", "lockToTicks"], outputs: ["valueChange", "slide", "slideStart", "slideStop", "change"] }, { kind: "directive", type: i11.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8177
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureCapabilityChannelComponent, deps: [{ token: PresetService }, { token: LivePreviewService }], target: i0.ɵɵFactoryTarget.Component }); }
8178
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: FixtureCapabilityChannelComponent, isStandalone: false, selector: "lib-app-fixture-capability-channel", inputs: { profile: "profile", channel: "channel", capabilityIndex: "capabilityIndex" }, viewQueries: [{ propertyName: "sliderValue", first: true, predicate: ["sliderValue"], descendants: true }], ngImport: i0, template: "<div class=\"card border-secondary h-100\" [class.capability-deactivated]=\"value == undefined\" style=\"min-height: 200px\">\n <div class=\"card-header\">\n <div class=\"my-auto\">\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capabilityGeneric{{ capabilityIndex }}Active\"\n [ngModel]=\"value != undefined\"\n (ngModelChange)=\"changeActive($event)\"\n />\n <label class=\"form-check-label\" for=\"capabilityGeneric{{ capabilityIndex }}Active\">\n {{ _channel?.name }}\n </label>\n </div>\n </div>\n </div>\n\n <div class=\"card-body h-100 d-flex\" style=\"flex-direction: column; overflow: hidden\">\n <div class=\"row h-100\">\n <!-- display all options, if there is more than one -->\n @if (_channel.capabilities?.length > 1) {\n <div class=\"col mr-3\" style=\"overflow-y: auto\">\n @for (capability of _channel.capabilities; track capability; let i = $index) {\n <div class=\"form-check\">\n <input\n [(ngModel)]=\"selectedCapability\"\n (change)=\"capabilitySelected()\"\n class=\"form-check-input\"\n type=\"radio\"\n name=\"capabilityGeneric{{ capabilityIndex }}Option\"\n id=\"capabilityGeneric{{ capabilityIndex }}Option{{ i }}\"\n [value]=\"capability\"\n />\n <label style=\"max-width: 200px\" class=\"form-check-label\" for=\"capabilityGeneric{{ capabilityIndex }}Option{{ i }}\">\n {{ 'designer.fixtureCapabilityType.' + capability.capability.type | translate }}@if (getDescription(capability)) {\n <span> ({{ getDescription(capability) }})</span>\n }<small\n >@for (color of capability.capability.colors; track color) {\n <div class=\"color\" [style.background-color]=\"color\"></div>\n } @if (getDescriptionStart(capability)) {\n <small> ({{ getDescriptionStart(capability) }} to {{ getDescriptionEnd(capability) }})</small>\n } @if (capability.capability.comment) {\n <span> - </span>\n } {{ capability.capability.comment }}</small\n >\n @if (capability.capability.soundControlled) {\n <i\n class=\"fa fa-microphone pl-1\"\n popover=\"{{ 'designer.fixture.capability-sound-controlled' | translate }}\"\n container=\"body\"\n placement=\"top\"\n triggers=\"mouseenter:mouseleave\"\n aria-hidden=\"true\"\n ></i>\n } @if (capability.capability.randomTiming) {\n <i\n class=\"fa fa-random pl-1\"\n popover=\"{{ 'designer.fixture.capability-random-timing' | translate }}\"\n container=\"body\"\n placement=\"top\"\n triggers=\"mouseenter:mouseleave\"\n aria-hidden=\"true\"\n ></i>\n }\n </label>\n </div>\n }\n </div>\n }\n\n <!-- display a slider to select the value for the currently selected capability, if it has a range -->\n @if (hasRange) {\n <div class=\"col col-auto d-flex mx-auto\" [class.pl-0]=\"_channel.capabilities?.length > 1\" style=\"flex-direction: column\">\n <div class=\"mb-2 w-100 d-flex\">\n <input\n #sliderValue\n class=\"mx-auto\"\n type=\"text\"\n [ngModel]=\"templateValue\"\n (ngModelChange)=\"setValue($event)\"\n style=\"width: 45px; height: 20px; text-align: center; font-size: 12px; font-family: monospace\"\n />\n </div>\n <div class=\"mx-auto mb-2\">{{ descriptionEnd }}</div>\n <div class=\"h-100 w-100 d-flex\">\n <mv-slider\n #slider\n class=\"mx-auto\"\n [value]=\"templateValue\"\n (change)=\"setValue($event.newValue)\"\n [orientation]=\"'vertical'\"\n [reversed]=\"true\"\n style=\"height: 100%\"\n [tooltip]=\"'hide'\"\n [min]=\"rangeMin\"\n [max]=\"rangeMax\"\n [step]=\"1\"\n ></mv-slider>\n </div>\n <div class=\"mx-auto mt-2\">{{ descriptionStart }}</div>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".color{display:inline-block;margin-left:5px;border-radius:50%;width:12px;height:12px;border:1px white solid;vertical-align:middle}\n"], dependencies: [{ kind: "directive", type: i3$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.SliderComponent, selector: "mv-slider", inputs: ["style", "value", "min", "max", "step", "precision", "orientation", "range", "selection", "tooltip", "tooltipSplit", "tooltipPosition", "handle", "reversed", "rtl", "enabled", "naturalArrowKeys", "ticks", "ticksPositions", "ticksLabels", "ticksSnapBounds", "ticksTooltip", "scale", "labelledBy", "rangeHighlights", "formatter", "lockToTicks"], outputs: ["valueChange", "slide", "slideStart", "slideStop", "change"] }, { kind: "directive", type: i12.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8082
8179
  }
8083
8180
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureCapabilityChannelComponent, decorators: [{
8084
8181
  type: Component,
8085
8182
  args: [{ selector: 'lib-app-fixture-capability-channel', changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, template: "<div class=\"card border-secondary h-100\" [class.capability-deactivated]=\"value == undefined\" style=\"min-height: 200px\">\n <div class=\"card-header\">\n <div class=\"my-auto\">\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capabilityGeneric{{ capabilityIndex }}Active\"\n [ngModel]=\"value != undefined\"\n (ngModelChange)=\"changeActive($event)\"\n />\n <label class=\"form-check-label\" for=\"capabilityGeneric{{ capabilityIndex }}Active\">\n {{ _channel?.name }}\n </label>\n </div>\n </div>\n </div>\n\n <div class=\"card-body h-100 d-flex\" style=\"flex-direction: column; overflow: hidden\">\n <div class=\"row h-100\">\n <!-- display all options, if there is more than one -->\n @if (_channel.capabilities?.length > 1) {\n <div class=\"col mr-3\" style=\"overflow-y: auto\">\n @for (capability of _channel.capabilities; track capability; let i = $index) {\n <div class=\"form-check\">\n <input\n [(ngModel)]=\"selectedCapability\"\n (change)=\"capabilitySelected()\"\n class=\"form-check-input\"\n type=\"radio\"\n name=\"capabilityGeneric{{ capabilityIndex }}Option\"\n id=\"capabilityGeneric{{ capabilityIndex }}Option{{ i }}\"\n [value]=\"capability\"\n />\n <label style=\"max-width: 200px\" class=\"form-check-label\" for=\"capabilityGeneric{{ capabilityIndex }}Option{{ i }}\">\n {{ 'designer.fixtureCapabilityType.' + capability.capability.type | translate }}@if (getDescription(capability)) {\n <span> ({{ getDescription(capability) }})</span>\n }<small\n >@for (color of capability.capability.colors; track color) {\n <div class=\"color\" [style.background-color]=\"color\"></div>\n } @if (getDescriptionStart(capability)) {\n <small> ({{ getDescriptionStart(capability) }} to {{ getDescriptionEnd(capability) }})</small>\n } @if (capability.capability.comment) {\n <span> - </span>\n } {{ capability.capability.comment }}</small\n >\n @if (capability.capability.soundControlled) {\n <i\n class=\"fa fa-microphone pl-1\"\n popover=\"{{ 'designer.fixture.capability-sound-controlled' | translate }}\"\n container=\"body\"\n placement=\"top\"\n triggers=\"mouseenter:mouseleave\"\n aria-hidden=\"true\"\n ></i>\n } @if (capability.capability.randomTiming) {\n <i\n class=\"fa fa-random pl-1\"\n popover=\"{{ 'designer.fixture.capability-random-timing' | translate }}\"\n container=\"body\"\n placement=\"top\"\n triggers=\"mouseenter:mouseleave\"\n aria-hidden=\"true\"\n ></i>\n }\n </label>\n </div>\n }\n </div>\n }\n\n <!-- display a slider to select the value for the currently selected capability, if it has a range -->\n @if (hasRange) {\n <div class=\"col col-auto d-flex mx-auto\" [class.pl-0]=\"_channel.capabilities?.length > 1\" style=\"flex-direction: column\">\n <div class=\"mb-2 w-100 d-flex\">\n <input\n #sliderValue\n class=\"mx-auto\"\n type=\"text\"\n [ngModel]=\"templateValue\"\n (ngModelChange)=\"setValue($event)\"\n style=\"width: 45px; height: 20px; text-align: center; font-size: 12px; font-family: monospace\"\n />\n </div>\n <div class=\"mx-auto mb-2\">{{ descriptionEnd }}</div>\n <div class=\"h-100 w-100 d-flex\">\n <mv-slider\n #slider\n class=\"mx-auto\"\n [value]=\"templateValue\"\n (change)=\"setValue($event.newValue)\"\n [orientation]=\"'vertical'\"\n [reversed]=\"true\"\n style=\"height: 100%\"\n [tooltip]=\"'hide'\"\n [min]=\"rangeMin\"\n [max]=\"rangeMax\"\n [step]=\"1\"\n ></mv-slider>\n </div>\n <div class=\"mx-auto mt-2\">{{ descriptionStart }}</div>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".color{display:inline-block;margin-left:5px;border-radius:50%;width:12px;height:12px;border:1px white solid;vertical-align:middle}\n"] }]
8086
- }], ctorParameters: () => [{ type: PresetService }], propDecorators: { sliderValue: [{
8183
+ }], ctorParameters: () => [{ type: PresetService }, { type: LivePreviewService }], propDecorators: { sliderValue: [{
8087
8184
  type: ViewChild,
8088
8185
  args: ['sliderValue', { static: false }]
8089
8186
  }], profile: [{
@@ -8143,7 +8240,7 @@ class FixtureChannelComponent {
8143
8240
  return false;
8144
8241
  }
8145
8242
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureChannelComponent, deps: [{ token: PresetService }, { token: i0.ChangeDetectorRef }, { token: ProjectService }], target: i0.ɵɵFactoryTarget.Component }); }
8146
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: FixtureChannelComponent, isStandalone: false, selector: "lib-app-fixture-channel", ngImport: i0, template: "<div class=\"card border-secondary panel h-100\">\n <div class=\"card-body capability-container d-flex h-100\" style=\"overflow-y: hidden\">\n <!-- h-100 needs to be applied in chrome to avoid performance issues with many layouts (reflows)\n during sliding. But the class must not be applied e.g. in Safari, because the bottom margin is not correct\n anymore afterwards. -->\n @if (presetService.selectedPreset) {\n <div class=\"row m-0 pl-3\" [class.h-100]=\"isChrome()\">\n <!-- profile selection -->\n @if (profiles.length > 1) {\n <div class=\"col col-auto p-3 my-3 mr-3\" style=\"height: calc(100% - 2rem); border: solid 1px #444; border-right: none\">\n @for (profile of profiles; track profile; let i = $index) {\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capabilityFilter{{ i }}\"\n [ngModel]=\"selectedProfiles.indexOf(profile) >= 0\"\n (ngModelChange)=\"changeProfileSelection($event, profile)\"\n />\n <label class=\"form-check-label\" for=\"capabilityFilter{{ i }}\">\n {{ profile.name }}\n </label>\n </div>\n }\n </div>\n }\n <!-- all channel capabilities -->\n @for (entry of channelCapabilities | keyvalue; track entry; let i = $index) { @for (capability of entry.value; track capability; let j\n = $index) {\n <div class=\"col col-auto p-0 my-3 mr-3\" style=\"height: calc(100% - 2rem)\">\n <lib-app-fixture-capability-channel [profile]=\"entry.key\" [channel]=\"capability\" [capabilityIndex]=\"i * 10000 + j\">\n </lib-app-fixture-capability-channel>\n </div>\n } }\n <!-- fix spacing at the end -->\n <div class=\"col col-auto p-0 my-3 mr-3\">&nbsp;</div>\n </div>\n } @if (projectService.project.fixtures.length == 0) {\n <div class=\"m-auto\">\n <p class=\"m-auto\" style=\"color: #717171\">{{ 'designer.fixture.no-fixtures' | translate }}</p>\n </div>\n } @if ( projectService.project.fixtures.length > 0 && presetService.selectedPreset && presetService.selectedPreset.fixtures.length == 0\n ) {\n <div class=\"m-auto\">\n <p class=\"m-auto\" style=\"color: #717171\">{{ 'designer.fixture.no-fixtures-selected' | translate }}</p>\n </div>\n }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: FixtureCapabilityChannelComponent, selector: "lib-app-fixture-capability-channel", inputs: ["profile", "channel", "capabilityIndex"] }, { kind: "pipe", type: i9.KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
8243
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: FixtureChannelComponent, isStandalone: false, selector: "lib-app-fixture-channel", ngImport: i0, template: "<div class=\"card border-secondary panel h-100\">\n <div class=\"card-body capability-container d-flex h-100\" style=\"overflow-y: hidden\">\n <!-- h-100 needs to be applied in chrome to avoid performance issues with many layouts (reflows)\n during sliding. But the class must not be applied e.g. in Safari, because the bottom margin is not correct\n anymore afterwards. -->\n @if (presetService.selectedPreset) {\n <div class=\"row m-0 pl-3\" [class.h-100]=\"isChrome()\">\n <!-- profile selection -->\n @if (profiles.length > 1) {\n <div class=\"col col-auto p-3 my-3 mr-3\" style=\"height: calc(100% - 2rem); border: solid 1px #444; border-right: none\">\n @for (profile of profiles; track profile; let i = $index) {\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capabilityFilter{{ i }}\"\n [ngModel]=\"selectedProfiles.indexOf(profile) >= 0\"\n (ngModelChange)=\"changeProfileSelection($event, profile)\"\n />\n <label class=\"form-check-label\" for=\"capabilityFilter{{ i }}\">\n {{ profile.name }}\n </label>\n </div>\n }\n </div>\n }\n <!-- all channel capabilities -->\n @for (entry of channelCapabilities | keyvalue; track entry; let i = $index) { @for (capability of entry.value; track capability; let j\n = $index) {\n <div class=\"col col-auto p-0 my-3 mr-3\" style=\"height: calc(100% - 2rem)\">\n <lib-app-fixture-capability-channel [profile]=\"entry.key\" [channel]=\"capability\" [capabilityIndex]=\"i * 10000 + j\">\n </lib-app-fixture-capability-channel>\n </div>\n } }\n <!-- fix spacing at the end -->\n <div class=\"col col-auto p-0 my-3 mr-3\">&nbsp;</div>\n </div>\n } @if (projectService.project.fixtures.length == 0) {\n <div class=\"m-auto\">\n <p class=\"m-auto\" style=\"color: #717171\">{{ 'designer.fixture.no-fixtures' | translate }}</p>\n </div>\n } @if ( projectService.project.fixtures.length > 0 && presetService.selectedPreset && presetService.selectedPreset.fixtures.length == 0\n ) {\n <div class=\"m-auto\">\n <p class=\"m-auto\" style=\"color: #717171\">{{ 'designer.fixture.no-fixtures-selected' | translate }}</p>\n </div>\n }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: FixtureCapabilityChannelComponent, selector: "lib-app-fixture-capability-channel", inputs: ["profile", "channel", "capabilityIndex"] }, { kind: "pipe", type: i10$1.KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
8147
8244
  }
8148
8245
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FixtureChannelComponent, decorators: [{
8149
8246
  type: Component,
@@ -8159,7 +8256,7 @@ class IntroComponent {
8159
8256
  this.introService.setShowIntro(false);
8160
8257
  }
8161
8258
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: IntroComponent, deps: [{ token: IntroService }], target: i0.ɵɵFactoryTarget.Component }); }
8162
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: IntroComponent, isStandalone: false, selector: "lib-app-intro", ngImport: i0, template: "@if (introService.showIntro) {\n<div\n class=\"card border-secondary h-100 panel card-intro-active\"\n [ngStyle]=\"{\n top: 'calc(' + introService.positionTopPercentage + '% - 150px)',\n left: 'calc(' + introService.positionLeftPercentage + '% - 200px)'\n }\"\n>\n <div class=\"card-header d-flex\">\n <div>\n <i class=\"fa fa-info-circle mr-1\" aria-hidden=\"true\"></i>\n {{ 'designer.intro.title-' + introService.activeStep | translate }}\n </div>\n <div class=\"ml-auto\">\n <a href=\"#\" class=\"btn btn-secondary m-0, p-0\" (click)=\"close(); (false)\"><i class=\"fa fa-times\" aria-hidden=\"true\"></i></a>\n </div>\n </div>\n <div class=\"card-body h-100\">\n <p>{{ 'designer.intro.step-' + introService.activeStep | translate }}</p>\n </div>\n <div class=\"card-footer\">\n @if (introService.activeStep != 'start') {\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"introService.back()\">\n <i class=\"fa fa-chevron-left\" aria-hidden=\"true\"></i> {{ 'designer.intro.back' | translate }}\n </button>\n } @if (introService.activeStep != 'finish') {\n <button type=\"button\" class=\"btn btn-secondary pull-right\" (click)=\"introService.next()\">\n {{ 'designer.intro.next' | translate }} <i class=\"fa fa-chevron-right\" aria-hidden=\"true\"></i>\n </button>\n } @if (introService.activeStep == 'finish') {\n <button type=\"button\" class=\"btn btn-secondary pull-right\" (click)=\"close()\">\n {{ 'designer.intro.close' | translate }}\n </button>\n }\n </div>\n</div>\n}\n", styles: [".card{position:absolute;width:400px;height:350px!important;z-index:999999}\n"], dependencies: [{ kind: "directive", type: i9.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
8259
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: IntroComponent, isStandalone: false, selector: "lib-app-intro", ngImport: i0, template: "@if (introService.showIntro) {\n<div\n class=\"card border-secondary h-100 panel card-intro-active\"\n [ngStyle]=\"{\n top: 'calc(' + introService.positionTopPercentage + '% - 150px)',\n left: 'calc(' + introService.positionLeftPercentage + '% - 200px)'\n }\"\n>\n <div class=\"card-header d-flex\">\n <div>\n <i class=\"fa fa-info-circle mr-1\" aria-hidden=\"true\"></i>\n {{ 'designer.intro.title-' + introService.activeStep | translate }}\n </div>\n <div class=\"ml-auto\">\n <a href=\"#\" class=\"btn btn-secondary m-0, p-0\" (click)=\"close(); (false)\"><i class=\"fa fa-times\" aria-hidden=\"true\"></i></a>\n </div>\n </div>\n <div class=\"card-body h-100\">\n <p>{{ 'designer.intro.step-' + introService.activeStep | translate }}</p>\n </div>\n <div class=\"card-footer\">\n @if (introService.activeStep != 'start') {\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"introService.back()\">\n <i class=\"fa fa-chevron-left\" aria-hidden=\"true\"></i> {{ 'designer.intro.back' | translate }}\n </button>\n } @if (introService.activeStep != 'finish') {\n <button type=\"button\" class=\"btn btn-secondary pull-right\" (click)=\"introService.next()\">\n {{ 'designer.intro.next' | translate }} <i class=\"fa fa-chevron-right\" aria-hidden=\"true\"></i>\n </button>\n } @if (introService.activeStep == 'finish') {\n <button type=\"button\" class=\"btn btn-secondary pull-right\" (click)=\"close()\">\n {{ 'designer.intro.close' | translate }}\n </button>\n }\n </div>\n</div>\n}\n", styles: [".card{position:absolute;width:400px;height:350px!important;z-index:999999}\n"], dependencies: [{ kind: "directive", type: i10$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
8163
8260
  }
8164
8261
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: IntroComponent, decorators: [{
8165
8262
  type: Component,
@@ -8443,13 +8540,13 @@ class DesignerComponent {
8443
8540
  this.translateService.use(language);
8444
8541
  localStorage.setItem('language', language);
8445
8542
  }
8446
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DesignerComponent, deps: [{ token: i4.TranslateService }, { token: ProjectService }, { token: ConfigService }, { token: FixturePoolService }, { token: HotkeyTargetExcludeService }, { token: i1$1.BsModalService }, { token: UserService }, { token: UserEnsureLoginService }, { token: ProjectLoadService }, { token: WarningDialogService }, { token: ErrorDialogService }, { token: FixtureService }, { token: TimelineService }, { token: IntroService }, { token: EffectService }], target: i0.ɵɵFactoryTarget.Component }); }
8447
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DesignerComponent, isStandalone: false, selector: "lib-designer", inputs: { menuHeightPx: "menuHeightPx", externalCompositionsAvailable: "externalCompositionsAvailable", restUrl: "restUrl", enableMediaLibrary: "enableMediaLibrary", loginAvailable: "loginAvailable", shareAvailable: "shareAvailable", languageSwitch: "languageSwitch", livePreview: "livePreview", localProfiles: "localProfiles", intro: "intro", uniqueProjectNames: "uniqueProjectNames", dropzoneChunking: "dropzoneChunking" }, host: { listeners: { "document:keydown": "handleKeyboardEvent($event)" } }, viewQueries: [{ propertyName: "previewComponent", first: true, predicate: PreviewComponent, descendants: true }, { propertyName: "timelineComponent", first: true, predicate: TimelineComponent, descendants: true }], ngImport: i0, template: "<!-- Wrap the whole component inside a div to encapsulate the CSS -->\n\n<!-- 100 % height minus the menu bar above and the gutter size of 13 px -->\n<!-- <div style=\"height: calc(100% - 33px)\"> -->\n<div id=\"designer\" [ngStyle]=\"{ height: 'calc(100% - ' + totalMenuHeightPx + 'px)' }\">\n <!-- Navigation -->\n <nav\n class=\"navbar navbar-expand-lg navbar-light bg-light border-secondary\"\n style=\"border-bottom: 1px solid #444; height: 20px; z-index: 9999\"\n >\n <!-- Menu buttons -->\n <ul class=\"navbar-nav mr-auto\">\n <li class=\"nav-item dropdown\">\n <a class=\"nav-link dropdown-toggle\" href=\"#\" id=\"fileDropdown\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\">\n {{ 'designer.navigation.project' | translate }}\n </a>\n <div class=\"dropdown-menu\" aria-labelledby=\"fileDropdown\">\n <a class=\"dropdown-item d-none d-md-block\" href=\"#\" (click)=\"projectNew(); (false)\"\n ><i class=\"fa fa-fw fa-file-o\" aria-hidden=\"true\"></i> {{ 'designer.navigation.project-new' | translate }}</a\n >\n <a class=\"dropdown-item\" href=\"#\" (click)=\"projectOpen(); (false)\"\n ><i class=\"fa fa-fw fa-folder-open-o\" aria-hidden=\"true\"></i> {{ 'designer.navigation.project-open' | translate }}</a\n >\n <a class=\"dropdown-item d-none d-md-block\" href=\"#\" (click)=\"projectSave(); (false)\"\n ><i class=\"fa fa-fw fa-floppy-o\" aria-hidden=\"true\"></i> {{ 'designer.navigation.project-save' | translate }}</a\n >\n <a class=\"dropdown-item d-none d-md-block\" href=\"#\" (click)=\"projectSaveAs(); (false)\"\n ><i class=\"fa fa-fw fa-floppy-o\" aria-hidden=\"true\"></i> {{ 'designer.navigation.project-save-as' | translate }}</a\n >\n <a class=\"dropdown-item d-none d-md-block\" href=\"#\" (click)=\"projectImport(); (false)\"\n ><i class=\"fa fa-fw fa-download\" aria-hidden=\"true\"></i> {{ 'designer.navigation.project-import' | translate }}</a\n >\n <a class=\"dropdown-item d-none d-md-block\" href=\"#\" (click)=\"projectExport(); (false)\"\n ><i class=\"fa fa-fw fa-external-link\" aria-hidden=\"true\"></i> {{ 'designer.navigation.project-export' | translate }}</a\n >\n </div>\n </li>\n <li class=\"nav-item dropdown d-none d-md-block\">\n <a\n class=\"nav-link dropdown-toggle\"\n href=\"#\"\n id=\"settingsDropdown\"\n data-toggle=\"dropdown\"\n aria-haspopup=\"true\"\n aria-expanded=\"false\"\n >\n {{ 'designer.navigation.settings' | translate }}\n </a>\n <div class=\"dropdown-menu\" aria-labelledby=\"settingsDropdown\">\n <a class=\"dropdown-item\" href=\"#\" (click)=\"openFixturePool(); (false)\">{{ 'designer.navigation.fixture-pool' | translate }}</a>\n <!-- <a class=\"dropdown-item\" href=\"#\">{{ 'designer.navigation.stage' | translate }}</a> -->\n </div>\n </li>\n <li class=\"nav-item dropdown d-none d-md-block\">\n <a\n class=\"nav-link dropdown-toggle\"\n href=\"#\"\n id=\"settingsDropdown\"\n data-toggle=\"dropdown\"\n aria-haspopup=\"true\"\n aria-expanded=\"false\"\n >\n {{ 'designer.navigation.help' | translate }}\n </a>\n <div class=\"dropdown-menu\" aria-labelledby=\"settingsDropdown\">\n <a class=\"dropdown-item\" href=\"#\" (click)=\"introService.reset(); (false)\">{{ 'designer.navigation.reset-intro' | translate }}</a>\n <a class=\"dropdown-item\" href=\"https://rocketshow.net/support/\" target=\"_blank\">{{\n 'designer.navigation.support' | translate\n }}</a>\n </div>\n </li>\n </ul>\n\n <ul class=\"navbar-nav\">\n @if (configService.shareAvailable) {\n <li class=\"nav-item d-none d-md-flex\" data-toggle=\"collapse\">\n <a class=\"nav-link text-primary\" (click)=\"projectShare(); (false)\" routerLinkActive=\"active\"\n ><i class=\"fa fa-share-alt\" aria-hidden=\"true\"></i> {{ 'designer.navigation.project-share' | translate }}</a\n >\n </li>\n } @if (configService.languageSwitch) {\n <li class=\"nav-item dropdown\">\n <a class=\"nav-link dropdown-toggle\" href=\"#\" id=\"settingsDropdown\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\"\n ><i class=\"fa fa-globe\" aria-hidden=\"true\"></i>\n {{ 'designer.misc.language' | translate }}\n </a>\n <div class=\"dropdown-menu dropdown-menu-right\" aria-labelledby=\"settingsDropdown\">\n <a class=\"dropdown-item\" href=\"#\" (click)=\"switchLanguage('en'); (false)\" target=\"_blank\">English</a>\n <a class=\"dropdown-item\" href=\"#\" (click)=\"switchLanguage('de'); (false)\" target=\"_blank\">Deutsch</a>\n </div>\n </li>\n } @if (configService.loginAvailable && !userService.isLoggedIn()) {\n <li class=\"nav-item\" data-toggle=\"collapse\">\n <a class=\"nav-link\" (click)=\"userRegister(); (false)\" routerLinkActive=\"active\"\n ><i class=\"fa fa-user\" aria-hidden=\"true\"></i> {{ 'designer.navigation.login' | translate }}</a\n >\n </li>\n } @if (configService.loginAvailable && userService.isLoggedIn()) {\n <li class=\"nav-item dropdown\">\n <a class=\"nav-link dropdown-toggle\" href=\"#\" id=\"settingsDropdown\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\"\n ><i class=\"fa fa-user\" aria-hidden=\"true\"></i>\n {{ userService.username }}\n </a>\n <div class=\"dropdown-menu dropdown-menu-right\" aria-labelledby=\"settingsDropdown\">\n <a class=\"dropdown-item\" href=\"#\" (click)=\"userService.logout(); (false)\" target=\"_blank\"\n ><i class=\"fa fa-sign-out\" aria-hidden=\"true\"></i> {{ 'designer.navigation.logout' | translate }}</a\n >\n </div>\n </li>\n }\n </ul>\n </nav>\n\n <!-- The main content for larger screens -->\n <div class=\"h-100 d-none d-md-block\">\n <div id=\"row1\" class=\"split split-vertical clearfix pt-3 pl-3\">\n <!-- Scenes -->\n <div id=\"scenes\" class=\"split split-horizontal h-100\">\n @if (projectService.project) {\n <lib-app-scene></lib-app-scene>\n }\n </div>\n\n <!-- Presets -->\n <div id=\"presets\" class=\"split split-horizontal h-100\">\n @if (projectService.project) {\n <lib-app-preset></lib-app-preset>\n }\n </div>\n\n <!-- 3D preview -->\n <div id=\"preview\" class=\"split split-horizontal h-100 pr-3\">\n @if (projectService.project) {\n <div class=\"card border-secondary h-100\" [class.card-intro-active]=\"introService.showStep('preview')\">\n <div class=\"card-body p-0 h-100\">\n <lib-app-preview class=\"h-100\"></lib-app-preview>\n </div>\n </div>\n }\n </div>\n </div>\n\n <div id=\"row2\" class=\"split split-vertical clearfix px-3 d-flex\" style=\"flex-direction: row\">\n <!-- Menu for the capabilities, channels, effects and settings -->\n @if (projectService.project) {\n <div class=\"col col-auto p-0\" style=\"margin-right: -1px\">\n <div class=\"nav flex-column nav-pills\" id=\"v-pills-tab\" role=\"tablist\" aria-orientation=\"vertical\">\n <a\n class=\"nav-link px-3 active\"\n (click)=\"openTab('capabilities')\"\n id=\"v-pills-capabilities-tab\"\n popover=\"{{ 'designer.misc.capabilities' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-capabilities\"\n role=\"tab\"\n aria-controls=\"v-pills-capabilities\"\n aria-selected=\"true\"\n >\n <i class=\"fa fa-bolt fa-fw\" aria-hidden=\"true\"></i>\n </a>\n <a\n class=\"nav-link px-3\"\n (click)=\"openTab('channels')\"\n id=\"v-pills-channels-tab\"\n popover=\"{{ 'designer.misc.channels' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-channels\"\n role=\"tab\"\n aria-controls=\"v-pills-channels\"\n aria-selected=\"false\"\n >\n <i class=\"fa fa-sliders fa-fw\" aria-hidden=\"true\"></i>\n </a>\n <a\n class=\"nav-link px-3\"\n (click)=\"openTab('effects')\"\n id=\"v-pills-effects-tab\"\n popover=\"{{ 'designer.misc.effects' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-effects\"\n role=\"tab\"\n aria-controls=\"v-pills-effects\"\n aria-selected=\"false\"\n >\n <i class=\"fa fa-magic fa-fw\" aria-hidden=\"true\"></i>\n </a>\n <a\n class=\"nav-link px-3\"\n (click)=\"openTab('settings')\"\n id=\"v-pills-settings-tab\"\n popover=\"{{ 'designer.misc.settings' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-settings\"\n role=\"tab\"\n aria-controls=\"v-pills-settings\"\n aria-selected=\"false\"\n style=\"border-top: 1px solid #444\"\n >\n <i class=\"fa fa-cog fa-fw\" aria-hidden=\"true\"></i>\n </a>\n </div>\n </div>\n }\n\n <div id=\"capabilities\" class=\"split split-horizontal h-100\" style=\"padding-left: 1rem\">\n @if (projectService.project) {\n <div class=\"row h-100\">\n <!-- Content for the capabilities, channels, effects and settings -->\n <div class=\"col pl-0 h-100\">\n <div class=\"tab-content h-100\" id=\"v-pills-tabContent\">\n <div class=\"tab-pane h-100 show active\" id=\"v-pills-capabilities\" role=\"tabpanel\">\n <lib-app-fixture-capability></lib-app-fixture-capability>\n </div>\n <div class=\"tab-pane h-100 show\" id=\"v-pills-channels\" role=\"tabpanel\">\n <lib-app-fixture-channel></lib-app-fixture-channel>\n </div>\n <div class=\"tab-pane h-100\" id=\"v-pills-effects\" role=\"tabpanel\" aria-labelledby=\"v-pills-profile-tab\">\n <lib-app-effect></lib-app-effect>\n </div>\n <div class=\"tab-pane h-100\" id=\"v-pills-settings\" role=\"tabpanel\" aria-labelledby=\"v-pills-home-tab\">\n <lib-app-fixture-settings></lib-app-fixture-settings>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n\n <!-- Fixtures -->\n <div id=\"fixtures\" class=\"split split-horizontal h-100\">\n @if (projectService.project) {\n <lib-app-fixture></lib-app-fixture>\n }\n </div>\n\n <!-- Master dimmer -->\n <div id=\"masterDimmer\" class=\"split split-horizontal h-100\">\n @if (projectService.project) {\n <lib-app-master-dimmer></lib-app-master-dimmer>\n }\n </div>\n </div>\n\n <!-- Timeline -->\n <div id=\"row3\" class=\"split split-vertical clearfix px-3 pb-3\" style=\"padding-bottom: 20px\">\n @if (projectService.project) {\n <lib-app-timeline></lib-app-timeline>\n }\n </div>\n </div>\n\n <!-- The components for small screens -->\n <div class=\"d-md-none p-3\">\n <div>\n @if (projectService.project) {\n <lib-app-master-dimmer></lib-app-master-dimmer>\n }\n </div>\n\n <div class=\"mt-3\">\n @if (projectService.project) {\n <lib-app-scene></lib-app-scene>\n }\n </div>\n </div>\n</div>\n\n<lib-app-intro class=\"d-none d-md-flex\"></lib-app-intro>\n", styles: [".modal-full{max-width:unset!important;margin:1.75rem!important}.modal{z-index:10001}#designer{font-size:14px}#designer .nav-link{cursor:pointer}#designer .dropdown-menu{z-index:100000}#designer .row{flex-wrap:unset}#designer .navbar-nav{flex-direction:row!important}#designer .navbar-expand-lg{flex-flow:row nowrap!important;justify-content:flex-start!important}#designer .navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem!important;padding-left:.5rem!important}#designer .list-group-item.active{color:#fff!important;background-color:#fd7e14!important;border-color:#fd7e14!important}#designer *:focus{outline:none}#designer select{font-size:.8rem;cursor:pointer}#designer input{font-size:.7rem;background-color:transparent;color:#fff;border:1px solid}#designer input,#designer select{border-color:#dee2e6}#designer .list-group-item{padding:.3rem 1.25rem;border-left:none;border-right:none}#designer .nav-pills .nav-link.active,#designer .nav-pills .show>.nav-link{background-color:#444}#designer .nav a,#designer .panel-title .btn-link{color:#fff!important}#designer .accordion-toggle .btn,#designer .accordion-toggle button{padding:0}#designer .card-body{overflow:auto;padding:.8rem}#designer .card-header{margin-bottom:0}#designer .card-header{padding:.4rem}#designer .panel-body{background-color:#303030}#designer .list-group-item.active-light{background-color:#906542;border-color:#906542}#designer .inactive-list-item{opacity:.3}#designer span.bigcheck-target{font-family:FontAwesome}#designer input[type=checkbox].bigcheck{position:relative;left:-999em}#designer input[type=checkbox].bigcheck+span.bigcheck-target:after{content:\"\\f096\"}#designer input[type=checkbox].bigcheck:checked+span.bigcheck-target:after{content:\"\\f046\"}#designer .gutter.gutter-horizontal{cursor:ew-resize}#designer .gutter.gutter-vertical{cursor:ns-resize}#designer .split-horizontal,#designer .gutter.gutter-horizontal{float:left}#designer .split-vertical,#designer .gutter.gutter-horizontal{height:100%}#designer .split{overflow-y:hidden;overflow-x:hidden}#designer .panel{background-color:transparent}#designer .slider{cursor:pointer}#designer .slider-horizontal .slider-track{height:2px!important;margin-top:-2px!important}#designer .slider-vertical .slider-track{width:2px!important;margin-left:4px!important}#designer .slider-track,#designer .slider-track-low,#designer .slider-track-high,#designer .slider-selection{background-color:#fff!important;border-radius:0!important;background-image:none!important;box-shadow:none!important}#designer .slider-handle{width:13px!important;height:13px!important;background-color:#fff!important;background-image:none!important;border:1px solid #303030}#designer .slider-vertical .slider-handle{margin-left:4px!important}#designer .slider-horizontal .slider-handle{margin-top:2px!important}#designer .slider-input{width:35px;margin-left:8px;text-align:center}#designer .slider-input-readonly{width:35px;margin-left:8px;text-align:center;color:#a9a9a9;border-color:gray}#designer .capability-container{padding:0;height:0}#designer accordion-group>div{border:none!important}#designer .popover{background-color:#fff}#designer .popover-body{color:#000}#designer .bs-popover-right .arrow:after,#designer .bs-popover-auto[x-placement^=right] .arrow:after{border-right-color:#fff}#designer .bs-popover-left .arrow:after,#designer .bs-popover-auto[x-placement^=left] .arrow:after{border-left-color:#fff}#designer .bs-popover-bottom .arrow:after,#designer .bs-popover-auto[x-placement^=bottom] .arrow:after{border-bottom-color:#fff}#designer .bs-popover-top .arrow:after,#designer .bs-popover-auto[x-placement^=top] .arrow:after{border-top-color:#fff}#designer .iro__wheel,#designer .iro__slider{cursor:pointer}#designer .pan-tilt-grid path{fill:none;stroke:#fff;stroke-width:10px}#designer .pan-tilt-grid circle{fill:#4682b4;stroke:#fff;stroke-width:3px}#designer .capability{overflow:visible}#designer .capability-deactivated{opacity:.4}#designer .wavesurfer-region{z-index:5!important}#designer .wavesurfer-region[data-region-selected=true]{z-index:6!important}#designer .wavesurfer-region[data-region-preset=true]{height:50%!important;top:50%!important}#designer .wavesurfer-region[data-region-name]:after{content:attr(data-region-name);margin-left:20px}#designer .wavesurfer-handle{width:10px!important;max-width:10px!important;border:1px solid #ddd;background:#0000001a;box-sizing:border-box;opacity:0;cursor:unset!important}#designer .wavesurfer-handle-end{margin-left:-10px}#designer .wavesurfer-region[data-region-selectable=true] .wavesurfer-handle{opacity:1;cursor:col-resize!important}#designer .wavesurfer-handle:before,#designer .wavesurfer-handle:after{content:\"\";display:block;position:absolute;z-index:1;border-top:1px solid #fff;border-bottom:1px solid #fff;height:4px;left:5%;right:5%;top:50%;transform:translateY(-50%)}#designer .wavesurfer-handle:before{margin-top:-3px}#designer timeline{overflow:scroll!important;overflow:-moz-scrollbars-none;-ms-overflow-style:none;scrollbar-width:none;cursor:s-resize}#designer timeline::-webkit-scrollbar{height:0!important}#designer cursor{top:-20px!important}#designer wave{border-right-color:#fd7e14!important;cursor:col-resize}#designer wave canvas{opacity:.2}\n"], dependencies: [{ kind: "directive", type: i3.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "directive", type: i9.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i11.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: PreviewComponent, selector: "lib-app-preview" }, { kind: "component", type: SceneComponent, selector: "lib-app-scene" }, { kind: "component", type: TimelineComponent, selector: "lib-app-timeline" }, { kind: "component", type: FixtureComponent, selector: "lib-app-fixture" }, { kind: "component", type: FixtureCapabilityComponent, selector: "lib-app-fixture-capability" }, { kind: "component", type: FixtureSettingsComponent, selector: "lib-app-fixture-settings" }, { kind: "component", type: EffectComponent, selector: "lib-app-effect" }, { kind: "component", type: PresetComponent, selector: "lib-app-preset" }, { kind: "component", type: MasterDimmerComponent, selector: "lib-app-master-dimmer" }, { kind: "component", type: FixtureChannelComponent, selector: "lib-app-fixture-channel" }, { kind: "component", type: IntroComponent, selector: "lib-app-intro" }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
8543
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DesignerComponent, deps: [{ token: i2.TranslateService }, { token: ProjectService }, { token: ConfigService }, { token: FixturePoolService }, { token: HotkeyTargetExcludeService }, { token: i1$1.BsModalService }, { token: UserService }, { token: UserEnsureLoginService }, { token: ProjectLoadService }, { token: WarningDialogService }, { token: ErrorDialogService }, { token: FixtureService }, { token: TimelineService }, { token: IntroService }, { token: EffectService }], target: i0.ɵɵFactoryTarget.Component }); }
8544
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DesignerComponent, isStandalone: false, selector: "lib-designer", inputs: { menuHeightPx: "menuHeightPx", externalCompositionsAvailable: "externalCompositionsAvailable", restUrl: "restUrl", enableMediaLibrary: "enableMediaLibrary", loginAvailable: "loginAvailable", shareAvailable: "shareAvailable", languageSwitch: "languageSwitch", livePreview: "livePreview", localProfiles: "localProfiles", intro: "intro", uniqueProjectNames: "uniqueProjectNames", dropzoneChunking: "dropzoneChunking" }, host: { listeners: { "document:keydown": "handleKeyboardEvent($event)" } }, viewQueries: [{ propertyName: "previewComponent", first: true, predicate: PreviewComponent, descendants: true }, { propertyName: "timelineComponent", first: true, predicate: TimelineComponent, descendants: true }], ngImport: i0, template: "<!-- Wrap the whole component inside a div to encapsulate the CSS -->\n\n<!-- 100 % height minus the menu bar above and the gutter size of 13 px -->\n<!-- <div style=\"height: calc(100% - 33px)\"> -->\n<div id=\"designer\" [ngStyle]=\"{ height: 'calc(100% - ' + totalMenuHeightPx + 'px)' }\">\n <!-- Navigation -->\n <nav\n class=\"navbar navbar-expand-lg navbar-light bg-light border-secondary\"\n style=\"border-bottom: 1px solid #444; height: 20px; z-index: 9999\"\n >\n <!-- Menu buttons -->\n <ul class=\"navbar-nav mr-auto\">\n <li class=\"nav-item dropdown\">\n <a class=\"nav-link dropdown-toggle\" href=\"#\" id=\"fileDropdown\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\">\n {{ 'designer.navigation.project' | translate }}\n </a>\n <div class=\"dropdown-menu\" aria-labelledby=\"fileDropdown\">\n <a class=\"dropdown-item d-none d-md-block\" href=\"#\" (click)=\"projectNew(); (false)\"\n ><i class=\"fa fa-fw fa-file-o\" aria-hidden=\"true\"></i> {{ 'designer.navigation.project-new' | translate }}</a\n >\n <a class=\"dropdown-item\" href=\"#\" (click)=\"projectOpen(); (false)\"\n ><i class=\"fa fa-fw fa-folder-open-o\" aria-hidden=\"true\"></i> {{ 'designer.navigation.project-open' | translate }}</a\n >\n <a class=\"dropdown-item d-none d-md-block\" href=\"#\" (click)=\"projectSave(); (false)\"\n ><i class=\"fa fa-fw fa-floppy-o\" aria-hidden=\"true\"></i> {{ 'designer.navigation.project-save' | translate }}</a\n >\n <a class=\"dropdown-item d-none d-md-block\" href=\"#\" (click)=\"projectSaveAs(); (false)\"\n ><i class=\"fa fa-fw fa-floppy-o\" aria-hidden=\"true\"></i> {{ 'designer.navigation.project-save-as' | translate }}</a\n >\n <a class=\"dropdown-item d-none d-md-block\" href=\"#\" (click)=\"projectImport(); (false)\"\n ><i class=\"fa fa-fw fa-download\" aria-hidden=\"true\"></i> {{ 'designer.navigation.project-import' | translate }}</a\n >\n <a class=\"dropdown-item d-none d-md-block\" href=\"#\" (click)=\"projectExport(); (false)\"\n ><i class=\"fa fa-fw fa-external-link\" aria-hidden=\"true\"></i> {{ 'designer.navigation.project-export' | translate }}</a\n >\n </div>\n </li>\n <li class=\"nav-item dropdown d-none d-md-block\">\n <a\n class=\"nav-link dropdown-toggle\"\n href=\"#\"\n id=\"settingsDropdown\"\n data-toggle=\"dropdown\"\n aria-haspopup=\"true\"\n aria-expanded=\"false\"\n >\n {{ 'designer.navigation.settings' | translate }}\n </a>\n <div class=\"dropdown-menu\" aria-labelledby=\"settingsDropdown\">\n <a class=\"dropdown-item\" href=\"#\" (click)=\"openFixturePool(); (false)\">{{ 'designer.navigation.fixture-pool' | translate }}</a>\n <!-- <a class=\"dropdown-item\" href=\"#\">{{ 'designer.navigation.stage' | translate }}</a> -->\n </div>\n </li>\n <li class=\"nav-item dropdown d-none d-md-block\">\n <a\n class=\"nav-link dropdown-toggle\"\n href=\"#\"\n id=\"settingsDropdown\"\n data-toggle=\"dropdown\"\n aria-haspopup=\"true\"\n aria-expanded=\"false\"\n >\n {{ 'designer.navigation.help' | translate }}\n </a>\n <div class=\"dropdown-menu\" aria-labelledby=\"settingsDropdown\">\n <a class=\"dropdown-item\" href=\"#\" (click)=\"introService.reset(); (false)\">{{ 'designer.navigation.reset-intro' | translate }}</a>\n <a class=\"dropdown-item\" href=\"https://rocketshow.net/support/\" target=\"_blank\">{{\n 'designer.navigation.support' | translate\n }}</a>\n </div>\n </li>\n </ul>\n\n <ul class=\"navbar-nav\">\n @if (configService.shareAvailable) {\n <li class=\"nav-item d-none d-md-flex\" data-toggle=\"collapse\">\n <a class=\"nav-link text-primary\" (click)=\"projectShare(); (false)\" routerLinkActive=\"active\"\n ><i class=\"fa fa-share-alt\" aria-hidden=\"true\"></i> {{ 'designer.navigation.project-share' | translate }}</a\n >\n </li>\n } @if (configService.languageSwitch) {\n <li class=\"nav-item dropdown\">\n <a class=\"nav-link dropdown-toggle\" href=\"#\" id=\"settingsDropdown\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\"\n ><i class=\"fa fa-globe\" aria-hidden=\"true\"></i>\n {{ 'designer.misc.language' | translate }}\n </a>\n <div class=\"dropdown-menu dropdown-menu-right\" aria-labelledby=\"settingsDropdown\">\n <a class=\"dropdown-item\" href=\"#\" (click)=\"switchLanguage('en'); (false)\" target=\"_blank\">English</a>\n <a class=\"dropdown-item\" href=\"#\" (click)=\"switchLanguage('de'); (false)\" target=\"_blank\">Deutsch</a>\n </div>\n </li>\n } @if (configService.loginAvailable && !userService.isLoggedIn()) {\n <li class=\"nav-item\" data-toggle=\"collapse\">\n <a class=\"nav-link\" (click)=\"userRegister(); (false)\" routerLinkActive=\"active\"\n ><i class=\"fa fa-user\" aria-hidden=\"true\"></i> {{ 'designer.navigation.login' | translate }}</a\n >\n </li>\n } @if (configService.loginAvailable && userService.isLoggedIn()) {\n <li class=\"nav-item dropdown\">\n <a class=\"nav-link dropdown-toggle\" href=\"#\" id=\"settingsDropdown\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\"\n ><i class=\"fa fa-user\" aria-hidden=\"true\"></i>\n {{ userService.username }}\n </a>\n <div class=\"dropdown-menu dropdown-menu-right\" aria-labelledby=\"settingsDropdown\">\n <a class=\"dropdown-item\" href=\"#\" (click)=\"userService.logout(); (false)\" target=\"_blank\"\n ><i class=\"fa fa-sign-out\" aria-hidden=\"true\"></i> {{ 'designer.navigation.logout' | translate }}</a\n >\n </div>\n </li>\n }\n </ul>\n </nav>\n\n <!-- The main content for larger screens -->\n <div class=\"h-100 d-none d-md-block\">\n <div id=\"row1\" class=\"split split-vertical clearfix pt-3 pl-3\">\n <!-- Scenes -->\n <div id=\"scenes\" class=\"split split-horizontal h-100\">\n @if (projectService.project) {\n <lib-app-scene></lib-app-scene>\n }\n </div>\n\n <!-- Presets -->\n <div id=\"presets\" class=\"split split-horizontal h-100\">\n @if (projectService.project) {\n <lib-app-preset></lib-app-preset>\n }\n </div>\n\n <!-- 3D preview -->\n <div id=\"preview\" class=\"split split-horizontal h-100 pr-3\">\n @if (projectService.project) {\n <div class=\"card border-secondary h-100\" [class.card-intro-active]=\"introService.showStep('preview')\">\n <div class=\"card-body p-0 h-100\">\n <lib-app-preview class=\"h-100\"></lib-app-preview>\n </div>\n </div>\n }\n </div>\n </div>\n\n <div id=\"row2\" class=\"split split-vertical clearfix px-3 d-flex\" style=\"flex-direction: row\">\n <!-- Menu for the capabilities, channels, effects and settings -->\n @if (projectService.project) {\n <div class=\"col col-auto p-0\" style=\"margin-right: -1px\">\n <div class=\"nav flex-column nav-pills\" id=\"v-pills-tab\" role=\"tablist\" aria-orientation=\"vertical\">\n <a\n class=\"nav-link px-3 active\"\n (click)=\"openTab('capabilities')\"\n id=\"v-pills-capabilities-tab\"\n popover=\"{{ 'designer.misc.capabilities' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-capabilities\"\n role=\"tab\"\n aria-controls=\"v-pills-capabilities\"\n aria-selected=\"true\"\n >\n <i class=\"fa fa-bolt fa-fw\" aria-hidden=\"true\"></i>\n </a>\n <a\n class=\"nav-link px-3\"\n (click)=\"openTab('channels')\"\n id=\"v-pills-channels-tab\"\n popover=\"{{ 'designer.misc.channels' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-channels\"\n role=\"tab\"\n aria-controls=\"v-pills-channels\"\n aria-selected=\"false\"\n >\n <i class=\"fa fa-sliders fa-fw\" aria-hidden=\"true\"></i>\n </a>\n <a\n class=\"nav-link px-3\"\n (click)=\"openTab('effects')\"\n id=\"v-pills-effects-tab\"\n popover=\"{{ 'designer.misc.effects' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-effects\"\n role=\"tab\"\n aria-controls=\"v-pills-effects\"\n aria-selected=\"false\"\n >\n <i class=\"fa fa-magic fa-fw\" aria-hidden=\"true\"></i>\n </a>\n <a\n class=\"nav-link px-3\"\n (click)=\"openTab('settings')\"\n id=\"v-pills-settings-tab\"\n popover=\"{{ 'designer.misc.settings' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-settings\"\n role=\"tab\"\n aria-controls=\"v-pills-settings\"\n aria-selected=\"false\"\n style=\"border-top: 1px solid #444\"\n >\n <i class=\"fa fa-cog fa-fw\" aria-hidden=\"true\"></i>\n </a>\n </div>\n </div>\n }\n\n <div id=\"capabilities\" class=\"split split-horizontal h-100\" style=\"padding-left: 1rem\">\n @if (projectService.project) {\n <div class=\"row h-100\">\n <!-- Content for the capabilities, channels, effects and settings -->\n <div class=\"col pl-0 h-100\">\n <div class=\"tab-content h-100\" id=\"v-pills-tabContent\">\n <div class=\"tab-pane h-100 show active\" id=\"v-pills-capabilities\" role=\"tabpanel\">\n <lib-app-fixture-capability></lib-app-fixture-capability>\n </div>\n <div class=\"tab-pane h-100 show\" id=\"v-pills-channels\" role=\"tabpanel\">\n <lib-app-fixture-channel></lib-app-fixture-channel>\n </div>\n <div class=\"tab-pane h-100\" id=\"v-pills-effects\" role=\"tabpanel\" aria-labelledby=\"v-pills-profile-tab\">\n <lib-app-effect></lib-app-effect>\n </div>\n <div class=\"tab-pane h-100\" id=\"v-pills-settings\" role=\"tabpanel\" aria-labelledby=\"v-pills-home-tab\">\n <lib-app-fixture-settings></lib-app-fixture-settings>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n\n <!-- Fixtures -->\n <div id=\"fixtures\" class=\"split split-horizontal h-100\">\n @if (projectService.project) {\n <lib-app-fixture></lib-app-fixture>\n }\n </div>\n\n <!-- Master dimmer -->\n <div id=\"masterDimmer\" class=\"split split-horizontal h-100\">\n @if (projectService.project) {\n <lib-app-master-dimmer></lib-app-master-dimmer>\n }\n </div>\n </div>\n\n <!-- Timeline -->\n <div id=\"row3\" class=\"split split-vertical clearfix px-3 pb-3\" style=\"padding-bottom: 20px\">\n @if (projectService.project) {\n <lib-app-timeline></lib-app-timeline>\n }\n </div>\n </div>\n\n <!-- The components for small screens -->\n <div class=\"d-md-none p-3\">\n <div>\n @if (projectService.project) {\n <lib-app-master-dimmer></lib-app-master-dimmer>\n }\n </div>\n\n <div class=\"mt-3\">\n @if (projectService.project) {\n <lib-app-scene></lib-app-scene>\n }\n </div>\n </div>\n</div>\n\n<lib-app-intro class=\"d-none d-md-flex\"></lib-app-intro>\n", styles: [".modal-full{max-width:unset!important;margin:1.75rem!important}.modal{z-index:10001}#designer{font-size:14px}#designer .nav-link{cursor:pointer}#designer .dropdown-menu{z-index:100000}#designer .row{flex-wrap:unset}#designer .navbar-nav{flex-direction:row!important}#designer .navbar-expand-lg{flex-flow:row nowrap!important;justify-content:flex-start!important}#designer .navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem!important;padding-left:.5rem!important}#designer .list-group-item.active{color:#fff!important;background-color:#fd7e14!important;border-color:#fd7e14!important}#designer *:focus{outline:none}#designer select{font-size:.8rem;cursor:pointer}#designer input{font-size:.7rem;background-color:transparent;color:#fff;border:1px solid}#designer input,#designer select{border-color:#dee2e6}#designer .list-group-item{padding:.3rem 1.25rem;border-left:none;border-right:none}#designer .nav-pills .nav-link.active,#designer .nav-pills .show>.nav-link{background-color:#444}#designer .nav a,#designer .panel-title .btn-link{color:#fff!important}#designer .accordion-toggle .btn,#designer .accordion-toggle button{padding:0}#designer .card-body{overflow:auto;padding:.8rem}#designer .card-header{margin-bottom:0}#designer .card-header{padding:.4rem}#designer .panel-body{background-color:#303030}#designer .list-group-item.active-light{background-color:#906542;border-color:#906542}#designer .inactive-list-item{opacity:.3}#designer span.bigcheck-target{font-family:FontAwesome}#designer input[type=checkbox].bigcheck{position:relative;left:-999em}#designer input[type=checkbox].bigcheck+span.bigcheck-target:after{content:\"\\f096\"}#designer input[type=checkbox].bigcheck:checked+span.bigcheck-target:after{content:\"\\f046\"}#designer .gutter.gutter-horizontal{cursor:ew-resize}#designer .gutter.gutter-vertical{cursor:ns-resize}#designer .split-horizontal,#designer .gutter.gutter-horizontal{float:left}#designer .split-vertical,#designer .gutter.gutter-horizontal{height:100%}#designer .split{overflow-y:hidden;overflow-x:hidden}#designer .panel{background-color:transparent}#designer .slider{cursor:pointer}#designer .slider-horizontal .slider-track{height:2px!important;margin-top:-2px!important}#designer .slider-vertical .slider-track{width:2px!important;margin-left:4px!important}#designer .slider-track,#designer .slider-track-low,#designer .slider-track-high,#designer .slider-selection{background-color:#fff!important;border-radius:0!important;background-image:none!important;box-shadow:none!important}#designer .slider-handle{width:13px!important;height:13px!important;background-color:#fff!important;background-image:none!important;border:1px solid #303030}#designer .slider-vertical .slider-handle{margin-left:4px!important}#designer .slider-horizontal .slider-handle{margin-top:2px!important}#designer .slider-input{width:35px;margin-left:8px;text-align:center}#designer .slider-input-readonly{width:35px;margin-left:8px;text-align:center;color:#a9a9a9;border-color:gray}#designer .capability-container{padding:0;height:0}#designer accordion-group>div{border:none!important}#designer .popover{background-color:#fff}#designer .popover-body{color:#000}#designer .bs-popover-right .arrow:after,#designer .bs-popover-auto[x-placement^=right] .arrow:after{border-right-color:#fff}#designer .bs-popover-left .arrow:after,#designer .bs-popover-auto[x-placement^=left] .arrow:after{border-left-color:#fff}#designer .bs-popover-bottom .arrow:after,#designer .bs-popover-auto[x-placement^=bottom] .arrow:after{border-bottom-color:#fff}#designer .bs-popover-top .arrow:after,#designer .bs-popover-auto[x-placement^=top] .arrow:after{border-top-color:#fff}#designer .iro__wheel,#designer .iro__slider{cursor:pointer}#designer .pan-tilt-grid path{fill:none;stroke:#fff;stroke-width:10px}#designer .pan-tilt-grid circle{fill:#4682b4;stroke:#fff;stroke-width:3px}#designer .capability{overflow:visible}#designer .capability-deactivated{opacity:.4}#designer .wavesurfer-region{z-index:5!important}#designer .wavesurfer-region[data-region-selected=true]{z-index:6!important}#designer .wavesurfer-region[data-region-preset=true]{height:50%!important;top:50%!important}#designer .wavesurfer-region[data-region-name]:after{content:attr(data-region-name);margin-left:20px}#designer .wavesurfer-handle{width:10px!important;max-width:10px!important;border:1px solid #ddd;background:#0000001a;box-sizing:border-box;opacity:0;cursor:unset!important}#designer .wavesurfer-handle-end{margin-left:-10px}#designer .wavesurfer-region[data-region-selectable=true] .wavesurfer-handle{opacity:1;cursor:col-resize!important}#designer .wavesurfer-handle:before,#designer .wavesurfer-handle:after{content:\"\";display:block;position:absolute;z-index:1;border-top:1px solid #fff;border-bottom:1px solid #fff;height:4px;left:5%;right:5%;top:50%;transform:translateY(-50%)}#designer .wavesurfer-handle:before{margin-top:-3px}#designer timeline{overflow:scroll!important;overflow:-moz-scrollbars-none;-ms-overflow-style:none;scrollbar-width:none;cursor:s-resize}#designer timeline::-webkit-scrollbar{height:0!important}#designer cursor{top:-20px!important}#designer wave{border-right-color:#fd7e14!important;cursor:col-resize}#designer wave canvas{opacity:.2}\n"], dependencies: [{ kind: "directive", type: i3.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "directive", type: i10$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i12.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: PreviewComponent, selector: "lib-app-preview" }, { kind: "component", type: SceneComponent, selector: "lib-app-scene" }, { kind: "component", type: TimelineComponent, selector: "lib-app-timeline" }, { kind: "component", type: FixtureComponent, selector: "lib-app-fixture" }, { kind: "component", type: FixtureCapabilityComponent, selector: "lib-app-fixture-capability" }, { kind: "component", type: FixtureSettingsComponent, selector: "lib-app-fixture-settings" }, { kind: "component", type: EffectComponent, selector: "lib-app-effect" }, { kind: "component", type: PresetComponent, selector: "lib-app-preset" }, { kind: "component", type: MasterDimmerComponent, selector: "lib-app-master-dimmer" }, { kind: "component", type: FixtureChannelComponent, selector: "lib-app-fixture-channel" }, { kind: "component", type: IntroComponent, selector: "lib-app-intro" }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
8448
8545
  }
8449
8546
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DesignerComponent, decorators: [{
8450
8547
  type: Component,
8451
8548
  args: [{ selector: 'lib-designer', encapsulation: ViewEncapsulation.None, standalone: false, template: "<!-- Wrap the whole component inside a div to encapsulate the CSS -->\n\n<!-- 100 % height minus the menu bar above and the gutter size of 13 px -->\n<!-- <div style=\"height: calc(100% - 33px)\"> -->\n<div id=\"designer\" [ngStyle]=\"{ height: 'calc(100% - ' + totalMenuHeightPx + 'px)' }\">\n <!-- Navigation -->\n <nav\n class=\"navbar navbar-expand-lg navbar-light bg-light border-secondary\"\n style=\"border-bottom: 1px solid #444; height: 20px; z-index: 9999\"\n >\n <!-- Menu buttons -->\n <ul class=\"navbar-nav mr-auto\">\n <li class=\"nav-item dropdown\">\n <a class=\"nav-link dropdown-toggle\" href=\"#\" id=\"fileDropdown\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\">\n {{ 'designer.navigation.project' | translate }}\n </a>\n <div class=\"dropdown-menu\" aria-labelledby=\"fileDropdown\">\n <a class=\"dropdown-item d-none d-md-block\" href=\"#\" (click)=\"projectNew(); (false)\"\n ><i class=\"fa fa-fw fa-file-o\" aria-hidden=\"true\"></i> {{ 'designer.navigation.project-new' | translate }}</a\n >\n <a class=\"dropdown-item\" href=\"#\" (click)=\"projectOpen(); (false)\"\n ><i class=\"fa fa-fw fa-folder-open-o\" aria-hidden=\"true\"></i> {{ 'designer.navigation.project-open' | translate }}</a\n >\n <a class=\"dropdown-item d-none d-md-block\" href=\"#\" (click)=\"projectSave(); (false)\"\n ><i class=\"fa fa-fw fa-floppy-o\" aria-hidden=\"true\"></i> {{ 'designer.navigation.project-save' | translate }}</a\n >\n <a class=\"dropdown-item d-none d-md-block\" href=\"#\" (click)=\"projectSaveAs(); (false)\"\n ><i class=\"fa fa-fw fa-floppy-o\" aria-hidden=\"true\"></i> {{ 'designer.navigation.project-save-as' | translate }}</a\n >\n <a class=\"dropdown-item d-none d-md-block\" href=\"#\" (click)=\"projectImport(); (false)\"\n ><i class=\"fa fa-fw fa-download\" aria-hidden=\"true\"></i> {{ 'designer.navigation.project-import' | translate }}</a\n >\n <a class=\"dropdown-item d-none d-md-block\" href=\"#\" (click)=\"projectExport(); (false)\"\n ><i class=\"fa fa-fw fa-external-link\" aria-hidden=\"true\"></i> {{ 'designer.navigation.project-export' | translate }}</a\n >\n </div>\n </li>\n <li class=\"nav-item dropdown d-none d-md-block\">\n <a\n class=\"nav-link dropdown-toggle\"\n href=\"#\"\n id=\"settingsDropdown\"\n data-toggle=\"dropdown\"\n aria-haspopup=\"true\"\n aria-expanded=\"false\"\n >\n {{ 'designer.navigation.settings' | translate }}\n </a>\n <div class=\"dropdown-menu\" aria-labelledby=\"settingsDropdown\">\n <a class=\"dropdown-item\" href=\"#\" (click)=\"openFixturePool(); (false)\">{{ 'designer.navigation.fixture-pool' | translate }}</a>\n <!-- <a class=\"dropdown-item\" href=\"#\">{{ 'designer.navigation.stage' | translate }}</a> -->\n </div>\n </li>\n <li class=\"nav-item dropdown d-none d-md-block\">\n <a\n class=\"nav-link dropdown-toggle\"\n href=\"#\"\n id=\"settingsDropdown\"\n data-toggle=\"dropdown\"\n aria-haspopup=\"true\"\n aria-expanded=\"false\"\n >\n {{ 'designer.navigation.help' | translate }}\n </a>\n <div class=\"dropdown-menu\" aria-labelledby=\"settingsDropdown\">\n <a class=\"dropdown-item\" href=\"#\" (click)=\"introService.reset(); (false)\">{{ 'designer.navigation.reset-intro' | translate }}</a>\n <a class=\"dropdown-item\" href=\"https://rocketshow.net/support/\" target=\"_blank\">{{\n 'designer.navigation.support' | translate\n }}</a>\n </div>\n </li>\n </ul>\n\n <ul class=\"navbar-nav\">\n @if (configService.shareAvailable) {\n <li class=\"nav-item d-none d-md-flex\" data-toggle=\"collapse\">\n <a class=\"nav-link text-primary\" (click)=\"projectShare(); (false)\" routerLinkActive=\"active\"\n ><i class=\"fa fa-share-alt\" aria-hidden=\"true\"></i> {{ 'designer.navigation.project-share' | translate }}</a\n >\n </li>\n } @if (configService.languageSwitch) {\n <li class=\"nav-item dropdown\">\n <a class=\"nav-link dropdown-toggle\" href=\"#\" id=\"settingsDropdown\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\"\n ><i class=\"fa fa-globe\" aria-hidden=\"true\"></i>\n {{ 'designer.misc.language' | translate }}\n </a>\n <div class=\"dropdown-menu dropdown-menu-right\" aria-labelledby=\"settingsDropdown\">\n <a class=\"dropdown-item\" href=\"#\" (click)=\"switchLanguage('en'); (false)\" target=\"_blank\">English</a>\n <a class=\"dropdown-item\" href=\"#\" (click)=\"switchLanguage('de'); (false)\" target=\"_blank\">Deutsch</a>\n </div>\n </li>\n } @if (configService.loginAvailable && !userService.isLoggedIn()) {\n <li class=\"nav-item\" data-toggle=\"collapse\">\n <a class=\"nav-link\" (click)=\"userRegister(); (false)\" routerLinkActive=\"active\"\n ><i class=\"fa fa-user\" aria-hidden=\"true\"></i> {{ 'designer.navigation.login' | translate }}</a\n >\n </li>\n } @if (configService.loginAvailable && userService.isLoggedIn()) {\n <li class=\"nav-item dropdown\">\n <a class=\"nav-link dropdown-toggle\" href=\"#\" id=\"settingsDropdown\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\"\n ><i class=\"fa fa-user\" aria-hidden=\"true\"></i>\n {{ userService.username }}\n </a>\n <div class=\"dropdown-menu dropdown-menu-right\" aria-labelledby=\"settingsDropdown\">\n <a class=\"dropdown-item\" href=\"#\" (click)=\"userService.logout(); (false)\" target=\"_blank\"\n ><i class=\"fa fa-sign-out\" aria-hidden=\"true\"></i> {{ 'designer.navigation.logout' | translate }}</a\n >\n </div>\n </li>\n }\n </ul>\n </nav>\n\n <!-- The main content for larger screens -->\n <div class=\"h-100 d-none d-md-block\">\n <div id=\"row1\" class=\"split split-vertical clearfix pt-3 pl-3\">\n <!-- Scenes -->\n <div id=\"scenes\" class=\"split split-horizontal h-100\">\n @if (projectService.project) {\n <lib-app-scene></lib-app-scene>\n }\n </div>\n\n <!-- Presets -->\n <div id=\"presets\" class=\"split split-horizontal h-100\">\n @if (projectService.project) {\n <lib-app-preset></lib-app-preset>\n }\n </div>\n\n <!-- 3D preview -->\n <div id=\"preview\" class=\"split split-horizontal h-100 pr-3\">\n @if (projectService.project) {\n <div class=\"card border-secondary h-100\" [class.card-intro-active]=\"introService.showStep('preview')\">\n <div class=\"card-body p-0 h-100\">\n <lib-app-preview class=\"h-100\"></lib-app-preview>\n </div>\n </div>\n }\n </div>\n </div>\n\n <div id=\"row2\" class=\"split split-vertical clearfix px-3 d-flex\" style=\"flex-direction: row\">\n <!-- Menu for the capabilities, channels, effects and settings -->\n @if (projectService.project) {\n <div class=\"col col-auto p-0\" style=\"margin-right: -1px\">\n <div class=\"nav flex-column nav-pills\" id=\"v-pills-tab\" role=\"tablist\" aria-orientation=\"vertical\">\n <a\n class=\"nav-link px-3 active\"\n (click)=\"openTab('capabilities')\"\n id=\"v-pills-capabilities-tab\"\n popover=\"{{ 'designer.misc.capabilities' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-capabilities\"\n role=\"tab\"\n aria-controls=\"v-pills-capabilities\"\n aria-selected=\"true\"\n >\n <i class=\"fa fa-bolt fa-fw\" aria-hidden=\"true\"></i>\n </a>\n <a\n class=\"nav-link px-3\"\n (click)=\"openTab('channels')\"\n id=\"v-pills-channels-tab\"\n popover=\"{{ 'designer.misc.channels' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-channels\"\n role=\"tab\"\n aria-controls=\"v-pills-channels\"\n aria-selected=\"false\"\n >\n <i class=\"fa fa-sliders fa-fw\" aria-hidden=\"true\"></i>\n </a>\n <a\n class=\"nav-link px-3\"\n (click)=\"openTab('effects')\"\n id=\"v-pills-effects-tab\"\n popover=\"{{ 'designer.misc.effects' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-effects\"\n role=\"tab\"\n aria-controls=\"v-pills-effects\"\n aria-selected=\"false\"\n >\n <i class=\"fa fa-magic fa-fw\" aria-hidden=\"true\"></i>\n </a>\n <a\n class=\"nav-link px-3\"\n (click)=\"openTab('settings')\"\n id=\"v-pills-settings-tab\"\n popover=\"{{ 'designer.misc.settings' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-settings\"\n role=\"tab\"\n aria-controls=\"v-pills-settings\"\n aria-selected=\"false\"\n style=\"border-top: 1px solid #444\"\n >\n <i class=\"fa fa-cog fa-fw\" aria-hidden=\"true\"></i>\n </a>\n </div>\n </div>\n }\n\n <div id=\"capabilities\" class=\"split split-horizontal h-100\" style=\"padding-left: 1rem\">\n @if (projectService.project) {\n <div class=\"row h-100\">\n <!-- Content for the capabilities, channels, effects and settings -->\n <div class=\"col pl-0 h-100\">\n <div class=\"tab-content h-100\" id=\"v-pills-tabContent\">\n <div class=\"tab-pane h-100 show active\" id=\"v-pills-capabilities\" role=\"tabpanel\">\n <lib-app-fixture-capability></lib-app-fixture-capability>\n </div>\n <div class=\"tab-pane h-100 show\" id=\"v-pills-channels\" role=\"tabpanel\">\n <lib-app-fixture-channel></lib-app-fixture-channel>\n </div>\n <div class=\"tab-pane h-100\" id=\"v-pills-effects\" role=\"tabpanel\" aria-labelledby=\"v-pills-profile-tab\">\n <lib-app-effect></lib-app-effect>\n </div>\n <div class=\"tab-pane h-100\" id=\"v-pills-settings\" role=\"tabpanel\" aria-labelledby=\"v-pills-home-tab\">\n <lib-app-fixture-settings></lib-app-fixture-settings>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n\n <!-- Fixtures -->\n <div id=\"fixtures\" class=\"split split-horizontal h-100\">\n @if (projectService.project) {\n <lib-app-fixture></lib-app-fixture>\n }\n </div>\n\n <!-- Master dimmer -->\n <div id=\"masterDimmer\" class=\"split split-horizontal h-100\">\n @if (projectService.project) {\n <lib-app-master-dimmer></lib-app-master-dimmer>\n }\n </div>\n </div>\n\n <!-- Timeline -->\n <div id=\"row3\" class=\"split split-vertical clearfix px-3 pb-3\" style=\"padding-bottom: 20px\">\n @if (projectService.project) {\n <lib-app-timeline></lib-app-timeline>\n }\n </div>\n </div>\n\n <!-- The components for small screens -->\n <div class=\"d-md-none p-3\">\n <div>\n @if (projectService.project) {\n <lib-app-master-dimmer></lib-app-master-dimmer>\n }\n </div>\n\n <div class=\"mt-3\">\n @if (projectService.project) {\n <lib-app-scene></lib-app-scene>\n }\n </div>\n </div>\n</div>\n\n<lib-app-intro class=\"d-none d-md-flex\"></lib-app-intro>\n", styles: [".modal-full{max-width:unset!important;margin:1.75rem!important}.modal{z-index:10001}#designer{font-size:14px}#designer .nav-link{cursor:pointer}#designer .dropdown-menu{z-index:100000}#designer .row{flex-wrap:unset}#designer .navbar-nav{flex-direction:row!important}#designer .navbar-expand-lg{flex-flow:row nowrap!important;justify-content:flex-start!important}#designer .navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem!important;padding-left:.5rem!important}#designer .list-group-item.active{color:#fff!important;background-color:#fd7e14!important;border-color:#fd7e14!important}#designer *:focus{outline:none}#designer select{font-size:.8rem;cursor:pointer}#designer input{font-size:.7rem;background-color:transparent;color:#fff;border:1px solid}#designer input,#designer select{border-color:#dee2e6}#designer .list-group-item{padding:.3rem 1.25rem;border-left:none;border-right:none}#designer .nav-pills .nav-link.active,#designer .nav-pills .show>.nav-link{background-color:#444}#designer .nav a,#designer .panel-title .btn-link{color:#fff!important}#designer .accordion-toggle .btn,#designer .accordion-toggle button{padding:0}#designer .card-body{overflow:auto;padding:.8rem}#designer .card-header{margin-bottom:0}#designer .card-header{padding:.4rem}#designer .panel-body{background-color:#303030}#designer .list-group-item.active-light{background-color:#906542;border-color:#906542}#designer .inactive-list-item{opacity:.3}#designer span.bigcheck-target{font-family:FontAwesome}#designer input[type=checkbox].bigcheck{position:relative;left:-999em}#designer input[type=checkbox].bigcheck+span.bigcheck-target:after{content:\"\\f096\"}#designer input[type=checkbox].bigcheck:checked+span.bigcheck-target:after{content:\"\\f046\"}#designer .gutter.gutter-horizontal{cursor:ew-resize}#designer .gutter.gutter-vertical{cursor:ns-resize}#designer .split-horizontal,#designer .gutter.gutter-horizontal{float:left}#designer .split-vertical,#designer .gutter.gutter-horizontal{height:100%}#designer .split{overflow-y:hidden;overflow-x:hidden}#designer .panel{background-color:transparent}#designer .slider{cursor:pointer}#designer .slider-horizontal .slider-track{height:2px!important;margin-top:-2px!important}#designer .slider-vertical .slider-track{width:2px!important;margin-left:4px!important}#designer .slider-track,#designer .slider-track-low,#designer .slider-track-high,#designer .slider-selection{background-color:#fff!important;border-radius:0!important;background-image:none!important;box-shadow:none!important}#designer .slider-handle{width:13px!important;height:13px!important;background-color:#fff!important;background-image:none!important;border:1px solid #303030}#designer .slider-vertical .slider-handle{margin-left:4px!important}#designer .slider-horizontal .slider-handle{margin-top:2px!important}#designer .slider-input{width:35px;margin-left:8px;text-align:center}#designer .slider-input-readonly{width:35px;margin-left:8px;text-align:center;color:#a9a9a9;border-color:gray}#designer .capability-container{padding:0;height:0}#designer accordion-group>div{border:none!important}#designer .popover{background-color:#fff}#designer .popover-body{color:#000}#designer .bs-popover-right .arrow:after,#designer .bs-popover-auto[x-placement^=right] .arrow:after{border-right-color:#fff}#designer .bs-popover-left .arrow:after,#designer .bs-popover-auto[x-placement^=left] .arrow:after{border-left-color:#fff}#designer .bs-popover-bottom .arrow:after,#designer .bs-popover-auto[x-placement^=bottom] .arrow:after{border-bottom-color:#fff}#designer .bs-popover-top .arrow:after,#designer .bs-popover-auto[x-placement^=top] .arrow:after{border-top-color:#fff}#designer .iro__wheel,#designer .iro__slider{cursor:pointer}#designer .pan-tilt-grid path{fill:none;stroke:#fff;stroke-width:10px}#designer .pan-tilt-grid circle{fill:#4682b4;stroke:#fff;stroke-width:3px}#designer .capability{overflow:visible}#designer .capability-deactivated{opacity:.4}#designer .wavesurfer-region{z-index:5!important}#designer .wavesurfer-region[data-region-selected=true]{z-index:6!important}#designer .wavesurfer-region[data-region-preset=true]{height:50%!important;top:50%!important}#designer .wavesurfer-region[data-region-name]:after{content:attr(data-region-name);margin-left:20px}#designer .wavesurfer-handle{width:10px!important;max-width:10px!important;border:1px solid #ddd;background:#0000001a;box-sizing:border-box;opacity:0;cursor:unset!important}#designer .wavesurfer-handle-end{margin-left:-10px}#designer .wavesurfer-region[data-region-selectable=true] .wavesurfer-handle{opacity:1;cursor:col-resize!important}#designer .wavesurfer-handle:before,#designer .wavesurfer-handle:after{content:\"\";display:block;position:absolute;z-index:1;border-top:1px solid #fff;border-bottom:1px solid #fff;height:4px;left:5%;right:5%;top:50%;transform:translateY(-50%)}#designer .wavesurfer-handle:before{margin-top:-3px}#designer timeline{overflow:scroll!important;overflow:-moz-scrollbars-none;-ms-overflow-style:none;scrollbar-width:none;cursor:s-resize}#designer timeline::-webkit-scrollbar{height:0!important}#designer cursor{top:-20px!important}#designer wave{border-right-color:#fd7e14!important;cursor:col-resize}#designer wave canvas{opacity:.2}\n"] }]
8452
- }], ctorParameters: () => [{ type: i4.TranslateService }, { type: ProjectService }, { type: ConfigService }, { type: FixturePoolService }, { type: HotkeyTargetExcludeService }, { type: i1$1.BsModalService }, { type: UserService }, { type: UserEnsureLoginService }, { type: ProjectLoadService }, { type: WarningDialogService }, { type: ErrorDialogService }, { type: FixtureService }, { type: TimelineService }, { type: IntroService }, { type: EffectService }], propDecorators: { menuHeightPx: [{
8549
+ }], ctorParameters: () => [{ type: i2.TranslateService }, { type: ProjectService }, { type: ConfigService }, { type: FixturePoolService }, { type: HotkeyTargetExcludeService }, { type: i1$1.BsModalService }, { type: UserService }, { type: UserEnsureLoginService }, { type: ProjectLoadService }, { type: WarningDialogService }, { type: ErrorDialogService }, { type: FixtureService }, { type: TimelineService }, { type: IntroService }, { type: EffectService }], propDecorators: { menuHeightPx: [{
8453
8550
  type: Input
8454
8551
  }], externalCompositionsAvailable: [{
8455
8552
  type: Input