@ruc-lib/screen-recorder 2.9.2 → 3.1.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.
@@ -1 +1 @@
1
- {"version":3,"file":"ruc-lib-screen-recorder.mjs","sources":["../../../../../libs/ruclib/screen-recorder/src/lib/models/screen-recorder.models.ts","../../../../../libs/ruclib/screen-recorder/src/lib/screen-recorder/screen-recorder-constant.ts","../../../../../libs/ruclib/screen-recorder/src/lib/services/screen-recorder.service.ts","../../../../../libs/ruclib/screen-recorder/src/lib/screen-recorder/screen-recorder.component.ts","../../../../../libs/ruclib/screen-recorder/src/lib/screen-recorder/screen-recorder.component.html","../../../../../libs/ruclib/screen-recorder/src/lib/ruclib-screen-recorder.module.ts","../../../../../libs/ruclib/screen-recorder/src/ruc-lib-screen-recorder.ts"],"sourcesContent":["export enum ScreenRecorderPosition {\r\n Top = 'top',\r\n Bottom = 'bottom',\r\n Left = 'left',\r\n Right = 'right',\r\n }\r\n \r\n export enum DisplayFormat {\r\n Icon = 'icon',\r\n Text = 'text',\r\n }\r\n \r\n export enum RecordingState {\r\n Idle = 'idle',\r\n Recording = 'recording',\r\n Paused = 'paused',\r\n Stopped = 'stopped',\r\n }\r\n \r\n export interface ScreenRecorderIcons {\r\n record?: string; // Default: '●' (filled circle) or a material icon class\r\n recordWithAudio?: string; // Alternative if specific icon for \"record with audio\" is needed\r\n recordWithoutAudio?: string; // Alternative if specific icon for \"record without audio\" is needed\r\n stop?: string; // Default: '■' (filled square) or a material icon class\r\n pause?: string; // Default: '❚❚' (pause symbol) or a material icon class\r\n resume?: string; // Default: '►' (play symbol) or a material icon class\r\n play?: string; // Default: '►' (play symbol) or a material icon class\r\n download?: string; // Default: '💾' (floppy disk) or a material icon class\r\n audioOn?: string; // Default: '🔊' (speaker high volume) or a material icon class\r\n audioOff?: string; // Default: '🔇' (muted speaker) or a material icon class\r\n }\r\n \r\n export interface ScreenRecorderOptions {\r\n position?: ScreenRecorderPosition;\r\n displayFormat?: DisplayFormat;\r\n showAudioToggle?: boolean;\r\n defaultAudioState?: boolean; // true for audio on, false for audio off\r\n downloadFileName?: string;\r\n icons?: ScreenRecorderIcons; // For custom icons (e.g., CSS classes for icon fonts)\r\n showTimer?: boolean;\r\n showPauseResume?: boolean;\r\n showPlaybackControls?: boolean; // To show/hide the video player preview\r\n showDownloadButton?: boolean;\r\n useUTCForTimer?: boolean;\r\n /* For specific area: getDisplayMedia allows user to choose window/tab/screen.\r\n If a more specific crop is needed, it's outside standard Web API scope.\r\n This option implies we ensure the browser's picker is used.\r\n */\r\n allowSpecificAreaSelection?: boolean;\r\n // Accessibility related texts\r\n accessibilityLabels?: {\r\n recordButton?: string;\r\n stopButton?: string;\r\n pauseButton?: string;\r\n resumeButton?: string;\r\n audioToggleButton?: string;\r\n downloadButton?: string;\r\n playbackVideo?: string;\r\n };\r\n }\r\n ","import { Injectable } from \"@angular/core\";\r\nimport {\r\n ScreenRecorderOptions,\r\n ScreenRecorderPosition,\r\n DisplayFormat,\r\n RecordingState,\r\n ScreenRecorderIcons,\r\n} from '../models/screen-recorder.models';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class ScreenRecorderConstants{\r\n constructor(){\r\n\r\n }\r\n public DEFAULT_ICONS: ScreenRecorderIcons = {\r\n record: 'fiber_manual_record', // Material Icon name\r\n stop: 'stop',\r\n pause: 'pause',\r\n resume: 'play_arrow',\r\n play: 'play_circle_filled',\r\n download: 'download',\r\n audioOn: 'volume_up',\r\n audioOff: 'volume_off',\r\n };\r\n \r\n public DEFAULT_LABELS = {\r\n recordButton: 'Start Recording',\r\n stopButton: 'Stop Recording',\r\n pauseButton: 'Pause Recording',\r\n resumeButton: 'Resume Recording',\r\n audioToggleButton: 'Toggle Audio',\r\n downloadButton: 'Download Recording',\r\n playbackVideo: 'Screen Recording Playback',\r\n };\r\n\r\n public INACTIVE = 'inactive';\r\n\r\n public AUDIO_ON = 'Audio ON';\r\n public AUDIO_OFF = 'Audio OFF';\r\n\r\n public RECORDING_IN_PROGRESS_ERROR = 'Recording is already in progress.';\r\n public FAILED_TO_GET_DISPLAY_MEDIA_STREAM_ERROR = 'Failed to get display media stream';\r\n public NO_SUPPORT_MIME = 'No supported MIME type found for MediaRecorder.';\r\n public NO_RECORDING_DOWNLOAD = 'No recording available to download.';\r\n public MEDIA_ERROR = 'MediaRecorder error';\r\n public PERMISSION_DENIED = \"Error starting screen recording: NotAllowedError - Permission denied\";\r\n public NO_SUPPORT = 'Screen recording is not supported in this browser.';\r\n\r\n}","import { Injectable } from '@angular/core';\r\nimport { BehaviorSubject, Observable, Subject, timer } from 'rxjs';\r\nimport { takeWhile, tap } from 'rxjs/operators';\r\nimport { RecordingState } from '../models/screen-recorder.models';\r\nimport { ScreenRecorderConstants } from '../screen-recorder/screen-recorder-constant';\r\n@Injectable({\r\n providedIn: 'root', // Or provide in your module if preferred\r\n})\r\nexport class ScreenRecorderService {\r\n private stream: MediaStream | null = null;\r\n private mediaRecorder: MediaRecorder | null = null;\r\n private recordedBlobs: Blob[] = [];\r\n private timerSubscription: any;\r\n private currentRecordedTime: number = 0;\r\n\r\n private readonly recordingStateSubject = new BehaviorSubject<RecordingState>(RecordingState.Idle);\r\n readonly recordingState$: Observable<RecordingState> = this.recordingStateSubject.asObservable();\r\n\r\n private readonly recordedTimeSubject = new BehaviorSubject<number>(0);\r\n readonly recordedTime$: Observable<number> = this.recordedTimeSubject.asObservable();\r\n\r\n private readonly recordedUrlSubject = new BehaviorSubject<string | null>(null);\r\n readonly recordedUrl$: Observable<string | null> = this.recordedUrlSubject.asObservable();\r\n\r\n private readonly recordingTimestampSubject = new BehaviorSubject<string>('');\r\n readonly recordingTimestamp$: Observable<string> = this.recordingTimestampSubject.asObservable();\r\n\r\n private readonly errorSubject = new Subject<string>();\r\n readonly error$: Observable<string> = this.errorSubject.asObservable();\r\n\r\n constructor(public screenRecordingConstant: ScreenRecorderConstants) { }\r\n\r\n /**\r\n * Starts the screen recording with optional audio\r\n * \r\n * @param options - Configuration options for recording\r\n * @param options.audio - Whether to include audio in the recording\r\n * \r\n * @throws Error if recording is already in progress or if media access is denied\r\n * @returns Promise<void>\r\n */\r\n async startRecording(options: { audio: boolean }): Promise<void> {\r\n\r\n if (this.recordingStateSubject.value === RecordingState.Recording || this.recordingStateSubject.value === RecordingState.Paused) {\r\n this.handleError(this.screenRecordingConstant.RECORDING_IN_PROGRESS_ERROR);\r\n return;\r\n }\r\n\r\n this.cleanupPreviousRecording();\r\n\r\n try {\r\n // The browser's native picker handles \"specific area\" selection (window, tab, screen).\r\n const displayStream = await navigator.mediaDevices.getDisplayMedia({\r\n video: true\r\n });\r\n\r\n // If audio is enabled, get the audio stream\r\n let audioStream: MediaStream | null = null;\r\n if (options.audio) {\r\n audioStream = await navigator.mediaDevices.getUserMedia({\r\n audio: {\r\n echoCancellation: true,\r\n noiseSuppression: true,\r\n sampleRate: 44100\r\n }\r\n });\r\n }\r\n\r\n // Combine the streams if audio is enabled\r\n if (audioStream) {\r\n this.stream = new MediaStream([...displayStream.getTracks(), ...audioStream.getTracks()]);\r\n } else {\r\n this.stream = displayStream;\r\n }\r\n\r\n // Listen for when the user stops sharing via browser UI\r\n this.stream.getVideoTracks()[0].onended = () => {\r\n if (this.recordingStateSubject.value === RecordingState.Recording || this.recordingStateSubject.value === RecordingState.Paused) {\r\n this.stopRecordingInternal();\r\n }\r\n };\r\n\r\n // Handle errors\r\n if (!this.stream) {\r\n this.handleError(this.screenRecordingConstant.FAILED_TO_GET_DISPLAY_MEDIA_STREAM_ERROR);\r\n return;\r\n }\r\n\r\n // Set recording timestamp\r\n const now = new Date();\r\n const timestamp = now.toLocaleString('en-IN', {\r\n year: 'numeric',\r\n month: '2-digit',\r\n day: '2-digit',\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n hour12: true\r\n });\r\n this.recordingTimestampSubject.next(timestamp);\r\n\r\n\r\n this.recordedBlobs = [];\r\n const mimeType = this.getSupportedMimeType();\r\n if (!mimeType) {\r\n this.handleError(this.screenRecordingConstant.NO_SUPPORT_MIME);\r\n this.stream?.getTracks().forEach(track => track.stop());\r\n this.stream = null;\r\n return;\r\n }\r\n\r\n // Create a canvas for timestamp overlay\r\n const canvas = document.createElement('canvas');\r\n const videoTrack = this.stream?.getVideoTracks()[0];\r\n if (videoTrack) {\r\n const video = document.createElement('video');\r\n video.srcObject = this.stream;\r\n\r\n // Wait for video to load metadata\r\n video.onloadedmetadata = () => {\r\n canvas.width = video.videoWidth;\r\n canvas.height = video.videoHeight;\r\n const ctx = canvas.getContext('2d');\r\n if (ctx) {\r\n // Draw video frame\r\n ctx.drawImage(video, 0, 0);\r\n\r\n // Draw timestamp\r\n ctx.font = '16px Arial';\r\n ctx.fillStyle = 'white';\r\n ctx.textAlign = 'right';\r\n ctx.textBaseline = 'top';\r\n ctx.fillText(`Recorded on: ${this.recordingTimestampSubject.value}`, canvas.width - 10, 10);\r\n }\r\n };\r\n }\r\n\r\n // Create a new stream with the canvas\r\n const canvasStream = canvas.captureStream();\r\n const combinedStream = new MediaStream([...this.stream?.getTracks() ?? [], canvasStream.getVideoTracks()[0]]);\r\n\r\n this.mediaRecorder = new MediaRecorder(combinedStream, { mimeType });\r\n\r\n this.mediaRecorder.ondataavailable = (event) => {\r\n if (event.data && event.data.size > 0) {\r\n this.recordedBlobs.push(event.data);\r\n }\r\n };\r\n\r\n this.mediaRecorder.onstop = () => {\r\n const superBuffer = new Blob(this.recordedBlobs, { type: mimeType });\r\n const url = window.URL.createObjectURL(superBuffer);\r\n this.recordedUrlSubject.next(url);\r\n this.recordingStateSubject.next(RecordingState.Stopped);\r\n this.stopTimer();\r\n\r\n };\r\n\r\n this.mediaRecorder.onerror = (event: Event) => {\r\n const errorEvent = event as ErrorEvent; // More specific type if available\r\n let message = this.screenRecordingConstant.MEDIA_ERROR;\r\n if (errorEvent.error && errorEvent.error.name) {\r\n message += `: ${errorEvent.error.name}`;\r\n if (errorEvent.error.message) message += ` - ${errorEvent.error.message}`;\r\n }\r\n this.handleError(message);\r\n this.recordingStateSubject.next(RecordingState.Idle);\r\n this.stopTimer();\r\n };\r\n\r\n this.mediaRecorder.start(); // Start recording\r\n this.recordingStateSubject.next(RecordingState.Recording);\r\n this.startTimer();\r\n } catch (err: any) {\r\n this.handleError(`Error starting screen recording: ${err.name} - ${err.message}`);\r\n this.recordingStateSubject.next(RecordingState.Idle);\r\n }\r\n }\r\n\r\n /**\r\n * Gets the first supported MIME type for MediaRecorder\r\n * \r\n * @returns string|null - The supported MIME type or null if none found\r\n */\r\n private getSupportedMimeType(): string | null {\r\n const mimeTypes = [\r\n 'video/webm;codecs=vp9,opus',\r\n 'video/webm;codecs=vp8,opus',\r\n 'video/webm;codecs=h264,opus',\r\n 'video/mp4;codecs=h264,aac', // MP4 might have broader compatibility but less browser support for recording\r\n 'video/webm',\r\n ];\r\n for (const mimeType of mimeTypes) {\r\n if (MediaRecorder.isTypeSupported(mimeType)) {\r\n return mimeType;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Internal method to stop the recording process\r\n * \r\n * @private\r\n * @returns void\r\n */\r\n private stopRecordingInternal(): void {\r\n if (this.mediaRecorder && (this.recordingStateSubject.value === RecordingState.Recording || this.recordingStateSubject.value === RecordingState.Paused)) {\r\n this.mediaRecorder.stop();\r\n }\r\n this.stream?.getTracks().forEach(track => track.stop());\r\n this.stream = null;\r\n // State will be updated by onstop handler\r\n }\r\n\r\n /**\r\n * \r\n * @returns Promise<void>\r\n * @throws Error if recording is not in progress\r\n */\r\n stopRecording(): void {\r\n this.stopRecordingInternal();\r\n }\r\n\r\n /**\r\n * Pauses the current recording\r\n * \r\n * @returns Promise<void>\r\n * @throws Error if recording is not in progress\r\n */\r\n pauseRecording(): void {\r\n if (this.mediaRecorder && this.recordingStateSubject.value === RecordingState.Recording) {\r\n this.mediaRecorder.pause();\r\n this.recordingStateSubject.next(RecordingState.Paused);\r\n this.stopTimer(); // Pauses the timer display\r\n }\r\n }\r\n\r\n /**\r\n * Resumes a paused recording\r\n * \r\n * @returns Promise<void>\r\n * @throws Error if recording is not paused\r\n */\r\n resumeRecording(): void {\r\n if (this.mediaRecorder && this.recordingStateSubject.value === RecordingState.Paused) {\r\n this.mediaRecorder.resume();\r\n this.recordingStateSubject.next(RecordingState.Recording);\r\n this.startTimer(this.currentRecordedTime); // Resumes timer display\r\n }\r\n }\r\n\r\n /**\r\n * \r\n * @param fileName \r\n */\r\n downloadRecording(fileName: string = 'recording.webm'): void {\r\n const url = this.recordedUrlSubject.value;\r\n const timestamp = this.recordingTimestampSubject.value;\r\n\r\n if (url && timestamp) {\r\n // Format the timestamp for filename (remove spaces and special characters)\r\n const formattedTimestamp = timestamp.replace(/[^a-zA-Z0-9]/g, '_');\r\n // Create filename with timestamp\r\n const fileExtension = fileName.split('.').pop() || 'webm';\r\n const newFileName = `screen_recording_${formattedTimestamp}.${fileExtension}`;\r\n\r\n const a = document.createElement('a');\r\n a.style.display = 'none';\r\n a.href = url;\r\n a.download = newFileName;\r\n document.body.appendChild(a);\r\n a.click();\r\n document.body.removeChild(a);\r\n // No need to revoke URL here if user might want to play it again.\r\n // Revoke on cleanup or new recording.\r\n } else {\r\n this.handleError(this.screenRecordingConstant.NO_RECORDING_DOWNLOAD);\r\n }\r\n }\r\n\r\n /**\r\n * Starts the recording timer\r\n * \r\n * @param startTime - Optional start time for the timer\r\n * @private\r\n * @returns void\r\n */\r\n private startTimer(startTime: number = 0): void {\r\n this.stopTimer(); // Ensure no multiple timers\r\n this.currentRecordedTime = startTime;\r\n this.recordedTimeSubject.next(this.currentRecordedTime);\r\n\r\n this.timerSubscription = timer(0, 1000)\r\n .pipe(\r\n tap(() => {\r\n if (this.recordingStateSubject.value === RecordingState.Recording) {\r\n this.currentRecordedTime++;\r\n this.recordedTimeSubject.next(this.currentRecordedTime);\r\n }\r\n }),\r\n takeWhile(() => this.recordingStateSubject.value === RecordingState.Recording)\r\n )\r\n .subscribe();\r\n }\r\n\r\n /**\r\n * Stops the recording timer\r\n * \r\n * @private\r\n * @returns void\r\n */\r\n private stopTimer(): void {\r\n if (this.timerSubscription) {\r\n this.timerSubscription.unsubscribe();\r\n this.timerSubscription = null;\r\n }\r\n }\r\n\r\n /**\r\n * Cleans up resources from previous recording\r\n * \r\n * @private\r\n * @returns void\r\n */\r\n private cleanupPreviousRecording(): void {\r\n if (this.recordedUrlSubject.value) {\r\n window.URL.revokeObjectURL(this.recordedUrlSubject.value);\r\n this.recordedUrlSubject.next(null);\r\n }\r\n this.recordedBlobs = [];\r\n this.currentRecordedTime = 0;\r\n this.recordedTimeSubject.next(0);\r\n if (this.stream) {\r\n this.stream.getTracks().forEach(track => track.stop());\r\n this.stream = null;\r\n }\r\n if (this.mediaRecorder && this.mediaRecorder.state !== this.screenRecordingConstant.INACTIVE) {\r\n this.mediaRecorder.stop();\r\n }\r\n this.mediaRecorder = null;\r\n }\r\n\r\n\r\n /**\r\n * Resets the recording state to idle\r\n * \r\n * @returns void\r\n */\r\n resetToIdle(): void {\r\n this.cleanupPreviousRecording();\r\n this.recordingStateSubject.next(RecordingState.Idle);\r\n this.errorSubject.next(''); // Clear any previous errors\r\n }\r\n\r\n\r\n /**\r\n * Handles and broadcasts recording errors\r\n * \r\n * @private\r\n * @param error - The error message to handle\r\n * @returns void\r\n */\r\n private handleError(error: string): void {\r\n this.errorSubject.next(error);\r\n }\r\n}\r\n","import { Component, Input, OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef, ViewChild, ElementRef } from '@angular/core';\r\nimport { DomSanitizer, SafeUrl } from '@angular/platform-browser';\r\nimport { Subscription } from 'rxjs';\r\nimport {\r\n ScreenRecorderOptions,\r\n ScreenRecorderPosition,\r\n DisplayFormat,\r\n RecordingState,\r\n ScreenRecorderIcons,\r\n} from '../models/screen-recorder.models';\r\nimport { ScreenRecorderService } from '../services/screen-recorder.service';\r\nimport { ScreenRecorderConstants } from './screen-recorder-constant';\r\n\r\n\r\n\r\n@Component({\r\n selector: 'uxp-screen-recorder',\r\n templateUrl: './screen-recorder.component.html',\r\n styleUrls: ['./screen-recorder.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class ScreenRecorderComponent implements OnInit, OnDestroy {\r\n @Input()\r\n customTheme: any;\r\n \r\n @Input()\r\n set rucInputData(value: ScreenRecorderOptions) {\r\n this._options = {\r\n position: ScreenRecorderPosition.Bottom,\r\n displayFormat: DisplayFormat.Icon,\r\n showAudioToggle: true,\r\n defaultAudioState: true,\r\n downloadFileName: 'screen-recording.webm',\r\n icons: { ...this.screenRecordingConstant.DEFAULT_ICONS },\r\n showTimer: true,\r\n showPauseResume: true,\r\n showPlaybackControls: true,\r\n showDownloadButton: true,\r\n useUTCForTimer: false,\r\n allowSpecificAreaSelection: true, // Default to allowing browser's native picker\r\n accessibilityLabels: { ...this.screenRecordingConstant.DEFAULT_LABELS },\r\n ...value,\r\n };\r\n // Deep merge icons and labels\r\n if (value.icons) {\r\n this._options.icons = { ...this.screenRecordingConstant.DEFAULT_ICONS, ...value.icons };\r\n }\r\n if (value.accessibilityLabels) {\r\n this._options.accessibilityLabels = { ...this.screenRecordingConstant.DEFAULT_LABELS, ...value.accessibilityLabels };\r\n }\r\n this.isAudioEnabled = this._options.defaultAudioState ?? true;\r\n }\r\n get rucInputData(): ScreenRecorderOptions {\r\n return this._options;\r\n }\r\n private _options!: ScreenRecorderOptions;\r\n\r\n @ViewChild('videoPlayer') videoPlayer!: ElementRef<HTMLVideoElement>;\r\n\r\n recordingState: RecordingState = RecordingState.Idle;\r\n recordedTime: number = 0;\r\n formattedTime: string = '00:00:00';\r\n safeRecordedUrl: SafeUrl | null = null;\r\n recordingTimestamp: string = '';\r\n /**\r\n * Checks if recording is currently in progress\r\n * \r\n * @returns boolean - True if recording is in progress, false otherwise\r\n */\r\n isRecordingInProgress(): boolean {\r\n return this.recordingState === RecordingState.Recording;\r\n }\r\n errorMessage: string | null = null;\r\n isBrowserSupported: boolean = true;\r\n isAudioEnabled: boolean = true;\r\n\r\n /**\r\n * Gets the appropriate icon for recording based on audio state and settings\r\n * @returns string - The icon name to display\r\n */\r\n getRecordingIcon(): string {\r\n if (this.isAudioEnabled && this.rucInputData.showAudioToggle) {\r\n return this.getIcon('recordWithAudio');\r\n }\r\n return this.getIcon('record');\r\n }\r\n\r\n // Expose enums to template\r\n DisplayFormat = DisplayFormat;\r\n RecordingState = RecordingState;\r\n ScreenRecorderPosition = ScreenRecorderPosition;\r\n\r\n private subscriptions = new Subscription();\r\n\r\n constructor(\r\n public screenRecorderService: ScreenRecorderService,\r\n private sanitizer: DomSanitizer,\r\n private cdr: ChangeDetectorRef,\r\n public screenRecordingConstant: ScreenRecorderConstants\r\n ) {\r\n\r\n // Initialize with default options. The setter will override if an input is provided.\r\n if (!this._options) {\r\n this.rucInputData = {}; // Trigger setter with empty object to apply defaults\r\n }\r\n } \r\n\r\n ngOnInit(): void {\r\n this.subscriptions.add(\r\n this.screenRecorderService.recordingState$.subscribe((state) => {\r\n this.recordingState = state;\r\n if (state === RecordingState.Idle || state === RecordingState.Stopped) {\r\n // Ensure audio toggle is reset to default if needed, or based on user action\r\n }\r\n this.cdr.detectChanges();\r\n })\r\n );\r\n\r\n this.subscriptions.add(\r\n this.screenRecorderService.recordingTimestamp$.subscribe((timestamp) => {\r\n this.recordingTimestamp = timestamp;\r\n this.cdr.detectChanges();\r\n })\r\n );\r\n\r\n this.subscriptions.add(\r\n this.screenRecorderService.recordedTime$.subscribe((time) => {\r\n this.recordedTime = time;\r\n this.formattedTime = this.formatTimeDisplay(time);\r\n this.cdr.detectChanges();\r\n })\r\n );\r\n\r\n this.subscriptions.add(\r\n this.screenRecorderService.recordedUrl$.subscribe((url) => {\r\n this.safeRecordedUrl = url ? this.sanitizer.bypassSecurityTrustUrl(url) : null;\r\n this.cdr.detectChanges();\r\n })\r\n );\r\n\r\n this.subscriptions.add(\r\n this.screenRecorderService.error$.subscribe((error) => {\r\n if(error != this.screenRecordingConstant.PERMISSION_DENIED){\r\n this.errorMessage = error;\r\n }\r\n this.cdr.detectChanges();\r\n })\r\n );\r\n }\r\n\r\n ngOnDestroy() {\r\n if (this.subscriptions) {\r\n this.subscriptions.unsubscribe();\r\n }\r\n }\r\n\r\n /**\r\n * Toggles the recording state between start and stop\r\n * \r\n * @returns Promise<void>\r\n */\r\n async toggleRecord(): Promise<void> {\r\n this.errorMessage = null; // Clear previous errors\r\n if (this.recordingState === RecordingState.Idle || this.recordingState === RecordingState.Stopped) {\r\n // Set recording timestamp when starting recording\r\n const now = new Date();\r\n this.recordingTimestamp = now.toLocaleString('en-IN', {\r\n year: 'numeric',\r\n month: '2-digit',\r\n day: '2-digit',\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n hour12: true\r\n });\r\n await this.screenRecorderService.startRecording({ audio: this.isAudioEnabled });\r\n } else {\r\n this.screenRecorderService.stopRecording();\r\n }\r\n }\r\n\r\n /**\r\n * Toggles between pause and resume states during recording\r\n * \r\n * @returns void\r\n */\r\n togglePauseResume(): void {\r\n this.errorMessage = null;\r\n if (this.recordingState === RecordingState.Recording) {\r\n this.screenRecorderService.pauseRecording();\r\n } else if (this.recordingState === RecordingState.Paused) {\r\n this.screenRecorderService.resumeRecording();\r\n }\r\n }\r\n\r\n /**\r\n * Checks if recording can be resumed\r\n * \r\n * @returns boolean - True if recording can be resumed, false otherwise\r\n */\r\n canResume(): boolean {\r\n return this.recordingState === RecordingState.Paused;\r\n }\r\n\r\n /**\r\n * Downloads the recorded video file\r\n * \r\n * @returns void\r\n */\r\n onDownload(): void {\r\n this.errorMessage = null;\r\n this.screenRecorderService.downloadRecording(this.rucInputData.downloadFileName);\r\n }\r\n\r\n /**\r\n * Checks if recording can be downloaded\r\n * \r\n * @returns boolean - True if recording can be downloaded, false otherwise\r\n */\r\n canDownload(): boolean {\r\n return this.recordingState === RecordingState.Stopped;\r\n }\r\n\r\n /**\r\n * Toggles audio recording on/off\r\n * \r\n * @returns void\r\n */\r\n toggleAudio(): void {\r\n this.isAudioEnabled = !this.isAudioEnabled;\r\n this.cdr.detectChanges();\r\n }\r\n\r\n /**\r\n * \r\n * @param iconName \r\n * @returns \r\n */\r\n getIcon(iconName: keyof ScreenRecorderIcons): string {\r\n return this.rucInputData.icons?.[iconName] || (this.screenRecordingConstant.DEFAULT_ICONS as any)[iconName];\r\n }\r\n\r\n /**\r\n * \r\n * @param labelName \r\n * @returns \r\n */\r\n getLabel(labelName: keyof NonNullable<ScreenRecorderOptions['accessibilityLabels']>): string {\r\n return this.rucInputData.accessibilityLabels?.[labelName] || (this.screenRecordingConstant.DEFAULT_LABELS as any)[labelName];\r\n }\r\n\r\n /**\r\n * \r\n * @param time - The time in seconds to format\r\n * @returns string - Formatted time string (HH:MM:SS)\r\n */\r\n formatTimeDisplay(time: number): string {\r\n const hours = Math.floor(time / 3600);\r\n const minutes = Math.floor((time % 3600) / 60);\r\n const seconds = time % 60;\r\n\r\n const pad = (num: number) => num.toString().padStart(2, '0');\r\n\r\n if (this.rucInputData && this.rucInputData.useUTCForTimer) {\r\n // This is a simple duration format, not a specific UTC time.\r\n // For actual UTC time of day, you'd use new Date().toUTCString() or similar.\r\n // Assuming timer should show elapsed time formatted as HH:MM:SS.\r\n return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;\r\n }\r\n return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;\r\n }\r\n\r\n // Method to reset the component and service to initial state\r\n reset(): void {\r\n this.screenRecorderService.resetToIdle();\r\n this.isAudioEnabled = this.rucInputData.defaultAudioState ?? true;\r\n this.cdr.detectChanges();\r\n }\r\n}\r\n\r\n","<div class=\"screen-recorder-controls\" [ngClass]=\"customTheme + ' position-' + (rucInputData.position || ScreenRecorderPosition.Bottom)\"\r\n *ngIf=\"isBrowserSupported\">\r\n\r\n <!-- Error Message -->\r\n <div *ngIf=\"errorMessage\" class=\"recorder-error\">\r\n {{ errorMessage }}\r\n </div>\r\n\r\n <!-- Record/Stop Button -->\r\n <button\r\n *ngIf=\"recordingState === RecordingState.Idle || recordingState === RecordingState.Stopped\" (click)=\"toggleRecord()\"\r\n [attr.aria-label]=\"getLabel('recordButton')\" [attr.aria-pressed]=\"false\" class=\"recorder-button record-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getRecordingIcon() || getIcon('record') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('recordButton')\r\n }}</ng-container>\r\n </button>\r\n\r\n <button\r\n *ngIf=\"recordingState === RecordingState.Recording || recordingState === RecordingState.Paused\"\r\n (click)=\"toggleRecord()\" [attr.aria-label]=\"getLabel('stopButton')\" [attr.aria-pressed]=\"true\"\r\n class=\"recorder-button stop-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('stop') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('stopButton') }}</ng-container>\r\n </button>\r\n\r\n <!-- Pause/Resume Button -->\r\n <button *ngIf=\"rucInputData.showPauseResume && recordingState === RecordingState.Recording\"\r\n (click)=\"togglePauseResume()\" [attr.aria-label]=\"getLabel('pauseButton')\" [attr.aria-pressed]=\"false\"\r\n class=\"recorder-button pause-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('pause') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('pauseButton') }}</ng-container>\r\n </button>\r\n <button *ngIf=\"rucInputData.showPauseResume && recordingState === RecordingState.Paused\"\r\n (click)=\"togglePauseResume()\" [attr.aria-label]=\"getLabel('resumeButton')\" [attr.aria-pressed]=\"true\"\r\n class=\"recorder-button resume-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('resume') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('resumeButton')\r\n }}</ng-container>\r\n </button>\r\n\r\n <!-- Audio Toggle Button -->\r\n <button\r\n *ngIf=\"rucInputData.showAudioToggle && (recordingState === RecordingState.Idle || recordingState === RecordingState.Stopped)\"\r\n (click)=\"toggleAudio()\" [attr.aria-label]=\"getLabel('audioToggleButton')\" [attr.aria-pressed]=\"isAudioEnabled\"\r\n class=\"recorder-button audio-toggle-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ isAudioEnabled ? getIcon('audioOn') : getIcon('audioOff') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">\r\n {{ isAudioEnabled ? screenRecordingConstant.AUDIO_ON : screenRecordingConstant.AUDIO_OFF }}\r\n </ng-container>\r\n </button>\r\n\r\n <!-- Timer -->\r\n <div\r\n *ngIf=\"rucInputData.showTimer && (recordingState === RecordingState.Recording || recordingState === RecordingState.Paused)\"\r\n class=\"recorder-timer\" aria-live=\"polite\" aria-atomic=\"true\">\r\n {{ formattedTime }}\r\n </div>\r\n\r\n <!-- Download Button -->\r\n <button\r\n *ngIf=\"rucInputData.showDownloadButton && recordingState === RecordingState.Stopped && safeRecordedUrl\"\r\n (click)=\"onDownload()\" [attr.aria-label]=\"getLabel('downloadButton')\" class=\"recorder-button download-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('download') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('downloadButton')\r\n }}</ng-container>\r\n </button>\r\n\r\n <!-- Playback Area -->\r\n <div *ngIf=\"rucInputData.showPlaybackControls && recordingState === RecordingState.Stopped && safeRecordedUrl\"\r\n class=\"playback-area\">\r\n <video #videoPlayer [src]=\"safeRecordedUrl\" controls [attr.aria-label]=\"getLabel('playbackVideo')\"></video>\r\n <div class=\"video-timer-overlay\">\r\n <span>Recorded on: {{ recordingTimestamp }}</span>\r\n </div>\r\n </div>\r\n\r\n <!-- Reset Button (optional, good for testing/clearing state) -->\r\n <button *ngIf=\"recordingState === RecordingState.Stopped && safeRecordedUrl\" (click)=\"reset()\"\r\n aria-label=\"New Recording\" class=\"recorder-button reset-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">refresh</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">New</ng-container>\r\n </button>\r\n\r\n</div>\r\n\r\n<div *ngIf=\"!isBrowserSupported\" class=\"recorder-notsupported\" [ngClass]=\"customTheme\">\r\n {{screenRecordingConstant.NO_SUPPORT}}\r\n</div>","import { NgModule } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { ScreenRecorderComponent } from './screen-recorder/screen-recorder.component';\r\nimport { ScreenRecorderService } from './services/screen-recorder.service';\r\n\r\n@NgModule({\r\n imports: [CommonModule],\r\n declarations: [ScreenRecorderComponent],\r\n exports: [ScreenRecorderComponent],\r\n providers: [ScreenRecorderService],\r\n})\r\nexport class RuclibScreenRecorderModule {}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1.ScreenRecorderConstants","i1.ScreenRecorderService","i3.ScreenRecorderConstants"],"mappings":";;;;;;;;;AAAY,IAAA,uBAKT;AALH,CAAA,UAAY,sBAAsB,EAAA;AAC9B,IAAA,sBAAA,CAAA,KAAA,CAAA,GAAA,KAAW,CAAA;AACX,IAAA,sBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACjB,IAAA,sBAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACb,IAAA,sBAAA,CAAA,OAAA,CAAA,GAAA,OAAe,CAAA;AACjB,CAAC,EALS,sBAAsB,KAAtB,sBAAsB,GAK/B,EAAA,CAAA,CAAA,CAAA;AAEW,IAAA,cAGX;AAHD,CAAA,UAAY,aAAa,EAAA;AACvB,IAAA,aAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACb,IAAA,aAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACf,CAAC,EAHW,aAAa,KAAb,aAAa,GAGxB,EAAA,CAAA,CAAA,CAAA;AAEW,IAAA,eAKX;AALD,CAAA,UAAY,cAAc,EAAA;AACxB,IAAA,cAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACb,IAAA,cAAA,CAAA,WAAA,CAAA,GAAA,WAAuB,CAAA;AACvB,IAAA,cAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACjB,IAAA,cAAA,CAAA,SAAA,CAAA,GAAA,SAAmB,CAAA;AACrB,CAAC,EALW,cAAc,KAAd,cAAc,GAKzB,EAAA,CAAA,CAAA;;MCLU,uBAAuB,CAAA;AAChC,IAAA,WAAA,GAAA;QAGO,IAAA,CAAA,aAAa,GAAwB;AAC1C,YAAA,MAAM,EAAE,qBAAqB;AAC7B,YAAA,IAAI,EAAE,MAAM;AACZ,YAAA,KAAK,EAAE,OAAO;AACd,YAAA,MAAM,EAAE,YAAY;AACpB,YAAA,IAAI,EAAE,oBAAoB;AAC1B,YAAA,QAAQ,EAAE,UAAU;AACpB,YAAA,OAAO,EAAE,WAAW;AACpB,YAAA,QAAQ,EAAE,YAAY;SACvB,CAAC;QAEK,IAAA,CAAA,cAAc,GAAG;AACtB,YAAA,YAAY,EAAE,iBAAiB;AAC/B,YAAA,UAAU,EAAE,gBAAgB;AAC5B,YAAA,WAAW,EAAE,iBAAiB;AAC9B,YAAA,YAAY,EAAE,kBAAkB;AAChC,YAAA,iBAAiB,EAAE,cAAc;AACjC,YAAA,cAAc,EAAE,oBAAoB;AACpC,YAAA,aAAa,EAAE,2BAA2B;SAC3C,CAAC;AAEK,QAAA,IAAQ,CAAA,QAAA,GAAG,UAAU,CAAC;AAEtB,QAAA,IAAQ,CAAA,QAAA,GAAG,UAAU,CAAC;AACtB,QAAA,IAAS,CAAA,SAAA,GAAG,WAAW,CAAC;AAExB,QAAA,IAA2B,CAAA,2BAAA,GAAG,mCAAmC,CAAC;AAClE,QAAA,IAAwC,CAAA,wCAAA,GAAG,oCAAoC,CAAC;AAChF,QAAA,IAAe,CAAA,eAAA,GAAG,iDAAiD,CAAC;AACpE,QAAA,IAAqB,CAAA,qBAAA,GAAG,qCAAqC,CAAC;AAC9D,QAAA,IAAW,CAAA,WAAA,GAAG,qBAAqB,CAAC;AACpC,QAAA,IAAiB,CAAA,iBAAA,GAAG,sEAAsE,CAAC;AAC3F,QAAA,IAAU,CAAA,UAAA,GAAG,oDAAoD,CAAC;KAjCxE;;qHAHQ,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAvB,uBAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,uBAAuB,cAFpB,MAAM,EAAA,CAAA,CAAA;4FAET,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBAHnC,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,UAAU,EAAE,MAAM;iBACrB,CAAA;;;MCHY,qBAAqB,CAAA;AAsBhC,IAAA,WAAA,CAAmB,uBAAgD,EAAA;AAAhD,QAAA,IAAuB,CAAA,uBAAA,GAAvB,uBAAuB,CAAyB;AArB3D,QAAA,IAAM,CAAA,MAAA,GAAuB,IAAI,CAAC;AAClC,QAAA,IAAa,CAAA,aAAA,GAAyB,IAAI,CAAC;AAC3C,QAAA,IAAa,CAAA,aAAA,GAAW,EAAE,CAAC;AAE3B,QAAA,IAAmB,CAAA,mBAAA,GAAW,CAAC,CAAC;QAEvB,IAAqB,CAAA,qBAAA,GAAG,IAAI,eAAe,CAAiB,cAAc,CAAC,IAAI,CAAC,CAAC;QACzF,IAAA,CAAA,eAAe,GAA+B,IAAI,CAAC,qBAAqB,CAAC,YAAY,EAAE,CAAC;QAEhF,IAAA,CAAA,mBAAmB,GAAG,IAAI,eAAe,CAAS,CAAC,CAAC,CAAC;QAC7D,IAAA,CAAA,aAAa,GAAuB,IAAI,CAAC,mBAAmB,CAAC,YAAY,EAAE,CAAC;QAEpE,IAAA,CAAA,kBAAkB,GAAG,IAAI,eAAe,CAAgB,IAAI,CAAC,CAAC;QACtE,IAAA,CAAA,YAAY,GAA8B,IAAI,CAAC,kBAAkB,CAAC,YAAY,EAAE,CAAC;QAEzE,IAAA,CAAA,yBAAyB,GAAG,IAAI,eAAe,CAAS,EAAE,CAAC,CAAC;QACpE,IAAA,CAAA,mBAAmB,GAAuB,IAAI,CAAC,yBAAyB,CAAC,YAAY,EAAE,CAAC;AAEhF,QAAA,IAAA,CAAA,YAAY,GAAG,IAAI,OAAO,EAAU,CAAC;QAC7C,IAAA,CAAA,MAAM,GAAuB,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC;KAEC;AAExE;;;;;;;;AAQG;AACG,IAAA,cAAc,CAAC,OAA2B,EAAA;;;AAE9C,YAAA,IAAI,IAAI,CAAC,qBAAqB,CAAC,KAAK,KAAK,cAAc,CAAC,SAAS,IAAI,IAAI,CAAC,qBAAqB,CAAC,KAAK,KAAK,cAAc,CAAC,MAAM,EAAE;gBAC/H,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,uBAAuB,CAAC,2BAA2B,CAAC,CAAC;gBAC3E,OAAO;AACR,aAAA;YAED,IAAI,CAAC,wBAAwB,EAAE,CAAC;YAEhC,IAAI;;gBAEF,MAAM,aAAa,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,eAAe,CAAC;AACjE,oBAAA,KAAK,EAAE,IAAI;AACZ,iBAAA,CAAC,CAAC;;gBAGH,IAAI,WAAW,GAAuB,IAAI,CAAC;gBAC3C,IAAI,OAAO,CAAC,KAAK,EAAE;AACjB,oBAAA,WAAW,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC;AACtD,wBAAA,KAAK,EAAE;AACL,4BAAA,gBAAgB,EAAE,IAAI;AACtB,4BAAA,gBAAgB,EAAE,IAAI;AACtB,4BAAA,UAAU,EAAE,KAAK;AAClB,yBAAA;AACF,qBAAA,CAAC,CAAC;AACJ,iBAAA;;AAGD,gBAAA,IAAI,WAAW,EAAE;oBACf,IAAI,CAAC,MAAM,GAAG,IAAI,WAAW,CAAC,CAAC,GAAG,aAAa,CAAC,SAAS,EAAE,EAAE,GAAG,WAAW,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;AAC3F,iBAAA;AAAM,qBAAA;AACL,oBAAA,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC;AAC7B,iBAAA;;AAGD,gBAAA,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,MAAK;AAC7C,oBAAA,IAAI,IAAI,CAAC,qBAAqB,CAAC,KAAK,KAAK,cAAc,CAAC,SAAS,IAAI,IAAI,CAAC,qBAAqB,CAAC,KAAK,KAAK,cAAc,CAAC,MAAM,EAAE;wBAC/H,IAAI,CAAC,qBAAqB,EAAE,CAAC;AAC9B,qBAAA;AACH,iBAAC,CAAC;;AAGF,gBAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;oBAChB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,uBAAuB,CAAC,wCAAwC,CAAC,CAAC;oBACxF,OAAO;AACR,iBAAA;;AAGD,gBAAA,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;AACvB,gBAAA,MAAM,SAAS,GAAG,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE;AAC5C,oBAAA,IAAI,EAAE,SAAS;AACf,oBAAA,KAAK,EAAE,SAAS;AAChB,oBAAA,GAAG,EAAE,SAAS;AACd,oBAAA,IAAI,EAAE,SAAS;AACf,oBAAA,MAAM,EAAE,SAAS;AACjB,oBAAA,MAAM,EAAE,IAAI;AACb,iBAAA,CAAC,CAAC;AACH,gBAAA,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAG/C,gBAAA,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;AACxB,gBAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;gBAC7C,IAAI,CAAC,QAAQ,EAAE;oBACb,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,uBAAuB,CAAC,eAAe,CAAC,CAAC;AAC/D,oBAAA,CAAA,EAAA,GAAA,IAAI,CAAC,MAAM,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,SAAS,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;AACxD,oBAAA,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;oBACnB,OAAO;AACR,iBAAA;;gBAGD,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;gBAChD,MAAM,UAAU,GAAG,CAAA,EAAA,GAAA,IAAI,CAAC,MAAM,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAE,cAAc,EAAA,CAAG,CAAC,CAAC,CAAC;AACpD,gBAAA,IAAI,UAAU,EAAE;oBACd,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;AAC9C,oBAAA,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC;;AAG9B,oBAAA,KAAK,CAAC,gBAAgB,GAAG,MAAK;AAC5B,wBAAA,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC;AAChC,wBAAA,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC;wBAClC,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AACpC,wBAAA,IAAI,GAAG,EAAE;;4BAEP,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;;AAG3B,4BAAA,GAAG,CAAC,IAAI,GAAG,YAAY,CAAC;AACxB,4BAAA,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC;AACxB,4BAAA,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC;AACxB,4BAAA,GAAG,CAAC,YAAY,GAAG,KAAK,CAAC;AACzB,4BAAA,GAAG,CAAC,QAAQ,CAAC,gBAAgB,IAAI,CAAC,yBAAyB,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,KAAK,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;AAC7F,yBAAA;AACH,qBAAC,CAAC;AACH,iBAAA;;AAGD,gBAAA,MAAM,YAAY,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;gBAC5C,MAAM,cAAc,GAAG,IAAI,WAAW,CAAC,CAAC,GAAG,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,IAAI,CAAC,MAAM,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAE,SAAS,EAAE,MAAI,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAA,EAAE,EAAE,YAAY,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE9G,gBAAA,IAAI,CAAC,aAAa,GAAG,IAAI,aAAa,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAErE,IAAI,CAAC,aAAa,CAAC,eAAe,GAAG,CAAC,KAAK,KAAI;oBAC7C,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE;wBACrC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACrC,qBAAA;AACH,iBAAC,CAAC;AAEF,gBAAA,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,MAAK;AAC/B,oBAAA,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;oBACrE,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;AACpD,oBAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBAClC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;oBACxD,IAAI,CAAC,SAAS,EAAE,CAAC;AAEnB,iBAAC,CAAC;gBAEF,IAAI,CAAC,aAAa,CAAC,OAAO,GAAG,CAAC,KAAY,KAAI;AAC5C,oBAAA,MAAM,UAAU,GAAG,KAAmB,CAAC;AACvC,oBAAA,IAAI,OAAO,GAAG,IAAI,CAAC,uBAAuB,CAAC,WAAW,CAAC;oBACvD,IAAI,UAAU,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE;wBAC7C,OAAO,IAAI,KAAK,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;AACxC,wBAAA,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO;4BAAE,OAAO,IAAI,MAAM,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;AAC3E,qBAAA;AACD,oBAAA,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;oBAC1B,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;oBACrD,IAAI,CAAC,SAAS,EAAE,CAAC;AACnB,iBAAC,CAAC;AAEF,gBAAA,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;gBAC3B,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;gBAC1D,IAAI,CAAC,UAAU,EAAE,CAAC;AACnB,aAAA;AAAC,YAAA,OAAO,GAAQ,EAAE;AACjB,gBAAA,IAAI,CAAC,WAAW,CAAC,CAAA,iCAAA,EAAoC,GAAG,CAAC,IAAI,CAAA,GAAA,EAAM,GAAG,CAAC,OAAO,CAAA,CAAE,CAAC,CAAC;gBAClF,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;AACtD,aAAA;;AACF,KAAA;AAED;;;;AAIC;IACO,oBAAoB,GAAA;AAC1B,QAAA,MAAM,SAAS,GAAG;YAChB,4BAA4B;YAC5B,4BAA4B;YAC5B,6BAA6B;YAC7B,2BAA2B;YAC3B,YAAY;SACb,CAAC;AACF,QAAA,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE;AAChC,YAAA,IAAI,aAAa,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE;AAC3C,gBAAA,OAAO,QAAQ,CAAC;AACjB,aAAA;AACF,SAAA;AACD,QAAA,OAAO,IAAI,CAAC;KACb;AAED;;;;;AAKG;IACK,qBAAqB,GAAA;;QAC3B,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI,CAAC,qBAAqB,CAAC,KAAK,KAAK,cAAc,CAAC,SAAS,IAAI,IAAI,CAAC,qBAAqB,CAAC,KAAK,KAAK,cAAc,CAAC,MAAM,CAAC,EAAE;AACvJ,YAAA,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;AAC3B,SAAA;AACD,QAAA,CAAA,EAAA,GAAA,IAAI,CAAC,MAAM,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,SAAS,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;AACxD,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;;KAEpB;AAED;;;;AAIG;IACH,aAAa,GAAA;QACX,IAAI,CAAC,qBAAqB,EAAE,CAAC;KAC9B;AAED;;;;;AAKG;IACH,cAAc,GAAA;AACZ,QAAA,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,qBAAqB,CAAC,KAAK,KAAK,cAAc,CAAC,SAAS,EAAE;AACvF,YAAA,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;YAC3B,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;AACvD,YAAA,IAAI,CAAC,SAAS,EAAE,CAAC;AAClB,SAAA;KACF;AAED;;;;;AAKG;IACH,eAAe,GAAA;AACb,QAAA,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,qBAAqB,CAAC,KAAK,KAAK,cAAc,CAAC,MAAM,EAAE;AACpF,YAAA,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;YAC5B,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;YAC1D,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;AAC3C,SAAA;KACF;AAED;;;AAGG;IACH,iBAAiB,CAAC,WAAmB,gBAAgB,EAAA;AACnD,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC;AAC1C,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC;QAEvD,IAAI,GAAG,IAAI,SAAS,EAAE;;YAEpB,MAAM,kBAAkB,GAAG,SAAS,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;;AAEnE,YAAA,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,MAAM,CAAC;AAC1D,YAAA,MAAM,WAAW,GAAG,CAAA,iBAAA,EAAoB,kBAAkB,CAAI,CAAA,EAAA,aAAa,EAAE,CAAC;YAE9E,MAAM,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;AACtC,YAAA,CAAC,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;AACzB,YAAA,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC;AACb,YAAA,CAAC,CAAC,QAAQ,GAAG,WAAW,CAAC;AACzB,YAAA,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YAC7B,CAAC,CAAC,KAAK,EAAE,CAAC;AACV,YAAA,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;;;AAG9B,SAAA;AAAM,aAAA;YACL,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,uBAAuB,CAAC,qBAAqB,CAAC,CAAC;AACtE,SAAA;KACF;AAED;;;;;;AAMC;IACO,UAAU,CAAC,YAAoB,CAAC,EAAA;AACtC,QAAA,IAAI,CAAC,SAAS,EAAE,CAAC;AACjB,QAAA,IAAI,CAAC,mBAAmB,GAAG,SAAS,CAAC;QACrC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAExD,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;AACpC,aAAA,IAAI,CACH,GAAG,CAAC,MAAK;YACP,IAAI,IAAI,CAAC,qBAAqB,CAAC,KAAK,KAAK,cAAc,CAAC,SAAS,EAAE;gBACjE,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC3B,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;AACzD,aAAA;AACH,SAAC,CAAC,EACF,SAAS,CAAC,MAAM,IAAI,CAAC,qBAAqB,CAAC,KAAK,KAAK,cAAc,CAAC,SAAS,CAAC,CAC/E;AACA,aAAA,SAAS,EAAE,CAAC;KAChB;AAED;;;;;AAKG;IACK,SAAS,GAAA;QACf,IAAI,IAAI,CAAC,iBAAiB,EAAE;AAC1B,YAAA,IAAI,CAAC,iBAAiB,CAAC,WAAW,EAAE,CAAC;AACrC,YAAA,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;AAC/B,SAAA;KACF;AAED;;;;;AAKG;IACK,wBAAwB,GAAA;AAC9B,QAAA,IAAI,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE;YACjC,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;AAC1D,YAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACpC,SAAA;AACD,QAAA,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;AACxB,QAAA,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;AAC7B,QAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjC,IAAI,IAAI,CAAC,MAAM,EAAE;AACf,YAAA,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;AACvD,YAAA,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;AACpB,SAAA;AACD,QAAA,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC,KAAK,KAAK,IAAI,CAAC,uBAAuB,CAAC,QAAQ,EAAE;AAC5F,YAAA,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;AAC3B,SAAA;AACD,QAAA,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;KAC3B;AAGD;;;;AAIC;IACD,WAAW,GAAA;QACT,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAChC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QACrD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;KAC5B;AAGD;;;;;;AAMC;AACO,IAAA,WAAW,CAAC,KAAa,EAAA;AAC/B,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;KAC/B;;mHApWU,qBAAqB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,uBAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAArB,qBAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,qBAAqB,cAFpB,MAAM,EAAA,CAAA,CAAA;4FAEP,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBAHjC,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;oBACV,UAAU,EAAE,MAAM;iBACnB,CAAA;;;MCcY,uBAAuB,CAAA;IAIlC,IACI,YAAY,CAAC,KAA4B,EAAA;;AAC3C,QAAA,IAAI,CAAC,QAAQ,GACX,MAAA,CAAA,MAAA,CAAA,EAAA,QAAQ,EAAE,sBAAsB,CAAC,MAAM,EACvC,aAAa,EAAE,aAAa,CAAC,IAAI,EACjC,eAAe,EAAE,IAAI,EACrB,iBAAiB,EAAE,IAAI,EACvB,gBAAgB,EAAE,uBAAuB,EACzC,KAAK,EAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAAO,IAAI,CAAC,uBAAuB,CAAC,aAAa,CACtD,EAAA,SAAS,EAAE,IAAI,EACf,eAAe,EAAE,IAAI,EACrB,oBAAoB,EAAE,IAAI,EAC1B,kBAAkB,EAAE,IAAI,EACxB,cAAc,EAAE,KAAK,EACrB,0BAA0B,EAAE,IAAI,EAChC,mBAAmB,EAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAAO,IAAI,CAAC,uBAAuB,CAAC,cAAc,CAClE,EAAA,EAAA,KAAK,CACT,CAAC;;QAEF,IAAI,KAAK,CAAC,KAAK,EAAE;AACf,YAAA,IAAI,CAAC,QAAQ,CAAC,KAAK,mCAAQ,IAAI,CAAC,uBAAuB,CAAC,aAAa,CAAK,EAAA,KAAK,CAAC,KAAK,CAAE,CAAC;AACzF,SAAA;QACD,IAAI,KAAK,CAAC,mBAAmB,EAAE;AAC7B,YAAA,IAAI,CAAC,QAAQ,CAAC,mBAAmB,mCAAQ,IAAI,CAAC,uBAAuB,CAAC,cAAc,CAAK,EAAA,KAAK,CAAC,mBAAmB,CAAE,CAAC;AACtH,SAAA;QACD,IAAI,CAAC,cAAc,GAAG,CAAA,EAAA,GAAA,IAAI,CAAC,QAAQ,CAAC,iBAAiB,MAAI,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAA,IAAI,CAAC;KAC/D;AACD,IAAA,IAAI,YAAY,GAAA;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC;KACtB;AAUD;;;;AAIG;IACH,qBAAqB,GAAA;AACnB,QAAA,OAAO,IAAI,CAAC,cAAc,KAAK,cAAc,CAAC,SAAS,CAAC;KACzD;AAKD;;;AAGG;IACH,gBAAgB,GAAA;QACd,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE;AAC5D,YAAA,OAAO,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;AACxC,SAAA;AACD,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;KAC/B;AASD,IAAA,WAAA,CACS,qBAA4C,EAC3C,SAAuB,EACvB,GAAsB,EACvB,uBAAgD,EAAA;AAHhD,QAAA,IAAqB,CAAA,qBAAA,GAArB,qBAAqB,CAAuB;AAC3C,QAAA,IAAS,CAAA,SAAA,GAAT,SAAS,CAAc;AACvB,QAAA,IAAG,CAAA,GAAA,GAAH,GAAG,CAAmB;AACvB,QAAA,IAAuB,CAAA,uBAAA,GAAvB,uBAAuB,CAAyB;AAvCzD,QAAA,IAAA,CAAA,cAAc,GAAmB,cAAc,CAAC,IAAI,CAAC;AACrD,QAAA,IAAY,CAAA,YAAA,GAAW,CAAC,CAAC;AACzB,QAAA,IAAa,CAAA,aAAA,GAAW,UAAU,CAAC;AACnC,QAAA,IAAe,CAAA,eAAA,GAAmB,IAAI,CAAC;AACvC,QAAA,IAAkB,CAAA,kBAAA,GAAW,EAAE,CAAC;AAShC,QAAA,IAAY,CAAA,YAAA,GAAkB,IAAI,CAAC;AACnC,QAAA,IAAkB,CAAA,kBAAA,GAAY,IAAI,CAAC;AACnC,QAAA,IAAc,CAAA,cAAA,GAAY,IAAI,CAAC;;AAc/B,QAAA,IAAa,CAAA,aAAA,GAAG,aAAa,CAAC;AAC9B,QAAA,IAAc,CAAA,cAAA,GAAG,cAAc,CAAC;AAChC,QAAA,IAAsB,CAAA,sBAAA,GAAG,sBAAsB,CAAC;AAExC,QAAA,IAAA,CAAA,aAAa,GAAG,IAAI,YAAY,EAAE,CAAC;;AAUzC,QAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;AAChB,YAAA,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;AAC1B,SAAA;KACF;IAED,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CACpB,IAAI,CAAC,qBAAqB,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,KAAK,KAAI;AAC7D,YAAA,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;YAC5B,IAAI,KAAK,KAAK,cAAc,CAAC,IAAI,IAAI,KAAK,KAAK,cAAc,CAAC,OAAO,EAAE;;AAEtE,aAAA;AACD,YAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;SAC1B,CAAC,CACH,CAAC;AAEF,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CACpB,IAAI,CAAC,qBAAqB,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,SAAS,KAAI;AACrE,YAAA,IAAI,CAAC,kBAAkB,GAAG,SAAS,CAAC;AACpC,YAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;SAC1B,CAAC,CACH,CAAC;AAEF,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CACpB,IAAI,CAAC,qBAAqB,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,IAAI,KAAI;AAC1D,YAAA,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YACzB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;AAClD,YAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;SAC1B,CAAC,CACH,CAAC;AAEF,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CACpB,IAAI,CAAC,qBAAqB,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,GAAG,KAAI;AACxD,YAAA,IAAI,CAAC,eAAe,GAAG,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;AAC/E,YAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;SAC1B,CAAC,CACH,CAAC;AAEF,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CACpB,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,KAAI;AACpD,YAAA,IAAG,KAAK,IAAI,IAAI,CAAC,uBAAuB,CAAC,iBAAiB,EAAC;AACzD,gBAAA,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;AAC3B,aAAA;AACD,YAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;SAC1B,CAAC,CACH,CAAC;KACH;IAED,WAAW,GAAA;QACT,IAAI,IAAI,CAAC,aAAa,EAAE;AACtB,YAAA,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC;AAClC,SAAA;KACF;AAED;;;;AAIG;IACG,YAAY,GAAA;;AAChB,YAAA,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;AACzB,YAAA,IAAI,IAAI,CAAC,cAAc,KAAK,cAAc,CAAC,IAAI,IAAI,IAAI,CAAC,cAAc,KAAK,cAAc,CAAC,OAAO,EAAE;;AAEjG,gBAAA,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,IAAI,CAAC,kBAAkB,GAAG,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE;AACpD,oBAAA,IAAI,EAAE,SAAS;AACf,oBAAA,KAAK,EAAE,SAAS;AAChB,oBAAA,GAAG,EAAE,SAAS;AACd,oBAAA,IAAI,EAAE,SAAS;AACf,oBAAA,MAAM,EAAE,SAAS;AACjB,oBAAA,MAAM,EAAE,IAAI;AACb,iBAAA,CAAC,CAAC;AACH,gBAAA,MAAM,IAAI,CAAC,qBAAqB,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;AACjF,aAAA;AAAM,iBAAA;AACL,gBAAA,IAAI,CAAC,qBAAqB,CAAC,aAAa,EAAE,CAAC;AAC5C,aAAA;SACF,CAAA,CAAA;AAAA,KAAA;AAED;;;;AAIG;IACH,iBAAiB,GAAA;AACf,QAAA,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;AACzB,QAAA,IAAI,IAAI,CAAC,cAAc,KAAK,cAAc,CAAC,SAAS,EAAE;AACpD,YAAA,IAAI,CAAC,qBAAqB,CAAC,cAAc,EAAE,CAAC;AAC7C,SAAA;AAAM,aAAA,IAAI,IAAI,CAAC,cAAc,KAAK,cAAc,CAAC,MAAM,EAAE;AACxD,YAAA,IAAI,CAAC,qBAAqB,CAAC,eAAe,EAAE,CAAC;AAC9C,SAAA;KACF;AAED;;;;AAIG;IACH,SAAS,GAAA;AACP,QAAA,OAAO,IAAI,CAAC,cAAc,KAAK,cAAc,CAAC,MAAM,CAAC;KACtD;AAED;;;;AAIG;IACH,UAAU,GAAA;AACR,QAAA,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,qBAAqB,CAAC,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;KAClF;AAED;;;;AAIG;IACH,WAAW,GAAA;AACT,QAAA,OAAO,IAAI,CAAC,cAAc,KAAK,cAAc,CAAC,OAAO,CAAC;KACvD;AAED;;;;AAIG;IACH,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,cAAc,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC;AAC3C,QAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;KAC1B;AAED;;;;AAIG;AACH,IAAA,OAAO,CAAC,QAAmC,EAAA;;AACzC,QAAA,OAAO,CAAA,CAAA,EAAA,GAAA,IAAI,CAAC,YAAY,CAAC,KAAK,MAAG,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,QAAQ,CAAC,KAAK,IAAI,CAAC,uBAAuB,CAAC,aAAqB,CAAC,QAAQ,CAAC,CAAC;KAC7G;AAED;;;;AAIG;AACH,IAAA,QAAQ,CAAC,SAA0E,EAAA;;AACjF,QAAA,OAAO,CAAA,CAAA,EAAA,GAAA,IAAI,CAAC,YAAY,CAAC,mBAAmB,MAAG,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,SAAS,CAAC,KAAK,IAAI,CAAC,uBAAuB,CAAC,cAAsB,CAAC,SAAS,CAAC,CAAC;KAC9H;AAED;;;;AAIG;AACH,IAAA,iBAAiB,CAAC,IAAY,EAAA;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;AACtC,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC;AAC/C,QAAA,MAAM,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;AAE1B,QAAA,MAAM,GAAG,GAAG,CAAC,GAAW,KAAK,GAAG,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAE7D,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE;;;;AAIvD,YAAA,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;AAC1D,SAAA;AACD,QAAA,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;KACxD;;IAGD,KAAK,GAAA;;AACH,QAAA,IAAI,CAAC,qBAAqB,CAAC,WAAW,EAAE,CAAC;QACzC,IAAI,CAAC,cAAc,GAAG,CAAA,EAAA,GAAA,IAAI,CAAC,YAAY,CAAC,iBAAiB,MAAI,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAA,IAAI,CAAC;AAClE,QAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;KAC1B;;qHA/PU,uBAAuB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAC,qBAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,YAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,iBAAA,EAAA,EAAA,EAAA,KAAA,EAAAC,uBAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAvB,uBAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,uBAAuB,6OCrBpC,s8KAqGM,EAAA,MAAA,EAAA,CAAA,m6DAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,IAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,UAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;4FDhFO,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBANnC,SAAS;+BACE,qBAAqB,EAAA,eAAA,EAGd,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,s8KAAA,EAAA,MAAA,EAAA,CAAA,m6DAAA,CAAA,EAAA,CAAA;uMAI/C,WAAW,EAAA,CAAA;sBADV,KAAK;gBAIF,YAAY,EAAA,CAAA;sBADf,KAAK;gBAgCoB,WAAW,EAAA,CAAA;sBAApC,SAAS;uBAAC,aAAa,CAAA;;;ME9Cb,0BAA0B,CAAA;;wHAA1B,0BAA0B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA,CAAA;AAA1B,0BAAA,CAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,0BAA0B,EAJtB,YAAA,EAAA,CAAA,uBAAuB,CAD5B,EAAA,OAAA,EAAA,CAAA,YAAY,aAEZ,uBAAuB,CAAA,EAAA,CAAA,CAAA;AAGtB,0BAAA,CAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,0BAA0B,EAF1B,SAAA,EAAA,CAAC,qBAAqB,CAAC,YAHxB,YAAY,CAAA,EAAA,CAAA,CAAA;4FAKX,0BAA0B,EAAA,UAAA,EAAA,CAAA;kBANtC,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;oBACR,OAAO,EAAE,CAAC,YAAY,CAAC;oBACvB,YAAY,EAAE,CAAC,uBAAuB,CAAC;oBACvC,OAAO,EAAE,CAAC,uBAAuB,CAAC;oBAClC,SAAS,EAAE,CAAC,qBAAqB,CAAC;iBACnC,CAAA;;;ACVD;;AAEG;;;;"}
1
+ {"version":3,"file":"ruc-lib-screen-recorder.mjs","sources":["../../src/lib/models/screen-recorder.models.ts","../../src/lib/screen-recorder/screen-recorder-constant.ts","../../src/lib/services/screen-recorder.service.ts","../../src/lib/screen-recorder/screen-recorder.component.ts","../../src/lib/screen-recorder/screen-recorder.component.html","../../src/lib/ruclib-screen-recorder.module.ts","../../src/ruc-lib-screen-recorder.ts"],"sourcesContent":["export enum ScreenRecorderPosition {\r\n Top = 'top',\r\n Bottom = 'bottom',\r\n Left = 'left',\r\n Right = 'right',\r\n }\r\n \r\n export enum DisplayFormat {\r\n Icon = 'icon',\r\n Text = 'text',\r\n }\r\n \r\n export enum RecordingState {\r\n Idle = 'idle',\r\n Recording = 'recording',\r\n Paused = 'paused',\r\n Stopped = 'stopped',\r\n }\r\n \r\n export interface ScreenRecorderIcons {\r\n record?: string; // Default: '●' (filled circle) or a material icon class\r\n recordWithAudio?: string; // Alternative if specific icon for \"record with audio\" is needed\r\n recordWithoutAudio?: string; // Alternative if specific icon for \"record without audio\" is needed\r\n stop?: string; // Default: '■' (filled square) or a material icon class\r\n pause?: string; // Default: '❚❚' (pause symbol) or a material icon class\r\n resume?: string; // Default: '►' (play symbol) or a material icon class\r\n play?: string; // Default: '►' (play symbol) or a material icon class\r\n download?: string; // Default: '💾' (floppy disk) or a material icon class\r\n audioOn?: string; // Default: '🔊' (speaker high volume) or a material icon class\r\n audioOff?: string; // Default: '🔇' (muted speaker) or a material icon class\r\n }\r\n \r\n export interface ScreenRecorderOptions {\r\n position?: ScreenRecorderPosition;\r\n displayFormat?: DisplayFormat;\r\n showAudioToggle?: boolean;\r\n defaultAudioState?: boolean; // true for audio on, false for audio off\r\n downloadFileName?: string;\r\n icons?: ScreenRecorderIcons; // For custom icons (e.g., CSS classes for icon fonts)\r\n showTimer?: boolean;\r\n showPauseResume?: boolean;\r\n showPlaybackControls?: boolean; // To show/hide the video player preview\r\n showDownloadButton?: boolean;\r\n useUTCForTimer?: boolean;\r\n /* For specific area: getDisplayMedia allows user to choose window/tab/screen.\r\n If a more specific crop is needed, it's outside standard Web API scope.\r\n This option implies we ensure the browser's picker is used.\r\n */\r\n allowSpecificAreaSelection?: boolean;\r\n // Accessibility related texts\r\n accessibilityLabels?: {\r\n recordButton?: string;\r\n stopButton?: string;\r\n pauseButton?: string;\r\n resumeButton?: string;\r\n audioToggleButton?: string;\r\n downloadButton?: string;\r\n playbackVideo?: string;\r\n };\r\n }\r\n ","import { Injectable } from \"@angular/core\";\r\nimport {\r\n ScreenRecorderOptions,\r\n ScreenRecorderPosition,\r\n DisplayFormat,\r\n RecordingState,\r\n ScreenRecorderIcons,\r\n} from '../models/screen-recorder.models';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class ScreenRecorderConstants{\r\n constructor(){\r\n\r\n }\r\n public DEFAULT_ICONS: ScreenRecorderIcons = {\r\n record: 'fiber_manual_record', // Material Icon name\r\n stop: 'stop',\r\n pause: 'pause',\r\n resume: 'play_arrow',\r\n play: 'play_circle_filled',\r\n download: 'download',\r\n audioOn: 'volume_up',\r\n audioOff: 'volume_off',\r\n };\r\n \r\n public DEFAULT_LABELS = {\r\n recordButton: 'Start Recording',\r\n stopButton: 'Stop Recording',\r\n pauseButton: 'Pause Recording',\r\n resumeButton: 'Resume Recording',\r\n audioToggleButton: 'Toggle Audio',\r\n downloadButton: 'Download Recording',\r\n playbackVideo: 'Screen Recording Playback',\r\n };\r\n\r\n public INACTIVE = 'inactive';\r\n\r\n public AUDIO_ON = 'Audio ON';\r\n public AUDIO_OFF = 'Audio OFF';\r\n\r\n public RECORDING_IN_PROGRESS_ERROR = 'Recording is already in progress.';\r\n public FAILED_TO_GET_DISPLAY_MEDIA_STREAM_ERROR = 'Failed to get display media stream';\r\n public NO_SUPPORT_MIME = 'No supported MIME type found for MediaRecorder.';\r\n public NO_RECORDING_DOWNLOAD = 'No recording available to download.';\r\n public MEDIA_ERROR = 'MediaRecorder error';\r\n public PERMISSION_DENIED = \"Error starting screen recording: NotAllowedError - Permission denied\";\r\n public NO_SUPPORT = 'Screen recording is not supported in this browser.';\r\n\r\n}","import { Injectable } from '@angular/core';\r\nimport { BehaviorSubject, Observable, Subject, timer } from 'rxjs';\r\nimport { takeWhile, tap } from 'rxjs/operators';\r\nimport { RecordingState } from '../models/screen-recorder.models';\r\nimport { ScreenRecorderConstants } from '../screen-recorder/screen-recorder-constant';\r\n@Injectable({\r\n providedIn: 'root', // Or provide in your module if preferred\r\n})\r\nexport class ScreenRecorderService {\r\n private stream: MediaStream | null = null;\r\n private mediaRecorder: MediaRecorder | null = null;\r\n private recordedBlobs: Blob[] = [];\r\n private timerSubscription: any;\r\n private currentRecordedTime: number = 0;\r\n\r\n private readonly recordingStateSubject = new BehaviorSubject<RecordingState>(RecordingState.Idle);\r\n readonly recordingState$: Observable<RecordingState> = this.recordingStateSubject.asObservable();\r\n\r\n private readonly recordedTimeSubject = new BehaviorSubject<number>(0);\r\n readonly recordedTime$: Observable<number> = this.recordedTimeSubject.asObservable();\r\n\r\n private readonly recordedUrlSubject = new BehaviorSubject<string | null>(null);\r\n readonly recordedUrl$: Observable<string | null> = this.recordedUrlSubject.asObservable();\r\n\r\n private readonly recordingTimestampSubject = new BehaviorSubject<string>('');\r\n readonly recordingTimestamp$: Observable<string> = this.recordingTimestampSubject.asObservable();\r\n\r\n private readonly errorSubject = new Subject<string>();\r\n readonly error$: Observable<string> = this.errorSubject.asObservable();\r\n\r\n constructor(public screenRecordingConstant: ScreenRecorderConstants) { }\r\n\r\n /**\r\n * Starts the screen recording with optional audio\r\n * \r\n * @param options - Configuration options for recording\r\n * @param options.audio - Whether to include audio in the recording\r\n * \r\n * @throws Error if recording is already in progress or if media access is denied\r\n * @returns Promise<void>\r\n */\r\n async startRecording(options: { audio: boolean }): Promise<void> {\r\n\r\n if (this.recordingStateSubject.value === RecordingState.Recording || this.recordingStateSubject.value === RecordingState.Paused) {\r\n this.handleError(this.screenRecordingConstant.RECORDING_IN_PROGRESS_ERROR);\r\n return;\r\n }\r\n\r\n this.cleanupPreviousRecording();\r\n\r\n try {\r\n // The browser's native picker handles \"specific area\" selection (window, tab, screen).\r\n const displayStream = await navigator.mediaDevices.getDisplayMedia({\r\n video: true\r\n });\r\n\r\n // If audio is enabled, get the audio stream\r\n let audioStream: MediaStream | null = null;\r\n if (options.audio) {\r\n audioStream = await navigator.mediaDevices.getUserMedia({\r\n audio: {\r\n echoCancellation: true,\r\n noiseSuppression: true,\r\n sampleRate: 44100\r\n }\r\n });\r\n }\r\n\r\n // Combine the streams if audio is enabled\r\n if (audioStream) {\r\n this.stream = new MediaStream([...displayStream.getTracks(), ...audioStream.getTracks()]);\r\n } else {\r\n this.stream = displayStream;\r\n }\r\n\r\n // Listen for when the user stops sharing via browser UI\r\n this.stream.getVideoTracks()[0].onended = () => {\r\n if (this.recordingStateSubject.value === RecordingState.Recording || this.recordingStateSubject.value === RecordingState.Paused) {\r\n this.stopRecordingInternal();\r\n }\r\n };\r\n\r\n // Handle errors\r\n if (!this.stream) {\r\n this.handleError(this.screenRecordingConstant.FAILED_TO_GET_DISPLAY_MEDIA_STREAM_ERROR);\r\n return;\r\n }\r\n\r\n // Set recording timestamp\r\n const now = new Date();\r\n const timestamp = now.toLocaleString('en-IN', {\r\n year: 'numeric',\r\n month: '2-digit',\r\n day: '2-digit',\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n hour12: true\r\n });\r\n this.recordingTimestampSubject.next(timestamp);\r\n\r\n\r\n this.recordedBlobs = [];\r\n const mimeType = this.getSupportedMimeType();\r\n if (!mimeType) {\r\n this.handleError(this.screenRecordingConstant.NO_SUPPORT_MIME);\r\n this.stream?.getTracks().forEach(track => track.stop());\r\n this.stream = null;\r\n return;\r\n }\r\n\r\n // Create a canvas for timestamp overlay\r\n const canvas = document.createElement('canvas');\r\n const videoTrack = this.stream?.getVideoTracks()[0];\r\n if (videoTrack) {\r\n const video = document.createElement('video');\r\n video.srcObject = this.stream;\r\n\r\n // Wait for video to load metadata\r\n video.onloadedmetadata = () => {\r\n canvas.width = video.videoWidth;\r\n canvas.height = video.videoHeight;\r\n const ctx = canvas.getContext('2d');\r\n if (ctx) {\r\n // Draw video frame\r\n ctx.drawImage(video, 0, 0);\r\n\r\n // Draw timestamp\r\n ctx.font = '16px Arial';\r\n ctx.fillStyle = 'white';\r\n ctx.textAlign = 'right';\r\n ctx.textBaseline = 'top';\r\n ctx.fillText(`Recorded on: ${this.recordingTimestampSubject.value}`, canvas.width - 10, 10);\r\n }\r\n };\r\n }\r\n\r\n // Create a new stream with the canvas\r\n const canvasStream = canvas.captureStream();\r\n const combinedStream = new MediaStream([...this.stream?.getTracks() ?? [], canvasStream.getVideoTracks()[0]]);\r\n\r\n this.mediaRecorder = new MediaRecorder(combinedStream, { mimeType });\r\n\r\n this.mediaRecorder.ondataavailable = (event) => {\r\n if (event.data && event.data.size > 0) {\r\n this.recordedBlobs.push(event.data);\r\n }\r\n };\r\n\r\n this.mediaRecorder.onstop = () => {\r\n const superBuffer = new Blob(this.recordedBlobs, { type: mimeType });\r\n const url = window.URL.createObjectURL(superBuffer);\r\n this.recordedUrlSubject.next(url);\r\n this.recordingStateSubject.next(RecordingState.Stopped);\r\n this.stopTimer();\r\n\r\n };\r\n\r\n this.mediaRecorder.onerror = (event: Event) => {\r\n const errorEvent = event as ErrorEvent; // More specific type if available\r\n let message = this.screenRecordingConstant.MEDIA_ERROR;\r\n if (errorEvent.error && errorEvent.error.name) {\r\n message += `: ${errorEvent.error.name}`;\r\n if (errorEvent.error.message) message += ` - ${errorEvent.error.message}`;\r\n }\r\n this.handleError(message);\r\n this.recordingStateSubject.next(RecordingState.Idle);\r\n this.stopTimer();\r\n };\r\n\r\n this.mediaRecorder.start(); // Start recording\r\n this.recordingStateSubject.next(RecordingState.Recording);\r\n this.startTimer();\r\n } catch (err: any) {\r\n this.handleError(`Error starting screen recording: ${err.name} - ${err.message}`);\r\n this.recordingStateSubject.next(RecordingState.Idle);\r\n }\r\n }\r\n\r\n /**\r\n * Gets the first supported MIME type for MediaRecorder\r\n * \r\n * @returns string|null - The supported MIME type or null if none found\r\n */\r\n private getSupportedMimeType(): string | null {\r\n const mimeTypes = [\r\n 'video/webm;codecs=vp9,opus',\r\n 'video/webm;codecs=vp8,opus',\r\n 'video/webm;codecs=h264,opus',\r\n 'video/mp4;codecs=h264,aac', // MP4 might have broader compatibility but less browser support for recording\r\n 'video/webm',\r\n ];\r\n for (const mimeType of mimeTypes) {\r\n if (MediaRecorder.isTypeSupported(mimeType)) {\r\n return mimeType;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Internal method to stop the recording process\r\n * \r\n * @private\r\n * @returns void\r\n */\r\n private stopRecordingInternal(): void {\r\n if (this.mediaRecorder && (this.recordingStateSubject.value === RecordingState.Recording || this.recordingStateSubject.value === RecordingState.Paused)) {\r\n this.mediaRecorder.stop();\r\n }\r\n this.stream?.getTracks().forEach(track => track.stop());\r\n this.stream = null;\r\n // State will be updated by onstop handler\r\n }\r\n\r\n /**\r\n * \r\n * @returns Promise<void>\r\n * @throws Error if recording is not in progress\r\n */\r\n stopRecording(): void {\r\n this.stopRecordingInternal();\r\n }\r\n\r\n /**\r\n * Pauses the current recording\r\n * \r\n * @returns Promise<void>\r\n * @throws Error if recording is not in progress\r\n */\r\n pauseRecording(): void {\r\n if (this.mediaRecorder && this.recordingStateSubject.value === RecordingState.Recording) {\r\n this.mediaRecorder.pause();\r\n this.recordingStateSubject.next(RecordingState.Paused);\r\n this.stopTimer(); // Pauses the timer display\r\n }\r\n }\r\n\r\n /**\r\n * Resumes a paused recording\r\n * \r\n * @returns Promise<void>\r\n * @throws Error if recording is not paused\r\n */\r\n resumeRecording(): void {\r\n if (this.mediaRecorder && this.recordingStateSubject.value === RecordingState.Paused) {\r\n this.mediaRecorder.resume();\r\n this.recordingStateSubject.next(RecordingState.Recording);\r\n this.startTimer(this.currentRecordedTime); // Resumes timer display\r\n }\r\n }\r\n\r\n /**\r\n * \r\n * @param fileName \r\n */\r\n downloadRecording(fileName: string = 'recording.webm'): void {\r\n const url = this.recordedUrlSubject.value;\r\n const timestamp = this.recordingTimestampSubject.value;\r\n\r\n if (url && timestamp) {\r\n // Format the timestamp for filename (remove spaces and special characters)\r\n const formattedTimestamp = timestamp.replace(/[^a-zA-Z0-9]/g, '_');\r\n // Create filename with timestamp\r\n const fileExtension = fileName.split('.').pop() || 'webm';\r\n const newFileName = `screen_recording_${formattedTimestamp}.${fileExtension}`;\r\n\r\n const a = document.createElement('a');\r\n a.style.display = 'none';\r\n a.href = url;\r\n a.download = newFileName;\r\n document.body.appendChild(a);\r\n a.click();\r\n document.body.removeChild(a);\r\n // No need to revoke URL here if user might want to play it again.\r\n // Revoke on cleanup or new recording.\r\n } else {\r\n this.handleError(this.screenRecordingConstant.NO_RECORDING_DOWNLOAD);\r\n }\r\n }\r\n\r\n /**\r\n * Starts the recording timer\r\n * \r\n * @param startTime - Optional start time for the timer\r\n * @private\r\n * @returns void\r\n */\r\n private startTimer(startTime: number = 0): void {\r\n this.stopTimer(); // Ensure no multiple timers\r\n this.currentRecordedTime = startTime;\r\n this.recordedTimeSubject.next(this.currentRecordedTime);\r\n\r\n this.timerSubscription = timer(0, 1000)\r\n .pipe(\r\n tap(() => {\r\n if (this.recordingStateSubject.value === RecordingState.Recording) {\r\n this.currentRecordedTime++;\r\n this.recordedTimeSubject.next(this.currentRecordedTime);\r\n }\r\n }),\r\n takeWhile(() => this.recordingStateSubject.value === RecordingState.Recording)\r\n )\r\n .subscribe();\r\n }\r\n\r\n /**\r\n * Stops the recording timer\r\n * \r\n * @private\r\n * @returns void\r\n */\r\n private stopTimer(): void {\r\n if (this.timerSubscription) {\r\n this.timerSubscription.unsubscribe();\r\n this.timerSubscription = null;\r\n }\r\n }\r\n\r\n /**\r\n * Cleans up resources from previous recording\r\n * \r\n * @private\r\n * @returns void\r\n */\r\n private cleanupPreviousRecording(): void {\r\n if (this.recordedUrlSubject.value) {\r\n window.URL.revokeObjectURL(this.recordedUrlSubject.value);\r\n this.recordedUrlSubject.next(null);\r\n }\r\n this.recordedBlobs = [];\r\n this.currentRecordedTime = 0;\r\n this.recordedTimeSubject.next(0);\r\n if (this.stream) {\r\n this.stream.getTracks().forEach(track => track.stop());\r\n this.stream = null;\r\n }\r\n if (this.mediaRecorder && this.mediaRecorder.state !== this.screenRecordingConstant.INACTIVE) {\r\n this.mediaRecorder.stop();\r\n }\r\n this.mediaRecorder = null;\r\n }\r\n\r\n\r\n /**\r\n * Resets the recording state to idle\r\n * \r\n * @returns void\r\n */\r\n resetToIdle(): void {\r\n this.cleanupPreviousRecording();\r\n this.recordingStateSubject.next(RecordingState.Idle);\r\n this.errorSubject.next(''); // Clear any previous errors\r\n }\r\n\r\n\r\n /**\r\n * Handles and broadcasts recording errors\r\n * \r\n * @private\r\n * @param error - The error message to handle\r\n * @returns void\r\n */\r\n private handleError(error: string): void {\r\n this.errorSubject.next(error);\r\n }\r\n}\r\n","import { Component, Input, OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef, ViewChild, ElementRef } from '@angular/core';\r\nimport { DomSanitizer, SafeUrl } from '@angular/platform-browser';\r\nimport { Subscription } from 'rxjs';\r\nimport {\r\n ScreenRecorderOptions,\r\n ScreenRecorderPosition,\r\n DisplayFormat,\r\n RecordingState,\r\n ScreenRecorderIcons,\r\n} from '../models/screen-recorder.models';\r\nimport { ScreenRecorderService } from '../services/screen-recorder.service';\r\nimport { ScreenRecorderConstants } from './screen-recorder-constant';\r\n\r\n\r\n\r\n@Component({\r\n selector: 'uxp-ruclib-screen-recorder',\r\n templateUrl: './screen-recorder.component.html',\r\n styleUrls: ['./screen-recorder.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class ScreenRecorderComponent implements OnInit, OnDestroy {\r\n @Input()\r\n customTheme: any;\r\n \r\n @Input()\r\n set rucInputData(value: ScreenRecorderOptions) {\r\n this._options = {\r\n position: ScreenRecorderPosition.Bottom,\r\n displayFormat: DisplayFormat.Icon,\r\n showAudioToggle: true,\r\n defaultAudioState: true,\r\n downloadFileName: 'screen-recording.webm',\r\n icons: { ...this.screenRecordingConstant.DEFAULT_ICONS },\r\n showTimer: true,\r\n showPauseResume: true,\r\n showPlaybackControls: true,\r\n showDownloadButton: true,\r\n useUTCForTimer: false,\r\n allowSpecificAreaSelection: true, // Default to allowing browser's native picker\r\n accessibilityLabels: { ...this.screenRecordingConstant.DEFAULT_LABELS },\r\n ...value,\r\n };\r\n // Deep merge icons and labels\r\n if (value.icons) {\r\n this._options.icons = { ...this.screenRecordingConstant.DEFAULT_ICONS, ...value.icons };\r\n }\r\n if (value.accessibilityLabels) {\r\n this._options.accessibilityLabels = { ...this.screenRecordingConstant.DEFAULT_LABELS, ...value.accessibilityLabels };\r\n }\r\n this.isAudioEnabled = this._options.defaultAudioState ?? true;\r\n }\r\n get rucInputData(): ScreenRecorderOptions {\r\n return this._options;\r\n }\r\n private _options!: ScreenRecorderOptions;\r\n\r\n @ViewChild('videoPlayer') videoPlayer!: ElementRef<HTMLVideoElement>;\r\n\r\n recordingState: RecordingState = RecordingState.Idle;\r\n recordedTime: number = 0;\r\n formattedTime: string = '00:00:00';\r\n safeRecordedUrl: SafeUrl | null = null;\r\n recordingTimestamp: string = '';\r\n /**\r\n * Checks if recording is currently in progress\r\n * \r\n * @returns boolean - True if recording is in progress, false otherwise\r\n */\r\n isRecordingInProgress(): boolean {\r\n return this.recordingState === RecordingState.Recording;\r\n }\r\n errorMessage: string | null = null;\r\n isBrowserSupported: boolean = true;\r\n isAudioEnabled: boolean = true;\r\n\r\n /**\r\n * Gets the appropriate icon for recording based on audio state and settings\r\n * @returns string - The icon name to display\r\n */\r\n getRecordingIcon(): string {\r\n if (this.isAudioEnabled && this.rucInputData.showAudioToggle) {\r\n return this.getIcon('recordWithAudio');\r\n }\r\n return this.getIcon('record');\r\n }\r\n\r\n // Expose enums to template\r\n DisplayFormat = DisplayFormat;\r\n RecordingState = RecordingState;\r\n ScreenRecorderPosition = ScreenRecorderPosition;\r\n\r\n private subscriptions = new Subscription();\r\n\r\n constructor(\r\n public screenRecorderService: ScreenRecorderService,\r\n private sanitizer: DomSanitizer,\r\n private cdr: ChangeDetectorRef,\r\n public screenRecordingConstant: ScreenRecorderConstants\r\n ) {\r\n\r\n // Initialize with default options. The setter will override if an input is provided.\r\n if (!this._options) {\r\n this.rucInputData = {}; // Trigger setter with empty object to apply defaults\r\n }\r\n } \r\n\r\n ngOnInit(): void {\r\n this.subscriptions.add(\r\n this.screenRecorderService.recordingState$.subscribe((state) => {\r\n this.recordingState = state;\r\n if (state === RecordingState.Idle || state === RecordingState.Stopped) {\r\n // Ensure audio toggle is reset to default if needed, or based on user action\r\n }\r\n this.cdr.detectChanges();\r\n })\r\n );\r\n\r\n this.subscriptions.add(\r\n this.screenRecorderService.recordingTimestamp$.subscribe((timestamp) => {\r\n this.recordingTimestamp = timestamp;\r\n this.cdr.detectChanges();\r\n })\r\n );\r\n\r\n this.subscriptions.add(\r\n this.screenRecorderService.recordedTime$.subscribe((time) => {\r\n this.recordedTime = time;\r\n this.formattedTime = this.formatTimeDisplay(time);\r\n this.cdr.detectChanges();\r\n })\r\n );\r\n\r\n this.subscriptions.add(\r\n this.screenRecorderService.recordedUrl$.subscribe((url) => {\r\n this.safeRecordedUrl = url ? this.sanitizer.bypassSecurityTrustUrl(url) : null;\r\n this.cdr.detectChanges();\r\n })\r\n );\r\n\r\n this.subscriptions.add(\r\n this.screenRecorderService.error$.subscribe((error) => {\r\n if(error != this.screenRecordingConstant.PERMISSION_DENIED){\r\n this.errorMessage = error;\r\n }\r\n this.cdr.detectChanges();\r\n })\r\n );\r\n }\r\n\r\n ngOnDestroy() {\r\n if (this.subscriptions) {\r\n this.subscriptions.unsubscribe();\r\n }\r\n }\r\n\r\n /**\r\n * Toggles the recording state between start and stop\r\n * \r\n * @returns Promise<void>\r\n */\r\n async toggleRecord(): Promise<void> {\r\n this.errorMessage = null; // Clear previous errors\r\n if (this.recordingState === RecordingState.Idle || this.recordingState === RecordingState.Stopped) {\r\n // Set recording timestamp when starting recording\r\n const now = new Date();\r\n this.recordingTimestamp = now.toLocaleString('en-IN', {\r\n year: 'numeric',\r\n month: '2-digit',\r\n day: '2-digit',\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n hour12: true\r\n });\r\n await this.screenRecorderService.startRecording({ audio: this.isAudioEnabled });\r\n } else {\r\n this.screenRecorderService.stopRecording();\r\n }\r\n }\r\n\r\n /**\r\n * Toggles between pause and resume states during recording\r\n * \r\n * @returns void\r\n */\r\n togglePauseResume(): void {\r\n this.errorMessage = null;\r\n if (this.recordingState === RecordingState.Recording) {\r\n this.screenRecorderService.pauseRecording();\r\n } else if (this.recordingState === RecordingState.Paused) {\r\n this.screenRecorderService.resumeRecording();\r\n }\r\n }\r\n\r\n /**\r\n * Checks if recording can be resumed\r\n * \r\n * @returns boolean - True if recording can be resumed, false otherwise\r\n */\r\n canResume(): boolean {\r\n return this.recordingState === RecordingState.Paused;\r\n }\r\n\r\n /**\r\n * Downloads the recorded video file\r\n * \r\n * @returns void\r\n */\r\n onDownload(): void {\r\n this.errorMessage = null;\r\n this.screenRecorderService.downloadRecording(this.rucInputData.downloadFileName);\r\n }\r\n\r\n /**\r\n * Checks if recording can be downloaded\r\n * \r\n * @returns boolean - True if recording can be downloaded, false otherwise\r\n */\r\n canDownload(): boolean {\r\n return this.recordingState === RecordingState.Stopped;\r\n }\r\n\r\n /**\r\n * Toggles audio recording on/off\r\n * \r\n * @returns void\r\n */\r\n toggleAudio(): void {\r\n this.isAudioEnabled = !this.isAudioEnabled;\r\n this.cdr.detectChanges();\r\n }\r\n\r\n /**\r\n * \r\n * @param iconName \r\n * @returns \r\n */\r\n getIcon(iconName: keyof ScreenRecorderIcons): string {\r\n return this.rucInputData.icons?.[iconName] || (this.screenRecordingConstant.DEFAULT_ICONS as any)[iconName];\r\n }\r\n\r\n /**\r\n * \r\n * @param labelName \r\n * @returns \r\n */\r\n getLabel(labelName: keyof NonNullable<ScreenRecorderOptions['accessibilityLabels']>): string {\r\n return this.rucInputData.accessibilityLabels?.[labelName] || (this.screenRecordingConstant.DEFAULT_LABELS as any)[labelName];\r\n }\r\n\r\n /**\r\n * \r\n * @param time - The time in seconds to format\r\n * @returns string - Formatted time string (HH:MM:SS)\r\n */\r\n formatTimeDisplay(time: number): string {\r\n const hours = Math.floor(time / 3600);\r\n const minutes = Math.floor((time % 3600) / 60);\r\n const seconds = time % 60;\r\n\r\n const pad = (num: number) => num.toString().padStart(2, '0');\r\n\r\n if (this.rucInputData && this.rucInputData.useUTCForTimer) {\r\n // This is a simple duration format, not a specific UTC time.\r\n // For actual UTC time of day, you'd use new Date().toUTCString() or similar.\r\n // Assuming timer should show elapsed time formatted as HH:MM:SS.\r\n return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;\r\n }\r\n return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;\r\n }\r\n\r\n // Method to reset the component and service to initial state\r\n reset(): void {\r\n this.screenRecorderService.resetToIdle();\r\n this.isAudioEnabled = this.rucInputData.defaultAudioState ?? true;\r\n this.cdr.detectChanges();\r\n }\r\n}\r\n\r\n","<div class=\"main\">\r\n <div class=\"screen-recorder-controls\"\r\n [ngClass]=\"customTheme + ' position-' + (rucInputData.position || ScreenRecorderPosition.Bottom)\"\r\n *ngIf=\"isBrowserSupported\">\r\n\r\n <!-- Error Message -->\r\n <div *ngIf=\"errorMessage\" class=\"recorder-error\">\r\n {{ errorMessage }}\r\n </div>\r\n\r\n <!-- Record/Stop Button -->\r\n <button *ngIf=\"recordingState === RecordingState.Idle || recordingState === RecordingState.Stopped\"\r\n (click)=\"toggleRecord()\" [attr.aria-label]=\"getLabel('recordButton')\" [attr.aria-pressed]=\"false\"\r\n class=\"recorder-button record-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getRecordingIcon() || getIcon('record') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('recordButton')\r\n }}</ng-container>\r\n </button>\r\n\r\n <button *ngIf=\"recordingState === RecordingState.Recording || recordingState === RecordingState.Paused\"\r\n (click)=\"toggleRecord()\" [attr.aria-label]=\"getLabel('stopButton')\" [attr.aria-pressed]=\"true\"\r\n class=\"recorder-button stop-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('stop') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('stopButton')\r\n }}</ng-container>\r\n </button>\r\n\r\n <!-- Pause/Resume Button -->\r\n <button *ngIf=\"rucInputData.showPauseResume && recordingState === RecordingState.Recording\"\r\n (click)=\"togglePauseResume()\" [attr.aria-label]=\"getLabel('pauseButton')\" [attr.aria-pressed]=\"false\"\r\n class=\"recorder-button pause-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('pause') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('pauseButton')\r\n }}</ng-container>\r\n </button>\r\n <button *ngIf=\"rucInputData.showPauseResume && recordingState === RecordingState.Paused\"\r\n (click)=\"togglePauseResume()\" [attr.aria-label]=\"getLabel('resumeButton')\" [attr.aria-pressed]=\"true\"\r\n class=\"recorder-button resume-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('resume') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('resumeButton')\r\n }}</ng-container>\r\n </button>\r\n\r\n <!-- Audio Toggle Button -->\r\n <button\r\n *ngIf=\"rucInputData.showAudioToggle && (recordingState === RecordingState.Idle || recordingState === RecordingState.Stopped)\"\r\n (click)=\"toggleAudio()\" [attr.aria-label]=\"getLabel('audioToggleButton')\" [attr.aria-pressed]=\"isAudioEnabled\"\r\n class=\"recorder-button audio-toggle-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ isAudioEnabled ? getIcon('audioOn') : getIcon('audioOff') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">\r\n {{ isAudioEnabled ? screenRecordingConstant.AUDIO_ON : screenRecordingConstant.AUDIO_OFF }}\r\n </ng-container>\r\n </button>\r\n\r\n <!-- Timer -->\r\n <div\r\n *ngIf=\"rucInputData.showTimer && (recordingState === RecordingState.Recording || recordingState === RecordingState.Paused)\"\r\n class=\"recorder-timer\" aria-live=\"polite\" aria-atomic=\"true\">\r\n {{ formattedTime }}\r\n </div>\r\n\r\n <!-- Download Button -->\r\n <button *ngIf=\"rucInputData.showDownloadButton && recordingState === RecordingState.Stopped && safeRecordedUrl\"\r\n (click)=\"onDownload()\" [attr.aria-label]=\"getLabel('downloadButton')\" class=\"recorder-button download-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('download') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('downloadButton')\r\n }}</ng-container>\r\n </button>\r\n\r\n <!-- Playback Area -->\r\n <div *ngIf=\"rucInputData.showPlaybackControls && recordingState === RecordingState.Stopped && safeRecordedUrl\"\r\n class=\"playback-area\">\r\n <video #videoPlayer [src]=\"safeRecordedUrl\" controls [attr.aria-label]=\"getLabel('playbackVideo')\"></video>\r\n <div class=\"video-timer-overlay\">\r\n <span>Recorded on: {{ recordingTimestamp }}</span>\r\n </div>\r\n </div>\r\n\r\n <!-- Reset Button (optional, good for testing/clearing state) -->\r\n <button *ngIf=\"recordingState === RecordingState.Stopped && safeRecordedUrl\" (click)=\"reset()\"\r\n aria-label=\"New Recording\" class=\"recorder-button reset-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">refresh</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">New</ng-container>\r\n </button>\r\n\r\n </div>\r\n\r\n <div *ngIf=\"!isBrowserSupported\" class=\"recorder-notsupported\" [ngClass]=\"customTheme\">\r\n {{screenRecordingConstant.NO_SUPPORT}}\r\n </div>\r\n</div>","import { NgModule } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { ScreenRecorderComponent } from './screen-recorder/screen-recorder.component';\r\nimport { ScreenRecorderService } from './services/screen-recorder.service';\r\n\r\n@NgModule({\r\n imports: [CommonModule],\r\n declarations: [ScreenRecorderComponent],\r\n exports: [ScreenRecorderComponent],\r\n providers: [ScreenRecorderService],\r\n})\r\nexport class RuclibScreenRecorderModule {}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1.ScreenRecorderConstants","i1.ScreenRecorderService","i3.ScreenRecorderConstants"],"mappings":";;;;;;;;;AAAY,IAAA,uBAKT;AALH,CAAA,UAAY,sBAAsB,EAAA;AAC9B,IAAA,sBAAA,CAAA,KAAA,CAAA,GAAA,KAAW,CAAA;AACX,IAAA,sBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACjB,IAAA,sBAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACb,IAAA,sBAAA,CAAA,OAAA,CAAA,GAAA,OAAe,CAAA;AACjB,CAAC,EALS,sBAAsB,KAAtB,sBAAsB,GAK/B,EAAA,CAAA,CAAA,CAAA;AAEW,IAAA,cAGX;AAHD,CAAA,UAAY,aAAa,EAAA;AACvB,IAAA,aAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACb,IAAA,aAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACf,CAAC,EAHW,aAAa,KAAb,aAAa,GAGxB,EAAA,CAAA,CAAA,CAAA;AAEW,IAAA,eAKX;AALD,CAAA,UAAY,cAAc,EAAA;AACxB,IAAA,cAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACb,IAAA,cAAA,CAAA,WAAA,CAAA,GAAA,WAAuB,CAAA;AACvB,IAAA,cAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACjB,IAAA,cAAA,CAAA,SAAA,CAAA,GAAA,SAAmB,CAAA;AACrB,CAAC,EALW,cAAc,KAAd,cAAc,GAKzB,EAAA,CAAA,CAAA;;MCLU,uBAAuB,CAAA;AAChC,IAAA,WAAA,GAAA;QAGO,IAAA,CAAA,aAAa,GAAwB;AAC1C,YAAA,MAAM,EAAE,qBAAqB;AAC7B,YAAA,IAAI,EAAE,MAAM;AACZ,YAAA,KAAK,EAAE,OAAO;AACd,YAAA,MAAM,EAAE,YAAY;AACpB,YAAA,IAAI,EAAE,oBAAoB;AAC1B,YAAA,QAAQ,EAAE,UAAU;AACpB,YAAA,OAAO,EAAE,WAAW;AACpB,YAAA,QAAQ,EAAE,YAAY;SACvB,CAAC;QAEK,IAAA,CAAA,cAAc,GAAG;AACtB,YAAA,YAAY,EAAE,iBAAiB;AAC/B,YAAA,UAAU,EAAE,gBAAgB;AAC5B,YAAA,WAAW,EAAE,iBAAiB;AAC9B,YAAA,YAAY,EAAE,kBAAkB;AAChC,YAAA,iBAAiB,EAAE,cAAc;AACjC,YAAA,cAAc,EAAE,oBAAoB;AACpC,YAAA,aAAa,EAAE,2BAA2B;SAC3C,CAAC;AAEK,QAAA,IAAQ,CAAA,QAAA,GAAG,UAAU,CAAC;AAEtB,QAAA,IAAQ,CAAA,QAAA,GAAG,UAAU,CAAC;AACtB,QAAA,IAAS,CAAA,SAAA,GAAG,WAAW,CAAC;AAExB,QAAA,IAA2B,CAAA,2BAAA,GAAG,mCAAmC,CAAC;AAClE,QAAA,IAAwC,CAAA,wCAAA,GAAG,oCAAoC,CAAC;AAChF,QAAA,IAAe,CAAA,eAAA,GAAG,iDAAiD,CAAC;AACpE,QAAA,IAAqB,CAAA,qBAAA,GAAG,qCAAqC,CAAC;AAC9D,QAAA,IAAW,CAAA,WAAA,GAAG,qBAAqB,CAAC;AACpC,QAAA,IAAiB,CAAA,iBAAA,GAAG,sEAAsE,CAAC;AAC3F,QAAA,IAAU,CAAA,UAAA,GAAG,oDAAoD,CAAC;KAjCxE;;qHAHQ,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAvB,uBAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,uBAAuB,cAFpB,MAAM,EAAA,CAAA,CAAA;4FAET,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBAHnC,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,UAAU,EAAE,MAAM;iBACrB,CAAA;;;MCHY,qBAAqB,CAAA;AAsBhC,IAAA,WAAA,CAAmB,uBAAgD,EAAA;AAAhD,QAAA,IAAuB,CAAA,uBAAA,GAAvB,uBAAuB,CAAyB;AArB3D,QAAA,IAAM,CAAA,MAAA,GAAuB,IAAI,CAAC;AAClC,QAAA,IAAa,CAAA,aAAA,GAAyB,IAAI,CAAC;AAC3C,QAAA,IAAa,CAAA,aAAA,GAAW,EAAE,CAAC;AAE3B,QAAA,IAAmB,CAAA,mBAAA,GAAW,CAAC,CAAC;QAEvB,IAAqB,CAAA,qBAAA,GAAG,IAAI,eAAe,CAAiB,cAAc,CAAC,IAAI,CAAC,CAAC;QACzF,IAAA,CAAA,eAAe,GAA+B,IAAI,CAAC,qBAAqB,CAAC,YAAY,EAAE,CAAC;QAEhF,IAAA,CAAA,mBAAmB,GAAG,IAAI,eAAe,CAAS,CAAC,CAAC,CAAC;QAC7D,IAAA,CAAA,aAAa,GAAuB,IAAI,CAAC,mBAAmB,CAAC,YAAY,EAAE,CAAC;QAEpE,IAAA,CAAA,kBAAkB,GAAG,IAAI,eAAe,CAAgB,IAAI,CAAC,CAAC;QACtE,IAAA,CAAA,YAAY,GAA8B,IAAI,CAAC,kBAAkB,CAAC,YAAY,EAAE,CAAC;QAEzE,IAAA,CAAA,yBAAyB,GAAG,IAAI,eAAe,CAAS,EAAE,CAAC,CAAC;QACpE,IAAA,CAAA,mBAAmB,GAAuB,IAAI,CAAC,yBAAyB,CAAC,YAAY,EAAE,CAAC;AAEhF,QAAA,IAAA,CAAA,YAAY,GAAG,IAAI,OAAO,EAAU,CAAC;QAC7C,IAAA,CAAA,MAAM,GAAuB,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC;KAEC;AAExE;;;;;;;;AAQG;AACG,IAAA,cAAc,CAAC,OAA2B,EAAA;;;AAE9C,YAAA,IAAI,IAAI,CAAC,qBAAqB,CAAC,KAAK,KAAK,cAAc,CAAC,SAAS,IAAI,IAAI,CAAC,qBAAqB,CAAC,KAAK,KAAK,cAAc,CAAC,MAAM,EAAE;gBAC/H,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,uBAAuB,CAAC,2BAA2B,CAAC,CAAC;gBAC3E,OAAO;AACR,aAAA;YAED,IAAI,CAAC,wBAAwB,EAAE,CAAC;YAEhC,IAAI;;gBAEF,MAAM,aAAa,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,eAAe,CAAC;AACjE,oBAAA,KAAK,EAAE,IAAI;AACZ,iBAAA,CAAC,CAAC;;gBAGH,IAAI,WAAW,GAAuB,IAAI,CAAC;gBAC3C,IAAI,OAAO,CAAC,KAAK,EAAE;AACjB,oBAAA,WAAW,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC;AACtD,wBAAA,KAAK,EAAE;AACL,4BAAA,gBAAgB,EAAE,IAAI;AACtB,4BAAA,gBAAgB,EAAE,IAAI;AACtB,4BAAA,UAAU,EAAE,KAAK;AAClB,yBAAA;AACF,qBAAA,CAAC,CAAC;AACJ,iBAAA;;AAGD,gBAAA,IAAI,WAAW,EAAE;oBACf,IAAI,CAAC,MAAM,GAAG,IAAI,WAAW,CAAC,CAAC,GAAG,aAAa,CAAC,SAAS,EAAE,EAAE,GAAG,WAAW,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;AAC3F,iBAAA;AAAM,qBAAA;AACL,oBAAA,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC;AAC7B,iBAAA;;AAGD,gBAAA,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,MAAK;AAC7C,oBAAA,IAAI,IAAI,CAAC,qBAAqB,CAAC,KAAK,KAAK,cAAc,CAAC,SAAS,IAAI,IAAI,CAAC,qBAAqB,CAAC,KAAK,KAAK,cAAc,CAAC,MAAM,EAAE;wBAC/H,IAAI,CAAC,qBAAqB,EAAE,CAAC;AAC9B,qBAAA;AACH,iBAAC,CAAC;;AAGF,gBAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;oBAChB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,uBAAuB,CAAC,wCAAwC,CAAC,CAAC;oBACxF,OAAO;AACR,iBAAA;;AAGD,gBAAA,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;AACvB,gBAAA,MAAM,SAAS,GAAG,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE;AAC5C,oBAAA,IAAI,EAAE,SAAS;AACf,oBAAA,KAAK,EAAE,SAAS;AAChB,oBAAA,GAAG,EAAE,SAAS;AACd,oBAAA,IAAI,EAAE,SAAS;AACf,oBAAA,MAAM,EAAE,SAAS;AACjB,oBAAA,MAAM,EAAE,IAAI;AACb,iBAAA,CAAC,CAAC;AACH,gBAAA,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAG/C,gBAAA,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;AACxB,gBAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;gBAC7C,IAAI,CAAC,QAAQ,EAAE;oBACb,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,uBAAuB,CAAC,eAAe,CAAC,CAAC;AAC/D,oBAAA,CAAA,EAAA,GAAA,IAAI,CAAC,MAAM,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,SAAS,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;AACxD,oBAAA,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;oBACnB,OAAO;AACR,iBAAA;;gBAGD,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;gBAChD,MAAM,UAAU,GAAG,CAAA,EAAA,GAAA,IAAI,CAAC,MAAM,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAE,cAAc,EAAA,CAAG,CAAC,CAAC,CAAC;AACpD,gBAAA,IAAI,UAAU,EAAE;oBACd,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;AAC9C,oBAAA,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC;;AAG9B,oBAAA,KAAK,CAAC,gBAAgB,GAAG,MAAK;AAC5B,wBAAA,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC;AAChC,wBAAA,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC;wBAClC,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AACpC,wBAAA,IAAI,GAAG,EAAE;;4BAEP,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;;AAG3B,4BAAA,GAAG,CAAC,IAAI,GAAG,YAAY,CAAC;AACxB,4BAAA,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC;AACxB,4BAAA,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC;AACxB,4BAAA,GAAG,CAAC,YAAY,GAAG,KAAK,CAAC;AACzB,4BAAA,GAAG,CAAC,QAAQ,CAAC,gBAAgB,IAAI,CAAC,yBAAyB,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,KAAK,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;AAC7F,yBAAA;AACH,qBAAC,CAAC;AACH,iBAAA;;AAGD,gBAAA,MAAM,YAAY,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;gBAC5C,MAAM,cAAc,GAAG,IAAI,WAAW,CAAC,CAAC,GAAG,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,IAAI,CAAC,MAAM,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAE,SAAS,EAAE,MAAI,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAA,EAAE,EAAE,YAAY,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE9G,gBAAA,IAAI,CAAC,aAAa,GAAG,IAAI,aAAa,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAErE,IAAI,CAAC,aAAa,CAAC,eAAe,GAAG,CAAC,KAAK,KAAI;oBAC7C,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE;wBACrC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACrC,qBAAA;AACH,iBAAC,CAAC;AAEF,gBAAA,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,MAAK;AAC/B,oBAAA,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;oBACrE,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;AACpD,oBAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBAClC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;oBACxD,IAAI,CAAC,SAAS,EAAE,CAAC;AAEnB,iBAAC,CAAC;gBAEF,IAAI,CAAC,aAAa,CAAC,OAAO,GAAG,CAAC,KAAY,KAAI;AAC5C,oBAAA,MAAM,UAAU,GAAG,KAAmB,CAAC;AACvC,oBAAA,IAAI,OAAO,GAAG,IAAI,CAAC,uBAAuB,CAAC,WAAW,CAAC;oBACvD,IAAI,UAAU,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE;wBAC7C,OAAO,IAAI,KAAK,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;AACxC,wBAAA,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO;4BAAE,OAAO,IAAI,MAAM,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;AAC3E,qBAAA;AACD,oBAAA,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;oBAC1B,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;oBACrD,IAAI,CAAC,SAAS,EAAE,CAAC;AACnB,iBAAC,CAAC;AAEF,gBAAA,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;gBAC3B,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;gBAC1D,IAAI,CAAC,UAAU,EAAE,CAAC;AACnB,aAAA;AAAC,YAAA,OAAO,GAAQ,EAAE;AACjB,gBAAA,IAAI,CAAC,WAAW,CAAC,CAAA,iCAAA,EAAoC,GAAG,CAAC,IAAI,CAAA,GAAA,EAAM,GAAG,CAAC,OAAO,CAAA,CAAE,CAAC,CAAC;gBAClF,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;AACtD,aAAA;;AACF,KAAA;AAED;;;;AAIC;IACO,oBAAoB,GAAA;AAC1B,QAAA,MAAM,SAAS,GAAG;YAChB,4BAA4B;YAC5B,4BAA4B;YAC5B,6BAA6B;YAC7B,2BAA2B;YAC3B,YAAY;SACb,CAAC;AACF,QAAA,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE;AAChC,YAAA,IAAI,aAAa,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE;AAC3C,gBAAA,OAAO,QAAQ,CAAC;AACjB,aAAA;AACF,SAAA;AACD,QAAA,OAAO,IAAI,CAAC;KACb;AAED;;;;;AAKG;IACK,qBAAqB,GAAA;;QAC3B,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI,CAAC,qBAAqB,CAAC,KAAK,KAAK,cAAc,CAAC,SAAS,IAAI,IAAI,CAAC,qBAAqB,CAAC,KAAK,KAAK,cAAc,CAAC,MAAM,CAAC,EAAE;AACvJ,YAAA,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;AAC3B,SAAA;AACD,QAAA,CAAA,EAAA,GAAA,IAAI,CAAC,MAAM,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,SAAS,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;AACxD,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;;KAEpB;AAED;;;;AAIG;IACH,aAAa,GAAA;QACX,IAAI,CAAC,qBAAqB,EAAE,CAAC;KAC9B;AAED;;;;;AAKG;IACH,cAAc,GAAA;AACZ,QAAA,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,qBAAqB,CAAC,KAAK,KAAK,cAAc,CAAC,SAAS,EAAE;AACvF,YAAA,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;YAC3B,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;AACvD,YAAA,IAAI,CAAC,SAAS,EAAE,CAAC;AAClB,SAAA;KACF;AAED;;;;;AAKG;IACH,eAAe,GAAA;AACb,QAAA,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,qBAAqB,CAAC,KAAK,KAAK,cAAc,CAAC,MAAM,EAAE;AACpF,YAAA,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;YAC5B,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;YAC1D,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;AAC3C,SAAA;KACF;AAED;;;AAGG;IACH,iBAAiB,CAAC,WAAmB,gBAAgB,EAAA;AACnD,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC;AAC1C,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC;QAEvD,IAAI,GAAG,IAAI,SAAS,EAAE;;YAEpB,MAAM,kBAAkB,GAAG,SAAS,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;;AAEnE,YAAA,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,MAAM,CAAC;AAC1D,YAAA,MAAM,WAAW,GAAG,CAAA,iBAAA,EAAoB,kBAAkB,CAAI,CAAA,EAAA,aAAa,EAAE,CAAC;YAE9E,MAAM,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;AACtC,YAAA,CAAC,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;AACzB,YAAA,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC;AACb,YAAA,CAAC,CAAC,QAAQ,GAAG,WAAW,CAAC;AACzB,YAAA,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YAC7B,CAAC,CAAC,KAAK,EAAE,CAAC;AACV,YAAA,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;;;AAG9B,SAAA;AAAM,aAAA;YACL,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,uBAAuB,CAAC,qBAAqB,CAAC,CAAC;AACtE,SAAA;KACF;AAED;;;;;;AAMC;IACO,UAAU,CAAC,YAAoB,CAAC,EAAA;AACtC,QAAA,IAAI,CAAC,SAAS,EAAE,CAAC;AACjB,QAAA,IAAI,CAAC,mBAAmB,GAAG,SAAS,CAAC;QACrC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAExD,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;AACpC,aAAA,IAAI,CACH,GAAG,CAAC,MAAK;YACP,IAAI,IAAI,CAAC,qBAAqB,CAAC,KAAK,KAAK,cAAc,CAAC,SAAS,EAAE;gBACjE,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC3B,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;AACzD,aAAA;AACH,SAAC,CAAC,EACF,SAAS,CAAC,MAAM,IAAI,CAAC,qBAAqB,CAAC,KAAK,KAAK,cAAc,CAAC,SAAS,CAAC,CAC/E;AACA,aAAA,SAAS,EAAE,CAAC;KAChB;AAED;;;;;AAKG;IACK,SAAS,GAAA;QACf,IAAI,IAAI,CAAC,iBAAiB,EAAE;AAC1B,YAAA,IAAI,CAAC,iBAAiB,CAAC,WAAW,EAAE,CAAC;AACrC,YAAA,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;AAC/B,SAAA;KACF;AAED;;;;;AAKG;IACK,wBAAwB,GAAA;AAC9B,QAAA,IAAI,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE;YACjC,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;AAC1D,YAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACpC,SAAA;AACD,QAAA,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;AACxB,QAAA,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;AAC7B,QAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjC,IAAI,IAAI,CAAC,MAAM,EAAE;AACf,YAAA,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;AACvD,YAAA,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;AACpB,SAAA;AACD,QAAA,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC,KAAK,KAAK,IAAI,CAAC,uBAAuB,CAAC,QAAQ,EAAE;AAC5F,YAAA,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;AAC3B,SAAA;AACD,QAAA,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;KAC3B;AAGD;;;;AAIC;IACD,WAAW,GAAA;QACT,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAChC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QACrD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;KAC5B;AAGD;;;;;;AAMC;AACO,IAAA,WAAW,CAAC,KAAa,EAAA;AAC/B,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;KAC/B;;mHApWU,qBAAqB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,uBAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAArB,qBAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,qBAAqB,cAFpB,MAAM,EAAA,CAAA,CAAA;4FAEP,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBAHjC,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;oBACV,UAAU,EAAE,MAAM;iBACnB,CAAA;;;MCcY,uBAAuB,CAAA;IAIlC,IACI,YAAY,CAAC,KAA4B,EAAA;;AAC3C,QAAA,IAAI,CAAC,QAAQ,GACX,MAAA,CAAA,MAAA,CAAA,EAAA,QAAQ,EAAE,sBAAsB,CAAC,MAAM,EACvC,aAAa,EAAE,aAAa,CAAC,IAAI,EACjC,eAAe,EAAE,IAAI,EACrB,iBAAiB,EAAE,IAAI,EACvB,gBAAgB,EAAE,uBAAuB,EACzC,KAAK,EAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAAO,IAAI,CAAC,uBAAuB,CAAC,aAAa,CACtD,EAAA,SAAS,EAAE,IAAI,EACf,eAAe,EAAE,IAAI,EACrB,oBAAoB,EAAE,IAAI,EAC1B,kBAAkB,EAAE,IAAI,EACxB,cAAc,EAAE,KAAK,EACrB,0BAA0B,EAAE,IAAI,EAChC,mBAAmB,EAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAAO,IAAI,CAAC,uBAAuB,CAAC,cAAc,CAClE,EAAA,EAAA,KAAK,CACT,CAAC;;QAEF,IAAI,KAAK,CAAC,KAAK,EAAE;AACf,YAAA,IAAI,CAAC,QAAQ,CAAC,KAAK,mCAAQ,IAAI,CAAC,uBAAuB,CAAC,aAAa,CAAK,EAAA,KAAK,CAAC,KAAK,CAAE,CAAC;AACzF,SAAA;QACD,IAAI,KAAK,CAAC,mBAAmB,EAAE;AAC7B,YAAA,IAAI,CAAC,QAAQ,CAAC,mBAAmB,mCAAQ,IAAI,CAAC,uBAAuB,CAAC,cAAc,CAAK,EAAA,KAAK,CAAC,mBAAmB,CAAE,CAAC;AACtH,SAAA;QACD,IAAI,CAAC,cAAc,GAAG,CAAA,EAAA,GAAA,IAAI,CAAC,QAAQ,CAAC,iBAAiB,MAAI,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAA,IAAI,CAAC;KAC/D;AACD,IAAA,IAAI,YAAY,GAAA;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC;KACtB;AAUD;;;;AAIG;IACH,qBAAqB,GAAA;AACnB,QAAA,OAAO,IAAI,CAAC,cAAc,KAAK,cAAc,CAAC,SAAS,CAAC;KACzD;AAKD;;;AAGG;IACH,gBAAgB,GAAA;QACd,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE;AAC5D,YAAA,OAAO,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;AACxC,SAAA;AACD,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;KAC/B;AASD,IAAA,WAAA,CACS,qBAA4C,EAC3C,SAAuB,EACvB,GAAsB,EACvB,uBAAgD,EAAA;AAHhD,QAAA,IAAqB,CAAA,qBAAA,GAArB,qBAAqB,CAAuB;AAC3C,QAAA,IAAS,CAAA,SAAA,GAAT,SAAS,CAAc;AACvB,QAAA,IAAG,CAAA,GAAA,GAAH,GAAG,CAAmB;AACvB,QAAA,IAAuB,CAAA,uBAAA,GAAvB,uBAAuB,CAAyB;AAvCzD,QAAA,IAAA,CAAA,cAAc,GAAmB,cAAc,CAAC,IAAI,CAAC;AACrD,QAAA,IAAY,CAAA,YAAA,GAAW,CAAC,CAAC;AACzB,QAAA,IAAa,CAAA,aAAA,GAAW,UAAU,CAAC;AACnC,QAAA,IAAe,CAAA,eAAA,GAAmB,IAAI,CAAC;AACvC,QAAA,IAAkB,CAAA,kBAAA,GAAW,EAAE,CAAC;AAShC,QAAA,IAAY,CAAA,YAAA,GAAkB,IAAI,CAAC;AACnC,QAAA,IAAkB,CAAA,kBAAA,GAAY,IAAI,CAAC;AACnC,QAAA,IAAc,CAAA,cAAA,GAAY,IAAI,CAAC;;AAc/B,QAAA,IAAa,CAAA,aAAA,GAAG,aAAa,CAAC;AAC9B,QAAA,IAAc,CAAA,cAAA,GAAG,cAAc,CAAC;AAChC,QAAA,IAAsB,CAAA,sBAAA,GAAG,sBAAsB,CAAC;AAExC,QAAA,IAAA,CAAA,aAAa,GAAG,IAAI,YAAY,EAAE,CAAC;;AAUzC,QAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;AAChB,YAAA,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;AAC1B,SAAA;KACF;IAED,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CACpB,IAAI,CAAC,qBAAqB,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,KAAK,KAAI;AAC7D,YAAA,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;YAC5B,IAAI,KAAK,KAAK,cAAc,CAAC,IAAI,IAAI,KAAK,KAAK,cAAc,CAAC,OAAO,EAAE;;AAEtE,aAAA;AACD,YAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;SAC1B,CAAC,CACH,CAAC;AAEF,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CACpB,IAAI,CAAC,qBAAqB,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,SAAS,KAAI;AACrE,YAAA,IAAI,CAAC,kBAAkB,GAAG,SAAS,CAAC;AACpC,YAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;SAC1B,CAAC,CACH,CAAC;AAEF,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CACpB,IAAI,CAAC,qBAAqB,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,IAAI,KAAI;AAC1D,YAAA,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YACzB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;AAClD,YAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;SAC1B,CAAC,CACH,CAAC;AAEF,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CACpB,IAAI,CAAC,qBAAqB,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,GAAG,KAAI;AACxD,YAAA,IAAI,CAAC,eAAe,GAAG,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;AAC/E,YAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;SAC1B,CAAC,CACH,CAAC;AAEF,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CACpB,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,KAAI;AACpD,YAAA,IAAG,KAAK,IAAI,IAAI,CAAC,uBAAuB,CAAC,iBAAiB,EAAC;AACzD,gBAAA,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;AAC3B,aAAA;AACD,YAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;SAC1B,CAAC,CACH,CAAC;KACH;IAED,WAAW,GAAA;QACT,IAAI,IAAI,CAAC,aAAa,EAAE;AACtB,YAAA,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC;AAClC,SAAA;KACF;AAED;;;;AAIG;IACG,YAAY,GAAA;;AAChB,YAAA,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;AACzB,YAAA,IAAI,IAAI,CAAC,cAAc,KAAK,cAAc,CAAC,IAAI,IAAI,IAAI,CAAC,cAAc,KAAK,cAAc,CAAC,OAAO,EAAE;;AAEjG,gBAAA,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,IAAI,CAAC,kBAAkB,GAAG,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE;AACpD,oBAAA,IAAI,EAAE,SAAS;AACf,oBAAA,KAAK,EAAE,SAAS;AAChB,oBAAA,GAAG,EAAE,SAAS;AACd,oBAAA,IAAI,EAAE,SAAS;AACf,oBAAA,MAAM,EAAE,SAAS;AACjB,oBAAA,MAAM,EAAE,IAAI;AACb,iBAAA,CAAC,CAAC;AACH,gBAAA,MAAM,IAAI,CAAC,qBAAqB,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;AACjF,aAAA;AAAM,iBAAA;AACL,gBAAA,IAAI,CAAC,qBAAqB,CAAC,aAAa,EAAE,CAAC;AAC5C,aAAA;SACF,CAAA,CAAA;AAAA,KAAA;AAED;;;;AAIG;IACH,iBAAiB,GAAA;AACf,QAAA,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;AACzB,QAAA,IAAI,IAAI,CAAC,cAAc,KAAK,cAAc,CAAC,SAAS,EAAE;AACpD,YAAA,IAAI,CAAC,qBAAqB,CAAC,cAAc,EAAE,CAAC;AAC7C,SAAA;AAAM,aAAA,IAAI,IAAI,CAAC,cAAc,KAAK,cAAc,CAAC,MAAM,EAAE;AACxD,YAAA,IAAI,CAAC,qBAAqB,CAAC,eAAe,EAAE,CAAC;AAC9C,SAAA;KACF;AAED;;;;AAIG;IACH,SAAS,GAAA;AACP,QAAA,OAAO,IAAI,CAAC,cAAc,KAAK,cAAc,CAAC,MAAM,CAAC;KACtD;AAED;;;;AAIG;IACH,UAAU,GAAA;AACR,QAAA,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,qBAAqB,CAAC,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;KAClF;AAED;;;;AAIG;IACH,WAAW,GAAA;AACT,QAAA,OAAO,IAAI,CAAC,cAAc,KAAK,cAAc,CAAC,OAAO,CAAC;KACvD;AAED;;;;AAIG;IACH,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,cAAc,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC;AAC3C,QAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;KAC1B;AAED;;;;AAIG;AACH,IAAA,OAAO,CAAC,QAAmC,EAAA;;AACzC,QAAA,OAAO,CAAA,CAAA,EAAA,GAAA,IAAI,CAAC,YAAY,CAAC,KAAK,MAAG,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,QAAQ,CAAC,KAAK,IAAI,CAAC,uBAAuB,CAAC,aAAqB,CAAC,QAAQ,CAAC,CAAC;KAC7G;AAED;;;;AAIG;AACH,IAAA,QAAQ,CAAC,SAA0E,EAAA;;AACjF,QAAA,OAAO,CAAA,CAAA,EAAA,GAAA,IAAI,CAAC,YAAY,CAAC,mBAAmB,MAAG,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,SAAS,CAAC,KAAK,IAAI,CAAC,uBAAuB,CAAC,cAAsB,CAAC,SAAS,CAAC,CAAC;KAC9H;AAED;;;;AAIG;AACH,IAAA,iBAAiB,CAAC,IAAY,EAAA;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;AACtC,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC;AAC/C,QAAA,MAAM,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;AAE1B,QAAA,MAAM,GAAG,GAAG,CAAC,GAAW,KAAK,GAAG,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAE7D,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE;;;;AAIvD,YAAA,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;AAC1D,SAAA;AACD,QAAA,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;KACxD;;IAGD,KAAK,GAAA;;AACH,QAAA,IAAI,CAAC,qBAAqB,CAAC,WAAW,EAAE,CAAC;QACzC,IAAI,CAAC,cAAc,GAAG,CAAA,EAAA,GAAA,IAAI,CAAC,YAAY,CAAC,iBAAiB,MAAI,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAA,IAAI,CAAC;AAClE,QAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;KAC1B;;qHA/PU,uBAAuB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAC,qBAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,YAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,iBAAA,EAAA,EAAA,EAAA,KAAA,EAAAC,uBAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAvB,uBAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,uBAAuB,oPCrBpC,yqLAwGM,EAAA,MAAA,EAAA,CAAA,+wlCAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,IAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,UAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;4FDnFO,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBANnC,SAAS;+BACE,4BAA4B,EAAA,eAAA,EAGrB,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,yqLAAA,EAAA,MAAA,EAAA,CAAA,+wlCAAA,CAAA,EAAA,CAAA;uMAI/C,WAAW,EAAA,CAAA;sBADV,KAAK;gBAIF,YAAY,EAAA,CAAA;sBADf,KAAK;gBAgCoB,WAAW,EAAA,CAAA;sBAApC,SAAS;uBAAC,aAAa,CAAA;;;ME9Cb,0BAA0B,CAAA;;wHAA1B,0BAA0B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA,CAAA;AAA1B,0BAAA,CAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,0BAA0B,EAJtB,YAAA,EAAA,CAAA,uBAAuB,CAD5B,EAAA,OAAA,EAAA,CAAA,YAAY,aAEZ,uBAAuB,CAAA,EAAA,CAAA,CAAA;AAGtB,0BAAA,CAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,0BAA0B,EAF1B,SAAA,EAAA,CAAC,qBAAqB,CAAC,YAHxB,YAAY,CAAA,EAAA,CAAA,CAAA;4FAKX,0BAA0B,EAAA,UAAA,EAAA,CAAA;kBANtC,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;oBACR,OAAO,EAAE,CAAC,YAAY,CAAC;oBACvB,YAAY,EAAE,CAAC,uBAAuB,CAAC;oBACvC,OAAO,EAAE,CAAC,uBAAuB,CAAC;oBAClC,SAAS,EAAE,CAAC,qBAAqB,CAAC;iBACnC,CAAA;;;ACVD;;AAEG;;;;"}
@@ -612,10 +612,10 @@ class ScreenRecorderComponent {
612
612
  }
613
613
  }
614
614
  ScreenRecorderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ScreenRecorderComponent, deps: [{ token: ScreenRecorderService }, { token: i2.DomSanitizer }, { token: i0.ChangeDetectorRef }, { token: ScreenRecorderConstants }], target: i0.ɵɵFactoryTarget.Component });
615
- ScreenRecorderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: ScreenRecorderComponent, selector: "uxp-screen-recorder", inputs: { customTheme: "customTheme", rucInputData: "rucInputData" }, viewQueries: [{ propertyName: "videoPlayer", first: true, predicate: ["videoPlayer"], descendants: true }], ngImport: i0, template: "<div class=\"screen-recorder-controls\" [ngClass]=\"customTheme + ' position-' + (rucInputData.position || ScreenRecorderPosition.Bottom)\"\r\n *ngIf=\"isBrowserSupported\">\r\n\r\n <!-- Error Message -->\r\n <div *ngIf=\"errorMessage\" class=\"recorder-error\">\r\n {{ errorMessage }}\r\n </div>\r\n\r\n <!-- Record/Stop Button -->\r\n <button\r\n *ngIf=\"recordingState === RecordingState.Idle || recordingState === RecordingState.Stopped\" (click)=\"toggleRecord()\"\r\n [attr.aria-label]=\"getLabel('recordButton')\" [attr.aria-pressed]=\"false\" class=\"recorder-button record-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getRecordingIcon() || getIcon('record') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('recordButton')\r\n }}</ng-container>\r\n </button>\r\n\r\n <button\r\n *ngIf=\"recordingState === RecordingState.Recording || recordingState === RecordingState.Paused\"\r\n (click)=\"toggleRecord()\" [attr.aria-label]=\"getLabel('stopButton')\" [attr.aria-pressed]=\"true\"\r\n class=\"recorder-button stop-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('stop') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('stopButton') }}</ng-container>\r\n </button>\r\n\r\n <!-- Pause/Resume Button -->\r\n <button *ngIf=\"rucInputData.showPauseResume && recordingState === RecordingState.Recording\"\r\n (click)=\"togglePauseResume()\" [attr.aria-label]=\"getLabel('pauseButton')\" [attr.aria-pressed]=\"false\"\r\n class=\"recorder-button pause-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('pause') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('pauseButton') }}</ng-container>\r\n </button>\r\n <button *ngIf=\"rucInputData.showPauseResume && recordingState === RecordingState.Paused\"\r\n (click)=\"togglePauseResume()\" [attr.aria-label]=\"getLabel('resumeButton')\" [attr.aria-pressed]=\"true\"\r\n class=\"recorder-button resume-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('resume') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('resumeButton')\r\n }}</ng-container>\r\n </button>\r\n\r\n <!-- Audio Toggle Button -->\r\n <button\r\n *ngIf=\"rucInputData.showAudioToggle && (recordingState === RecordingState.Idle || recordingState === RecordingState.Stopped)\"\r\n (click)=\"toggleAudio()\" [attr.aria-label]=\"getLabel('audioToggleButton')\" [attr.aria-pressed]=\"isAudioEnabled\"\r\n class=\"recorder-button audio-toggle-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ isAudioEnabled ? getIcon('audioOn') : getIcon('audioOff') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">\r\n {{ isAudioEnabled ? screenRecordingConstant.AUDIO_ON : screenRecordingConstant.AUDIO_OFF }}\r\n </ng-container>\r\n </button>\r\n\r\n <!-- Timer -->\r\n <div\r\n *ngIf=\"rucInputData.showTimer && (recordingState === RecordingState.Recording || recordingState === RecordingState.Paused)\"\r\n class=\"recorder-timer\" aria-live=\"polite\" aria-atomic=\"true\">\r\n {{ formattedTime }}\r\n </div>\r\n\r\n <!-- Download Button -->\r\n <button\r\n *ngIf=\"rucInputData.showDownloadButton && recordingState === RecordingState.Stopped && safeRecordedUrl\"\r\n (click)=\"onDownload()\" [attr.aria-label]=\"getLabel('downloadButton')\" class=\"recorder-button download-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('download') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('downloadButton')\r\n }}</ng-container>\r\n </button>\r\n\r\n <!-- Playback Area -->\r\n <div *ngIf=\"rucInputData.showPlaybackControls && recordingState === RecordingState.Stopped && safeRecordedUrl\"\r\n class=\"playback-area\">\r\n <video #videoPlayer [src]=\"safeRecordedUrl\" controls [attr.aria-label]=\"getLabel('playbackVideo')\"></video>\r\n <div class=\"video-timer-overlay\">\r\n <span>Recorded on: {{ recordingTimestamp }}</span>\r\n </div>\r\n </div>\r\n\r\n <!-- Reset Button (optional, good for testing/clearing state) -->\r\n <button *ngIf=\"recordingState === RecordingState.Stopped && safeRecordedUrl\" (click)=\"reset()\"\r\n aria-label=\"New Recording\" class=\"recorder-button reset-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">refresh</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">New</ng-container>\r\n </button>\r\n\r\n</div>\r\n\r\n<div *ngIf=\"!isBrowserSupported\" class=\"recorder-notsupported\" [ngClass]=\"customTheme\">\r\n {{screenRecordingConstant.NO_SUPPORT}}\r\n</div>", styles: [":host{display:block;font-family:sans-serif}.screen-recorder-controls{display:flex;gap:8px;align-items:center;padding:8px;border-radius:4px;position:relative;z-index:1000}.screen-recorder-controls.position-top-left{margin-top:10px;margin-left:10px;flex-direction:row}.screen-recorder-controls.position-top-right{margin-top:10px;margin-right:10px;flex-direction:row}.screen-recorder-controls.position-bottom-left{margin-bottom:10px;margin-left:10px;flex-direction:row}.screen-recorder-controls.position-bottom-right{margin-bottom:10px;margin-right:10px;flex-direction:row}.screen-recorder-controls.position-left,.screen-recorder-controls.position-right{float:right}.recorder-button{padding:8px 12px;border:1px solid #ccc;border-radius:4px;background-color:#fff;cursor:pointer;display:inline-flex;align-items:center;gap:4px}.recorder-button:hover{background-color:#e9e9e9}.recorder-button:active{background-color:#d0d0d0}.recorder-button.record-button{color:red}.material-icons{font-family:Material Icons;font-weight:400;font-style:normal;font-size:20px;display:inline-block;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:\"liga\"}.recorder-timer{padding:0 8px;font-feature-settings:\"tnum\";font-variant-numeric:tabular-nums}.playback-area{width:100%;max-width:100%;margin-top:1rem;position:relative}.playback-area video{width:100%;height:auto;max-width:100%}.playback-area .video-timer-overlay{position:absolute;top:10px;right:10px;background:rgba(0,0,0,.7);color:#fff;padding:5px 10px;border-radius:4px;font-size:14px;z-index:10}.recorder-error{color:red;padding:8px;border:1px solid red;background-color:#ffe0e0;border-radius:4px;margin-bottom:8px}.recorder-notsupported{padding:10px;background-color:#fff3cd;border:1px solid #ffeeba;color:#856404;border-radius:4px}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
615
+ ScreenRecorderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: ScreenRecorderComponent, selector: "uxp-ruclib-screen-recorder", inputs: { customTheme: "customTheme", rucInputData: "rucInputData" }, viewQueries: [{ propertyName: "videoPlayer", first: true, predicate: ["videoPlayer"], descendants: true }], ngImport: i0, template: "<div class=\"main\">\r\n <div class=\"screen-recorder-controls\"\r\n [ngClass]=\"customTheme + ' position-' + (rucInputData.position || ScreenRecorderPosition.Bottom)\"\r\n *ngIf=\"isBrowserSupported\">\r\n\r\n <!-- Error Message -->\r\n <div *ngIf=\"errorMessage\" class=\"recorder-error\">\r\n {{ errorMessage }}\r\n </div>\r\n\r\n <!-- Record/Stop Button -->\r\n <button *ngIf=\"recordingState === RecordingState.Idle || recordingState === RecordingState.Stopped\"\r\n (click)=\"toggleRecord()\" [attr.aria-label]=\"getLabel('recordButton')\" [attr.aria-pressed]=\"false\"\r\n class=\"recorder-button record-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getRecordingIcon() || getIcon('record') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('recordButton')\r\n }}</ng-container>\r\n </button>\r\n\r\n <button *ngIf=\"recordingState === RecordingState.Recording || recordingState === RecordingState.Paused\"\r\n (click)=\"toggleRecord()\" [attr.aria-label]=\"getLabel('stopButton')\" [attr.aria-pressed]=\"true\"\r\n class=\"recorder-button stop-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('stop') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('stopButton')\r\n }}</ng-container>\r\n </button>\r\n\r\n <!-- Pause/Resume Button -->\r\n <button *ngIf=\"rucInputData.showPauseResume && recordingState === RecordingState.Recording\"\r\n (click)=\"togglePauseResume()\" [attr.aria-label]=\"getLabel('pauseButton')\" [attr.aria-pressed]=\"false\"\r\n class=\"recorder-button pause-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('pause') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('pauseButton')\r\n }}</ng-container>\r\n </button>\r\n <button *ngIf=\"rucInputData.showPauseResume && recordingState === RecordingState.Paused\"\r\n (click)=\"togglePauseResume()\" [attr.aria-label]=\"getLabel('resumeButton')\" [attr.aria-pressed]=\"true\"\r\n class=\"recorder-button resume-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('resume') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('resumeButton')\r\n }}</ng-container>\r\n </button>\r\n\r\n <!-- Audio Toggle Button -->\r\n <button\r\n *ngIf=\"rucInputData.showAudioToggle && (recordingState === RecordingState.Idle || recordingState === RecordingState.Stopped)\"\r\n (click)=\"toggleAudio()\" [attr.aria-label]=\"getLabel('audioToggleButton')\" [attr.aria-pressed]=\"isAudioEnabled\"\r\n class=\"recorder-button audio-toggle-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ isAudioEnabled ? getIcon('audioOn') : getIcon('audioOff') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">\r\n {{ isAudioEnabled ? screenRecordingConstant.AUDIO_ON : screenRecordingConstant.AUDIO_OFF }}\r\n </ng-container>\r\n </button>\r\n\r\n <!-- Timer -->\r\n <div\r\n *ngIf=\"rucInputData.showTimer && (recordingState === RecordingState.Recording || recordingState === RecordingState.Paused)\"\r\n class=\"recorder-timer\" aria-live=\"polite\" aria-atomic=\"true\">\r\n {{ formattedTime }}\r\n </div>\r\n\r\n <!-- Download Button -->\r\n <button *ngIf=\"rucInputData.showDownloadButton && recordingState === RecordingState.Stopped && safeRecordedUrl\"\r\n (click)=\"onDownload()\" [attr.aria-label]=\"getLabel('downloadButton')\" class=\"recorder-button download-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('download') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('downloadButton')\r\n }}</ng-container>\r\n </button>\r\n\r\n <!-- Playback Area -->\r\n <div *ngIf=\"rucInputData.showPlaybackControls && recordingState === RecordingState.Stopped && safeRecordedUrl\"\r\n class=\"playback-area\">\r\n <video #videoPlayer [src]=\"safeRecordedUrl\" controls [attr.aria-label]=\"getLabel('playbackVideo')\"></video>\r\n <div class=\"video-timer-overlay\">\r\n <span>Recorded on: {{ recordingTimestamp }}</span>\r\n </div>\r\n </div>\r\n\r\n <!-- Reset Button (optional, good for testing/clearing state) -->\r\n <button *ngIf=\"recordingState === RecordingState.Stopped && safeRecordedUrl\" (click)=\"reset()\"\r\n aria-label=\"New Recording\" class=\"recorder-button reset-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">refresh</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">New</ng-container>\r\n </button>\r\n\r\n </div>\r\n\r\n <div *ngIf=\"!isBrowserSupported\" class=\"recorder-notsupported\" [ngClass]=\"customTheme\">\r\n {{screenRecordingConstant.NO_SUPPORT}}\r\n </div>\r\n</div>", styles: [".mat-ripple{overflow:hidden;position:relative}.mat-ripple:not(:empty){transform:translateZ(0)}.mat-ripple.mat-ripple-unbounded{overflow:visible}.mat-ripple-element{position:absolute;border-radius:50%;pointer-events:none;transition:opacity,transform 0ms cubic-bezier(0,0,.2,1);transform:scale3d(0,0,0)}.cdk-high-contrast-active .mat-ripple-element{display:none}.cdk-visually-hidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap;outline:0;-webkit-appearance:none;-moz-appearance:none;left:0}[dir=rtl] .cdk-visually-hidden{left:auto;right:0}.cdk-overlay-container,.cdk-global-overlay-wrapper{pointer-events:none;top:0;left:0;height:100%;width:100%}.cdk-overlay-container{position:fixed;z-index:1000}.cdk-overlay-container:empty{display:none}.cdk-global-overlay-wrapper{display:flex;position:absolute;z-index:1000}.cdk-overlay-pane{position:absolute;pointer-events:auto;box-sizing:border-box;z-index:1000;display:flex;max-width:100%;max-height:100%}.cdk-overlay-backdrop{position:absolute;inset:0;z-index:1000;pointer-events:auto;-webkit-tap-highlight-color:transparent;transition:opacity .4s cubic-bezier(.25,.8,.25,1);opacity:0}.cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:1}.cdk-high-contrast-active .cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:.6}.cdk-overlay-dark-backdrop{background:rgba(0,0,0,.32)}.cdk-overlay-transparent-backdrop{transition:visibility 1ms linear,opacity 1ms linear;visibility:hidden;opacity:1}.cdk-overlay-transparent-backdrop.cdk-overlay-backdrop-showing{opacity:0;visibility:visible}.cdk-overlay-backdrop-noop-animation{transition:none}.cdk-overlay-connected-position-bounding-box{position:absolute;z-index:1000;display:flex;flex-direction:column;min-width:1px;min-height:1px}.cdk-global-scrollblock{position:fixed;width:100%;overflow-y:scroll}textarea.cdk-textarea-autosize{resize:none}textarea.cdk-textarea-autosize-measuring{padding:2px 0!important;box-sizing:content-box!important;height:auto!important;overflow:hidden!important}textarea.cdk-textarea-autosize-measuring-firefox{padding:2px 0!important;box-sizing:content-box!important;height:0!important}@keyframes cdk-text-field-autofill-start{}@keyframes cdk-text-field-autofill-end{}.cdk-text-field-autofill-monitored:-webkit-autofill{animation:cdk-text-field-autofill-start 0s 1ms}.cdk-text-field-autofill-monitored:not(:-webkit-autofill){animation:cdk-text-field-autofill-end 0s 1ms}.mat-focus-indicator{position:relative}.mat-focus-indicator:before{inset:0;position:absolute;box-sizing:border-box;pointer-events:none;display:var(--mat-focus-indicator-display, none);border:var(--mat-focus-indicator-border-width, 3px) var(--mat-focus-indicator-border-style, solid) var(--mat-focus-indicator-border-color, transparent);border-radius:var(--mat-focus-indicator-border-radius, 4px)}.mat-focus-indicator:focus:before{content:\"\"}.cdk-high-contrast-active{--mat-focus-indicator-display: block}.mat-mdc-focus-indicator{position:relative}.mat-mdc-focus-indicator:before{inset:0;position:absolute;box-sizing:border-box;pointer-events:none;display:var(--mat-mdc-focus-indicator-display, none);border:var(--mat-mdc-focus-indicator-border-width, 3px) var(--mat-mdc-focus-indicator-border-style, solid) var(--mat-mdc-focus-indicator-border-color, transparent);border-radius:var(--mat-mdc-focus-indicator-border-radius, 4px)}.mat-mdc-focus-indicator:focus:before{content:\"\"}.cdk-high-contrast-active{--mat-mdc-focus-indicator-display: block}.main{font-size:16px;font-weight:400;line-height:24px;font-family:Roboto,sans-serif;letter-spacing:.03125em}.ruc-custom-theme{font-size:14px;font-weight:400;line-height:20px;font-family:Roboto,sans-serif;letter-spacing:normal}.ruc-custom-theme .mat-mdc-option{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-body1-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-body1-font-size, 15px);line-height:var(--mdc-typography-body1-line-height, 24px);font-weight:var(--mdc-typography-body1-font-weight, 400);letter-spacing:var(--mdc-typography-body1-letter-spacing, normal)}.ruc-custom-theme .mat-mdc-card-title{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-headline6-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-headline6-font-size, 20px);line-height:var(--mdc-typography-headline6-line-height, 32px);font-weight:var(--mdc-typography-headline6-font-weight, 500);letter-spacing:var(--mdc-typography-headline6-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-headline6-text-decoration, inherit);text-decoration:var(--mdc-typography-headline6-text-decoration, inherit);text-transform:var(--mdc-typography-headline6-text-transform, none)}.ruc-custom-theme .mat-mdc-card-subtitle{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-subtitle2-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-subtitle2-font-size, 20px);line-height:var(--mdc-typography-subtitle2-line-height, 24px);font-weight:var(--mdc-typography-subtitle2-font-weight, 500);letter-spacing:var(--mdc-typography-subtitle2-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-subtitle2-text-decoration, inherit);text-decoration:var(--mdc-typography-subtitle2-text-decoration, inherit);text-transform:var(--mdc-typography-subtitle2-text-transform, none)}.ruc-custom-theme .mat-mdc-tooltip{--mdc-plain-tooltip-supporting-text-font: Roboto, sans-serif;--mdc-plain-tooltip-supporting-text-size: 12px;--mdc-plain-tooltip-supporting-text-weight: 400;--mdc-plain-tooltip-supporting-text-tracking: normal}.ruc-custom-theme .mat-mdc-form-field-infix{min-height:56px}.ruc-custom-theme .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-floating-label{top:28px}.ruc-custom-theme .mat-mdc-text-field-wrapper.mdc-text-field--outlined .mdc-notched-outline--upgraded .mdc-floating-label--float-above{--mat-mdc-form-field-label-transform: translateY( -34.75px) scale(var(--mat-mdc-form-field-floating-label-scale, .75));transform:var(--mat-mdc-form-field-label-transform)}.ruc-custom-theme .mat-mdc-text-field-wrapper.mdc-text-field--outlined .mat-mdc-form-field-infix{padding-top:16px;padding-bottom:16px}.ruc-custom-theme .mat-mdc-text-field-wrapper:not(.mdc-text-field--outlined) .mat-mdc-form-field-infix{padding-top:24px;padding-bottom:8px}.ruc-custom-theme .mdc-text-field--no-label:not(.mdc-text-field--outlined):not(.mdc-text-field--textarea) .mat-mdc-form-field-infix{padding-top:16px;padding-bottom:16px}.ruc-custom-theme .mdc-text-field__input,.ruc-custom-theme .mdc-text-field__affix{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-subtitle1-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-subtitle1-font-size, 16px);font-weight:var(--mdc-typography-subtitle1-font-weight, 400);letter-spacing:var(--mdc-typography-subtitle1-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-subtitle1-text-decoration, inherit);text-decoration:var(--mdc-typography-subtitle1-text-decoration, inherit);text-transform:var(--mdc-typography-subtitle1-text-transform, none)}.ruc-custom-theme .mdc-text-field--textarea .mdc-text-field__input{line-height:1.5rem}.ruc-custom-theme .mdc-floating-label{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-subtitle1-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-subtitle1-font-size, 16px);font-weight:var(--mdc-typography-subtitle1-font-weight, 400);letter-spacing:var(--mdc-typography-subtitle1-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-subtitle1-text-decoration, inherit);text-decoration:var(--mdc-typography-subtitle1-text-decoration, inherit);text-transform:var(--mdc-typography-subtitle1-text-transform, none)}.ruc-custom-theme .mat-mdc-form-field-subscript-wrapper,.ruc-custom-theme .mat-mdc-form-field-bottom-align:before{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-caption-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-caption-font-size, 12px);line-height:var(--mdc-typography-caption-line-height, 20px);font-weight:var(--mdc-typography-caption-font-weight, 400);letter-spacing:var(--mdc-typography-caption-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-caption-text-decoration, inherit);text-decoration:var(--mdc-typography-caption-text-decoration, inherit);text-transform:var(--mdc-typography-caption-text-transform, none)}.ruc-custom-theme .mat-mdc-form-field,.ruc-custom-theme .mat-mdc-floating-label{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-body1-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-body1-font-size, 15px);line-height:var(--mdc-typography-body1-line-height, 24px);font-weight:var(--mdc-typography-body1-font-weight, 400);letter-spacing:var(--mdc-typography-body1-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-body1-text-decoration, inherit);text-decoration:var(--mdc-typography-body1-text-decoration, inherit);text-transform:var(--mdc-typography-body1-text-transform, none)}.ruc-custom-theme .mat-mdc-form-field .mdc-text-field--outlined .mdc-floating-label--float-above{font-size:calc(15px * var(--mat-mdc-form-field-floating-label-scale, .75))}.ruc-custom-theme .mat-mdc-form-field .mdc-text-field--outlined .mdc-notched-outline--upgraded .mdc-floating-label--float-above{font-size:15px}.ruc-custom-theme .mat-mdc-select-panel{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-subtitle1-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-subtitle1-font-size, 16px);line-height:var(--mdc-typography-subtitle1-line-height, 28px);font-weight:var(--mdc-typography-subtitle1-font-weight, 400);letter-spacing:var(--mdc-typography-subtitle1-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-subtitle1-text-decoration, inherit);text-decoration:var(--mdc-typography-subtitle1-text-decoration, inherit);text-transform:var(--mdc-typography-subtitle1-text-transform, none);line-height:24px}.ruc-custom-theme .mat-mdc-select{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-body1-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-body1-font-size, 15px);line-height:var(--mdc-typography-body1-line-height, 24px);font-weight:var(--mdc-typography-body1-font-weight, 400);letter-spacing:var(--mdc-typography-body1-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-body1-text-decoration, inherit);text-decoration:var(--mdc-typography-body1-text-decoration, inherit);text-transform:var(--mdc-typography-body1-text-transform, none)}.ruc-custom-theme .mat-mdc-autocomplete-panel{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-subtitle1-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-subtitle1-font-size, 16px);line-height:var(--mdc-typography-subtitle1-line-height, 28px);font-weight:var(--mdc-typography-subtitle1-font-weight, 400);letter-spacing:var(--mdc-typography-subtitle1-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-subtitle1-text-decoration, inherit);text-decoration:var(--mdc-typography-subtitle1-text-decoration, inherit);text-transform:var(--mdc-typography-subtitle1-text-transform, none);line-height:24px}.ruc-custom-theme .mat-mdc-dialog-container{--mdc-dialog-subhead-font: Roboto, sans-serif;--mdc-dialog-subhead-line-height: 32px;--mdc-dialog-subhead-size: 20px;--mdc-dialog-subhead-weight: 500;--mdc-dialog-subhead-tracking: normal;--mdc-dialog-supporting-text-font: Roboto, sans-serif;--mdc-dialog-supporting-text-line-height: 24px;--mdc-dialog-supporting-text-size: 15px;--mdc-dialog-supporting-text-weight: 400;--mdc-dialog-supporting-text-tracking: normal}.ruc-custom-theme .mat-mdc-chip{height:32px}.ruc-custom-theme .mat-mdc-standard-chip{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-body2-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-body2-font-size, 14px);line-height:var(--mdc-typography-body2-line-height, 20px);font-weight:var(--mdc-typography-body2-font-weight, 400);letter-spacing:var(--mdc-typography-body2-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-body2-text-decoration, inherit);text-decoration:var(--mdc-typography-body2-text-decoration, inherit);text-transform:var(--mdc-typography-body2-text-transform, none)}.ruc-custom-theme .mat-mdc-slide-toggle{--mdc-switch-state-layer-size: 48px}.ruc-custom-theme .mat-mdc-radio-button .mdc-radio{padding:10px}.ruc-custom-theme .mat-mdc-radio-button .mdc-radio .mdc-radio__background:before{top:-10px;left:-10px;width:40px;height:40px}.ruc-custom-theme .mat-mdc-radio-button .mdc-radio .mdc-radio__native-control{top:0;right:0;left:0;width:40px;height:40px}.ruc-custom-theme .mat-mdc-slider{--mdc-slider-label-label-text-font: Roboto, sans-serif;--mdc-slider-label-label-text-size: 20px;--mdc-slider-label-label-text-line-height: 24px;--mdc-slider-label-label-text-tracking: normal;--mdc-slider-label-label-text-weight: 500}.ruc-custom-theme .mat-mdc-menu-content{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-subtitle1-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-subtitle1-font-size, 16px);line-height:var(--mdc-typography-subtitle1-line-height, 28px);font-weight:var(--mdc-typography-subtitle1-font-weight, 400);letter-spacing:var(--mdc-typography-subtitle1-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-subtitle1-text-decoration, inherit);text-decoration:var(--mdc-typography-subtitle1-text-decoration, inherit);text-transform:var(--mdc-typography-subtitle1-text-transform, none);line-height:24px}.ruc-custom-theme .mat-mdc-menu-content,.ruc-custom-theme .mat-mdc-menu-content .mat-mdc-menu-item .mdc-list-item__primary-text{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-body1-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-body1-font-size, 15px);line-height:var(--mdc-typography-body1-line-height, 24px);font-weight:var(--mdc-typography-body1-font-weight, 400);letter-spacing:var(--mdc-typography-body1-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-body1-text-decoration, inherit);text-decoration:var(--mdc-typography-body1-text-decoration, inherit);text-transform:var(--mdc-typography-body1-text-transform, none)}.ruc-custom-theme .mat-mdc-list-base{--mdc-list-list-item-one-line-container-height: 48px;--mdc-list-list-item-two-line-container-height: 64px;--mdc-list-list-item-three-line-container-height: 88px}.ruc-custom-theme .mat-mdc-list-item.mdc-list-item--with-leading-avatar.mdc-list-item--with-one-line,.ruc-custom-theme .mat-mdc-list-item.mdc-list-item--with-leading-checkbox.mdc-list-item--with-one-line,.ruc-custom-theme .mat-mdc-list-item.mdc-list-item--with-leading-icon.mdc-list-item--with-one-line{height:56px}.ruc-custom-theme .mat-mdc-list-item.mdc-list-item--with-leading-avatar.mdc-list-item--with-two-lines,.ruc-custom-theme .mat-mdc-list-item.mdc-list-item--with-leading-checkbox.mdc-list-item--with-two-lines,.ruc-custom-theme .mat-mdc-list-item.mdc-list-item--with-leading-icon.mdc-list-item--with-two-lines{height:72px}.ruc-custom-theme .mat-mdc-list-base{--mdc-list-list-item-label-text-font: Roboto, sans-serif;--mdc-list-list-item-label-text-line-height: 24px;--mdc-list-list-item-label-text-size: 15px;--mdc-list-list-item-label-text-tracking: normal;--mdc-list-list-item-label-text-weight: 400;--mdc-list-list-item-supporting-text-font: Roboto, sans-serif;--mdc-list-list-item-supporting-text-line-height: 20px;--mdc-list-list-item-supporting-text-size: 14px;--mdc-list-list-item-supporting-text-tracking: normal;--mdc-list-list-item-supporting-text-weight: 400;--mdc-list-list-item-trailing-supporting-text-font: Roboto, sans-serif;--mdc-list-list-item-trailing-supporting-text-line-height: 20px;--mdc-list-list-item-trailing-supporting-text-size: 12px;--mdc-list-list-item-trailing-supporting-text-tracking: normal;--mdc-list-list-item-trailing-supporting-text-weight: 400}.ruc-custom-theme .mdc-list-group__subheader{font-size:16px;font-weight:400;line-height:28px;font-family:Roboto,sans-serif;letter-spacing:normal}.ruc-custom-theme .mat-mdc-paginator .mat-mdc-form-field-infix{min-height:40px}.ruc-custom-theme .mat-mdc-paginator .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-floating-label{top:20px}.ruc-custom-theme .mat-mdc-paginator .mat-mdc-text-field-wrapper.mdc-text-field--outlined .mdc-notched-outline--upgraded .mdc-floating-label--float-above{--mat-mdc-form-field-label-transform: translateY( -26.75px) scale(var(--mat-mdc-form-field-floating-label-scale, .75));transform:var(--mat-mdc-form-field-label-transform)}.ruc-custom-theme .mat-mdc-paginator .mat-mdc-text-field-wrapper.mdc-text-field--outlined .mat-mdc-form-field-infix{padding-top:8px;padding-bottom:8px}.ruc-custom-theme .mat-mdc-paginator .mat-mdc-text-field-wrapper:not(.mdc-text-field--outlined) .mat-mdc-form-field-infix{padding-top:8px;padding-bottom:8px}.ruc-custom-theme .mat-mdc-paginator .mdc-text-field--no-label:not(.mdc-text-field--outlined):not(.mdc-text-field--textarea) .mat-mdc-form-field-infix{padding-top:8px;padding-bottom:8px}.ruc-custom-theme .mat-mdc-paginator .mat-mdc-text-field-wrapper:not(.mdc-text-field--outlined) .mat-mdc-floating-label{display:none}.ruc-custom-theme .mat-mdc-paginator-container{min-height:56px}.ruc-custom-theme .mat-mdc-paginator{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-caption-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-caption-font-size, 12px);line-height:var(--mdc-typography-caption-line-height, 20px);font-weight:var(--mdc-typography-caption-font-weight, 400);letter-spacing:var(--mdc-typography-caption-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-caption-text-decoration, inherit);text-decoration:var(--mdc-typography-caption-text-decoration, inherit);text-transform:var(--mdc-typography-caption-text-transform, none)}.ruc-custom-theme .mat-mdc-paginator .mat-mdc-select-value{font-size:12px}.ruc-custom-theme .mat-mdc-tab-header .mdc-tab{height:48px}.ruc-custom-theme .mdc-tab{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-button-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-button-font-size, 20px);line-height:var(--mdc-typography-button-line-height, 60px);font-weight:var(--mdc-typography-button-font-weight, 500);letter-spacing:var(--mdc-typography-button-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-button-text-decoration, none);text-decoration:var(--mdc-typography-button-text-decoration, none);text-transform:var(--mdc-typography-button-text-transform, none)}.ruc-custom-theme .mat-mdc-checkbox .mdc-checkbox{padding:calc((var(--mdc-checkbox-ripple-size, 40px) - 18px) / 2);margin:calc((var(--mdc-checkbox-touch-target-size, 40px) - 40px) / 2)}.ruc-custom-theme .mat-mdc-checkbox .mdc-checkbox .mdc-checkbox__background{top:calc((var(--mdc-checkbox-ripple-size, 40px) - 18px) / 2);left:calc((var(--mdc-checkbox-ripple-size, 40px) - 18px) / 2)}.ruc-custom-theme .mat-mdc-checkbox .mdc-checkbox .mdc-checkbox__native-control{top:calc((40px - var(--mdc-checkbox-touch-target-size, 40px)) / 2);right:calc((40px - var(--mdc-checkbox-touch-target-size, 40px)) / 2);left:calc((40px - var(--mdc-checkbox-touch-target-size, 40px)) / 2);width:var(--mdc-checkbox-touch-target-size, 40px);height:var(--mdc-checkbox-touch-target-size, 40px)}@media all and (-ms-high-contrast: none){.ruc-custom-theme .mdc-checkbox .mdc-checkbox__focus-ring{display:none}}.ruc-custom-theme .mdc-form-field{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-body2-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-body2-font-size, 14px);line-height:var(--mdc-typography-body2-line-height, 20px);font-weight:var(--mdc-typography-body2-font-weight, 400);letter-spacing:var(--mdc-typography-body2-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-body2-text-decoration, inherit);text-decoration:var(--mdc-typography-body2-text-decoration, inherit);text-transform:var(--mdc-typography-body2-text-transform, none)}.ruc-custom-theme .mat-mdc-button.mat-mdc-button-base,.ruc-custom-theme .mat-mdc-raised-button.mat-mdc-button-base,.ruc-custom-theme .mat-mdc-unelevated-button.mat-mdc-button-base,.ruc-custom-theme .mat-mdc-outlined-button.mat-mdc-button-base{height:36px}.ruc-custom-theme .mdc-button{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-button-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-button-font-size, 20px);line-height:var(--mdc-typography-button-line-height, 60px);font-weight:var(--mdc-typography-button-font-weight, 500);letter-spacing:var(--mdc-typography-button-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-button-text-decoration, none);text-decoration:var(--mdc-typography-button-text-decoration, none);text-transform:var(--mdc-typography-button-text-transform, none)}.ruc-custom-theme .mat-mdc-icon-button.mat-mdc-button-base{width:48px;height:48px;padding:12px}.ruc-custom-theme .mat-mdc-icon-button.mat-mdc-button-base .mdc-icon-button__focus-ring{max-height:48px;max-width:48px}.ruc-custom-theme .mat-mdc-icon-button.mat-mdc-button-base.mdc-icon-button--reduced-size .mdc-icon-button__ripple{width:40px;height:40px;margin:4px}.ruc-custom-theme .mat-mdc-icon-button.mat-mdc-button-base.mdc-icon-button--reduced-size .mdc-icon-button__focus-ring{max-height:40px;max-width:40px}.ruc-custom-theme .mat-mdc-icon-button.mat-mdc-button-base .mdc-icon-button__touch{position:absolute;top:50%;height:48px;left:50%;width:48px;transform:translate(-50%,-50%)}.ruc-custom-theme .mdc-fab--extended{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-button-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-button-font-size, 20px);line-height:var(--mdc-typography-button-line-height, 60px);font-weight:var(--mdc-typography-button-font-weight, 500);letter-spacing:var(--mdc-typography-button-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-button-text-decoration, none);text-decoration:var(--mdc-typography-button-text-decoration, none);text-transform:var(--mdc-typography-button-text-transform, none)}.ruc-custom-theme .mat-mdc-snack-bar-container{--mdc-snackbar-supporting-text-font: Roboto, sans-serif;--mdc-snackbar-supporting-text-line-height: 20px;--mdc-snackbar-supporting-text-size: 14px;--mdc-snackbar-supporting-text-weight: 400}.ruc-custom-theme .mat-mdc-table .mdc-data-table__row{height:52px}.ruc-custom-theme .mat-mdc-table .mdc-data-table__pagination{min-height:52px}.ruc-custom-theme .mat-mdc-table .mdc-data-table__header-row{height:56px}.ruc-custom-theme .mdc-data-table__content,.ruc-custom-theme .mdc-data-table__cell{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-body2-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-body2-font-size, 14px);line-height:var(--mdc-typography-body2-line-height, 20px);font-weight:var(--mdc-typography-body2-font-weight, 400);letter-spacing:var(--mdc-typography-body2-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-body2-text-decoration, inherit);text-decoration:var(--mdc-typography-body2-text-decoration, inherit);text-transform:var(--mdc-typography-body2-text-transform, none)}.ruc-custom-theme .mdc-data-table__header-cell{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-subtitle2-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-subtitle2-font-size, 20px);line-height:var(--mdc-typography-subtitle2-line-height, 24px);font-weight:var(--mdc-typography-subtitle2-font-weight, 500);letter-spacing:var(--mdc-typography-subtitle2-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-subtitle2-text-decoration, inherit);text-decoration:var(--mdc-typography-subtitle2-text-decoration, inherit);text-transform:var(--mdc-typography-subtitle2-text-transform, none)}.ruc-custom-theme .mat-badge{position:relative}.ruc-custom-theme .mat-badge.mat-badge{overflow:visible}.ruc-custom-theme .mat-badge-hidden .mat-badge-content{display:none}.ruc-custom-theme .mat-badge-content{position:absolute;text-align:center;display:inline-block;border-radius:50%;transition:transform .2s ease-in-out;transform:scale(.6);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;pointer-events:none}.ruc-custom-theme .ng-animate-disabled .mat-badge-content,.ruc-custom-theme .mat-badge-content._mat-animation-noopable{transition:none}.ruc-custom-theme .mat-badge-content.mat-badge-active{transform:none}.ruc-custom-theme .mat-badge-small .mat-badge-content{width:16px;height:16px;line-height:16px}.ruc-custom-theme .mat-badge-small.mat-badge-above .mat-badge-content{top:-8px}.ruc-custom-theme .mat-badge-small.mat-badge-below .mat-badge-content{bottom:-8px}.ruc-custom-theme .mat-badge-small.mat-badge-before .mat-badge-content{left:-16px}[dir=rtl] .ruc-custom-theme .mat-badge-small.mat-badge-before .mat-badge-content{left:auto;right:-16px}.ruc-custom-theme .mat-badge-small.mat-badge-after .mat-badge-content{right:-16px}[dir=rtl] .ruc-custom-theme .mat-badge-small.mat-badge-after .mat-badge-content{right:auto;left:-16px}.ruc-custom-theme .mat-badge-small.mat-badge-overlap.mat-badge-before .mat-badge-content{left:-8px}[dir=rtl] .ruc-custom-theme .mat-badge-small.mat-badge-overlap.mat-badge-before .mat-badge-content{left:auto;right:-8px}.ruc-custom-theme .mat-badge-small.mat-badge-overlap.mat-badge-after .mat-badge-content{right:-8px}[dir=rtl] .ruc-custom-theme .mat-badge-small.mat-badge-overlap.mat-badge-after .mat-badge-content{right:auto;left:-8px}.ruc-custom-theme .mat-badge-medium .mat-badge-content{width:22px;height:22px;line-height:22px}.ruc-custom-theme .mat-badge-medium.mat-badge-above .mat-badge-content{top:-11px}.ruc-custom-theme .mat-badge-medium.mat-badge-below .mat-badge-content{bottom:-11px}.ruc-custom-theme .mat-badge-medium.mat-badge-before .mat-badge-content{left:-22px}[dir=rtl] .ruc-custom-theme .mat-badge-medium.mat-badge-before .mat-badge-content{left:auto;right:-22px}.ruc-custom-theme .mat-badge-medium.mat-badge-after .mat-badge-content{right:-22px}[dir=rtl] .ruc-custom-theme .mat-badge-medium.mat-badge-after .mat-badge-content{right:auto;left:-22px}.ruc-custom-theme .mat-badge-medium.mat-badge-overlap.mat-badge-before .mat-badge-content{left:-11px}[dir=rtl] .ruc-custom-theme .mat-badge-medium.mat-badge-overlap.mat-badge-before .mat-badge-content{left:auto;right:-11px}.ruc-custom-theme .mat-badge-medium.mat-badge-overlap.mat-badge-after .mat-badge-content{right:-11px}[dir=rtl] .ruc-custom-theme .mat-badge-medium.mat-badge-overlap.mat-badge-after .mat-badge-content{right:auto;left:-11px}.ruc-custom-theme .mat-badge-large .mat-badge-content{width:28px;height:28px;line-height:28px}.ruc-custom-theme .mat-badge-large.mat-badge-above .mat-badge-content{top:-14px}.ruc-custom-theme .mat-badge-large.mat-badge-below .mat-badge-content{bottom:-14px}.ruc-custom-theme .mat-badge-large.mat-badge-before .mat-badge-content{left:-28px}[dir=rtl] .ruc-custom-theme .mat-badge-large.mat-badge-before .mat-badge-content{left:auto;right:-28px}.ruc-custom-theme .mat-badge-large.mat-badge-after .mat-badge-content{right:-28px}[dir=rtl] .ruc-custom-theme .mat-badge-large.mat-badge-after .mat-badge-content{right:auto;left:-28px}.ruc-custom-theme .mat-badge-large.mat-badge-overlap.mat-badge-before .mat-badge-content{left:-14px}[dir=rtl] .ruc-custom-theme .mat-badge-large.mat-badge-overlap.mat-badge-before .mat-badge-content{left:auto;right:-14px}.ruc-custom-theme .mat-badge-large.mat-badge-overlap.mat-badge-after .mat-badge-content{right:-14px}[dir=rtl] .ruc-custom-theme .mat-badge-large.mat-badge-overlap.mat-badge-after .mat-badge-content{right:auto;left:-14px}.ruc-custom-theme .mat-badge-content{font-weight:600;font-size:12px;font-family:Roboto,sans-serif}.ruc-custom-theme .mat-badge-small .mat-badge-content{font-size:9px}.ruc-custom-theme .mat-badge-large .mat-badge-content{font-size:24px}.ruc-custom-theme .mat-bottom-sheet-container{font-size:14px;font-weight:400;line-height:20px;font-family:Roboto,sans-serif;letter-spacing:normal}.ruc-custom-theme .mat-button-toggle-appearance-standard .mat-button-toggle-label-content{line-height:48px}.ruc-custom-theme .mat-button-toggle{font-family:Roboto,sans-serif}.ruc-custom-theme .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base{width:40px;height:40px;padding:8px}.ruc-custom-theme .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base .mdc-icon-button__focus-ring{max-height:40px;max-width:40px}.ruc-custom-theme .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base.mdc-icon-button--reduced-size .mdc-icon-button__ripple{width:40px;height:40px;margin:0}.ruc-custom-theme .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base.mdc-icon-button--reduced-size .mdc-icon-button__focus-ring{max-height:40px;max-width:40px}.ruc-custom-theme .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base .mdc-icon-button__touch{position:absolute;top:50%;height:40px;left:50%;width:40px;transform:translate(-50%,-50%)}.ruc-custom-theme .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base .mat-mdc-button-touch-target{display:none}.ruc-custom-theme .mat-calendar{font-family:Roboto,sans-serif}.ruc-custom-theme .mat-calendar-body{font-size:13px}.ruc-custom-theme .mat-calendar-body-label,.ruc-custom-theme .mat-calendar-period-button{font-size:20px;font-weight:500}.ruc-custom-theme .mat-calendar-table-header th{font-size:11px;font-weight:400}.ruc-custom-theme .mat-expansion-panel-header{height:48px}.ruc-custom-theme .mat-expansion-panel-header.mat-expanded{height:64px}.ruc-custom-theme .mat-expansion-panel-header{font-family:Roboto,sans-serif;font-size:15px;font-weight:400}.ruc-custom-theme .mat-expansion-panel-content{font-size:14px;font-weight:400;line-height:20px;font-family:Roboto,sans-serif;letter-spacing:normal}.ruc-custom-theme .mat-grid-tile-header,.ruc-custom-theme .mat-grid-tile-footer{font-size:14px}.ruc-custom-theme .mat-grid-tile-header .mat-line,.ruc-custom-theme .mat-grid-tile-footer .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;box-sizing:border-box}.ruc-custom-theme .mat-grid-tile-header .mat-line:nth-child(n+2),.ruc-custom-theme .mat-grid-tile-footer .mat-line:nth-child(n+2){font-size:12px}.ruc-custom-theme .mat-horizontal-stepper-header{height:72px}.ruc-custom-theme .mat-stepper-label-position-bottom .mat-horizontal-stepper-header,.ruc-custom-theme .mat-vertical-stepper-header{padding:24px}.ruc-custom-theme .mat-stepper-vertical-line:before{top:-16px;bottom:-16px}.ruc-custom-theme .mat-stepper-label-position-bottom .mat-horizontal-stepper-header:after,.ruc-custom-theme .mat-stepper-label-position-bottom .mat-horizontal-stepper-header:before{top:36px}.ruc-custom-theme .mat-stepper-label-position-bottom .mat-stepper-horizontal-line{top:36px}.ruc-custom-theme .mat-stepper-vertical,.ruc-custom-theme .mat-stepper-horizontal{font-family:Roboto,sans-serif}.ruc-custom-theme .mat-step-label{font-size:14px;font-weight:400}.ruc-custom-theme .mat-step-sub-label-error{font-weight:400}.ruc-custom-theme .mat-step-label-error{font-size:20px}.ruc-custom-theme .mat-step-label-selected{font-size:20px;font-weight:500}.ruc-custom-theme .mat-toolbar-multiple-rows{min-height:64px}.ruc-custom-theme .mat-toolbar-row,.ruc-custom-theme .mat-toolbar-single-row{height:64px}@media (max-width: 599px){.ruc-custom-theme .mat-toolbar-multiple-rows{min-height:56px}.ruc-custom-theme .mat-toolbar-row,.ruc-custom-theme .mat-toolbar-single-row{height:56px}}.ruc-custom-theme .mat-toolbar,.ruc-custom-theme .mat-toolbar h1,.ruc-custom-theme .mat-toolbar h2,.ruc-custom-theme .mat-toolbar h3,.ruc-custom-theme .mat-toolbar h4,.ruc-custom-theme .mat-toolbar h5,.ruc-custom-theme .mat-toolbar h6{font-size:20px;font-weight:500;line-height:32px;font-family:Roboto,sans-serif;letter-spacing:normal;margin:0}.ruc-custom-theme .mat-tree-node{min-height:48px}.ruc-custom-theme .mat-tree{font-family:Roboto,sans-serif}.ruc-custom-theme .mat-tree-node,.ruc-custom-theme .mat-nested-tree-node{font-weight:400;font-size:14px}:host{display:block;font-family:sans-serif}.screen-recorder-controls{display:flex;gap:8px;align-items:center;padding:8px;border-radius:4px;position:relative;z-index:1000}.screen-recorder-controls.position-top-left{margin-top:10px;margin-left:10px;flex-direction:row}.screen-recorder-controls.position-top-right{margin-top:10px;margin-right:10px;flex-direction:row}.screen-recorder-controls.position-bottom-left{margin-bottom:10px;margin-left:10px;flex-direction:row}.screen-recorder-controls.position-bottom-right{margin-bottom:10px;margin-right:10px;flex-direction:row}.screen-recorder-controls.position-left,.screen-recorder-controls.position-right{float:right}.recorder-button{padding:8px 12px;border:1px solid #ccc;border-radius:4px;background-color:#fff;cursor:pointer;display:inline-flex;align-items:center;gap:4px}.recorder-button:hover{background-color:#e9e9e9}.recorder-button:active{background-color:#d0d0d0}.recorder-button.record-button{color:red}.material-icons{font-family:Material Icons;font-weight:400;font-style:normal;font-size:20px;display:inline-block;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:\"liga\"}.recorder-timer{padding:0 8px;font-feature-settings:\"tnum\";font-variant-numeric:tabular-nums}.playback-area{width:100%;max-width:100%;margin-top:1rem;position:relative}.playback-area video{width:100%;height:auto;max-width:100%}.playback-area .video-timer-overlay{position:absolute;top:10px;right:10px;background:rgba(0,0,0,.7);color:#fff;padding:5px 10px;border-radius:4px;font-size:14px;z-index:10}.recorder-error{color:red;padding:8px;border:1px solid red;background-color:#ffe0e0;border-radius:4px;margin-bottom:8px}.recorder-notsupported{padding:10px;background-color:#fff3cd;border:1px solid #ffeeba;color:#856404;border-radius:4px}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
616
616
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ScreenRecorderComponent, decorators: [{
617
617
  type: Component,
618
- args: [{ selector: 'uxp-screen-recorder', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"screen-recorder-controls\" [ngClass]=\"customTheme + ' position-' + (rucInputData.position || ScreenRecorderPosition.Bottom)\"\r\n *ngIf=\"isBrowserSupported\">\r\n\r\n <!-- Error Message -->\r\n <div *ngIf=\"errorMessage\" class=\"recorder-error\">\r\n {{ errorMessage }}\r\n </div>\r\n\r\n <!-- Record/Stop Button -->\r\n <button\r\n *ngIf=\"recordingState === RecordingState.Idle || recordingState === RecordingState.Stopped\" (click)=\"toggleRecord()\"\r\n [attr.aria-label]=\"getLabel('recordButton')\" [attr.aria-pressed]=\"false\" class=\"recorder-button record-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getRecordingIcon() || getIcon('record') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('recordButton')\r\n }}</ng-container>\r\n </button>\r\n\r\n <button\r\n *ngIf=\"recordingState === RecordingState.Recording || recordingState === RecordingState.Paused\"\r\n (click)=\"toggleRecord()\" [attr.aria-label]=\"getLabel('stopButton')\" [attr.aria-pressed]=\"true\"\r\n class=\"recorder-button stop-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('stop') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('stopButton') }}</ng-container>\r\n </button>\r\n\r\n <!-- Pause/Resume Button -->\r\n <button *ngIf=\"rucInputData.showPauseResume && recordingState === RecordingState.Recording\"\r\n (click)=\"togglePauseResume()\" [attr.aria-label]=\"getLabel('pauseButton')\" [attr.aria-pressed]=\"false\"\r\n class=\"recorder-button pause-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('pause') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('pauseButton') }}</ng-container>\r\n </button>\r\n <button *ngIf=\"rucInputData.showPauseResume && recordingState === RecordingState.Paused\"\r\n (click)=\"togglePauseResume()\" [attr.aria-label]=\"getLabel('resumeButton')\" [attr.aria-pressed]=\"true\"\r\n class=\"recorder-button resume-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('resume') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('resumeButton')\r\n }}</ng-container>\r\n </button>\r\n\r\n <!-- Audio Toggle Button -->\r\n <button\r\n *ngIf=\"rucInputData.showAudioToggle && (recordingState === RecordingState.Idle || recordingState === RecordingState.Stopped)\"\r\n (click)=\"toggleAudio()\" [attr.aria-label]=\"getLabel('audioToggleButton')\" [attr.aria-pressed]=\"isAudioEnabled\"\r\n class=\"recorder-button audio-toggle-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ isAudioEnabled ? getIcon('audioOn') : getIcon('audioOff') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">\r\n {{ isAudioEnabled ? screenRecordingConstant.AUDIO_ON : screenRecordingConstant.AUDIO_OFF }}\r\n </ng-container>\r\n </button>\r\n\r\n <!-- Timer -->\r\n <div\r\n *ngIf=\"rucInputData.showTimer && (recordingState === RecordingState.Recording || recordingState === RecordingState.Paused)\"\r\n class=\"recorder-timer\" aria-live=\"polite\" aria-atomic=\"true\">\r\n {{ formattedTime }}\r\n </div>\r\n\r\n <!-- Download Button -->\r\n <button\r\n *ngIf=\"rucInputData.showDownloadButton && recordingState === RecordingState.Stopped && safeRecordedUrl\"\r\n (click)=\"onDownload()\" [attr.aria-label]=\"getLabel('downloadButton')\" class=\"recorder-button download-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('download') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('downloadButton')\r\n }}</ng-container>\r\n </button>\r\n\r\n <!-- Playback Area -->\r\n <div *ngIf=\"rucInputData.showPlaybackControls && recordingState === RecordingState.Stopped && safeRecordedUrl\"\r\n class=\"playback-area\">\r\n <video #videoPlayer [src]=\"safeRecordedUrl\" controls [attr.aria-label]=\"getLabel('playbackVideo')\"></video>\r\n <div class=\"video-timer-overlay\">\r\n <span>Recorded on: {{ recordingTimestamp }}</span>\r\n </div>\r\n </div>\r\n\r\n <!-- Reset Button (optional, good for testing/clearing state) -->\r\n <button *ngIf=\"recordingState === RecordingState.Stopped && safeRecordedUrl\" (click)=\"reset()\"\r\n aria-label=\"New Recording\" class=\"recorder-button reset-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">refresh</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">New</ng-container>\r\n </button>\r\n\r\n</div>\r\n\r\n<div *ngIf=\"!isBrowserSupported\" class=\"recorder-notsupported\" [ngClass]=\"customTheme\">\r\n {{screenRecordingConstant.NO_SUPPORT}}\r\n</div>", styles: [":host{display:block;font-family:sans-serif}.screen-recorder-controls{display:flex;gap:8px;align-items:center;padding:8px;border-radius:4px;position:relative;z-index:1000}.screen-recorder-controls.position-top-left{margin-top:10px;margin-left:10px;flex-direction:row}.screen-recorder-controls.position-top-right{margin-top:10px;margin-right:10px;flex-direction:row}.screen-recorder-controls.position-bottom-left{margin-bottom:10px;margin-left:10px;flex-direction:row}.screen-recorder-controls.position-bottom-right{margin-bottom:10px;margin-right:10px;flex-direction:row}.screen-recorder-controls.position-left,.screen-recorder-controls.position-right{float:right}.recorder-button{padding:8px 12px;border:1px solid #ccc;border-radius:4px;background-color:#fff;cursor:pointer;display:inline-flex;align-items:center;gap:4px}.recorder-button:hover{background-color:#e9e9e9}.recorder-button:active{background-color:#d0d0d0}.recorder-button.record-button{color:red}.material-icons{font-family:Material Icons;font-weight:400;font-style:normal;font-size:20px;display:inline-block;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:\"liga\"}.recorder-timer{padding:0 8px;font-feature-settings:\"tnum\";font-variant-numeric:tabular-nums}.playback-area{width:100%;max-width:100%;margin-top:1rem;position:relative}.playback-area video{width:100%;height:auto;max-width:100%}.playback-area .video-timer-overlay{position:absolute;top:10px;right:10px;background:rgba(0,0,0,.7);color:#fff;padding:5px 10px;border-radius:4px;font-size:14px;z-index:10}.recorder-error{color:red;padding:8px;border:1px solid red;background-color:#ffe0e0;border-radius:4px;margin-bottom:8px}.recorder-notsupported{padding:10px;background-color:#fff3cd;border:1px solid #ffeeba;color:#856404;border-radius:4px}\n"] }]
618
+ args: [{ selector: 'uxp-ruclib-screen-recorder', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"main\">\r\n <div class=\"screen-recorder-controls\"\r\n [ngClass]=\"customTheme + ' position-' + (rucInputData.position || ScreenRecorderPosition.Bottom)\"\r\n *ngIf=\"isBrowserSupported\">\r\n\r\n <!-- Error Message -->\r\n <div *ngIf=\"errorMessage\" class=\"recorder-error\">\r\n {{ errorMessage }}\r\n </div>\r\n\r\n <!-- Record/Stop Button -->\r\n <button *ngIf=\"recordingState === RecordingState.Idle || recordingState === RecordingState.Stopped\"\r\n (click)=\"toggleRecord()\" [attr.aria-label]=\"getLabel('recordButton')\" [attr.aria-pressed]=\"false\"\r\n class=\"recorder-button record-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getRecordingIcon() || getIcon('record') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('recordButton')\r\n }}</ng-container>\r\n </button>\r\n\r\n <button *ngIf=\"recordingState === RecordingState.Recording || recordingState === RecordingState.Paused\"\r\n (click)=\"toggleRecord()\" [attr.aria-label]=\"getLabel('stopButton')\" [attr.aria-pressed]=\"true\"\r\n class=\"recorder-button stop-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('stop') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('stopButton')\r\n }}</ng-container>\r\n </button>\r\n\r\n <!-- Pause/Resume Button -->\r\n <button *ngIf=\"rucInputData.showPauseResume && recordingState === RecordingState.Recording\"\r\n (click)=\"togglePauseResume()\" [attr.aria-label]=\"getLabel('pauseButton')\" [attr.aria-pressed]=\"false\"\r\n class=\"recorder-button pause-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('pause') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('pauseButton')\r\n }}</ng-container>\r\n </button>\r\n <button *ngIf=\"rucInputData.showPauseResume && recordingState === RecordingState.Paused\"\r\n (click)=\"togglePauseResume()\" [attr.aria-label]=\"getLabel('resumeButton')\" [attr.aria-pressed]=\"true\"\r\n class=\"recorder-button resume-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('resume') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('resumeButton')\r\n }}</ng-container>\r\n </button>\r\n\r\n <!-- Audio Toggle Button -->\r\n <button\r\n *ngIf=\"rucInputData.showAudioToggle && (recordingState === RecordingState.Idle || recordingState === RecordingState.Stopped)\"\r\n (click)=\"toggleAudio()\" [attr.aria-label]=\"getLabel('audioToggleButton')\" [attr.aria-pressed]=\"isAudioEnabled\"\r\n class=\"recorder-button audio-toggle-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ isAudioEnabled ? getIcon('audioOn') : getIcon('audioOff') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">\r\n {{ isAudioEnabled ? screenRecordingConstant.AUDIO_ON : screenRecordingConstant.AUDIO_OFF }}\r\n </ng-container>\r\n </button>\r\n\r\n <!-- Timer -->\r\n <div\r\n *ngIf=\"rucInputData.showTimer && (recordingState === RecordingState.Recording || recordingState === RecordingState.Paused)\"\r\n class=\"recorder-timer\" aria-live=\"polite\" aria-atomic=\"true\">\r\n {{ formattedTime }}\r\n </div>\r\n\r\n <!-- Download Button -->\r\n <button *ngIf=\"rucInputData.showDownloadButton && recordingState === RecordingState.Stopped && safeRecordedUrl\"\r\n (click)=\"onDownload()\" [attr.aria-label]=\"getLabel('downloadButton')\" class=\"recorder-button download-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">{{ getIcon('download') }}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">{{ getLabel('downloadButton')\r\n }}</ng-container>\r\n </button>\r\n\r\n <!-- Playback Area -->\r\n <div *ngIf=\"rucInputData.showPlaybackControls && recordingState === RecordingState.Stopped && safeRecordedUrl\"\r\n class=\"playback-area\">\r\n <video #videoPlayer [src]=\"safeRecordedUrl\" controls [attr.aria-label]=\"getLabel('playbackVideo')\"></video>\r\n <div class=\"video-timer-overlay\">\r\n <span>Recorded on: {{ recordingTimestamp }}</span>\r\n </div>\r\n </div>\r\n\r\n <!-- Reset Button (optional, good for testing/clearing state) -->\r\n <button *ngIf=\"recordingState === RecordingState.Stopped && safeRecordedUrl\" (click)=\"reset()\"\r\n aria-label=\"New Recording\" class=\"recorder-button reset-button\">\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Icon\">\r\n <span class=\"material-icons\">refresh</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rucInputData.displayFormat === DisplayFormat.Text\">New</ng-container>\r\n </button>\r\n\r\n </div>\r\n\r\n <div *ngIf=\"!isBrowserSupported\" class=\"recorder-notsupported\" [ngClass]=\"customTheme\">\r\n {{screenRecordingConstant.NO_SUPPORT}}\r\n </div>\r\n</div>", styles: [".mat-ripple{overflow:hidden;position:relative}.mat-ripple:not(:empty){transform:translateZ(0)}.mat-ripple.mat-ripple-unbounded{overflow:visible}.mat-ripple-element{position:absolute;border-radius:50%;pointer-events:none;transition:opacity,transform 0ms cubic-bezier(0,0,.2,1);transform:scale3d(0,0,0)}.cdk-high-contrast-active .mat-ripple-element{display:none}.cdk-visually-hidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap;outline:0;-webkit-appearance:none;-moz-appearance:none;left:0}[dir=rtl] .cdk-visually-hidden{left:auto;right:0}.cdk-overlay-container,.cdk-global-overlay-wrapper{pointer-events:none;top:0;left:0;height:100%;width:100%}.cdk-overlay-container{position:fixed;z-index:1000}.cdk-overlay-container:empty{display:none}.cdk-global-overlay-wrapper{display:flex;position:absolute;z-index:1000}.cdk-overlay-pane{position:absolute;pointer-events:auto;box-sizing:border-box;z-index:1000;display:flex;max-width:100%;max-height:100%}.cdk-overlay-backdrop{position:absolute;inset:0;z-index:1000;pointer-events:auto;-webkit-tap-highlight-color:transparent;transition:opacity .4s cubic-bezier(.25,.8,.25,1);opacity:0}.cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:1}.cdk-high-contrast-active .cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:.6}.cdk-overlay-dark-backdrop{background:rgba(0,0,0,.32)}.cdk-overlay-transparent-backdrop{transition:visibility 1ms linear,opacity 1ms linear;visibility:hidden;opacity:1}.cdk-overlay-transparent-backdrop.cdk-overlay-backdrop-showing{opacity:0;visibility:visible}.cdk-overlay-backdrop-noop-animation{transition:none}.cdk-overlay-connected-position-bounding-box{position:absolute;z-index:1000;display:flex;flex-direction:column;min-width:1px;min-height:1px}.cdk-global-scrollblock{position:fixed;width:100%;overflow-y:scroll}textarea.cdk-textarea-autosize{resize:none}textarea.cdk-textarea-autosize-measuring{padding:2px 0!important;box-sizing:content-box!important;height:auto!important;overflow:hidden!important}textarea.cdk-textarea-autosize-measuring-firefox{padding:2px 0!important;box-sizing:content-box!important;height:0!important}@keyframes cdk-text-field-autofill-start{}@keyframes cdk-text-field-autofill-end{}.cdk-text-field-autofill-monitored:-webkit-autofill{animation:cdk-text-field-autofill-start 0s 1ms}.cdk-text-field-autofill-monitored:not(:-webkit-autofill){animation:cdk-text-field-autofill-end 0s 1ms}.mat-focus-indicator{position:relative}.mat-focus-indicator:before{inset:0;position:absolute;box-sizing:border-box;pointer-events:none;display:var(--mat-focus-indicator-display, none);border:var(--mat-focus-indicator-border-width, 3px) var(--mat-focus-indicator-border-style, solid) var(--mat-focus-indicator-border-color, transparent);border-radius:var(--mat-focus-indicator-border-radius, 4px)}.mat-focus-indicator:focus:before{content:\"\"}.cdk-high-contrast-active{--mat-focus-indicator-display: block}.mat-mdc-focus-indicator{position:relative}.mat-mdc-focus-indicator:before{inset:0;position:absolute;box-sizing:border-box;pointer-events:none;display:var(--mat-mdc-focus-indicator-display, none);border:var(--mat-mdc-focus-indicator-border-width, 3px) var(--mat-mdc-focus-indicator-border-style, solid) var(--mat-mdc-focus-indicator-border-color, transparent);border-radius:var(--mat-mdc-focus-indicator-border-radius, 4px)}.mat-mdc-focus-indicator:focus:before{content:\"\"}.cdk-high-contrast-active{--mat-mdc-focus-indicator-display: block}.main{font-size:16px;font-weight:400;line-height:24px;font-family:Roboto,sans-serif;letter-spacing:.03125em}.ruc-custom-theme{font-size:14px;font-weight:400;line-height:20px;font-family:Roboto,sans-serif;letter-spacing:normal}.ruc-custom-theme .mat-mdc-option{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-body1-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-body1-font-size, 15px);line-height:var(--mdc-typography-body1-line-height, 24px);font-weight:var(--mdc-typography-body1-font-weight, 400);letter-spacing:var(--mdc-typography-body1-letter-spacing, normal)}.ruc-custom-theme .mat-mdc-card-title{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-headline6-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-headline6-font-size, 20px);line-height:var(--mdc-typography-headline6-line-height, 32px);font-weight:var(--mdc-typography-headline6-font-weight, 500);letter-spacing:var(--mdc-typography-headline6-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-headline6-text-decoration, inherit);text-decoration:var(--mdc-typography-headline6-text-decoration, inherit);text-transform:var(--mdc-typography-headline6-text-transform, none)}.ruc-custom-theme .mat-mdc-card-subtitle{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-subtitle2-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-subtitle2-font-size, 20px);line-height:var(--mdc-typography-subtitle2-line-height, 24px);font-weight:var(--mdc-typography-subtitle2-font-weight, 500);letter-spacing:var(--mdc-typography-subtitle2-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-subtitle2-text-decoration, inherit);text-decoration:var(--mdc-typography-subtitle2-text-decoration, inherit);text-transform:var(--mdc-typography-subtitle2-text-transform, none)}.ruc-custom-theme .mat-mdc-tooltip{--mdc-plain-tooltip-supporting-text-font: Roboto, sans-serif;--mdc-plain-tooltip-supporting-text-size: 12px;--mdc-plain-tooltip-supporting-text-weight: 400;--mdc-plain-tooltip-supporting-text-tracking: normal}.ruc-custom-theme .mat-mdc-form-field-infix{min-height:56px}.ruc-custom-theme .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-floating-label{top:28px}.ruc-custom-theme .mat-mdc-text-field-wrapper.mdc-text-field--outlined .mdc-notched-outline--upgraded .mdc-floating-label--float-above{--mat-mdc-form-field-label-transform: translateY( -34.75px) scale(var(--mat-mdc-form-field-floating-label-scale, .75));transform:var(--mat-mdc-form-field-label-transform)}.ruc-custom-theme .mat-mdc-text-field-wrapper.mdc-text-field--outlined .mat-mdc-form-field-infix{padding-top:16px;padding-bottom:16px}.ruc-custom-theme .mat-mdc-text-field-wrapper:not(.mdc-text-field--outlined) .mat-mdc-form-field-infix{padding-top:24px;padding-bottom:8px}.ruc-custom-theme .mdc-text-field--no-label:not(.mdc-text-field--outlined):not(.mdc-text-field--textarea) .mat-mdc-form-field-infix{padding-top:16px;padding-bottom:16px}.ruc-custom-theme .mdc-text-field__input,.ruc-custom-theme .mdc-text-field__affix{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-subtitle1-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-subtitle1-font-size, 16px);font-weight:var(--mdc-typography-subtitle1-font-weight, 400);letter-spacing:var(--mdc-typography-subtitle1-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-subtitle1-text-decoration, inherit);text-decoration:var(--mdc-typography-subtitle1-text-decoration, inherit);text-transform:var(--mdc-typography-subtitle1-text-transform, none)}.ruc-custom-theme .mdc-text-field--textarea .mdc-text-field__input{line-height:1.5rem}.ruc-custom-theme .mdc-floating-label{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-subtitle1-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-subtitle1-font-size, 16px);font-weight:var(--mdc-typography-subtitle1-font-weight, 400);letter-spacing:var(--mdc-typography-subtitle1-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-subtitle1-text-decoration, inherit);text-decoration:var(--mdc-typography-subtitle1-text-decoration, inherit);text-transform:var(--mdc-typography-subtitle1-text-transform, none)}.ruc-custom-theme .mat-mdc-form-field-subscript-wrapper,.ruc-custom-theme .mat-mdc-form-field-bottom-align:before{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-caption-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-caption-font-size, 12px);line-height:var(--mdc-typography-caption-line-height, 20px);font-weight:var(--mdc-typography-caption-font-weight, 400);letter-spacing:var(--mdc-typography-caption-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-caption-text-decoration, inherit);text-decoration:var(--mdc-typography-caption-text-decoration, inherit);text-transform:var(--mdc-typography-caption-text-transform, none)}.ruc-custom-theme .mat-mdc-form-field,.ruc-custom-theme .mat-mdc-floating-label{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-body1-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-body1-font-size, 15px);line-height:var(--mdc-typography-body1-line-height, 24px);font-weight:var(--mdc-typography-body1-font-weight, 400);letter-spacing:var(--mdc-typography-body1-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-body1-text-decoration, inherit);text-decoration:var(--mdc-typography-body1-text-decoration, inherit);text-transform:var(--mdc-typography-body1-text-transform, none)}.ruc-custom-theme .mat-mdc-form-field .mdc-text-field--outlined .mdc-floating-label--float-above{font-size:calc(15px * var(--mat-mdc-form-field-floating-label-scale, .75))}.ruc-custom-theme .mat-mdc-form-field .mdc-text-field--outlined .mdc-notched-outline--upgraded .mdc-floating-label--float-above{font-size:15px}.ruc-custom-theme .mat-mdc-select-panel{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-subtitle1-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-subtitle1-font-size, 16px);line-height:var(--mdc-typography-subtitle1-line-height, 28px);font-weight:var(--mdc-typography-subtitle1-font-weight, 400);letter-spacing:var(--mdc-typography-subtitle1-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-subtitle1-text-decoration, inherit);text-decoration:var(--mdc-typography-subtitle1-text-decoration, inherit);text-transform:var(--mdc-typography-subtitle1-text-transform, none);line-height:24px}.ruc-custom-theme .mat-mdc-select{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-body1-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-body1-font-size, 15px);line-height:var(--mdc-typography-body1-line-height, 24px);font-weight:var(--mdc-typography-body1-font-weight, 400);letter-spacing:var(--mdc-typography-body1-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-body1-text-decoration, inherit);text-decoration:var(--mdc-typography-body1-text-decoration, inherit);text-transform:var(--mdc-typography-body1-text-transform, none)}.ruc-custom-theme .mat-mdc-autocomplete-panel{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-subtitle1-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-subtitle1-font-size, 16px);line-height:var(--mdc-typography-subtitle1-line-height, 28px);font-weight:var(--mdc-typography-subtitle1-font-weight, 400);letter-spacing:var(--mdc-typography-subtitle1-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-subtitle1-text-decoration, inherit);text-decoration:var(--mdc-typography-subtitle1-text-decoration, inherit);text-transform:var(--mdc-typography-subtitle1-text-transform, none);line-height:24px}.ruc-custom-theme .mat-mdc-dialog-container{--mdc-dialog-subhead-font: Roboto, sans-serif;--mdc-dialog-subhead-line-height: 32px;--mdc-dialog-subhead-size: 20px;--mdc-dialog-subhead-weight: 500;--mdc-dialog-subhead-tracking: normal;--mdc-dialog-supporting-text-font: Roboto, sans-serif;--mdc-dialog-supporting-text-line-height: 24px;--mdc-dialog-supporting-text-size: 15px;--mdc-dialog-supporting-text-weight: 400;--mdc-dialog-supporting-text-tracking: normal}.ruc-custom-theme .mat-mdc-chip{height:32px}.ruc-custom-theme .mat-mdc-standard-chip{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-body2-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-body2-font-size, 14px);line-height:var(--mdc-typography-body2-line-height, 20px);font-weight:var(--mdc-typography-body2-font-weight, 400);letter-spacing:var(--mdc-typography-body2-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-body2-text-decoration, inherit);text-decoration:var(--mdc-typography-body2-text-decoration, inherit);text-transform:var(--mdc-typography-body2-text-transform, none)}.ruc-custom-theme .mat-mdc-slide-toggle{--mdc-switch-state-layer-size: 48px}.ruc-custom-theme .mat-mdc-radio-button .mdc-radio{padding:10px}.ruc-custom-theme .mat-mdc-radio-button .mdc-radio .mdc-radio__background:before{top:-10px;left:-10px;width:40px;height:40px}.ruc-custom-theme .mat-mdc-radio-button .mdc-radio .mdc-radio__native-control{top:0;right:0;left:0;width:40px;height:40px}.ruc-custom-theme .mat-mdc-slider{--mdc-slider-label-label-text-font: Roboto, sans-serif;--mdc-slider-label-label-text-size: 20px;--mdc-slider-label-label-text-line-height: 24px;--mdc-slider-label-label-text-tracking: normal;--mdc-slider-label-label-text-weight: 500}.ruc-custom-theme .mat-mdc-menu-content{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-subtitle1-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-subtitle1-font-size, 16px);line-height:var(--mdc-typography-subtitle1-line-height, 28px);font-weight:var(--mdc-typography-subtitle1-font-weight, 400);letter-spacing:var(--mdc-typography-subtitle1-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-subtitle1-text-decoration, inherit);text-decoration:var(--mdc-typography-subtitle1-text-decoration, inherit);text-transform:var(--mdc-typography-subtitle1-text-transform, none);line-height:24px}.ruc-custom-theme .mat-mdc-menu-content,.ruc-custom-theme .mat-mdc-menu-content .mat-mdc-menu-item .mdc-list-item__primary-text{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-body1-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-body1-font-size, 15px);line-height:var(--mdc-typography-body1-line-height, 24px);font-weight:var(--mdc-typography-body1-font-weight, 400);letter-spacing:var(--mdc-typography-body1-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-body1-text-decoration, inherit);text-decoration:var(--mdc-typography-body1-text-decoration, inherit);text-transform:var(--mdc-typography-body1-text-transform, none)}.ruc-custom-theme .mat-mdc-list-base{--mdc-list-list-item-one-line-container-height: 48px;--mdc-list-list-item-two-line-container-height: 64px;--mdc-list-list-item-three-line-container-height: 88px}.ruc-custom-theme .mat-mdc-list-item.mdc-list-item--with-leading-avatar.mdc-list-item--with-one-line,.ruc-custom-theme .mat-mdc-list-item.mdc-list-item--with-leading-checkbox.mdc-list-item--with-one-line,.ruc-custom-theme .mat-mdc-list-item.mdc-list-item--with-leading-icon.mdc-list-item--with-one-line{height:56px}.ruc-custom-theme .mat-mdc-list-item.mdc-list-item--with-leading-avatar.mdc-list-item--with-two-lines,.ruc-custom-theme .mat-mdc-list-item.mdc-list-item--with-leading-checkbox.mdc-list-item--with-two-lines,.ruc-custom-theme .mat-mdc-list-item.mdc-list-item--with-leading-icon.mdc-list-item--with-two-lines{height:72px}.ruc-custom-theme .mat-mdc-list-base{--mdc-list-list-item-label-text-font: Roboto, sans-serif;--mdc-list-list-item-label-text-line-height: 24px;--mdc-list-list-item-label-text-size: 15px;--mdc-list-list-item-label-text-tracking: normal;--mdc-list-list-item-label-text-weight: 400;--mdc-list-list-item-supporting-text-font: Roboto, sans-serif;--mdc-list-list-item-supporting-text-line-height: 20px;--mdc-list-list-item-supporting-text-size: 14px;--mdc-list-list-item-supporting-text-tracking: normal;--mdc-list-list-item-supporting-text-weight: 400;--mdc-list-list-item-trailing-supporting-text-font: Roboto, sans-serif;--mdc-list-list-item-trailing-supporting-text-line-height: 20px;--mdc-list-list-item-trailing-supporting-text-size: 12px;--mdc-list-list-item-trailing-supporting-text-tracking: normal;--mdc-list-list-item-trailing-supporting-text-weight: 400}.ruc-custom-theme .mdc-list-group__subheader{font-size:16px;font-weight:400;line-height:28px;font-family:Roboto,sans-serif;letter-spacing:normal}.ruc-custom-theme .mat-mdc-paginator .mat-mdc-form-field-infix{min-height:40px}.ruc-custom-theme .mat-mdc-paginator .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-floating-label{top:20px}.ruc-custom-theme .mat-mdc-paginator .mat-mdc-text-field-wrapper.mdc-text-field--outlined .mdc-notched-outline--upgraded .mdc-floating-label--float-above{--mat-mdc-form-field-label-transform: translateY( -26.75px) scale(var(--mat-mdc-form-field-floating-label-scale, .75));transform:var(--mat-mdc-form-field-label-transform)}.ruc-custom-theme .mat-mdc-paginator .mat-mdc-text-field-wrapper.mdc-text-field--outlined .mat-mdc-form-field-infix{padding-top:8px;padding-bottom:8px}.ruc-custom-theme .mat-mdc-paginator .mat-mdc-text-field-wrapper:not(.mdc-text-field--outlined) .mat-mdc-form-field-infix{padding-top:8px;padding-bottom:8px}.ruc-custom-theme .mat-mdc-paginator .mdc-text-field--no-label:not(.mdc-text-field--outlined):not(.mdc-text-field--textarea) .mat-mdc-form-field-infix{padding-top:8px;padding-bottom:8px}.ruc-custom-theme .mat-mdc-paginator .mat-mdc-text-field-wrapper:not(.mdc-text-field--outlined) .mat-mdc-floating-label{display:none}.ruc-custom-theme .mat-mdc-paginator-container{min-height:56px}.ruc-custom-theme .mat-mdc-paginator{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-caption-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-caption-font-size, 12px);line-height:var(--mdc-typography-caption-line-height, 20px);font-weight:var(--mdc-typography-caption-font-weight, 400);letter-spacing:var(--mdc-typography-caption-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-caption-text-decoration, inherit);text-decoration:var(--mdc-typography-caption-text-decoration, inherit);text-transform:var(--mdc-typography-caption-text-transform, none)}.ruc-custom-theme .mat-mdc-paginator .mat-mdc-select-value{font-size:12px}.ruc-custom-theme .mat-mdc-tab-header .mdc-tab{height:48px}.ruc-custom-theme .mdc-tab{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-button-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-button-font-size, 20px);line-height:var(--mdc-typography-button-line-height, 60px);font-weight:var(--mdc-typography-button-font-weight, 500);letter-spacing:var(--mdc-typography-button-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-button-text-decoration, none);text-decoration:var(--mdc-typography-button-text-decoration, none);text-transform:var(--mdc-typography-button-text-transform, none)}.ruc-custom-theme .mat-mdc-checkbox .mdc-checkbox{padding:calc((var(--mdc-checkbox-ripple-size, 40px) - 18px) / 2);margin:calc((var(--mdc-checkbox-touch-target-size, 40px) - 40px) / 2)}.ruc-custom-theme .mat-mdc-checkbox .mdc-checkbox .mdc-checkbox__background{top:calc((var(--mdc-checkbox-ripple-size, 40px) - 18px) / 2);left:calc((var(--mdc-checkbox-ripple-size, 40px) - 18px) / 2)}.ruc-custom-theme .mat-mdc-checkbox .mdc-checkbox .mdc-checkbox__native-control{top:calc((40px - var(--mdc-checkbox-touch-target-size, 40px)) / 2);right:calc((40px - var(--mdc-checkbox-touch-target-size, 40px)) / 2);left:calc((40px - var(--mdc-checkbox-touch-target-size, 40px)) / 2);width:var(--mdc-checkbox-touch-target-size, 40px);height:var(--mdc-checkbox-touch-target-size, 40px)}@media all and (-ms-high-contrast: none){.ruc-custom-theme .mdc-checkbox .mdc-checkbox__focus-ring{display:none}}.ruc-custom-theme .mdc-form-field{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-body2-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-body2-font-size, 14px);line-height:var(--mdc-typography-body2-line-height, 20px);font-weight:var(--mdc-typography-body2-font-weight, 400);letter-spacing:var(--mdc-typography-body2-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-body2-text-decoration, inherit);text-decoration:var(--mdc-typography-body2-text-decoration, inherit);text-transform:var(--mdc-typography-body2-text-transform, none)}.ruc-custom-theme .mat-mdc-button.mat-mdc-button-base,.ruc-custom-theme .mat-mdc-raised-button.mat-mdc-button-base,.ruc-custom-theme .mat-mdc-unelevated-button.mat-mdc-button-base,.ruc-custom-theme .mat-mdc-outlined-button.mat-mdc-button-base{height:36px}.ruc-custom-theme .mdc-button{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-button-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-button-font-size, 20px);line-height:var(--mdc-typography-button-line-height, 60px);font-weight:var(--mdc-typography-button-font-weight, 500);letter-spacing:var(--mdc-typography-button-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-button-text-decoration, none);text-decoration:var(--mdc-typography-button-text-decoration, none);text-transform:var(--mdc-typography-button-text-transform, none)}.ruc-custom-theme .mat-mdc-icon-button.mat-mdc-button-base{width:48px;height:48px;padding:12px}.ruc-custom-theme .mat-mdc-icon-button.mat-mdc-button-base .mdc-icon-button__focus-ring{max-height:48px;max-width:48px}.ruc-custom-theme .mat-mdc-icon-button.mat-mdc-button-base.mdc-icon-button--reduced-size .mdc-icon-button__ripple{width:40px;height:40px;margin:4px}.ruc-custom-theme .mat-mdc-icon-button.mat-mdc-button-base.mdc-icon-button--reduced-size .mdc-icon-button__focus-ring{max-height:40px;max-width:40px}.ruc-custom-theme .mat-mdc-icon-button.mat-mdc-button-base .mdc-icon-button__touch{position:absolute;top:50%;height:48px;left:50%;width:48px;transform:translate(-50%,-50%)}.ruc-custom-theme .mdc-fab--extended{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-button-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-button-font-size, 20px);line-height:var(--mdc-typography-button-line-height, 60px);font-weight:var(--mdc-typography-button-font-weight, 500);letter-spacing:var(--mdc-typography-button-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-button-text-decoration, none);text-decoration:var(--mdc-typography-button-text-decoration, none);text-transform:var(--mdc-typography-button-text-transform, none)}.ruc-custom-theme .mat-mdc-snack-bar-container{--mdc-snackbar-supporting-text-font: Roboto, sans-serif;--mdc-snackbar-supporting-text-line-height: 20px;--mdc-snackbar-supporting-text-size: 14px;--mdc-snackbar-supporting-text-weight: 400}.ruc-custom-theme .mat-mdc-table .mdc-data-table__row{height:52px}.ruc-custom-theme .mat-mdc-table .mdc-data-table__pagination{min-height:52px}.ruc-custom-theme .mat-mdc-table .mdc-data-table__header-row{height:56px}.ruc-custom-theme .mdc-data-table__content,.ruc-custom-theme .mdc-data-table__cell{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-body2-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-body2-font-size, 14px);line-height:var(--mdc-typography-body2-line-height, 20px);font-weight:var(--mdc-typography-body2-font-weight, 400);letter-spacing:var(--mdc-typography-body2-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-body2-text-decoration, inherit);text-decoration:var(--mdc-typography-body2-text-decoration, inherit);text-transform:var(--mdc-typography-body2-text-transform, none)}.ruc-custom-theme .mdc-data-table__header-cell{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mdc-typography-subtitle2-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:var(--mdc-typography-subtitle2-font-size, 20px);line-height:var(--mdc-typography-subtitle2-line-height, 24px);font-weight:var(--mdc-typography-subtitle2-font-weight, 500);letter-spacing:var(--mdc-typography-subtitle2-letter-spacing, normal);-webkit-text-decoration:var(--mdc-typography-subtitle2-text-decoration, inherit);text-decoration:var(--mdc-typography-subtitle2-text-decoration, inherit);text-transform:var(--mdc-typography-subtitle2-text-transform, none)}.ruc-custom-theme .mat-badge{position:relative}.ruc-custom-theme .mat-badge.mat-badge{overflow:visible}.ruc-custom-theme .mat-badge-hidden .mat-badge-content{display:none}.ruc-custom-theme .mat-badge-content{position:absolute;text-align:center;display:inline-block;border-radius:50%;transition:transform .2s ease-in-out;transform:scale(.6);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;pointer-events:none}.ruc-custom-theme .ng-animate-disabled .mat-badge-content,.ruc-custom-theme .mat-badge-content._mat-animation-noopable{transition:none}.ruc-custom-theme .mat-badge-content.mat-badge-active{transform:none}.ruc-custom-theme .mat-badge-small .mat-badge-content{width:16px;height:16px;line-height:16px}.ruc-custom-theme .mat-badge-small.mat-badge-above .mat-badge-content{top:-8px}.ruc-custom-theme .mat-badge-small.mat-badge-below .mat-badge-content{bottom:-8px}.ruc-custom-theme .mat-badge-small.mat-badge-before .mat-badge-content{left:-16px}[dir=rtl] .ruc-custom-theme .mat-badge-small.mat-badge-before .mat-badge-content{left:auto;right:-16px}.ruc-custom-theme .mat-badge-small.mat-badge-after .mat-badge-content{right:-16px}[dir=rtl] .ruc-custom-theme .mat-badge-small.mat-badge-after .mat-badge-content{right:auto;left:-16px}.ruc-custom-theme .mat-badge-small.mat-badge-overlap.mat-badge-before .mat-badge-content{left:-8px}[dir=rtl] .ruc-custom-theme .mat-badge-small.mat-badge-overlap.mat-badge-before .mat-badge-content{left:auto;right:-8px}.ruc-custom-theme .mat-badge-small.mat-badge-overlap.mat-badge-after .mat-badge-content{right:-8px}[dir=rtl] .ruc-custom-theme .mat-badge-small.mat-badge-overlap.mat-badge-after .mat-badge-content{right:auto;left:-8px}.ruc-custom-theme .mat-badge-medium .mat-badge-content{width:22px;height:22px;line-height:22px}.ruc-custom-theme .mat-badge-medium.mat-badge-above .mat-badge-content{top:-11px}.ruc-custom-theme .mat-badge-medium.mat-badge-below .mat-badge-content{bottom:-11px}.ruc-custom-theme .mat-badge-medium.mat-badge-before .mat-badge-content{left:-22px}[dir=rtl] .ruc-custom-theme .mat-badge-medium.mat-badge-before .mat-badge-content{left:auto;right:-22px}.ruc-custom-theme .mat-badge-medium.mat-badge-after .mat-badge-content{right:-22px}[dir=rtl] .ruc-custom-theme .mat-badge-medium.mat-badge-after .mat-badge-content{right:auto;left:-22px}.ruc-custom-theme .mat-badge-medium.mat-badge-overlap.mat-badge-before .mat-badge-content{left:-11px}[dir=rtl] .ruc-custom-theme .mat-badge-medium.mat-badge-overlap.mat-badge-before .mat-badge-content{left:auto;right:-11px}.ruc-custom-theme .mat-badge-medium.mat-badge-overlap.mat-badge-after .mat-badge-content{right:-11px}[dir=rtl] .ruc-custom-theme .mat-badge-medium.mat-badge-overlap.mat-badge-after .mat-badge-content{right:auto;left:-11px}.ruc-custom-theme .mat-badge-large .mat-badge-content{width:28px;height:28px;line-height:28px}.ruc-custom-theme .mat-badge-large.mat-badge-above .mat-badge-content{top:-14px}.ruc-custom-theme .mat-badge-large.mat-badge-below .mat-badge-content{bottom:-14px}.ruc-custom-theme .mat-badge-large.mat-badge-before .mat-badge-content{left:-28px}[dir=rtl] .ruc-custom-theme .mat-badge-large.mat-badge-before .mat-badge-content{left:auto;right:-28px}.ruc-custom-theme .mat-badge-large.mat-badge-after .mat-badge-content{right:-28px}[dir=rtl] .ruc-custom-theme .mat-badge-large.mat-badge-after .mat-badge-content{right:auto;left:-28px}.ruc-custom-theme .mat-badge-large.mat-badge-overlap.mat-badge-before .mat-badge-content{left:-14px}[dir=rtl] .ruc-custom-theme .mat-badge-large.mat-badge-overlap.mat-badge-before .mat-badge-content{left:auto;right:-14px}.ruc-custom-theme .mat-badge-large.mat-badge-overlap.mat-badge-after .mat-badge-content{right:-14px}[dir=rtl] .ruc-custom-theme .mat-badge-large.mat-badge-overlap.mat-badge-after .mat-badge-content{right:auto;left:-14px}.ruc-custom-theme .mat-badge-content{font-weight:600;font-size:12px;font-family:Roboto,sans-serif}.ruc-custom-theme .mat-badge-small .mat-badge-content{font-size:9px}.ruc-custom-theme .mat-badge-large .mat-badge-content{font-size:24px}.ruc-custom-theme .mat-bottom-sheet-container{font-size:14px;font-weight:400;line-height:20px;font-family:Roboto,sans-serif;letter-spacing:normal}.ruc-custom-theme .mat-button-toggle-appearance-standard .mat-button-toggle-label-content{line-height:48px}.ruc-custom-theme .mat-button-toggle{font-family:Roboto,sans-serif}.ruc-custom-theme .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base{width:40px;height:40px;padding:8px}.ruc-custom-theme .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base .mdc-icon-button__focus-ring{max-height:40px;max-width:40px}.ruc-custom-theme .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base.mdc-icon-button--reduced-size .mdc-icon-button__ripple{width:40px;height:40px;margin:0}.ruc-custom-theme .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base.mdc-icon-button--reduced-size .mdc-icon-button__focus-ring{max-height:40px;max-width:40px}.ruc-custom-theme .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base .mdc-icon-button__touch{position:absolute;top:50%;height:40px;left:50%;width:40px;transform:translate(-50%,-50%)}.ruc-custom-theme .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base .mat-mdc-button-touch-target{display:none}.ruc-custom-theme .mat-calendar{font-family:Roboto,sans-serif}.ruc-custom-theme .mat-calendar-body{font-size:13px}.ruc-custom-theme .mat-calendar-body-label,.ruc-custom-theme .mat-calendar-period-button{font-size:20px;font-weight:500}.ruc-custom-theme .mat-calendar-table-header th{font-size:11px;font-weight:400}.ruc-custom-theme .mat-expansion-panel-header{height:48px}.ruc-custom-theme .mat-expansion-panel-header.mat-expanded{height:64px}.ruc-custom-theme .mat-expansion-panel-header{font-family:Roboto,sans-serif;font-size:15px;font-weight:400}.ruc-custom-theme .mat-expansion-panel-content{font-size:14px;font-weight:400;line-height:20px;font-family:Roboto,sans-serif;letter-spacing:normal}.ruc-custom-theme .mat-grid-tile-header,.ruc-custom-theme .mat-grid-tile-footer{font-size:14px}.ruc-custom-theme .mat-grid-tile-header .mat-line,.ruc-custom-theme .mat-grid-tile-footer .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;box-sizing:border-box}.ruc-custom-theme .mat-grid-tile-header .mat-line:nth-child(n+2),.ruc-custom-theme .mat-grid-tile-footer .mat-line:nth-child(n+2){font-size:12px}.ruc-custom-theme .mat-horizontal-stepper-header{height:72px}.ruc-custom-theme .mat-stepper-label-position-bottom .mat-horizontal-stepper-header,.ruc-custom-theme .mat-vertical-stepper-header{padding:24px}.ruc-custom-theme .mat-stepper-vertical-line:before{top:-16px;bottom:-16px}.ruc-custom-theme .mat-stepper-label-position-bottom .mat-horizontal-stepper-header:after,.ruc-custom-theme .mat-stepper-label-position-bottom .mat-horizontal-stepper-header:before{top:36px}.ruc-custom-theme .mat-stepper-label-position-bottom .mat-stepper-horizontal-line{top:36px}.ruc-custom-theme .mat-stepper-vertical,.ruc-custom-theme .mat-stepper-horizontal{font-family:Roboto,sans-serif}.ruc-custom-theme .mat-step-label{font-size:14px;font-weight:400}.ruc-custom-theme .mat-step-sub-label-error{font-weight:400}.ruc-custom-theme .mat-step-label-error{font-size:20px}.ruc-custom-theme .mat-step-label-selected{font-size:20px;font-weight:500}.ruc-custom-theme .mat-toolbar-multiple-rows{min-height:64px}.ruc-custom-theme .mat-toolbar-row,.ruc-custom-theme .mat-toolbar-single-row{height:64px}@media (max-width: 599px){.ruc-custom-theme .mat-toolbar-multiple-rows{min-height:56px}.ruc-custom-theme .mat-toolbar-row,.ruc-custom-theme .mat-toolbar-single-row{height:56px}}.ruc-custom-theme .mat-toolbar,.ruc-custom-theme .mat-toolbar h1,.ruc-custom-theme .mat-toolbar h2,.ruc-custom-theme .mat-toolbar h3,.ruc-custom-theme .mat-toolbar h4,.ruc-custom-theme .mat-toolbar h5,.ruc-custom-theme .mat-toolbar h6{font-size:20px;font-weight:500;line-height:32px;font-family:Roboto,sans-serif;letter-spacing:normal;margin:0}.ruc-custom-theme .mat-tree-node{min-height:48px}.ruc-custom-theme .mat-tree{font-family:Roboto,sans-serif}.ruc-custom-theme .mat-tree-node,.ruc-custom-theme .mat-nested-tree-node{font-weight:400;font-size:14px}:host{display:block;font-family:sans-serif}.screen-recorder-controls{display:flex;gap:8px;align-items:center;padding:8px;border-radius:4px;position:relative;z-index:1000}.screen-recorder-controls.position-top-left{margin-top:10px;margin-left:10px;flex-direction:row}.screen-recorder-controls.position-top-right{margin-top:10px;margin-right:10px;flex-direction:row}.screen-recorder-controls.position-bottom-left{margin-bottom:10px;margin-left:10px;flex-direction:row}.screen-recorder-controls.position-bottom-right{margin-bottom:10px;margin-right:10px;flex-direction:row}.screen-recorder-controls.position-left,.screen-recorder-controls.position-right{float:right}.recorder-button{padding:8px 12px;border:1px solid #ccc;border-radius:4px;background-color:#fff;cursor:pointer;display:inline-flex;align-items:center;gap:4px}.recorder-button:hover{background-color:#e9e9e9}.recorder-button:active{background-color:#d0d0d0}.recorder-button.record-button{color:red}.material-icons{font-family:Material Icons;font-weight:400;font-style:normal;font-size:20px;display:inline-block;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:\"liga\"}.recorder-timer{padding:0 8px;font-feature-settings:\"tnum\";font-variant-numeric:tabular-nums}.playback-area{width:100%;max-width:100%;margin-top:1rem;position:relative}.playback-area video{width:100%;height:auto;max-width:100%}.playback-area .video-timer-overlay{position:absolute;top:10px;right:10px;background:rgba(0,0,0,.7);color:#fff;padding:5px 10px;border-radius:4px;font-size:14px;z-index:10}.recorder-error{color:red;padding:8px;border:1px solid red;background-color:#ffe0e0;border-radius:4px;margin-bottom:8px}.recorder-notsupported{padding:10px;background-color:#fff3cd;border:1px solid #ffeeba;color:#856404;border-radius:4px}\n"] }]
619
619
  }], ctorParameters: function () { return [{ type: ScreenRecorderService }, { type: i2.DomSanitizer }, { type: i0.ChangeDetectorRef }, { type: ScreenRecorderConstants }]; }, propDecorators: { customTheme: [{
620
620
  type: Input
621
621
  }], rucInputData: [{