import { createImageTemplate, DEFAULT_CONFIDENCE, type CategorizedTemplate } from 'packages/domain/value-objects/ImageTemplate'; import type { ImageTemplate } from 'packages/domain/value-objects/ImageTemplate'; /** * Template definitions for iRacing UI elements. * * These templates replace CSS selectors with image-based matching for TOS-compliant * OS-level automation. Templates reference images in resources/templates/iracing/ * * Template images should be captured from the actual iRacing UI at standard resolution. * Recommended: 1920x1080 or 2560x1440 with PNG format for lossless quality. */ /** * Step template configuration containing all templates needed for a workflow step. */ export interface StepTemplates { /** Templates to detect if we're on this step */ indicators: ImageTemplate[]; /** Button templates for navigation and actions */ buttons: Record; /** Field templates for form inputs */ fields?: Record; /** Modal-related templates if applicable */ modal?: { indicator: ImageTemplate; closeButton: ImageTemplate; confirmButton?: ImageTemplate; searchInput?: ImageTemplate; }; } /** * Complete template map type for iRacing automation. */ export interface IRacingTemplateMapType { /** Common templates used across multiple steps */ common: { /** Logged-in state indicators */ loginIndicators: ImageTemplate[]; /** Logged-out state indicators */ logoutIndicators: ImageTemplate[]; /** Generic navigation buttons */ navigation: Record; /** Loading indicators */ loading: ImageTemplate[]; }; /** Step-specific templates */ steps: Record; /** Base path for template images */ templateBasePath: string; } /** * Template paths for iRacing UI elements. * All paths are relative to resources/templates/iracing/ */ const TEMPLATE_PATHS = { common: { login: 'common/login-indicator.png', logout: 'common/logout-indicator.png', userAvatar: 'common/user-avatar.png', memberBadge: 'common/member-badge.png', loginButton: 'common/login-button.png', loadingSpinner: 'common/loading-spinner.png', nextButton: 'common/next-button.png', backButton: 'common/back-button.png', checkoutButton: 'common/checkout-button.png', closeModal: 'common/close-modal-button.png', }, steps: { 1: { loginForm: 'step01-login/login-form.png', emailField: 'step01-login/email-field.png', passwordField: 'step01-login/password-field.png', submitButton: 'step01-login/submit-button.png', }, 2: { hostedRacingTab: 'step02-hosted/hosted-racing-tab.png', // Using 1x template - will be scaled by 2x for Retina displays createRaceButton: 'step02-hosted/create-race-button.png', sessionList: 'step02-hosted/session-list.png', }, 3: { createRaceModal: 'step03-create/create-race-modal.png', confirmButton: 'step03-create/confirm-button.png', }, 4: { stepIndicator: 'step04-info/race-info-indicator.png', sessionNameField: 'step04-info/session-name-field.png', passwordField: 'step04-info/password-field.png', descriptionField: 'step04-info/description-field.png', nextButton: 'step04-info/next-button.png', }, 5: { stepIndicator: 'step05-server/server-details-indicator.png', regionDropdown: 'step05-server/region-dropdown.png', startNowToggle: 'step05-server/start-now-toggle.png', nextButton: 'step05-server/next-button.png', }, 6: { stepIndicator: 'step06-admins/admins-indicator.png', addAdminButton: 'step06-admins/add-admin-button.png', adminModal: 'step06-admins/admin-modal.png', searchField: 'step06-admins/search-field.png', nextButton: 'step06-admins/next-button.png', }, 7: { stepIndicator: 'step07-time/time-limits-indicator.png', practiceField: 'step07-time/practice-field.png', qualifyField: 'step07-time/qualify-field.png', raceField: 'step07-time/race-field.png', nextButton: 'step07-time/next-button.png', }, 8: { stepIndicator: 'step08-cars/cars-indicator.png', addCarButton: 'step08-cars/add-car-button.png', carList: 'step08-cars/car-list.png', nextButton: 'step08-cars/next-button.png', }, 9: { carModal: 'step09-addcar/car-modal.png', searchField: 'step09-addcar/search-field.png', carGrid: 'step09-addcar/car-grid.png', selectButton: 'step09-addcar/select-button.png', closeButton: 'step09-addcar/close-button.png', }, 10: { stepIndicator: 'step10-classes/car-classes-indicator.png', classDropdown: 'step10-classes/class-dropdown.png', nextButton: 'step10-classes/next-button.png', }, 11: { stepIndicator: 'step11-track/track-indicator.png', addTrackButton: 'step11-track/add-track-button.png', trackList: 'step11-track/track-list.png', nextButton: 'step11-track/next-button.png', }, 12: { trackModal: 'step12-addtrack/track-modal.png', searchField: 'step12-addtrack/search-field.png', trackGrid: 'step12-addtrack/track-grid.png', selectButton: 'step12-addtrack/select-button.png', closeButton: 'step12-addtrack/close-button.png', }, 13: { stepIndicator: 'step13-trackopts/track-options-indicator.png', configDropdown: 'step13-trackopts/config-dropdown.png', nextButton: 'step13-trackopts/next-button.png', }, 14: { stepIndicator: 'step14-tod/time-of-day-indicator.png', timeSlider: 'step14-tod/time-slider.png', datePicker: 'step14-tod/date-picker.png', nextButton: 'step14-tod/next-button.png', }, 15: { stepIndicator: 'step15-weather/weather-indicator.png', weatherDropdown: 'step15-weather/weather-dropdown.png', temperatureField: 'step15-weather/temperature-field.png', nextButton: 'step15-weather/next-button.png', }, 16: { stepIndicator: 'step16-race/race-options-indicator.png', maxDriversField: 'step16-race/max-drivers-field.png', rollingStartToggle: 'step16-race/rolling-start-toggle.png', nextButton: 'step16-race/next-button.png', }, 17: { stepIndicator: 'step17-team/team-driving-indicator.png', teamDrivingToggle: 'step17-team/team-driving-toggle.png', nextButton: 'step17-team/next-button.png', }, 18: { stepIndicator: 'step18-conditions/track-conditions-indicator.png', trackStateDropdown: 'step18-conditions/track-state-dropdown.png', marblesToggle: 'step18-conditions/marbles-toggle.png', // NOTE: No checkout button template - automation stops here for safety }, }, } as const; /** * Complete template map for iRacing hosted session automation. * Templates are organized by common elements and workflow steps. */ export const IRacingTemplateMap: IRacingTemplateMapType = { templateBasePath: 'resources/templates/iracing', common: { loginIndicators: [ createImageTemplate( 'login-user-avatar', TEMPLATE_PATHS.common.userAvatar, 'User avatar indicating logged-in state', { confidence: DEFAULT_CONFIDENCE.HIGH } ), createImageTemplate( 'login-member-badge', TEMPLATE_PATHS.common.memberBadge, 'Member badge indicating logged-in state', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), ], logoutIndicators: [ createImageTemplate( 'logout-login-button', TEMPLATE_PATHS.common.loginButton, 'Login button indicating logged-out state', { confidence: DEFAULT_CONFIDENCE.HIGH } ), ], navigation: { next: createImageTemplate( 'nav-next', TEMPLATE_PATHS.common.nextButton, 'Next button for wizard navigation', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), back: createImageTemplate( 'nav-back', TEMPLATE_PATHS.common.backButton, 'Back button for wizard navigation', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), checkout: createImageTemplate( 'nav-checkout', TEMPLATE_PATHS.common.checkoutButton, 'Checkout/submit button', { confidence: DEFAULT_CONFIDENCE.HIGH } ), closeModal: createImageTemplate( 'nav-close-modal', TEMPLATE_PATHS.common.closeModal, 'Close modal button', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), }, loading: [ createImageTemplate( 'loading-spinner', TEMPLATE_PATHS.common.loadingSpinner, 'Loading spinner indicator', { confidence: DEFAULT_CONFIDENCE.LOW } ), ], }, steps: { // Step 1: LOGIN (handled externally, templates for detection only) 1: { indicators: [ createImageTemplate( 'step1-login-form', TEMPLATE_PATHS.steps[1].loginForm, 'Login form indicator', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), ], buttons: { submit: createImageTemplate( 'step1-submit', TEMPLATE_PATHS.steps[1].submitButton, 'Login submit button', { confidence: DEFAULT_CONFIDENCE.HIGH } ), }, fields: { email: createImageTemplate( 'step1-email', TEMPLATE_PATHS.steps[1].emailField, 'Email input field', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), password: createImageTemplate( 'step1-password', TEMPLATE_PATHS.steps[1].passwordField, 'Password input field', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), }, }, // Step 2: HOSTED_RACING // NOTE: Using DEBUG confidence (0.5) temporarily to test template matching // after fixing the Retina scaling issue (DISPLAY_SCALE_FACTOR=1) 2: { indicators: [ createImageTemplate( 'step2-hosted-tab', TEMPLATE_PATHS.steps[2].hostedRacingTab, 'Hosted racing tab indicator', { confidence: DEFAULT_CONFIDENCE.DEBUG } ), ], buttons: { createRace: createImageTemplate( 'step2-create-race', TEMPLATE_PATHS.steps[2].createRaceButton, 'Create a Race button', { confidence: DEFAULT_CONFIDENCE.DEBUG } ), }, }, // Step 3: CREATE_RACE 3: { indicators: [ createImageTemplate( 'step3-modal', TEMPLATE_PATHS.steps[3].createRaceModal, 'Create race modal indicator', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), ], buttons: { confirm: createImageTemplate( 'step3-confirm', TEMPLATE_PATHS.steps[3].confirmButton, 'Confirm create race button', { confidence: DEFAULT_CONFIDENCE.HIGH } ), }, }, // Step 4: RACE_INFORMATION 4: { indicators: [ createImageTemplate( 'step4-indicator', TEMPLATE_PATHS.steps[4].stepIndicator, 'Race information step indicator', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), ], buttons: { next: createImageTemplate( 'step4-next', TEMPLATE_PATHS.steps[4].nextButton, 'Next to Server Details button', { confidence: DEFAULT_CONFIDENCE.HIGH } ), }, fields: { sessionName: createImageTemplate( 'step4-session-name', TEMPLATE_PATHS.steps[4].sessionNameField, 'Session name input field', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), password: createImageTemplate( 'step4-password', TEMPLATE_PATHS.steps[4].passwordField, 'Session password input field', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), description: createImageTemplate( 'step4-description', TEMPLATE_PATHS.steps[4].descriptionField, 'Session description textarea', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), }, }, // Step 5: SERVER_DETAILS 5: { indicators: [ createImageTemplate( 'step5-indicator', TEMPLATE_PATHS.steps[5].stepIndicator, 'Server details step indicator', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), ], buttons: { next: createImageTemplate( 'step5-next', TEMPLATE_PATHS.steps[5].nextButton, 'Next to Admins button', { confidence: DEFAULT_CONFIDENCE.HIGH } ), }, fields: { region: createImageTemplate( 'step5-region', TEMPLATE_PATHS.steps[5].regionDropdown, 'Server region dropdown', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), startNow: createImageTemplate( 'step5-start-now', TEMPLATE_PATHS.steps[5].startNowToggle, 'Start now toggle', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), }, }, // Step 6: SET_ADMINS (modal step) 6: { indicators: [ createImageTemplate( 'step6-indicator', TEMPLATE_PATHS.steps[6].stepIndicator, 'Admins step indicator', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), ], buttons: { addAdmin: createImageTemplate( 'step6-add-admin', TEMPLATE_PATHS.steps[6].addAdminButton, 'Add admin button', { confidence: DEFAULT_CONFIDENCE.HIGH } ), next: createImageTemplate( 'step6-next', TEMPLATE_PATHS.steps[6].nextButton, 'Next to Time Limits button', { confidence: DEFAULT_CONFIDENCE.HIGH } ), }, modal: { indicator: createImageTemplate( 'step6-modal', TEMPLATE_PATHS.steps[6].adminModal, 'Add admin modal indicator', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), closeButton: createImageTemplate( 'step6-modal-close', TEMPLATE_PATHS.common.closeModal, 'Close admin modal button', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), searchInput: createImageTemplate( 'step6-search', TEMPLATE_PATHS.steps[6].searchField, 'Admin search field', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), }, }, // Step 7: TIME_LIMITS 7: { indicators: [ createImageTemplate( 'step7-indicator', TEMPLATE_PATHS.steps[7].stepIndicator, 'Time limits step indicator', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), ], buttons: { next: createImageTemplate( 'step7-next', TEMPLATE_PATHS.steps[7].nextButton, 'Next to Cars button', { confidence: DEFAULT_CONFIDENCE.HIGH } ), }, fields: { practice: createImageTemplate( 'step7-practice', TEMPLATE_PATHS.steps[7].practiceField, 'Practice length field', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), qualify: createImageTemplate( 'step7-qualify', TEMPLATE_PATHS.steps[7].qualifyField, 'Qualify length field', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), race: createImageTemplate( 'step7-race', TEMPLATE_PATHS.steps[7].raceField, 'Race length field', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), }, }, // Step 8: SET_CARS 8: { indicators: [ createImageTemplate( 'step8-indicator', TEMPLATE_PATHS.steps[8].stepIndicator, 'Cars step indicator', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), ], buttons: { addCar: createImageTemplate( 'step8-add-car', TEMPLATE_PATHS.steps[8].addCarButton, 'Add car button', { confidence: DEFAULT_CONFIDENCE.HIGH } ), next: createImageTemplate( 'step8-next', TEMPLATE_PATHS.steps[8].nextButton, 'Next to Track button', { confidence: DEFAULT_CONFIDENCE.HIGH } ), }, }, // Step 9: ADD_CAR (modal step) 9: { indicators: [ createImageTemplate( 'step9-modal', TEMPLATE_PATHS.steps[9].carModal, 'Add car modal indicator', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), ], buttons: { select: createImageTemplate( 'step9-select', TEMPLATE_PATHS.steps[9].selectButton, 'Select car button', { confidence: DEFAULT_CONFIDENCE.HIGH } ), }, modal: { indicator: createImageTemplate( 'step9-modal-indicator', TEMPLATE_PATHS.steps[9].carModal, 'Car selection modal', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), closeButton: createImageTemplate( 'step9-close', TEMPLATE_PATHS.steps[9].closeButton, 'Close car modal button', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), searchInput: createImageTemplate( 'step9-search', TEMPLATE_PATHS.steps[9].searchField, 'Car search field', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), }, }, // Step 10: SET_CAR_CLASSES 10: { indicators: [ createImageTemplate( 'step10-indicator', TEMPLATE_PATHS.steps[10].stepIndicator, 'Car classes step indicator', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), ], buttons: { next: createImageTemplate( 'step10-next', TEMPLATE_PATHS.steps[10].nextButton, 'Next to Track button', { confidence: DEFAULT_CONFIDENCE.HIGH } ), }, fields: { class: createImageTemplate( 'step10-class', TEMPLATE_PATHS.steps[10].classDropdown, 'Car class dropdown', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), }, }, // Step 11: SET_TRACK 11: { indicators: [ createImageTemplate( 'step11-indicator', TEMPLATE_PATHS.steps[11].stepIndicator, 'Track step indicator', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), ], buttons: { addTrack: createImageTemplate( 'step11-add-track', TEMPLATE_PATHS.steps[11].addTrackButton, 'Add track button', { confidence: DEFAULT_CONFIDENCE.HIGH } ), next: createImageTemplate( 'step11-next', TEMPLATE_PATHS.steps[11].nextButton, 'Next to Track Options button', { confidence: DEFAULT_CONFIDENCE.HIGH } ), }, }, // Step 12: ADD_TRACK (modal step) 12: { indicators: [ createImageTemplate( 'step12-modal', TEMPLATE_PATHS.steps[12].trackModal, 'Add track modal indicator', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), ], buttons: { select: createImageTemplate( 'step12-select', TEMPLATE_PATHS.steps[12].selectButton, 'Select track button', { confidence: DEFAULT_CONFIDENCE.HIGH } ), }, modal: { indicator: createImageTemplate( 'step12-modal-indicator', TEMPLATE_PATHS.steps[12].trackModal, 'Track selection modal', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), closeButton: createImageTemplate( 'step12-close', TEMPLATE_PATHS.steps[12].closeButton, 'Close track modal button', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), searchInput: createImageTemplate( 'step12-search', TEMPLATE_PATHS.steps[12].searchField, 'Track search field', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), }, }, // Step 13: TRACK_OPTIONS 13: { indicators: [ createImageTemplate( 'step13-indicator', TEMPLATE_PATHS.steps[13].stepIndicator, 'Track options step indicator', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), ], buttons: { next: createImageTemplate( 'step13-next', TEMPLATE_PATHS.steps[13].nextButton, 'Next to Time of Day button', { confidence: DEFAULT_CONFIDENCE.HIGH } ), }, fields: { config: createImageTemplate( 'step13-config', TEMPLATE_PATHS.steps[13].configDropdown, 'Track configuration dropdown', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), }, }, // Step 14: TIME_OF_DAY 14: { indicators: [ createImageTemplate( 'step14-indicator', TEMPLATE_PATHS.steps[14].stepIndicator, 'Time of day step indicator', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), ], buttons: { next: createImageTemplate( 'step14-next', TEMPLATE_PATHS.steps[14].nextButton, 'Next to Weather button', { confidence: DEFAULT_CONFIDENCE.HIGH } ), }, fields: { time: createImageTemplate( 'step14-time', TEMPLATE_PATHS.steps[14].timeSlider, 'Time of day slider', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), date: createImageTemplate( 'step14-date', TEMPLATE_PATHS.steps[14].datePicker, 'Date picker', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), }, }, // Step 15: WEATHER 15: { indicators: [ createImageTemplate( 'step15-indicator', TEMPLATE_PATHS.steps[15].stepIndicator, 'Weather step indicator', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), ], buttons: { next: createImageTemplate( 'step15-next', TEMPLATE_PATHS.steps[15].nextButton, 'Next to Race Options button', { confidence: DEFAULT_CONFIDENCE.HIGH } ), }, fields: { weather: createImageTemplate( 'step15-weather', TEMPLATE_PATHS.steps[15].weatherDropdown, 'Weather type dropdown', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), temperature: createImageTemplate( 'step15-temperature', TEMPLATE_PATHS.steps[15].temperatureField, 'Temperature field', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), }, }, // Step 16: RACE_OPTIONS 16: { indicators: [ createImageTemplate( 'step16-indicator', TEMPLATE_PATHS.steps[16].stepIndicator, 'Race options step indicator', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), ], buttons: { next: createImageTemplate( 'step16-next', TEMPLATE_PATHS.steps[16].nextButton, 'Next to Track Conditions button', { confidence: DEFAULT_CONFIDENCE.HIGH } ), }, fields: { maxDrivers: createImageTemplate( 'step16-max-drivers', TEMPLATE_PATHS.steps[16].maxDriversField, 'Maximum drivers field', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), rollingStart: createImageTemplate( 'step16-rolling-start', TEMPLATE_PATHS.steps[16].rollingStartToggle, 'Rolling start toggle', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), }, }, // Step 17: TEAM_DRIVING 17: { indicators: [ createImageTemplate( 'step17-indicator', TEMPLATE_PATHS.steps[17].stepIndicator, 'Team driving step indicator', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), ], buttons: { next: createImageTemplate( 'step17-next', TEMPLATE_PATHS.steps[17].nextButton, 'Next to Track Conditions button', { confidence: DEFAULT_CONFIDENCE.HIGH } ), }, fields: { teamDriving: createImageTemplate( 'step17-team-driving', TEMPLATE_PATHS.steps[17].teamDrivingToggle, 'Team driving toggle', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), }, }, // Step 18: TRACK_CONDITIONS (final step - no checkout for safety) 18: { indicators: [ createImageTemplate( 'step18-indicator', TEMPLATE_PATHS.steps[18].stepIndicator, 'Track conditions step indicator', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), ], buttons: { // NOTE: No checkout button - automation intentionally stops here // User must manually review and submit }, fields: { trackState: createImageTemplate( 'step18-track-state', TEMPLATE_PATHS.steps[18].trackStateDropdown, 'Track state dropdown', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), marbles: createImageTemplate( 'step18-marbles', TEMPLATE_PATHS.steps[18].marblesToggle, 'Marbles toggle', { confidence: DEFAULT_CONFIDENCE.STANDARD } ), }, }, }, }; /** * Get templates for a specific step. */ export function getStepTemplates(stepId: number): StepTemplates | undefined { return IRacingTemplateMap.steps[stepId]; } /** * Check if a step is a modal step (requires opening a secondary dialog). */ export function isModalStep(stepId: number): boolean { const templates = IRacingTemplateMap.steps[stepId]; return templates?.modal !== undefined; } /** * Get the step name for logging/debugging. */ export function getStepName(stepId: number): string { const stepNames: Record = { 1: 'LOGIN', 2: 'HOSTED_RACING', 3: 'CREATE_RACE', 4: 'RACE_INFORMATION', 5: 'SERVER_DETAILS', 6: 'SET_ADMINS', 7: 'TIME_LIMITS', 8: 'SET_CARS', 9: 'ADD_CAR', 10: 'SET_CAR_CLASSES', 11: 'SET_TRACK', 12: 'ADD_TRACK', 13: 'TRACK_OPTIONS', 14: 'TIME_OF_DAY', 15: 'WEATHER', 16: 'RACE_OPTIONS', 17: 'TEAM_DRIVING', 18: 'TRACK_CONDITIONS', }; return stepNames[stepId] || `UNKNOWN_STEP_${stepId}`; } /** * Get all login indicator templates. */ export function getLoginIndicators(): ImageTemplate[] { return IRacingTemplateMap.common.loginIndicators; } /** * Get all logout indicator templates. */ export function getLogoutIndicators(): ImageTemplate[] { return IRacingTemplateMap.common.logoutIndicators; }