@seatlayer/js 0.68.0 → 0.68.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +24 -20
- package/dist/index.d.cts +77 -1
- package/dist/index.d.ts +77 -1
- package/dist/index.js +23 -19
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -615,6 +615,9 @@ interface GaPromptPicker {
|
|
|
615
615
|
onGAPromptHook?: ((prompt: GAPromptRequest) => boolean | void) | undefined;
|
|
616
616
|
}
|
|
617
617
|
|
|
618
|
+
type SeatingChartBuyerView = 'map' | 'venue3d';
|
|
619
|
+
type SeatingChartNavigationMode = 'orbit' | 'pan';
|
|
620
|
+
|
|
618
621
|
/**
|
|
619
622
|
* SeatingChart — the embeddable buyer picker.
|
|
620
623
|
*
|
|
@@ -681,6 +684,10 @@ interface SeatingChartPickerState {
|
|
|
681
684
|
bestAvailable: boolean;
|
|
682
685
|
accessibilityFilter: boolean;
|
|
683
686
|
limitedViewFilter: boolean;
|
|
687
|
+
/** Real lazy-loaded WebGL venue view, not the retired isometric projection. */
|
|
688
|
+
venue3d: boolean;
|
|
689
|
+
/** Authored or chart-derived view-from-seat panorama. */
|
|
690
|
+
seatView: boolean;
|
|
684
691
|
};
|
|
685
692
|
catalog: {
|
|
686
693
|
categories: Array<{
|
|
@@ -723,6 +730,9 @@ interface SeatingChartPickerState {
|
|
|
723
730
|
focusedSectionId: string | null;
|
|
724
731
|
focusedSection: SectionSummary | null;
|
|
725
732
|
viewMode: RendererViewMode;
|
|
733
|
+
buyerView: SeatingChartBuyerView;
|
|
734
|
+
view3dTargetSeatId: string | null;
|
|
735
|
+
view3dNavigationMode: SeatingChartNavigationMode;
|
|
726
736
|
colorblindSafe: boolean;
|
|
727
737
|
categoryFilter: string[] | null;
|
|
728
738
|
accessibilityFilter: string[] | null;
|
|
@@ -820,6 +830,12 @@ interface SeatingChartOptions {
|
|
|
820
830
|
* real 3D venue view (`setBuyerView('venue3d')`); they remain accepted for
|
|
821
831
|
* source compatibility and will be removed in the next major. Use `'flat'`. */
|
|
822
832
|
initialView?: RendererViewMode;
|
|
833
|
+
/** Offer the real, lazy-loaded interactive venue view. Default true. */
|
|
834
|
+
enable3D?: boolean;
|
|
835
|
+
/** Offer authored/generated view-from-seat inspection. Default true. */
|
|
836
|
+
enableSeatView?: boolean;
|
|
837
|
+
/** Optional device-specific ceiling for offering the venue WebGL scene. */
|
|
838
|
+
max3DSeats?: number;
|
|
823
839
|
/**
|
|
824
840
|
* Built-in seat tooltip on mouse hover (seat · category · price · status).
|
|
825
841
|
* Rendered inside the widget so every host gets it; default true. Turn off
|
|
@@ -906,8 +922,13 @@ interface SeatingChartOptions {
|
|
|
906
922
|
onSalesClosed?: () => void;
|
|
907
923
|
/** A programmatic/native map-control action changed serializable map state. */
|
|
908
924
|
onMapStateChange?: () => void;
|
|
909
|
-
/**
|
|
925
|
+
/** rAF-coalesced camera-frame signal for in-page overlays; not native state. */
|
|
910
926
|
onViewChange?: () => void;
|
|
927
|
+
/** Real buyer-view transitions and 3D camera targets. */
|
|
928
|
+
onBuyerViewChange?: (state: {
|
|
929
|
+
view: SeatingChartBuyerView;
|
|
930
|
+
seatId?: string;
|
|
931
|
+
}) => void;
|
|
911
932
|
/**
|
|
912
933
|
* Non-blocking, localized selection advice — currently the orphan-seat hint
|
|
913
934
|
* (the selection would strand a single free seat between taken neighbors).
|
|
@@ -922,6 +943,13 @@ declare class SeatingChart {
|
|
|
922
943
|
readonly publicKey?: string;
|
|
923
944
|
private mount;
|
|
924
945
|
private hostEl;
|
|
946
|
+
/**
|
|
947
|
+
* Native hosts can render a Flutter/Swift/Kotlin decision surface above this
|
|
948
|
+
* DOM tree. UIKit platform views still participate in hit testing beneath a
|
|
949
|
+
* composited native overlay, so the runtime must be able to make its own DOM
|
|
950
|
+
* inert rather than relying on the host's visual stacking alone.
|
|
951
|
+
*/
|
|
952
|
+
private interactionEnabled_;
|
|
925
953
|
/** The organizer's language for this event, learned when the chart resolves. */
|
|
926
954
|
private eventLocale;
|
|
927
955
|
private rendered;
|
|
@@ -933,6 +961,8 @@ declare class SeatingChart {
|
|
|
933
961
|
private accessibilityFilter_;
|
|
934
962
|
private hideLimitedView_;
|
|
935
963
|
private focusedSection_;
|
|
964
|
+
/** Last rung already exposed to native chrome; raw camera frames stay in-canvas. */
|
|
965
|
+
private lastReportedViewRung_;
|
|
936
966
|
private accessState_;
|
|
937
967
|
private tipEl;
|
|
938
968
|
private tipPos;
|
|
@@ -940,8 +970,18 @@ declare class SeatingChart {
|
|
|
940
970
|
/** Null for the ordinary public chart — the tokenless path is untouched. */
|
|
941
971
|
private readonly access;
|
|
942
972
|
private readonly api;
|
|
973
|
+
private readonly buyerAssetUrls;
|
|
974
|
+
private readonly immersive;
|
|
943
975
|
private realtime;
|
|
944
976
|
constructor(options: SeatingChartOptions);
|
|
977
|
+
/**
|
|
978
|
+
* Camera x/y/scale is renderer-local and deliberately absent from the native
|
|
979
|
+
* picker snapshot. Keep pan and pinch frames on the canvas; only a semantic
|
|
980
|
+
* rung transition needs to wake native chrome.
|
|
981
|
+
*/
|
|
982
|
+
private handleViewChange;
|
|
983
|
+
/** Record the current rung before publishing an explicit state mutation. */
|
|
984
|
+
private notifyMapStateChange;
|
|
945
985
|
/** Fetch the chart, mount the renderer, seed statuses and go live. Idempotent. */
|
|
946
986
|
render(): Promise<this>;
|
|
947
987
|
/**
|
|
@@ -1125,6 +1165,28 @@ declare class SeatingChart {
|
|
|
1125
1165
|
zoomOut(): void;
|
|
1126
1166
|
/** Reset the camera so the whole chart fits the container. */
|
|
1127
1167
|
zoomToFit(): void;
|
|
1168
|
+
/** Enter or leave the same real lazy-loaded venue scene as SeatPicker. */
|
|
1169
|
+
setBuyerView(view: SeatingChartBuyerView, options?: {
|
|
1170
|
+
flyToSeatId?: string;
|
|
1171
|
+
resetView?: boolean;
|
|
1172
|
+
}): Promise<void>;
|
|
1173
|
+
getBuyerView(): SeatingChartBuyerView;
|
|
1174
|
+
/** Open an authored or chart-derived 360° view for one physical seat. */
|
|
1175
|
+
openSeatView(seatId: string): Promise<void>;
|
|
1176
|
+
/** Explicit Rotate / Move control for native and custom picker chrome. */
|
|
1177
|
+
setVenue3DNavigationMode(mode: SeatingChartNavigationMode): void;
|
|
1178
|
+
/**
|
|
1179
|
+
* Enable or suppress all buyer input inside this chart without unmounting it.
|
|
1180
|
+
*
|
|
1181
|
+
* Native SDKs use this while a native confirmation, quantity prompt, loading
|
|
1182
|
+
* surface or error surface owns the chart area. Disabling input in the DOM is
|
|
1183
|
+
* intentional: an iOS WKWebView can receive the same physical tap beneath a
|
|
1184
|
+
* Flutter overlay even when the Flutter widget is wrapped in IgnorePointer.
|
|
1185
|
+
* Programmatic bridge commands continue to work, so a prompt can still open
|
|
1186
|
+
* view-from-seat or 3D and then re-enable interaction after the handoff.
|
|
1187
|
+
*/
|
|
1188
|
+
setInteractionEnabled(enabled: boolean): void;
|
|
1189
|
+
private applyInteractionState;
|
|
1128
1190
|
/** Release the current hold (if any). No-op when nothing is held. */
|
|
1129
1191
|
release(): Promise<void>;
|
|
1130
1192
|
/** Release selected labels from the current hold while keeping the remainder. */
|
|
@@ -2241,6 +2303,7 @@ declare class SeatPicker implements GaPromptPicker {
|
|
|
2241
2303
|
private tipPos;
|
|
2242
2304
|
/** True while a TAPPED seat card is held open (touch has no hover to lose). */
|
|
2243
2305
|
private tipPinned;
|
|
2306
|
+
private tipMarkedHoverLabel;
|
|
2244
2307
|
private lastPointerType;
|
|
2245
2308
|
private confirmEl;
|
|
2246
2309
|
private confirmSeat;
|
|
@@ -2751,6 +2814,8 @@ declare class SeatPicker implements GaPromptPicker {
|
|
|
2751
2814
|
private nightStripFor;
|
|
2752
2815
|
/** Close a tapped-open card. Safe to call when nothing is pinned. */
|
|
2753
2816
|
private unpinTooltip;
|
|
2817
|
+
/** A press outside the card dismisses it; its own controls must reach click. */
|
|
2818
|
+
private handleMapPointerDown;
|
|
2754
2819
|
private updateTooltip;
|
|
2755
2820
|
/**
|
|
2756
2821
|
* Push the wrapper's current seat marks at the renderer.
|
|
@@ -3008,6 +3073,7 @@ interface PerformanceGroupDescriptor {
|
|
|
3008
3073
|
venue: string;
|
|
3009
3074
|
timezone: string | null;
|
|
3010
3075
|
inventoryModelVersion: 2;
|
|
3076
|
+
inclusionMode?: 'fixed' | 'flexible_dates';
|
|
3011
3077
|
performanceCount: number;
|
|
3012
3078
|
/** Present when the server versions the inclusion set. See {@link PerformanceGroupAvailability}. */
|
|
3013
3079
|
revision?: string;
|
|
@@ -3103,6 +3169,8 @@ interface PerformanceGroupCheckoutHandoff {
|
|
|
3103
3169
|
expiresAt: number;
|
|
3104
3170
|
performanceGroup: PerformanceGroupDescriptor;
|
|
3105
3171
|
selectionMode: PerformanceGroupSelectionMode;
|
|
3172
|
+
/** Performances actually included in this hold (all members for fixed groups). */
|
|
3173
|
+
performanceKeys: string[];
|
|
3106
3174
|
/** Logical booking identities only. Re-inspect the opaque hold on your server. */
|
|
3107
3175
|
seatLabels: string[];
|
|
3108
3176
|
/** Present for per-performance selection. Prices and child hold IDs remain server-only. */
|
|
@@ -3221,6 +3289,9 @@ declare class PerformanceGroupPicker {
|
|
|
3221
3289
|
private progressHost;
|
|
3222
3290
|
private legendHost;
|
|
3223
3291
|
private paneHost;
|
|
3292
|
+
private datesSummaryHost;
|
|
3293
|
+
private datesCardsHost;
|
|
3294
|
+
private resettingFlexibleSelection;
|
|
3224
3295
|
/** Labels pushed at the renderer on the last pull, so departures clear. */
|
|
3225
3296
|
private markedLabels;
|
|
3226
3297
|
private holdTicker;
|
|
@@ -3315,6 +3386,11 @@ declare class PerformanceGroupPicker {
|
|
|
3315
3386
|
* the buyer could reasonably hold us to.
|
|
3316
3387
|
*/
|
|
3317
3388
|
private heldTotal;
|
|
3389
|
+
private includedPerformances;
|
|
3390
|
+
/** Keep the persistent date promise aligned with the subset used by HOLD. */
|
|
3391
|
+
private syncIncludedDates;
|
|
3392
|
+
/** Turn one two-tone seat into a normal selection without changing charts. */
|
|
3393
|
+
private selectPartialSeat;
|
|
3318
3394
|
/** One tick a second while a hold is live, so the countdown line is true. */
|
|
3319
3395
|
private syncHoldTicker;
|
|
3320
3396
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -615,6 +615,9 @@ interface GaPromptPicker {
|
|
|
615
615
|
onGAPromptHook?: ((prompt: GAPromptRequest) => boolean | void) | undefined;
|
|
616
616
|
}
|
|
617
617
|
|
|
618
|
+
type SeatingChartBuyerView = 'map' | 'venue3d';
|
|
619
|
+
type SeatingChartNavigationMode = 'orbit' | 'pan';
|
|
620
|
+
|
|
618
621
|
/**
|
|
619
622
|
* SeatingChart — the embeddable buyer picker.
|
|
620
623
|
*
|
|
@@ -681,6 +684,10 @@ interface SeatingChartPickerState {
|
|
|
681
684
|
bestAvailable: boolean;
|
|
682
685
|
accessibilityFilter: boolean;
|
|
683
686
|
limitedViewFilter: boolean;
|
|
687
|
+
/** Real lazy-loaded WebGL venue view, not the retired isometric projection. */
|
|
688
|
+
venue3d: boolean;
|
|
689
|
+
/** Authored or chart-derived view-from-seat panorama. */
|
|
690
|
+
seatView: boolean;
|
|
684
691
|
};
|
|
685
692
|
catalog: {
|
|
686
693
|
categories: Array<{
|
|
@@ -723,6 +730,9 @@ interface SeatingChartPickerState {
|
|
|
723
730
|
focusedSectionId: string | null;
|
|
724
731
|
focusedSection: SectionSummary | null;
|
|
725
732
|
viewMode: RendererViewMode;
|
|
733
|
+
buyerView: SeatingChartBuyerView;
|
|
734
|
+
view3dTargetSeatId: string | null;
|
|
735
|
+
view3dNavigationMode: SeatingChartNavigationMode;
|
|
726
736
|
colorblindSafe: boolean;
|
|
727
737
|
categoryFilter: string[] | null;
|
|
728
738
|
accessibilityFilter: string[] | null;
|
|
@@ -820,6 +830,12 @@ interface SeatingChartOptions {
|
|
|
820
830
|
* real 3D venue view (`setBuyerView('venue3d')`); they remain accepted for
|
|
821
831
|
* source compatibility and will be removed in the next major. Use `'flat'`. */
|
|
822
832
|
initialView?: RendererViewMode;
|
|
833
|
+
/** Offer the real, lazy-loaded interactive venue view. Default true. */
|
|
834
|
+
enable3D?: boolean;
|
|
835
|
+
/** Offer authored/generated view-from-seat inspection. Default true. */
|
|
836
|
+
enableSeatView?: boolean;
|
|
837
|
+
/** Optional device-specific ceiling for offering the venue WebGL scene. */
|
|
838
|
+
max3DSeats?: number;
|
|
823
839
|
/**
|
|
824
840
|
* Built-in seat tooltip on mouse hover (seat · category · price · status).
|
|
825
841
|
* Rendered inside the widget so every host gets it; default true. Turn off
|
|
@@ -906,8 +922,13 @@ interface SeatingChartOptions {
|
|
|
906
922
|
onSalesClosed?: () => void;
|
|
907
923
|
/** A programmatic/native map-control action changed serializable map state. */
|
|
908
924
|
onMapStateChange?: () => void;
|
|
909
|
-
/**
|
|
925
|
+
/** rAF-coalesced camera-frame signal for in-page overlays; not native state. */
|
|
910
926
|
onViewChange?: () => void;
|
|
927
|
+
/** Real buyer-view transitions and 3D camera targets. */
|
|
928
|
+
onBuyerViewChange?: (state: {
|
|
929
|
+
view: SeatingChartBuyerView;
|
|
930
|
+
seatId?: string;
|
|
931
|
+
}) => void;
|
|
911
932
|
/**
|
|
912
933
|
* Non-blocking, localized selection advice — currently the orphan-seat hint
|
|
913
934
|
* (the selection would strand a single free seat between taken neighbors).
|
|
@@ -922,6 +943,13 @@ declare class SeatingChart {
|
|
|
922
943
|
readonly publicKey?: string;
|
|
923
944
|
private mount;
|
|
924
945
|
private hostEl;
|
|
946
|
+
/**
|
|
947
|
+
* Native hosts can render a Flutter/Swift/Kotlin decision surface above this
|
|
948
|
+
* DOM tree. UIKit platform views still participate in hit testing beneath a
|
|
949
|
+
* composited native overlay, so the runtime must be able to make its own DOM
|
|
950
|
+
* inert rather than relying on the host's visual stacking alone.
|
|
951
|
+
*/
|
|
952
|
+
private interactionEnabled_;
|
|
925
953
|
/** The organizer's language for this event, learned when the chart resolves. */
|
|
926
954
|
private eventLocale;
|
|
927
955
|
private rendered;
|
|
@@ -933,6 +961,8 @@ declare class SeatingChart {
|
|
|
933
961
|
private accessibilityFilter_;
|
|
934
962
|
private hideLimitedView_;
|
|
935
963
|
private focusedSection_;
|
|
964
|
+
/** Last rung already exposed to native chrome; raw camera frames stay in-canvas. */
|
|
965
|
+
private lastReportedViewRung_;
|
|
936
966
|
private accessState_;
|
|
937
967
|
private tipEl;
|
|
938
968
|
private tipPos;
|
|
@@ -940,8 +970,18 @@ declare class SeatingChart {
|
|
|
940
970
|
/** Null for the ordinary public chart — the tokenless path is untouched. */
|
|
941
971
|
private readonly access;
|
|
942
972
|
private readonly api;
|
|
973
|
+
private readonly buyerAssetUrls;
|
|
974
|
+
private readonly immersive;
|
|
943
975
|
private realtime;
|
|
944
976
|
constructor(options: SeatingChartOptions);
|
|
977
|
+
/**
|
|
978
|
+
* Camera x/y/scale is renderer-local and deliberately absent from the native
|
|
979
|
+
* picker snapshot. Keep pan and pinch frames on the canvas; only a semantic
|
|
980
|
+
* rung transition needs to wake native chrome.
|
|
981
|
+
*/
|
|
982
|
+
private handleViewChange;
|
|
983
|
+
/** Record the current rung before publishing an explicit state mutation. */
|
|
984
|
+
private notifyMapStateChange;
|
|
945
985
|
/** Fetch the chart, mount the renderer, seed statuses and go live. Idempotent. */
|
|
946
986
|
render(): Promise<this>;
|
|
947
987
|
/**
|
|
@@ -1125,6 +1165,28 @@ declare class SeatingChart {
|
|
|
1125
1165
|
zoomOut(): void;
|
|
1126
1166
|
/** Reset the camera so the whole chart fits the container. */
|
|
1127
1167
|
zoomToFit(): void;
|
|
1168
|
+
/** Enter or leave the same real lazy-loaded venue scene as SeatPicker. */
|
|
1169
|
+
setBuyerView(view: SeatingChartBuyerView, options?: {
|
|
1170
|
+
flyToSeatId?: string;
|
|
1171
|
+
resetView?: boolean;
|
|
1172
|
+
}): Promise<void>;
|
|
1173
|
+
getBuyerView(): SeatingChartBuyerView;
|
|
1174
|
+
/** Open an authored or chart-derived 360° view for one physical seat. */
|
|
1175
|
+
openSeatView(seatId: string): Promise<void>;
|
|
1176
|
+
/** Explicit Rotate / Move control for native and custom picker chrome. */
|
|
1177
|
+
setVenue3DNavigationMode(mode: SeatingChartNavigationMode): void;
|
|
1178
|
+
/**
|
|
1179
|
+
* Enable or suppress all buyer input inside this chart without unmounting it.
|
|
1180
|
+
*
|
|
1181
|
+
* Native SDKs use this while a native confirmation, quantity prompt, loading
|
|
1182
|
+
* surface or error surface owns the chart area. Disabling input in the DOM is
|
|
1183
|
+
* intentional: an iOS WKWebView can receive the same physical tap beneath a
|
|
1184
|
+
* Flutter overlay even when the Flutter widget is wrapped in IgnorePointer.
|
|
1185
|
+
* Programmatic bridge commands continue to work, so a prompt can still open
|
|
1186
|
+
* view-from-seat or 3D and then re-enable interaction after the handoff.
|
|
1187
|
+
*/
|
|
1188
|
+
setInteractionEnabled(enabled: boolean): void;
|
|
1189
|
+
private applyInteractionState;
|
|
1128
1190
|
/** Release the current hold (if any). No-op when nothing is held. */
|
|
1129
1191
|
release(): Promise<void>;
|
|
1130
1192
|
/** Release selected labels from the current hold while keeping the remainder. */
|
|
@@ -2241,6 +2303,7 @@ declare class SeatPicker implements GaPromptPicker {
|
|
|
2241
2303
|
private tipPos;
|
|
2242
2304
|
/** True while a TAPPED seat card is held open (touch has no hover to lose). */
|
|
2243
2305
|
private tipPinned;
|
|
2306
|
+
private tipMarkedHoverLabel;
|
|
2244
2307
|
private lastPointerType;
|
|
2245
2308
|
private confirmEl;
|
|
2246
2309
|
private confirmSeat;
|
|
@@ -2751,6 +2814,8 @@ declare class SeatPicker implements GaPromptPicker {
|
|
|
2751
2814
|
private nightStripFor;
|
|
2752
2815
|
/** Close a tapped-open card. Safe to call when nothing is pinned. */
|
|
2753
2816
|
private unpinTooltip;
|
|
2817
|
+
/** A press outside the card dismisses it; its own controls must reach click. */
|
|
2818
|
+
private handleMapPointerDown;
|
|
2754
2819
|
private updateTooltip;
|
|
2755
2820
|
/**
|
|
2756
2821
|
* Push the wrapper's current seat marks at the renderer.
|
|
@@ -3008,6 +3073,7 @@ interface PerformanceGroupDescriptor {
|
|
|
3008
3073
|
venue: string;
|
|
3009
3074
|
timezone: string | null;
|
|
3010
3075
|
inventoryModelVersion: 2;
|
|
3076
|
+
inclusionMode?: 'fixed' | 'flexible_dates';
|
|
3011
3077
|
performanceCount: number;
|
|
3012
3078
|
/** Present when the server versions the inclusion set. See {@link PerformanceGroupAvailability}. */
|
|
3013
3079
|
revision?: string;
|
|
@@ -3103,6 +3169,8 @@ interface PerformanceGroupCheckoutHandoff {
|
|
|
3103
3169
|
expiresAt: number;
|
|
3104
3170
|
performanceGroup: PerformanceGroupDescriptor;
|
|
3105
3171
|
selectionMode: PerformanceGroupSelectionMode;
|
|
3172
|
+
/** Performances actually included in this hold (all members for fixed groups). */
|
|
3173
|
+
performanceKeys: string[];
|
|
3106
3174
|
/** Logical booking identities only. Re-inspect the opaque hold on your server. */
|
|
3107
3175
|
seatLabels: string[];
|
|
3108
3176
|
/** Present for per-performance selection. Prices and child hold IDs remain server-only. */
|
|
@@ -3221,6 +3289,9 @@ declare class PerformanceGroupPicker {
|
|
|
3221
3289
|
private progressHost;
|
|
3222
3290
|
private legendHost;
|
|
3223
3291
|
private paneHost;
|
|
3292
|
+
private datesSummaryHost;
|
|
3293
|
+
private datesCardsHost;
|
|
3294
|
+
private resettingFlexibleSelection;
|
|
3224
3295
|
/** Labels pushed at the renderer on the last pull, so departures clear. */
|
|
3225
3296
|
private markedLabels;
|
|
3226
3297
|
private holdTicker;
|
|
@@ -3315,6 +3386,11 @@ declare class PerformanceGroupPicker {
|
|
|
3315
3386
|
* the buyer could reasonably hold us to.
|
|
3316
3387
|
*/
|
|
3317
3388
|
private heldTotal;
|
|
3389
|
+
private includedPerformances;
|
|
3390
|
+
/** Keep the persistent date promise aligned with the subset used by HOLD. */
|
|
3391
|
+
private syncIncludedDates;
|
|
3392
|
+
/** Turn one two-tone seat into a normal selection without changing charts. */
|
|
3393
|
+
private selectPartialSeat;
|
|
3318
3394
|
/** One tick a second while a hold is live, so the countdown line is true. */
|
|
3319
3395
|
private syncHoldTicker;
|
|
3320
3396
|
/**
|