Files
HC_APTBS/Resources/Strings.en.xaml
LucianoDev 197e9d1775 feat: redesign dashboard with Fluent KPI tiles, connection strip, and devices column
- Replace LCD-style readings with a 3×2 KPI tile grid (Fluent card surfaces, 52pt values)
- Add persistent top connection strip with horizontal chips + pump name badge
- Add elapsed test timer (DispatcherTimer, mm:ss) to Test Summary card
- Restyle Test Summary and Active Alarms with Fluent brushes/iconography
- Add Devices column (CAN / K-Line / Bench tiles) between KPI grid and test/alarms
  - Enumerates attached PCAN USB channels via PCAN_ATTACHED_CHANNELS API
  - Enumerates FTDI K-Line adapters via existing FtdiInterface helpers
  - Click to connect/disconnect; confirmation dialog when session active or test running
  - Hover tint: blue = will connect, red = will disconnect; Bench row is read-only stub
- Extend ICanService with SelectedChannel + EnumerateAttachedChannels()
- Expose IKwpService.ConnectedPort for active session device tracking
- Add DeviceRow button style with MultiDataTrigger hover colour logic
- Add 30+ new localization keys (ES + EN) for KPI labels, devices, confirmations

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 22:25:00 +02:00

506 lines
36 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=System.Runtime">
<!-- ══════════════════════════════════════════════════════════════════
English (ENG)
══════════════════════════════════════════════════════════════════ -->
<!-- ── App ──────────────────────────────────────────────────────────── -->
<sys:String x:Key="App.Title">HC_APTBS — Herlic Test Bench</sys:String>
<!-- ── Navigation rail ──────────────────────────────────────────────── -->
<sys:String x:Key="Nav.Dashboard">Dashboard</sys:String>
<sys:String x:Key="Nav.Bench">Bench</sys:String>
<sys:String x:Key="Nav.Pump">Pump</sys:String>
<sys:String x:Key="Nav.Tests">Tests</sys:String>
<sys:String x:Key="Nav.Results">Results</sys:String>
<sys:String x:Key="Nav.Settings">Settings</sys:String>
<!-- ── Dashboard page ───────────────────────────────────────────────── -->
<sys:String x:Key="Dashboard.Readings">Bench readings</sys:String>
<sys:String x:Key="Dashboard.Connections">Connections</sys:String>
<sys:String x:Key="Dashboard.Conn.Can">CAN bus</sys:String>
<sys:String x:Key="Dashboard.Conn.Bench">Bench controller</sys:String>
<sys:String x:Key="Dashboard.Conn.Pump">Pump ECU</sys:String>
<sys:String x:Key="Dashboard.Conn.KLine">K-Line session</sys:String>
<sys:String x:Key="Dashboard.StateOnline">ONLINE</sys:String>
<sys:String x:Key="Dashboard.StateOffline">OFFLINE</sys:String>
<sys:String x:Key="Dashboard.StateOpen">OPEN</sys:String>
<sys:String x:Key="Dashboard.StateClosed">CLOSED</sys:String>
<sys:String x:Key="Dashboard.StateFailed">FAILED</sys:String>
<sys:String x:Key="Dashboard.Alarms">Active alarms</sys:String>
<sys:String x:Key="Dashboard.AlarmsNone">System OK — no active alarms</sys:String>
<sys:String x:Key="Dashboard.TestSummary">Test summary</sys:String>
<sys:String x:Key="Dashboard.TestActive">Active:</sys:String>
<sys:String x:Key="Dashboard.TestPhase">Phase:</sys:String>
<sys:String x:Key="Dashboard.NoTestRunning">No test is currently running.</sys:String>
<sys:String x:Key="Dashboard.LastTestPass">Last test: PASS</sys:String>
<sys:String x:Key="Dashboard.LastTestFail">Last test: FAIL</sys:String>
<sys:String x:Key="Dashboard.Action.StartTest">Start Test</sys:String>
<sys:String x:Key="Dashboard.Action.StartTest.Tip">Requires a selected pump and an open CAN connection.</sys:String>
<sys:String x:Key="Dashboard.Action.Stop">Stop</sys:String>
<sys:String x:Key="Dashboard.Action.EmergencyStop">EMERGENCY STOP</sys:String>
<!-- ── Dashboard KPI tile labels ──────────────────────────────────────── -->
<sys:String x:Key="Dashboard.Kpi.Rpm">Bench RPM</sys:String>
<sys:String x:Key="Dashboard.Kpi.Qdelivery">Q delivery</sys:String>
<sys:String x:Key="Dashboard.Kpi.P1">Pressure P1</sys:String>
<sys:String x:Key="Dashboard.Kpi.P2">Pressure P2</sys:String>
<sys:String x:Key="Dashboard.Kpi.Tin">Oil in T</sys:String>
<sys:String x:Key="Dashboard.Kpi.Tout">Oil out T</sys:String>
<sys:String x:Key="Dashboard.Kpi.Unit.Rpm">rpm</sys:String>
<sys:String x:Key="Dashboard.Kpi.Unit.CcS">cc/s</sys:String>
<sys:String x:Key="Dashboard.Kpi.Unit.Bar">bar</sys:String>
<sys:String x:Key="Dashboard.Kpi.Unit.Celsius">°C</sys:String>
<!-- Dashboard test summary extras -->
<sys:String x:Key="Dashboard.TestSummary.Elapsed">Elapsed:</sys:String>
<!-- Dashboard connection chip extras -->
<sys:String x:Key="Dashboard.Conn.Pump.Label">Pump:</sys:String>
<sys:String x:Key="Dashboard.Conn.NoPump">No pump</sys:String>
<!-- ── Dashboard Devices column ─────────────────────────────────────── -->
<sys:String x:Key="Dashboard.Devices">Devices</sys:String>
<sys:String x:Key="Dashboard.Devices.Can">CAN</sys:String>
<sys:String x:Key="Dashboard.Devices.Kline">K-Line</sys:String>
<sys:String x:Key="Dashboard.Devices.Bench">Bench</sys:String>
<sys:String x:Key="Dashboard.Devices.Refresh">Refresh</sys:String>
<sys:String x:Key="Dashboard.Devices.State.Idle">Available</sys:String>
<sys:String x:Key="Dashboard.Devices.State.Connected">Connected</sys:String>
<sys:String x:Key="Dashboard.Devices.State.Active">Session active</sys:String>
<sys:String x:Key="Dashboard.Devices.State.Failed">Error</sys:String>
<sys:String x:Key="Dashboard.Devices.None">No devices found</sys:String>
<sys:String x:Key="Dashboard.Devices.BenchRow">Bench controller</sys:String>
<!-- Confirmation dialogs -->
<sys:String x:Key="Devices.Confirm.Title">Confirm device change</sys:String>
<sys:String x:Key="Devices.Confirm.Body.Active">The {0} session is active. Disconnect?</sys:String>
<sys:String x:Key="Devices.Confirm.Body.TestRunning">A test is running. Changing device state may abort it. Continue?</sys:String>
<!-- ── Status bar / connection indicators ───────────────────────────── -->
<sys:String x:Key="Status.Label">Status:</sys:String>
<sys:String x:Key="Status.Can">CAN</sys:String>
<sys:String x:Key="Status.Bench">Bench</sys:String>
<sys:String x:Key="Status.Pump">Pump</sys:String>
<sys:String x:Key="Status.KLine">K-Line</sys:String>
<sys:String x:Key="Status.Connected">Connected</sys:String>
<sys:String x:Key="Status.ConnectionFailed">Connection failed</sys:String>
<sys:String x:Key="Status.Disconnected">Disconnected</sys:String>
<!-- ── Bench section ────────────────────────────────────────────────── -->
<sys:String x:Key="Bench.ConnectCan">Connect CAN</sys:String>
<sys:String x:Key="Bench.DisconnectCan">Disconnect CAN</sys:String>
<sys:String x:Key="Bench.Rpm">rpm</sys:String>
<sys:String x:Key="Bench.Target">Target:</sys:String>
<sys:String x:Key="Bench.Voltage">V:</sys:String>
<sys:String x:Key="Bench.TempIn">T. In:</sys:String>
<sys:String x:Key="Bench.TempOut">T. Out:</sys:String>
<sys:String x:Key="Bench.Temp4">T. 4:</sys:String>
<sys:String x:Key="Bench.TempTank">T. Tank:</sys:String>
<sys:String x:Key="Bench.P1">P1:</sys:String>
<sys:String x:Key="Bench.P2">P2:</sys:String>
<sys:String x:Key="Bench.QDelivery">Q-Del.:</sys:String>
<sys:String x:Key="Bench.QOver">Q-Over:</sys:String>
<sys:String x:Key="Bench.CcStroke">cc/stroke</sys:String>
<sys:String x:Key="Bench.PumpRpm">P-RPM:</sys:String>
<sys:String x:Key="Bench.PumpTemp">P-Temp:</sys:String>
<sys:String x:Key="Bench.PumpMe">P-ME:</sys:String>
<sys:String x:Key="Bench.PumpFbkw">P-FBkW:</sys:String>
<sys:String x:Key="Bench.PsgEncoder">PSG Encoder:</sys:String>
<!-- ── Bench controls ───────────────────────────────────────────────── -->
<sys:String x:Key="Bench.Direction">Direction</sys:String>
<sys:String x:Key="Bench.Left">LEFT</sys:String>
<sys:String x:Key="Bench.Right">RIGHT</sys:String>
<sys:String x:Key="Bench.Motor">Bench Motor</sys:String>
<sys:String x:Key="Bench.Start">START</sys:String>
<sys:String x:Key="Bench.Stop">STOP</sys:String>
<sys:String x:Key="Bench.SetRpm">Set RPM:</sys:String>
<sys:String x:Key="Bench.Go">GO</sys:String>
<sys:String x:Key="Bench.OilPump">Oil Pump</sys:String>
<sys:String x:Key="Bench.OilOff">OIL OFF</sys:String>
<sys:String x:Key="Bench.OilOn">OIL ON</sys:String>
<sys:String x:Key="Bench.Counter">Counter</sys:String>
<sys:String x:Key="Bench.Turns">Turns:</sys:String>
<sys:String x:Key="Bench.Send">Send</sys:String>
<sys:String x:Key="Bench.Relays">Relays</sys:String>
<sys:String x:Key="Bench.Electronic">Electronic</sys:String>
<sys:String x:Key="Bench.DepositCooler">Deposit Cooler</sys:String>
<sys:String x:Key="Bench.DepositHeater">Deposit Heater</sys:String>
<sys:String x:Key="Bench.TinCooler">T-in Cooler</sys:String>
<sys:String x:Key="Bench.Flasher">Flasher</sys:String>
<sys:String x:Key="Bench.Pulse4Signal">4-Pulse Signal</sys:String>
<sys:String x:Key="Bench.RelayOn">ON</sys:String>
<sys:String x:Key="Bench.RelayOff">OFF</sys:String>
<sys:String x:Key="Bench.TempControl">Temperature</sys:String>
<sys:String x:Key="Bench.Setpoint">Setpoint</sys:String>
<sys:String x:Key="Bench.Tolerance">Tolerance</sys:String>
<sys:String x:Key="Bench.ApplySetpoint">Apply setpoint</sys:String>
<!-- ── Pump page sub-nav / banners ──────────────────────────────────── -->
<sys:String x:Key="PumpSub.Identification">Identification</sys:String>
<sys:String x:Key="PumpSub.Dtcs">Fault Codes</sys:String>
<sys:String x:Key="PumpSub.LiveData">Live Data</sys:String>
<sys:String x:Key="PumpSub.Adaptation">Adaptation</sys:String>
<sys:String x:Key="PumpSub.Unlock">Immobilizer Unlock</sys:String>
<sys:String x:Key="Pump.KLineClosed">K-Line session is not open. Identify a pump to begin diagnostics.</sys:String>
<sys:String x:Key="Pump.NoPumpSelected">Select a pump on the Identification tab to enable diagnostics.</sys:String>
<sys:String x:Key="Pump.NoUnlockActive">No immobilizer unlock is currently in progress for this pump.</sys:String>
<sys:String x:Key="PumpLive.Engineering">Engineering values (raw)</sys:String>
<!-- ── DTC list ─────────────────────────────────────────────────────── -->
<sys:String x:Key="Dtc.Read">Read DTCs</sys:String>
<sys:String x:Key="Dtc.Clear">Clear DTCs</sys:String>
<sys:String x:Key="Dtc.NoFaults">No fault codes reported by the ECU.</sys:String>
<sys:String x:Key="Dtc.LastRead">Last read:</sys:String>
<sys:String x:Key="Dtc.Cleared">Fault codes cleared.</sys:String>
<!-- ── Auth gate ────────────────────────────────────────────────────── -->
<sys:String x:Key="AuthGate.LockedTitle">Authentication required</sys:String>
<sys:String x:Key="AuthGate.LockedMessage">This section can modify pump parameters. Sign in to unlock.</sys:String>
<sys:String x:Key="AuthGate.Authenticate">Authenticate…</sys:String>
<sys:String x:Key="AuthGate.UnlockedAs">Unlocked as</sys:String>
<sys:String x:Key="AuthGate.Lock">Lock</sys:String>
<!-- ── Pump live data ───────────────────────────────────────────────── -->
<sys:String x:Key="Pump.THyb">T-hyb</sys:String>
<sys:String x:Key="Pump.Rpm">RPM</sys:String>
<sys:String x:Key="Pump.TEin">T-ein</sys:String>
<sys:String x:Key="Pump.UnitRpm">1/min</sys:String>
<!-- ── Pump identification ──────────────────────────────────────────── -->
<sys:String x:Key="PumpId.Label">Pump:</sys:String>
<sys:String x:Key="PumpId.Dfi">DFI:</sys:String>
<sys:String x:Key="PumpId.PumpId">Pump ID:</sys:String>
<sys:String x:Key="PumpId.SerialNo">Serial No:</sys:String>
<sys:String x:Key="PumpId.ModelRef">Model Ref:</sys:String>
<sys:String x:Key="PumpId.DataRecord">Data Record:</sys:String>
<sys:String x:Key="PumpId.PumpCtrl">Pump Ctrl:</sys:String>
<sys:String x:Key="PumpId.ModelIndex">Model Index:</sys:String>
<sys:String x:Key="PumpId.SwVer1">SW Ver 1:</sys:String>
<sys:String x:Key="PumpId.SwVer2">SW Ver 2:</sys:String>
<sys:String x:Key="PumpId.Errors">Errors:</sys:String>
<sys:String x:Key="PumpId.Error">Error:</sys:String>
<sys:String x:Key="PumpId.ReadKLine">Read K-Line</sys:String>
<sys:String x:Key="PumpId.Disconnect">Disconnect</sys:String>
<sys:String x:Key="PumpId.NoKLineDevice">No K-Line device found</sys:String>
<!-- ── DFI management ───────────────────────────────────────────────── -->
<sys:String x:Key="Dfi.Read">READ</sys:String>
<sys:String x:Key="Dfi.Write">WRITE</sys:String>
<sys:String x:Key="Dfi.Label">DFI:</sys:String>
<sys:String x:Key="Dfi.Auto">AUTO</sys:String>
<!-- ── Pump control sliders ─────────────────────────────────────────── -->
<sys:String x:Key="PumpCtrl.Fbkw">FBKW - Advance Control</sys:String>
<sys:String x:Key="PumpCtrl.Me">ME - Quantity Control</sys:String>
<sys:String x:Key="PumpCtrl.PreInj">ME - Pre-inj Quantity</sys:String>
<sys:String x:Key="PumpCtrl.MinStepMax">Min / Step / Max</sys:String>
<sys:String x:Key="PumpCtrl.Min">Min</sys:String>
<sys:String x:Key="PumpCtrl.Step">Step</sys:String>
<sys:String x:Key="PumpCtrl.Max">Max</sys:String>
<!-- ── Bench parameter config ───────────────────────────────────────── -->
<sys:String x:Key="BenchParam.CanBusId">CAN-Bus ID (0x)</sys:String>
<sys:String x:Key="BenchParam.ByteL">Byte L</sys:String>
<sys:String x:Key="BenchParam.ByteH">Byte H</sys:String>
<sys:String x:Key="BenchParam.FilterAlpha">Filter α</sys:String>
<sys:String x:Key="BenchParam.EnableFormula">Enable formula</sys:String>
<!-- ── Angle display ────────────────────────────────────────────────── -->
<sys:String x:Key="Angle.Header">ADVANCE MONITORING</sys:String>
<sys:String x:Key="Angle.Psg">PSG:</sys:String>
<sys:String x:Key="Angle.Inj">INJ:</sys:String>
<sys:String x:Key="Angle.AbsDeg">ABS °:</sys:String>
<sys:String x:Key="Angle.LockDeg">LOCK °:</sys:String>
<sys:String x:Key="Angle.SetPsgZero">Set PSG zero reference</sys:String>
<sys:String x:Key="Angle.SetInjZero">Set INJ zero reference</sys:String>
<!-- ── Test panel ───────────────────────────────────────────────────── -->
<sys:String x:Key="Test.StartTest">▶ START TEST</sys:String>
<sys:String x:Key="Test.Stop">■ STOP</sys:String>
<sys:String x:Key="Test.Report">📄 Report</sys:String>
<sys:String x:Key="Test.ShowValues">Show values</sys:String>
<sys:String x:Key="Test.CheckAll">Check All</sys:String>
<sys:String x:Key="Test.SecondsRemaining">s remaining</sys:String>
<sys:String x:Key="Test.Condition">Cond:</sys:String>
<sys:String x:Key="Test.Measurement">Meas:</sys:String>
<sys:String x:Key="Test.MeasPerSec">M/s:</sys:String>
<sys:String x:Key="Test.Required">Required:</sys:String>
<sys:String x:Key="Test.TestLabel">Test:</sys:String>
<sys:String x:Key="Test.Critical">Critical</sys:String>
<sys:String x:Key="Test.Started">Test started...</sys:String>
<sys:String x:Key="Test.Stopped">Test stopped.</sys:String>
<!-- ── Tests-page wizard ──────────────────────────────────────────────── -->
<sys:String x:Key="Test.Wizard.Plan">1. Plan</sys:String>
<sys:String x:Key="Test.Wizard.Preconditions">2. Preconditions</sys:String>
<sys:String x:Key="Test.Wizard.Running">3. Running</sys:String>
<sys:String x:Key="Test.Wizard.Done">4. Done</sys:String>
<sys:String x:Key="Test.Wizard.Next">Next ▶</sys:String>
<sys:String x:Key="Test.Wizard.Back">◀ Back</sys:String>
<!-- ── Preconditions checklist ────────────────────────────────────────── -->
<sys:String x:Key="Test.Precheck.Title">Preconditions</sys:String>
<sys:String x:Key="Test.Precheck.PumpSelected">Pump selected</sys:String>
<sys:String x:Key="Test.Precheck.CanLive">CAN bus live</sys:String>
<sys:String x:Key="Test.Precheck.KLineOpen">K-Line session open</sys:String>
<sys:String x:Key="Test.Precheck.RpmZero">Bench RPM at zero</sys:String>
<sys:String x:Key="Test.Precheck.OilPumpOn">Oil pump running</sys:String>
<sys:String x:Key="Test.Precheck.NoCriticalAlarms">No critical alarms</sys:String>
<sys:String x:Key="Test.Precheck.UserAuth">User authenticated</sys:String>
<sys:String x:Key="Test.Precheck.FixButton">Fix</sys:String>
<sys:String x:Key="Test.Precheck.Ready">All preconditions met. Ready to start.</sys:String>
<sys:String x:Key="Test.Precheck.NotReady">Resolve the items above before starting.</sys:String>
<sys:String x:Key="Test.Precheck.AuthBanner">This test requires operator authentication.</sys:String>
<sys:String x:Key="Test.Precheck.AuthButton">Authenticate…</sys:String>
<sys:String x:Key="Test.Precheck.Remediation.SelectPump">Go to Pump page to select a pump.</sys:String>
<sys:String x:Key="Test.Precheck.Remediation.CheckCan">Open the Dashboard to check CAN connection.</sys:String>
<sys:String x:Key="Test.Precheck.Remediation.OpenKLine">Open a K-Line session on the Pump page.</sys:String>
<sys:String x:Key="Test.Precheck.Remediation.StopBench">Stop the bench from the Bench page.</sys:String>
<sys:String x:Key="Test.Precheck.Remediation.StartOilPump">Start the oil pump from the Bench page.</sys:String>
<sys:String x:Key="Test.Precheck.Remediation.ClearAlarms">Clear critical alarms on the Dashboard.</sys:String>
<sys:String x:Key="Test.Precheck.Remediation.Authenticate">Authenticate the operator above.</sys:String>
<!-- ── Running step controls ──────────────────────────────────────────── -->
<sys:String x:Key="Test.Running.Abort">■ Abort</sys:String>
<sys:String x:Key="Test.Running.Pause">Pause</sys:String>
<sys:String x:Key="Test.Running.Resume">Resume</sys:String>
<sys:String x:Key="Test.Running.Retry">Retry phase</sys:String>
<sys:String x:Key="Test.Running.Skip">Skip phase</sys:String>
<sys:String x:Key="Test.Running.ComingSoon">Coming soon</sys:String>
<!-- ── Done step ──────────────────────────────────────────────────────── -->
<sys:String x:Key="Test.Done.Passed">PASSED</sys:String>
<sys:String x:Key="Test.Done.Failed">FAILED</sys:String>
<sys:String x:Key="Test.Done.ViewFullResults">View full results</sys:String>
<sys:String x:Key="Test.Done.RunAgain">Run again</sys:String>
<!-- ── Abort confirmation ─────────────────────────────────────────────── -->
<sys:String x:Key="Test.Abort.Title">Abort test?</sys:String>
<sys:String x:Key="Test.Abort.Message">Stopping the test now will end the current phase and return partial results. Continue?</sys:String>
<sys:String x:Key="Test.Abort.Confirm">Abort</sys:String>
<sys:String x:Key="Test.Abort.Cancel">Keep running</sys:String>
<!-- ── Test types ───────────────────────────────────────────────────── -->
<sys:String x:Key="TestType.Warmup">Warm-up</sys:String>
<sys:String x:Key="TestType.Adjustment">Adjustment</sys:String>
<sys:String x:Key="TestType.Flow">Flow</sys:String>
<sys:String x:Key="TestType.ServoValve">Servo valve</sys:String>
<sys:String x:Key="TestType.Upstroke">Upstroke</sys:String>
<sys:String x:Key="TestType.PreInjection">Pre-injection</sys:String>
<!-- ── Result display ───────────────────────────────────────────────── -->
<sys:String x:Key="Result.Phase">Phase</sys:String>
<sys:String x:Key="Result.Parameter">Parameter</sys:String>
<sys:String x:Key="Result.Target">Target</sys:String>
<sys:String x:Key="Result.Tolerance">Tol ±</sys:String>
<sys:String x:Key="Result.Average">Average</sys:String>
<sys:String x:Key="Result.ResultHeader">Result</sys:String>
<sys:String x:Key="Result.AllTests">All Tests</sys:String>
<!-- ── Results page (§5) ────────────────────────────────────────────── -->
<sys:String x:Key="Results.PageTitle">Results</sys:String>
<sys:String x:Key="Results.HistoryHeader">Test history (session)</sys:String>
<sys:String x:Key="Results.DetailHeader">Run detail</sys:String>
<sys:String x:Key="Results.ObservationsLabel">Observations / Notes</sys:String>
<sys:String x:Key="Results.ExportButton">Export PDF…</sys:String>
<sys:String x:Key="Results.EmptyState">No completed tests yet. Finish a test on the Tests page to see it here.</sys:String>
<sys:String x:Key="Results.NoSelection">Select a run on the left to view its details.</sys:String>
<sys:String x:Key="Results.InterruptedLabel">INTERRUPTED</sys:String>
<sys:String x:Key="Results.DeleteTooltip">Remove this entry</sys:String>
<sys:String x:Key="Results.ClearSessionButton">Clear session</sys:String>
<sys:String x:Key="Results.ClearSessionConfirm">Clear all history entries for this session?</sys:String>
<!-- ── Common strings ───────────────────────────────────────────────── -->
<sys:String x:Key="Common.Pass">PASS</sys:String>
<sys:String x:Key="Common.Fail">FAIL</sys:String>
<sys:String x:Key="Common.Accept">Accept</sys:String>
<sys:String x:Key="Common.Cancel">Cancel</sys:String>
<sys:String x:Key="Common.Close">Close</sys:String>
<sys:String x:Key="Common.Save">Save</sys:String>
<sys:String x:Key="Common.Ok">OK</sys:String>
<sys:String x:Key="Common.Yes">Yes</sys:String>
<sys:String x:Key="Common.No">No</sys:String>
<sys:String x:Key="Common.Warning">WARNING</sys:String>
<sys:String x:Key="Common.Disabled">disabled</sys:String>
<!-- ── Dialog: Report ───────────────────────────────────────────────── -->
<sys:String x:Key="Dialog.Report.Title">Generate Report</sys:String>
<sys:String x:Key="Dialog.Report.ClientList">Client List</sys:String>
<sys:String x:Key="Dialog.Report.ClientData">Client Data</sys:String>
<sys:String x:Key="Dialog.Report.CompanyData">Company Data</sys:String>
<sys:String x:Key="Dialog.Report.Name">Name:</sys:String>
<sys:String x:Key="Dialog.Report.ClientInfo">Client information</sys:String>
<sys:String x:Key="Dialog.Report.Observations">Observations</sys:String>
<sys:String x:Key="Dialog.Report.Operator">Operator:</sys:String>
<sys:String x:Key="Dialog.Report.Company">Company:</sys:String>
<sys:String x:Key="Dialog.Report.CompanyInfo">Company information</sys:String>
<sys:String x:Key="Dialog.Report.DeleteClient">Delete Client</sys:String>
<sys:String x:Key="Dialog.Report.Generate">Generate</sys:String>
<!-- ── Dialog: User authentication ──────────────────────────────────── -->
<sys:String x:Key="Dialog.UserCheck.Title">User Authentication</sys:String>
<sys:String x:Key="Dialog.UserCheck.Username">Username:</sys:String>
<sys:String x:Key="Dialog.UserCheck.Password">Password:</sys:String>
<!-- ── Dialog: Voltage warning ──────────────────────────────────────── -->
<sys:String x:Key="Dialog.Voltage.Title">Power Supply Warning</sys:String>
<sys:String x:Key="Dialog.Voltage.VoltageLabel">VOLTAGE: </sys:String>
<sys:String x:Key="Dialog.Voltage.PumpRequires">The selected pump requires </sys:String>
<sys:String x:Key="Dialog.Voltage.PowerSupply"> power supply.</sys:String>
<sys:String x:Key="Dialog.Voltage.SwitchTo">SWITCH THE POWER SUPPLY TO </sys:String>
<!-- ── Dialog: Oil pump confirmation ────────────────────────────────── -->
<sys:String x:Key="Dialog.OilPump.Title">Oil Pump Activation</sys:String>
<sys:String x:Key="Dialog.OilPump.Message">You are about to activate the oil pump. Confirm that the oil level is adequate and all connections are secure before proceeding.</sys:String>
<sys:String x:Key="Dialog.OilPump.LeaksChecked">I have checked — no leaks, connections are ready</sys:String>
<!-- ── Dialog: RPM safety warning ───────────────────────────────────── -->
<sys:String x:Key="Dialog.RpmSafety.Title">RPM Safety Warning</sys:String>
<sys:String x:Key="Dialog.RpmSafety.Message">The oil pump is OFF. Running the bench motor without oil circulation can cause bearing damage to the pump.</sys:String>
<sys:String x:Key="Dialog.RpmSafety.OilAndProceed">Turn on oil pump and start the bench</sys:String>
<sys:String x:Key="Dialog.RpmSafety.ProceedWithout">I know what I'm doing — start without oil</sys:String>
<!-- ── Dialog: Unlock progress ──────────────────────────────────────── -->
<sys:String x:Key="Dialog.Unlock.Title">Immobilizer Unlock</sys:String>
<sys:String x:Key="Dialog.Unlock.Progress">PROGRESS</sys:String>
<sys:String x:Key="Dialog.Unlock.Phase1">Phase 1: Sending unlock signals</sys:String>
<sys:String x:Key="Dialog.Unlock.Phase2Testing">Phase 2: Testing</sys:String>
<sys:String x:Key="Dialog.Unlock.Phase2Sending">Phase 2: Sending...</sys:String>
<sys:String x:Key="Dialog.Unlock.Cancelled">CANCELLED</sys:String>
<sys:String x:Key="Dialog.Unlock.Unlocked">UNLOCKED</sys:String>
<sys:String x:Key="Dialog.Unlock.Failed">UNLOCK FAILED</sys:String>
<sys:String x:Key="Dialog.Unlock.TypeLabel">Type {0}</sys:String>
<!-- ── Dialog: K-Line errors ────────────────────────────────────────── -->
<sys:String x:Key="Dialog.KlineErrors.Title">K-Line Fault Codes</sys:String>
<sys:String x:Key="Dialog.KlineErrors.Header">Fault codes:</sys:String>
<sys:String x:Key="Dialog.KlineErrors.Read">Read</sys:String>
<sys:String x:Key="Dialog.KlineErrors.Clear">Clear</sys:String>
<!-- ── Dialog: Settings ───────────────────────────────────────────────── -->
<sys:String x:Key="Dialog.Settings.Title">Settings</sys:String>
<sys:String x:Key="Dialog.Settings.Tab.General">General</sys:String>
<sys:String x:Key="Dialog.Settings.Tab.Safety">Safety</sys:String>
<sys:String x:Key="Dialog.Settings.Tab.Pid">PID</sys:String>
<sys:String x:Key="Dialog.Settings.Tab.Motor">Motor</sys:String>
<sys:String x:Key="Dialog.Settings.Tab.Report">Report</sys:String>
<sys:String x:Key="Dialog.Settings.Tab.KLine">K-Line</sys:String>
<sys:String x:Key="Dialog.Settings.Tab.Advanced">Advanced</sys:String>
<sys:String x:Key="Dialog.Settings.Language">Language:</sys:String>
<sys:String x:Key="Dialog.Settings.DaysKeepLogs">Days to keep logs:</sys:String>
<sys:String x:Key="Dialog.Settings.TempMax">Max. temperature (°C):</sys:String>
<sys:String x:Key="Dialog.Settings.TempMin">Min. temperature (°C):</sys:String>
<sys:String x:Key="Dialog.Settings.SecurityRpmLimit">Safety RPM limit:</sys:String>
<sys:String x:Key="Dialog.Settings.MaxPressureBar">Max. pressure (bar):</sys:String>
<sys:String x:Key="Dialog.Settings.ToleranceUp">UP tolerance extension:</sys:String>
<sys:String x:Key="Dialog.Settings.TolerancePfp">PFP tolerance extension:</sys:String>
<sys:String x:Key="Dialog.Settings.IgnoreTin">Ignore T-in by default</sys:String>
<sys:String x:Key="Dialog.Settings.PidP">Proportional (P):</sys:String>
<sys:String x:Key="Dialog.Settings.PidI">Integral (I):</sys:String>
<sys:String x:Key="Dialog.Settings.PidD">Derivative (D):</sys:String>
<sys:String x:Key="Dialog.Settings.PidLoopMs">Loop period (ms):</sys:String>
<sys:String x:Key="Dialog.Settings.EncoderRes">Encoder resolution:</sys:String>
<sys:String x:Key="Dialog.Settings.VoltMaxRpm">Voltage for max RPM (V):</sys:String>
<sys:String x:Key="Dialog.Settings.MaxRpm">Max RPM:</sys:String>
<sys:String x:Key="Dialog.Settings.RightRelay">Right = relay ON</sys:String>
<sys:String x:Key="Dialog.Settings.Relations">RPM-Voltage Table</sys:String>
<sys:String x:Key="Dialog.Settings.RelRpm">RPM</sys:String>
<sys:String x:Key="Dialog.Settings.RelVoltage">Voltage (V)</sys:String>
<sys:String x:Key="Dialog.Settings.AddRow">Add</sys:String>
<sys:String x:Key="Dialog.Settings.RemoveRow">Remove</sys:String>
<sys:String x:Key="Dialog.Settings.CompanyName">Company name:</sys:String>
<sys:String x:Key="Dialog.Settings.CompanyInfo">Company information:</sys:String>
<sys:String x:Key="Dialog.Settings.ReportLogo">Report logo path:</sys:String>
<sys:String x:Key="Dialog.Settings.BrowseLogoTitle">Select Logo Image</sys:String>
<sys:String x:Key="Dialog.Settings.KLinePort">K-Line port (FTDI):</sys:String>
<sys:String x:Key="Dialog.Settings.RefreshPorts">Refresh</sys:String>
<sys:String x:Key="Dialog.Settings.KLineHint">Select an FTDI device or type the serial number manually.</sys:String>
<sys:String x:Key="Dialog.Settings.RefreshBench">Bench interface (ms):</sys:String>
<sys:String x:Key="Dialog.Settings.RefreshReading">While reading K-Line (ms):</sys:String>
<sys:String x:Key="Dialog.Settings.RefreshCanBus">CAN bus read (ms):</sys:String>
<sys:String x:Key="Dialog.Settings.RefreshPumpReq">Pump request (ms):</sys:String>
<sys:String x:Key="Dialog.Settings.RefreshPumpParams">Pump params (ms):</sys:String>
<sys:String x:Key="Dialog.Settings.BlinkInterval">Blink interval (ms):</sys:String>
<sys:String x:Key="Dialog.Settings.FlasherInterval">Flasher interval (ms):</sys:String>
<sys:String x:Key="Dialog.Settings.UsersHeader">Users</sys:String>
<sys:String x:Key="Dialog.Settings.ManageUsers">Manage Users...</sys:String>
<!-- ── Dialog: User management ──────────────────────────────────────── -->
<sys:String x:Key="Dialog.UserManage.Title">User Management</sys:String>
<sys:String x:Key="Dialog.UserManage.ColumnUsername">Username</sys:String>
<sys:String x:Key="Dialog.UserManage.Add">Add...</sys:String>
<sys:String x:Key="Dialog.UserManage.Remove">Remove</sys:String>
<sys:String x:Key="Dialog.UserManage.ChangePassword">Change Password...</sys:String>
<sys:String x:Key="Dialog.UserManage.Close">Close</sys:String>
<sys:String x:Key="Dialog.UserManage.Prompt.AddTitle">Add User</sys:String>
<sys:String x:Key="Dialog.UserManage.Prompt.ChangeTitle">Change password for '{0}'</sys:String>
<sys:String x:Key="Dialog.UserManage.Confirm.RemoveTitle">Remove User</sys:String>
<sys:String x:Key="Dialog.UserManage.Confirm.Remove">Remove user '{0}'?</sys:String>
<sys:String x:Key="Dialog.UserManage.Error.EmptyTitle">Invalid Input</sys:String>
<sys:String x:Key="Dialog.UserManage.Error.Empty">Username and password cannot be empty.</sys:String>
<sys:String x:Key="Dialog.UserManage.Error.InvalidCharsTitle">Invalid Input</sys:String>
<sys:String x:Key="Dialog.UserManage.Error.InvalidChars">Username must not contain ':' or ','.</sys:String>
<sys:String x:Key="Dialog.UserManage.Error.DuplicateTitle">Duplicate User</sys:String>
<sys:String x:Key="Dialog.UserManage.Error.Duplicate">A user with that name already exists.</sys:String>
<sys:String x:Key="Dialog.UserManage.Error.LastUserTitle">Cannot Remove</sys:String>
<sys:String x:Key="Dialog.UserManage.Error.LastUser">Cannot remove the last remaining user.</sys:String>
<!-- ── Error messages ───────────────────────────────────────────────── -->
<sys:String x:Key="Error.ReportGeneration">Failed to generate report:\n{0}</sys:String>
<sys:String x:Key="Error.ReportTitle">Report Error</sys:String>
<sys:String x:Key="Error.PsgSync">PSG sync pulse not detected. Check encoder connection.</sys:String>
<sys:String x:Key="Error.PsgTitle">PSG Error</sys:String>
<sys:String x:Key="Error.EmergencyStop">EMERGENCY STOP: {0}</sys:String>
<sys:String x:Key="Error.KLineNotFound">K-Line device not found. Check that the FTDI adapter is connected.</sys:String>
<sys:String x:Key="Error.KLineTitle">K-Line Error</sys:String>
<sys:String x:Key="Error.AuthInvalid">Invalid username or password.\n(Both are case-sensitive.)</sys:String>
<sys:String x:Key="Error.AuthTitle">Authentication Error</sys:String>
<!-- ── PDF Report ───────────────────────────────────────────────────── -->
<sys:String x:Key="Pdf.ReportTitle">VP44 INJECTION PUMP TEST REPORT</sys:String>
<sys:String x:Key="Pdf.GeneratedBy">Generated by HC-APTBS</sys:String>
<sys:String x:Key="Pdf.Page">Page </sys:String>
<sys:String x:Key="Pdf.Of"> of </sys:String>
<sys:String x:Key="Pdf.Date">Date: {0:dd/MM/yyyy HH:mm}</sys:String>
<sys:String x:Key="Pdf.Operator">Operator: {0}</sys:String>
<sys:String x:Key="Pdf.Client">Client: {0}</sys:String>
<sys:String x:Key="Pdf.PumpIdentification">PUMP IDENTIFICATION</sys:String>
<sys:String x:Key="Pdf.PumpId">Pump ID:</sys:String>
<sys:String x:Key="Pdf.Model">Model:</sys:String>
<sys:String x:Key="Pdf.SerialNo">Serial No.:</sys:String>
<sys:String x:Key="Pdf.Injector">Injector:</sys:String>
<sys:String x:Key="Pdf.Tube">Tube:</sys:String>
<sys:String x:Key="Pdf.Valve">Valve:</sys:String>
<sys:String x:Key="Pdf.Tension">Tension:</sys:String>
<sys:String x:Key="Pdf.Rotation">Rotation:</sys:String>
<sys:String x:Key="Pdf.LockAngle">Lock Angle:</sys:String>
<sys:String x:Key="Pdf.Measured">Measured:</sys:String>
<sys:String x:Key="Pdf.Chaveta">Chaveta:</sys:String>
<sys:String x:Key="Pdf.PreInj">Pre-Inj.:</sys:String>
<sys:String x:Key="Pdf.EcuData">ECU DATA (K-Line)</sys:String>
<sys:String x:Key="Pdf.OverallResult">OVERALL TEST RESULT</sys:String>
<sys:String x:Key="Pdf.TestsExecuted">Tests executed: {0} of {1}</sys:String>
<sys:String x:Key="Pdf.ParamsEvaluated">Parameters evaluated: {0} / {1} passed</sys:String>
<sys:String x:Key="Pdf.TestHeader">TEST: {0}</sys:String>
<sys:String x:Key="Pdf.Phase">Phase</sys:String>
<sys:String x:Key="Pdf.Parameter">Parameter</sys:String>
<sys:String x:Key="Pdf.Target">Target</sys:String>
<sys:String x:Key="Pdf.ToleranceHeader">Tolerance ±</sys:String>
<sys:String x:Key="Pdf.Average">Average</sys:String>
<sys:String x:Key="Pdf.Result">Result</sys:String>
<sys:String x:Key="Pdf.ErrorBits"> ⚠ Error bits: {0}</sys:String>
<sys:String x:Key="Pdf.NoSampleData">No sample data available for graphical display.</sys:String>
<sys:String x:Key="Pdf.ChartSamples">Samples: {0} | Target: {1} ± {2} | Average: {3} | Result: {4}</sys:String>
<sys:String x:Key="Pdf.Observations">OBSERVATIONS</sys:String>
</ResourceDictionary>