diff --git a/README.md b/README.md index 5851ab7..c5598a8 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ 完整仿真功能范围、任务分解和 M0-M8 里程碑见 [`完整仿真移植实施计划`](docs/linuxcnc-web-wasm-complete-simulation-plan.md);技术实施接续入口为 [`nextTask1.md`](nextTask1.md)。 +五轴 XYZAC TRT Web/WASM 源码对标轨道的独立接续入口为 [`nextTask-rtcp.md`](nextTask-rtcp.md),详细设计和实施资料位于 [`doc-rtcp`](doc-rtcp/README.md)。 + 恢复或开始工作时,首先读取 [`nextTask1.md`](nextTask1.md)。它是当前仿真轨道的唯一接续入口,刻意限制在 8 KiB 以内,不包含聊天记录、完整日志或历史证据。只有定位旧证据时才按需读取 [`docs/task-history.md`](docs/task-history.md) 和其中引用的产物。 项目整体流程、LinuxCNC 案例到 WASM/Worker/前端的映射,以及后续任务起点见 diff --git a/coverage/runtime-mapping.report.json b/coverage/runtime-mapping.report.json index b04e2d7..df83762 100644 --- a/coverage/runtime-mapping.report.json +++ b/coverage/runtime-mapping.report.json @@ -2,7 +2,7 @@ "schema": "runtime-mapping-report.v1", "status": "passed", "mapped_error_codes": 18, - "commands": 27, + "commands": 50, "limits": 6, "real_exclusions": 3 } diff --git a/coverage/sim-case-catalog.report.json b/coverage/sim-case-catalog.report.json index 67b4572..1920d2a 100644 --- a/coverage/sim-case-catalog.report.json +++ b/coverage/sim-case-catalog.report.json @@ -5,20 +5,20 @@ "host devices, unsupported dynamic loaders, and missing LinuxCNC source resources remain blocked" ], "catalog": { - "catalog_sha256": "ac762b8b27b4b7988c0c8c532c6299a0957a69538ccb42bc65f78593b8ab4815", + "catalog_sha256": "3c35f4b6df095ea0c4d3fcaacab1b5eee08274e451e0229b9668ca6107ef0167", "module": "web/workspace/sim-case-catalog.mjs" }, "counts": { - "cases": 235, - "files": 2000, - "indexed_blocked": 226, + "cases": 236, + "files": 2006, + "indexed_blocked": 227, "indexed_static_ready": 9 }, "implementation_status": "verified", "inputs": [ { "path": "coverage/full-configuration-startup-matrix.report.json", - "sha256": "f2140e4c1685ca17738645faedb962dcaa7210200c9151084bd5df40285eadf9" + "sha256": "9345288c2e5353d382a17e2ff18f881d8516f2e792920325c2b5cc28ac17a2f9" }, { "path": "coverage/hal-component-manifest.report.json", @@ -27,33 +27,33 @@ ], "outputs": [ { - "bytes": 226050, + "bytes": 227026, "path": "web/workspace/sim-case-catalog.mjs", - "sha256": "a43d9868fb8d749cd9aa7958cfc6630cbc1bbf78827feb612d7c2f952d267b99", + "sha256": "e90af5f821e30e5f655dae245448b4ae691961d7b03ee47138bdcbbbb6d16b6a", "status": "present" }, { - "bytes": 11291, + "bytes": 14544, "path": "web/workspace/sim-case-loader.mjs", - "sha256": "9f76f8fd886a9e39990b0036c4a75c1cc5a02325da5487bbe5793702a746f8ee", + "sha256": "a79b4c89e2d06f7d7dba5378848983ae1f8c2baa56729f1238bf31210c1b5675", "status": "present" }, { - "bytes": 3444, + "bytes": 3686, "path": "web/workspace/hal-configuration.mjs", - "sha256": "3979f687b9a808256b918b9e1919a0ed6d59c591cb990d4b7bdb57903c50a385", + "sha256": "44823665f199acc48bbfdf0903acf19e95d5ac4aeededcd570293cb7456169d6", "status": "present" }, { - "bytes": 2911, + "bytes": 3546, "path": "web/workspace/test_sim_case_loader.mjs", - "sha256": "0a07affb488505f91889cb3b843eb84782725b9f337313f1023510778e3381c3", + "sha256": "99f1656f402491c4f1d56b495d7274f440775bc4b557720dd82640b904bc14ba", "status": "present" }, { - "bytes": 16777, + "bytes": 16849, "path": "web/app/app.mjs", - "sha256": "5ae3c3df053383f5ae3242aba20c2c8818b04639868e96514955bd1a760ec2ef", + "sha256": "f2af4be261941e4eaa48e32c1d929fcb8adfa4fe91475c398eec03f1fa99a8a4", "status": "present" }, { @@ -75,7 +75,7 @@ "status": "present" } ], - "report_sha256": "b17fe0aad525c7b9e914d6a1ff384ab640bc8d3f475e8553aa3745bed02c49c0", + "report_sha256": "09ddb06b10860f9e37d7cb8d40499cb8b6fe3e121b88cd3b371b9df6b3fa91c5", "schema": "linuxcnc-sim-case-catalog-report.v1", "scope": "configs/sim case catalog and exact-path browser loader input", "status": "verified", diff --git a/coverage/task-packets/PARITY-00.handoff.json b/coverage/task-packets/PARITY-00.handoff.json new file mode 100644 index 0000000..f512f6f --- /dev/null +++ b/coverage/task-packets/PARITY-00.handoff.json @@ -0,0 +1,42 @@ +{ + "schema": "task-handoff.v1", + "task_id": "PARITY-00", + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "status": "verified", + "scope": "xyzac_only", + "result": "Native C, WASM C and Worker protocol/control/state/canonical/recovery traces compare tick-by-tick with positive divergence detection", + "report": {"path": "coverage/xyzac-trt-trace-parity.report.json", "sha256": "39c63aa9af38fd98e49fd68ec2401ee8715fcafef98d47c070a47ab6f6dc0a48"}, + "outputs": [ + {"path": "scripts/compare_xyzac_native_wasm_trace.py", "sha256": "89834553f2a7afc47e351bbddd33f83259665b943cd7f22fe48acbba32aaf7c4"}, + {"path": "web/worker/test_xyzac_trace_parity.mjs", "sha256": "f5c6a7cd3e8b7f72bb1b25b5c368c0e52d494b9c811022d34435e668612ec4ce"}, + {"path": "coverage/xyzac-trt-trace-parity.report.json", "sha256": "ef914bb7823b9cdb0f6e15ca409515659d5575d09cdc6da2c458cd81fafa595a"}, + {"path": "wasm-core/tests/sim_xyzac_trace_test.c", "sha256": "0a3d5f748d9f69f4212c3a1cdd65fe2986c253442c4de2de78de2e5a5635ff08"} + ], + "checks": { + "baseline": "passed", + "download_index": "passed", + "pointer": "passed", + "protocol_level": "passed", + "control_level": "passed", + "state_level": "passed", + "canonical_level": "passed", + "recovery_level": "passed", + "native_wasm_exact": "passed", + "native_worker_semantic": "passed", + "positive_divergence_tick": "passed", + "report_self_hash": "passed", + "native_ctest_21": "passed", + "react_typecheck_build": "passed" + }, + "evidence": { + "levels": ["protocol", "control", "state", "canonical", "recovery"], + "first_divergent_tick": null, + "positive_sample_tick": 2, + "positive_sample_path": "$[1].active_type", + "native_wasm_trace_sha256": "18d2ef9d77f9a7a5bf2fa8d9380c8b04383a58ee2b0258364cba31ec34a168f0" + }, + "failure_samples": [], + "next_task": "RTCP-09", + "next_task_status": "queued", + "release_status": "STOP_RELEASE" +} diff --git a/coverage/task-packets/RELEASE-00.handoff.json b/coverage/task-packets/RELEASE-00.handoff.json new file mode 100644 index 0000000..147c632 --- /dev/null +++ b/coverage/task-packets/RELEASE-00.handoff.json @@ -0,0 +1,40 @@ +{ + "schema": "task-handoff.v1", + "task_id": "RELEASE-00", + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "status": "verified", + "scope": "xyzac_only", + "result": "Selected xyzac-trt.ini WASM-only release gate verified; release remains STOP_RELEASE by explicit scope governance", + "report": {"path": "coverage/xyzac-trt-wasm-only-release-gate.report.json", "sha256": "368bc17b4ade17b8567abe299b7d7395abc0f09d187028a0cb750aa170b5891c"}, + "outputs": [ + {"path": "scripts/generate_xyzac_trt_wasm_only_release_gate.py", "sha256": "06e4c564d0b4fc482150ffd19ae7ce93d553a6bf525144159875d824054eca70"}, + {"path": "coverage/xyzac-trt-wasm-only-release-gate.report.json", "sha256": "f85319a0d1a5bc28a2ab06aed6c043ba1fff8a5d69d8901754b6d62ce6eb0c1c"} + ], + "checks": { + "baseline": "passed", + "download_index": "passed", + "pointer": "passed", + "wasm_authority": "passed", + "all_13_selected_case_reports": "passed", + "native_worker_trace": "passed", + "browser_matrix": "passed", + "recovery_endpoint": "passed", + "scope_exclusions_explicit": "passed", + "release_report_self_hash": "passed" + }, + "evidence": { + "selected_case": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "candidate_eligible": false, + "release_status": "STOP_RELEASE", + "blockers": [ + "HOST_EXCLUDED: Safari not in project scope", + "REAL-EXCLUDED: physical power loss not simulated", + "HOST_EXCLUDED: xyzbc/3axis/other LinuxCNC cases out of scope" + ], + "first_divergent_tick": null + }, + "failure_samples": [], + "next_task": null, + "next_task_status": "complete", + "release_status": "STOP_RELEASE" +} diff --git a/coverage/task-packets/RTCP-01.handoff.json b/coverage/task-packets/RTCP-01.handoff.json new file mode 100644 index 0000000..316de38 --- /dev/null +++ b/coverage/task-packets/RTCP-01.handoff.json @@ -0,0 +1,42 @@ +{ + "schema": "task-handoff.v1", + "task_id": "RTCP-01", + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "status": "verified", + "result": "XYZAC Worker topology, logical scheduler, command ledger and cancellation/reconcile contract verified", + "outputs": [ + {"path": "web/worker/xyzac-session.mjs", "sha256": "9cbbbd08ae372e515bafe906f87fe3a9552571f52997b4e5495b42a36097c6b3"}, + {"path": "web/worker/xyzac-scheduler.mjs", "sha256": "0c7544298869c9c2858cce1275db8f3f2034655a5aa92aac5bd6dbf2b16e3221"}, + {"path": "web/worker/xyzac-command-ledger.mjs", "sha256": "90d5fd10547f544338014a026a407cfb73f08c639bf0f1bef9c19a85fbcd16f5"}, + {"path": "web/worker/test_xyzac_session.mjs", "sha256": "76cd74a09a0318a33d70529f7c5b9cad25fd0daebd6dd8bb05f87b42626858ef"} + ], + "checks": { + "baseline": "passed", + "download_index": "passed", + "pointer": "passed", + "xyzac_session": "passed", + "xyzac_case_worker": "passed", + "xyzac_program_authority": "passed", + "xyzac_io_authority": "passed", + "ledger_replay_commit": "passed", + "ledger_timeout_reconcile": "passed", + "cancel_no_blind_retry": "passed", + "scheduler_logical_tick": "passed", + "native_ctest": "20/20 passed", + "react_typecheck_build": "passed" + }, + "evidence": { + "session_authority": "linuxcnc-wasm-worker", + "machine": {"coordinates": "XYZAC", "joint_count": 5, "kinematics": "xyzac-trt", "rotary_units": "degrees"}, + "scheduler_tick": 3, + "scheduler_state_hash": "fnv1a64:d6b307bada354385", + "replayed": true, + "committed_operation": "step-1", + "pending_after_abort": 0, + "first_divergent_tick": null + }, + "failure_samples": [], + "next_task": "RTCP-02", + "next_task_status": "queued", + "release_status": "STOP_RELEASE" +} diff --git a/coverage/task-packets/RTCP-02.handoff.json b/coverage/task-packets/RTCP-02.handoff.json new file mode 100644 index 0000000..88cfd66 --- /dev/null +++ b/coverage/task-packets/RTCP-02.handoff.json @@ -0,0 +1,35 @@ +{ + "schema": "task-handoff.v1", + "task_id": "RTCP-02", + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "status": "verified", + "scope": "xyzac_only", + "result": "Exact xyzac-trt.ini resource closure and startup state machine verified; xyzbc/3axis/other cases excluded", + "report": {"path": "coverage/xyzac-trt-startup.report.json", "sha256": "12cdae5c4547d8f2647da1f4721e147807ba738474adeb60901b3d837e4cb39e"}, + "outputs": [ + {"path": "web/workspace/xyzac-trt-case-loader.mjs", "sha256": "8480a20a13301cfc8dd37fbe66cf9b4cbfbfd7bd18623e81499a583c72f9f44a"}, + {"path": "coverage/xyzac-trt-startup.report.json", "sha256": "56e040b645bcefc3d6c57244cb2d3aba16f421ff5137089d9c3336970dfd968b"}, + {"path": "web/worker/test_xyzac_startup.mjs", "sha256": "013023e5f0a01d93ed8ab568879937f462a97e2fe08742995f15775c867fb8aa"}, + {"path": "scripts/generate_xyzac_trt_startup_report.py", "sha256": "0b7fca4feb6039423b92164cd57802b7aaaefa7e141dffd38cb024f9b031fb5e"} + ], + "checks": { + "baseline": "passed", + "download_index": "passed", + "pointer": "passed", + "xyzac_startup_test": "passed", + "startup_report_self_hash": "passed", + "exact_resource_count": 15, + "required_ini_sections": 7, + "hal_record_count": 165, + "missing_resource_fail_closed": "passed", + "xyzac_worker_case": "passed", + "native_ctest": "20/20 passed", + "react_typecheck": "passed" + }, + "startup_state_sequence": ["TASK_NEW", "CONFIG_RESOLVED", "HAL_READY", "RUNTIME_READY", "TASK_READY"], + "machine": {"coordinates": "XYZAC", "joint_count": 5, "rotary_units": "degrees", "kinematics": "xyzac-trt"}, + "failure_samples": [], + "next_task": "RTCP-03", + "next_task_status": "queued", + "release_status": "STOP_RELEASE" +} diff --git a/coverage/task-packets/RTCP-03.handoff.json b/coverage/task-packets/RTCP-03.handoff.json new file mode 100644 index 0000000..5423dbc --- /dev/null +++ b/coverage/task-packets/RTCP-03.handoff.json @@ -0,0 +1,41 @@ +{ + "schema": "task-handoff.v1", + "task_id": "RTCP-03", + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "status": "verified", + "scope": "xyzac_only", + "result": "XYZAC authoritative snapshot, axis_state projection and gate matrix verified", + "report": {"path": "coverage/xyzac-trt-gate-matrix.report.json", "sha256": "25deaea6a1fb442d86e660319fdd1d3061ca7da0af7d48858258aad4c71ec56c"}, + "outputs": [ + {"path": "web/worker/test_xyzac_gate_matrix.mjs", "sha256": "07e4f05f3b7bf470fb87ecea077587e7584928d28fe7e28932f8a649c960525d"}, + {"path": "coverage/xyzac-trt-gate-matrix.report.json", "sha256": "7c8cb2dad644e54462b30dd0ec3e3e792ecee8da67c9c2de236bc38f1c0e6188"}, + {"path": "web/app/axis-contract.mjs", "sha256": "51854238857e03c42abe91f1dec4da3f49734386a6cf3d99dae97d7f07ebafd5"}, + {"path": "web/worker/sim-session.mjs", "sha256": "bdde47643f15780fe32cc10fe1b8542bd70c3170fd057b26d34b5c79ccd9dc29"}, + {"path": "scripts/generate_xyzac_trt_gate_matrix_report.py", "sha256": "a5ec4edbe3f416f134812fe8e4b7222a426de0aa7b524fb9deafbcc3d999b6a9"} + ], + "checks": { + "baseline": "passed", + "download_index": "passed", + "pointer": "passed", + "xyzac_gate_matrix": "passed", + "gate_report_self_hash": "passed", + "xyzac_worker_case": "passed", + "panel_gate_regression": "passed", + "axis_contract_regression": "passed", + "react_typecheck": "passed" + }, + "gate_scenarios": { + "no_file": "axis_taskfile_missing", + "highlight_missing": "axis_highlight_missing", + "switchkins_hal_missing": "xyzac_hal_pin_vars_missing", + "switchkins_estop": "xyzac_estop_active", + "running_pause_abort": "verified", + "paused_resume": "verified", + "vismach_clear_visual_only": "verified" + }, + "state_hash": "fnv1a64:a95c3da31e470f59", + "failure_samples": [], + "next_task": "RTCP-04", + "next_task_status": "queued", + "release_status": "STOP_RELEASE" +} diff --git a/coverage/task-packets/RTCP-04.handoff.json b/coverage/task-packets/RTCP-04.handoff.json new file mode 100644 index 0000000..e08c6a7 --- /dev/null +++ b/coverage/task-packets/RTCP-04.handoff.json @@ -0,0 +1,20 @@ +{ + "schema": "task-handoff.v1", + "task_id": "RTCP-04", + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "status": "verified", + "scope": "xyzac_only", + "result": "WASM canonical XYZAC program load/preview/ledger flow verified", + "report": {"path": "coverage/xyzac-trt-program-preview.report.json", "sha256": "ad151b42a738667f0d62f1811409190adc06f5b59f3bde9019eec8b895abf736"}, + "outputs": [ + {"path": "web/worker/test_xyzac_program_preview.mjs", "sha256": "2ecec15067d0350741b1a02d14dd4aed3587ef1bc236065a51c28bc3391c2eef"}, + {"path": "coverage/xyzac-trt-program-preview.report.json", "sha256": "3398060c346e51691717b43c164322c333cab951a5c83ac3dd5e87fe0e452429"}, + {"path": "web/worker/wasm-program-runtime.mjs", "sha256": "3a91b2111f9803d58c8dc6dfc8fb0db4f7343cc7b87108bc53b642a13032c844"} + ], + "checks": {"baseline": "passed", "download_index": "passed", "pointer": "passed", "xyzac_program_preview": "passed", "preview_report_self_hash": "passed", "source_path_hash": "passed", "canonical_segments": "passed", "invalid_gcode_fail_closed": "passed", "empty_program_fail_closed": "passed", "program_load_replay": "passed", "xyzac_worker_case": "passed", "react_typecheck": "passed"}, + "evidence": {"source_hash": "fnv1a64:b7f4678312207b31", "line_count": 5, "segment_count": 2, "preview_hash": "fnv1a64:e226b45322b06337", "state_hash": "fnv1a64:d1505250bdc90614", "preview_authority": "linuxcnc-wasm-sim_program", "first_divergent_tick": null}, + "failure_samples": [], + "next_task": "RTCP-05", + "next_task_status": "queued", + "release_status": "STOP_RELEASE" +} diff --git a/coverage/task-packets/RTCP-05.handoff.json b/coverage/task-packets/RTCP-05.handoff.json new file mode 100644 index 0000000..e5a90c5 --- /dev/null +++ b/coverage/task-packets/RTCP-05.handoff.json @@ -0,0 +1,20 @@ +{ + "schema": "task-handoff.v1", + "task_id": "RTCP-05", + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "status": "verified", + "scope": "xyzac_only", + "result": "WASM XYZAC Run/Pause/Resume/Step/Abort/Restart/Run-from-line workflow verified", + "report": {"path": "coverage/xyzac-trt-workflow.report.json", "sha256": "5abbef3106546d65d0951cce07777532903653abeed52221a9c8ecd142d5bc0d"}, + "outputs": [ + {"path": "web/worker/test_xyzac_workflow.mjs", "sha256": "6c738c6993d43b4ce16feecfe87d2b507824a88b06ead2f0659db6ca25c346b5"}, + {"path": "scripts/generate_xyzac_trt_workflow_report.py", "sha256": "f1f4b34105b64d7caea34921ec8504d0c58006ee0fd9fa15561cecb1cba93abb"}, + {"path": "coverage/xyzac-trt-workflow.report.json", "sha256": "0a9749ed647fb5ead26681719468470b7cf9e765ea4df5881d74404c019c0a5d"} + ], + "checks": {"baseline": "passed", "download_index": "passed", "pointer": "passed", "xyzac_workflow": "passed", "workflow_report_self_hash": "passed", "run_pause_resume_step": "passed", "abort_queue_empty": "passed", "restart_source_hash": "passed", "run_from_line": "passed", "checkpoint_recovery": "passed", "xyzac_preview_regression": "passed", "xyzac_gate_regression": "passed", "react_typecheck": "passed"}, + "evidence": {"tick_after_first": 1, "active_before_abort": 1, "pause_cursor": 1, "restart_source_hash": "fnv1a64:7e075e2e695feafd", "run_from_line": 4, "recovery": "recovered", "final_state_hash": "fnv1a64:de58dbdf1fa2606f", "first_divergent_tick": null}, + "failure_samples": [], + "next_task": "RTCP-06", + "next_task_status": "queued", + "release_status": "STOP_RELEASE" +} diff --git a/coverage/task-packets/RTCP-06.handoff.json b/coverage/task-packets/RTCP-06.handoff.json new file mode 100644 index 0000000..894e4d4 --- /dev/null +++ b/coverage/task-packets/RTCP-06.handoff.json @@ -0,0 +1,21 @@ +{ + "schema": "task-handoff.v1", + "task_id": "RTCP-06", + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "status": "verified", + "scope": "xyzac_only", + "result": "WASM XYZAC MDI, five-axis jog, home, limits and ESTOP recovery verified", + "report": {"path": "coverage/xyzac-trt-manual-control.report.json", "sha256": "ec2180de513726dc70c0940ed15e03a7d9e54714960ba7246aba19eaf95d849b"}, + "outputs": [ + {"path": "web/worker/test_xyzac_manual_control.mjs", "sha256": "75ed33fcbe9f40f0c244029b4dd57017c4f9944107c88c5500ade5c6e67fe893"}, + {"path": "coverage/xyzac-trt-manual-control.report.json", "sha256": "012871cb9758621d0b38a0acf240e5d077b332a72bad42d9592fe39c86567a99"}, + {"path": "wasm-core/src/sim_posemath.c", "sha256": "2e63d8cc2bf4275a89238b2622b41dcd8dfabfe6d24ef5918628083a4f4f5216"}, + {"path": "wasm-core/src/sim_motion_queue.c", "sha256": "252de61937b685689c479be60e6ce398364790ef5034e54cd89db138b368937f"} + ], + "checks": {"baseline": "passed", "download_index": "passed", "pointer": "passed", "xyzac_manual_control": "passed", "manual_report_self_hash": "passed", "home_five_joints": "passed", "jog_xyz": "passed", "jog_ac_degrees": "passed", "mdi": "passed", "nonfinite_speed": "passed", "range_boundary": "passed", "following_error": "passed", "mdi_running_gate": "passed", "estop_recovery": "passed", "xyzac_workflow_regression": "passed", "react_typecheck": "passed"}, + "evidence": {"linear_axes": ["X", "Y", "Z"], "angular_axes": ["A", "C"], "angular_units": "degrees", "home_joint_count": 5, "jog_state_hash": "fnv1a64:458a605f469d43cc", "first_divergent_tick": null}, + "failure_samples": [], + "next_task": "RTCP-07", + "next_task_status": "queued", + "release_status": "STOP_RELEASE" +} diff --git a/coverage/task-packets/RTCP-07.handoff.json b/coverage/task-packets/RTCP-07.handoff.json new file mode 100644 index 0000000..041e220 --- /dev/null +++ b/coverage/task-packets/RTCP-07.handoff.json @@ -0,0 +1,60 @@ +{ + "schema": "task-handoff.v1", + "task_id": "RTCP-07", + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "status": "verified", + "scope": "xyzac_only", + "result": "WASM XYZAC HAL, PyVCP, tool, spindle, coolant, device acknowledgement and alarm authority verified", + "report": { + "path": "coverage/xyzac-trt-hal-tool-alarm.report.json", + "sha256": "3b59d77a19277228a3d37d00486c5344571392651adcf4b7d019217d0880fbe8" + }, + "outputs": [ + { + "path": "web/worker/test_xyzac_hal_tool_alarm.mjs", + "sha256": "731ff64fc5b9abd70c6ab6649a2644e51e363bda710a0d4ec9faeffa3bb77db3" + }, + { + "path": "coverage/xyzac-trt-hal-tool-alarm.report.json", + "sha256": "d0e8fef743ea45ed230a29bb5deefa563f07d82df85e6f9c70be56f67e79031a" + }, + { + "path": "web/worker/wasm-xyzac-io.mjs", + "sha256": "c5b77654b952e0656edc9d649f07af6e3244d649313761b9ff42aed329c98f0b" + }, + { + "path": "web/worker/sim-session.mjs", + "sha256": "ec5846105eeecb5dcf5d9ec579ff00b185eaaba2039caeabe1e9a199a6749873" + } + ], + "checks": { + "baseline": "passed", + "download_index": "passed", + "pointer": "passed", + "xyzac_hal_tool_alarm": "passed", + "hal_tool_alarm_report_self_hash": "passed", + "pyvcp_switches": "passed", + "vismach_clear_visual_only": "passed", + "hal_write_allowlist": "passed", + "tool_spindle_coolant": "passed", + "device_ack_timeout_abort": "passed", + "xyzac_io_regression": "passed", + "xyzac_manual_control_regression": "passed", + "native_ctest": "passed", + "react_typecheck_build": "passed" + }, + "evidence": { + "pyvcp_m_codes": ["M429", "M428", "M430"], + "hal_allowed": "motion.probe-input", + "hal_denied_code": "wasm_hal_write_denied", + "tool": 7, + "spindle_rpm": 1200, + "ack_timeout_code": "wasm_sim_device_ack_ack_-1008", + "state_hash": "fnv1a64:78582773ec5a3bbe", + "first_divergent_tick": null + }, + "failure_samples": [], + "next_task": "RTCP-08", + "next_task_status": "queued", + "release_status": "STOP_RELEASE" +} diff --git a/coverage/task-packets/RTCP-08.handoff.json b/coverage/task-packets/RTCP-08.handoff.json new file mode 100644 index 0000000..36b7f34 --- /dev/null +++ b/coverage/task-packets/RTCP-08.handoff.json @@ -0,0 +1,60 @@ +{ + "schema": "task-handoff.v1", + "task_id": "RTCP-08", + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "status": "verified", + "scope": "xyzac_only", + "result": "WASM XYZAC identity/TRT/userk kinematics, offsets, limits, multi-turn G93 arc, switchkins and lifecycle recovery verified", + "report": { + "path": "coverage/xyzac-trt-rtcp.report.json", + "sha256": "c370004d8f2d962937b3b91abe2b0dd1632283f570e29d2d194731bc0fe0a083" + }, + "outputs": [ + {"path": "web/worker/test_xyzac_rtcp.mjs", "sha256": "9bc14997e56a8d0f6f0043b3a92fa5efe0fc8b3fa9c973bffa9045446973208f"}, + {"path": "coverage/xyzac-trt-rtcp.report.json", "sha256": "b1562d6d2c9cd5144c7c8c9b334bd8bf67919ea7297f103ec67cb32773608d08"}, + {"path": "web/worker/wasm-xyzac-kinematics.mjs", "sha256": "f14581a52830df5f55d612a1ec88d82737bb429ff63b5267ea3903984be6050e"}, + {"path": "web/worker/sim-session.mjs", "sha256": "f3b3f78146a08ad0f770bceae9cb46e66dd997c1270e3be7e27c544c2f5d3b6b"}, + {"path": "wasm-core/src/sim_interpreter.c", "sha256": "714396428b6826d9ac8c05d654dcc33acf24eef4b6393f610c8997997e540e5a"} + ], + "checks": { + "baseline": "passed", + "download_index": "passed", + "pointer": "passed", + "xyzac_rtcp_k0_k6": "passed", + "rtcp_report_self_hash": "passed", + "identity_forward_inverse": "passed", + "xyzac_forward_inverse_offsets": "passed", + "userk_static_capability": "passed", + "dynamic_userk_rejection": "passed", + "switchkins_pose_preservation": "passed", + "g93_multiturn_arc": "passed", + "pause_abort_restart_recovery": "passed", + "native_ctest_20": "passed", + "wasm_switchkins_kinematics_userkins": "passed", + "xyzac_worker_regressions": "passed", + "motion_checkpoint_regression": "passed", + "react_typecheck_build": "passed" + }, + "evidence": { + "coordinates": "XYZAC", + "linear_units": "mm", + "angular_units": "deg", + "range_error": "wasm_xyzac_forward_-702", + "nonfinite_error": "wasm_xyzac_forward_-701", + "dynamic_userk_error": -712, + "helix_turn": -3, + "recovered_active_type": 1, + "recovered_state_hash": "fnv1a64:8c57efd84475776a", + "first_divergent_tick": null + }, + "failure_samples": [ + { + "classification": "HOST_EXCLUDED", + "code": "wasm_ctest_node18_local_url", + "detail": "CTest sim_api_test uses Node 18 fetch on a bare local .wasm path; real Node 24 Worker module and single-file WASM tests passed" + } + ], + "next_task": "PARITY-00", + "next_task_status": "queued", + "release_status": "STOP_RELEASE" +} diff --git a/coverage/task-packets/RTCP-09.handoff.json b/coverage/task-packets/RTCP-09.handoff.json new file mode 100644 index 0000000..4c659ce --- /dev/null +++ b/coverage/task-packets/RTCP-09.handoff.json @@ -0,0 +1,42 @@ +{ + "schema": "task-handoff.v1", + "task_id": "RTCP-09", + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "status": "verified", + "scope": "xyzac_only", + "result": "XYZAC additive Worker commands, typed snapshot projection, React controls, gate/operation/alarm/recovery visibility and browser layout verified", + "report": {"path": "coverage/xyzac-trt-protocol-react.report.json", "sha256": "ad83b98df362f1f7e25effbdbf43da2b2ea4e2b0f1f185568f33495c88aba854"}, + "outputs": [ + {"path": "web/react/src/XyzacTrtPanel.tsx", "sha256": "f17e25f74d87a39a1bd7520f65cf1b285cb4c38d8e4fcaec13320e41c4ca6511"}, + {"path": "web/react/src/xyzac-panel-contract.ts", "sha256": "650ac562d6153c992762a138752e5821e0d4fc16706622511cb94e4a733e6733"}, + {"path": "coverage/xyzac-trt-protocol-react.report.json", "sha256": "94bb31615c0cbe5a227fbfd6af42ed1b6ace82880d2453bd3cde89340647fc6d"}, + {"path": "web/worker/test_xyzac_protocol_react.mjs", "sha256": "69d942dfdcb7bc0d7fb26d6708220a47af13aa84acdcf490780980f6de0cc03d"} + ], + "checks": { + "baseline": "passed", + "download_index": "passed", + "pointer": "passed", + "additive_power": "passed", + "kinematics_select": "passed", + "visual_clear_visual_only": "passed", + "gate_rejection_reason": "passed", + "operation_pending_ack_result": "passed", + "react_worker_only_static_audit": "passed", + "react_typecheck_build": "passed", + "browser_desktop": "passed", + "browser_mobile": "passed", + "canvas_nonblank": "passed", + "horizontal_overflow": "passed" + }, + "evidence": { + "commands": ["POWER", "KINEMATICS_SELECT", "VISUAL_CLEAR"], + "components": ["XyzacTrtPanel", "XyzacProgramPane", "XyzacKinematicsControl", "XyzacManualPanel", "XyzacDiagnostics"], + "browser": {"desktop": [1440, 1000], "mobile": [390, 844], "desktop_status": "READY", "mobile_status": "READY", "desktop_scroll_width": 1425, "mobile_scroll_width": 390}, + "state_hash": "fnv1a64:4034107d88cc3171", + "first_divergent_tick": null + }, + "failure_samples": [], + "next_task": "RTCP-10", + "next_task_status": "queued", + "release_status": "STOP_RELEASE" +} diff --git a/coverage/task-packets/RTCP-10.handoff.json b/coverage/task-packets/RTCP-10.handoff.json new file mode 100644 index 0000000..23abfc8 --- /dev/null +++ b/coverage/task-packets/RTCP-10.handoff.json @@ -0,0 +1,43 @@ +{ + "schema": "task-handoff.v1", + "task_id": "RTCP-10", + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "status": "verified", + "scope": "xyzac_only", + "result": "Three.js XYZAC TRT Vismach hierarchy, signed table/saddle/spindle translations, A/C rotations, tool offset and authoritative visual trace verified", + "report": {"path": "coverage/xyzac-trt-threejs.report.json", "sha256": "592f729730cb122238edefd90417399cd2f21a2084603001d1b46aadad7b261f"}, + "outputs": [ + {"path": "web/react/src/XyzacMachineView.tsx", "sha256": "2645e2dadeda98357e73974ae7a48b5fb825a2362ddca33689604bb11ee78a71"}, + {"path": "web/react/src/XyzacToolPreview.tsx", "sha256": "32f6879594c3ed9bb6a9f2bb17650ea2cfb89a972c93ce31091bcccc73cdb6ef"}, + {"path": "web/react/src/xyzac-visual-adapter.ts", "sha256": "1e9aca3e5f206876310268b86c5cabd0c37cd23a28cfbf599e29612effdf20dd"}, + {"path": "web/react/src/test_xyzac_threejs.mjs", "sha256": "a858df19658826e92e5d6f6df566a16741741648631f4e02f36b2825b97f6e7d"}, + {"path": "web/react/src/test_xyzac_tool_preview.mjs", "sha256": "be345e8df99a1bb4912c2a1fb334ed1823e03dd2ba67ca6cf60bee927d269b0a"}, + {"path": "coverage/xyzac-trt-threejs.report.json", "sha256": "0bdd0e072c7d1c87f1a3183ca522cc61baf0bdc3d26a94199d1f3e005a960dbb"} + ], + "checks": { + "baseline": "passed", + "download_index": "passed", + "pointer": "passed", + "machine_hierarchy": "passed", + "tool_preview_separated": "passed", + "ac_direction_offset": "passed", + "authoritative_tick_hash": "passed", + "canvas_nonblank_desktop": "passed", + "canvas_nonblank_mobile": "passed", + "visual_clear_nonmutating": "passed", + "horizontal_overflow_desktop_mobile": "passed", + "react_typecheck_build": "passed", + "xyzac_worker_regressions": "passed", + "native_ctest_21": "passed" + }, + "evidence": { + "machine_groups": ["xyzac-machine", "table-x", "saddle-y", "spindle-z", "tilt-a", "rotate-c", "tool-offset", "xyzac-toolpath", "xyzac-live-toolpath"], + "direction": {"table_x": -1, "saddle_y": -1, "spindle_z": -1, "tilt_a": "x+", "rotate_c": "z+", "tool_offset": "z-"}, + "browser_pixel_oracle": {"desktop_nonzero_pixels": 777266, "mobile_nonzero_pixels": 118864}, + "first_divergent_tick": null + }, + "failure_samples": [], + "next_task": "RTCP-11", + "next_task_status": "queued", + "release_status": "STOP_RELEASE" +} diff --git a/coverage/task-packets/RTCP-11.handoff.json b/coverage/task-packets/RTCP-11.handoff.json new file mode 100644 index 0000000..1c25267 --- /dev/null +++ b/coverage/task-packets/RTCP-11.handoff.json @@ -0,0 +1,45 @@ +{ + "schema": "task-handoff.v1", + "task_id": "RTCP-11", + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "status": "verified", + "scope": "xyzac_only", + "result": "XYZAC WASM checkpoint/journal/restart/replay/reconcile recovery verified with no duplicate M428 and fail-closed corruption paths", + "report": {"path": "coverage/xyzac-trt-recovery.report.json", "sha256": "9dc18abe81d4d7f84ef2543d664895f43ffd52ab5b4925672402724902b2369f"}, + "outputs": [ + {"path": "web/worker/test_xyzac_recovery.mjs", "sha256": "d8f02b0ab5b7c9fc5ef30a3a67f7896071ecf9bbaa7d2f3614c031d118e655e7"}, + {"path": "coverage/xyzac-trt-recovery.report.json", "sha256": "a863e06fce29904913b38526fe0f780f3f8912f0e741763c1e7221283a335808"}, + {"path": "scripts/generate_xyzac_trt_recovery_report.py", "sha256": "5e75fe82fd069d891e7a34a07da7aa9b4e7b3152b6b61ce791a77a97e2dc957c"}, + {"path": "web/worker/sim-session.mjs", "sha256": "0ab5e206629e005eabb834db8bb90106e28f2cfcc23ddec4acbb96f38c3d5423"} + ], + "checks": { + "baseline": "passed", + "download_index": "passed", + "pointer": "passed", + "checkpoint_minimum_fields": "passed", + "endpoint_pose_joints_program_hash": "passed", + "no_duplicate_m428": "passed", + "ledger_reconcile": "passed", + "corrupt_checkpoint_fail_closed": "passed", + "schema_mismatch_fail_closed": "passed", + "journal_commit_recovery": "passed", + "journal_corruption_fail_closed": "passed", + "opfs_unavailable_fail_closed": "passed", + "native_ctest_21": "passed", + "react_typecheck_build": "passed" + }, + "evidence": { + "required_checkpoint_fields": ["context_id", "simulation_tick", "event_cursor", "state_hash", "task", "program", "kinematics", "motion", "wasm_motion", "ledger"], + "endpoint_at_checkpoint_equal": true, + "no_duplicate_m428": true, + "replayed_operation": true, + "corrupt_checkpoint": "blocked", + "schema_mismatch": "blocked", + "opfs_physical_crash": "REAL-EXCLUDED", + "first_divergent_tick": null + }, + "failure_samples": [], + "next_task": "RTCP-12", + "next_task_status": "queued", + "release_status": "STOP_RELEASE" +} diff --git a/coverage/task-packets/RTCP-12.handoff.json b/coverage/task-packets/RTCP-12.handoff.json new file mode 100644 index 0000000..c4f18df --- /dev/null +++ b/coverage/task-packets/RTCP-12.handoff.json @@ -0,0 +1,38 @@ +{ + "schema": "task-handoff.v1", + "task_id": "RTCP-12", + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "status": "verified", + "scope": "xyzac_only", + "result": "Selected xyzac-trt.ini native/Worker/WASM/React/Three.js parity aggregate verified with explicit release exclusions", + "report": {"path": "coverage/xyzac-trt-web-wasm-parity.report.json", "sha256": "676f94870045670d2808c2193bded706fdd4909f06d70be00f46dd2653d92927"}, + "outputs": [ + {"path": "scripts/generate_xyzac_trt_web_wasm_parity_report.py", "sha256": "fd658a157981d8ca8bd95eecea3cf803443c0f10c7d7ca1dde75c184a69abd4d"}, + {"path": "coverage/xyzac-trt-web-wasm-parity.report.json", "sha256": "032912a30e5bdd970f6ff10cadb9a30642b7bdb45252ea40cd7f1b953a1050c7"} + ], + "checks": { + "baseline": "passed", + "download_index": "passed", + "pointer": "passed", + "all_13_selected_case_reports": "passed", + "native_wasm_trace": "passed", + "native_worker_trace": "passed", + "first_divergent_tick_normal": "null", + "first_divergent_tick_positive_sample": "2", + "browser_desktop_mobile": "passed", + "recovery_endpoint_equal": "passed", + "blocker_identity_explicit": "passed", + "report_self_hash": "passed" + }, + "evidence": { + "report_count": 13, + "candidate_eligible": false, + "release_status": "STOP_RELEASE", + "excluded": ["Safari", "physical power loss", "host hardware", "xyzbc", "3axis", "other cases"], + "first_divergent_tick": null + }, + "failure_samples": [], + "next_task": "RELEASE-00", + "next_task_status": "queued", + "release_status": "STOP_RELEASE" +} diff --git a/coverage/task-packets/SRC-00-REMEDIATION.handoff.json b/coverage/task-packets/SRC-00-REMEDIATION.handoff.json new file mode 100644 index 0000000..5468c13 --- /dev/null +++ b/coverage/task-packets/SRC-00-REMEDIATION.handoff.json @@ -0,0 +1,33 @@ +{ + "schema": "task-handoff.v1", + "task_id": "SRC-00-REMEDIATION", + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "status": "verified", + "result": "resolved native source startup, exact intro resource, and XYZAC native/WASM/Worker evidence", + "reports": [ + {"path": "coverage/xyzac-trt-native-wasm-parity.report.json", "sha256": "ec9c3d9062ab68ab542e5193852e7f8296a40c9c1813d9a303b0971cf4b89598"}, + {"path": "coverage/xyzac-trt-source-slice-inventory.report.json", "sha256": "69385c93662a6627dc6d83eaca851411ddf76156ae9aa85f56d4e029455e68ef"} + ], + "resolved": [ + "run-5axis-rtcp.sh now uses the repository run-in-place launcher", + "sim_lib.tcl recognizes xyzac-trt-kins and xyzbc-trt-kins", + "INTRO_GRAPHIC uses the existing linuxcnc.gif exact manifest asset", + "Worker loads xyzac-trt-headless_cmds.hal fixture and TASK_READY", + "WASM C API supplies XYZAC five-joint kinematics and M428/M429/M430 transitions" + ], + "checks": { + "native_xyzac_xyzbc_startup": "passed", + "native_wasm_kinematics_trace": "passed", + "native_wasm_switchkins_trace": "passed", + "xyzac_worker_case": "passed", + "source_slice_self_hash": "passed", + "native_ctest": "20/20", + "wasm_kinematics_tests": "passed", + "react_typecheck": "passed" + }, + "evidence": {"control_count": 110, "menus": 80, "toolbar": 20, "keyboard": 10, "slices": 11, "direct_sources": 35, "unregistered_slices": 0, "js_authority": 0, "first_divergent_tick": null}, + "packet": {"path": "coverage/task-packets/SRC-00-REMEDIATION.json", "sha256": "855839e8a1e5ca5168330ab25a3dc6eebc87ce3f9b6e69475c53e2b74a2b4e33"}, + "next_task": "WASM-00", + "next_task_status": "queued", + "release_status": "STOP_RELEASE" +} diff --git a/coverage/task-packets/SRC-00.handoff.json b/coverage/task-packets/SRC-00.handoff.json new file mode 100644 index 0000000..f65576d --- /dev/null +++ b/coverage/task-packets/SRC-00.handoff.json @@ -0,0 +1,42 @@ +{ + "schema": "task-handoff.v1", + "task_id": "SRC-00", + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "status": "verified", + "result": "source inventory, native/WASM parity, and exact XYZAC Worker authority evidence verified", + "reports": [ + {"path": "coverage/xyzac-trt-source-slice-inventory.report.json", "sha256": "601fb94f39681e382262b0ed6d6890f9db67e27a8ff4383b977fb073b46562e4"}, + {"path": "coverage/xyzac-trt-native-wasm-parity.report.json", "sha256": "f67633527c623e826c14d89687139d109d046fdeaf445fc754506a66c8262d8e"} + ], + "checks": { + "baseline": "passed", + "download_index": "passed", + "pointer": "passed", + "source_slice_unittest": "passed", + "source_slice_self_hash": "passed", + "native_xyzac_xyzbc_startup": "passed", + "native_wasm_kinematics_trace": "passed", + "native_wasm_switchkins_trace": "passed", + "xyzac_worker_case": "passed", + "mjs_syntax": "passed", + "react_typecheck": "passed" + }, + "evidence": { + "control_count": 110, + "menus": 80, + "toolbar": 20, + "keyboard": 10, + "slices": 11, + "direct_sources": 35, + "unregistered_slices": 0, + "blocked_resources": 0, + "js_authority": 0, + "first_divergent_tick": null, + "worker_state_hash": "fnv1a64:72275811a4320d7c" + }, + "failure_samples": [], + "packet": {"path": "coverage/task-packets/SRC-00.json", "sha256": "a13fa893653494bf12cee5e15c38cc6c74edc6ffcd02a10cb788c4a87e3cf37b"}, + "next_task": "WASM-00", + "next_task_status": "queued", + "release_status": "STOP_RELEASE" +} diff --git a/coverage/task-packets/WASM-00-REMEDIATION.handoff.json b/coverage/task-packets/WASM-00-REMEDIATION.handoff.json new file mode 100644 index 0000000..d42c11b --- /dev/null +++ b/coverage/task-packets/WASM-00-REMEDIATION.handoff.json @@ -0,0 +1,45 @@ +{ + "schema": "task-handoff.v1", + "task_id": "WASM-00-REMEDIATION", + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "status": "verified", + "result": "selected XYZAC authority verified for the simulation scope; physical power-loss and Safari are accepted scope exclusions", + "report": {"path": "coverage/xyzac-trt-wasm-authority-audit.report.json", "sha256": "279a9c2b0496e415cb3da25fc387ee245e826e942b67471a25796a3c23122205"}, + "implemented": [ + "sim_program C/WASM runtime owns selected XYZAC program load/control/interpreter/motion events", + "selected XYZAC jog/home/limit validation routes through WASM motion queue and home-limit", + "selected XYZAC snapshots omit JS compatibility planner state", + "sim_io C/WASM owns spindle/tool/probe/ESTOP/recovery and HAL scalar writes", + "sim_device_io C/WASM owns encoder/coolant/door/interlock/ack state", + "Chromium SIGKILL/profile reopen and corruption detection verified", + "Firefox Worker OPFS round-trip verified" + ], + "tests": { + "native_ctest": "20/20 passed", + "react_typecheck_build": "passed", + "xyzac_worker": "passed", + "xyzac_program_authority": "passed", + "xyzac_io_authority": "passed", + "native_xyzac_xyzbc_startup": "passed", + "native_wasm_parity": "passed", + "chromium_opfs_crash": "passed", + "chromium_opfs_corruption": "passed", + "firefox_opfs_round_trip": "passed", + "authority_audit": "passed" + }, + "authority_matrix": { + "program_interpreter": "verified", + "motion_jog_home_limit": "verified", + "task_state": "verified", + "hal_io_tool_probe": "verified", + "kinematics_rtcp_switchkins": "verified" + }, + "accepted_scope_exclusions": [ + {"code": "PHYSICAL_POWER_LOSS_OUTSIDE_BROWSER", "status": "accepted_scope_exclusion"}, + {"code": "SAFARI_NOT_REQUIRED", "status": "accepted_scope_exclusion"} + ], + "failure_samples": [], + "next_task": "RTCP-01", + "next_task_status": "queued", + "release_status": "STOP_RELEASE" +} diff --git a/coverage/task-packets/WASM-00.handoff.json b/coverage/task-packets/WASM-00.handoff.json new file mode 100644 index 0000000..ec22b28 --- /dev/null +++ b/coverage/task-packets/WASM-00.handoff.json @@ -0,0 +1,38 @@ +{ + "schema": "task-handoff.v1", + "task_id": "WASM-00", + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "status": "blocked", + "result": "XYZAC WASM authority audit completed; selected Worker trace is verified but JS authority and external recovery/browser boundaries remain open", + "report": {"path": "coverage/xyzac-trt-wasm-authority-audit.report.json", "sha256": "36fdd77229015634dcde9f796e32eb0435ae2729dc4267aca28d081179a44d7f"}, + "packet": {"path": "coverage/task-packets/WASM-00.json", "sha256": "4bdb5ca36b7a57d977248693ebea2b76a6bc9cc7d3a8998d59983630a342e73e"}, + "checks": { + "authority_audit_unittest": "passed", + "report_self_hash": "passed", + "xyzac_worker_trace": "passed", + "worker_motion_authority": "wasm", + "first_divergent_tick": null, + "react_direct_wasm_pointer": "passed", + "react_direct_opfs_writer": "passed" + }, + "evidence": { + "control_count": 110, + "switchkins": ["M429", "M428", "M430"], + "tick_sequence": [0, 0, 0], + "state_hash": "fnv1a64:72275811a4320d7c", + "js_authority_call_count": 0, + "js_authority_findings": 3, + "blocker_count": 5, + "candidate_eligible": false + }, + "failure_samples": [ + {"code": "JS_PROGRAM_CONTROL_FLOW", "detail": "ProgramRunner executes control directives and schedules interpreter blocks from JS"}, + {"code": "JS_MOTION_STATE_MIRROR", "detail": "MotionState owns XYZAC-relevant HOME/JOG/limit/fault transitions"}, + {"code": "JS_COMPATIBILITY_PLANNER_PRESENT", "detail": "AuthoritativeRuntime remains constructed and serializable for the selected session"}, + {"code": "BROWSER_OPFS_ORACLE_BLOCKED", "detail": "physical OPFS crash/restart and Firefox/Safari matrix are unavailable"}, + {"code": "FULL_XYZAC_AUTHORITY_MATRIX_PENDING", "detail": "HAL/IO/tool/probe and non-selected authority closure remain outside WASM-00"} + ], + "next_task": "RTCP-01", + "next_task_status": "blocked", + "release_status": "STOP_RELEASE" +} diff --git a/coverage/xyzac-trt-gate-matrix.report.json b/coverage/xyzac-trt-gate-matrix.report.json new file mode 100644 index 0000000..453b7e5 --- /dev/null +++ b/coverage/xyzac-trt-gate-matrix.report.json @@ -0,0 +1,76 @@ +{ + "authority": "linuxcnc-wasm-worker", + "candidate_eligible": true, + "case": { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "sha256": "f985970db293b70c055e4c41fc316d0c16037b5dc7ce07490e18f554e851f811" + }, + "command_trace": [ + "HELLO", + "SESSION_ATTACH", + "LOAD_WORKSPACE", + "PROGRAM_LOAD", + "PROGRAM_RUN", + "PROGRAM_PAUSE", + "PROGRAM_ABORT", + "ESTOP", + "IO_RECOVER", + "SNAPSHOT_REQUEST" + ], + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "failure_samples": [], + "gate_scenarios": { + "highlight_missing": { + "reason": "axis_highlight_missing", + "status": "verified" + }, + "no_file": { + "reason": "axis_taskfile_missing", + "status": "verified" + }, + "paused_resume": { + "resume": true, + "status": "verified" + }, + "running_pause_abort": { + "abort": true, + "pause": true, + "status": "verified" + }, + "switchkins_estop": { + "reason": "xyzac_estop_active", + "status": "verified" + }, + "switchkins_hal_missing": { + "reason": "xyzac_hal_pin_vars_missing", + "status": "verified" + }, + "vismach_clear": { + "status": "verified", + "visual_only": true + } + }, + "release_status": "STOP_RELEASE", + "report_sha256": "ae3ebd07146e75e1fa50c90d37e56ca195e2c6b82069718aedf9b63338ad2219", + "schema": "xyzac-gate-matrix-rtcp-03.v1", + "scope": "xyzac_only", + "state_hash": "fnv1a64:9abaa158693c6300", + "status": "verified", + "task_id": "RTCP-03", + "tests": [ + { + "command": [ + "node", + "web/worker/test_xyzac_gate_matrix.mjs" + ], + "output_sha256": "a8e61897c9e8f666970804f4ba8d0a959557960df40bf26261a7b4d73517de9a", + "returncode": 0, + "status": "verified" + } + ], + "tick_trace": [ + 0, + 0, + 0 + ] +} diff --git a/coverage/xyzac-trt-hal-tool-alarm.report.json b/coverage/xyzac-trt-hal-tool-alarm.report.json new file mode 100644 index 0000000..144cd11 --- /dev/null +++ b/coverage/xyzac-trt-hal-tool-alarm.report.json @@ -0,0 +1,87 @@ +{ + "ack": { + "abort": "verified", + "normal": "verified", + "timeout": "wasm_sim_device_ack_ack_-1008" + }, + "alarm": { + "code": "wasm_hal_write_denied", + "operation_id": "hal-denied" + }, + "authority": "linuxcnc-wasm-worker", + "candidate_eligible": true, + "case": { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "sha256": "f985970db293b70c055e4c41fc316d0c16037b5dc7ce07490e18f554e851f811" + }, + "command_trace": [ + "MDI_EXECUTE:M429", + "MDI_EXECUTE:M428", + "MDI_EXECUTE:M430", + "VCP_UPDATE:VISMACH_CLEAR", + "HAL_SET_ALLOWED", + "HAL_SET_DENIED", + "SPINDLE_COMMAND", + "COOLANT_COMMAND", + "TOOL_PREPARE", + "TOOL_CHANGE", + "MDI:G43", + "MDI:G49", + "DEVICE_ACK", + "DEVICE_ACK_TIMEOUT", + "DEVICE_ACK_ABORT" + ], + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "coolant": { + "flood": 1, + "lube": 0, + "mist": 1 + }, + "failure_samples": [], + "hal": { + "allowed": "motion.probe-input", + "denied": "wasm_hal_write_denied" + }, + "hal_write_policy": { + "direct_switchkins_write": "denied", + "mode": "allowlist", + "switchkins_path": "M429/M428/M430" + }, + "pyvcp": [ + "M429", + "M428", + "M430", + "vismach-clear" + ], + "release_status": "STOP_RELEASE", + "report_sha256": "75c368880a881da1230d3e66ec5265ad693053dc9eecce462d92c84f5a025872", + "schema": "xyzac-hal-tool-alarm-rtcp-07.v1", + "scope": "xyzac_only", + "spindle_rpm": 1200, + "state_hash": "fnv1a64:184c713588cb828d", + "status": "verified", + "task_id": "RTCP-07", + "tests": [ + { + "command": [ + "node", + "web/worker/test_xyzac_hal_tool_alarm.mjs" + ], + "output_sha256": "02c7e7eace9b8be9d3a3144f259fdfbf870569df26ba01c22b4146e1bc3bc9e2", + "returncode": 0, + "status": "verified" + } + ], + "tick_trace": [ + 0, + 10, + 30, + 31 + ], + "tool": 7, + "visual_clear": { + "runtime_hash_unchanged": true, + "status": "verified", + "visual_only": true + } +} diff --git a/coverage/xyzac-trt-manual-control.report.json b/coverage/xyzac-trt-manual-control.report.json new file mode 100644 index 0000000..487e6a0 --- /dev/null +++ b/coverage/xyzac-trt-manual-control.report.json @@ -0,0 +1,96 @@ +{ + "authority": "linuxcnc-wasm-worker", + "axes": [ + { + "axis": "x", + "end": 0.01, + "start": 0 + }, + { + "axis": "y", + "end": 0.01, + "start": 0 + }, + { + "axis": "z", + "end": 0.01, + "start": 0 + }, + { + "axis": "a", + "end": 0.01, + "start": 0 + }, + { + "axis": "c", + "end": 0.01, + "start": 0 + } + ], + "boundary": { + "following_error": "motion_following_error", + "nonfinite_speed": "motion_queue", + "out_of_range": "motion_queue" + }, + "candidate_eligible": true, + "case": { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "sha256": "f985970db293b70c055e4c41fc316d0c16037b5dc7ce07490e18f554e851f811" + }, + "command_trace": [ + "HOME", + "JOG_START:X", + "SIM_STEP", + "JOG_STOP", + "JOG_START:Y", + "JOG_START:Z", + "JOG_START:A", + "JOG_START:C", + "MDI_EXECUTE", + "PROGRAM_RUN", + "MDI_EXECUTE_BLOCKED", + "ESTOP", + "IO_RECOVER" + ], + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "estop_recovery": "verified", + "failure_samples": [], + "home": { + "authority": "wasm_home_limit", + "joints": 5 + }, + "mdi": "verified", + "release_status": "STOP_RELEASE", + "report_sha256": "0660bca7d4ae6d68e584346606911c98aaacb14922f1b5fc9a7a44d782936be6", + "schema": "xyzac-manual-control-rtcp-06.v1", + "scope": "xyzac_only", + "state_hash": "fnv1a64:fac98a76f1a41fbc", + "status": "verified", + "task_id": "RTCP-06", + "tests": [ + { + "command": [ + "node", + "web/worker/test_xyzac_manual_control.mjs" + ], + "output_sha256": "930fe1e249389de9b0c0460f59c36e46820e3e006dc4675ffdf2528891731066", + "returncode": 0, + "status": "verified" + } + ], + "tick_trace": [ + 1 + ], + "units": { + "angular_axes": [ + "A", + "C" + ], + "angular_units": "degrees", + "linear_axes": [ + "X", + "Y", + "Z" + ] + } +} diff --git a/coverage/xyzac-trt-native-wasm-parity.report.json b/coverage/xyzac-trt-native-wasm-parity.report.json new file mode 100644 index 0000000..fa316f0 --- /dev/null +++ b/coverage/xyzac-trt-native-wasm-parity.report.json @@ -0,0 +1,116 @@ +{ + "authority": "linuxcnc-wasm-worker", + "case": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "js_authority": 0, + "native": { + "command": [ + "./build-native/sim_xyzac_trace_test" + ], + "output_sha256": "18d2ef9d77f9a7a5bf2fa8d9380c8b04383a58ee2b0258364cba31ec34a168f0", + "returncode": 0, + "trace_sha256": "ca13e8dcb6d2816787a98c7bddc04db552b88f8d8a994b49301973a1bd11245a" + }, + "release_status": "STOP_RELEASE", + "report_sha256": "3a6278c6c80adf6565944b0fdce78349e640dc197c3e187eea16cdbbf6572ed3", + "schema": "xyzac-trt-native-wasm-parity.v2", + "scope": "xyzac_only", + "status": "verified", + "task_id": "PARITY-00", + "trace": { + "first_divergent_tick": null, + "levels": [ + "protocol", + "control", + "state", + "canonical", + "recovery" + ], + "native_wasm": { + "first_divergent_tick": null, + "levels": { + "canonical": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "control": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "protocol": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "recovery": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "state": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + } + }, + "status": "verified" + }, + "native_worker": { + "first_divergent_tick": null, + "levels": { + "canonical": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "control": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "protocol": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "recovery": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "state": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + } + }, + "status": "verified" + }, + "positive_divergence_sample": { + "detected": true, + "difference_path": "$[1].active_type", + "first_divergent_tick": 2, + "mutation": "state[1].active_type=99" + } + }, + "wasm": { + "command": [ + "node", + "build-wasm/sim_xyzac_trace_wasm_test.js" + ], + "output_sha256": "18d2ef9d77f9a7a5bf2fa8d9380c8b04383a58ee2b0258364cba31ec34a168f0", + "returncode": 0, + "trace_sha256": "ca13e8dcb6d2816787a98c7bddc04db552b88f8d8a994b49301973a1bd11245a" + }, + "worker": { + "command": [ + "node", + "web/worker/test_xyzac_trace_parity.mjs" + ], + "output_sha256": "773f77181d7fd891a25a9ec6e7c3109f5f6e9b7ddcc3f876e1e973657959558e", + "returncode": 0, + "trace_sha256": "ca13e8dcb6d2816787a98c7bddc04db552b88f8d8a994b49301973a1bd11245a" + } +} diff --git a/coverage/xyzac-trt-program-preview.report.json b/coverage/xyzac-trt-program-preview.report.json new file mode 100644 index 0000000..b3612e6 --- /dev/null +++ b/coverage/xyzac-trt-program-preview.report.json @@ -0,0 +1,62 @@ +{ + "authority": "linuxcnc-wasm-worker", + "candidate_eligible": true, + "case": { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "sha256": "f985970db293b70c055e4c41fc316d0c16037b5dc7ce07490e18f554e851f811" + }, + "command_trace": [ + "PROGRAM_LOAD", + "WASM_PROGRAM_PREVIEW", + "SNAPSHOT_REQUEST", + "PROGRAM_LOAD_REPLAY", + "PROGRAM_LOAD_INVALID", + "PROGRAM_LOAD_EMPTY" + ], + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "error_cases": { + "empty_source": "program_source_invalid", + "invalid_gcode": "error" + }, + "failure_samples": [], + "line_count": 4, + "preview_authority": "linuxcnc-wasm-sim_program", + "preview_fields": [ + "id", + "source_line", + "start", + "end", + "motion_type", + "center", + "normal", + "turn" + ], + "preview_hash": "fnv1a64:6bdaeeddf0262c90", + "recovery": { + "no_duplicate_side_effect": true, + "replay_same_operation": "verified" + }, + "release_status": "STOP_RELEASE", + "report_sha256": "bde1a054c9a633a62595ec19e5097d73499ca8fbcf07c817c01265dbf643f04a", + "schema": "xyzac-program-preview-rtcp-04.v1", + "scope": "xyzac_only", + "segment_count": 2, + "source_hash": "fnv1a64:b7f4678312207b31", + "state_hash": "fnv1a64:fda625a2e7b00ac7", + "status": "verified", + "task_id": "RTCP-04", + "tests": [ + { + "command": [ + "node", + "web/worker/test_xyzac_program_preview.mjs" + ], + "output_sha256": "79dd24d44e07958fd86484197c4502d3bdadd6d6971b7e74727b594d1d6b630f", + "returncode": 0, + "status": "verified" + } + ], + "tick_trace": [ + 0 + ] +} diff --git a/coverage/xyzac-trt-protocol-react.report.json b/coverage/xyzac-trt-protocol-react.report.json new file mode 100644 index 0000000..f4f4be8 --- /dev/null +++ b/coverage/xyzac-trt-protocol-react.report.json @@ -0,0 +1,146 @@ +{ + "additive_commands": [ + "POWER", + "KINEMATICS_SELECT", + "VISUAL_CLEAR" + ], + "authority": "linuxcnc-wasm-worker", + "browser_matrix": { + "console_exceptions": 0, + "desktop": { + "canvas_nonblank": true, + "document_width": 1425, + "scroll_width": 1425, + "status": "READY", + "switchkins_controls": 3, + "viewport": [ + 1440, + 1000 + ] + }, + "functional_note": "Chromium simulation only; Safari and physical power loss are excluded by scope", + "mobile": { + "canvas_nonblank": true, + "document_width": 390, + "scroll_width": 390, + "status": "READY", + "switchkins_controls": 3, + "viewport": [ + 390, + 844 + ] + } + }, + "candidate_eligible": true, + "case": { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "scope": "xyzac_only" + }, + "components": [ + "XyzacTrtPanel", + "XyzacProgramPane", + "XyzacKinematicsControl", + "XyzacManualPanel", + "XyzacDiagnostics" + ], + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "default_case": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "exclusions": [ + "xyzbc", + "3axis", + "other cases", + "Safari", + "physical power loss", + "host hardware" + ], + "failure_samples": [], + "gates": { + "controller": [ + "blocked", + "pending", + "result" + ], + "invalid": "xyzac_kinematics_type_invalid", + "running": "xyzac_interp_not_idle" + }, + "known_blockers": [], + "operation_phases": [ + "blocked", + "pending", + "result" + ], + "outputs": [ + { + "path": "web/react/src/XyzacTrtPanel.tsx", + "sha256": "f17e25f74d87a39a1bd7520f65cf1b285cb4c38d8e4fcaec13320e41c4ca6511" + }, + { + "path": "web/react/src/xyzac-panel-contract.ts", + "sha256": "a1afaa368927bbc5b7d9e21a64213b963a97b687cecb0005bb9b8e47e969e823" + }, + { + "path": "web/worker/test_xyzac_protocol_react.mjs", + "sha256": "69d942dfdcb7bc0d7fb26d6708220a47af13aa84acdcf490780980f6de0cc03d" + } + ], + "release_status": "STOP_RELEASE", + "report_sha256": "a8ee87b6cb3ccbd683e9888c85a063dabbe17fafdd2708636bd48be592b7b520", + "schema": "xyzac-trt-protocol-react-report.v1", + "state_hash": "fnv1a64:2de42fa3ac15497a", + "status": "verified", + "switchkins": [ + { + "operation_id": "select-0-4", + "phase": "committed", + "type": 0 + }, + { + "operation_id": "select-1-5", + "phase": "committed", + "type": 1 + }, + { + "operation_id": "select-2-6", + "phase": "committed", + "type": 2 + }, + { + "operation_id": "select-1-7", + "phase": "committed", + "type": 1 + } + ], + "task_id": "RTCP-09", + "tests": [ + { + "command": [ + "node", + "web/worker/test_xyzac_protocol_react.mjs" + ], + "output_sha256": "cf72a973132e3e79c155fcb0feb58f07259c082970287127d786e94a92cc4327", + "returncode": 0 + }, + { + "command": [ + "npm", + "run", + "typecheck" + ], + "output_sha256": "08fb3e3d0d9396a56f8720eb15d9f6920f8a30c2dad7b0b6672ac446801f27e3", + "returncode": 0 + } + ], + "visibility": { + "alarms": true, + "gate_reason": true, + "pending_ack_result_error": true, + "recovery": true + }, + "worker_only_boundary": { + "react_direct_opfs": 0, + "react_direct_wasm": 0, + "react_post_message": 0, + "status": "verified", + "transport": "ReactWorkerClient" + } +} diff --git a/coverage/xyzac-trt-recovery.report.json b/coverage/xyzac-trt-recovery.report.json new file mode 100644 index 0000000..dd61c42 --- /dev/null +++ b/coverage/xyzac-trt-recovery.report.json @@ -0,0 +1,102 @@ +{ + "authority": "linuxcnc-wasm-worker", + "candidate_eligible": true, + "case": { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "scope": "xyzac_only" + }, + "checkpoint": { + "active_type": 1, + "required_fields": [ + "context_id", + "simulation_tick", + "event_cursor", + "state_hash", + "task", + "program", + "kinematics", + "motion", + "wasm_motion", + "ledger" + ], + "state_hash": "fnv1a64:1463b940dede5cf0" + }, + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "endpoint": { + "at_checkpoint_equal": true, + "continuous_hash": "fnv1a64:a4dee4490d19b4ec", + "restored_hash": "fnv1a64:ca9e3481aaa28f6d" + }, + "exclusions": [ + "xyzbc", + "3axis", + "other cases", + "Safari", + "physical power loss", + "host hardware" + ], + "fail_closed": { + "corrupt_checkpoint": "blocked", + "journal_corrupt": "blocked", + "journal_schema": "blocked", + "schema_mismatch": "blocked" + }, + "failure_samples": [], + "first_divergent_tick": null, + "journal": { + "corrupt_status": "blocked", + "schema_status": "blocked", + "status": "recovered" + }, + "known_blockers": [], + "no_duplicate_side_effect": { + "m428": true, + "replayed_operation": true + }, + "opfs": { + "physical_crash": "REAL-EXCLUDED", + "probe_status": "blocked", + "unavailable_status": "blocked" + }, + "outputs": [ + { + "path": "web/worker/test_xyzac_recovery.mjs", + "sha256": "d8f02b0ab5b7c9fc5ef30a3a67f7896071ecf9bbaa7d2f3614c031d118e655e7" + }, + { + "path": "web/worker/sim-session.mjs", + "sha256": "7ce91549f0f3a06ff77db9ee281fd9544848f6e41e08f9da302ee2e7827194e3" + }, + { + "path": "web/worker/wasm-program-runtime.mjs", + "sha256": "60da7b953ac4ee2659f2b05c6bb93b58c8d0c2c4b56363f6a93e44aab7aebb02" + } + ], + "release_status": "STOP_RELEASE", + "report_sha256": "6c38c4e541868934f7a8231d36314b7e736daeb6d685f1dad48809fa49ef65ae", + "required_checkpoint_fields": [ + "context_id", + "simulation_tick", + "event_cursor", + "state_hash", + "task", + "program", + "kinematics", + "motion", + "wasm_motion", + "ledger" + ], + "schema": "xyzac-trt-recovery-report.v1", + "status": "verified", + "task_id": "RTCP-11", + "tests": [ + { + "command": [ + "node", + "web/worker/test_xyzac_recovery.mjs" + ], + "output_sha256": "d13944363157b9b97a440adb6135ec8977332f31778fb7ae40383e52ba2f1f35", + "returncode": 0 + } + ] +} diff --git a/coverage/xyzac-trt-rtcp.report.json b/coverage/xyzac-trt-rtcp.report.json new file mode 100644 index 0000000..79b0b23 --- /dev/null +++ b/coverage/xyzac-trt-rtcp.report.json @@ -0,0 +1,256 @@ +{ + "authority": "linuxcnc-wasm-sim_kinematics_switch", + "boundaries": { + "nonfinite_joints": "wasm_xyzac_forward_-701", + "nonfinite_pose": "wasm_xyzac_inverse_-701", + "range": "wasm_xyzac_forward_-702", + "xyzac_singularity": "closed_form_no_singular_branch" + }, + "candidate_eligible": true, + "case": { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "sha256": "f985970db293b70c055e4c41fc316d0c16037b5dc7ce07490e18f554e851f811" + }, + "command_trace": [ + "WASM:IDENTITY_FORWARD_INVERSE", + "WASM:XYZAC_FORWARD_INVERSE", + "WASM:TOOL_ROTATION_AXIS_OFFSETS", + "WASM:USERK_IDENTITY_TEMPLATE", + "WASM:DYNAMIC_USERK_REJECT", + "WORKER:MDI_M429_M428_M430", + "WASM:G93_G2_P3_XYZAC_HELIX", + "WORKER:PROGRAM_PAUSE_RESUME_ABORT_RESTART", + "WORKER:CHECKPOINT_RECOVER" + ], + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "environment": { + "functional_node": "v24", + "wasm_ctest_harness": "HOST_EXCLUDED", + "wasm_ctest_node": "v18" + }, + "exclusions": [ + "xyzbc", + "3axis", + "other cases", + "Safari", + "physical power loss", + "host hardware" + ], + "failure_samples": [ + { + "classification": "HOST_EXCLUDED", + "code": "wasm_ctest_node18_local_url", + "detail": "CTest sim_api_test uses Node 18 fetch on a bare local .wasm path; real Node 24 Worker module and single-file WASM tests passed" + } + ], + "first_divergent_tick": null, + "helix": { + "end": { + "a": 30, + "b": 0, + "c": 45, + "u": 0, + "v": 0, + "w": 0, + "x": 10, + "y": 0, + "z": 5 + }, + "motion_type": 2, + "turn": -3, + "velocity": 6.538822170860375 + }, + "identity": { + "pose": { + "a": 30, + "b": 0, + "c": 45, + "u": 0, + "v": 0, + "w": 0, + "x": 12, + "y": -5, + "z": 20 + }, + "state_hash": "fnv1a64:1b181f155736dc31" + }, + "inputs": [ + { + "path": "linuxcnc/src/emc/kinematics/xyzac-trt-kins.c", + "sha256": "24c633613db9876c2ec246e1519a63d288fd27c68296d89f89f0368105634e69" + }, + { + "path": "linuxcnc/src/emc/kinematics/trtfuncs.c", + "sha256": "ced2f9d4732681e2e82153b2f6343eccdf6972222d558d1e277bf1ec0bdc87fd" + }, + { + "path": "linuxcnc/src/emc/kinematics/switchkins.c", + "sha256": "4de32a4a147e5ceee5346b9c6bf471dddf5c64ff58afe5044406c50bcd96b7f5" + }, + { + "path": "linuxcnc/src/emc/kinematics/userkfuncs.c", + "sha256": "146238645955f8d4e2cb0cd34ff44db3a9dad01e149f81c08f8a53c19f1609bc" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "sha256": "f985970db293b70c055e4c41fc316d0c16037b5dc7ce07490e18f554e851f811" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_ac.ngc", + "sha256": "06cb755e33dc35d9a179b3c48e4203c8469632ab248d94379b10f2538dd0b54a" + } + ], + "known_blockers": [], + "lifecycle": { + "abort": "STOPPED", + "pause": "PAUSED", + "recovery": "recovered", + "restart": "loaded", + "resume": "RUNNING" + }, + "mapping": { + "angular_units": "deg", + "coordinates": "XYZAC", + "limits": { + "a": [ + -100, + 50 + ], + "c": [ + -36000, + 36000 + ], + "x": [ + -200, + 200 + ], + "y": [ + -100, + 100 + ], + "z": [ + -120, + 120 + ] + }, + "linear_units": "mm" + }, + "offsets": { + "base": { + "a": 30, + "b": 0, + "c": 45, + "u": 0, + "v": 0, + "w": 0, + "x": 50.44481813796586, + "y": -20.265859980688887, + "z": 32.32050807568878 + }, + "changed": { + "a": 30, + "b": 0, + "c": 45, + "u": 0, + "v": 0, + "w": 0, + "x": 43.07044946720128, + "y": -25.569160839588, + "z": 35.6698729810778 + }, + "configured": { + "tool_offset": 25, + "x_rot_point": 5, + "y_offset": 20, + "z_offset": 10 + } + }, + "recovery": { + "active_type": 1, + "state_hash": "fnv1a64:8c57efd84475776a" + }, + "release_status": "STOP_RELEASE", + "report_sha256": "c370004d8f2d962937b3b91abe2b0dd1632283f570e29d2d194731bc0fe0a083", + "schema": "xyzac-rtcp-08-report.v1", + "scope": "xyzac_only", + "singularity_classification": { + "reason": "xyzac-trt forward/inverse is closed-form and has no denominator singular branch; A=-90 degree boundary roundtrip is retained", + "status": "not_applicable" + }, + "status": "verified", + "switchkins": [ + { + "active_type": 0, + "code": "M429", + "state_hash": "fnv1a64:7614a240beddd8ba" + }, + { + "active_type": 1, + "code": "M428", + "state_hash": "fnv1a64:1463b940dede5cf0" + }, + { + "active_type": 2, + "code": "M430", + "state_hash": "fnv1a64:310f1bed69a45614" + }, + { + "active_type": 1, + "code": "M428", + "state_hash": "fnv1a64:6c90a42b0ca912d4" + } + ], + "task_id": "RTCP-08", + "tests": [ + { + "command": [ + "node", + "web/worker/test_xyzac_rtcp.mjs" + ], + "output_sha256": "3b4411bd1f640a689bde7a99e087965edd0694ca49696d1a936397113980e6c1", + "returncode": 0, + "status": "verified" + } + ], + "tick_trace": [ + 0, + 1, + 2 + ], + "trt": { + "joints": [ + 49.99999999999999, + 10.000000000000004, + 30.000000000000007, + 30, + 45 + ], + "pivot_boundary": { + "a": -90, + "b": 0, + "c": 45, + "u": 0, + "v": 0, + "w": 0, + "x": 14.142135623730951, + "y": -14.142135623730951, + "z": -4.999999999999998 + }, + "pose": { + "a": 30, + "b": 0, + "c": 45, + "u": 0, + "v": 0, + "w": 0, + "x": 50.44481813796586, + "y": -20.265859980688887, + "z": 32.32050807568878 + }, + "state_hash": "fnv1a64:928adf4a1feb90e9" + }, + "userk": { + "dynamic_module_error": -712, + "native_type": "userk-identity-template" + } +} diff --git a/coverage/xyzac-trt-source-slice-inventory.report.json b/coverage/xyzac-trt-source-slice-inventory.report.json new file mode 100644 index 0000000..b8b7e08 --- /dev/null +++ b/coverage/xyzac-trt-source-slice-inventory.report.json @@ -0,0 +1,2666 @@ +{ + "authority": { + "authority_owner": "linuxcnc-wasm-worker", + "existing_audit": { + "open_boundaries": [ + "T1_FULL_CANONICAL_CALLBACKS", + "T2_FULL_WASM_PREVIEW", + "T3_NON_SELECTED_MOTION_AUTHORITY", + "T4_HAL_IO_TOOL_PROBE_CANONICAL_STATE", + "T5_FULL_MATRIX" + ], + "path": "coverage/wasm-only-source-audit.report.json", + "status": "blocked" + }, + "js_authority": 0 + }, + "axis_controls": { + "keyboard_bindings": [ + { + "binding": "Alt-v", + "control_id": "AXIS-KEY-ALT_V", + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": "2242-2243", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "bind" + } + }, + { + "binding": "Button-1", + "control_id": "AXIS-KEY-BUTTON_1", + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": null, + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "bind" + } + }, + { + "binding": "ButtonRelease-1", + "control_id": "AXIS-KEY-BUTTONRELEASE_1", + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": null, + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "bind" + } + }, + { + "binding": "Configure", + "control_id": "AXIS-KEY-CONFIGURE", + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": "2234-2234", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "bind" + } + }, + { + "binding": "Control-Tab", + "control_id": "AXIS-KEY-CONTROL_TAB", + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": "1989-1989", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "bind" + } + }, + { + "binding": "Key-Escape", + "control_id": "AXIS-KEY-KEY_ESCAPE", + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": "1551-1607", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "bind" + } + }, + { + "binding": "Key-Return", + "control_id": "AXIS-KEY-KEY_RETURN", + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": "1550-2245", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "bind" + } + }, + { + "binding": "greater", + "control_id": "AXIS-KEY-GREATER", + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": "1406-1406", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "bind" + } + }, + { + "binding": "less", + "control_id": "AXIS-KEY-LESS", + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": "1405-1405", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "bind" + } + }, + { + "binding": "semicolon", + "control_id": "AXIS-KEY-SEMICOLON", + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": "1430-1430", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "bind" + } + } + ], + "keyboard_count": 10, + "menu_count": 80, + "menus": [ + { + "control_id": "AXIS-MENU-FILE-_OPEN...", + "label_source": "\"_Open...\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "58-58", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-FILE-RECENT__FILES", + "label_source": "\"Recent _Files\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "62-62", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-FILE-_EDIT...", + "label_source": "\"_Edit...\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "66-66", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-FILE-_RELOAD", + "label_source": "\"_Reload\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "71-71", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-FILE-_SAVE_G-CODE_AS...", + "label_source": "\"_Save G-code as...\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "76-76", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-FILE-_PROPERTIES...", + "label_source": "\"_Properties...\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "80-80", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-FILE-EDIT__TOOL_DATA...", + "label_source": "\"Edit _tool data...\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "86-86", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-FILE-RELOAD_TOOL__DATA", + "label_source": "\"Reload tool _data\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "90-90", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-FILE-_LADDER_EDITOR...", + "label_source": "\"_Ladder Editor...\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "96-96", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-FILE-_QUIT", + "label_source": "\"_Quit\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "102-102", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-TOGGLE__EMERGENCY_STOP", + "label_source": "\"Toggle _Emergency Stop\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "108-108", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-TOGGLE__MACHINE_POWER", + "label_source": "\"Toggle _Machine Power\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "113-113", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-_RUN_PROGRAM", + "label_source": "\"_Run program\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "120-120", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-RU_N_FROM_SELECTED_LINE", + "label_source": "\"Ru_n from selected line\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "124-124", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-S_TEP", + "label_source": "\"S_tep\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "129-129", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-_PAUSE", + "label_source": "\"_Pause\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "134-134", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-RE_SUME", + "label_source": "\"Re_sume\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "139-139", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-STOP", + "label_source": "\"Stop\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "144-144", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-STOP_AT_M_1", + "label_source": "\"Stop at M_1\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "149-149", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-SKIP_LINES_WITH__/", + "label_source": "\"Skip lines with '_/'\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "154-154", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAR_MDI_H_ISTORY", + "label_source": "\"Clear MDI h_istory\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "161-161", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-COPY_FROM_MDI_HIST_ORY", + "label_source": "\"Copy from MDI hist_ory\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "165-165", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-PASTE_TO_MDI_HISTOR_Y", + "label_source": "\"Paste to MDI histor_y\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "169-169", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-_CALIBRATION", + "label_source": "\"_Calibration\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "175-175", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-SHOW__HAL_CONFIGURATION", + "label_source": "\"Show _Hal Configuration\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "179-179", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-H_AL_METER", + "label_source": "\"H_al Meter\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "183-183", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-HA_L_SCOPE", + "label_source": "\"Ha_l Scope\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "187-187", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-SHO_W_LINUXCNC_STATUS", + "label_source": "\"Sho_w LinuxCNC Status\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "191-191", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-SET__DEBUG_LEVEL", + "label_source": "\"Set _Debug Level\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "195-195", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-HOMIN_G", + "label_source": "\"Homin_g\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "201-201", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-_UNHOMING", + "label_source": "\"_Unhoming\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "205-205", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-_ZERO_COORDINATE_SYSTEM", + "label_source": "\"_Zero coordinate system\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "209-209", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAROFFSET-P1__G5_4", + "label_source": "\"P1 G5_4\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "213-213", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAROFFSET-P2__G5_5", + "label_source": "\"P2 G5_5\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "217-217", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAROFFSET-P3__G5_6", + "label_source": "\"P3 G5_6\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "221-221", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAROFFSET-P4__G5_7", + "label_source": "\"P4 G5_7\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "225-225", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAROFFSET-P5__G5_8", + "label_source": "\"P5 G5_8\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "229-229", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAROFFSET-P6__G5_9", + "label_source": "\"P6 G5_9\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "233-233", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAROFFSET-P7__G59._1", + "label_source": "\"P7 G59._1\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "237-237", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAROFFSET-P8__G59._2", + "label_source": "\"P8 G59._2\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "241-241", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAROFFSET-P9__G59._3", + "label_source": "\"P9 G59._3\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "245-245", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAROFFSET-_G92", + "label_source": "\"_G92\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "249-249", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-TOOL_TOUCH_OFF_TO_WOR_KPIECE", + "label_source": "\"Tool touch off to wor_kpiece\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "257-257", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-TOOL_TOUCH_OFF_TO__FIXTURE", + "label_source": "\"Tool touch off to _fixture\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "263-263", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-_TOP_VIEW", + "label_source": "\"_Top view\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "271-271", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-_ROTATED_TOP_VIEW", + "label_source": "\"_Rotated Top view\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "278-278", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-_SIDE_VIEW", + "label_source": "\"_Side view\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "285-285", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-_FRONT_VIEW", + "label_source": "\"_Front view\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "292-292", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-_PERSPECTIVE_VIEW", + "label_source": "\"_Perspective view\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "299-299", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-DISPLAY__INCHES", + "label_source": "\"Display _Inches\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "308-308", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-DISPLAY__MM", + "label_source": "\"Display _MM\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "315-315", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-S_HOW_PROGRAM", + "label_source": "\"S_how program\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "322-322", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW_PROGRAM_R_APIDS", + "label_source": "\"Show program r_apids\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "327-327", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-ALPHA-_BLEND_PROGRAM", + "label_source": "\"Alpha-_blend program\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "332-332", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHO_W_LIVE_PLOT", + "label_source": "\"Sho_w live plot\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "337-337", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW_TOO_L", + "label_source": "\"Show too_l\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "342-342", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW_E_XTENTS", + "label_source": "\"Show e_xtents\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "347-347", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-_GRID", + "label_source": "\"_Grid\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "351-351", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW_O_FFSETS", + "label_source": "\"Show o_ffsets\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "356-356", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SH_OW_MACHINE_LIMITS", + "label_source": "\"Sh_ow machine limits\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "361-361", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW_V_ELOCITY", + "label_source": "\"Show v_elocity\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "366-366", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW__DISTANCE_TO_GO", + "label_source": "\"Show _distance to go\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "371-371", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-LARGE_COORDINATE_FO_NT", + "label_source": "\"Large coordinate fo_nt\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "376-376", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-_CLEAR_LIVE_PLOT", + "label_source": "\"_Clear live plot\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "381-381", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW_PYVCP_PAN_EL", + "label_source": "\"Show PyVCP pan_el\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "387-387", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW_COMMANDED_POSITION", + "label_source": "\"Show commanded position\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "396-396", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW_ACTUAL_POSITION", + "label_source": "\"Show actual position\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "403-403", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW_MACHINE_POSITION", + "label_source": "\"Show machine position\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "412-412", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW_RELATIVE_POSITION", + "label_source": "\"Show relative position\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "419-419", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-JOINT_MODE", + "label_source": "\"Joint mode\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "428-428", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-WORLD_MODE", + "label_source": "\"World mode\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "435-435", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-GRID-_OFF", + "label_source": "\"_Off\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "443-443", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-GRID-_CUSTOM", + "label_source": "\"_Custom\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "449-449", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-HELP-_ABOUT_AXIS", + "label_source": "\"_About AXIS\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "460-460", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-HELP-QUICK__REFERENCE", + "label_source": "\"Quick _Reference\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "464-464", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU--_FILE", + "label_source": "_File]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "470-470", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU--_MACHINE", + "label_source": "_Machine]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "474-474", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU--_VIEW", + "label_source": "_View]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "478-478", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU--_HELP", + "label_source": "_Help]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "482-482", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-FILE-RECENT-_CLEAR_RECENTS_LIST", + "label_source": "\"_Clear Recents List\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "2230-2230", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + } + ], + "source_sha256": "c9f0b4dc686717b37565f85fb0ab8cc8ded9cfa0028cc0aaaccdbcf808c4c524", + "toolbar": [ + { + "control_id": "AXIS-TOOLBAR-MACHINE_ESTOP", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "490-1775", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.machine_estop" + }, + "widget": ".toolbar.machine_estop" + }, + { + "control_id": "AXIS-TOOLBAR-MACHINE_POWER", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "498-1778", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.machine_power" + }, + "widget": ".toolbar.machine_power" + }, + { + "control_id": "AXIS-TOOLBAR-FILE_OPEN", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "509-1787", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.file_open" + }, + "widget": ".toolbar.file_open" + }, + { + "control_id": "AXIS-TOOLBAR-RELOAD", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "517-1781", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.reload" + }, + "widget": ".toolbar.reload" + }, + { + "control_id": "AXIS-TOOLBAR-PROGRAM_RUN", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "527-1799", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.program_run" + }, + "widget": ".toolbar.program_run" + }, + { + "control_id": "AXIS-TOOLBAR-PROGRAM_STEP", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "535-1801", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.program_step" + }, + "widget": ".toolbar.program_step" + }, + { + "control_id": "AXIS-TOOLBAR-PROGRAM_PAUSE", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "543-1810", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.program_pause" + }, + "widget": ".toolbar.program_pause" + }, + { + "control_id": "AXIS-TOOLBAR-PROGRAM_STOP", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "558-1818", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.program_stop" + }, + "widget": ".toolbar.program_stop" + }, + { + "control_id": "AXIS-TOOLBAR-PROGRAM_BLOCKDELETE", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "568-1812", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.program_blockdelete" + }, + "widget": ".toolbar.program_blockdelete" + }, + { + "control_id": "AXIS-TOOLBAR-PROGRAM_OPTPAUSE", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "575-1814", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.program_optpause" + }, + "widget": ".toolbar.program_optpause" + }, + { + "control_id": "AXIS-TOOLBAR-VIEW_ZOOMIN", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "584-741", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.view_zoomin" + }, + "widget": ".toolbar.view_zoomin" + }, + { + "control_id": "AXIS-TOOLBAR-VIEW_ZOOMOUT", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "592-745", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.view_zoomout" + }, + "widget": ".toolbar.view_zoomout" + }, + { + "control_id": "AXIS-TOOLBAR-VIEW_Z", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "584-753", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.view_z" + }, + "widget": ".toolbar.view_z" + }, + { + "control_id": "AXIS-TOOLBAR-VIEW_Z2", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "608-753", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.view_z2" + }, + "widget": ".toolbar.view_z2" + }, + { + "control_id": "AXIS-TOOLBAR-VIEW_X", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "616-757", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.view_x" + }, + "widget": ".toolbar.view_x" + }, + { + "control_id": "AXIS-TOOLBAR-VIEW_Y", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "624-765", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.view_y" + }, + "widget": ".toolbar.view_y" + }, + { + "control_id": "AXIS-TOOLBAR-VIEW_Y2", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "632-765", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.view_y2" + }, + "widget": ".toolbar.view_y2" + }, + { + "control_id": "AXIS-TOOLBAR-VIEW_P", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "640-769", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.view_p" + }, + "widget": ".toolbar.view_p" + }, + { + "control_id": "AXIS-TOOLBAR-ROTATE", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "648-773", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.rotate" + }, + "widget": ".toolbar.rotate" + }, + { + "control_id": "AXIS-TOOLBAR-CLEAR_PLOT", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "663-784", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.clear_plot" + }, + "widget": ".toolbar.clear_plot" + } + ], + "toolbar_count": 20 + }, + "blockers": [], + "case": { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "sha256": "f985970db293b70c055e4c41fc316d0c16037b5dc7ce07490e18f554e851f811", + "status": "indexed" + }, + "checks": { + "all_controls_commands_states_have_slice_id": true, + "all_direct_sources_have_sha256": true, + "exact_resources_resolved_or_explicitly_blocked": true, + "js_authority": 0, + "unregistered_slice_count": 0 + }, + "command_contract": [ + { + "command": "PROGRAM_LOAD", + "slice_id": "AXIS-XYZAC-PROGRAM-MDI" + }, + { + "command": "PROGRAM_RUN", + "slice_id": "AXIS-XYZAC-PROGRAM-MDI" + }, + { + "command": "PROGRAM_PAUSE", + "slice_id": "AXIS-XYZAC-PROGRAM-MDI" + }, + { + "command": "PROGRAM_RESUME", + "slice_id": "AXIS-XYZAC-PROGRAM-MDI" + }, + { + "command": "PROGRAM_ABORT", + "slice_id": "AXIS-XYZAC-PROGRAM-MDI" + }, + { + "command": "MDI_EXECUTE", + "slice_id": "AXIS-XYZAC-PROGRAM-MDI" + }, + { + "command": "JOG_START", + "slice_id": "AXIS-XYZAC-JOG-HOME" + }, + { + "command": "JOG_STOP", + "slice_id": "AXIS-XYZAC-JOG-HOME" + }, + { + "command": "HOME", + "slice_id": "AXIS-XYZAC-JOG-HOME" + }, + { + "command": "M428", + "slice_id": "AXIS-XYZAC-M428-M429-M430" + }, + { + "command": "M429", + "slice_id": "AXIS-XYZAC-M428-M429-M430" + }, + { + "command": "M430", + "slice_id": "AXIS-XYZAC-M428-M429-M430" + }, + { + "command": "SIM_STEP", + "slice_id": "AXIS-XYZAC-TASK-TP-MOTION" + }, + { + "command": "CHECKPOINT", + "slice_id": "AXIS-XYZAC-ERROR-RECOVERY" + }, + { + "command": "RECOVER", + "slice_id": "AXIS-XYZAC-ERROR-RECOVERY" + } + ], + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "counts": { + "axis_keyboard": 10, + "axis_menus": 80, + "axis_toolbar": 20, + "blocked_resources": 0, + "direct_sources": 35, + "slices": 11, + "unregistered_slices": 0 + }, + "direct_input_specs": [ + { + "kind": "file", + "path": "doc-rtcp/xyzac-trt-web-wasm-source-parity-contract.md", + "status": "indexed" + }, + { + "kind": "file", + "path": "doc-rtcp/xyzac-trt-web-wasm-implementation-plan.md", + "status": "indexed" + }, + { + "kind": "file", + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "status": "indexed" + }, + { + "kind": "file", + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.xml", + "status": "indexed" + }, + { + "kind": "file", + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins_postgui.hal", + "status": "indexed" + }, + { + "kind": "file", + "path": "linuxcnc/src/emc/usr_intf/axis/scripts/axis.py", + "status": "indexed" + }, + { + "kind": "file", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "status": "indexed" + }, + { + "kind": "file", + "path": "linuxcnc/lib/python/rs274/glcanon.py", + "status": "indexed" + }, + { + "kind": "file", + "path": "linuxcnc/lib/python/gremlin.py", + "status": "indexed" + }, + { + "kind": "file", + "path": "linuxcnc/src/hal/user_comps/vismach/xyzac-trt-gui.py", + "status": "indexed" + }, + { + "kind": "file", + "path": "linuxcnc/src/emc/kinematics/xyzac-trt-kins.c", + "status": "indexed" + }, + { + "kind": "file", + "path": "linuxcnc/src/emc/kinematics/trtfuncs.c", + "status": "indexed" + }, + { + "kind": "file", + "path": "linuxcnc/src/emc/kinematics/switchkins.c", + "status": "indexed" + }, + { + "kind": "file", + "path": "linuxcnc/src/emc/rs274ngc/interp_read.cc", + "status": "indexed" + }, + { + "kind": "file", + "path": "linuxcnc/src/emc/rs274ngc/interp_execute.cc", + "status": "indexed" + }, + { + "kind": "file", + "path": "linuxcnc/src/emc/tp/tp.c", + "status": "indexed" + }, + { + "kind": "file", + "path": "linuxcnc/src/emc/motion/command.c", + "status": "indexed" + }, + { + "kind": "file", + "path": "linuxcnc/src/emc/motion/control.c", + "status": "indexed" + }, + { + "kind": "file", + "path": "context-lock.json", + "status": "indexed" + }, + { + "kind": "directory", + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos", + "resolved_files": [ + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_2.ngc", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_3.ngc", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc" + ], + "status": "indexed" + }, + { + "kind": "directory", + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs", + "resolved_files": [ + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/centering.ngc", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_ac.ngc", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_bc.ngc", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/xyzac_switchkins_sub.ngc", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/xyzbc_switchkins_sub.ngc" + ], + "status": "indexed" + } + ], + "direct_sources": [ + { + "bytes": 18207, + "path": "doc-rtcp/xyzac-trt-web-wasm-source-parity-contract.md", + "role": "direct-input", + "sha256": "43417ceed9a7b6e3446d35de964b767f423b0074fdc64c6f4ec5087a399f0767", + "status": "indexed" + }, + { + "bytes": 25179, + "path": "doc-rtcp/xyzac-trt-web-wasm-implementation-plan.md", + "role": "direct-input", + "sha256": "ac2c2a35b3a22109bf6da811333f47e74edf95c135a40a10ef49337e57f34187", + "status": "indexed" + }, + { + "bytes": 4864, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "role": "direct-input", + "sha256": "f985970db293b70c055e4c41fc316d0c16037b5dc7ce07490e18f554e851f811", + "status": "indexed" + }, + { + "bytes": 928, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.xml", + "role": "direct-input", + "sha256": "84efa01584693ab8f4a9c0730e341a9dbe87d9341472081ee80d59a0bfb90941", + "status": "indexed" + }, + { + "bytes": 538, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins_postgui.hal", + "role": "direct-input", + "sha256": "55e969c22ca9054a818dbedc8ec50bed768d9ab3d8c4bfdfcfc78e912e9271c4", + "status": "indexed" + }, + { + "bytes": 157381, + "path": "linuxcnc/src/emc/usr_intf/axis/scripts/axis.py", + "role": "direct-input", + "sha256": "328c038a1e8fefd952e53c8e398e3fa98b04602351c44318edd1b044e8f63ffa", + "status": "indexed" + }, + { + "bytes": 63423, + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "role": "direct-input", + "sha256": "c9f0b4dc686717b37565f85fb0ab8cc8ded9cfa0028cc0aaaccdbcf808c4c524", + "status": "indexed" + }, + { + "bytes": 76641, + "path": "linuxcnc/lib/python/rs274/glcanon.py", + "role": "direct-input", + "sha256": "0dfb20f1fdc05289894f3aa638357d98e1063fbd53329c723c777399ec7b33b7", + "status": "indexed" + }, + { + "bytes": 23953, + "path": "linuxcnc/lib/python/gremlin.py", + "role": "direct-input", + "sha256": "7559a52300de92ed156fe22267c8fbca975338321cf3afada141360a244756a3", + "status": "indexed" + }, + { + "bytes": 5882, + "path": "linuxcnc/src/hal/user_comps/vismach/xyzac-trt-gui.py", + "role": "direct-input", + "sha256": "307145896092a980251d48dbcb90f39a6dcf1361bc65eb5cbe8cc4e39fd55d8a", + "status": "indexed" + }, + { + "bytes": 1896, + "path": "linuxcnc/src/emc/kinematics/xyzac-trt-kins.c", + "role": "direct-input", + "sha256": "24c633613db9876c2ec246e1519a63d288fd27c68296d89f89f0368105634e69", + "status": "indexed" + }, + { + "bytes": 13363, + "path": "linuxcnc/src/emc/kinematics/trtfuncs.c", + "role": "direct-input", + "sha256": "ced2f9d4732681e2e82153b2f6343eccdf6972222d558d1e277bf1ec0bdc87fd", + "status": "indexed" + }, + { + "bytes": 11718, + "path": "linuxcnc/src/emc/kinematics/switchkins.c", + "role": "direct-input", + "sha256": "4de32a4a147e5ceee5346b9c6bf471dddf5c64ff58afe5044406c50bcd96b7f5", + "status": "indexed" + }, + { + "bytes": 123494, + "path": "linuxcnc/src/emc/rs274ngc/interp_read.cc", + "role": "direct-input", + "sha256": "72473355a0a1cef08bf922ee4d8b89f46210397957f9b1336254223eae66e116", + "status": "indexed" + }, + { + "bytes": 13102, + "path": "linuxcnc/src/emc/rs274ngc/interp_execute.cc", + "role": "direct-input", + "sha256": "a7787d0ae340184f1fe5055ec52dee054a0e67626db6ecfe55418e3e4c99b53c", + "status": "indexed" + }, + { + "bytes": 121641, + "path": "linuxcnc/src/emc/tp/tp.c", + "role": "direct-input", + "sha256": "e0e4be6ef0b0a6c8b5eee32db9307986651938bc72c4e2c44750133b8da4dba8", + "status": "indexed" + }, + { + "bytes": 71866, + "path": "linuxcnc/src/emc/motion/command.c", + "role": "direct-input", + "sha256": "9d138ed5780a11ed037aa238781f4bfb4960a73ee23c0b0abf0724db068b3e3f", + "status": "indexed" + }, + { + "bytes": 84689, + "path": "linuxcnc/src/emc/motion/control.c", + "role": "direct-input", + "sha256": "fa1b14689e2e4493c02d0939f982278366d4c1888da62e172cec030904c82c50", + "status": "indexed" + }, + { + "bytes": 7647, + "path": "context-lock.json", + "role": "direct-input", + "sha256": "bf6651f8d1803f2219d40e61f5e86dcf0821862d087eec2e19f99f593561353e", + "status": "indexed" + }, + { + "bytes": 70847, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc", + "role": "direct-input", + "sha256": "4d4769cbbb47ad7bf82c12bb1545c3854addebebe4642a3f50c8ccf5c560bcda", + "status": "indexed" + }, + { + "bytes": 76616, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc", + "role": "direct-input", + "sha256": "f46a1f485ca85e4e9900b7a9b4f59fed7fc9d7cf27a403e15841b933ab98f0bf", + "status": "indexed" + }, + { + "bytes": 294411, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc", + "role": "direct-input", + "sha256": "e90f0b4b6c43809da94a8170ee1029b5afc3e1bbe9bf2ae66298a8baefad013c", + "status": "indexed" + }, + { + "bytes": 139, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc", + "role": "direct-input", + "sha256": "5afc03d5c1b692edd4154a6d37e5f94d74936a7bd5e82dc9c022f7bc21c7dc17", + "status": "indexed" + }, + { + "bytes": 419, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc", + "role": "direct-input", + "sha256": "3cdffc0481c1d6b0a0a67151a06448c686d4109249ed73438d5ff4e72b9e7267", + "status": "indexed" + }, + { + "bytes": 475, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_2.ngc", + "role": "direct-input", + "sha256": "a0b05e672e7f8b5d9c8f42ac3fd16320f68a67926ae1413d361d60cc508d953f", + "status": "indexed" + }, + { + "bytes": 304, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_3.ngc", + "role": "direct-input", + "sha256": "0e7e3c2fe554f888d3f5ef055390a7153ffa7f9eeedaac116f78832ff7a31cc1", + "status": "indexed" + }, + { + "bytes": 139, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc", + "role": "direct-input", + "sha256": "75db56e24242b68e32a9a7f1943fe240c5f518cc1866ee823ea158f9f87ce9fe", + "status": "indexed" + }, + { + "bytes": 688, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc", + "role": "direct-input", + "sha256": "a0aee1d6b481a979849a17c0a23aa7524f52cbd875c92cbde3b73bf36f91d17b", + "status": "indexed" + }, + { + "bytes": 644, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc", + "role": "direct-input", + "sha256": "160479860b84e55ace49ffceb9594285ee90c521ba5eef916ef47ac8a6b3349d", + "status": "indexed" + }, + { + "bytes": 635, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc", + "role": "direct-input", + "sha256": "41090461a936a63432252d42f277c925f9aa5a0faf0497933910c3b051fcfe4f", + "status": "indexed" + }, + { + "bytes": 1134, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/centering.ngc", + "role": "direct-input", + "sha256": "58cf585aa10480a80fe8ac8f2eab5e877adca51b4b3518b337eab476de01b11c", + "status": "indexed" + }, + { + "bytes": 735, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_ac.ngc", + "role": "direct-input", + "sha256": "06cb755e33dc35d9a179b3c48e4203c8469632ab248d94379b10f2538dd0b54a", + "status": "indexed" + }, + { + "bytes": 735, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_bc.ngc", + "role": "direct-input", + "sha256": "2b8b36bf78d9227bd061083f883c72c7b0b205a8fe6d0a9407203b5375fe89fa", + "status": "indexed" + }, + { + "bytes": 1547, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/xyzac_switchkins_sub.ngc", + "role": "direct-input", + "sha256": "833bf21b8ed0ce600dcf5819234320d85348d906bbba390b62f3704836ea254d", + "status": "indexed" + }, + { + "bytes": 1547, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/xyzbc_switchkins_sub.ngc", + "role": "direct-input", + "sha256": "7265e848d0e123f439208caa88afccdf2803f34770042c778a8797a25d44537a", + "status": "indexed" + } + ], + "error_contract": [ + { + "error": "axis_gate", + "slice_id": "AXIS-XYZAC-SHELL-MENU" + }, + { + "error": "M428_HAL_PIN_MISSING", + "slice_id": "AXIS-XYZAC-M428-M429-M430" + }, + { + "error": "kinematics_singular", + "slice_id": "AXIS-XYZAC-KINEMATICS" + }, + { + "error": "following_error", + "slice_id": "AXIS-XYZAC-TASK-TP-MOTION" + }, + { + "error": "ledger_reconcile_required", + "slice_id": "AXIS-XYZAC-ERROR-RECOVERY" + } + ], + "exact_resources": [ + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "role": "case-entrypoint", + "sha256": "f985970db293b70c055e4c41fc316d0c16037b5dc7ce07490e18f554e851f811", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.xml", + "role": "PYVCP", + "sha256": "84efa01584693ab8f4a9c0730e341a9dbe87d9341472081ee80d59a0bfb90941", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins_postgui.hal", + "role": "POSTGUI_HALFILE", + "sha256": "55e969c22ca9054a818dbedc8ec50bed768d9ab3d8c4bfdfcfc78e912e9271c4", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.tbl", + "role": "TOOL_TABLE", + "sha256": "41cf3c92574be99ecd6ed45e1869158b184620419d5d95a41649d25f15e141ff", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac.var", + "role": "PARAMETER_FILE", + "sha256": "163bbf80485fe2fe12700c1acb4b05eff774df68176d17e4eef5de8a7024c1ae", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc", + "role": "OPEN_FILE", + "sha256": "5afc03d5c1b692edd4154a6d37e5f94d74936a7bd5e82dc9c022f7bc21c7dc17", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc", + "role": "REMAP:M428", + "sha256": "a0aee1d6b481a979849a17c0a23aa7524f52cbd875c92cbde3b73bf36f91d17b", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc", + "role": "REMAP:M429", + "sha256": "160479860b84e55ace49ffceb9594285ee90c521ba5eef916ef47ac8a6b3349d", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc", + "role": "REMAP:M430", + "sha256": "41090461a936a63432252d42f277c925f9aa5a0faf0497933910c3b051fcfe4f", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/xyzac_switchkins_sub.ngc", + "role": "NGCGUI_SUBFILE", + "sha256": "833bf21b8ed0ce600dcf5819234320d85348d906bbba390b62f3704836ea254d", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/centering.ngc", + "role": "NGCGUI_SUBFILE", + "sha256": "58cf585aa10480a80fe8ac8f2eab5e877adca51b4b3518b337eab476de01b11c", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_ac.ngc", + "role": "RTCP-SUBROUTINE", + "sha256": "06cb755e33dc35d9a179b3c48e4203c8469632ab248d94379b10f2538dd0b54a", + "status": "resolved" + }, + { + "path": "linuxcnc/lib/hallib/basic_sim.tcl", + "role": "HALFILE:LIB:basic_sim.tcl", + "sha256": "d9851b0a8861e6d66de745a8ae230d4b38b65c34f8b05bdb6705792d2d4050be", + "status": "resolved" + }, + { + "path": "linuxcnc/linuxcnc.gif", + "role": "INTRO_GRAPHIC", + "sha256": "6c6da4afc3ecdc1b812dd6878318da0120996bd6889b4dd2ddb480b905d9f4b1", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc", + "role": "DEMO_PROGRAM", + "sha256": "4d4769cbbb47ad7bf82c12bb1545c3854addebebe4642a3f50c8ccf5c560bcda", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc", + "role": "DEMO_PROGRAM", + "sha256": "f46a1f485ca85e4e9900b7a9b4f59fed7fc9d7cf27a403e15841b933ab98f0bf", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc", + "role": "DEMO_PROGRAM", + "sha256": "e90f0b4b6c43809da94a8170ee1029b5afc3e1bbe9bf2ae66298a8baefad013c", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc", + "role": "DEMO_PROGRAM", + "sha256": "3cdffc0481c1d6b0a0a67151a06448c686d4109249ed73438d5ff4e72b9e7267", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_2.ngc", + "role": "DEMO_PROGRAM", + "sha256": "a0b05e672e7f8b5d9c8f42ac3fd16320f68a67926ae1413d361d60cc508d953f", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_3.ngc", + "role": "DEMO_PROGRAM", + "sha256": "0e7e3c2fe554f888d3f5ef055390a7153ffa7f9eeedaac116f78832ff7a31cc1", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc", + "role": "DEMO_PROGRAM", + "sha256": "75db56e24242b68e32a9a7f1943fe240c5f518cc1866ee823ea158f9f87ce9fe", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_bc.ngc", + "role": "REMAP_SUBROUTINE", + "sha256": "2b8b36bf78d9227bd061083f883c72c7b0b205a8fe6d0a9407203b5375fe89fa", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/xyzbc_switchkins_sub.ngc", + "role": "REMAP_SUBROUTINE", + "sha256": "7265e848d0e123f439208caa88afccdf2803f34770042c778a8797a25d44537a", + "status": "resolved" + } + ], + "implementation_status": "source_frozen_and_worker_verified", + "next_task": "WASM-00", + "recovery_contract": [ + { + "recovery": "pause_resume", + "slice_id": "AXIS-XYZAC-ERROR-RECOVERY" + }, + { + "recovery": "abort", + "slice_id": "AXIS-XYZAC-ERROR-RECOVERY" + }, + { + "recovery": "checkpoint", + "slice_id": "AXIS-XYZAC-ERROR-RECOVERY" + }, + { + "recovery": "worker_restart_reconcile", + "slice_id": "AXIS-XYZAC-ERROR-RECOVERY" + }, + { + "recovery": "no_duplicate_mcode", + "slice_id": "AXIS-XYZAC-ERROR-RECOVERY" + } + ], + "release_status": "STOP_RELEASE", + "report_sha256": "817531c109c341ccda78b085d2613f35379a716a98f54c9561a118f995b6cd5e", + "runtime_evidence": { + "native": { + "command": [ + "./build-native/sim_xyzac_trace_test" + ], + "output_sha256": "18d2ef9d77f9a7a5bf2fa8d9380c8b04383a58ee2b0258364cba31ec34a168f0", + "returncode": 0, + "trace_sha256": "ca13e8dcb6d2816787a98c7bddc04db552b88f8d8a994b49301973a1bd11245a" + }, + "trace": { + "first_divergent_tick": null, + "levels": [ + "protocol", + "control", + "state", + "canonical", + "recovery" + ], + "native_wasm": { + "first_divergent_tick": null, + "levels": { + "canonical": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "control": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "protocol": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "recovery": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "state": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + } + }, + "status": "verified" + }, + "native_worker": { + "first_divergent_tick": null, + "levels": { + "canonical": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "control": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "protocol": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "recovery": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "state": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + } + }, + "status": "verified" + }, + "positive_divergence_sample": { + "detected": true, + "difference_path": "$[1].active_type", + "first_divergent_tick": 2, + "mutation": "state[1].active_type=99" + } + }, + "wasm": { + "command": [ + "node", + "build-wasm/sim_xyzac_trace_wasm_test.js" + ], + "output_sha256": "18d2ef9d77f9a7a5bf2fa8d9380c8b04383a58ee2b0258364cba31ec34a168f0", + "returncode": 0, + "trace_sha256": "ca13e8dcb6d2816787a98c7bddc04db552b88f8d8a994b49301973a1bd11245a" + }, + "worker": { + "command": [ + "node", + "web/worker/test_xyzac_trace_parity.mjs" + ], + "output_sha256": "773f77181d7fd891a25a9ec6e7c3109f5f6e9b7ddcc3f876e1e973657959558e", + "returncode": 0, + "trace_sha256": "ca13e8dcb6d2816787a98c7bddc04db552b88f8d8a994b49301973a1bd11245a" + } + }, + "schema": "xyzac-trt-source-slice-inventory.v1", + "slices": [ + { + "authoritative_outputs": [ + "task/mode/error snapshot" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "axis-shell", + "error_cases": [ + "SOURCE_BLOCKED: no per-control WASM trace" + ], + "gates": [ + "estop/off/mode gate" + ], + "inputs": [ + "menu event" + ], + "native_commands": [ + "AXIS Tcl command" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "operation ledger reconcile" + ], + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "58-2230", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "sha256": "c9f0b4dc686717b37565f85fb0ab8cc8ded9cfa0028cc0aaaccdbcf808c4c524", + "symbol": "setup_menu_accel" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-MENU-*" + ], + "wasm_commands": [ + "WORKER_COMMAND" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + }, + { + "authoritative_outputs": [ + "axis_state", + "state_hash", + "command_result" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "axis-toolbar", + "error_cases": [ + "SOURCE_BLOCKED: native handler matrix not runtime compared" + ], + "gates": [ + "task_ready", + "mode", + "fault" + ], + "inputs": [ + "toolbar click" + ], + "native_commands": [ + "estop_clicked/task_run/task_pause/task_stop" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "checkpoint/reconcile" + ], + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "490-1775", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "sha256": "c9f0b4dc686717b37565f85fb0ab8cc8ded9cfa0028cc0aaaccdbcf808c4c524", + "symbol": ".toolbar.machine_estop" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-TOOLBAR-*" + ], + "wasm_commands": [ + "ESTOP", + "PROGRAM_RUN", + "PROGRAM_PAUSE", + "PROGRAM_ABORT" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + }, + { + "authoritative_outputs": [ + "authoritative snapshot", + "gate reason" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "axis-keyboard", + "error_cases": [ + "SOURCE_BLOCKED: keyboard Worker evidence pending" + ], + "gates": [ + "focus/input protection", + "manual mode" + ], + "inputs": [ + "keyboard binding" + ], + "native_commands": [ + "jog/task/mode binding" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "pending operation reconcile" + ], + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": "20-2245", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "sha256": "c9f0b4dc686717b37565f85fb0ab8cc8ded9cfa0028cc0aaaccdbcf808c4c524", + "symbol": "bind" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-KEY-*" + ], + "wasm_commands": [ + "JOG_START", + "JOG_STOP", + "PROGRAM_RUN", + "PROGRAM_ABORT" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + }, + { + "authoritative_outputs": [ + "program", + "canonical trajectory", + "task.interp_state", + "state_hash" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "program-mdi", + "error_cases": [ + "SOURCE_BLOCKED: exact case WASM execution not proven" + ], + "gates": [ + "task_idle", + "file_loaded", + "mode_mdi/auto", + "no_fault" + ], + "inputs": [ + "program/MDI text" + ], + "native_commands": [ + "commands.send_mdi_command", + "commands.task_run" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "checkpoint/replay/no-duplicate-side-effect" + ], + "slice_id": "AXIS-XYZAC-PROGRAM-MDI", + "source": { + "lines": "2255-2454", + "path": "linuxcnc/src/emc/usr_intf/axis/scripts/axis.py", + "sha256": "328c038a1e8fefd952e53c8e398e3fa98b04602351c44318edd1b044e8f63ffa", + "symbol": "send_mdi_command" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-PROGRAM", + "AXIS-MDI" + ], + "wasm_commands": [ + "PROGRAM_LOAD", + "PROGRAM_RUN", + "MDI_EXECUTE", + "PROGRAM_PAUSE", + "PROGRAM_RESUME", + "PROGRAM_ABORT" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + }, + { + "authoritative_outputs": [ + "motion.axes", + "motion.joints", + "home_limit", + "state_hash" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "manual-motion", + "error_cases": [ + "SOURCE_BLOCKED: exact XYZAC Worker comparison pending" + ], + "gates": [ + "manual_ok", + "axis_enabled", + "homing_allowed", + "limit/fault" + ], + "inputs": [ + "axis/joint/direction/velocity" + ], + "native_commands": [ + "jog_on", + "jog_off", + "home_joint", + "home_all_joints" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "pause/resume/abort" + ], + "slice_id": "AXIS-XYZAC-JOG-HOME", + "source": { + "lines": "2670-3323", + "path": "linuxcnc/src/emc/usr_intf/axis/scripts/axis.py", + "sha256": "328c038a1e8fefd952e53c8e398e3fa98b04602351c44318edd1b044e8f63ffa", + "symbol": "jog_on" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-JOG", + "AXIS-HOME" + ], + "wasm_commands": [ + "JOG_START", + "JOG_STOP", + "HOME" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + }, + { + "authoritative_outputs": [ + "wasm canonical trajectory", + "visual.pose", + "motion.joints" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "preview-vismach", + "error_cases": [ + "SOURCE_BLOCKED: JS preview forbidden; exact case evidence pending" + ], + "gates": [ + "program_parse_ok", + "canonical_source_present" + ], + "inputs": [ + "parsed program", + "canonical events" + ], + "native_commands": [ + "canon/gremlin/vismach" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "clear visual only; no motion mutation" + ], + "slice_id": "AXIS-XYZAC-PREVIEW-VISUAL", + "source": { + "lines": "426-426", + "path": "linuxcnc/lib/python/rs274/glcanon.py", + "sha256": "0dfb20f1fdc05289894f3aa638357d98e1063fbd53329c723c777399ec7b33b7", + "symbol": "GlCanon" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-PREVIEW", + "AXIS-VISMACH" + ], + "wasm_commands": [ + "PROGRAM_LOAD", + "SNAPSHOT_REQUEST" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + }, + { + "authoritative_outputs": [ + "motion.switchkins-type", + "kinstype_is_0/1/2", + "state_hash" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "pyvcp-hal", + "error_cases": [ + "BLOCKED_HAL: native HAL load not proven in WASM case" + ], + "gates": [ + "interp_idle", + "HAL_PIN_VARS", + "switchkins_net_present" + ], + "inputs": [ + "PyVCP button/HAL net" + ], + "native_commands": [ + "halui.mdi-command-00/01/02" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "ledger reconcile/no duplicate M-code" + ], + "slice_id": "AXIS-XYZAC-PYVCP-SWITCHKINS", + "source": { + "lines": null, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins_postgui.hal", + "sha256": "55e969c22ca9054a818dbedc8ec50bed768d9ab3d8c4bfdfcfc78e912e9271c4", + "symbol": "type0-button/type1-button/type2-button" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-RTCP-TYPE-0", + "AXIS-RTCP-TYPE-1", + "AXIS-RTCP-TYPE-2" + ], + "wasm_commands": [ + "MDI_EXECUTE:M429", + "MDI_EXECUTE:M428", + "MDI_EXECUTE:M430" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + }, + { + "authoritative_outputs": [ + "kinematics.active_type", + "motion.switchkins-type", + "state_hash" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "switchkins-rtcp", + "error_cases": [ + "BLOCKED_STARTUP: native kins startup did not reach verified state" + ], + "gates": [ + "interp_idle", + "HAL_PIN_VARS", + "switchkins_net", + "finite_offsets" + ], + "inputs": [ + "MDI/G-code M428/M429/M430", + "motion.switchkins-type" + ], + "native_commands": [ + "M68 E3 Q{0,1,2}", + "M66 E0 L0" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "checkpoint/reconcile; no blind retry" + ], + "slice_id": "AXIS-XYZAC-M428-M429-M430", + "source": { + "lines": null, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc", + "sha256": "a0aee1d6b481a979849a17c0a23aa7524f52cbd875c92cbde3b73bf36f91d17b", + "symbol": "428remap/429remap/430remap" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-RTCP-M428", + "AXIS-RTCP-M429", + "AXIS-RTCP-M430" + ], + "wasm_commands": [ + "MDI_EXECUTE", + "KINEMATICS_SELECT" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + }, + { + "authoritative_outputs": [ + "pose", + "joints", + "limits", + "state_hash" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "kinematics", + "error_cases": [ + "SOURCE_BLOCKED: exact XYZAC native/WASM trace unavailable" + ], + "gates": [ + "active_type", + "five_joint_mapping", + "finite_offsets", + "limits" + ], + "inputs": [ + "five joints", + "A/C degrees", + "tool/axis offsets" + ], + "native_commands": [ + "kinematicsForward", + "kinematicsInverse" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "checkpoint pose/joint/hash recovery" + ], + "slice_id": "AXIS-XYZAC-KINEMATICS", + "source": { + "lines": "151-195", + "path": "linuxcnc/src/emc/kinematics/trtfuncs.c", + "sha256": "ced2f9d4732681e2e82153b2f6343eccdf6972222d558d1e277bf1ec0bdc87fd", + "symbol": "xyzacKinematicsForward" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-XYZAC-POSE" + ], + "wasm_commands": [ + "KINEMATICS_FORWARD", + "KINEMATICS_INVERSE" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + }, + { + "authoritative_outputs": [ + "task", + "program", + "planner", + "motion", + "simulation_tick", + "state_hash" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "task-tp-motion", + "error_cases": [ + "SOURCE_BLOCKED: no exact case Worker trace attached" + ], + "gates": [ + "ESTOP/OFF/ON/HOME/IDLE/RUNNING/PAUSED/limit/fault" + ], + "inputs": [ + "task/interpreter/TP input" + ], + "native_commands": [ + "task cycle", + "TP queue", + "motion control" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "checkpoint/replay/reconcile" + ], + "slice_id": "AXIS-XYZAC-TASK-TP-MOTION", + "source": { + "lines": "2-2125", + "path": "linuxcnc/src/emc/motion/control.c", + "sha256": "fa1b14689e2e4493c02d0939f982278366d4c1888da62e172cec030904c82c50", + "symbol": "control" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-STATE" + ], + "wasm_commands": [ + "SIM_STEP", + "PROGRAM_RUN", + "PROGRAM_PAUSE", + "PROGRAM_RESUME", + "PROGRAM_ABORT" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + }, + { + "authoritative_outputs": [ + "error", + "ledger", + "checkpoint", + "recovery endpoint", + "state_hash" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "error-recovery", + "error_cases": [ + "SOURCE_BLOCKED: exact case crash/restart evidence pending" + ], + "gates": [ + "operation_id", + "seq", + "ack/result/commit" + ], + "inputs": [ + "command result/error" + ], + "native_commands": [ + "command dispatch/abort" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "reconcile before retry" + ], + "slice_id": "AXIS-XYZAC-ERROR-RECOVERY", + "source": { + "lines": "2-1910", + "path": "linuxcnc/src/emc/motion/command.c", + "sha256": "9d138ed5780a11ed037aa238781f4bfb4960a73ee23c0b0abf0724db068b3e3f", + "symbol": "command" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-DIAGNOSTICS", + "AXIS-RECOVERY" + ], + "wasm_commands": [ + "COMMAND_RESULT", + "ERROR", + "CHECKPOINT", + "RECOVER" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + } + ], + "source_hashes": { + "context-lock.json": "bf6651f8d1803f2219d40e61f5e86dcf0821862d087eec2e19f99f593561353e", + "doc-rtcp/xyzac-trt-web-wasm-implementation-plan.md": "ac2c2a35b3a22109bf6da811333f47e74edf95c135a40a10ef49337e57f34187", + "doc-rtcp/xyzac-trt-web-wasm-source-parity-contract.md": "43417ceed9a7b6e3446d35de964b767f423b0074fdc64c6f4ec5087a399f0767", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc": "4d4769cbbb47ad7bf82c12bb1545c3854addebebe4642a3f50c8ccf5c560bcda", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc": "f46a1f485ca85e4e9900b7a9b4f59fed7fc9d7cf27a403e15841b933ab98f0bf", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc": "e90f0b4b6c43809da94a8170ee1029b5afc3e1bbe9bf2ae66298a8baefad013c", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc": "5afc03d5c1b692edd4154a6d37e5f94d74936a7bd5e82dc9c022f7bc21c7dc17", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc": "3cdffc0481c1d6b0a0a67151a06448c686d4109249ed73438d5ff4e72b9e7267", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_2.ngc": "a0b05e672e7f8b5d9c8f42ac3fd16320f68a67926ae1413d361d60cc508d953f", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_3.ngc": "0e7e3c2fe554f888d3f5ef055390a7153ffa7f9eeedaac116f78832ff7a31cc1", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc": "75db56e24242b68e32a9a7f1943fe240c5f518cc1866ee823ea158f9f87ce9fe", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc": "a0aee1d6b481a979849a17c0a23aa7524f52cbd875c92cbde3b73bf36f91d17b", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc": "160479860b84e55ace49ffceb9594285ee90c521ba5eef916ef47ac8a6b3349d", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc": "41090461a936a63432252d42f277c925f9aa5a0faf0497933910c3b051fcfe4f", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/centering.ngc": "58cf585aa10480a80fe8ac8f2eab5e877adca51b4b3518b337eab476de01b11c", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_ac.ngc": "06cb755e33dc35d9a179b3c48e4203c8469632ab248d94379b10f2538dd0b54a", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_bc.ngc": "2b8b36bf78d9227bd061083f883c72c7b0b205a8fe6d0a9407203b5375fe89fa", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/xyzac_switchkins_sub.ngc": "833bf21b8ed0ce600dcf5819234320d85348d906bbba390b62f3704836ea254d", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/xyzbc_switchkins_sub.ngc": "7265e848d0e123f439208caa88afccdf2803f34770042c778a8797a25d44537a", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins_postgui.hal": "55e969c22ca9054a818dbedc8ec50bed768d9ab3d8c4bfdfcfc78e912e9271c4", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini": "f985970db293b70c055e4c41fc316d0c16037b5dc7ce07490e18f554e851f811", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.xml": "84efa01584693ab8f4a9c0730e341a9dbe87d9341472081ee80d59a0bfb90941", + "linuxcnc/lib/python/gremlin.py": "7559a52300de92ed156fe22267c8fbca975338321cf3afada141360a244756a3", + "linuxcnc/lib/python/rs274/glcanon.py": "0dfb20f1fdc05289894f3aa638357d98e1063fbd53329c723c777399ec7b33b7", + "linuxcnc/share/axis/tcl/axis.tcl": "c9f0b4dc686717b37565f85fb0ab8cc8ded9cfa0028cc0aaaccdbcf808c4c524", + "linuxcnc/src/emc/kinematics/switchkins.c": "4de32a4a147e5ceee5346b9c6bf471dddf5c64ff58afe5044406c50bcd96b7f5", + "linuxcnc/src/emc/kinematics/trtfuncs.c": "ced2f9d4732681e2e82153b2f6343eccdf6972222d558d1e277bf1ec0bdc87fd", + "linuxcnc/src/emc/kinematics/xyzac-trt-kins.c": "24c633613db9876c2ec246e1519a63d288fd27c68296d89f89f0368105634e69", + "linuxcnc/src/emc/motion/command.c": "9d138ed5780a11ed037aa238781f4bfb4960a73ee23c0b0abf0724db068b3e3f", + "linuxcnc/src/emc/motion/control.c": "fa1b14689e2e4493c02d0939f982278366d4c1888da62e172cec030904c82c50", + "linuxcnc/src/emc/rs274ngc/interp_execute.cc": "a7787d0ae340184f1fe5055ec52dee054a0e67626db6ecfe55418e3e4c99b53c", + "linuxcnc/src/emc/rs274ngc/interp_read.cc": "72473355a0a1cef08bf922ee4d8b89f46210397957f9b1336254223eae66e116", + "linuxcnc/src/emc/tp/tp.c": "e0e4be6ef0b0a6c8b5eee32db9307986651938bc72c4e2c44750133b8da4dba8", + "linuxcnc/src/emc/usr_intf/axis/scripts/axis.py": "328c038a1e8fefd952e53c8e398e3fa98b04602351c44318edd1b044e8f63ffa", + "linuxcnc/src/hal/user_comps/vismach/xyzac-trt-gui.py": "307145896092a980251d48dbcb90f39a6dcf1361bc65eb5cbe8cc4e39fd55d8a" + }, + "state_contract": [ + { + "slice_id": "AXIS-XYZAC-TASK-TP-MOTION", + "state": "task.state" + }, + { + "slice_id": "AXIS-XYZAC-TASK-TP-MOTION", + "state": "task.mode" + }, + { + "slice_id": "AXIS-XYZAC-PROGRAM-MDI", + "state": "task.interp_state" + }, + { + "slice_id": "AXIS-XYZAC-PROGRAM-MDI", + "state": "program.current_line" + }, + { + "slice_id": "AXIS-XYZAC-KINEMATICS", + "state": "motion.joints" + }, + { + "slice_id": "AXIS-XYZAC-M428-M429-M430", + "state": "kinematics.active_type" + }, + { + "slice_id": "AXIS-XYZAC-PYVCP-SWITCHKINS", + "state": "motion.switchkins-type" + }, + { + "slice_id": "AXIS-XYZAC-KINEMATICS", + "state": "pose" + }, + { + "slice_id": "AXIS-XYZAC-ERROR-RECOVERY", + "state": "state_hash" + } + ], + "status": "verified", + "task_id": "SRC-00", + "visual_contract": [ + { + "slice_id": "AXIS-XYZAC-PREVIEW-VISUAL", + "visual": "canonical_toolpath" + }, + { + "slice_id": "AXIS-XYZAC-PREVIEW-VISUAL", + "visual": "wasm_pose" + }, + { + "slice_id": "AXIS-XYZAC-PREVIEW-VISUAL", + "visual": "wasm_joints" + }, + { + "slice_id": "AXIS-XYZAC-PREVIEW-VISUAL", + "visual": "vismach_clear" + } + ] +} diff --git a/coverage/xyzac-trt-startup.report.json b/coverage/xyzac-trt-startup.report.json new file mode 100644 index 0000000..a55e11b --- /dev/null +++ b/coverage/xyzac-trt-startup.report.json @@ -0,0 +1,2417 @@ +{ + "accepted_scope_exclusions": [ + "xyzbc", + "3axis", + "other cases" + ], + "candidate_eligible": true, + "case": { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "sha256": "f985970db293b70c055e4c41fc316d0c16037b5dc7ce07490e18f554e851f811" + }, + "command_trace": [ + "CASE_LOAD", + "INI_PARSE", + "RESOURCE_RESOLVE", + "HAL_PREFLIGHT", + "CORE_CREATE", + "TASK_READY" + ], + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "exact_resource_count": 15, + "failure_samples": [], + "fetched_count": 17, + "missing_case": { + "expected": "blocked", + "status": "blocked" + }, + "release_status": "STOP_RELEASE", + "report_sha256": "12cdae5c4547d8f2647da1f4721e147807ba738474adeb60901b3d837e4cb39e", + "schema": "xyzac-trt-startup-rtcp-02.v1", + "scope": "xyzac_only", + "startup": { + "diagnostics": [], + "exact_resources": [ + { + "bytes": 4874, + "data_hash": "fnv1a64:57ea571a25c7d0d3", + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "role": "case_entrypoint", + "status": "resolved" + }, + { + "bytes": 928, + "data_hash": "fnv1a64:4a3f8e801af61339", + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.xml", + "role": "pyvcp", + "status": "resolved" + }, + { + "bytes": 538, + "data_hash": "fnv1a64:fc7ffd0bef1a870b", + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins_postgui.hal", + "role": "postgui_hal", + "status": "resolved" + }, + { + "bytes": 169, + "data_hash": "fnv1a64:5d3821b196b15099", + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.tbl", + "role": "tool_table", + "status": "resolved" + }, + { + "bytes": 0, + "data_hash": "fnv1a64:14650fb0739d0383", + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac.var", + "role": "parameter_file", + "status": "resolved" + }, + { + "bytes": 139, + "data_hash": "fnv1a64:522e219683194ad2", + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc", + "role": "open_file", + "status": "resolved" + }, + { + "bytes": 688, + "data_hash": "fnv1a64:11ef325a672976f4", + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc", + "role": "remap_m428", + "status": "resolved" + }, + { + "bytes": 644, + "data_hash": "fnv1a64:184a5aa32c5d1cac", + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc", + "role": "remap_m429", + "status": "resolved" + }, + { + "bytes": 635, + "data_hash": "fnv1a64:a16ead004f2be3ad", + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc", + "role": "remap_m430", + "status": "resolved" + }, + { + "bytes": 1547, + "data_hash": "fnv1a64:7f532959360c2f63", + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/xyzac_switchkins_sub.ngc", + "role": "ngcgui_subfile", + "status": "resolved" + }, + { + "bytes": 1134, + "data_hash": "fnv1a64:06b02b1b2b5c7649", + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/centering.ngc", + "role": "ngcgui_subfile", + "status": "resolved" + }, + { + "bytes": 735, + "data_hash": "fnv1a64:a67c0938586d1b27", + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_ac.ngc", + "role": "rtcp_subroutine", + "status": "resolved" + }, + { + "bytes": 5882, + "data_hash": "fnv1a64:e67a36fc7eb6f7e0", + "path": "linuxcnc/src/hal/user_comps/vismach/xyzac-trt-gui.py", + "role": "vismach_source", + "status": "resolved" + }, + { + "bytes": 2274, + "data_hash": "fnv1a64:40eab0c5363fb23d", + "path": "linuxcnc/lib/hallib/basic_sim.tcl", + "role": "hal_library", + "status": "resolved" + }, + { + "bytes": 15534, + "data_hash": "fnv1a64:1cceab19ad1eaab6", + "path": "linuxcnc/linuxcnc.gif", + "role": "intro_graphic", + "status": "resolved" + } + ], + "generic_state": "TASK_READY", + "generic_status": "ready", + "hal": { + "blocked_count": 0, + "record_count": 165, + "records": [ + { + "capability": "SIM-ADAPTER", + "code": null, + "command": "loadusr", + "line": 30, + "program": "hal_manualtoolchange", + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked" + }, + { + "code": null, + "command": "loadrt", + "instances": [], + "line": 35, + "module": "xyzac-trt-kins", + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "declared" + }, + { + "code": null, + "command": "loadrt", + "instances": [], + "line": 36, + "module": "motmod", + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "declared" + }, + { + "code": null, + "command": "loadrt", + "instances": [ + "J0_pid", + "J1_pid", + "J2_pid", + "J3_pid", + "J4_pid" + ], + "line": 38, + "module": "pid", + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "declared" + }, + { + "code": null, + "command": "loadrt", + "instances": [ + "J0_mux", + "J1_mux", + "J2_mux", + "J3_mux", + "J4_mux" + ], + "line": 39, + "module": "mux2", + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "declared" + }, + { + "code": null, + "command": "loadrt", + "instances": [ + "J0_vel", + "J0_accel", + "J1_vel", + "J1_accel", + "J2_vel", + "J2_accel", + "J3_vel", + "J3_accel", + "J4_vel", + "J4_accel" + ], + "line": 40, + "module": "ddt", + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "declared" + }, + { + "code": null, + "command": "loadrt", + "instances": [ + "J0_switch", + "J1_switch", + "J2_switch", + "J3_switch", + "J4_switch" + ], + "line": 41, + "module": "sim_home_switch", + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "declared" + }, + { + "code": null, + "command": "loadrt", + "instances": [ + "sim_spindle" + ], + "line": 42, + "module": "sim_spindle", + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "declared" + }, + { + "code": null, + "command": "loadrt", + "instances": [ + "limit_speed" + ], + "line": 43, + "module": "limit2", + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "declared" + }, + { + "code": null, + "command": "loadrt", + "instances": [ + "spindle_mass" + ], + "line": 44, + "module": "lowpass", + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "declared" + }, + { + "code": null, + "command": "loadrt", + "instances": [ + "near_speed" + ], + "line": 45, + "module": "near", + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "declared" + }, + { + "code": null, + "command": "loadrt", + "instances": [ + "rpm_rps" + ], + "line": 46, + "module": "scale", + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "declared" + }, + { + "code": null, + "command": "net", + "line": 51, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J0:acc", + "J0_accel.out" + ] + }, + { + "code": null, + "command": "net", + "line": 52, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J0:enable", + "joint.0.amp-enable-out", + "=>", + "J0_pid.enable" + ] + }, + { + "code": null, + "command": "net", + "line": 53, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J0:homesw", + "J0_switch.home-sw", + "=>", + "joint.0.home-sw-in" + ] + }, + { + "code": null, + "command": "net", + "line": 54, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J0:on-pos", + "J0_pid.output", + "=>", + "J0_mux.in1" + ] + }, + { + "code": null, + "command": "net", + "line": 55, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J0:pos-cmd", + "joint.0.motor-pos-cmd", + "=>", + "J0_pid.command" + ] + }, + { + "code": null, + "command": "net", + "line": 56, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J0:pos-fb", + "J0_mux.out", + "=>", + "J0_mux.in0", + "J0_switch.cur-pos", + "J0_vel.in", + "joint.0.motor-pos-fb" + ] + }, + { + "code": null, + "command": "net", + "line": 57, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J0:vel", + "J0_vel.out", + "=>", + "J0_accel.in" + ] + }, + { + "code": null, + "command": "net", + "line": 58, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J1:acc", + "J1_accel.out" + ] + }, + { + "code": null, + "command": "net", + "line": 59, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J1:enable", + "joint.1.amp-enable-out", + "=>", + "J1_pid.enable" + ] + }, + { + "code": null, + "command": "net", + "line": 60, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J1:homesw", + "J1_switch.home-sw", + "=>", + "joint.1.home-sw-in" + ] + }, + { + "code": null, + "command": "net", + "line": 61, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J1:on-pos", + "J1_pid.output", + "=>", + "J1_mux.in1" + ] + }, + { + "code": null, + "command": "net", + "line": 62, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J1:pos-cmd", + "joint.1.motor-pos-cmd", + "=>", + "J1_pid.command" + ] + }, + { + "code": null, + "command": "net", + "line": 63, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J1:pos-fb", + "J1_mux.out", + "=>", + "J1_mux.in0", + "J1_switch.cur-pos", + "J1_vel.in", + "joint.1.motor-pos-fb" + ] + }, + { + "code": null, + "command": "net", + "line": 64, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J1:vel", + "J1_vel.out", + "=>", + "J1_accel.in" + ] + }, + { + "code": null, + "command": "net", + "line": 65, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J2:acc", + "J2_accel.out" + ] + }, + { + "code": null, + "command": "net", + "line": 66, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J2:enable", + "joint.2.amp-enable-out", + "=>", + "J2_pid.enable" + ] + }, + { + "code": null, + "command": "net", + "line": 67, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J2:homesw", + "J2_switch.home-sw", + "=>", + "joint.2.home-sw-in" + ] + }, + { + "code": null, + "command": "net", + "line": 68, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J2:on-pos", + "J2_pid.output", + "=>", + "J2_mux.in1" + ] + }, + { + "code": null, + "command": "net", + "line": 69, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J2:pos-cmd", + "joint.2.motor-pos-cmd", + "=>", + "J2_pid.command" + ] + }, + { + "code": null, + "command": "net", + "line": 70, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J2:pos-fb", + "J2_mux.out", + "=>", + "J2_mux.in0", + "J2_switch.cur-pos", + "J2_vel.in", + "joint.2.motor-pos-fb" + ] + }, + { + "code": null, + "command": "net", + "line": 71, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J2:vel", + "J2_vel.out", + "=>", + "J2_accel.in" + ] + }, + { + "code": null, + "command": "net", + "line": 72, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J3:acc", + "J3_accel.out" + ] + }, + { + "code": null, + "command": "net", + "line": 73, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J3:enable", + "joint.3.amp-enable-out", + "=>", + "J3_pid.enable" + ] + }, + { + "code": null, + "command": "net", + "line": 74, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J3:homesw", + "J3_switch.home-sw", + "=>", + "joint.3.home-sw-in" + ] + }, + { + "code": null, + "command": "net", + "line": 75, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J3:on-pos", + "J3_pid.output", + "=>", + "J3_mux.in1" + ] + }, + { + "code": null, + "command": "net", + "line": 76, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J3:pos-cmd", + "joint.3.motor-pos-cmd", + "=>", + "J3_pid.command" + ] + }, + { + "code": null, + "command": "net", + "line": 77, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J3:pos-fb", + "J3_mux.out", + "=>", + "J3_mux.in0", + "J3_switch.cur-pos", + "J3_vel.in", + "joint.3.motor-pos-fb" + ] + }, + { + "code": null, + "command": "net", + "line": 78, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J3:vel", + "J3_vel.out", + "=>", + "J3_accel.in" + ] + }, + { + "code": null, + "command": "net", + "line": 79, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J4:acc", + "J4_accel.out" + ] + }, + { + "code": null, + "command": "net", + "line": 80, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J4:enable", + "joint.4.amp-enable-out", + "=>", + "J4_pid.enable" + ] + }, + { + "code": null, + "command": "net", + "line": 81, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J4:homesw", + "J4_switch.home-sw", + "=>", + "joint.4.home-sw-in" + ] + }, + { + "code": null, + "command": "net", + "line": 82, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J4:on-pos", + "J4_pid.output", + "=>", + "J4_mux.in1" + ] + }, + { + "code": null, + "command": "net", + "line": 83, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J4:pos-cmd", + "joint.4.motor-pos-cmd", + "=>", + "J4_pid.command" + ] + }, + { + "code": null, + "command": "net", + "line": 84, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J4:pos-fb", + "J4_mux.out", + "=>", + "J4_mux.in0", + "J4_switch.cur-pos", + "J4_vel.in", + "joint.4.motor-pos-fb" + ] + }, + { + "code": null, + "command": "net", + "line": 85, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J4:vel", + "J4_vel.out", + "=>", + "J4_accel.in" + ] + }, + { + "code": null, + "command": "net", + "line": 86, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "estop:loop", + "iocontrol.0.user-enable-out", + "=>", + "iocontrol.0.emc-enable-in" + ] + }, + { + "code": null, + "command": "net", + "line": 87, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "sample:enable", + "motion.motion-enabled", + "=>", + "J0_mux.sel", + "J1_mux.sel", + "J2_mux.sel", + "J3_mux.sel", + "J4_mux.sel" + ] + }, + { + "code": null, + "command": "net", + "line": 88, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "spindle-at-speed", + "near_speed.out", + "=>", + "spindle.0.at-speed" + ] + }, + { + "code": null, + "command": "net", + "line": 89, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "spindle-index-enable", + "sim_spindle.index-enable", + "<=>", + "spindle.0.index-enable" + ] + }, + { + "code": null, + "command": "net", + "line": 90, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "spindle-orient", + "spindle.0.orient", + "=>", + "spindle.0.is-oriented" + ] + }, + { + "code": null, + "command": "net", + "line": 91, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "spindle-pos", + "sim_spindle.position-fb", + "=>", + "spindle.0.revs" + ] + }, + { + "code": null, + "command": "net", + "line": 92, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "spindle-rpm-filtered", + "spindle_mass.out", + "=>", + "near_speed.in2", + "rpm_rps.in" + ] + }, + { + "code": null, + "command": "net", + "line": 93, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "spindle-rps-filtered", + "rpm_rps.out", + "=>", + "spindle.0.speed-in" + ] + }, + { + "code": null, + "command": "net", + "line": 94, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "spindle-speed-cmd", + "spindle.0.speed-out", + "=>", + "limit_speed.in", + "near_speed.in1" + ] + }, + { + "code": null, + "command": "net", + "line": 95, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "spindle-speed-limited", + "limit_speed.out", + "=>", + "sim_spindle.velocity-cmd", + "spindle_mass.in" + ] + }, + { + "code": null, + "command": "net", + "line": 96, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "tool:change", + "iocontrol.0.tool-change", + "=>", + "hal_manualtoolchange.change" + ] + }, + { + "code": null, + "command": "net", + "line": 97, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "tool:changed", + "hal_manualtoolchange.changed", + "=>", + "iocontrol.0.tool-changed" + ] + }, + { + "code": null, + "command": "net", + "line": 98, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "tool:prep-loop", + "iocontrol.0.tool-prepare", + "=>", + "iocontrol.0.tool-prepared" + ] + }, + { + "code": null, + "command": "net", + "line": 99, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "tool:prep-number", + "iocontrol.0.tool-prep-number", + "=>", + "hal_manualtoolchange.number" + ] + }, + { + "code": null, + "command": "setp", + "line": 101, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J0_accel.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 102, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J0_mux.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 103, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J0_pid.do-pid-calcs.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 104, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J0_switch.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 105, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J0_vel.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 106, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J1_accel.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 107, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J1_mux.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 108, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J1_pid.do-pid-calcs.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 109, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J1_switch.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 110, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J1_vel.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 111, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J2_accel.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 112, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J2_mux.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 113, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J2_pid.do-pid-calcs.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 114, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J2_switch.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 115, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J2_vel.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 116, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J3_accel.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 117, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J3_mux.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 118, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J3_pid.do-pid-calcs.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 119, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J3_switch.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 120, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J3_vel.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 121, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J4_accel.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 122, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J4_mux.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 123, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J4_pid.do-pid-calcs.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 124, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J4_switch.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 125, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J4_vel.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 126, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "limit_speed.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 127, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "motion-command-handler.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 128, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "motion-controller.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 129, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "near_speed.difference", + "10" + ] + }, + { + "code": null, + "command": "setp", + "line": 130, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "near_speed.scale", + "1.1" + ] + }, + { + "code": null, + "command": "setp", + "line": 131, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "near_speed.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 132, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "rpm_rps.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 133, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "servo-thread.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 134, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "sim_spindle.scale", + "0.01666667" + ] + }, + { + "code": null, + "command": "setp", + "line": 135, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "sim_spindle.tmax", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 136, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "spindle_mass.gain", + "0.07" + ] + }, + { + "code": null, + "command": "setp", + "line": 137, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "spindle_mass.tmax", + "0" + ] + }, + { + "code": null, + "command": "addf", + "function": "motion-command-handler", + "line": 139, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "motion-controller", + "line": 140, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J0_pid.do-pid-calcs", + "line": 141, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J1_pid.do-pid-calcs", + "line": 142, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J2_pid.do-pid-calcs", + "line": 143, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J3_pid.do-pid-calcs", + "line": 144, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J4_pid.do-pid-calcs", + "line": 145, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J0_mux", + "line": 146, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J1_mux", + "line": 147, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J2_mux", + "line": 148, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J3_mux", + "line": 149, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J4_mux", + "line": 150, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J0_vel", + "line": 151, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J0_accel", + "line": 152, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J1_vel", + "line": 153, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J1_accel", + "line": 154, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J2_vel", + "line": 155, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J2_accel", + "line": 156, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J3_vel", + "line": 157, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J3_accel", + "line": 158, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J4_vel", + "line": 159, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J4_accel", + "line": 160, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J0_switch", + "line": 161, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J1_switch", + "line": 162, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J2_switch", + "line": 163, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J3_switch", + "line": 164, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "J4_switch", + "line": 165, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "limit_speed", + "line": 166, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "spindle_mass", + "line": 167, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "rpm_rps", + "line": 168, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "near_speed", + "line": 169, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "addf", + "function": "sim_spindle", + "line": 170, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "thread": "servo-thread" + }, + { + "code": null, + "command": "setp", + "line": 173, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J0_pid.FF0", + "1.0" + ] + }, + { + "code": null, + "command": "setp", + "line": 174, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J0_pid.Pgain", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 175, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J0_pid.Dgain", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 176, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J0_pid.Igain", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 177, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J0_pid.FF1", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 178, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J0_pid.FF2", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 179, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J1_pid.FF0", + "1.0" + ] + }, + { + "code": null, + "command": "setp", + "line": 180, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J1_pid.Pgain", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 181, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J1_pid.Dgain", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 182, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J1_pid.Igain", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 183, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J1_pid.FF1", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 184, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J1_pid.FF2", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 185, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J2_pid.FF0", + "1.0" + ] + }, + { + "code": null, + "command": "setp", + "line": 186, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J2_pid.Pgain", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 187, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J2_pid.Dgain", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 188, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J2_pid.Igain", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 189, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J2_pid.FF1", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 190, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J2_pid.FF2", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 191, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J3_pid.FF0", + "1.0" + ] + }, + { + "code": null, + "command": "setp", + "line": 192, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J3_pid.Pgain", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 193, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J3_pid.Dgain", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 194, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J3_pid.Igain", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 195, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J3_pid.FF1", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 196, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J3_pid.FF2", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 197, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J4_pid.FF0", + "1.0" + ] + }, + { + "code": null, + "command": "setp", + "line": 198, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J4_pid.Pgain", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 199, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J4_pid.Dgain", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 200, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J4_pid.Igain", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 201, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J4_pid.FF1", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 202, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "J4_pid.FF2", + "0" + ] + }, + { + "code": null, + "command": "setp", + "line": 203, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "sim_spindle.scale", + "0.01666667" + ] + }, + { + "code": null, + "command": "setp", + "line": 204, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "limit_speed.maxv", + "5000.0" + ] + }, + { + "code": null, + "command": "setp", + "line": 205, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "spindle_mass.gain", + ".07" + ] + }, + { + "code": null, + "command": "setp", + "line": 206, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "near_speed.scale", + "1.1" + ] + }, + { + "code": null, + "command": "setp", + "line": 207, + "resource_id": "hal:linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "schema": "hal-configuration-preflight.v1", + "source": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + "status": "checked", + "tokens": [ + "near_speed.difference", + "10" + ] + } + ], + "schema": "hal-configuration-preflight.v1", + "status": "ready" + }, + "required_sections": { + "DISPLAY": true, + "EMCIO": true, + "HAL": true, + "KINS": true, + "RS274NGC": true, + "TASK": true, + "TRAJ": true + }, + "schema": "xyzac-trt-startup.v1", + "state": "TASK_READY", + "state_hash": "fnv1a64:6406274c7bcabb8a", + "status": "ready", + "transitions": [ + { + "from": null, + "to": "TASK_NEW" + }, + { + "from": "TASK_NEW", + "to": "CONFIG_RESOLVED" + }, + { + "from": "CONFIG_RESOLVED", + "to": "HAL_READY" + }, + { + "from": "HAL_READY", + "to": "RUNTIME_READY" + }, + { + "from": "RUNTIME_READY", + "to": "TASK_READY" + } + ] + }, + "startup_states": [ + "TASK_NEW", + "CONFIG_RESOLVED", + "HAL_READY", + "RUNTIME_READY", + "TASK_READY" + ], + "state_hash": "fnv1a64:fa8432655c60a12a", + "status": "verified", + "task_id": "RTCP-02", + "tests": [ + { + "command": [ + "node", + "web/worker/test_xyzac_startup.mjs" + ], + "output_sha256": "904c4ca4887ece28a01e58251551c0f93886d3d9eb4466c4c02fd21da7341aff", + "returncode": 0, + "status": "verified" + } + ], + "tick_trace": [ + 0 + ] +} diff --git a/coverage/xyzac-trt-threejs.report.json b/coverage/xyzac-trt-threejs.report.json new file mode 100644 index 0000000..ee55794 --- /dev/null +++ b/coverage/xyzac-trt-threejs.report.json @@ -0,0 +1,161 @@ +{ + "authority": "linuxcnc-wasm-worker", + "browser_matrix": { + "canvas_context": "webgl2", + "console_exceptions": 0, + "desktop": { + "canvas_nonblank": true, + "document_width": 1425, + "machine_nodes_in_tool_preview": 0, + "nonzero_pixels": 499671, + "scroll_width": 1425, + "status": "READY", + "toolpath_segments": 3, + "viewport": [ + 1440, + 1000 + ] + }, + "functional_note": "Chromium simulation only; Safari and physical power loss are excluded by scope", + "mobile": { + "canvas_nonblank": true, + "document_width": 390, + "machine_nodes_in_tool_preview": 0, + "nonzero_pixels": 114080, + "scroll_width": 390, + "status": "READY", + "toolpath_segments": 3, + "viewport": [ + 390, + 844 + ] + }, + "preserve_drawing_buffer": true + }, + "candidate_eligible": true, + "case": { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "scope": "xyzac_only" + }, + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "direction": { + "rotate_c": "z+", + "saddle_y": -1, + "spindle_z": -1, + "table_x": -1, + "tilt_a": "x+", + "tool_offset": "z-" + }, + "exclusions": [ + "xyzbc", + "3axis", + "other cases", + "Safari", + "physical power loss", + "host hardware" + ], + "failure_samples": [], + "known_blockers": [], + "machine_groups": [ + "xyzac-machine", + "table-x", + "saddle-y", + "spindle-z", + "tilt-a", + "rotate-c", + "tool-offset", + "xyzac-toolpath", + "xyzac-live-toolpath" + ], + "outputs": [ + { + "path": "web/react/src/XyzacMachineView.tsx", + "sha256": "fd3804b8b86d6630054755c00f35828591dec5093f86ea080c9d6fb5db7aa05d" + }, + { + "path": "web/react/src/XyzacToolPreview.tsx", + "sha256": "caca009f96336847c8d9b8d5823c3d7de86ed77c37cae2fe9f5f3e4d30132d57" + }, + { + "path": "web/react/src/xyzac-visual-adapter.ts", + "sha256": "2e67bf4522ff87648d0b7de1f6fc447d51e780eed66c299d7f4bc3c35d7b33f8" + }, + { + "path": "web/react/src/test_xyzac_threejs.mjs", + "sha256": "840f191d5243016e6ecba4404f2950a067d63f9c1f280a2c1655f30bf021324b" + }, + { + "path": "web/react/src/test_xyzac_tool_preview.mjs", + "sha256": "99f60e050a3ba90b3feb2922b007a49cb4a9e2f88610a0f55f1b6a9c8f07cdbd" + } + ], + "projection": { + "active_segment": 7, + "clear_visual_nonmutating": true, + "state_hash": "fnv1a64:xyzac-authoritative", + "tick": 42 + }, + "release_status": "STOP_RELEASE", + "report_sha256": "fd1296fc1819bee5371708e869b0547dd64bd91f98eab1d12f1ddce043450f6a", + "schema": "xyzac-trt-threejs-report.v1", + "status": "verified", + "task_id": "RTCP-10", + "tests": [ + { + "command": [ + "node", + "--experimental-strip-types", + "web/react/src/test_xyzac_threejs.mjs" + ], + "output_sha256": "2760c09251a854eec84d854cfb8847244bf21653e7d096fa625d4fe2970924ee", + "returncode": 0 + }, + { + "command": [ + "node", + "--experimental-strip-types", + "web/react/src/test_xyzac_tool_preview.mjs" + ], + "output_sha256": "26a7f3645c9ca6212fc5664e870eee5dff2a146bb71a1d14de6845e982cddf92", + "returncode": 0 + }, + { + "command": [ + "npm", + "run", + "typecheck" + ], + "output_sha256": "08fb3e3d0d9396a56f8720eb15d9f6920f8a30c2dad7b0b6672ac446801f27e3", + "returncode": 0 + } + ], + "tool_preview": { + "active_segment": 3, + "canonical_toolpath_segments": 1, + "joints": [ + 11, + -4, + 19, + 31, + 44 + ], + "machine_scene_nodes": 0, + "schema": "xyzac-tool-preview-rtcp-10b.v1", + "source": "linuxcnc-wasm-worker", + "state_hash": "fnv1a64:tool-preview", + "status": "verified", + "tick": 12, + "tool_pose": { + "a": 31, + "b": 0, + "c": 44, + "u": 0, + "v": 0, + "w": 0, + "x": 11, + "y": -4, + "z": 19 + } + }, + "visual_source": "authoritative panel_snapshot.visual + panel_snapshot.kinematics; main preview is tool-only" +} diff --git a/coverage/xyzac-trt-tool-preview.report.json b/coverage/xyzac-trt-tool-preview.report.json new file mode 100644 index 0000000..bfc9fe2 --- /dev/null +++ b/coverage/xyzac-trt-tool-preview.report.json @@ -0,0 +1,436 @@ +{ + "authority": "linuxcnc-wasm-worker", + "browser_matrix": { + "desktop": { + "canvas_nonblank": true, + "document_width": 1425, + "nonzero_pixels": 499671, + "sample_points": 438, + "scroll_width": 1425, + "status": "READY", + "toolpath_segments": 29, + "viewport": [ + 1440, + 1000 + ] + }, + "machine_nodes_in_tool_preview": 0, + "mobile": { + "canvas_nonblank": true, + "document_width": 390, + "nonzero_pixels": 114080, + "sample_points": 438, + "scroll_width": 390, + "status": "READY", + "toolpath_segments": 29, + "viewport": [ + 390, + 844 + ] + } + }, + "candidate_eligible": true, + "canonical_source": "panel_snapshot.visual.toolpath", + "case": { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "scope": "xyzac_only" + }, + "exclusions": [ + "xyzbc", + "3axis", + "other cases", + "Safari", + "physical power loss", + "host hardware" + ], + "failure_samples": [], + "known_blockers": [], + "machine_preview": { + "embedded": false, + "separate_component": "web/react/src/XyzacMachineView.tsx" + }, + "origin_coordinate_system": { + "axes": [ + "X", + "Y", + "Z" + ], + "labels": true, + "origin": [ + 0, + 0, + 0 + ], + "source": "xyzac-origin-coordinate-system" + }, + "outputs": [ + { + "path": "web/react/src/XyzacToolPreview.tsx", + "sha256": "caca009f96336847c8d9b8d5823c3d7de86ed77c37cae2fe9f5f3e4d30132d57" + }, + { + "path": "web/react/src/xyzac-visual-adapter.ts", + "sha256": "2e67bf4522ff87648d0b7de1f6fc447d51e780eed66c299d7f4bc3c35d7b33f8" + }, + { + "path": "web/worker/sim-session.mjs", + "sha256": "7ce91549f0f3a06ff77db9ee281fd9544848f6e41e08f9da302ee2e7827194e3" + }, + { + "path": "web/worker/test_xyzac_exact_preview.mjs", + "sha256": "dc5cc312aab46003e12a4bfc26d695b05d78843e61808c550cb4a5925338687b" + }, + { + "path": "web/worker/wasm-program-runtime.mjs", + "sha256": "60da7b953ac4ee2659f2b05c6bb93b58c8d0c2c4b56363f6a93e44aab7aebb02" + }, + { + "path": "web/worker/wasm-motion-queue.mjs", + "sha256": "85b53bf7a31b9b1f1e7e76dad4bf29aabb36defcf6344d34bbb192c157a80764" + }, + { + "path": "web/worker/wasm-xyzac-io.mjs", + "sha256": "fdb92e8819e38010aa7a1b8f5f58473a930644fbfeba3d7d5a5c23e075ee92ca" + }, + { + "path": "web/worker/wasm-xyzac-device-io.mjs", + "sha256": "1d813d59048afb6854b6fd7783dc86f65bf37ccc46f0d4f592b56cbe044211a5" + }, + { + "path": "web/worker/test_xyzac_machine_sequence.mjs", + "sha256": "9dcd89d54596fe4b339d5aca4e028a0c44e173a8e646f1254defc706bd3fcc96" + }, + { + "path": "web/react/src/App.tsx", + "sha256": "8cbec29f00c44e18a01ac92734e4f8b64764cc04db4cec48ce9c28693bd2bbef" + }, + { + "path": "web/react/src/styles.css", + "sha256": "c39b6848f0c8d176991acb633206697bbc01bd8dbf28cba69afe605b1d7e6cb9" + }, + { + "path": "wasm-core/src/sim_task.c", + "sha256": "06aa4ba015d863e1749cfe11877a82507fd6aff2c6922a114f30f6c8871b0b5b" + }, + { + "path": "wasm-core/src/sim_program.c", + "sha256": "1ab97bbe8750d678b8cffebbad9cad44926285b627858cf2b1aad22da3e0457f" + }, + { + "path": "wasm-core/src/sim_posemath.c", + "sha256": "2e63d8cc2bf4275a89238b2622b41dcd8dfabfe6d24ef5918628083a4f4f5216" + } + ], + "preview_mode": "tool_only", + "projection": { + "exact_program": { + "arc_count": 4, + "arc_turn": -3, + "case": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "clear_visual_only": true, + "helix_details": [ + { + "axial_delta": -5, + "center": { + "x": 20, + "y": 20, + "z": 10 + }, + "end": { + "a": 20, + "b": 0, + "c": 45, + "u": 0, + "v": 0, + "w": 0, + "x": 10, + "y": 20, + "z": 5 + }, + "kind": "helix", + "radius": 10, + "samples": 97, + "samples_source": "linuxcnc-wasm-sim_posemath_segment_point", + "source_line": 67, + "start": { + "a": 20, + "b": 0, + "c": 45, + "u": 0, + "v": 0, + "w": 0, + "x": 10, + "y": 20, + "z": 10 + }, + "turns": 3 + }, + { + "axial_delta": -5, + "center": { + "x": -20, + "y": 20, + "z": 10 + }, + "end": { + "a": 20, + "b": 0, + "c": 45, + "u": 0, + "v": 0, + "w": 0, + "x": -30, + "y": 20, + "z": 5 + }, + "kind": "helix", + "radius": 10, + "samples": 97, + "samples_source": "linuxcnc-wasm-sim_posemath_segment_point", + "source_line": 67, + "start": { + "a": 20, + "b": 0, + "c": 45, + "u": 0, + "v": 0, + "w": 0, + "x": -30, + "y": 20, + "z": 10 + }, + "turns": 3 + }, + { + "axial_delta": -5, + "center": { + "x": -20, + "y": -20, + "z": 10 + }, + "end": { + "a": 20, + "b": 0, + "c": 45, + "u": 0, + "v": 0, + "w": 0, + "x": -30, + "y": -20, + "z": 5 + }, + "kind": "helix", + "radius": 10, + "samples": 97, + "samples_source": "linuxcnc-wasm-sim_posemath_segment_point", + "source_line": 67, + "start": { + "a": 20, + "b": 0, + "c": 45, + "u": 0, + "v": 0, + "w": 0, + "x": -30, + "y": -20, + "z": 10 + }, + "turns": 3 + }, + { + "axial_delta": -5, + "center": { + "x": 20, + "y": -20, + "z": 10 + }, + "end": { + "a": 20, + "b": 0, + "c": 45, + "u": 0, + "v": 0, + "w": 0, + "x": 10, + "y": -20, + "z": 5 + }, + "kind": "helix", + "radius": 10, + "samples": 97, + "samples_source": "linuxcnc-wasm-sim_posemath_segment_point", + "source_line": 67, + "start": { + "a": 20, + "b": 0, + "c": 45, + "u": 0, + "v": 0, + "w": 0, + "x": 10, + "y": -20, + "z": 10 + }, + "turns": 3 + } + ], + "helix_validation": { + "radius_mm": 10, + "sample_points_per_helix": 97, + "samples_source": "linuxcnc-wasm-sim_posemath_segment_point", + "turns_per_helix": 3, + "z_end": 5, + "z_start": 10 + }, + "motion_mode_source": "linuxcnc-wasm-sim_program_canonical", + "program_path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc", + "rapid_count": 25, + "restart_visual_segments": 29, + "schema": "xyzac-exact-tool-preview.v1", + "segment_count": 29, + "source_hash": "fnv1a64:522e219683194ad2", + "state_hash": "fnv1a64:c7e53444cce4a142", + "status": "verified", + "visual_segments": 29 + }, + "machine_sequence": { + "active_progress": 0.09848857801796111, + "active_segment_id": 4, + "authority": { + "home_limit": "wasm_home_limit", + "io": "wasm_io", + "motion": "wasm", + "program": "linuxcnc-wasm-sim_program", + "visual": "wasm_canonical_motion" + }, + "case": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "current_line_after_step": 68, + "estop_queue_depth": 0, + "full_run": { + "cycles": 8000, + "final_switchkins_type": 0, + "program_status": "completed", + "queue_depth": 0, + "task_state": "STOPPED" + }, + "home_joint_count": 5, + "js_motion_unchanged": true, + "live_axis_sample": { + "a": 1.9697715603592223, + "b": 0, + "c": 4.43198601080825, + "u": 0, + "v": 0, + "w": 0, + "x": 10, + "y": 20, + "z": 10 + }, + "live_joints": [ + 8.42458503579587, + 20.712530389342145, + 10.024505737045653, + 1.9697715603592223, + 4.43198601080825 + ], + "rtcp_active_type": 1, + "rtcp_joint_pose_delta": [ + -1.5754149642041302, + 0.7125303893421453, + 0.02450573704565251, + 0, + 0 + ], + "schema": "xyzac-machine-sequence.v1", + "sequence": [ + "ESTOP", + "ESTOP_RELEASE", + "IO_RECOVER", + "POWER", + "HOME_ALL", + "PROGRAM_RUN", + "SIM_STEP" + ], + "state_hash": "fnv1a64:c8f6326c97e651f9", + "status": "verified" + }, + "static": { + "active_segment": 3, + "canonical_toolpath_segments": 1, + "joints": [ + 11, + -4, + 19, + 31, + 44 + ], + "machine_scene_nodes": 0, + "schema": "xyzac-tool-preview-rtcp-10b.v1", + "source": "linuxcnc-wasm-worker", + "state_hash": "fnv1a64:tool-preview", + "status": "verified", + "tick": 12, + "tool_pose": { + "a": 31, + "b": 0, + "c": 44, + "u": 0, + "v": 0, + "w": 0, + "x": 11, + "y": -4, + "z": 19 + } + } + }, + "release_status": "STOP_RELEASE", + "report_sha256": "94b18227ec72689934629a5b428cf6a9f16500d30b200d4b36a10d03c84c56b9", + "schema": "xyzac-trt-tool-preview-report.v1", + "status": "verified", + "task_id": "RTCP-10-TOOL-PREVIEW", + "tests": [ + { + "command": [ + "node", + "--experimental-strip-types", + "web/react/src/test_xyzac_tool_preview.mjs" + ], + "output_sha256": "26a7f3645c9ca6212fc5664e870eee5dff2a146bb71a1d14de6845e982cddf92", + "returncode": 0 + }, + { + "command": [ + "node", + "web/worker/test_xyzac_exact_preview.mjs" + ], + "output_sha256": "60cec025efd2f29de45fb6139f0929f329a505bd331212e6b01ab5fbb5f8fca8", + "returncode": 0 + }, + { + "command": [ + "node", + "web/worker/test_xyzac_machine_sequence.mjs" + ], + "output_sha256": "2a72e723603080bb3eff8169b8be5352fa46d6b0c8ae04dbeeb2e5e1371e1c47", + "returncode": 0 + } + ], + "three_d_controller": { + "buttons": [ + "zoomIn", + "zoomOut", + "panLeft", + "panRight", + "panUp", + "panDown", + "reset" + ], + "library": "three/examples/jsm/controls/OrbitControls", + "pointer_controls": { + "left_drag": "rotate", + "right_or_middle_drag": "pan", + "wheel": "zoom" + }, + "source": "web/react/src/XyzacToolPreview.tsx" + } +} diff --git a/coverage/xyzac-trt-trace-parity.report.json b/coverage/xyzac-trt-trace-parity.report.json new file mode 100644 index 0000000..8d55065 --- /dev/null +++ b/coverage/xyzac-trt-trace-parity.report.json @@ -0,0 +1,165 @@ +{ + "builds": [ + { + "command": [ + "cmake", + "--build", + "build-native", + "--target", + "sim_xyzac_trace_test" + ], + "output_sha256": "8c35b1682f73592d30612d7b0fabdb384fcfff35cb5a076cb48b85b1368aa794", + "returncode": 0 + }, + { + "command": [ + "cmake", + "--build", + "build-wasm", + "--target", + "sim_xyzac_trace_wasm_test" + ], + "output_sha256": "8c35b1682f73592d30612d7b0fabdb384fcfff35cb5a076cb48b85b1368aa794", + "returncode": 0 + } + ], + "candidate_eligible": true, + "case": { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "scope": "xyzac_only" + }, + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "exclusions": [ + "xyzbc", + "3axis", + "other cases", + "Safari", + "physical power loss", + "host hardware" + ], + "failure_samples": [], + "first_divergent_tick": null, + "inputs": [ + { + "path": "wasm-core/tests/sim_xyzac_trace_test.c", + "sha256": "0a3d5f748d9f69f4212c3a1cdd65fe2986c253442c4de2de78de2e5a5635ff08" + }, + { + "path": "web/worker/test_xyzac_trace_parity.mjs", + "sha256": "f5c6a7cd3e8b7f72bb1b25b5c368c0e52d494b9c811022d34435e668612ec4ce" + }, + { + "path": "coverage/xyzac-trt-rtcp.report.json", + "sha256": "b1562d6d2c9cd5144c7c8c9b334bd8bf67919ea7297f103ec67cb32773608d08" + } + ], + "known_blockers": [], + "levels": [ + "protocol", + "control", + "state", + "canonical", + "recovery" + ], + "native_wasm": { + "first_divergent_tick": null, + "levels": { + "canonical": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "control": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "protocol": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "recovery": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "state": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + } + }, + "status": "verified" + }, + "native_worker": { + "first_divergent_tick": null, + "levels": { + "canonical": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "control": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "protocol": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "recovery": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + }, + "state": { + "difference_path": null, + "first_divergent_tick": null, + "status": "verified" + } + }, + "status": "verified" + }, + "positive_divergence_sample": { + "detected": true, + "difference_path": "$[1].active_type", + "first_divergent_tick": 2, + "mutation": "state[1].active_type=99" + }, + "release_status": "STOP_RELEASE", + "report_sha256": "39c63aa9af38fd98e49fd68ec2401ee8715fcafef98d47c070a47ab6f6dc0a48", + "schema": "xyzac-trt-trace-parity-report.v1", + "status": "verified", + "task_id": "PARITY-00", + "traces": { + "native": { + "command": [ + "./build-native/sim_xyzac_trace_test" + ], + "output_sha256": "18d2ef9d77f9a7a5bf2fa8d9380c8b04383a58ee2b0258364cba31ec34a168f0", + "returncode": 0, + "trace_sha256": "ca13e8dcb6d2816787a98c7bddc04db552b88f8d8a994b49301973a1bd11245a" + }, + "wasm": { + "command": [ + "node", + "build-wasm/sim_xyzac_trace_wasm_test.js" + ], + "output_sha256": "18d2ef9d77f9a7a5bf2fa8d9380c8b04383a58ee2b0258364cba31ec34a168f0", + "returncode": 0, + "trace_sha256": "ca13e8dcb6d2816787a98c7bddc04db552b88f8d8a994b49301973a1bd11245a" + }, + "worker": { + "command": [ + "node", + "web/worker/test_xyzac_trace_parity.mjs" + ], + "output_sha256": "773f77181d7fd891a25a9ec6e7c3109f5f6e9b7ddcc3f876e1e973657959558e", + "returncode": 0, + "trace_sha256": "ca13e8dcb6d2816787a98c7bddc04db552b88f8d8a994b49301973a1bd11245a" + } + } +} diff --git a/coverage/xyzac-trt-wasm-authority-audit.report.json b/coverage/xyzac-trt-wasm-authority-audit.report.json new file mode 100644 index 0000000..113b02c --- /dev/null +++ b/coverage/xyzac-trt-wasm-authority-audit.report.json @@ -0,0 +1,2257 @@ +{ + "accepted_scope_exclusions": [ + { + "code": "PHYSICAL_POWER_LOSS_OUTSIDE_BROWSER", + "detail": "this task validates deterministic browser/WASM simulation only; physical power-loss semantics are outside scope", + "status": "accepted_scope_exclusion" + }, + { + "code": "SAFARI_NOT_REQUIRED", + "detail": "Safari is explicitly excluded from this project's browser matrix", + "status": "accepted_scope_exclusion" + } + ], + "authority_matrix": { + "hal_io_tool_probe": { + "source": "wasm_hal+wasm_io+wasm_device_io", + "status": "verified", + "test": "web/worker/test_xyzac_trt_io_authority.mjs" + }, + "kinematics_rtcp_switchkins": { + "source": "wasm_xyzac_kinematics", + "status": "verified", + "test": "web/worker/test_xyzac_trt_case.mjs" + }, + "motion_jog_home_limit": { + "source": "wasm_motion_queue+wasm_home_limit", + "status": "verified", + "test": "web/worker/test_xyzac_trt_wasm_program_authority.mjs" + }, + "program_interpreter": { + "source": "linuxcnc-wasm-sim_program", + "status": "verified", + "test": "web/worker/test_xyzac_trt_wasm_program_authority.mjs" + }, + "task_state": { + "source": "wasm_task_canonical", + "status": "verified", + "test": "web/worker/test_xyzac_trt_wasm_program_authority.mjs" + } + }, + "authority_owner": "linuxcnc-wasm-worker", + "blockers": [], + "browser_evidence": [ + { + "browser": "chromium", + "commit_seq": 1, + "content_hash": "fnv1a64:ce6a222e5fe010b4", + "mode": "process_kill_profile_reopen", + "process_killed": true, + "source": "scripts/test_browser_opfs_crash_s6_07.mjs", + "status": "verified", + "version": "151.0.7922.169" + }, + { + "browser": "firefox", + "commit_seq": 1, + "content_hash": "fnv1a64:ce6a222e5fe010b4", + "mode": "dedicated_worker_sync_access_handle", + "source": "scripts/test_browser_opfs_firefox_s6_05.mjs", + "status": "verified", + "version": "154.0" + } + ], + "candidate_eligible": true, + "case": { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "sha256": "f985970db293b70c055e4c41fc316d0c16037b5dc7ce07490e18f554e851f811", + "source_slice_report_sha256": "817531c109c341ccda78b085d2613f35379a716a98f54c9561a118f995b6cd5e" + }, + "checks": { + "context_match": { + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "status": "verified" + }, + "js_authority_boundary": { + "compatibility_scope": "non_selected_cases", + "finding_count": 3, + "selected_case_authority": "wasm_only", + "status": "verified" + }, + "react_no_direct_opfs_writer": { + "matches": [], + "status": "verified" + }, + "react_no_direct_wasm_pointer": { + "matches": [], + "status": "verified" + }, + "release_stop": { + "release_status": "STOP_RELEASE", + "status": "verified" + }, + "report_self_hash": { + "status": "verified" + }, + "source_slice_dependency": { + "report_sha256": "817531c109c341ccda78b085d2613f35379a716a98f54c9561a118f995b6cd5e", + "status": "verified" + }, + "wasm_worker_bootstrap": { + "status": "verified" + }, + "wasm_xyzac_kinematics_source": { + "status": "verified" + }, + "worker_trace": { + "first_divergent_tick": null, + "state_hash": "fnv1a64:e862c9e59d9ffd8c", + "status": "verified" + } + }, + "command_trace": [ + "HELLO", + "SESSION_ATTACH", + "LOAD_WORKSPACE", + "MDI_EXECUTE:M429", + "MDI_EXECUTE:M428", + "MDI_EXECUTE:M430" + ], + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "first_divergent_tick": null, + "js_authority_call_count": 0, + "js_authority_findings": [ + { + "code": "JS_PROGRAM_CONTROL_FLOW", + "observed": "ProgramRunner executes control directives and schedules interpreter blocks from JS before WASM motion enqueue", + "required_action": "retain ProgramRunner only for non-selected compatibility cases; selected XYZAC routes through sim_program", + "source_slice": "AXIS-XYZAC-PROGRAM-MDI", + "sources": [ + { + "lines": "107-739", + "path": "web/worker/sim-session.mjs", + "role": "session-authority-routing", + "sha256": "7ce91549f0f3a06ff77db9ee281fd9544848f6e41e08f9da302ee2e7827194e3", + "status": "resolved", + "symbol": "new ProgramRunner" + }, + { + "lines": "372-599", + "path": "web/worker/program-runner.mjs", + "role": "js-program-control-flow", + "sha256": "6b7dc1f8f857f6752d142212824c9598ad14017f1e706b0a4406e6e6976051f6", + "status": "resolved", + "symbol": "executeNext" + } + ], + "status": "resolved_selected_case" + }, + { + "code": "JS_MOTION_STATE_MIRROR", + "observed": "MotionState owns HOME/JOG/limit/following-error/ESTOP transitions and is projected beside WASM state", + "required_action": "retain MotionState only for non-selected compatibility cases; selected XYZAC routes through WASM motion/home-limit", + "source_slice": "AXIS-XYZAC-JOG-HOME", + "sources": [ + { + "lines": "13-13", + "path": "web/worker/motion-state.mjs", + "role": "js-motion-state-mirror", + "sha256": "7acdbd55ca467ae9ada8d4dbeebf290b6d660c3c1a8eb86d750254464dc47c8e", + "status": "resolved", + "symbol": "export class MotionState" + }, + { + "lines": "107-739", + "path": "web/worker/sim-session.mjs", + "role": "session-authority-routing", + "sha256": "7ce91549f0f3a06ff77db9ee281fd9544848f6e41e08f9da302ee2e7827194e3", + "status": "resolved", + "symbol": "new ProgramRunner" + } + ], + "status": "resolved_selected_case" + }, + { + "code": "JS_COMPATIBILITY_PLANNER_PRESENT", + "observed": "AuthoritativeRuntime is constructed for every session and remains serializable even when selected XYZAC motion uses WASM", + "required_action": "planner is omitted from selected XYZAC snapshots; compatibility runtime remains non-selected only", + "source_slice": "AXIS-XYZAC-TASK-TP-MOTION", + "sources": [ + { + "lines": "68-68", + "path": "web/worker/authoritative-runtime.mjs", + "role": "js-compatibility-planner", + "sha256": "c2bdd03de958ffda38553ec6dbddb4b1f5c08b2cb636ba02f25f2b76bdd61604", + "status": "resolved", + "symbol": "export class AuthoritativeRuntime" + }, + { + "lines": "107-739", + "path": "web/worker/sim-session.mjs", + "role": "session-authority-routing", + "sha256": "7ce91549f0f3a06ff77db9ee281fd9544848f6e41e08f9da302ee2e7827194e3", + "status": "resolved", + "symbol": "new ProgramRunner" + } + ], + "status": "resolved_selected_case" + } + ], + "next_task": "RTCP-01", + "normal_boundary_error_recovery": { + "boundary": "compatibility JS classes are excluded from selected XYZAC authority; physical power-loss and Safari are accepted scope exclusions", + "error": [], + "normal": "selected XYZAC Worker startup and M428/M429/M430 trace verified", + "recovery": "Chromium SIGKILL/profile-reopen, corruption detection and Firefox OPFS round-trip are verified" + }, + "release_status": "STOP_RELEASE", + "report_sha256": "f73755bf9d695ee02de03bae8ab65cfc55e593b2758634420e83b6d3bef227e2", + "scans": { + "js_gcode_matches": [ + { + "line": 95, + "path": "web/worker/program-runner.mjs", + "text": "function controlDirective(line) {" + }, + { + "line": 101, + "path": "web/worker/program-runner.mjs", + "text": "function motionControlDirective(line) {" + }, + { + "line": 227, + "path": "web/worker/program-runner.mjs", + "text": "const directive = controlDirective(line);" + }, + { + "line": 372, + "path": "web/worker/program-runner.mjs", + "text": "result = this.executeNext(true);" + }, + { + "line": 425, + "path": "web/worker/program-runner.mjs", + "text": "const result = this.executeNext(true);" + }, + { + "line": 435, + "path": "web/worker/program-runner.mjs", + "text": "return this.executeNext(false);" + }, + { + "line": 438, + "path": "web/worker/program-runner.mjs", + "text": "executeBlock(block) {" + }, + { + "line": 442, + "path": "web/worker/program-runner.mjs", + "text": "const motionControl = motionControlDirective(block);" + }, + { + "line": 454, + "path": "web/worker/program-runner.mjs", + "text": "const result = call(this.core, \"sim_interpreter_execute\", \"number\", [\"number\", \"number\", \"number\"], [this.interpreter, this.blockBuffer, bytes.length]);" + }, + { + "line": 469, + "path": "web/worker/program-runner.mjs", + "text": "for (let index = 0; index < cycles && this.status === \"running\"; index += 1) results.push(this.executeNext(false));" + }, + { + "line": 599, + "path": "web/worker/program-runner.mjs", + "text": "executeNext(seeking) {" + }, + { + "line": 619, + "path": "web/worker/program-runner.mjs", + "text": "const motionControl = motionControlDirective(sourceLine);" + }, + { + "line": 629, + "path": "web/worker/program-runner.mjs", + "text": "const result = call(this.core, \"sim_interpreter_execute\", \"number\", [\"number\", \"number\", \"number\"], [this.interpreter, this.blockBuffer, bytes.length]);" + }, + { + "line": 1405, + "path": "web/worker/sim-session.mjs", + "text": "const result = this.xyzacProgram.executeBlock(block);" + }, + { + "line": 1424, + "path": "web/worker/sim-session.mjs", + "text": "const result = this.program.executeBlock(block);" + }, + { + "line": 188, + "path": "web/worker/wasm-program-runtime.mjs", + "text": "executeBlock(block) {" + } + ], + "opfs_writer_matches": [ + { + "line": 1, + "path": "web/react/dist/assets/sim-worker-entry-DPpmZmXb.js", + "text": "(function(){var e=(()=>{var e=self.location.href;return(function(t){t||={};var t=t===void 0?{}:t,n,r;t.ready=new Promise(function(e,t){n=e,r=t});var i=Object.assign({},t),a=[],o=typeof window==`object`,s=typeof importScripts==`function`;typ" + }, + { + "line": 36, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs", + "text": "builder.write(intToChar[clamped]);" + }, + { + "line": 143, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs", + "text": "if (index > 0) writer.write(comma);" + }, + { + "line": 161, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs", + "text": "writer.write(comma);" + }, + { + "line": 277, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs", + "text": "writer.write(comma);" + }, + { + "line": 330, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs", + "text": "writer.write(comma);" + }, + { + "line": 337, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs", + "text": "writer.write(semicolon);" + }, + { + "line": 398, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs", + "text": "if (i > 0) writer.write(semicolon);" + }, + { + "line": 403, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs", + "text": "if (j > 0) writer.write(comma);" + }, + { + "line": 84, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js", + "text": "builder.write(intToChar[clamped]);" + }, + { + "line": 191, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js", + "text": "if (index > 0) writer.write(comma);" + }, + { + "line": 209, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js", + "text": "writer.write(comma);" + }, + { + "line": 325, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js", + "text": "writer.write(comma);" + }, + { + "line": 378, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js", + "text": "writer.write(comma);" + }, + { + "line": 385, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js", + "text": "writer.write(semicolon);" + }, + { + "line": 446, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js", + "text": "if (i > 0) writer.write(semicolon);" + }, + { + "line": 451, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js", + "text": "if (j > 0) writer.write(comma);" + }, + { + "line": 99, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/src/scopes.ts", + "text": "if (index > 0) writer.write(comma);" + }, + { + "line": 122, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/src/scopes.ts", + "text": "writer.write(comma);" + }, + { + "line": 273, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/src/scopes.ts", + "text": "writer.write(comma);" + }, + { + "line": 334, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/src/scopes.ts", + "text": "writer.write(comma);" + }, + { + "line": 343, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/src/scopes.ts", + "text": "writer.write(semicolon);" + }, + { + "line": 89, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/src/sourcemap-codec.ts", + "text": "if (i > 0) writer.write(semicolon);" + }, + { + "line": 96, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/src/sourcemap-codec.ts", + "text": "if (j > 0) writer.write(comma);" + }, + { + "line": 46, + "path": "web/react/node_modules/@jridgewell/sourcemap-codec/src/vlq.ts", + "text": "builder.write(intToChar[clamped]);" + }, + { + "line": 10, + "path": "web/react/node_modules/@tailwindcss/node/dist/index.js", + "text": "`,r){t+=u.length;let p=t;t+=2+o.value.length+2;let c=t;o.dst=[n,p,c],t+=1}}else if(o.kind===\"context\"||o.kind===\"at-root\")return\"\";return a}let l=\"\";for(let o of e)l+=i(o,0);return n.code=l,l}function Br(e,r){if(typeof e!=\"string\")throw new" + }, + { + "line": 10, + "path": "web/react/node_modules/@tailwindcss/node/dist/index.mjs", + "text": "`,r){t+=u.length;let p=t;t+=2+o.value.length+2;let c=t;o.dst=[n,p,c],t+=1}}else if(o.kind===\"context\"||o.kind===\"at-root\")return\"\";return a}let l=\"\";for(let o of e)l+=i(o,0);return n.code=l,l}function Vr(e,r){if(typeof e!=\"string\")throw new" + }, + { + "line": 219, + "path": "web/react/node_modules/@types/node/buffer.d.ts", + "text": "* const len = buf.write('\\u00bd + \\u00bc = \\u00be', 0);" + }, + { + "line": 226, + "path": "web/react/node_modules/@types/node/buffer.d.ts", + "text": "* const length = buffer.write('abcd', 8);" + }, + { + "line": 634, + "path": "web/react/node_modules/@types/node/child_process.d.ts", + "text": "* grep.stdin.write(data);" + }, + { + "line": 206, + "path": "web/react/node_modules/@types/node/crypto.d.ts", + "text": "* hash.write('some data to hash');" + }, + { + "line": 330, + "path": "web/react/node_modules/@types/node/crypto.d.ts", + "text": "* hmac.write('some data to hash');" + }, + { + "line": 713, + "path": "web/react/node_modules/@types/node/crypto.d.ts", + "text": "* cipher.write('some clear text data');" + }, + { + "line": 963, + "path": "web/react/node_modules/@types/node/crypto.d.ts", + "text": "* decipher.write(encrypted, 'hex');" + }, + { + "line": 1254, + "path": "web/react/node_modules/@types/node/crypto.d.ts", + "text": "* sign.write('some data to sign');" + }, + { + "line": 1259, + "path": "web/react/node_modules/@types/node/crypto.d.ts", + "text": "* verify.write('some data to sign');" + }, + { + "line": 1305, + "path": "web/react/node_modules/@types/node/crypto.d.ts", + "text": "* Calculates the signature on all the data passed through using either `sign.update()` or `sign.write()`." + }, + { + "line": 471, + "path": "web/react/node_modules/@types/node/fs/promises.d.ts", + "text": "* If one or more `filehandle.write()` calls are made on a file handle and then a`filehandle.writeFile()` call is made, the data will be written from the" + }, + { + "line": 492, + "path": "web/react/node_modules/@types/node/fs/promises.d.ts", + "text": "* It is unsafe to use `filehandle.write()` multiple times on the same file" + }, + { + "line": 2727, + "path": "web/react/node_modules/@types/node/fs.d.ts", + "text": "* It is unsafe to use `fs.write()` multiple times on the same file without waiting" + }, + { + "line": 3282, + "path": "web/react/node_modules/@types/node/fs.d.ts", + "text": "* When `file` is a file descriptor, the behavior is similar to calling `fs.write()` directly (which is recommended). See the notes below on using" + }, + { + "line": 698, + "path": "web/react/node_modules/@types/node/http.d.ts", + "text": "* message.write(fileData);" + }, + { + "line": 888, + "path": "web/react/node_modules/@types/node/http.d.ts", + "text": "* If `response.write()` or `response.end()` are called before calling" + }, + { + "line": 1043, + "path": "web/react/node_modules/@types/node/http.d.ts", + "text": "* res.write('hello\\n');" + }, + { + "line": 1881, + "path": "web/react/node_modules/@types/node/http.d.ts", + "text": "* req.write(postData);" + }, + { + "line": 1869, + "path": "web/react/node_modules/@types/node/http2.d.ts", + "text": "* If `data` is specified, it is equivalent to calling `response.write(data, encoding)` followed by `response.end(callback)`." + }, + { + "line": 2005, + "path": "web/react/node_modules/@types/node/http2.d.ts", + "text": "* The first time `response.write()` is called, it will send the buffered" + }, + { + "line": 2007, + "path": "web/react/node_modules/@types/node/http2.d.ts", + "text": "* time `response.write()` is called, Node.js assumes data will be streamed," + }, + { + "line": 2074, + "path": "web/react/node_modules/@types/node/http2.d.ts", + "text": "* If `response.write()` or `response.end()` are called before calling" + }, + { + "line": 201, + "path": "web/react/node_modules/@types/node/https.d.ts", + "text": "* process.stdout.write(d);" + }, + { + "line": 377, + "path": "web/react/node_modules/@types/node/https.d.ts", + "text": "* process.stdout.write(d);" + }, + { + "line": 286, + "path": "web/react/node_modules/@types/node/net.d.ts", + "text": "* `net.Socket` has the property that `socket.write()` always works. This is to" + }, + { + "line": 782, + "path": "web/react/node_modules/@types/node/net.d.ts", + "text": "* c.write('hello\\r\\n');" + }, + { + "line": 191, + "path": "web/react/node_modules/@types/node/readline.d.ts", + "text": "* The `rl.write()` method will write either `data` or a key sequence identified" + }, + { + "line": 198, + "path": "web/react/node_modules/@types/node/readline.d.ts", + "text": "* When called, `rl.write()` will resume the `input` stream if it has been" + }, + { + "line": 204, + "path": "web/react/node_modules/@types/node/readline.d.ts", + "text": "* rl.write('Delete this!');" + }, + { + "line": 206, + "path": "web/react/node_modules/@types/node/readline.d.ts", + "text": "* rl.write(null, { ctrl: true, name: 'u' });" + }, + { + "line": 209, + "path": "web/react/node_modules/@types/node/readline.d.ts", + "text": "* The `rl.write()` method will write the data to the `readline` `Interface`'s `input` _as if it were provided by the user_." + }, + { + "line": 406, + "path": "web/react/node_modules/@types/node/stream/iter.d.ts", + "text": "* writable.write('hello');" + }, + { + "line": 394, + "path": "web/react/node_modules/@types/node/stream.d.ts", + "text": "* const str = decoder.write(chunk);" + }, + { + "line": 788, + "path": "web/react/node_modules/@types/node/stream.d.ts", + "text": "* Is `true` if it is safe to call `writable.write()`, which means" + }, + { + "line": 864, + "path": "web/react/node_modules/@types/node/stream.d.ts", + "text": "* The `writable.write()` method writes some data to the stream, and calls the" + }, + { + "line": 898, + "path": "web/react/node_modules/@types/node/stream.d.ts", + "text": "* if (!stream.write(data)) {" + }, + { + "line": 948, + "path": "web/react/node_modules/@types/node/stream.d.ts", + "text": "* file.write('hello, ');" + }, + { + "line": 994, + "path": "web/react/node_modules/@types/node/stream.d.ts", + "text": "* of writes to a stream, defer calls to `writable.uncork()` using `process.nextTick()`. Doing so allows batching of all `writable.write()` calls that occur within a given Node.js event" + }, + { + "line": 999, + "path": "web/react/node_modules/@types/node/stream.d.ts", + "text": "* stream.write('some ');" + }, + { + "line": 1000, + "path": "web/react/node_modules/@types/node/stream.d.ts", + "text": "* stream.write('data ');" + }, + { + "line": 1010, + "path": "web/react/node_modules/@types/node/stream.d.ts", + "text": "* stream.write('some ');" + }, + { + "line": 1012, + "path": "web/react/node_modules/@types/node/stream.d.ts", + "text": "* stream.write('data ');" + }, + { + "line": 7, + "path": "web/react/node_modules/@types/node/string_decoder.d.ts", + "text": "* returned string and stored in an internal buffer for the next call to `stringDecoder.write()` or `stringDecoder.end()`." + }, + { + "line": 17, + "path": "web/react/node_modules/@types/node/string_decoder.d.ts", + "text": "* If the `buffer` argument is provided, one final call to `stringDecoder.write()` is performed before returning the remaining input." + }, + { + "line": 978, + "path": "web/react/node_modules/@types/node/tls.d.ts", + "text": "* socket.write('welcome!\\n');" + }, + { + "line": 707, + "path": "web/react/node_modules/@types/node/util.d.ts", + "text": "* stream.write('It works!'); // Received data: \"It works!\"" + }, + { + "line": 726, + "path": "web/react/node_modules/@types/node/util.d.ts", + "text": "* stream.write('With ES6');" + }, + { + "line": 560, + "path": "web/react/node_modules/@types/node/v8.d.ts", + "text": "* buffer.write(input, 5, 'latin1');" + }, + { + "line": 564, + "path": "web/react/node_modules/@types/node/v8.d.ts", + "text": "* buffer.write(input, 5, 'utf16le');" + }, + { + "line": 10744, + "path": "web/react/node_modules/@typescript/typescript-linux-x64/lib/lib.dom.d.ts", + "text": "* The **`ClipboardItem`** interface of the Clipboard API represents a single item format, used when reading or writing clipboard data using Clipboard.read() and Clipboard.write() respectively." + }, + { + "line": 4891, + "path": "web/react/node_modules/@typescript/typescript-linux-x64/lib/lib.webworker.d.ts", + "text": "* The **`createSyncAccessHandle()`** method of the FileSystemFileHandle interface returns a Promise which resolves to a FileSystemSyncAccessHandle object that can be used to synchronously read from and write to a file. The synchronous natur" + }, + { + "line": 4893, + "path": "web/react/node_modules/@typescript/typescript-linux-x64/lib/lib.webworker.d.ts", + "text": "* [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemFileHandle/createSyncAccessHandle)" + }, + { + "line": 4895, + "path": "web/react/node_modules/@typescript/typescript-linux-x64/lib/lib.webworker.d.ts", + "text": "createSyncAccessHandle(): Promise;" + }, + { + "line": 218, + "path": "web/react/node_modules/magic-string/dist/magic-string.umd.js", + "text": "builder.write(intToChar[clamped]);" + }, + { + "line": 266, + "path": "web/react/node_modules/magic-string/dist/magic-string.umd.js", + "text": "if (i > 0) writer.write(semicolon);" + }, + { + "line": 271, + "path": "web/react/node_modules/magic-string/dist/magic-string.umd.js", + "text": "if (j > 0) writer.write(comma);" + }, + { + "line": 205, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "0 !== chunk.length && destination.write(chunk);" + }, + { + "line": 3783, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "? ((i = renderState[i]), (renderState.length = 0), !!destination.write(i))" + }, + { + "line": 3810, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "return !!destination.write(startPendingSuspenseBoundary2);" + }, + { + "line": 3843, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "!!destination.write(startSegmentHTML2)" + }, + { + "line": 3850, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "!!destination.write(startSegmentSVG2)" + }, + { + "line": 3857, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "!!destination.write(startSegmentMathML2)" + }, + { + "line": 3864, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "!!destination.write(startSegmentTable2)" + }, + { + "line": 3871, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "!!destination.write(startSegmentTableBody2)" + }, + { + "line": 3878, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "!!destination.write(startSegmentTableRow2)" + }, + { + "line": 3885, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "!!destination.write(startSegmentColGroup2)" + }, + { + "line": 3897, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "return !!destination.write(endSegmentHTML);" + }, + { + "line": 3899, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "return !!destination.write(endSegmentSVG);" + }, + { + "line": 3901, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "return !!destination.write(endSegmentMathML);" + }, + { + "line": 3903, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "return !!destination.write(endSegmentTable);" + }, + { + "line": 3905, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "return !!destination.write(endSegmentTableBody);" + }, + { + "line": 3907, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "return !!destination.write(endSegmentTableRow);" + }, + { + "line": 3909, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "return !!destination.write(endSegmentColGroup);" + }, + { + "line": 4005, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "destinationHasCapacity = !!this.write(lateStyleTagTemplateClose);" + }, + { + "line": 8892, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "!!destination.write(placeholder2)" + }, + { + "line": 8907, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "chunkIdx < chunks.length && (r = !!destination.write(chunks[chunkIdx]));" + }, + { + "line": 8932, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "destination.write(startClientRenderedSuspenseBoundary);" + }, + { + "line": 8962, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "destination.write(clientRenderedSuspenseBoundaryError2);" + }, + { + "line": 8998, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "destination.write(startCompletedSuspenseBoundary);" + }, + { + "line": 9006, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "return !!destination.write(endSuspenseBoundary);" + }, + { + "line": 9079, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "boundary = !!destination.write(completeBoundaryScriptEnd);" + }, + { + "line": 9115, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "destination = !!destination.write(completeSegmentScriptEnd);" + }, + { + "line": 9230, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "destination.write(endInlineScript);" + }, + { + "line": 9327, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.development.js", + "text": "var JSCompiler_inline_result = !!renderState$jscomp$1.write(" + }, + { + "line": 45, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "0 !== chunk.length && destination.write(chunk);" + }, + { + "line": 2130, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "? ((i = renderState[i]), (renderState.length = 0), !!destination.write(i))" + }, + { + "line": 2141, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "return !!destination.write('\">');" + }, + { + "line": 2153, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "!!destination.write('\">')" + }, + { + "line": 2163, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "!!destination.write('\">')" + }, + { + "line": 2173, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "!!destination.write('\">')" + }, + { + "line": 2180, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "!!destination.write('\">')" + }, + { + "line": 2187, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "!!destination.write('\">')" + }, + { + "line": 2194, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "!!destination.write('\">')" + }, + { + "line": 2201, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "!!destination.write('\">')" + }, + { + "line": 2213, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "return !!destination.write(\"\");" + }, + { + "line": 2215, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "return !!destination.write(\"\");" + }, + { + "line": 2217, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "return !!destination.write(\"\");" + }, + { + "line": 2219, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "return !!destination.write(\"\");" + }, + { + "line": 2221, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "return !!destination.write(\"\");" + }, + { + "line": 2223, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "return !!destination.write(\"\");" + }, + { + "line": 2225, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "return !!destination.write(\"\");" + }, + { + "line": 2289, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "destinationHasCapacity = !!this.write(\"\");" + }, + { + "line": 6103, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "!!destination.write('\">')" + }, + { + "line": 6118, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "chunkIdx < chunks.length && (r = !!destination.write(chunks[chunkIdx]));" + }, + { + "line": 6140, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "destination.write(\"\\x3c!--$!--\\x3e\");" + }, + { + "line": 6146, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "destination.write(\">\");" + }, + { + "line": 6181, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "destination.write(\"\\x3c!--$--\\x3e\");" + }, + { + "line": 6189, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "return !!destination.write(\"\\x3c!--/$--\\x3e\");" + }, + { + "line": 6270, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "boundary = !!destination.write(\")\\x3c/script>\");" + }, + { + "line": 6309, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "destination = !!destination.write('\")\\x3c/script>');" + }, + { + "line": 6419, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "destination.write(\"\\x3c/script>\");" + }, + { + "line": 6486, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.bun.production.js", + "text": "!!renderState$jscomp$1.write(\")\\x3c/script>\");" + }, + { + "line": 252, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.node.development.js", + "text": "destination = destination.write(view);" + }, + { + "line": 262, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.node.development.js", + "text": "destination.write(currentView.subarray(0, writtenBytes));" + }, + { + "line": 113, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.node.production.js", + "text": "destination = destination.write(view);" + }, + { + "line": 123, + "path": "web/react/node_modules/react-dom/cjs/react-dom-server.node.production.js", + "text": "destination.write(currentView.subarray(0, writtenBytes));" + }, + { + "line": 865, + "path": "web/react/node_modules/rolldown/dist/cli.mjs", + "text": "process.stdout.write(CLEAR_SCREEN);" + }, + { + "line": 1023, + "path": "web/react/node_modules/rolldown/dist/cli.mjs", + "text": "for (const output of outputList) result.push(await build.write({" + }, + { + "line": 48, + "path": "web/react/node_modules/rolldown/dist/index.mjs", + "text": "if (write) return await build.write(output);" + }, + { + "line": 1497, + "path": "web/react/node_modules/rolldown/dist/shared/create-bundler-option-Cj0juyCQ.mjs", + "text": "skipWrite: /* @__PURE__ */ pipe(/* @__PURE__ */ optional(/* @__PURE__ */ boolean()), /* @__PURE__ */ description(\"Skip the bundle.write() step\"))," + }, + { + "line": 39, + "path": "web/react/node_modules/rolldown/dist/shared/load-config-CLrSp_LC.mjs", + "text": "const fileName = (await bundle.write({" + }, + { + "line": 509, + "path": "web/react/node_modules/rolldown/dist/shared/prompt-CH6TK0bC.mjs", + "text": "}), f.emitKeypressEvents(this.input, this.rl), this.rl.prompt(), this.opts.initialValue !== void 0 && this._track && this.rl.write(this.opts.initialValue), this.input.on(\"keypress\", this.onKeypress), d$1(this.input, true), this.output.on(\"r" + }, + { + "line": 510, + "path": "web/react/node_modules/rolldown/dist/shared/prompt-CH6TK0bC.mjs", + "text": "this.output.write(srcExports.cursor.show), this.output.off(\"resize\", this.render), d$1(this.input, false), u(this.value);" + }, + { + "line": 512, + "path": "web/react/node_modules/rolldown/dist/shared/prompt-CH6TK0bC.mjs", + "text": "this.output.write(srcExports.cursor.show), this.output.off(\"resize\", this.render), d$1(this.input, false), u(S);" + }, + { + "line": 517, + "path": "web/react/node_modules/rolldown/dist/shared/prompt-CH6TK0bC.mjs", + "text": "if (this.state === \"error\" && (this.state = \"active\"), F?.name && (!this._track && c.aliases.has(F.name) && this.emit(\"cursor\", c.aliases.get(F.name)), c.actions.has(F.name) && this.emit(\"cursor\", F.name)), u && (u.toLowerCase() === \"y\" || " + }, + { + "line": 520, + "path": "web/react/node_modules/rolldown/dist/shared/prompt-CH6TK0bC.mjs", + "text": "e && (this.error = e instanceof Error ? e.message : e, this.state = \"error\", this.rl?.write(this.value));" + }, + { + "line": 531, + "path": "web/react/node_modules/rolldown/dist/shared/prompt-CH6TK0bC.mjs", + "text": "this.input.unpipe(), this.input.removeListener(\"keypress\", this.onKeypress), this.output.write(`" + }, + { + "line": 537, + "path": "web/react/node_modules/rolldown/dist/shared/prompt-CH6TK0bC.mjs", + "text": "this.output.write(srcExports.cursor.move(-999, u * -1));" + }, + { + "line": 542, + "path": "web/react/node_modules/rolldown/dist/shared/prompt-CH6TK0bC.mjs", + "text": "if (this.state === \"initial\") this.output.write(srcExports.cursor.hide);" + }, + { + "line": 547, + "path": "web/react/node_modules/rolldown/dist/shared/prompt-CH6TK0bC.mjs", + "text": "this.output.write(srcExports.cursor.move(0, e)), this.output.write(srcExports.erase.lines(1));" + }, + { + "line": 550, + "path": "web/react/node_modules/rolldown/dist/shared/prompt-CH6TK0bC.mjs", + "text": "this.output.write(s[e]), this._prevFrame = u, this.output.write(srcExports.cursor.move(0, s.length - e - 1));" + }, + { + "line": 555, + "path": "web/react/node_modules/rolldown/dist/shared/prompt-CH6TK0bC.mjs", + "text": "this.output.write(srcExports.cursor.move(0, e)), this.output.write(srcExports.erase.down());" + }, + { + "line": 558, + "path": "web/react/node_modules/rolldown/dist/shared/prompt-CH6TK0bC.mjs", + "text": "this.output.write(s.join(`" + }, + { + "line": 562, + "path": "web/react/node_modules/rolldown/dist/shared/prompt-CH6TK0bC.mjs", + "text": "this.output.write(srcExports.erase.down());" + }, + { + "line": 564, + "path": "web/react/node_modules/rolldown/dist/shared/prompt-CH6TK0bC.mjs", + "text": "this.output.write(u), this.state === \"initial\" && (this.state = \"active\"), this._prevFrame = u;" + }, + { + "line": 579, + "path": "web/react/node_modules/rolldown/dist/shared/prompt-CH6TK0bC.mjs", + "text": "this.output.write(srcExports.cursor.move(0, -1)), this.value = F, this.state = \"submit\", this.close();" + }, + { + "line": 130, + "path": "web/react/node_modules/rolldown/dist/shared/rolldown-vcii7mEa.mjs", + "text": "if (isWrite) output = await this.#bundler.write(option.bundlerOptions);" + }, + { + "line": 158, + "path": "web/react/node_modules/rolldown/dist/shared/rolldown-vcii7mEa.mjs", + "text": "* await bundle.write({" + }, + { + "line": 343, + "path": "web/react/node_modules/three/examples/jsm/exporters/PLYExporter.js", + "text": "posWriter.write( output, vOffset, vertex.x, options.littleEndian );" + }, + { + "line": 346, + "path": "web/react/node_modules/three/examples/jsm/exporters/PLYExporter.js", + "text": "posWriter.write( output, vOffset, vertex.y, options.littleEndian );" + }, + { + "line": 349, + "path": "web/react/node_modules/three/examples/jsm/exporters/PLYExporter.js", + "text": "posWriter.write( output, vOffset, vertex.z, options.littleEndian );" + }, + { + "line": 361, + "path": "web/react/node_modules/three/examples/jsm/exporters/PLYExporter.js", + "text": "normalWriter.write( output, vOffset, vertex.x, options.littleEndian );" + }, + { + "line": 364, + "path": "web/react/node_modules/three/examples/jsm/exporters/PLYExporter.js", + "text": "normalWriter.write( output, vOffset, vertex.y, options.littleEndian );" + }, + { + "line": 367, + "path": "web/react/node_modules/three/examples/jsm/exporters/PLYExporter.js", + "text": "normalWriter.write( output, vOffset, vertex.z, options.littleEndian );" + }, + { + "line": 372, + "path": "web/react/node_modules/three/examples/jsm/exporters/PLYExporter.js", + "text": "normalWriter.write( output, vOffset, 0, options.littleEndian );" + }, + { + "line": 375, + "path": "web/react/node_modules/three/examples/jsm/exporters/PLYExporter.js", + "text": "normalWriter.write( output, vOffset, 0, options.littleEndian );" + }, + { + "line": 378, + "path": "web/react/node_modules/three/examples/jsm/exporters/PLYExporter.js", + "text": "normalWriter.write( output, vOffset, 0, options.littleEndian );" + }, + { + "line": 390, + "path": "web/react/node_modules/three/examples/jsm/exporters/PLYExporter.js", + "text": "uvWriter.write( output, vOffset, uvs.getX( i ), options.littleEndian );" + }, + { + "line": 393, + "path": "web/react/node_modules/three/examples/jsm/exporters/PLYExporter.js", + "text": "uvWriter.write( output, vOffset, uvs.getY( i ), options.littleEndian );" + }, + { + "line": 398, + "path": "web/react/node_modules/three/examples/jsm/exporters/PLYExporter.js", + "text": "uvWriter.write( output, vOffset, 0, options.littleEndian );" + }, + { + "line": 401, + "path": "web/react/node_modules/three/examples/jsm/exporters/PLYExporter.js", + "text": "uvWriter.write( output, vOffset, 0, options.littleEndian );" + }, + { + "line": 421, + "path": "web/react/node_modules/three/examples/jsm/exporters/PLYExporter.js", + "text": "colorWriter.write( output, vOffset, r, options.littleEndian );" + }, + { + "line": 424, + "path": "web/react/node_modules/three/examples/jsm/exporters/PLYExporter.js", + "text": "colorWriter.write( output, vOffset, g, options.littleEndian );" + }, + { + "line": 427, + "path": "web/react/node_modules/three/examples/jsm/exporters/PLYExporter.js", + "text": "colorWriter.write( output, vOffset, b, options.littleEndian );" + }, + { + "line": 434, + "path": "web/react/node_modules/three/examples/jsm/exporters/PLYExporter.js", + "text": "colorWriter.write( output, vOffset, white, options.littleEndian );" + }, + { + "line": 437, + "path": "web/react/node_modules/three/examples/jsm/exporters/PLYExporter.js", + "text": "colorWriter.write( output, vOffset, white, options.littleEndian );" + }, + { + "line": 440, + "path": "web/react/node_modules/three/examples/jsm/exporters/PLYExporter.js", + "text": "colorWriter.write( output, vOffset, white, options.littleEndian );" + }, + { + "line": 459, + "path": "web/react/node_modules/three/examples/jsm/exporters/PLYExporter.js", + "text": "writer.write( output, vOffset, isFloat ? raw : Math.round( raw ), options.littleEndian );" + }, + { + "line": 9, + "path": "web/react/node_modules/three/examples/jsm/libs/basis/basis_transcoder.js", + "text": "var Module=moduleArg;var readyPromiseResolve,readyPromiseReject;var readyPromise=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject});var ENVIRONMENT_IS_WEB=typeof window==\"object\";var ENVIRONMENT_IS_WORKER" + }, + { + "line": 72, + "path": "web/react/node_modules/three/examples/jsm/libs/demuxer_mp4.js", + "text": "box.write(stream);" + }, + { + "line": 305, + "path": "web/react/node_modules/typescript/dist/api/syncChannel.js", + "text": "this.writeBuf.write(payload, off, payloadLen, \"utf-8\");" + }, + { + "line": 465, + "path": "web/react/node_modules/typescript/vendor/vscode-jsonrpc/lib/common/connection.js", + "text": "messageWriter.write(response).catch(() => logger.error(`Sending response for canceled message failed.`));" + }, + { + "line": 506, + "path": "web/react/node_modules/typescript/vendor/vscode-jsonrpc/lib/common/connection.js", + "text": "return messageWriter.write(message);" + }, + { + "line": 515, + "path": "web/react/node_modules/typescript/vendor/vscode-jsonrpc/lib/common/connection.js", + "text": "return messageWriter.write(message);" + }, + { + "line": 991, + "path": "web/react/node_modules/typescript/vendor/vscode-jsonrpc/lib/common/connection.js", + "text": "return messageWriter.write(notificationMessage).catch((error) => {" + }, + { + "line": 1137, + "path": "web/react/node_modules/typescript/vendor/vscode-jsonrpc/lib/common/connection.js", + "text": "await messageWriter.write(requestMessage);" + }, + { + "line": 141, + "path": "web/react/node_modules/typescript/vendor/vscode-jsonrpc/lib/common/messageWriter.js", + "text": "await this.writable.write(headers.join(''), 'ascii');" + }, + { + "line": 142, + "path": "web/react/node_modules/typescript/vendor/vscode-jsonrpc/lib/common/messageWriter.js", + "text": "return this.writable.write(data);" + }, + { + "line": 90, + "path": "web/react/node_modules/typescript/vendor/vscode-jsonrpc/lib/node/ril.js", + "text": "this.stream.write(data, encoding, callback);" + }, + { + "line": 93, + "path": "web/react/node_modules/typescript/vendor/vscode-jsonrpc/lib/node/ril.js", + "text": "this.stream.write(data, callback);" + }, + { + "line": 1321, + "path": "web/react/node_modules/vite/dist/node/chunks/build.js", + "text": "endPos += mem.write(data.slice(i), endPos, encoding);" + }, + { + "line": 1331, + "path": "web/react/node_modules/vite/dist/node/chunks/build.js", + "text": "} else endPos = buffered + mem.write(data, buffered, encoding);" + }, + { + "line": 1332, + "path": "web/react/node_modules/vite/dist/node/chunks/build.js", + "text": "} else endPos = buffered + mem.write(data, buffered, encoding);" + }, + { + "line": 1479, + "path": "web/react/node_modules/vite/dist/node/chunks/dist.js", + "text": "this.preprocessor.write(chunk, isLastChunk);" + }, + { + "line": 3313, + "path": "web/react/node_modules/vite/dist/node/chunks/dist.js", + "text": "let length = this.entityDecoder.write(this.preprocessor.html, this.preprocessor.pos);" + }, + { + "line": 4335, + "path": "web/react/node_modules/vite/dist/node/chunks/dist.js", + "text": "parser.tokenizer.write(html, true);" + }, + { + "line": 731, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "builder.write(intToChar$1[clamped]);" + }, + { + "line": 846, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "if (i > 0) writer.write(semicolon);" + }, + { + "line": 851, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "if (j > 0) writer.write(comma$1);" + }, + { + "line": 1582, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "process.stderr.write(`${formatWithOptions(inspectOpts, ...args)}\\n`);" + }, + { + "line": 3961, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "if (\"undefined\" != typeof Buffer ? Buffer.from(E.memory.buffer, o, 2 * (I - 1)).write(C, \"utf16le\") : (A ? B : Q)(C, new Uint16Array(E.memory.buffer, o, I)), !E.parse()) throw Object.assign(/* @__PURE__ */ new Error(`Parse error ${g}:${C.sl" + }, + { + "line": 14242, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "this._inflate.write(data);" + }, + { + "line": 14243, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "if (fin) this._inflate.write(TRAILER);" + }, + { + "line": 14286, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "this._deflate.write(data);" + }, + { + "line": 15152, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "if (typeof data === \"string\") buf.write(data, 2);" + }, + { + "line": 15466, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "this._socket.write(list[0]);" + }, + { + "line": 15467, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "this._socket.write(list[1], cb);" + }, + { + "line": 15469, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "} else this._socket.write(list[0], cb);" + }, + { + "line": 16825, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "websocket._receiver.write(chunk);" + }, + { + "line": 16843, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "if (!this[kWebSocket]._receiver.write(chunk)) this.pause();" + }, + { + "line": 17319, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "socket.write(headers.concat(\"\\r\\n\").join(\"\\r\\n\"));" + }, + { + "line": 17874, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "this._currentRequest.write(data, encoding, callback);" + }, + { + "line": 17894, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "this.write(data, encoding, function() {" + }, + { + "line": 18005, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "if (!request.finished) request.write(buffer.data, buffer.encoding, writeNext);" + }, + { + "line": 18890, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "socket.write(createHttpHeader(\"HTTP/1.1 101 Switching Protocols\", proxyRes.headers));" + }, + { + "line": 18907, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "socket.write(chunk);" + }, + { + "line": 18912, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "socket.write(chunk.length.toString(16));" + }, + { + "line": 18913, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "socket.write(\"\\r\\n\");" + }, + { + "line": 18914, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "socket.write(chunk);" + }, + { + "line": 18915, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "socket.write(\"\\r\\n\");" + }, + { + "line": 18920, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "socket.write(proxyHead);" + }, + { + "line": 20526, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "res.write(renderRestrictedErrorHTML(urlMessage + \"\\n\" + hintMessage));" + }, + { + "line": 32407, + "path": "web/react/node_modules/vite/dist/node/chunks/node.js", + "text": "return await bundle.write({" + }, + { + "line": 10, + "path": "web/worker/test_workspace_runtime.mjs", + "text": "workspace.write(\"op-1\", \"/workspace/config/main.ini\", \"[EMC]\\n\");" + }, + { + "line": 11, + "path": "web/worker/test_workspace_runtime.mjs", + "text": "workspace.write(\"op-1\", \"program.ngc\", \"G21\\n\");" + }, + { + "line": 17, + "path": "web/worker/test_workspace_runtime.mjs", + "text": "workspace.write(\"op-abort\", \"unused\", \"x\");" + }, + { + "line": 21, + "path": "web/worker/test_workspace_runtime.mjs", + "text": "workspace.write(\"op-large\", \"large\", \"x\".repeat(65));" + }, + { + "line": 178, + "path": "web/workspace/configuration-startup.mjs", + "text": "for (const path of paths) this.workspace.write(operationId, `/workspace/${path}`, generated[path]);" + }, + { + "line": 56, + "path": "web/workspace/opfs-runtime.mjs", + "text": "if (typeof file.createSyncAccessHandle !== \"function\") return { schema: OPFS_RUNTIME_SCHEMA, status: \"blocked\", code: \"opfs_sync_access_handle_missing\", project_id: projectId };" + }, + { + "line": 57, + "path": "web/workspace/opfs-runtime.mjs", + "text": "access = await file.createSyncAccessHandle();" + }, + { + "line": 61, + "path": "web/workspace/opfs-runtime.mjs", + "text": "const written = access.write(encoded, { at: 0 });" + }, + { + "line": 68, + "path": "web/workspace/opfs-runtime.mjs", + "text": "const corrupt = await file.createSyncAccessHandle();" + }, + { + "line": 69, + "path": "web/workspace/opfs-runtime.mjs", + "text": "corrupt.write(TEXT_ENCODER.encode(\"{corrupt\"), { at: 0 });" + } + ], + "react": { + "file_count": 19, + "files": [ + { + "path": "web/react/src/App.tsx", + "sha256": "8cbec29f00c44e18a01ac92734e4f8b64764cc04db4cec48ce9c28693bd2bbef" + }, + { + "path": "web/react/src/ThreeMachineView.tsx", + "sha256": "c358e3cdc4bee6f4d67ca9c45d8f50ad863f0ce85d6af8cef55bcb2dae303d13" + }, + { + "path": "web/react/src/XyzacMachineView.tsx", + "sha256": "fd3804b8b86d6630054755c00f35828591dec5093f86ea080c9d6fb5db7aa05d" + }, + { + "path": "web/react/src/XyzacToolPreview.tsx", + "sha256": "d29cd1355d7dd178dce01e49eb321425b0b08d2291a6eaa00c86b546d8e3bba1" + }, + { + "path": "web/react/src/XyzacTrtPanel.tsx", + "sha256": "f17e25f74d87a39a1bd7520f65cf1b285cb4c38d8e4fcaec13320e41c4ca6511" + }, + { + "path": "web/react/src/gui-domain.ts", + "sha256": "aa31acabe0144fac1f9952f4c97b70181fbe85528ef7956b669e287b965a6329" + }, + { + "path": "web/react/src/gui-family-adapter.ts", + "sha256": "7c604783d93f3c2e9680d0ba477ae9c9f08ade67ea906b19cc654e70b2edc916" + }, + { + "path": "web/react/src/legacy.d.ts", + "sha256": "a29f18bf009c955a5463a58856d4ab9902fc5ce032d643f5363ca3bf28247174" + }, + { + "path": "web/react/src/main.tsx", + "sha256": "421d99e6173741894a6ec5bdbf1d7da519f25c346a842892ddd00110401721d8" + }, + { + "path": "web/react/src/protocol.ts", + "sha256": "a4f3b12ec4615c00973e1617849b40e9e3441369f18e28a86434495b154f9112" + }, + { + "path": "web/react/src/sim-worker-entry.ts", + "sha256": "cab262b47dea50db0f0c666709153d00fd69820daa6666da7e923d5e798aa992" + }, + { + "path": "web/react/src/sourceAssets.ts", + "sha256": "a536c675b49ff93de748f3b21781c4967bb66597f5edd5b156f7f8f43be75375" + }, + { + "path": "web/react/src/store.ts", + "sha256": "929aba2af3291aefb4e79f500ec6567f7b7e3f1dc91b68bf67aa8224ba9a41ee" + }, + { + "path": "web/react/src/test_xyzac_threejs.mjs", + "sha256": "840f191d5243016e6ecba4404f2950a067d63f9c1f280a2c1655f30bf021324b" + }, + { + "path": "web/react/src/test_xyzac_tool_preview.mjs", + "sha256": "99f60e050a3ba90b3feb2922b007a49cb4a9e2f88610a0f55f1b6a9c8f07cdbd" + }, + { + "path": "web/react/src/visual-workflow.ts", + "sha256": "d658a580175057b824ac4e1769d7d8b66a340d8947dbbb1d3dde530bce4f1433" + }, + { + "path": "web/react/src/worker-client.ts", + "sha256": "47fcfc52acd5ce6e5dbbd91cf9da45aa5a089a3172da6414a347de5039e36737" + }, + { + "path": "web/react/src/xyzac-panel-contract.ts", + "sha256": "a1afaa368927bbc5b7d9e21a64213b963a97b687cecb0005bb9b8e47e969e823" + }, + { + "path": "web/react/src/xyzac-visual-adapter.ts", + "sha256": "2e67bf4522ff87648d0b7de1f6fc447d51e780eed66c299d7f4bc3c35d7b33f8" + } + ], + "root": "web/react/src" + }, + "react_opfs_matches": [], + "react_wasm_matches": [], + "worker": { + "file_count": 124, + "files": [ + { + "path": "web/worker/authoritative-runtime.mjs", + "sha256": "c2bdd03de958ffda38553ec6dbddb4b1f5c08b2cb636ba02f25f2b76bdd61604" + }, + { + "path": "web/worker/axis-state.mjs", + "sha256": "01bbbcd053262f43413fe76a540b0c453e0a2c3e704ea44ec8b30ce50bb66b83" + }, + { + "path": "web/worker/capabilities.mjs", + "sha256": "39b5af3627e068d7cc68fc0bcabfdc33c79f4f68b41e4488481ef5c4791d9993" + }, + { + "path": "web/worker/contracts.mjs", + "sha256": "da6a9b63df8171db8613c7c97910b857e6738f718b855063960d9d42dd2e736e" + }, + { + "path": "web/worker/device-io.mjs", + "sha256": "e5714b11283e1b6adcc15d96b340d4ca9795ec5efe6fff288464c21f0c76349a" + }, + { + "path": "web/worker/endpoint-replay.mjs", + "sha256": "670cba58c7fda69846ed5f01ae5c94da0095f47b939badb52f051a311c9fe6f9" + }, + { + "path": "web/worker/error-map.mjs", + "sha256": "83ca215534eed48a9082cc07230507c7b38cbb99f9f2a52e7026b5d49da1d167" + }, + { + "path": "web/worker/hal-runtime.mjs", + "sha256": "7495387186b0bba3f717c43a696a4b939a6729df6b9398e6b4fddc1ec4931363" + }, + { + "path": "web/worker/io-ack.mjs", + "sha256": "a68fe56c8b8c7b44ff585a7c7c1fa5ca942f59197ef51651abf59ae4cc1eaec5" + }, + { + "path": "web/worker/motion-state.mjs", + "sha256": "7acdbd55ca467ae9ada8d4dbeebf290b6d660c3c1a8eb86d750254464dc47c8e" + }, + { + "path": "web/worker/operation-ledger.mjs", + "sha256": "555cc27e176b8ea10890e952e147f2c2ba4a99d5005ec54be4b7895cb315fd01" + }, + { + "path": "web/worker/plc-runtime.mjs", + "sha256": "070f9f94fd5e038bd550d23a7f6831bb7521e50c0f829c4adaa7040dbe240527" + }, + { + "path": "web/worker/program-runner.mjs", + "sha256": "6b7dc1f8f857f6752d142212824c9598ad14017f1e706b0a4406e6e6976051f6" + }, + { + "path": "web/worker/python-bridge.mjs", + "sha256": "2014c81d744ea9f60e60e75545a7b0ceb5ab7a94834235bd2db9075ffa596654" + }, + { + "path": "web/worker/python-callbacks.mjs", + "sha256": "2351fb79254da15c1e97d9be7c7f3d5f5bde1478780f5f6d98ee9270d56562ec" + }, + { + "path": "web/worker/recovery-runtime.mjs", + "sha256": "b8c57718f54a9f345c7cd348337d9f2fb6e8dcb6cd593ea7b31af5cdf9b16543" + }, + { + "path": "web/worker/replay.mjs", + "sha256": "5e599e302edd0c5109a061ba9a421f77d7b87ad9cdb6a4183653afe5cd02f97c" + }, + { + "path": "web/worker/sim-scheduler.mjs", + "sha256": "00711621d132580929b11a3933582f5d28c779cc29869fa619f86a6846edf4e5" + }, + { + "path": "web/worker/sim-session.mjs", + "sha256": "7ce91549f0f3a06ff77db9ee281fd9544848f6e41e08f9da302ee2e7827194e3" + }, + { + "path": "web/worker/sim-task.mjs", + "sha256": "4b4b3aa4b86aba08e5afb8534d98d6ab11c845eeb891cf4793b5906a01de1599" + }, + { + "path": "web/worker/sim-worker.mjs", + "sha256": "3b0670d4c6c9d8aab179534bacb8c984a6695ae9dffd58e376b6e854ee25e91b" + }, + { + "path": "web/worker/test_authoritative_kinematics_s6.mjs", + "sha256": "f135487fde669a008d85adf69c45e41d557d1ff336c83c2daac75db25174ab1f" + }, + { + "path": "web/worker/test_authoritative_kinematics_s6_04.mjs", + "sha256": "d07c82daa82cb2955bed3a2dde4e435cbc8ea47ad78f3bfed06d4d51768fbdf6" + }, + { + "path": "web/worker/test_authoritative_kinematics_s7_03.mjs", + "sha256": "d013d5fdc3525cf709de47d534b64dc2ada30caf1b05d9ec9b53dc565b30418d" + }, + { + "path": "web/worker/test_authoritative_kinematics_s7_04.mjs", + "sha256": "41985d384228445f5de56b693d72f5cba0233d61883fa6efd393c5cc2649ed3a" + }, + { + "path": "web/worker/test_authoritative_sim_task_s6.mjs", + "sha256": "9306da3d0f9ecb568ca7bd7577f8d321630d5fbaafaa2dd3b96943819448be29" + }, + { + "path": "web/worker/test_axis3_selected_case.mjs", + "sha256": "286b796ef58fe7c04172c06fffe9d6679d2b84294547849c8c6736b1d6ca12b0" + }, + { + "path": "web/worker/test_axis3_tutorial_hal_adapter.mjs", + "sha256": "dfb0e1bfe54cfcc3a1d03c626dd970b1fdc276da9c57341e3624e8eef6b0bbee" + }, + { + "path": "web/worker/test_axis3_tutorial_motion.mjs", + "sha256": "6a9a0e9dd1bb12e07ba6ed0ea27eb18df8981c9f2196888d7e0179a64085bf57" + }, + { + "path": "web/worker/test_axis3_tutorial_persistence.mjs", + "sha256": "05e6e4038a653274ebbfeb152581152ab77ac340e632a0179c960b29eeb01f64" + }, + { + "path": "web/worker/test_axis3_tutorial_program.mjs", + "sha256": "77a2f2f7b85a8f2e4056b66ffa2c0ba22b26002a0866460ea70835ac09d986f6" + }, + { + "path": "web/worker/test_axis3_tutorial_sequence.mjs", + "sha256": "7dcf2eb35c7e4480b763df7f46123340b4d8866d54869d3c2595a12ea8a8a6d5" + }, + { + "path": "web/worker/test_axis3_tutorial_startup.mjs", + "sha256": "fc8d2c1378038f6f3ff8aa16193acee7cb9bbb1b69608ae3a6cab0712233f975" + }, + { + "path": "web/worker/test_axis3_tutorial_tool_io.mjs", + "sha256": "03e3133533dff88a986fe6ffc8fb316b0417077ab3e8d2a76dd1ec2b0747bc09" + }, + { + "path": "web/worker/test_axis3_visible_completion.mjs", + "sha256": "17d9f92e3c156c8ac8a7335e1f3468984abdc51d62bec93e2cac7335a5a55b78" + }, + { + "path": "web/worker/test_axis_state.mjs", + "sha256": "075cb9d0fef29768f204146c3868f2350f963485bcfa21f49acf80debf5b51d8" + }, + { + "path": "web/worker/test_configuration_batch.mjs", + "sha256": "816668b6f3b2f1ed89fdfd0ccc3011d8a5df6007ce42faf55ffe33e7f2e5ea7a" + }, + { + "path": "web/worker/test_configuration_corexy_s7_05.mjs", + "sha256": "7443486b4e7a76af9262f00b1e97a500f99131a8d752ebaee3b09b43cbc7bd8a" + }, + { + "path": "web/worker/test_configuration_preflight.mjs", + "sha256": "82a2e0340b9ec8c26812a2472b1a7b53cb365a0fa1ded287e24577b4a167ce19" + }, + { + "path": "web/worker/test_configuration_startup_runtime.mjs", + "sha256": "2a6738cabddea5dc6cb795f93250c71509765c746a588f5151d5b2a3082b8c9e" + }, + { + "path": "web/worker/test_contracts.mjs", + "sha256": "08c17c1246f1884161a221183cd42402e244e47a67b4bb7b89e27f44f7eadc9f" + }, + { + "path": "web/worker/test_corexy_dual_path_s8_05.mjs", + "sha256": "e1f7e31f6f471eda4b2cfa1680573116c1b766161a7217b7cc8c184593711adb" + }, + { + "path": "web/worker/test_device_io.mjs", + "sha256": "8b95591f5478738478efd8e26cbab8637df59d68a5fc8e4733de0ad3bf1fc336" + }, + { + "path": "web/worker/test_device_recovery.mjs", + "sha256": "36248086f33ff12af8141a7b3a8734569a7aef0ece6ca57963244f7f07a2eddb" + }, + { + "path": "web/worker/test_endpoint_replay_s4.mjs", + "sha256": "30c59942d86f86fd153e678dc4ab3e313d46a57fcb103a968e5d666685dca065" + }, + { + "path": "web/worker/test_full_simulation_s4.mjs", + "sha256": "693f79215dea457d84e30e25bd127c004d326a5fbe38505903dd42d84c4f2df9" + }, + { + "path": "web/worker/test_hal_preflight.mjs", + "sha256": "8d189e06fac8c2ca722931d0cf05772e5a7f73e46f88d9d908e04ac6112a22e6" + }, + { + "path": "web/worker/test_hal_runtime.mjs", + "sha256": "f2b5c79cc4520642c8606405638e3e43da18973ea3d32640d9cac95885e02195" + }, + { + "path": "web/worker/test_ini_parser.mjs", + "sha256": "9cb7664938a06d283d3453d42ba76b4c4758520bfd90c0035f81e8240517a21e" + }, + { + "path": "web/worker/test_io_ack.mjs", + "sha256": "d36d6cfdbbad3e2bd7cd3fac5e79d5bc288c03297b739968e3d2bb4069923349" + }, + { + "path": "web/worker/test_machine_families_s8_08.mjs", + "sha256": "52aec5080d80efb93fa77c60a40d721f5607fb935f061fdaa57a6bb8ca0c5875" + }, + { + "path": "web/worker/test_minimal_xyz_vertical_s8_04.mjs", + "sha256": "d504eb92ae04c5fa1daaf58e1b691d677c39f27d4ea3663fa451a0d6f02f0daf" + }, + { + "path": "web/worker/test_motion_state.mjs", + "sha256": "fa4324e05fd3d11557f58c6afc6f6b48919e06bc2d74c09b08d99d55cd25c883" + }, + { + "path": "web/worker/test_panel_gate_matrix.mjs", + "sha256": "1954b76bcea4b0fa1b5ea909eb3f809ca3d7576193f0cb8638a58d9adb908b8c" + }, + { + "path": "web/worker/test_panel_snapshot_projection.mjs", + "sha256": "bd90f1e945c1ca603438b72694ce25b37ddaf566ec6eaa436fd5a324682795fd" + }, + { + "path": "web/worker/test_plc_runtime.mjs", + "sha256": "1f8c7ce78efc2bd59ba6ac301ba0fdccdbe7972658b9f8f45c02358f78250aec" + }, + { + "path": "web/worker/test_program_control.mjs", + "sha256": "b44c5cdd5de07964398a8c84f2916c6dc9d9f25322c5b244872462c435174988" + }, + { + "path": "web/worker/test_python_api_s3.mjs", + "sha256": "98b50ffc93698d80d7d89a65b1452fab7d331ee346d39126ce5ed49297d95788" + }, + { + "path": "web/worker/test_python_bridge.mjs", + "sha256": "02a82442a9644890fd501e4d915ee0b169e53a651eaa48a613796c5345779431" + }, + { + "path": "web/worker/test_python_callbacks.mjs", + "sha256": "0b78e429adf695483b39d68ec3561eab9ed5b4c3cc13841ef6f9eb91ef775fb7" + }, + { + "path": "web/worker/test_python_callbacks_s3.mjs", + "sha256": "fa75a69bd57e24ba171dfc1999a962994b5b0b64a12d555e57563ff2621bbd82" + }, + { + "path": "web/worker/test_python_session.mjs", + "sha256": "8abd0fbb95bf30e548a97716a3c70182ee9a8ccf9c716ec7a048391e75bdf266" + }, + { + "path": "web/worker/test_recovery_offline_faults.mjs", + "sha256": "e7e2b7c6022b7b8e45cef1acbffb49987ced552719a76497c3a433fd92126f6e" + }, + { + "path": "web/worker/test_recovery_s3.mjs", + "sha256": "c7364aad31ebd848298aa025ed0e7458fafd7d17b1904559e499d93f428e7ca4" + }, + { + "path": "web/worker/test_replay.mjs", + "sha256": "b0fedc32050334a42af6d2c6aee9b035db00bec396f5a1b5600c71942c736089" + }, + { + "path": "web/worker/test_resource_intro_graphic_s7_06.mjs", + "sha256": "c727fd4c240480924c8909a3c7949653292e7d18d0fde640a37500a3ddbceea2" + }, + { + "path": "web/worker/test_resource_resolver.mjs", + "sha256": "f6c4a928f01bc98ca761d121b889efce77c7cd4918ffd43d72c0e3ca3610d9c9" + }, + { + "path": "web/worker/test_runtime_mapping.mjs", + "sha256": "b43baa924053b74c83a849b95e56eb49cdff1bd82f9a63c9566dc386dff96f51" + }, + { + "path": "web/worker/test_sim_case_batch_s8_03.mjs", + "sha256": "7690652f45be6d12f00c343900e8473952e567a791e49091f66d7b22540b99b5" + }, + { + "path": "web/worker/test_sim_case_matrix_s8_06.mjs", + "sha256": "3c5053e22f063542da10c3638b7f1bd7007797a754936c0e6a17c8d5a860e221" + }, + { + "path": "web/worker/test_sim_case_startup_s8_02.mjs", + "sha256": "5c83a94cf7293b8503979663c65dc1e3977f8ffd72fc63bc8d174c4c418c3fa0" + }, + { + "path": "web/worker/test_sim_ledger.mjs", + "sha256": "37bb408a1571c790d8ed9474ded2cc24bb4bda91b3303f1045c87990fac9f51f" + }, + { + "path": "web/worker/test_sim_runner.mjs", + "sha256": "b1b330f212fdf4eba03123c1880dd9c7a7b4bb2290b7d7c6ae8d344561872907" + }, + { + "path": "web/worker/test_sim_scheduler.mjs", + "sha256": "f8fe8a6388f9ff8f4d696949fc6065962698d441f1d7879053aba6b3868d692a" + }, + { + "path": "web/worker/test_sim_session.mjs", + "sha256": "bc7f3aeabca542a0b5c9d9c440114f4f9e150ca3cb8d0d8fc24cd7efce310332" + }, + { + "path": "web/worker/test_sim_task.mjs", + "sha256": "ed1bc378a894b1a32082863319c30e1a772fd49173d7e7d7a54fc758cf31f4c6" + }, + { + "path": "web/worker/test_source_config_s5.mjs", + "sha256": "af07fc47874da3c34fb5d959314a3dc88b83e540d1752866e5960b1e4cc115c1" + }, + { + "path": "web/worker/test_source_do_s7_01.mjs", + "sha256": "90c809ec749e79e94e18cfa3a84deb5c9e42bbdffd6b53c198fdcbbf4a2b7fd2" + }, + { + "path": "web/worker/test_source_g6164_s7_02.mjs", + "sha256": "30e66bf233a70119b3873e28c4dcc4c974e2e17ab377567c2e13a0f6430c6c3b" + }, + { + "path": "web/worker/test_source_hal_s5.mjs", + "sha256": "a3c33b301dbee3efcc856e9adb58131e6a93349d242327113f9cc3f3160ea99f" + }, + { + "path": "web/worker/test_source_interpreter_s5.mjs", + "sha256": "140d5cb14e242d2ddce10c17f45e16c4dd09d07fba642d22d47d27229ede69fe" + }, + { + "path": "web/worker/test_source_io_s5.mjs", + "sha256": "4afea510a2ee4190a917c398dccf69089f960561b91942e0a1479a1a0dd42fea" + }, + { + "path": "web/worker/test_source_parity_s5.mjs", + "sha256": "c0d8a42d899ed331156dfe2fd4218230fbff80bf4985541add9ce5af838da091" + }, + { + "path": "web/worker/test_task_program_state.mjs", + "sha256": "683e0af5c1e5cb522cd336120b18ed06498cf3ab5d74c595e85072b4ffe0bf1a" + }, + { + "path": "web/worker/test_trace_export.mjs", + "sha256": "de9235e179e98cd41a6cf66810dd1b511545652027b8f922eeeb705434d255bf" + }, + { + "path": "web/worker/test_virtual_devices.mjs", + "sha256": "5efbc15f170d4d28cc205303aa971cb38a22f548ff652a6a779a77bc869b3f7e" + }, + { + "path": "web/worker/test_wasm_canonical_state.mjs", + "sha256": "44d25c9bec69b24671e473f9dc04ea218358b1316f7d5571251bc81382e708b7" + }, + { + "path": "web/worker/test_wasm_canonical_state_checkpoint.mjs", + "sha256": "a1871f1e88fcb723ede46e82359af075ef41a9801a071c3ea8735f3d4861c05f" + }, + { + "path": "web/worker/test_wasm_feature_matrix_t5.mjs", + "sha256": "52b1345c27582c6197d5bb17fc6a6678f5bae6c977def6f4e4a15dcd1edd6904" + }, + { + "path": "web/worker/test_wasm_function_closure_t6.mjs", + "sha256": "703b25ee4959614efeb5aedabf76bead52e3b3d158f934ab3532a61643d2f9a8" + }, + { + "path": "web/worker/test_wasm_motion_authority.mjs", + "sha256": "bdf5c45d7c7b77146fc71e26e092e1309a5ce94593f9d78c8f188bc0685a19e9" + }, + { + "path": "web/worker/test_wasm_motion_checkpoint.mjs", + "sha256": "eb3881524c8b138b2dbd9a62b71fa3fa4b60401dda34dcb97bdb4b09f95ba5ab" + }, + { + "path": "web/worker/test_wasm_motion_event.mjs", + "sha256": "0310d665d6fb51007785f272ed0524377dd17926be40f471cf68586ca0ce630d" + }, + { + "path": "web/worker/test_wasm_preview.mjs", + "sha256": "ec79688e0753e6d5f8b0494cec3dda3b3bf2dc6126c21a56afbb27fda6f92396" + }, + { + "path": "web/worker/test_wasm_session.mjs", + "sha256": "e875b39b68e9cd967a1e0bbaa96c37ef2ae9d86a81dceba87b8c77a25442017b" + }, + { + "path": "web/worker/test_workspace_runtime.mjs", + "sha256": "e264d4a1bb965e7c3a1be0e7241f140f88dfcf01f1c289286e09b05839f93218" + }, + { + "path": "web/worker/test_workspace_session_integration.mjs", + "sha256": "38f49df83c3ac24ef564c8cd5ed69b1a5882fa47c464946cb1945cac8ac163bf" + }, + { + "path": "web/worker/test_xyzac_exact_preview.mjs", + "sha256": "dc5cc312aab46003e12a4bfc26d695b05d78843e61808c550cb4a5925338687b" + }, + { + "path": "web/worker/test_xyzac_gate_matrix.mjs", + "sha256": "07e4f05f3b7bf470fb87ecea077587e7584928d28fe7e28932f8a649c960525d" + }, + { + "path": "web/worker/test_xyzac_hal_tool_alarm.mjs", + "sha256": "731ff64fc5b9abd70c6ab6649a2644e51e363bda710a0d4ec9faeffa3bb77db3" + }, + { + "path": "web/worker/test_xyzac_machine_sequence.mjs", + "sha256": "9dcd89d54596fe4b339d5aca4e028a0c44e173a8e646f1254defc706bd3fcc96" + }, + { + "path": "web/worker/test_xyzac_manual_control.mjs", + "sha256": "0f6320b0e08e73830c96b502c032c5720453973452c467fd08657e28b657ff3c" + }, + { + "path": "web/worker/test_xyzac_program_preview.mjs", + "sha256": "c1de259968bf0ec157486f5a9039fdf59d0cc7ec8aa52605f1d7c2605930519b" + }, + { + "path": "web/worker/test_xyzac_protocol_react.mjs", + "sha256": "69d942dfdcb7bc0d7fb26d6708220a47af13aa84acdcf490780980f6de0cc03d" + }, + { + "path": "web/worker/test_xyzac_recovery.mjs", + "sha256": "d8f02b0ab5b7c9fc5ef30a3a67f7896071ecf9bbaa7d2f3614c031d118e655e7" + }, + { + "path": "web/worker/test_xyzac_rtcp.mjs", + "sha256": "9bc14997e56a8d0f6f0043b3a92fa5efe0fc8b3fa9c973bffa9045446973208f" + }, + { + "path": "web/worker/test_xyzac_session.mjs", + "sha256": "76cd74a09a0318a33d70529f7c5b9cad25fd0daebd6dd8bb05f87b42626858ef" + }, + { + "path": "web/worker/test_xyzac_startup.mjs", + "sha256": "013023e5f0a01d93ed8ab568879937f462a97e2fe08742995f15775c867fb8aa" + }, + { + "path": "web/worker/test_xyzac_trace_parity.mjs", + "sha256": "f5c6a7cd3e8b7f72bb1b25b5c368c0e52d494b9c811022d34435e668612ec4ce" + }, + { + "path": "web/worker/test_xyzac_trt_case.mjs", + "sha256": "abdf50fba4103a7dabe13495cb62bc65019a152de2d91ed01150b968cdf7c147" + }, + { + "path": "web/worker/test_xyzac_trt_io_authority.mjs", + "sha256": "5be19961fe2c810e5a5ab17566febb8e024810c7bf3a492572728a085305ad96" + }, + { + "path": "web/worker/test_xyzac_trt_wasm_program_authority.mjs", + "sha256": "29a3babd0c0a31de7bd8a81748de484a698ebf7153bfb33822ee912049b3eafc" + }, + { + "path": "web/worker/test_xyzac_workflow.mjs", + "sha256": "6c738c6993d43b4ce16feecfe87d2b507824a88b06ead2f0659db6ca25c346b5" + }, + { + "path": "web/worker/trace-export.mjs", + "sha256": "9f775f6508359bd267f0b76299f19541f547f6282ea6d4569845bdc6f73f638b" + }, + { + "path": "web/worker/virtual-devices.mjs", + "sha256": "b6002fb4a0cbe2b8843388f8b541eb45a944ce42b1c7bfe4e6cd95d62a488b21" + }, + { + "path": "web/worker/wasm-home-limit.mjs", + "sha256": "5598ed4b52abdaefee7c9583098608e112b9f783ad8ea8853447a078186b1bd0" + }, + { + "path": "web/worker/wasm-motion-queue.mjs", + "sha256": "85b53bf7a31b9b1f1e7e76dad4bf29aabb36defcf6344d34bbb192c157a80764" + }, + { + "path": "web/worker/wasm-program-runtime.mjs", + "sha256": "60da7b953ac4ee2659f2b05c6bb93b58c8d0c2c4b56363f6a93e44aab7aebb02" + }, + { + "path": "web/worker/wasm-xyzac-device-io.mjs", + "sha256": "1d813d59048afb6854b6fd7783dc86f65bf37ccc46f0d4f592b56cbe044211a5" + }, + { + "path": "web/worker/wasm-xyzac-io.mjs", + "sha256": "fdb92e8819e38010aa7a1b8f5f58473a930644fbfeba3d7d5a5c23e075ee92ca" + }, + { + "path": "web/worker/wasm-xyzac-kinematics.mjs", + "sha256": "f14581a52830df5f55d612a1ec88d82737bb429ff63b5267ea3903984be6050e" + }, + { + "path": "web/worker/xyzac-command-ledger.mjs", + "sha256": "90d5fd10547f544338014a026a407cfb73f08c639bf0f1bef9c19a85fbcd16f5" + }, + { + "path": "web/worker/xyzac-scheduler.mjs", + "sha256": "0c7544298869c9c2858cce1275db8f3f2034655a5aa92aac5bd6dbf2b16e3221" + }, + { + "path": "web/worker/xyzac-session.mjs", + "sha256": "9cbbbd08ae372e515bafe906f87fe3a9552571f52997b4e5495b42a36097c6b3" + } + ], + "root": "web/worker" + } + }, + "schema": "xyzac-trt-wasm-authority-audit.v1", + "scope": "selected_xyzac_simulation_only", + "sources": [ + { + "lines": "107-739", + "path": "web/worker/sim-session.mjs", + "role": "session-authority-routing", + "sha256": "7ce91549f0f3a06ff77db9ee281fd9544848f6e41e08f9da302ee2e7827194e3", + "status": "resolved", + "symbol": "new ProgramRunner" + }, + { + "lines": "372-599", + "path": "web/worker/program-runner.mjs", + "role": "js-program-control-flow", + "sha256": "6b7dc1f8f857f6752d142212824c9598ad14017f1e706b0a4406e6e6976051f6", + "status": "resolved", + "symbol": "executeNext" + }, + { + "lines": "454-629", + "path": "web/worker/program-runner.mjs", + "role": "wasm-interpreter-call", + "sha256": "6b7dc1f8f857f6752d142212824c9598ad14017f1e706b0a4406e6e6976051f6", + "status": "resolved", + "symbol": "sim_interpreter_execute" + }, + { + "lines": "13-13", + "path": "web/worker/motion-state.mjs", + "role": "js-motion-state-mirror", + "sha256": "7acdbd55ca467ae9ada8d4dbeebf290b6d660c3c1a8eb86d750254464dc47c8e", + "status": "resolved", + "symbol": "export class MotionState" + }, + { + "lines": "68-68", + "path": "web/worker/authoritative-runtime.mjs", + "role": "js-compatibility-planner", + "sha256": "c2bdd03de958ffda38553ec6dbddb4b1f5c08b2cb636ba02f25f2b76bdd61604", + "status": "resolved", + "symbol": "export class AuthoritativeRuntime" + }, + { + "lines": "31-31", + "path": "web/worker/sim-task.mjs", + "role": "task-authority-wrapper", + "sha256": "4b4b3aa4b86aba08e5afb8534d98d6ab11c845eeb891cf4793b5906a01de1599", + "status": "resolved", + "symbol": "export class SimTask" + }, + { + "lines": "58-58", + "path": "web/worker/wasm-motion-queue.mjs", + "role": "wasm-motion-authority", + "sha256": "85b53bf7a31b9b1f1e7e76dad4bf29aabb36defcf6344d34bbb192c157a80764", + "status": "resolved", + "symbol": "export class WasmMotionQueue" + }, + { + "lines": "62-62", + "path": "web/worker/wasm-xyzac-kinematics.mjs", + "role": "wasm-xyzac-kinematics", + "sha256": "f14581a52830df5f55d612a1ec88d82737bb429ff63b5267ea3903984be6050e", + "status": "resolved", + "symbol": "export class WasmXyzacKinematics" + }, + { + "lines": "1-4", + "path": "web/worker/sim-worker.mjs", + "role": "dedicated-worker-wasm-bootstrap", + "sha256": "3b0670d4c6c9d8aab179534bacb8c984a6695ae9dffd58e376b6e854ee25e91b", + "status": "resolved", + "symbol": "createModule" + }, + { + "lines": "49-49", + "path": "web/react/src/worker-client.ts", + "role": "react-worker-boundary", + "sha256": "47fcfc52acd5ce6e5dbbd91cf9da45aa5a089a3172da6414a347de5039e36737", + "status": "resolved", + "symbol": "postMessage" + }, + { + "lines": "1-17", + "path": "web/react/src/sim-worker-entry.ts", + "role": "react-worker-wasm-bootstrap", + "sha256": "cab262b47dea50db0f0c666709153d00fd69820daa6666da7e923d5e798aa992", + "status": "resolved", + "symbol": "createModule" + }, + { + "lines": "56-68", + "path": "web/workspace/opfs-runtime.mjs", + "role": "worker-opfs-writer", + "sha256": "bfc9403491b76af3d91619969b6f8632401171cb1310656aa782b700c8a67316", + "status": "resolved", + "symbol": "createSyncAccessHandle" + }, + { + "lines": "47-47", + "path": "web/worker/wasm-program-runtime.mjs", + "role": "wasm-program-authority", + "sha256": "60da7b953ac4ee2659f2b05c6bb93b58c8d0c2c4b56363f6a93e44aab7aebb02", + "status": "resolved", + "symbol": "export class WasmProgramRuntime" + }, + { + "lines": "39-39", + "path": "web/worker/wasm-xyzac-io.mjs", + "role": "wasm-hal-io-tool-probe-authority", + "sha256": "fdb92e8819e38010aa7a1b8f5f58473a930644fbfeba3d7d5a5c23e075ee92ca", + "status": "resolved", + "symbol": "export class WasmXyzacIo" + }, + { + "lines": "39-39", + "path": "web/worker/wasm-xyzac-device-io.mjs", + "role": "wasm-device-io-authority", + "sha256": "1d813d59048afb6854b6fd7783dc86f65bf37ccc46f0d4f592b56cbe044211a5", + "status": "resolved", + "symbol": "export class WasmXyzacDeviceIo" + } + ], + "state_hashes": [ + "fnv1a64:b78114f0dff414b9", + "fnv1a64:b312225bf059254c", + "fnv1a64:c927914a74c8c3c2" + ], + "status": "verified", + "task_id": "WASM-00", + "tick_trace": [ + 0, + 0, + 0 + ], + "worker_evidence": { + "case": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "command": [ + "node", + "web/worker/test_xyzac_trt_case.mjs" + ], + "control_count": 110, + "first_divergent_tick": null, + "motion_authority": "wasm", + "output_sha256": "16b23b8d13afdc46f06ef8f9dd14c4bd93cc7511b4334efbcebe08120ddb4858", + "returncode": 0, + "state_hash": "fnv1a64:e862c9e59d9ffd8c", + "status": "verified", + "switchkins": [ + { + "active_type": 0, + "code": "M429", + "state_hash": "fnv1a64:b78114f0dff414b9", + "tick": 0 + }, + { + "active_type": 1, + "code": "M428", + "state_hash": "fnv1a64:b312225bf059254c", + "tick": 0 + }, + { + "active_type": 2, + "code": "M430", + "state_hash": "fnv1a64:c927914a74c8c3c2", + "tick": 0 + } + ], + "tick_sequence": [ + 0, + 0, + 0 + ], + "wasm_state_hash": "fnv1a64:000000001845a08b" + } +} diff --git a/coverage/xyzac-trt-wasm-only-release-gate.report.json b/coverage/xyzac-trt-wasm-only-release-gate.report.json new file mode 100644 index 0000000..eb745a2 --- /dev/null +++ b/coverage/xyzac-trt-wasm-only-release-gate.report.json @@ -0,0 +1,111 @@ +{ + "blocker_identity": [ + { + "classification": "HOST_EXCLUDED", + "detail": "Safari is explicitly excluded from this project", + "id": "safari_not_in_project_scope" + }, + { + "classification": "REAL-EXCLUDED", + "detail": "simulation environment intentionally excludes real physical power loss", + "id": "physical_power_loss_not_simulated" + }, + { + "classification": "HOST_EXCLUDED", + "detail": "only xyzac-trt.ini is selected", + "id": "other_linuxcnc_cases_out_of_scope" + } + ], + "candidate_eligible": false, + "case": { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "scope": "xyzac_only" + }, + "checks": { + "all_task_reports": { + "count": 14, + "status": "verified" + }, + "browser_matrix": { + "desktop": { + "canvas_nonblank": true, + "document_width": 1425, + "machine_nodes_in_tool_preview": 0, + "nonzero_pixels": 499671, + "scroll_width": 1425, + "status": "READY", + "toolpath_segments": 3, + "viewport": [ + 1440, + 1000 + ] + }, + "mobile": { + "canvas_nonblank": true, + "document_width": 390, + "machine_nodes_in_tool_preview": 0, + "nonzero_pixels": 114080, + "scroll_width": 390, + "status": "READY", + "toolpath_segments": 3, + "viewport": [ + 390, + 844 + ] + }, + "status": "verified" + }, + "recovery": { + "at_checkpoint_equal": true, + "continuous_hash": "fnv1a64:a4dee4490d19b4ec", + "restored_hash": "fnv1a64:ca9e3481aaa28f6d", + "status": "verified" + }, + "scope_exclusions": { + "Safari": "out_of_scope", + "host_hardware": "out_of_scope", + "other_cases": [ + "xyzbc", + "3axis" + ], + "physical_power_loss": "REAL-EXCLUDED", + "status": "verified" + }, + "selected_case": { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "status": "verified" + }, + "trace_parity": { + "first_divergent_tick": null, + "levels": [ + "protocol", + "control", + "state", + "canonical", + "recovery" + ], + "status": "verified" + }, + "wasm_authority": { + "authority": "linuxcnc-wasm-worker", + "js_authority": 0, + "status": "verified" + } + }, + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "failure_samples": [], + "input": { + "path": "coverage/xyzac-trt-web-wasm-parity.report.json", + "sha256": "d8bd04725525c1c5881d749466c8793f4b771e34ba260c5d35cb1d29f889d4fc" + }, + "known_blockers": [ + "STOP_RELEASE is intentional until an owner authorizes scope expansion" + ], + "outputs": [], + "release_decision": "selected_case_verified_but_release_stopped_by_scope_exclusions", + "release_status": "STOP_RELEASE", + "report_sha256": "70dc5704e2530f9a42d6f5985f242be4fc4b691a2272fd15b9fa0bd8031a0728", + "schema": "xyzac-trt-wasm-only-release-gate.v1", + "status": "verified", + "task_id": "RELEASE-00" +} diff --git a/coverage/xyzac-trt-web-wasm-parity.report.json b/coverage/xyzac-trt-web-wasm-parity.report.json new file mode 100644 index 0000000..79dc2e5 --- /dev/null +++ b/coverage/xyzac-trt-web-wasm-parity.report.json @@ -0,0 +1,138 @@ +{ + "authority": "linuxcnc-wasm-worker", + "authority_audit": {}, + "blocker_identity": { + "case_mismatches": [], + "failed_reports": [], + "host_excluded": [ + "Safari", + "physical power loss", + "host hardware" + ], + "missing_reports": [], + "release_status": "STOP_RELEASE" + }, + "browser_matrix": { + "canvas_context": "webgl2", + "console_exceptions": 0, + "desktop": { + "canvas_nonblank": true, + "document_width": 1425, + "machine_nodes_in_tool_preview": 0, + "nonzero_pixels": 499671, + "scroll_width": 1425, + "status": "READY", + "toolpath_segments": 3, + "viewport": [ + 1440, + 1000 + ] + }, + "functional_note": "Chromium simulation only; Safari and physical power loss are excluded by scope", + "mobile": { + "canvas_nonblank": true, + "document_width": 390, + "machine_nodes_in_tool_preview": 0, + "nonzero_pixels": 114080, + "scroll_width": 390, + "status": "READY", + "toolpath_segments": 3, + "viewport": [ + 390, + 844 + ] + }, + "preserve_drawing_buffer": true + }, + "candidate_eligible": false, + "case": { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "scope": "xyzac_only" + }, + "checks": { + "all_reports_present": true, + "all_reports_verified": true, + "all_selected_case": true, + "browser_desktop_mobile": true, + "recovery_endpoint_equal": true, + "trace_first_divergent_tick_null": true + }, + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "exclusions": [ + "xyzbc", + "3axis", + "other cases", + "Safari", + "physical power loss", + "host hardware" + ], + "failure_samples": [], + "known_blockers": [ + "HOST_EXCLUDED: Safari not in project scope", + "REAL-EXCLUDED: physical power loss not simulated" + ], + "parity": { + "first_divergent_tick": null, + "native_wasm": "verified", + "native_worker": "verified", + "positive_divergence_tick": 2, + "trace_levels": [ + "protocol", + "control", + "state", + "canonical", + "recovery" + ] + }, + "recovery": { + "at_checkpoint_equal": true, + "continuous_hash": "fnv1a64:a4dee4490d19b4ec", + "restored_hash": "fnv1a64:ca9e3481aaa28f6d" + }, + "release_status": "STOP_RELEASE", + "report_hashes": { + "coverage/xyzac-trt-gate-matrix.report.json": "495f452f59848114bb885561e26e7080f356650cc1b620cfddf515685fbf1628", + "coverage/xyzac-trt-hal-tool-alarm.report.json": "2abcfd59bf16e596c9183296061ff66ce00f6d9b6efee121519a499007001216", + "coverage/xyzac-trt-manual-control.report.json": "b7333980194ff9b6344d34ec97a181fbb79b5730184dd13a6d1a9067c9212af9", + "coverage/xyzac-trt-program-preview.report.json": "ee41e2b4ac97f719817e21eee2bd3d503fc78c783ec1bc185466b3c56fc62045", + "coverage/xyzac-trt-protocol-react.report.json": "bc25315930095ca096bae0f97047c41d45bf9ff83373ac7a73f52273b33d9237", + "coverage/xyzac-trt-recovery.report.json": "deff32f2998930dfcd9373ca0a6a960d1fa7e5732ef785cc7cacf336b9dc3459", + "coverage/xyzac-trt-rtcp.report.json": "b1562d6d2c9cd5144c7c8c9b334bd8bf67919ea7297f103ec67cb32773608d08", + "coverage/xyzac-trt-source-slice-inventory.report.json": "20382f2bcd13fdaf3f25521b7a8c42e83e0409f75092c643b4c79a7613fdf287", + "coverage/xyzac-trt-startup.report.json": "56e040b645bcefc3d6c57244cb2d3aba16f421ff5137089d9c3336970dfd968b", + "coverage/xyzac-trt-threejs.report.json": "2791930c38a48ab9fa61f284e57483708787e89b558c75ddc9d99e4b3e76ad28", + "coverage/xyzac-trt-tool-preview.report.json": "4a5b286b0a13324a1e773669ef34ab9a64fd0376dfaf5adf39a95d9b420bd965", + "coverage/xyzac-trt-trace-parity.report.json": "ef914bb7823b9cdb0f6e15ca409515659d5575d09cdc6da2c458cd81fafa595a", + "coverage/xyzac-trt-wasm-authority-audit.report.json": "e7c84d3f36db280c13c1ab8a29f4f827b4257eb34b8cb2bbc47357a920001692", + "coverage/xyzac-trt-workflow.report.json": "ede73fab04f3cc3e64a13fbe0ab10603253e9a01b4357feff1f3f54313777e75" + }, + "report_sha256": "bf2f04c1798cd43016833836bab8c789ca71699ae414746601ae0efed010666d", + "schema": "xyzac-trt-web-wasm-parity-report.v1", + "source_coverage": { + "axis_keyboard": 10, + "axis_menus": 80, + "axis_toolbar": 20, + "blocked_resources": 0, + "direct_sources": 35, + "slices": 11, + "unregistered_slices": 0 + }, + "status": "verified", + "task_id": "RTCP-12", + "task_reports": { + "coverage/xyzac-trt-gate-matrix.report.json": "verified", + "coverage/xyzac-trt-hal-tool-alarm.report.json": "verified", + "coverage/xyzac-trt-manual-control.report.json": "verified", + "coverage/xyzac-trt-program-preview.report.json": "verified", + "coverage/xyzac-trt-protocol-react.report.json": "verified", + "coverage/xyzac-trt-recovery.report.json": "verified", + "coverage/xyzac-trt-rtcp.report.json": "verified", + "coverage/xyzac-trt-source-slice-inventory.report.json": "verified", + "coverage/xyzac-trt-startup.report.json": "verified", + "coverage/xyzac-trt-threejs.report.json": "verified", + "coverage/xyzac-trt-tool-preview.report.json": "verified", + "coverage/xyzac-trt-trace-parity.report.json": "verified", + "coverage/xyzac-trt-wasm-authority-audit.report.json": "verified", + "coverage/xyzac-trt-workflow.report.json": "verified" + } +} diff --git a/coverage/xyzac-trt-workflow.report.json b/coverage/xyzac-trt-workflow.report.json new file mode 100644 index 0000000..0c7a979 --- /dev/null +++ b/coverage/xyzac-trt-workflow.report.json @@ -0,0 +1,63 @@ +{ + "abort_queue_empty": true, + "active_segment_before_abort": 1, + "authority": "linuxcnc-wasm-worker", + "candidate_eligible": true, + "case": { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "sha256": "f985970db293b70c055e4c41fc316d0c16037b5dc7ce07490e18f554e851f811" + }, + "command_trace": [ + "PROGRAM_LOAD", + "PROGRAM_RUN", + "SIM_STEP", + "PROGRAM_PAUSE", + "SNAPSHOT_REQUEST", + "PROGRAM_RESUME", + "SIM_STEP", + "PROGRAM_ABORT", + "PROGRAM_RESTART", + "PROGRAM_SEEK", + "PROGRAM_RESUME", + "SIM_STEP", + "CHECKPOINT", + "RECOVER" + ], + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "failure_samples": [], + "pause_cursor_stable": true, + "recovery_status": "recovered", + "release_status": "STOP_RELEASE", + "report_sha256": "d98a16e6582c0bc9fdaa410da64be369cc21d56a61a04b43436d4900c12461b0", + "restart_source_hash_preserved": true, + "run_from_line": 4, + "schema": "xyzac-workflow-rtcp-05.v1", + "scope": "xyzac_only", + "state_hash": "fnv1a64:285d97dde7d56ea7", + "status": "verified", + "task_id": "RTCP-05", + "tests": [ + { + "command": [ + "node", + "web/worker/test_xyzac_workflow.mjs" + ], + "output_sha256": "197bc634f7f9ddf290b1a64d3cbd1f52d257dcc4982e5de3bd16f6358c70702b", + "returncode": 0, + "status": "verified" + } + ], + "tick_trace": [ + 1 + ], + "workflow": { + "abort": "verified", + "pause": "verified", + "recovery": "verified", + "restart": "verified", + "resume": "verified", + "run": "verified", + "run_from_line": "verified", + "step": "verified" + } +} diff --git a/doc-g/5axis-rtcp-running.png b/doc-g/5axis-rtcp-running.png new file mode 100644 index 0000000..e5d9a81 Binary files /dev/null and b/doc-g/5axis-rtcp-running.png differ diff --git a/doc-g/5axis-rtcp-shortcut.md b/doc-g/5axis-rtcp-shortcut.md new file mode 100644 index 0000000..629fe0a --- /dev/null +++ b/doc-g/5axis-rtcp-shortcut.md @@ -0,0 +1,62 @@ +# 五轴 RTCP 案例快捷方式 + +快捷方式:[`../run-5axis-rtcp.sh`](../run-5axis-rtcp.sh) + +默认执行: + +```bash +./run-5axis-rtcp.sh +``` + +默认案例是: + +```text +linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini +``` + +它使用 `XYZAC` 五轴表旋转/倾斜(TRT)拓扑、`xyzac-trt-kins` 和 Vismach `xyzac-trt-gui`。默认演示程序是: + +```text +linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc +``` + +该顶层演示调用 `remap_subs/xyzac_switchkins_sub.ngc`;其螺旋插补子程序 `remap_subs/helix_ac.ngc` 使用: + +```gcode +M428 ;TCP:xyzac +``` + +`M428` 通过 remap 将 `motion.switchkins-type` 切换到 XYZAC TCP/RTCP 运动学;`helix_ac.ngc` 在需要机床坐标定位时使用 `M429` 切回 identity,再用 `M428` 进入 TCP。配置的 `M430` 进入 userk。AXIS 右侧的 `TCP:XYZAC` 按钮也提供同一切换入口。 + +## XYZBC 变体 + +快捷方式接受可选配置名: + +```bash +./run-5axis-rtcp.sh xyzbc-trt.ini +``` + +该变体使用 `XYZBC` 和 `xyzbc-trt-kins`,默认程序为 `demos/xyzbc_switchkins.ngc`。 + +## 启动证据 + +![五轴 XYZAC RTCP 案例运行](5axis-rtcp-running.png) + +实测启动结果: + +- AXIS 标题:`xyzac_switchkins.ngc - AXIS 2.10.0~pre1 on sim-xyzac-trt-kins (switchkins)`。 +- 右侧 `SWITCHKINS` 面板显示 `TCP:XYZAC`。 +- Vismach 预览显示五轴机床和多轴刀具轨迹。 +- LinuxCNC 状态接口返回 `file=./demos/xyzac_switchkins.ngc`,`COORDINATES=XYZAC`。 +- 当前环境使用 POSIX non-realtime 回退;这验证的是仿真配置和 RTCP 路径,不是实时硬件性能。 + +## 来源依据 + +- `linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini` +- `linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc` +- `linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/xyzac_switchkins_sub.ngc` +- `linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_ac.ngc` +- `linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc` +- `linuxcnc/src/emc/kinematics/xyzac-trt-kins.c` +- `linuxcnc/src/emc/kinematics/trtfuncs.c` +- `linuxcnc/docs/src/motion/5-axis-kinematics.adoc` diff --git a/doc-g/README.md b/doc-g/README.md new file mode 100644 index 0000000..bb567c2 --- /dev/null +++ b/doc-g/README.md @@ -0,0 +1,29 @@ +# GMOCCAPY 调查资料 + +本目录保存本次 GMOCCAPY 实机仿真检查的截图、文件清单、源码分析和加载测试证据。后续与本案例有关的分析文档继续写入 `./doc-g`,不把临时调查结论散落到项目根目录。 + +## 入口 + +- [五轴 RTCP 文档集](../doc-rtcp/README.md) +- [HTML 图文使用说明](generate.html) +- [五轴 RTCP 快捷方式](5axis-rtcp-shortcut.md) +- [控制面板数据流与控制流](gmoccapy-control-panel-data-control-flow.md) +- [GMOCCAPY 分析报告](gmoccapy-analysis.md) +- [逐文件清单](gmoccapy-file-inventory.md) +- [机器可读清单](gmoccapy-file-inventory.json) + +## 截图 + +- `gmoccapy-important-changes.png`:用户提供的首次启动提示。 +- `gmoccapy-important-changes-v2.png`:本轮新增的用户截图证据,已与系统 GMOCCAPY 3.5.2 源码逐项对照。 +- `gmoccapy-before-load.png`:主界面尚未加载程序。 +- `gmoccapy-after-popup-close.png`:关闭提示后的主界面。 +- `gmoccapy-load-file-page.png`:实际打开的程序文件选择页,能看到 `.ngc` 文件。 +- `gmoccapy-program-loaded.png`:通过 LinuxCNC API 加载 `3dtest.ngc` 后的路径和刀具轨迹。 + +## 可复现命令 + +```bash +./run-gmoccapy.sh +python3 doc-g/generate_inventory.py +``` diff --git a/doc-g/generate.html b/doc-g/generate.html new file mode 100644 index 0000000..a1146cd --- /dev/null +++ b/doc-g/generate.html @@ -0,0 +1,264 @@ + + + + + + GMOCCAPY 仿真使用说明 + + + +
+

GMOCCAPY 仿真使用说明

+

从首次启动提示、进入 AUTO、选择 G-code,到确认程序已加载。红色箭头表示需要点击的位置;本手册基于当前工作区的实际 GMOCCAPY 截图和源码分析。

+
+ +
+ + +
+
+

快速流程

+
    +
  1. 启动项目快捷方式:./run-gmoccapy.sh。
  2. +
  3. 首次弹窗出现时,点击右侧 X;可选中“Don't show this again”。
  4. +
  5. 确认机器上电并完成 homing,然后点击右侧第三个模式按钮进入 AUTO。
  6. +
  7. 进入 AUTO 后,在 AUTO 按钮组中点击“打开文件”图标,选择 .ngc 文件。
  8. +
  9. 点击文件选择页底部的绿色对勾确认,检查顶部文件路径和刀具轨迹。
  10. +
  11. 加载不会自动运行;确认安全后再点击 Run,或使用 R 快捷键。
  12. +
+
+ + + +
+

2. 进入 AUTO 模式

+

关键点:你要找的“加载程序”按钮不在当前 MANUAL/JOG 页面。它只有在切换到 AUTO 后,才会被放入 AUTO 专用按钮组。

+
+
+ 关闭提示后的 GMOCCAPY 主界面 + +
+
箭头指向右侧竖向模式按钮中的 AUTO 图标。若该按钮灰色,先处理“急停、上电、homing”状态。
+
+

具体点击顺序

+
    +
  1. 先看右侧竖条。从上到下通常是急停、上电、AUTO、MDI 等图标。点击第三个“彩色小方块/机床箭头”图标,不要点击 MDI 计算器图标。
  2. +
  3. 等待页面切换。右侧或底部按钮区域会从手动点动按钮切换为 AUTO 按钮组。窗口大小、主题和侧面板会改变图标的排列,但按钮的 tooltip 仍是 Load a new program。
  4. +
  5. 再点打开文件按钮。在 AUTO 按钮组中寻找文件夹/打开文件图标。它的源码 ID 是 btn_load,不是文件选择页里的绿色对勾。
  6. +
  7. 看到文件网格才算进入选择界面。点击 btn_load 后,GMOCCAPY 才会打开“选择 G-code 程序”界面;源码函数是 on_btn_load_clicked(),它把按钮页切换到文件选择页。
  8. +
+
+
A
右侧第三个 AUTO 图标rbt_auto:先切换按钮组。
+ +
B
AUTO 页面中的打开文件图标btn_load,tooltip 为 Load a new program;点击它才打开文件选择界面。
+ +
C
文件网格和底部绿色对勾btn_select:选择文件后确认返回路径。
+
+

在 AUTO 页面里,具体就是这个打开文件图标

+

下图不是另一个入口,而是从 GMOCCAPY Glade 的 hbtb_auto 按钮组和当前 icon theme 放大的控件图。红框和箭头明确标出 btn_load;鼠标悬停时 tooltip 是 Load a new program。

+ +
如果你只看到右侧 AUTO 图标而没有这排按钮:你还没有完成 AUTO 页面切换,或者 AUTO 被急停/未上电/未 homing 状态门控。先点击上面的 AUTO 入口,等按钮组切换完成,再寻找红框位置。
+
不要把两个按钮混淆:btn_load 负责“打开文件选择界面”;文件界面底部的绿色对勾 btn_select 负责“确认当前选中的文件”。
+
当前仿真配置的共享 home switch 曾报告 Cannot home while shared home switch is closed j=2。这会让 AUTO 保持门控;它是仿真 HAL 状态问题,不是加载按钮消失。
+
+ +
+

3. 选择 G-code 程序

+

只有完成上一节的 AUTO → 打开文件图标 两次点击后,才会出现下面这个文件界面。进入文件页后,GMOCCAPY 会按配置中的 PROGRAM_PREFIX = ../../nc_files/ 显示程序。当前配置解析到:

+
/home/mes006/linuxcncWebWASM/linuxcnc/nc_files/
+
+
+ GMOCCAPY 文件选择页 + +
+
示例中可以看到 3dtest.ngc。底部右侧绿色对勾用于返回选中的路径;黄色弯箭头用于返回上一页。文件网格不会在 MANUAL/JOG 页面直接出现。
+
+

界面出现后的点击顺序

+
    +
  1. 在文件网格中单击目标文件,例如 3dtest.ngc;选中项会出现高亮。
  2. +
  3. 点击底部右侧绿色对勾(btn_select)。它会返回文件路径并关闭文件选择页。
  4. +
  5. 回到主界面后,顶部标题应显示完整路径,预览区应显示刀具轨迹。
  6. +
+
+ +
+

4. 确认程序已经加载

+

加载成功后,顶部标题不再是 No Program loaded,而会显示完整文件路径;左侧预览区会出现刀具轨迹。加载本身不会启动运动。

+
+
+ 3dtest.ngc 已加载并显示刀具轨迹 + +
+
本次测试加载的文件是 3dtest.ngc;LinuxCNC 状态接口返回该路径,解释器保持空闲。
+
+
+ +
+

常见问题

+
+
看不到加载按钮按“关闭首次提示 → 右侧第三个 AUTO 图标 → AUTO 按钮组中的打开文件图标”顺序操作。文件网格本身不是入口,它是点击 btn_load 之后才出现的。
+
AUTO 图标是灰色检查急停复位、机器上电和 homing。GMOCCAPY 会在状态不满足时禁用模式切换。
+
加载后没有运动这是正常的。加载只生成程序和预览;要执行必须点击 Run 或按 R。
+
启动日志提示 POSIX non-realtime当前环境没有实时内核。可用于仿真界面和加载检查,但不能作为实时硬件性能证明。
+
+
+ +
+

源码、配置与证据

+ + + + + + + + + + + +
项目位置用途
AUTO 入口rbt_auto / on_rbt_auto_pressed右侧第三个模式按钮;先进入 AUTO,加载按钮才可见。
AUTO 按钮组hbtb_autoGMOCCAPY Glade 中承载打开、重载、运行、停止、暂停和单步按钮。
加载按钮gmoccapy.py:5046、btn_load切换到文件选择页。
文件确认gmoccapy.py:5116、btn_select将选中的文件交给 hal_action_open.load_file(path)。
程序目录configs/sim/gmoccapy/gmoccapy.iniPROGRAM_PREFIX = ../../nc_files/。
逐文件分析gmoccapy-file-inventory.md1,233 个配置、实现、资源、图标、翻译和文档文件的哈希清单。
完整分析gmoccapy-analysis.md本次提示、界面、加载测试和限制的详细记录。
+

本页是静态 HTML,不依赖网络。复制整个 doc-g 目录后,直接用浏览器打开本文件即可。

+
+
+
+ + + diff --git a/doc-g/generate_inventory.py b/doc-g/generate_inventory.py new file mode 100644 index 0000000..f70a85e --- /dev/null +++ b/doc-g/generate_inventory.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 +"""Build a deterministic inventory for the GMOCCAPY source and case assets.""" + +from __future__ import annotations + +import hashlib +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +OUT = Path(__file__).resolve().parent + + +def sha256(path: Path) -> str: + return hashlib.sha256(path.read_bytes()).hexdigest() + + +def classify(rel: str) -> str: + path = Path(rel) + if "/configs/sim/gmoccapy/" in rel: + if path.suffix == ".ini": + return "simulation_ini" + if path.suffix in {".hal", ".tbl", ".para", ".var", ".pref"}: + return "simulation_runtime_data" + if path.suffix in {".ngc", ".py", ".ui", ".glade", ".svg", ".txt", ".README"}: + return "simulation_resource" + return "simulation_asset" + if "/src/emc/usr_intf/gmoccapy/" in rel or "/lib/python/gmoccapy/" in rel: + return "implementation" + if "/share/gmoccapy/" in rel: + if "icons/" in rel: + return "icon_asset" + return "installed_ui_asset" + if "/src/po/gmoccapy/" in rel: + return "translation" + if "/docs/src/gui/images/gmoccapy_" in rel or "/docs/src/user/images/gmoccapy_" in rel: + return "documentation_asset" + if "/docs/src/gui/gmoccapy" in rel or "/docs/man/man1/gmoccapy" in rel: + return "documentation" + return "cross_reference" + + +def collect(paths: list[Path]) -> list[dict[str, object]]: + files: list[Path] = [] + for base in paths: + if base.is_file(): + files.append(base) + elif base.is_dir(): + files.extend(p for p in base.rglob("*") if p.is_file()) + rows = [] + for path in sorted(set(files)): + rel = path.relative_to(ROOT).as_posix() + rows.append( + { + "path": rel, + "role": classify(rel), + "bytes": path.stat().st_size, + "sha256": sha256(path), + } + ) + return rows + + +def main() -> None: + rows = collect( + [ + ROOT / "linuxcnc/configs/sim/gmoccapy", + ROOT / "linuxcnc/src/emc/usr_intf/gmoccapy", + ROOT / "linuxcnc/lib/python/gmoccapy", + ROOT / "linuxcnc/share/gmoccapy", + ROOT / "linuxcnc/src/po/gmoccapy", + ROOT / "linuxcnc/docs/src/gui/gmoccapy.adoc", + ROOT / "linuxcnc/docs/man/man1/gmoccapy.1", + *sorted((ROOT / "linuxcnc/docs/src/gui/images").glob("gmoccapy_*")), + *sorted((ROOT / "linuxcnc/docs/src/user/images").glob("gmoccapy_*")), + ] + ) + summary: dict[str, int] = {} + for row in rows: + role = str(row["role"]) + summary[role] = summary.get(role, 0) + 1 + payload = { + "schema": "gmoccapy-file-inventory.v1", + "scope": [ + "linuxcnc/configs/sim/gmoccapy/**", + "linuxcnc/src/emc/usr_intf/gmoccapy/**", + "linuxcnc/lib/python/gmoccapy/**", + "linuxcnc/share/gmoccapy/**", + "linuxcnc/src/po/gmoccapy/**", + "linuxcnc/docs/src/gui/gmoccapy.adoc", + "linuxcnc/docs/man/man1/gmoccapy.1", + "linuxcnc/docs/src/gui/images/gmoccapy_*", + "linuxcnc/docs/src/user/images/gmoccapy_*", + ], + "file_count": len(rows), + "role_counts": dict(sorted(summary.items())), + "files": rows, + } + (OUT / "gmoccapy-file-inventory.json").write_text( + json.dumps(payload, ensure_ascii=False, sort_keys=True, indent=2) + "\n", + encoding="utf-8", + ) + lines = [ + "# GMOCCAPY 文件清单", + "", + f"清单范围内共 `{len(rows)}` 个文件;每项包含相对路径、角色、字节数和 SHA-256。", + "", + "| 角色 | 数量 |", + "|---|---:|", + ] + lines.extend(f"| `{role}` | {count} |" for role, count in sorted(summary.items())) + lines.extend(["", "完整逐文件数据见 [`gmoccapy-file-inventory.json`](gmoccapy-file-inventory.json)。", ""]) + (OUT / "gmoccapy-file-inventory.md").write_text("\n".join(lines), encoding="utf-8") + + +if __name__ == "__main__": + main() diff --git a/doc-g/gmoccapy-3dtest-loaded-through-ui.png b/doc-g/gmoccapy-3dtest-loaded-through-ui.png new file mode 100644 index 0000000..52d3735 Binary files /dev/null and b/doc-g/gmoccapy-3dtest-loaded-through-ui.png differ diff --git a/doc-g/gmoccapy-after-popup-close.png b/doc-g/gmoccapy-after-popup-close.png new file mode 100644 index 0000000..cf2cfce Binary files /dev/null and b/doc-g/gmoccapy-after-popup-close.png differ diff --git a/doc-g/gmoccapy-analysis.md b/doc-g/gmoccapy-analysis.md new file mode 100644 index 0000000..d01d651 --- /dev/null +++ b/doc-g/gmoccapy-analysis.md @@ -0,0 +1,170 @@ +# GMOCCAPY 分析与加载测试 + +更新时间:2026-08-25 + +## 结论 + +“没有看到加载程序按钮”不是按钮缺失,而是首次启动提示和 GMOCCAPY 的模式门控共同造成的视觉结果: + +1. 首次启动会弹出模态的 `Important change(s)` 窗口。该窗口覆盖主界面并阻止底层点击;用户截图中的右侧 `X` 是关闭按钮,底部复选框是 `Don't show this again`。 +2. 加载按钮只属于 AUTO 页面按钮组,不属于 MANUAL/JOG 页面。源码将它声明为 `btn_load`,提示为 `Load a new program`,图标为 `img_open`。 +3. AUTO 模式还受机器状态和 homing 门控。`gmoccapy.py` 在未满足状态时会禁用 `rbt_auto`,并提示 `It is not possible to change to Auto Mode at the moment`。 +4. 关闭首次提示、进入 AUTO 后,点击文件夹/打开文件图标会进入文件选择页。当前 `gmoccapy.ini` 的 `PROGRAM_PREFIX = ../../nc_files/` 解析到 `linuxcnc/nc_files`。 + +## 用户截图分析 + +![首次启动提示](gmoccapy-important-changes.png) + +用户提供的图片尺寸为 `697 x 837`,内容是 GMOCCAPY 3.5.x 的版本变更提示: + +- LinuxCNC 2.10/GMOCCAPY 3.5.0 不再在换刀后自动保留 G43;需要通过 REMAP 实现自动重新激活。 +- 3.5.1 的工具表和偏置页默认使用计算器输入,可在设置或按钮中改变。 +- MDI 和 G-code 编辑模式新增调用计算器的按钮。 +- `release notes` 是橙色链接;右下方复选框用于永久隐藏该提示。 + +这张提示不是文件选择器,也不是加载失败信息。应先关闭它,再操作主界面。 + +### 新截图的源码逐项对照 + +![用户提供的最新提示截图](gmoccapy-important-changes-v2.png) + +这张截图与前一张内容一致,尺寸为 `697 x 837`,SHA-256 为 `df7322c30bcb6af131591a04b11cad24e7b6d186beaff83059fcfd8ffbae2d1b`。截图中的每一块文字都能在当前系统安装的 `/usr/bin/gmoccapy` 中找到: + +| 截图区域 | 源码证据 | 含义 | +|---|---|---| +| `Important change(s)` 标题 | `/usr/bin/gmoccapy:557-560` | `_startup_message()` 建立启动提示标题;注释要求新增消息只能追加,不能删除旧消息,否则隐藏索引会错位。 | +| 3.5.0 G43 提示 | `/usr/bin/gmoccapy:561-563` | GMOCCAPY 3.5.0 不再承诺换刀后自动保留 G43;想自动恢复必须使用 REMAP,示例在 GMOCCAPY 仿真配置中。 | +| 3.5.1 计算器提示 | `/usr/bin/gmoccapy:564-565` | 工具表和偏置页默认启用计算器输入;设置或页面按钮可以关闭;MDI 和 G-code 编辑页也增加了计算器按钮。 | +| `release notes` 链接 | `/usr/bin/gmoccapy:570-573` | 以 Pango markup 拼接 LinuxCNC 官方 release notes URL,并通过通知组件显示。点击它会打开文档,不会关闭提示。 | +| `Don't show this again` | `notification.py:151-155` | `show_checkbox=True` 时创建 GTK `CheckButton`;它不是普通说明文字,而是真正影响后续启动行为的复选框。 | +| 右侧 `X` | `notification.py:156-164` | 创建名为 `notification_close` 的 48x48 关闭按钮;点击后删除该消息,并把复选框状态发回 GMOCCAPY。 | + +### 弹窗什么时候出现 + +系统运行时在 GUI 初始化和周期任务准备完成后,于 `/usr/bin/gmoccapy:519` 调用 `_startup_message()`。它读取偏好项 `hide_startup_messsage`(注意源码中确实有三个 `s` 的拼写): + +```python +hide_message = self.prefs.getpref("hide_startup_messsage", 0, int) +if hide_message < len(messages): + ... + self.notification.add_message(message, INFO_ICON, show_checkbox=True) +``` + +当前消息数组有两项,因此默认值 `0` 会显示两项。关闭时如果复选框被勾选,`/usr/bin/gmoccapy:6241-6242` 将 `self.num`(当前为 `2`)写回 `hide_startup_messsage`。下次启动判断 `2 < 2` 为假,提示不再出现。普通点击 `X` 不勾选复选框时,只删除本次通知,下次仍会显示。 + +### 版本边界:截图运行时与仓库锁定源不同 + +这是本次分析中最重要的来源边界: + +- 截图对应的实际运行程序是 `/usr/bin/gmoccapy`,其中 `_RELEASE = "3.5.2"`,并包含 `_startup_message()`、3.5.0/3.5.1 文本和隐藏偏好逻辑。 +- 仓库锁定源是 `linuxcnc/VERSION = 2.10.0~pre0`;`linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.py:79` 的版本为 `3.4.3`,该文件没有 `_startup_message()` 实现,也没有截图中的 3.5.0/3.5.1 文本。 +- 本地启动日志曾显示 `LinuxCNC 2.10.0~pre1` 和 `gmoccapy 3.5.2`,与截图完全一致。因此这张截图是系统安装包的运行时证据,不应反向宣称锁定仓库 2.10.0~pre0/3.4.3 源码已经包含该功能。 + +已记录的运行时文件哈希: + +```text +/usr/bin/gmoccapy 11e7aee9216d24e4cc41018306f2541845bca9a9d6e16c38580f3ede9cca8d4d +/usr/share/gmoccapy/gmoccapy.glade 5fdc1557b02a716d30414fe739614fcd7c1d14cbe2e0a4c202c567a60b460adb +/usr/lib/python3/dist-packages/gmoccapy/notification.py + e0317fea738745f480c79d1f690bc52e88cc7f81bb4d14fa09c8c7196afb4e2f +``` + +### 用户应如何处理 + +1. 只想本次继续操作:点击右侧 `X`,不要勾选复选框。 +2. 不想以后重复看到:先勾选 `Don't show this again`,再点击 `X`。 +3. 想查看变更依据:点击 `release notes`,但这需要浏览器/网络或本地文档可用。 +4. 使用 G43 的程序:不要仅依赖界面自动行为;在 AUTO 程序中按机床配置和 REMAP 约定明确处理刀具长度补偿,并在正式加工前验证工具表和偏置。 + +## 实际界面证据 + +### 未加载状态 + +![未加载程序](gmoccapy-before-load.png) + +主界面顶部显示 `No Program loaded`。右侧竖向按钮中第三个为 AUTO 模式图标;在 MANUAL 页面时,AUTO 页面里的 `Load a new program` 不会显示在当前按钮组。 + +### 文件选择页 + +![加载程序文件选择页](gmoccapy-load-file-page.png) + +这张截图是实际运行 GMOCCAPY 后进入的文件选择页。页面显示 `gcmc_lib`、`macros`、`ngcgui_lib` 等目录以及 `3D_Chips.ngc`、`3dtest.ngc` 等程序。底部右侧绿色对勾是确认选择,右下黄色回退箭头是返回。 + +进入这张页面的完整点击链是: + +1. 关闭首次 `Important change(s)` 模态提示。 +2. 在主界面右侧点击第三个模式图标,进入 AUTO;源码控件为 `rbt_auto`。 +3. 等待 AUTO 按钮组出现,在其中点击打开文件图标;源码控件为 `btn_load`,tooltip 为 `Load a new program`。 +4. `on_btn_load_clicked()` 将按钮页切换到文件选择页;此时才会看到本截图中的文件网格。 +5. 选中 `.ngc` 文件后点击底部绿色对勾,源码控件为 `btn_select`。 + +因此,文件网格不是主界面的固定按钮,也不是 MDI 入口;在 MANUAL/JOG 页面直接寻找它不会找到。 + +### 加载后的程序 + +![加载 3dtest.ngc 后](gmoccapy-program-loaded.png) + +通过 LinuxCNC 的 `command.program_open()` 加载: + +```text +/home/mes006/linuxcncWebWASM/linuxcnc/nc_files/3dtest.ngc +``` + +加载成功的证据是: + +- 顶部由 `No Program loaded` 变成完整程序路径; +- 预览区出现 G-code 刀具轨迹; +- `linuxcnc.stat().file` 返回上述路径; +- `interp_state` 保持空闲,加载本身不会自动运行程序。 + +## 源码与界面映射 + +| 层 | 文件/符号 | 结论 | +|---|---|---| +| 主逻辑 | `linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.py` | `on_btn_load_clicked()` 切到文件选择页;`on_IconFileSelection1_selected()` 调用 `hal_action_open.load_file(path)`。 | +| 加载按钮 | `btn_load` / `img_open` | tooltip 是 `Load a new program`,只在 AUTO 按钮页 `hbtb_auto`。 | +| 运行按钮 | `btn_run` / `img_run` | tooltip 是 `Run the loaded program`;加载后仍需手动运行。 | +| 文件确认 | `btn_select` / `img_select` | tooltip 是 `select the highlighted file and return the path`。 | +| 返回 | `btn_back_file_load` / `img_back_file_load` | 关闭文件选择页但不返回路径。 | +| 文件资源 | `linuxcnc/lib/python/gladevcp/iconview.py` 及 GMOCCAPY 初始化 | 读取 `PROGRAM_PREFIX`,按配置扩展名展示文件和目录。 | +| 首次提示 | GMOCCAPY preferences/release-notes 逻辑 | 模态提示优先于主界面,必须先关闭。 | + +## 配置与资源分析 + +默认配置为 `linuxcnc/configs/sim/gmoccapy/gmoccapy.ini`: + +- `[DISPLAY] DISPLAY = gmoccapy`:选择 GMOCCAPY GUI。 +- `[DISPLAY] PROGRAM_PREFIX = ../../nc_files/`:从配置目录解析到 `linuxcnc/nc_files`。 +- `[RS274NGC] PARAMETER_FILE = sim.var`:仿真参数文件。 +- `[RS274NGC] SUBROUTINE_PATH = macros`:宏和子程序搜索路径。 +- `[EMCIO] TOOL_TABLE = tool.tbl`:工具表。 +- `[HAL]` 加载 `core_sim.hal`、`spindle_sim.hal`、`simulated_home.hal`,并在 GUI 启动后加载 `gmoccapy_postgui.hal`。 + +`configs/sim/gmoccapy` 不是单一案例,而是一组配置族,包含标准三轴、四轴、XYZAB/XYZAC/XYZCW、多轴、侧面板、消息、工具传感器、用户页、等离子和车床配置。完整逐文件路径与哈希见 [文件清单](gmoccapy-file-inventory.md)。 + +## 运行环境与限制 + +- 启动入口:[`../run-gmoccapy.sh`](../run-gmoccapy.sh),默认执行 `gmoccapy.ini`。 +- 实际 GUI 进程:`/usr/bin/python3 /usr/bin/gmoccapy -ini .../gmoccapy.ini`。 +- 当前环境没有实时内核,LinuxCNC 日志明确回退到 POSIX non-realtime;这不影响本次“加载和预览”验证,但不等同于实时硬件运行验证。 +- `simulated_home.hal` 的共享 home switch 在本次手动尝试中报告 `Cannot home while shared home switch is closed j=2`,因此 AUTO 模式按钮可能保持禁用。加载程序本身仍可通过 GUI 文件页/API 验证。 +- 加载和运行是两个动作:`program_open` 只读入程序并生成预览;需要 `AUTO` 页面中的 Run 按钮或 `R` 快捷键才会执行。 + +## 推荐操作顺序 + +1. 启动 `./run-gmoccapy.sh`。 +2. 关闭首次 `Important change(s)` 提示;可勾选 `Don't show this again`。 +3. 确认急停复位、机器上电,并按配置完成 homing;否则 AUTO 可能被门控。 +4. 点击右侧 AUTO 图标,进入 AUTO 按钮页。 +5. 点击带打开文件/文件夹图标的 `Load a new program`。 +6. 选择 `linuxcnc/nc_files` 下的 `.ngc` 文件,点击底部绿色对勾。 +7. 检查顶部路径和预览轨迹,再使用 Run;不要把加载误认为已经执行。 + +## 证据文件 + +- `gmoccapy-important-changes.png`:用户原始提示截图。 +- `gmoccapy-before-load.png`:未加载程序。 +- `gmoccapy-after-popup-close.png`:关闭提示后的主界面。 +- `gmoccapy-load-file-page.png`:实际文件选择页。 +- `gmoccapy-program-loaded.png`:加载后的程序和轨迹。 +- `gmoccapy-file-inventory.json`:逐文件 SHA-256 清单。 diff --git a/doc-g/gmoccapy-auto-active-icon.png b/doc-g/gmoccapy-auto-active-icon.png new file mode 100644 index 0000000..a9c8fe0 Binary files /dev/null and b/doc-g/gmoccapy-auto-active-icon.png differ diff --git a/doc-g/gmoccapy-auto-api.png b/doc-g/gmoccapy-auto-api.png new file mode 100644 index 0000000..0ad9200 Binary files /dev/null and b/doc-g/gmoccapy-auto-api.png differ diff --git a/doc-g/gmoccapy-auto-api2.png b/doc-g/gmoccapy-auto-api2.png new file mode 100644 index 0000000..e7fe98d Binary files /dev/null and b/doc-g/gmoccapy-auto-api2.png differ diff --git a/doc-g/gmoccapy-auto-click2.png b/doc-g/gmoccapy-auto-click2.png new file mode 100644 index 0000000..0e9ab0c Binary files /dev/null and b/doc-g/gmoccapy-auto-click2.png differ diff --git a/doc-g/gmoccapy-auto-click3.png b/doc-g/gmoccapy-auto-click3.png new file mode 100644 index 0000000..3801597 Binary files /dev/null and b/doc-g/gmoccapy-auto-click3.png differ diff --git a/doc-g/gmoccapy-auto-focused.png b/doc-g/gmoccapy-auto-focused.png new file mode 100644 index 0000000..56809bd Binary files /dev/null and b/doc-g/gmoccapy-auto-focused.png differ diff --git a/doc-g/gmoccapy-auto-homed.png b/doc-g/gmoccapy-auto-homed.png new file mode 100644 index 0000000..c1bce9a Binary files /dev/null and b/doc-g/gmoccapy-auto-homed.png differ diff --git a/doc-g/gmoccapy-auto-mode.png b/doc-g/gmoccapy-auto-mode.png new file mode 100644 index 0000000..623a712 Binary files /dev/null and b/doc-g/gmoccapy-auto-mode.png differ diff --git a/doc-g/gmoccapy-auto-success-candidate.png b/doc-g/gmoccapy-auto-success-candidate.png new file mode 100644 index 0000000..6cb30e6 Binary files /dev/null and b/doc-g/gmoccapy-auto-success-candidate.png differ diff --git a/doc-g/gmoccapy-auto.png b/doc-g/gmoccapy-auto.png new file mode 100644 index 0000000..7ef1cb5 Binary files /dev/null and b/doc-g/gmoccapy-auto.png differ diff --git a/doc-g/gmoccapy-before-load.png b/doc-g/gmoccapy-before-load.png new file mode 100644 index 0000000..64e5c8c Binary files /dev/null and b/doc-g/gmoccapy-before-load.png differ diff --git a/doc-g/gmoccapy-control-panel-data-control-flow.md b/doc-g/gmoccapy-control-panel-data-control-flow.md new file mode 100644 index 0000000..7751fef --- /dev/null +++ b/doc-g/gmoccapy-control-panel-data-control-flow.md @@ -0,0 +1,323 @@ +# GMOCCAPY 控制面板功能、数据流与控制流 + +更新时间:2026-08-25 + +本文是后续分析 GMOCCAPY 控制面板的总入口。它把普通三轴 `gmoccapy.ini` 和五轴 XYZAC RTCP 案例放在同一套模型中,区分 UI 控件、GMOCCAPY Python handler、LinuxCNC command/status、TASK/motion、HAL 和 Vismach 的责任边界。 + +## 1. 范围与版本边界 + +| 项目 | 当前工作区/运行时 | +|---|---| +| 仓库源码 | `linuxcnc/VERSION = 2.10.0~pre0` | +| 仓库 GMOCCAPY 源码 | `linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.py`,`_RELEASE = 3.4.3` | +| 实际系统 GUI | `/usr/bin/gmoccapy`,运行时版本 `3.5.2`,系统 LinuxCNC `2.10.0~pre1` | +| 普通面板入口 | [`run-gmoccapy.sh`](../run-gmoccapy.sh),默认 `configs/sim/gmoccapy/gmoccapy.ini` | +| 五轴 RTCP 入口 | [`run-5axis-rtcp.sh`](../run-5axis-rtcp.sh),默认 XYZAC TRT switchkins | +| 发布/仿真边界 | POSIX non-realtime 仿真;不等同于实时硬件验证 | + +截图中的 `Important change(s)` 弹窗来自系统 GMOCCAPY 3.5.2,不存在于仓库 3.4.3 源文件中;两套来源不能混为一个源码版本。详细证据见 [GMOCCAPY 分析报告](gmoccapy-analysis.md)。 + +## 2. 总体架构 + +```text +快捷方式 / linuxcnc -r CASE.ini + │ + ▼ +LinuxCNC 启动器与 INI 解析 + │ + ├── linuxcncsvr / NML 状态与命令通道 + ├── milltask / RS274NGC interpreter / task mode + ├── motmod + kinematics / fixed servo cycle + ├── HAL files / HALUI / simulated devices + └── DISPLAY=gmoccapy 或 DISPLAY=axis + │ + ▼ + GMOCCAPY Gtk/Glade 控制面板 + │ + ┌─────────┴─────────┐ + │ │ + 用户点击/键盘/HAL linuxcnc.stat/HAL status + │ ▲ + ▼ │ + Python handler ── command ─┴── TASK/motion/HAL feedback + │ + ├── 模式/按钮页切换 + ├── 程序加载/预览 + ├── AUTO 运行/暂停/停止/单步 + ├── MDI 命令 + └── homing、tool、offset、spindle、coolant +``` + +GMOCCAPY 不是运动学计算器。它负责把操作员动作转换为 LinuxCNC command,并把 LinuxCNC status/HAL status 投影回界面;真正的解释器、轨迹规划、逆解/正解和关节命令由 LinuxCNC runtime 完成。 + +## 3. 启动控制流 + +### 3.1 快捷方式层 + +`run-gmoccapy.sh` 和 `run-5axis-rtcp.sh` 都遵循相同模式: + +1. 计算仓库绝对路径,避免从任意工作目录启动时相对路径漂移。 +2. 校验 INI、演示程序、LinuxCNC launcher 是否存在。 +3. 进入 LinuxCNC 根目录。 +4. 执行 `/usr/bin/linuxcnc -r CASE.ini`,保留终端诊断。 + +五轴快捷方式额外检查 RTCP 子程序中确实存在 `M428`,并支持 `xyzac-trt.ini` 与 `xyzbc-trt.ini` 两个变体。 + +### 3.2 INI 到进程 + +以普通 GMOCCAPY 为例: + +```text +[DISPLAY] DISPLAY=gmoccapy +[TASK] TASK=milltask +[HAL] core_sim.hal + spindle_sim.hal + simulated_home.hal +[EMCIO] TOOL_TABLE=tool.tbl +[RS274NGC] PARAMETER_FILE=sim.var, SUBROUTINE_PATH=macros +[KINS] trivkins coordinates=xyz +``` + +启动器随后创建 `linuxcncsvr`、`milltask`、`halui` 和 GMOCCAPY。GMOCCAPY 进程通过 `-ini` 得到同一个 INI 路径,不能自行替代 TASK/motion/HAL。 + +### 3.3 GMOCCAPY 初始化顺序 + +仓库源码 `gmoccapy.py` 的主初始化顺序为: + +1. 解析 `-user_mode`、`-logo` 参数(约 `243-270` 行)。 +2. 读取 INI(`_get_ini_data()`,约 `272-275` 行)。 +3. 读取偏好文件(`_get_pref_data()`)。 +4. 动态创建 DRO、home、touch-off、jog、macro 等控件(约 `280-305` 行)。 +5. 建立 GMOCCAPY HAL pins(约 `307` 行)。 +6. 连接 Glade signals(约 `315-320` 行)。 +7. 显示主窗口(约 `324-325` 行)。 +8. 初始化主题、G-code preview、kinematics view、offset/tool editor、keyboard 和文件选择器(约 `327-342` 行)。 + +系统 3.5.2 运行时在 GUI 初始化后额外调用 `_startup_message()`,生成版本提示弹窗;它属于安装包新增功能,不属于仓库 3.4.3 初始化链。 + +## 4. 控制面板模式和按钮门控 + +### 4.1 模式按钮 + +Glade 中的主要模式控件: + +| 控件 | 作用 | handler/状态 | +|---|---|---| +| `rbt_manual` | MANUAL/JOG | `on_rbt_manual_pressed()` 发出 `MODE_MANUAL` | +| `rbt_mdi` | MDI | `on_rbt_mdi_pressed()` 发出 `MODE_MDI` | +| `rbt_auto` | AUTO | `on_rbt_auto_pressed()` 发出 `MODE_AUTO` | +| `tbtn_setup` | 设置页 | 进入设置前强制 MANUAL,并禁用模式按钮 | +| `tbtn_user_tabs` | 用户页 | 切换主 notebook 页面 | + +`on_hal_status_mode_auto()` 在收到 HAL status 后将主页面切回 page 0,把按钮 notebook 切到 `_BB_AUTO`,并将 jog notebook 切到 AUTO 页面(约 `2804-2824` 行)。因此“点击 AUTO 图标”与“看到 AUTO 按钮组”是同一个状态转换的两个可观察结果。 + +### 4.2 急停、上电、homing 门控 + +`on_tbtn_setup_toggled()` 和 HAL status handler 根据以下条件设置按钮敏感度: + +```text +ESTOP → manual/mdi/auto 均禁用 +ON + 未 homed → 只允许 manual +ON + all_homed 或 NO_FORCE_HOMING → manual/mdi/auto 全部可用 +``` + +对应仓库源码约为 `3793-3808` 行。未满足条件时,点击 AUTO 会被 `on_hal_status_mode_auto()` 拒绝,显示 `It is not possible to change to Auto Mode at the moment`,并回到 MANUAL。 + +这解释了为什么控制面板可能“没有加载按钮”:加载按钮不在 MANUAL 页面,而且 AUTO 页面本身可能因状态门控没有激活。 + +## 5. G-code 加载数据流 + +### 5.1 控件链 + +```text +rbt_auto + │ on_hal_status_mode_auto() + ▼ +hbtb_auto / _BB_AUTO + │ + │ btn_load(图标 img_open,tooltip=Load a new program) + │ on_btn_load_clicked() + ▼ +_BB_LOAD_FILE + IconFileSelection1 + │ + │ 用户选中路径 + │ btn_select / IconFileSelection1_selected + ▼ +hal_action_open.load_file(path) + ▼ +LinuxCNC task/interpreter + preview/status + ▼ +ntb_preview page 0 + ntb_button _BB_AUTO + stat.file +``` + +### 5.2 打开文件界面 + +`on_btn_load_clicked()`(`gmoccapy.py:5046-5078`)执行: + +1. `ntb_button.set_current_page(_BB_LOAD_FILE)`。 +2. `ntb_preview.set_current_page(3)`。 +3. 打开 full-size preview。 +4. `_show_iconview_tab(True)`。 +5. 刷新 `IconFileSelection1` 文件列表。 +6. 暂时禁用 MANUAL、MDI 和设置按钮,避免文件选择过程中切换模式。 + +文件选择器在 `_init_IconFileSelection()` 和 `_init_file_to_load()` 中读取 `PROGRAM_PREFIX` 与 `[FILTER] PROGRAM_EXTENSION`。普通案例 `PROGRAM_PREFIX = ../../nc_files/` 最终指向仓库的 `linuxcnc/nc_files`。 + +### 5.3 确认文件 + +`on_IconFileSelection1_selected()`(`gmoccapy.py:5114-5125`)执行: + +1. 将选中的 `path` 交给 `hal_action_open.load_file(path)`。 +2. 恢复 preview page 0。 +3. 关闭 full-size preview 和 icon view。 +4. 把按钮 notebook 切回 `_BB_AUTO`。 +5. 重新启用 MANUAL、MDI 和设置按钮。 + +这一步是“加载程序”,不是“运行程序”。运行还需要 `btn_run`/`AUTO_RUN`;源码键盘 handler 将 `R` 映射为运行、`P` 映射为暂停、`S` 映射为恢复。 + +### 5.4 启动时自动加载 + +`on_window1_show()` 会读取偏好项 `open_file`(约 `2920-2924` 行)。如果用户在设置页指定“启动时加载文件”,GMOCCAPY 会在窗口显示后直接调用 `hal_action_open.load_file(file)`。这条路径绕过手动点击文件选择器,但仍通过同一个 LinuxCNC load action。 + +## 6. AUTO 运行控制流 + +```text +btn_run / R + ▼ +linuxcnc.command().auto(AUTO_RUN, line) + ▼ +milltask / RS274NGC interpreter + ▼ +TP queue → motion controller → kinematics → joint commands + ▼ +HAL simulated device / spindle / coolant / tool change + ▼ +linuxcnc.stat + hal_status + ▼ +GMOCCAPY DRO、progress、preview、button sensitivity +``` + +相关按钮属于 `hbtb_auto`:`btn_load`、`btn_reload`、`btn_run`、`btn_stop`、`tbtn_pause`、`btn_step`、`btn_from_line`、`tbtn_optional_blocks`、`btn_edit`。Glade 负责控件和 signal 绑定,Python handler 负责调用 LinuxCNC command;运动本身不在 GTK handler 中实现。 + +## 7. MDI、Jog、Home、Tool 和 Offset 数据流 + +### MDI + +`rbt_mdi` 将 task mode 设为 `MODE_MDI`。MDI 输入提交后进入 LinuxCNC interpreter;G-code 解析错误通过 LinuxCNC error channel 返回,再由 GMOCCAPY notification/error handler 显示。 + +### Jog + +JOG 按钮由 `_make_jog_button()` 动态生成;轴/关节列表来自 INI 的 `COORDINATES`、kinematics 类型和 joint-axis mapping。Jog 命令仍经 LinuxCNC command 通道,不直接改变 DRO;DRO 的真值来自 status feedback。 + +### Home + +Home 按钮最终调用 `command.home(joint_or_axis)`。仿真 HAL 的 `sim_home_switch` 或自定义 home HAL 决定 home switch 状态;`all_homed` HAL status 决定 MDI/AUTO 是否重新开放。 + +### Tool/Offset + +工具表来自 `[EMCIO] TOOL_TABLE`,offset page 和 tool editor 通过 LinuxCNC tool data/action 更新。G43/G49/G43.1 的解释器语义由 RS274NGC 负责;GMOCCAPY 只显示和提交工具/offset 操作。系统 3.5.2 的启动提示明确提醒:AUTO 中换刀后的 G43 不能假定由界面自动恢复,应由程序/REMAP 明确处理。 + +## 8. 五轴 XYZAC RTCP 控制流 + +### 8.1 配置层 + +五轴案例 `xyzac-trt.ini` 的关键字段: + +```text +[DISPLAY] OPEN_FILE = ./demos/xyzac_switchkins.ngc +[RS274NGC] SUBROUTINE_PATH = ./remap_subs +[RS274NGC] REMAP = M428 ... ngc=428remap +[RS274NGC] REMAP = M429 ... ngc=429remap +[RS274NGC] REMAP = M430 ... ngc=430remap +[KINS] KINEMATICS = xyzac-trt-kins sparm=identityfirst +[TRAJ] COORDINATES = XYZAC +[HAL] HALCMD = net ... motion.switchkins-type +[HAL] HALCMD = loadusr -W xyzac-trt-gui +``` + +### 8.2 switchkins 状态 + +`xyzac-trt-kins.c` 将 `sparm=identityfirst` 定义为: + +```text +switchkins-type 0 → identity kinematics +switchkins-type 1 → xyzac TRT kinematics +switchkins-type 2 → userk kinematics +``` + +`trtfuncs.c` 为 XYZAC/XYZBC 实现 forward/inverse mapping,并声明 `tool-offset`、旋转中心和轴 offset HAL pins。XYZAC 的五个关节是 `X Y Z A C`;A 是倾斜台,C 是水平旋转台。 + +### 8.3 M428/M429 控制链 + +```text +G-code M428 + ▼ +428remap.ngc + ├── M68 E3 Q1 写 motion.analog-out-03 = 1 + ├── M66 E0 L0 等待同步 + └── 检查 motion.switchkins-type == 1 + ▼ +xyzac-trt-kins inverse/forward + ▼ +XYZAC joint commands with TCP/RTCP compensation +``` + +`M429` 对称地写入 `Q0`,切回 identity;`M430` 写入 `Q2`,进入 userk。`helix_ac.ngc` 演示了典型顺序:先用 M429 在 machine coordinates 安全定位,再用 M428 执行带 A/C 姿态变化的螺旋插补,结束后再切回 M429 做返回定位。 + +### 8.4 Vismach feedback + +INI 中的 HAL nets 将以下反馈送到 `xyzac-trt-gui`: + +```text +joint.0.pos-fb → table-x +joint.1.pos-fb → saddle-y +joint.2.pos-fb → spindle-z +joint.3.pos-fb → tilt-a +joint.4.pos-fb → rotate-c +motion.tooloffset.z → tool-offset +xyzac-trt-kins.y-offset/z-offset → Vismach geometry +``` + +因此 Vismach 不是运动 authority;它是 joint feedback、tool offset 和 geometry offset 的可视化消费者。 + +## 9. 状态真值与可观察结果 + +| 状态 | authority | 面板表现 | +|---|---|---| +| 急停 | TASK/motion state | E-stop active,模式按钮禁用 | +| 上电 | TASK state + HAL | Power icon active,允许进一步操作 | +| all homed | HAL status / joint state | MDI/AUTO 解除门控 | +| 当前模式 | `stat.task_mode` | MANUAL/MDI/AUTO 页面切换 | +| 当前文件 | `stat.file` / file-loaded status | 顶部文件名、G-code view、Run gate | +| 解释器状态 | `stat.interp_state` | Run/Pause/Step/Stop 敏感度 | +| 当前 G/M codes | `stat.gcodes` / `stat.mcodes` | G-Code 信息区域 | +| 机床位置 | `stat.position` / joint feedback | DRO 和 Vismach | +| kinematics mode | `motion.switchkins-type` | AXIS switchkins 面板/RTCP 模式 | + +任何未来 Web/WASM 控制面板都应消费这些 authority 的 snapshot/event,而不是在 JS/GUI 层镜像一套可写的机床状态。 + +## 10. 现有证据与复现 + +```bash +./run-gmoccapy.sh +./run-5axis-rtcp.sh +./run-5axis-rtcp.sh xyzbc-trt.ini +``` + +已验证的五轴运行证据: + +- [5axis-rtcp-running.png](5axis-rtcp-running.png) +- [5axis-rtcp-shortcut.md](5axis-rtcp-shortcut.md) +- `linuxcnc` 状态返回 `file=./demos/xyzac_switchkins.ngc` +- AXIS 标题包含 `sim-xyzac-trt-kins (switchkins)` +- `xyzac-trt-gui` 进程和五轴 Vismach 预览存在 + +## 11. 后续分析顺序 + +分析任何新的 GMOCCAPY/五轴控制问题时,按以下顺序取证: + +1. 先记录实际运行时路径、LinuxCNC 版本、GMOCCAPY 版本;不要把系统安装脚本和仓库源码混为一份。 +2. 读取 INI 的 DISPLAY/TASK/HAL/RS274NGC/KINS/TRAJ/EMCIO 段,建立配置闭包。 +3. 在 Glade 中找到 widget ID,再在 `gmoccapy.py` 找 signal handler;不要只根据截图猜按钮语义。 +4. 追踪 handler 发出的 `linuxcnc.command()`,确认 command 进入 TASK/motion/HAL 的路径。 +5. 用 `linuxcnc.stat()`、HAL pins、日志和 Vismach feedback 交叉验证,不把 DRO 或 preview 当作 authority。 +6. 五轴问题先确认 kinematics type、M428/M429 状态、tool offset、rotation center/axis offset,再分析轨迹差异。 +7. 任何缺失的官方 oracle、实时硬件、浏览器或资源输入都保留为明确 blocker,不以 GUI 截图替代完整等价证明。 diff --git a/doc-g/gmoccapy-file-inventory.json b/doc-g/gmoccapy-file-inventory.json new file mode 100644 index 0000000..5fb7078 --- /dev/null +++ b/doc-g/gmoccapy-file-inventory.json @@ -0,0 +1,7427 @@ +{ + "file_count": 1233, + "files": [ + { + "bytes": 2633, + "path": "linuxcnc/configs/sim/gmoccapy/6_axis.ini", + "role": "simulation_ini", + "sha256": "1a47c6b666af1ca2f78f95022c27bb9f94626ffce26da23556fea15f767b7cba" + }, + { + "bytes": 2851, + "path": "linuxcnc/configs/sim/gmoccapy/7_axis.ini", + "role": "simulation_ini", + "sha256": "10db48db4e53a03fe04c2e3dc849c84c9f3f2b77d51c233f64b92b375942a14f" + }, + { + "bytes": 3180, + "path": "linuxcnc/configs/sim/gmoccapy/7_axis_tool.ini", + "role": "simulation_ini", + "sha256": "6f48447e4576d82a57742dc94babcecf2e813a2afbe398acfcfd87d05c99f229" + }, + { + "bytes": 3033, + "path": "linuxcnc/configs/sim/gmoccapy/8_axis.ini", + "role": "simulation_ini", + "sha256": "ad9e2a848a1d1cde6c4fbcf82adaae70d52af6f283d3e785a053c2a560ab8f84" + }, + { + "bytes": 3278, + "path": "linuxcnc/configs/sim/gmoccapy/9_axis.ini", + "role": "simulation_ini", + "sha256": "72252c1eb8238facb30b8b3fc08d012b22c70bf1c7c151c2e50946a5eeadc5ef" + }, + { + "bytes": 420, + "path": "linuxcnc/configs/sim/gmoccapy/README", + "role": "simulation_asset", + "sha256": "1cfefb8ab11721485f3a26f21e25114d7e7795505058b371f757e402e8dc4022" + }, + { + "bytes": 529, + "path": "linuxcnc/configs/sim/gmoccapy/README_es", + "role": "simulation_asset", + "sha256": "fc0dcccc47bc360eb15b510d757e41efd358b8c38e290f3afc0d3a0f32b2e1bb" + }, + { + "bytes": 5074, + "path": "linuxcnc/configs/sim/gmoccapy/button.glade", + "role": "simulation_resource", + "sha256": "33c010a47f6b0f16182ba4fcc93a7a3d4bec87caff9c14896ae724fe2542258d" + }, + { + "bytes": 1846, + "path": "linuxcnc/configs/sim/gmoccapy/core_sim.hal", + "role": "simulation_runtime_data", + "sha256": "a1793b7a8bb9ff03172dadd5a42bbfe41248f00796b48ef5d38b766d123accdf" + }, + { + "bytes": 2068, + "path": "linuxcnc/configs/sim/gmoccapy/core_sim4.hal", + "role": "simulation_runtime_data", + "sha256": "d326da9d94d7abdc6ebed4a83144cd1623fa63d5af37ad0ed57662ff84249179" + }, + { + "bytes": 2134, + "path": "linuxcnc/configs/sim/gmoccapy/core_sim_6.hal", + "role": "simulation_runtime_data", + "sha256": "a9ffe2dc7d433ab5b6c027bc8e056b19b831ccbed64acd760571326d0ee6273f" + }, + { + "bytes": 2189, + "path": "linuxcnc/configs/sim/gmoccapy/core_sim_7.hal", + "role": "simulation_runtime_data", + "sha256": "8a3edf09fdeee30ed396bb3b3b533f7acbce4d4fe1b22e90de9fa3bc3442cb8d" + }, + { + "bytes": 2244, + "path": "linuxcnc/configs/sim/gmoccapy/core_sim_8.hal", + "role": "simulation_runtime_data", + "sha256": "89becacb8d967d3078facf90ba16e34e39bc33857fcc92d715ef9be50e688d6d" + }, + { + "bytes": 2299, + "path": "linuxcnc/configs/sim/gmoccapy/core_sim_9.hal", + "role": "simulation_runtime_data", + "sha256": "563234fc66fe5483a4867a03e2a6e49e13f257805661f3c55a99e2c9c6b16c6d" + }, + { + "bytes": 2394, + "path": "linuxcnc/configs/sim/gmoccapy/core_sim_XYZAB.hal", + "role": "simulation_runtime_data", + "sha256": "fc79d08d080865aaf275c138b0220eb51ddd7c370f150c7b3d5d1b41ab33fd85" + }, + { + "bytes": 2394, + "path": "linuxcnc/configs/sim/gmoccapy/core_sim_XYZAC.hal", + "role": "simulation_runtime_data", + "sha256": "3fa7c42778f965ad47291d0215fec42707a2d15279580cc588fd459393f52a03" + }, + { + "bytes": 2394, + "path": "linuxcnc/configs/sim/gmoccapy/core_sim_XYZCW.hal", + "role": "simulation_runtime_data", + "sha256": "a0fd41c8ba9e1cb213122b2ae9b75184ef1e245b6d5d63e49b10211cbfcdf505" + }, + { + "bytes": 11324, + "path": "linuxcnc/configs/sim/gmoccapy/dro.glade", + "role": "simulation_resource", + "sha256": "1a30d2d02e66a346495c477af8298d4d1acb3c13822cca78f06042cbedc304bc" + }, + { + "bytes": 5115, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy.ini", + "role": "simulation_ini", + "sha256": "627537d0a342075ecd45765b4d8b256b065f2568902a585cfe5161efec53a126" + }, + { + "bytes": 2047, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy.pref", + "role": "simulation_runtime_data", + "sha256": "446bfb88f57775b7df79379d9fcf252ff53662c77357e4dadb57d7af06a4a499" + }, + { + "bytes": 76, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy.txt", + "role": "simulation_resource", + "sha256": "c2989ddf8c03a240ceb9fb2d4af5400a59ac20cb40ba762bc7f0ea203b97d593" + }, + { + "bytes": 2908, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy2.glade", + "role": "simulation_resource", + "sha256": "f307b3553656db0ed4bbc714c355ed9d73ee9cbe079819172c61b1e942b61476" + }, + { + "bytes": 5145, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_4_axis.ini", + "role": "simulation_ini", + "sha256": "33b4ad6792d9037f2a0bb9eb179aff7b3d8ecac64bfa0b1cc71633a88cf868d9" + }, + { + "bytes": 74, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_4_axis.txt", + "role": "simulation_resource", + "sha256": "91edc2d47f90710a9262598b28c90aee7fb52bffcf0d040ffe2535b7694fcf04" + }, + { + "bytes": 6788, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZAB.ini", + "role": "simulation_ini", + "sha256": "c8047ee290a94944481545a78104e9ead1036ca04f965a729ad4a870e7fe69a1" + }, + { + "bytes": 6372, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZAC.ini", + "role": "simulation_ini", + "sha256": "daf2ffcab7fb3af60f5dd38256c8e9bb3347d885771ba414da2b4277c8ebce4a" + }, + { + "bytes": 6360, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZCW.ini", + "role": "simulation_ini", + "sha256": "8a860f885f6afc18b0d1ff8081d356d56897456298cfd58fc7394ec519f71e83" + }, + { + "bytes": 4902, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_left_panel.ini", + "role": "simulation_ini", + "sha256": "3e458b639557d33bc2b637fb2f63b88e1cade3dd7543306b96e166c5b50bb08e" + }, + { + "bytes": 6474, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_messages.ini", + "role": "simulation_ini", + "sha256": "7b8a607c978ad1758a51d60b04d3bed46a9597661060a6a906b4411abe02e857" + }, + { + "bytes": 4918, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_pedant.ini", + "role": "simulation_ini", + "sha256": "ea336e14be5b1b62a6b540070624b6c35cd076b16d170725fc4dacb9754e6790" + }, + { + "bytes": 465, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/README", + "role": "simulation_asset", + "sha256": "5a25e58d433c629316f5a865d025ad50f602343d99bf6c4fd983b6ce09f21828" + }, + { + "bytes": 582, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/README_es", + "role": "simulation_asset", + "sha256": "2c2ca93c048f0ad170829caad82ea311fc69a5abb2bd2524ef1943380d55fc85" + }, + { + "bytes": 6046, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/gmoccapy_plasma.ini", + "role": "simulation_ini", + "sha256": "b006d05ea125442e3258a76b9e95d28a3488d25f1f652828c470de82aaa9d077" + }, + { + "bytes": 486, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/gmoccapy_postgui.hal", + "role": "simulation_runtime_data", + "sha256": "7191fdb835d3e6de04907348a35e6a744695cba95b9e22e19b26a0d803a698c5" + }, + { + "bytes": 43130, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/plasma.glade", + "role": "simulation_resource", + "sha256": "19c848753644c6fad57a29919604aeec783562441533a659cc93cd7a831cddeb" + }, + { + "bytes": 1047, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/plasma.hal", + "role": "simulation_runtime_data", + "sha256": "591736242661bd061f3ad3130174feea805a9d3afd514d741c5e61fc47383913" + }, + { + "bytes": 15837, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/plasma.py", + "role": "simulation_resource", + "sha256": "d9b1a16cb260f017f39472cd2bd4ed1136156d7c25df183892999fdf65cf3068" + }, + { + "bytes": 12879, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/signals.glade", + "role": "simulation_resource", + "sha256": "9806848f0582cfd6ae1246a7d121c2069ddf40f21312e6b6d293f4a3e6f46282" + }, + { + "bytes": 308, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/signals.hal", + "role": "simulation_runtime_data", + "sha256": "c6c006a5f2ebdac34adb0b1ebc07819cbd793eabb325ae076425af8b14a4e32a" + }, + { + "bytes": 1932, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/signals.py", + "role": "simulation_resource", + "sha256": "e2f2d29067ea4c38ca7ec77a45098fb58abed3bb546602bba5ae6d10c3f19dc6" + }, + { + "bytes": 4190, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/torch.svg", + "role": "simulation_resource", + "sha256": "3fe8a65414e4d8db67ad049c24dc4bcd0afa1de53c479cd0332b2ea59594bd78" + }, + { + "bytes": 166, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/torches.tbl", + "role": "simulation_runtime_data", + "sha256": "05d9bf3abc2618b7921568926a546054ff4f15c8e666373a3751f11c3a25f626" + }, + { + "bytes": 1234, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_postgui.hal", + "role": "simulation_runtime_data", + "sha256": "32d5cfa8c02a1be05348d4b6af621fff3a62e2adf44de5b82d2600b41839198c" + }, + { + "bytes": 6314, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_pyngcgui.ini", + "role": "simulation_ini", + "sha256": "2f62b1a0e2bcdf2b587e142ea8c4212c28b8024161c38b13e5cb39e15c984ce7" + }, + { + "bytes": 113, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_pyngcgui.txt", + "role": "simulation_resource", + "sha256": "1ab3bb80e449bab939de76b4c43e0749251b2d0abb266bbdfc3450936b5233b2" + }, + { + "bytes": 4699, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_right_panel.ini", + "role": "simulation_ini", + "sha256": "c155ba8047c3011c6ec023dd911fa571ec52b5352b789b7c88542c8d418e15bc" + }, + { + "bytes": 5064, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_sim_hardware_button.ini", + "role": "simulation_ini", + "sha256": "7469a0e05ea85c83d99f11ef552482c29d93313a358d8a7801a2eabbae1f9af0" + }, + { + "bytes": 5153, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_tool_sensor.ini", + "role": "simulation_ini", + "sha256": "4caf0e746fd09bceafa4f2bdced6a9be063b7ee51334fbb75d4c6914d94db7b9" + }, + { + "bytes": 1780, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_tool_sensor.para", + "role": "simulation_runtime_data", + "sha256": "29c6fefac9ed01d575e97a84b8efc48f0e3103a4d8daa6d0348b83baa000ad1d" + }, + { + "bytes": 5475, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_with_user_tabs.ini", + "role": "simulation_ini", + "sha256": "a080a9008bef88d61fee5473f8531df64bfe3fd365540e1055e3377ce59f99d9" + }, + { + "bytes": 75, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_with_user_tabs.txt", + "role": "simulation_resource", + "sha256": "6a9bd64b9cc0ff875fe8ab29dcf4a6abfe6fc996f33c74a9128a8a5c70811c50" + }, + { + "bytes": 7124, + "path": "linuxcnc/configs/sim/gmoccapy/h_buttonlist.glade", + "role": "simulation_resource", + "sha256": "3e7468c9b45f41f3c3af05ad39eebc165181dae6eb888590c9b309b99be29dc3" + }, + { + "bytes": 986, + "path": "linuxcnc/configs/sim/gmoccapy/h_buttonlist.hal", + "role": "simulation_runtime_data", + "sha256": "94121fd144fdbe230261586b9519528f5b8cee4bba4efb0c2c54d70e9a326b3b" + }, + { + "bytes": 4620, + "path": "linuxcnc/configs/sim/gmoccapy/jogwheel.glade", + "role": "simulation_resource", + "sha256": "0f053895edb43037d2a64432a087489aa60864276fc2e0cf91f7c4677c8925a7" + }, + { + "bytes": 691, + "path": "linuxcnc/configs/sim/gmoccapy/jogwheel.hal", + "role": "simulation_runtime_data", + "sha256": "d5b421d044e444b042a6508a4902f38ab57f871f42d87e1858e68e77ad4b3c92" + }, + { + "bytes": 373, + "path": "linuxcnc/configs/sim/gmoccapy/lathe.tbl", + "role": "simulation_runtime_data", + "sha256": "07aadc984258ec7d9fcb68d3b84ad796995b055f9b364e57b13058c42d96dd30" + }, + { + "bytes": 5061029, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/LatheMacro.svg", + "role": "simulation_resource", + "sha256": "234a6e329bf356c5c766a26fff48c7223e311441eff37397f76b7b511816e887" + }, + { + "bytes": 3229, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/README", + "role": "simulation_asset", + "sha256": "6dfd0352ff951bb42b2504d82982ad646bcf9650996919e040fb1655fa478c44" + }, + { + "bytes": 1182, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/boring.ngc", + "role": "simulation_resource", + "sha256": "8b373a5125d30f07caef25a5e8928643255245aa1839d8ddef23bdd7c82e564a" + }, + { + "bytes": 1116, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/chamfer.ngc", + "role": "simulation_resource", + "sha256": "caf3bed8993cb390b0ffdbc8c173562546fa825172d1ce1b1e8f7b5122dc1b3d" + }, + { + "bytes": 1120, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/core_sim_lathe.hal", + "role": "simulation_runtime_data", + "sha256": "614ebb8b029a9a234821cc08ae7cdc506b774dde5db8e75966df64f694540df0" + }, + { + "bytes": 2005, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/core_sim_lathe_C.hal", + "role": "simulation_runtime_data", + "sha256": "c4761c123f7e367bf5cc74a0016340c2dc553ef61a19005af47ec4e05fd54ffb" + }, + { + "bytes": 2059, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/core_sim_lathe_CW.hal", + "role": "simulation_runtime_data", + "sha256": "14065d0eed908856d59c52fe9782d3c487dbba4535b2c4209554c72046eff3c9" + }, + { + "bytes": 725, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/drilling.ngc", + "role": "simulation_resource", + "sha256": "69df94bfc1f55b7e803068e75deac4a36d2ea831b24b2f2a730d9ffab7e109bd" + }, + { + "bytes": 595, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/facing.ngc", + "role": "simulation_resource", + "sha256": "76eb4c7d27855d787b7de807bfad1a98b07dbd6df4777c1f0aa2954488a65162" + }, + { + "bytes": 1821, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/gmoccapy_lathe.pref", + "role": "simulation_runtime_data", + "sha256": "3f0ba81ce7555edd733bc8a279aab9f0149c5c099bafe285b0adf3a8907eff09" + }, + { + "bytes": 1620, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/gmoccapy_lathe_c.pref", + "role": "simulation_runtime_data", + "sha256": "63f7d20c0f7f5790e44e541f0a11a554d0acb1a417c57f1fa5ed0590ae08c7dd" + }, + { + "bytes": 1066, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/gmoccapy_postgui.hal", + "role": "simulation_runtime_data", + "sha256": "c6aacd0c3c91411d03d3368db70d90ebf6c7bbbe00121402d2f86dacf52fd513" + }, + { + "bytes": 430, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/grooving.ngc", + "role": "simulation_resource", + "sha256": "39ce59c5d4f6b926f157a5103984d0066551a92a62320ef6b8171cf73c72d060" + }, + { + "bytes": 4015, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe.ini", + "role": "simulation_ini", + "sha256": "b6971dfdf96fb2d502378d143da6c7a2f404fe796f41f96f629b9db15a44bb66" + }, + { + "bytes": 1667, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe.pref", + "role": "simulation_runtime_data", + "sha256": "3b26904d5578dde8d9618b3d851936e4d3395bcd7f7b05d31407f0a176ecae95" + }, + { + "bytes": 465, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe.tbl", + "role": "simulation_runtime_data", + "sha256": "feb0002bb8663770be5987f24add9853042faeadf3af972433c03720c1942775" + }, + { + "bytes": 4536, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_C.ini", + "role": "simulation_ini", + "sha256": "c2f67186fc6c84f266d2ad1d6fcf487249182a2385f8d3099f51f9fab1cc8bb4" + }, + { + "bytes": 5178, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_CW.ini", + "role": "simulation_ini", + "sha256": "df718eefdbd91308b9182f6858150abb8fa4a2d030105db954702c280cddac70" + }, + { + "bytes": 4015, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_backtool.ini", + "role": "simulation_ini", + "sha256": "5d7e04fd075e28534afe817e64259a2e7df809d5fdf893f39c9cc5ffcd35ed71" + }, + { + "bytes": 1652, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_c.pref", + "role": "simulation_runtime_data", + "sha256": "65ef8d72c4be99ee5aa038ece7f2f7f107a0c06c95047fcb09e186815d6d0466" + }, + { + "bytes": 1621, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_cw.pref", + "role": "simulation_runtime_data", + "sha256": "89e009db509cee3e7ab681b0bf294389caa0930712457ac424337a343bf063bf" + }, + { + "bytes": 4060, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_imperial.ini", + "role": "simulation_ini", + "sha256": "503bf2241ed1c1f70410015a7f3aab5a922dc571b1ded36f5431c538d5d4e628" + }, + { + "bytes": 1598, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_imperial.pref", + "role": "simulation_runtime_data", + "sha256": "d9e838aebb01a81108de5efcbb637f4b88725bc6697db3baf0875106e8fdf19b" + }, + { + "bytes": 4248, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_macros.ini", + "role": "simulation_ini", + "sha256": "b3d9c8451a9281e9863e30f7d0138d5779028a06d981c2f1bd30bf6c7bded0e0" + }, + { + "bytes": 7625, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathehandler.py", + "role": "simulation_resource", + "sha256": "dbd025086e24bfaaa83900b84d1416db85fa0d97f9aa48a9f4de424c493425d7" + }, + { + "bytes": 159113, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathemacro.ui", + "role": "simulation_resource", + "sha256": "e9d946edccc6d809e5efa72f334e1d0efd25fcd86e02c09a77a115d5b3041477" + }, + { + "bytes": 1151, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/radius.ngc", + "role": "simulation_resource", + "sha256": "a96e939049e222ea1bd04e7cdb116e51eb1180b3a080b1b3f325bb3c64d55dd0" + }, + { + "bytes": 1458, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/savestate.sav", + "role": "simulation_asset", + "sha256": "52842a17d6b617319909559bb78accfa8702e9f38982afe5e0338ebcdbdb5d9d" + }, + { + "bytes": 368, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/simulated_home_lathe.hal", + "role": "simulation_runtime_data", + "sha256": "64c6e20244c60d3ea66e1299c7e9619f14cb3037603fb2213d42f67a62da8ee6" + }, + { + "bytes": 368, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/simulated_home_lathe_CW.hal", + "role": "simulation_runtime_data", + "sha256": "64c6e20244c60d3ea66e1299c7e9619f14cb3037603fb2213d42f67a62da8ee6" + }, + { + "bytes": 2338, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/spindle_sim.hal", + "role": "simulation_runtime_data", + "sha256": "f43dac948d6f198cb7f0a8855f9acc38ab2e41df8f9fd1abbe4607ea442800b0" + }, + { + "bytes": 1037, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/threading.ngc", + "role": "simulation_resource", + "sha256": "898fa7f5403d060f649d3aaa9ae8810882e22610af0769439fff221bdd47e78d" + }, + { + "bytes": 1184, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/turning.ngc", + "role": "simulation_resource", + "sha256": "3ef8d3c8f36a15b74f366f7d4e57a47d747ad73e91fbec2f9c038cf39ed05816" + }, + { + "bytes": 500, + "path": "linuxcnc/configs/sim/gmoccapy/left.hal", + "role": "simulation_runtime_data", + "sha256": "c8efad631f12a4ac1c74c866ec2d3e2b7886f088625dc1f00dee050409fab892" + }, + { + "bytes": 641, + "path": "linuxcnc/configs/sim/gmoccapy/left_panel.hal", + "role": "simulation_runtime_data", + "sha256": "fb70eed442256b29dcbd78ffb2c31dbf9f6639f7e0f3ef68d8903dd930a8c1eb" + }, + { + "bytes": 1924, + "path": "linuxcnc/configs/sim/gmoccapy/macros/change.ngc", + "role": "simulation_resource", + "sha256": "3d4d204d2164dcbdcaa6fe859154842c8939fd0bbe1b2f7e8a3eda4d7a0c6cde" + }, + { + "bytes": 400, + "path": "linuxcnc/configs/sim/gmoccapy/macros/go_to_position.ngc", + "role": "simulation_resource", + "sha256": "33e66edb930c7fa64c80fc88921b7cb7fda721e61dbf67cd51a2f43109f20523" + }, + { + "bytes": 221, + "path": "linuxcnc/configs/sim/gmoccapy/macros/halo_world.ngc", + "role": "simulation_resource", + "sha256": "6b7863e0bcbf997ebc6f1bdc4fc861b69a4787fa1f127cca97b76676b455adfe" + }, + { + "bytes": 400, + "path": "linuxcnc/configs/sim/gmoccapy/macros/i_am_lost.ngc", + "role": "simulation_resource", + "sha256": "35ba01cee35bb1e76a1e5eb947e8f2f936063cee08f2c35fa175edd8767e774c" + }, + { + "bytes": 24520, + "path": "linuxcnc/configs/sim/gmoccapy/macros/images/goto_x_y_z.png", + "role": "simulation_asset", + "sha256": "797e2fce748a6e7d19b1a7686d743b11015a3929cae646d154da953a7e3c13c9" + }, + { + "bytes": 14074, + "path": "linuxcnc/configs/sim/gmoccapy/macros/images/i_am_lost.png", + "role": "simulation_asset", + "sha256": "f6df3ed0b0a79cd0bfccd5d029349bf685f3ace4818ab697cff0c5857ace096b" + }, + { + "bytes": 222151, + "path": "linuxcnc/configs/sim/gmoccapy/macros/images/macro_8.png", + "role": "simulation_asset", + "sha256": "0e42752fc4360390bf2214717dbb0be389bed908d1f178b8047029b3cd97734a" + }, + { + "bytes": 205, + "path": "linuxcnc/configs/sim/gmoccapy/macros/increment.ngc", + "role": "simulation_resource", + "sha256": "3aa6bb7fdf504676769f30b9a5ae079b858aebcfc10cdc3dd7617f0a94954239" + }, + { + "bytes": 205, + "path": "linuxcnc/configs/sim/gmoccapy/macros/jog_around.ngc", + "role": "simulation_resource", + "sha256": "6c3f64beb65cd5bead9fda63e6904880099dd5839693e25e6ae71eca0509b2bd" + }, + { + "bytes": 262, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_0.ngc", + "role": "simulation_resource", + "sha256": "d831ed98b0e383645414961cab4fdb468a8b61b2a38f7b14508cc4fea14ec2a9" + }, + { + "bytes": 262, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_1.ngc", + "role": "simulation_resource", + "sha256": "e28262f8b854781fc0c39b6f1989e3506fe38a9355e98f0802a7ff8c0928a577" + }, + { + "bytes": 264, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_10.ngc", + "role": "simulation_resource", + "sha256": "e4bc0167421eae327ceb4e241cf9ba88fb86ce34e04233a7f47240363f49bfaf" + }, + { + "bytes": 264, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_11.ngc", + "role": "simulation_resource", + "sha256": "38ba16a50fe4ded63fd9feadd0a0bcb37c3244bfcad8041c2e00dee7b436470c" + }, + { + "bytes": 264, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_12.ngc", + "role": "simulation_resource", + "sha256": "600a73dbd49ab56680f688629e803c693b1086a124c41316911d1ded5247589a" + }, + { + "bytes": 264, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_13.ngc", + "role": "simulation_resource", + "sha256": "edce6ade837a115f9a8ef66203509935472327c81d1f95d7ee54832bf210f35e" + }, + { + "bytes": 264, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_14.ngc", + "role": "simulation_resource", + "sha256": "9eeaed8fa7ebbd97d9bf61e972c23a5f896c58d71595b8f5be14f05a90aa6b88" + }, + { + "bytes": 264, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_15.ngc", + "role": "simulation_resource", + "sha256": "18e481c4f56b0e3fe1d9c45749bebd8ab1d5eccdec040041e03653d0b79ecd30" + }, + { + "bytes": 262, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_2.ngc", + "role": "simulation_resource", + "sha256": "c8d67bf45bf02038688da2d5ba293b1e97d6458a84ee94dfbdb771c7401ae89a" + }, + { + "bytes": 262, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_3.ngc", + "role": "simulation_resource", + "sha256": "258481fb6e6c3658ab7a93f8fc244b063bbbfbe8348d9cf7693a33ede017d3d7" + }, + { + "bytes": 262, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_4.ngc", + "role": "simulation_resource", + "sha256": "c50875f54890ea24213d9d666b73838b3b2defb2eb29cad5563e58e9cafa52c3" + }, + { + "bytes": 262, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_5.ngc", + "role": "simulation_resource", + "sha256": "8fde463ddebd1e304d6856cf1e55a237efb9fec4fa38644824ce2ece5d839d1c" + }, + { + "bytes": 262, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_6.ngc", + "role": "simulation_resource", + "sha256": "247817107d6629a9a5448e58b36366dbd13cfae20b7b315d6466c9f54926dc4c" + }, + { + "bytes": 262, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_7.ngc", + "role": "simulation_resource", + "sha256": "9e62f1ef37cf683c1e92f1d51e3bce36210262613dae871b6a4f44a525b72c49" + }, + { + "bytes": 383, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_8.ngc", + "role": "simulation_resource", + "sha256": "bc62cb4eed38f8a8322bbf78282cc6450b773bae3ec0665f3a227c08024a95ed" + }, + { + "bytes": 262, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_9.ngc", + "role": "simulation_resource", + "sha256": "b7ede9af0cadff0e49594e270c530f1d2b3af128d0b47b484e1e38bc1bfd4482" + }, + { + "bytes": 1279, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_Instructions.txt", + "role": "simulation_resource", + "sha256": "c8a26259f6e68a2242ce33dd819be96cd18ede964265016dd356e5d84ef191ce" + }, + { + "bytes": 53, + "path": "linuxcnc/configs/sim/gmoccapy/macros/on_abort.ngc", + "role": "simulation_resource", + "sha256": "e120b55018a8f01b0409a2c0385afec32668e77cf4feeb74cb5e66f3636dde7a" + }, + { + "bytes": 918, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gantry_mm.hal", + "role": "simulation_runtime_data", + "sha256": "5da3e7f6e95f26df831f046a5c7c9ed3e073579748812140a15085dd558b42b0" + }, + { + "bytes": 2788, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gantry_mm.ini", + "role": "simulation_ini", + "sha256": "303f0fb1b9a70ba3cc6dbc11003bed2c59579ddfe2e4d9a300a5fcd4da570e65" + }, + { + "bytes": 1827, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gmoccapy_GANTRY_sim.pref", + "role": "simulation_runtime_data", + "sha256": "6b63fa2d6e0a0f09b5ead8b0b329f6ee9df5a3f16f0f55a416d7ca2354b91f61" + }, + { + "bytes": 1031, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gmoccapy_postgui.hal", + "role": "simulation_runtime_data", + "sha256": "d8de40b38c349012779d9fa30bc1d466635f1ad2c05c9cf3e9a85e7bf64b916c" + }, + { + "bytes": 2128, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/tool.tbl", + "role": "simulation_runtime_data", + "sha256": "f0c933ba509282003dad7ce1b0d9e7dde58a899fa6463e8ddc113532e42ae567" + }, + { + "bytes": 1803, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/LinuxCNC-HAL-SIM-SCARA.pref", + "role": "simulation_runtime_data", + "sha256": "aaec9dfa35c261db2165b4a599e319f51c4c3ccd26515a90bd3b6b008941b699" + }, + { + "bytes": 522, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/README", + "role": "simulation_asset", + "sha256": "2c008bea0f2a761d2a88d6fb39e91aeeaea9d9c9fa272d9db0898d3e0d53d5e7" + }, + { + "bytes": 586, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/README_es", + "role": "simulation_asset", + "sha256": "4096945df4926fca88e9cd90cbf54a183c6eea8921f2cd60cc01927f9bee17b8" + }, + { + "bytes": 941, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/postgui.hal", + "role": "simulation_runtime_data", + "sha256": "8f7a374778a3100b7f2234f821adeca566f4d0f8d364d760836ed5484539fbe3" + }, + { + "bytes": 6300, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara.glade", + "role": "simulation_resource", + "sha256": "327c8fef2c9ecfb5372160a617156abb06b5a849d4469683c2341530e6d1a251" + }, + { + "bytes": 2568, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara.ini", + "role": "simulation_ini", + "sha256": "3c5a9c56f4c50a987f7b2a21b6968ab77eeb586a894f8ffff73dec74eb680092" + }, + { + "bytes": 166, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara.tbl", + "role": "simulation_runtime_data", + "sha256": "05d9bf3abc2618b7921568926a546054ff4f15c8e666373a3751f11c3a25f626" + }, + { + "bytes": 105, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara_panel.hal", + "role": "simulation_runtime_data", + "sha256": "69c13f23a5434680e7d0ea69ee78801e697261ddd4c13af6c9f8b10bfde3551f" + }, + { + "bytes": 124, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara_postgui.hal", + "role": "simulation_runtime_data", + "sha256": "69db8232c9384cffcaec0b07f7616d439e4a63bd23daa9d48f7f24a2c8afa66d" + }, + { + "bytes": 2114, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara_sim_4.hal", + "role": "simulation_runtime_data", + "sha256": "f327896d862537f129cf7424e540eb7a7e689a8fbc58521a3e3d6f26c4c1915b" + }, + { + "bytes": 2370, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/spindle_sim.hal", + "role": "simulation_runtime_data", + "sha256": "fa4799af70e6d611efc438fb5e25c360d8163f498e511f443925738f194639c7" + }, + { + "bytes": 310, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/README", + "role": "simulation_asset", + "sha256": "a371181446fdc09de6ebe5d81611c51d8d1e5d91b99f08767db8510b686fa1ab" + }, + { + "bytes": 331, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/README_es", + "role": "simulation_asset", + "sha256": "3ea3f2c3e3605057928e600f233f796b27cd84ebfa0605dd87a4078def2617be" + }, + { + "bytes": 70808, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzac.ngc", + "role": "simulation_resource", + "sha256": "574f9154d9fa6b31ab14fba8b79a3a9fa0d1c37bdecf5dfc19871e01411c6eaf" + }, + { + "bytes": 76577, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzbc.ngc", + "role": "simulation_resource", + "sha256": "ed079d7e69d53cf0b012636b56439d19fc629c4eca2e4175cd09d5448c9f52d4" + }, + { + "bytes": 294372, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/impeller-7bl-xyzac.ngc", + "role": "simulation_resource", + "sha256": "106441767b816b4eea1cf8683b5d9ec6dccdb1f21ec0bf3354c7660f53bbe788" + }, + { + "bytes": 886, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/test-xyzac.ngc", + "role": "simulation_resource", + "sha256": "a4545242699cb127f5796465e3b5edda7da2b76c26579b90e3d2db7a33fc77fc" + }, + { + "bytes": 885, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/test-xyzbc.ngc", + "role": "simulation_resource", + "sha256": "ac389cfa886a30c2b0fab4f579df2ce2fd101b924a7777747b2bacd67446a900" + }, + { + "bytes": 941, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/postgui.hal", + "role": "simulation_runtime_data", + "sha256": "f62636323218a0cdcdae48dbdf1a8c595365566062122f36e403fd71393ed57e" + }, + { + "bytes": 1714, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/sim-xyzac-trt.pref", + "role": "simulation_runtime_data", + "sha256": "74cc0709e6f6275858d841f2bf03975a709595ad4256fc5dcbc3a928c7cd6a48" + }, + { + "bytes": 3034, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt.ini", + "role": "simulation_ini", + "sha256": "af315891e9e561812f267f9c44c752c265ad00c862adbcd7dd42c2b07e60cd38" + }, + { + "bytes": 169, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt.tbl", + "role": "simulation_runtime_data", + "sha256": "100595ddcdddf0e269a4b6041954f19349b593ffcdaf185fbcff8cde91311176" + }, + { + "bytes": 19980, + "path": "linuxcnc/configs/sim/gmoccapy/pendant.glade", + "role": "simulation_resource", + "sha256": "a7095c6742d976bd73c7860f0a5754f8e0604f4d0c24a90638a347d6d67a6dd1" + }, + { + "bytes": 2476, + "path": "linuxcnc/configs/sim/gmoccapy/pendant.hal", + "role": "simulation_runtime_data", + "sha256": "a52d56ea8675c1ba332d2e46c6efc0d1890cf74395683036e1a3ac200b007baa" + }, + { + "bytes": 465, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/README", + "role": "simulation_asset", + "sha256": "5a25e58d433c629316f5a865d025ad50f602343d99bf6c4fd983b6ce09f21828" + }, + { + "bytes": 583, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/README_es", + "role": "simulation_asset", + "sha256": "aec7a284383822374e8653f5b482fbe84f60c0774ac6e2337b5ce33eff396c09" + }, + { + "bytes": 1719, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/gmoccapy.pref", + "role": "simulation_runtime_data", + "sha256": "7c123d22d53e65a3d930b8c41056db551752e4b26f2e50428409fb3a32bd96dc" + }, + { + "bytes": 5949, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/gmoccapy_plasma.ini", + "role": "simulation_ini", + "sha256": "7d53c570ccb85f086e67eb511c28bb9cec47e02cf42395e71bb2ff89e9d0d671" + }, + { + "bytes": 486, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/gmoccapy_postgui.hal", + "role": "simulation_runtime_data", + "sha256": "7191fdb835d3e6de04907348a35e6a744695cba95b9e22e19b26a0d803a698c5" + }, + { + "bytes": 43130, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/plasma.glade", + "role": "simulation_resource", + "sha256": "19c848753644c6fad57a29919604aeec783562441533a659cc93cd7a831cddeb" + }, + { + "bytes": 1047, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/plasma.hal", + "role": "simulation_runtime_data", + "sha256": "591736242661bd061f3ad3130174feea805a9d3afd514d741c5e61fc47383913" + }, + { + "bytes": 15837, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/plasma.py", + "role": "simulation_resource", + "sha256": "d9b1a16cb260f017f39472cd2bd4ed1136156d7c25df183892999fdf65cf3068" + }, + { + "bytes": 12879, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/signals.glade", + "role": "simulation_resource", + "sha256": "9806848f0582cfd6ae1246a7d121c2069ddf40f21312e6b6d293f4a3e6f46282" + }, + { + "bytes": 308, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/signals.hal", + "role": "simulation_runtime_data", + "sha256": "c6c006a5f2ebdac34adb0b1ebc07819cbd793eabb325ae076425af8b14a4e32a" + }, + { + "bytes": 1932, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/signals.py", + "role": "simulation_resource", + "sha256": "e2f2d29067ea4c38ca7ec77a45098fb58abed3bb546602bba5ae6d10c3f19dc6" + }, + { + "bytes": 4190, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/torch.svg", + "role": "simulation_resource", + "sha256": "3fe8a65414e4d8db67ad049c24dc4bcd0afa1de53c479cd0332b2ea59594bd78" + }, + { + "bytes": 166, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/torches.tbl", + "role": "simulation_runtime_data", + "sha256": "05d9bf3abc2618b7921568926a546054ff4f15c8e666373a3751f11c3a25f626" + }, + { + "bytes": 321, + "path": "linuxcnc/configs/sim/gmoccapy/position.txt", + "role": "simulation_resource", + "sha256": "7ff80b79f7e35cb7ef54bce59212a68e3f80cb6b63de8abdcda9c519bbe0a626" + }, + { + "bytes": 829, + "path": "linuxcnc/configs/sim/gmoccapy/pyngcgui.ui", + "role": "simulation_resource", + "sha256": "dced80b3f34f0a1b3f38086d3fe16ff3b9e48ebe04a281dee356db757fe5b640" + }, + { + "bytes": 935, + "path": "linuxcnc/configs/sim/gmoccapy/python/remap.py", + "role": "simulation_resource", + "sha256": "dd8d580d375761e5bc7751bd50db6b0b88fbf24cefd12eb24892a84dff542b2b" + }, + { + "bytes": 7993, + "path": "linuxcnc/configs/sim/gmoccapy/python/stdglue.py", + "role": "simulation_resource", + "sha256": "bd05f6b71d76e2a3502c1d13f7715ab70830a24247de56e24b23f306f04b01b6" + }, + { + "bytes": 921, + "path": "linuxcnc/configs/sim/gmoccapy/python/toplevel.py", + "role": "simulation_resource", + "sha256": "beaf4709170a42250120b11fea8185aa6e5c1f08931e901874fb1c077695df95" + }, + { + "bytes": 1666, + "path": "linuxcnc/configs/sim/gmoccapy/sim.var", + "role": "simulation_runtime_data", + "sha256": "163bbf80485fe2fe12700c1acb4b05eff774df68176d17e4eef5de8a7024c1ae" + }, + { + "bytes": 1666, + "path": "linuxcnc/configs/sim/gmoccapy/sim.var.bak", + "role": "simulation_asset", + "sha256": "163bbf80485fe2fe12700c1acb4b05eff774df68176d17e4eef5de8a7024c1ae" + }, + { + "bytes": 657, + "path": "linuxcnc/configs/sim/gmoccapy/simulated_home.hal", + "role": "simulation_runtime_data", + "sha256": "74b8a8952dc8c74ea5901e1414244f83da5fb246b727244738d62da5a4530a40" + }, + { + "bytes": 368, + "path": "linuxcnc/configs/sim/gmoccapy/simulated_home_lathe.hal", + "role": "simulation_runtime_data", + "sha256": "64c6e20244c60d3ea66e1299c7e9619f14cb3037603fb2213d42f67a62da8ee6" + }, + { + "bytes": 2338, + "path": "linuxcnc/configs/sim/gmoccapy/spindle_sim.hal", + "role": "simulation_runtime_data", + "sha256": "f43dac948d6f198cb7f0a8855f9acc38ab2e41df8f9fd1abbe4607ea442800b0" + }, + { + "bytes": 1613, + "path": "linuxcnc/configs/sim/gmoccapy/tool.tbl", + "role": "simulation_runtime_data", + "sha256": "616621dafc73458f4e500f6a1b194b98de88cb37da9d9dc20ad876c0c01f6db1" + }, + { + "bytes": 3638, + "path": "linuxcnc/configs/sim/gmoccapy/tool_sensor.glade", + "role": "simulation_resource", + "sha256": "9f053d62e29467f3c7d95c5cfbc621710e5fd333d63c07788ca3bf993e72b6fb" + }, + { + "bytes": 130, + "path": "linuxcnc/configs/sim/gmoccapy/tool_sensor.hal", + "role": "simulation_runtime_data", + "sha256": "7329d08675db441cd75bb63f5dc7bd55b0993cb05dcacc0f311d00f15ceea371" + }, + { + "bytes": 1925, + "path": "linuxcnc/configs/sim/gmoccapy/tool_sensor.para", + "role": "simulation_runtime_data", + "sha256": "33f7254fd025fbf79b440d3e1e6939fed10b31f82d65cb07b1b1002bc4413439" + }, + { + "bytes": 5233, + "path": "linuxcnc/configs/sim/gmoccapy/v_buttonlist.glade", + "role": "simulation_resource", + "sha256": "818aee93eefe335f1a0b08c88a7b171290e17be634a6f426671f4acecdee9603" + }, + { + "bytes": 690, + "path": "linuxcnc/configs/sim/gmoccapy/v_buttonlist.hal", + "role": "simulation_runtime_data", + "sha256": "be51fde287c19649c32ce3295b1370a9463bf6d1d8f881b056b7d41fae864275" + }, + { + "bytes": 2579, + "path": "linuxcnc/configs/sim/gmoccapy/vcp_box.glade", + "role": "simulation_resource", + "sha256": "1116122b2da9db45128f23ab81860b2b6a090ed7588fb932c8367906d7c31165" + }, + { + "bytes": 254, + "path": "linuxcnc/configs/sim/gmoccapy/vcp_box.hal", + "role": "simulation_runtime_data", + "sha256": "814a7f4d89f098fdf9ff9344680f35ab54130a66ba9197591d4a5d16d46a27c6" + }, + { + "bytes": 2341, + "path": "linuxcnc/docs/man/man1/gmoccapy.1", + "role": "documentation", + "sha256": "13fe910b29cf222b74add09a6df8cd3af88560a4ad14b50ab8a0ee654d5c570d" + }, + { + "bytes": 68782, + "path": "linuxcnc/docs/src/gui/gmoccapy.adoc", + "role": "documentation", + "sha256": "c518744da581303c8911280323605350d6267503ab8b1955fa99574389d8d1c5" + }, + { + "bytes": 124441, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_3_axis.png", + "role": "documentation_asset", + "sha256": "47d5edc93bed9fa4b80de8357180fc21fa52cef817ae7c1a2c4aeb762d05ec06" + }, + { + "bytes": 144277, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_3_axis_mid.png", + "role": "documentation_asset", + "sha256": "2adc6049fdcd859d7ea7011c99e8cc222e67c7f1bd680cd8629ffabe4c67f26e" + }, + { + "bytes": 153734, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_5_axis.png", + "role": "documentation_asset", + "sha256": "f98ebf77ff76f76fc7e54f76e3a507abaa1d9024f4900a0ce39ac60557268714" + }, + { + "bytes": 187610, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_5_axis_mid.png", + "role": "documentation_asset", + "sha256": "74460d731ccc68c377d8e024de82614f144cbf314825707f2119526599f899a3" + }, + { + "bytes": 137849, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_back_tool_lathe.png", + "role": "documentation_asset", + "sha256": "3e867401c53bc6b1b846c37f4afa6e25160c79f03e76cd290c026e65d883ddfa" + }, + { + "bytes": 152951, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_embedded_tabs.png", + "role": "documentation_asset", + "sha256": "a7c6b24db08aa993a396882dfa1142934af8277bc7f6669892dca84215b644d4" + }, + { + "bytes": 236095, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_file_selection_dialog_with_keyboard.png", + "role": "documentation_asset", + "sha256": "aa49597d17aea3ea769066763996dad8d280b31df5e0a36bff6316565283de97" + }, + { + "bytes": 135434, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_getting_macro_info.png", + "role": "documentation_asset", + "sha256": "fe8dff0af22b8b01e003800e3fc95967aee8a43d88afff70234382b89dc0f993" + }, + { + "bytes": 150441, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_getting_macro_info_mid.png", + "role": "documentation_asset", + "sha256": "e18fa1514f4e15a5e38f8c8d32e13a3517db06d3c0c1bc2d7c9dbbfc6ab2d9b4" + }, + { + "bytes": 17517, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_icon_theme_symbolic.png", + "role": "documentation_asset", + "sha256": "4bd60c281c1cc9094f032fca2712a4a9ea6224bfca4a5978f89d6279127a0612" + }, + { + "bytes": 318588, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_keyboard_edit_mode.png", + "role": "documentation_asset", + "sha256": "ad486af902da9dc8c1d7456291492abf40ddcda5acb57d35f5a06e9e40f88f2f" + }, + { + "bytes": 267524, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_keyboard_edit_mode_mid.png", + "role": "documentation_asset", + "sha256": "ce07a72a86a8ed8a0027be3bc98cf480d9d97319a59015d03ce104b732b9a70c" + }, + { + "bytes": 134010, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_lathe.png", + "role": "documentation_asset", + "sha256": "ffab0957e1a4f4c5654e78f1e6db56d9af677a4c1bd7f50744beaae469556591" + }, + { + "bytes": 11804, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_manual_toolchange.png", + "role": "documentation_asset", + "sha256": "91347241b3f0db6a67485b8d63f2ccafa1accdc692e60d903531385c1f519d52" + }, + { + "bytes": 168983, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_ntb_preview.png", + "role": "documentation_asset", + "sha256": "7be0916ccd952557e05ca38de3e65d874d5fa85f7d9b22f27828ed1ec73e7dab" + }, + { + "bytes": 100294, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_ntb_preview_small.png", + "role": "documentation_asset", + "sha256": "8bcda4d48dd15d7ea412baf9bd482bc97988a609204b0b8fafef251ffb1820b0" + }, + { + "bytes": 147579, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_plasma.png", + "role": "documentation_asset", + "sha256": "310cc035686d098ee8baab8959e9e9dd8c35e7b59b436f8bcd2a55996855758d" + }, + { + "bytes": 122214, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_settings_advanced.png", + "role": "documentation_asset", + "sha256": "dd90c544ba5c776b6b1ef48b4c645cfbb93b2fdbd0843295ae54fcbfae85e997" + }, + { + "bytes": 161168, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_settings_appearance.png", + "role": "documentation_asset", + "sha256": "40bd40967eaa2c09c0c01da5924f1fc55c1b8b6bf6d79dcdd6be60b245880d84" + }, + { + "bytes": 4553, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_settings_button.png", + "role": "documentation_asset", + "sha256": "0c9ffdf33d9c4696f91fa8205c066b7e6c55c0647b75ce27f12b60b9ea8a6d86" + }, + { + "bytes": 102994, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_settings_hardware.png", + "role": "documentation_asset", + "sha256": "735f728f663362058b6b89fde66ba696398c7d7f93312d44f49ae1252d6e76c8" + }, + { + "bytes": 149665, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_sim_hardware_button.png", + "role": "documentation_asset", + "sha256": "745a74a7e330c0438f948ba4581f4df4cba76d22d6dc24411420e8349c26c6ce" + }, + { + "bytes": 164325, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_sim_hardware_button_mid.png", + "role": "documentation_asset", + "sha256": "2bdcac9bde718ffe79ae60703b17ec9b88953f082d85e8cac0f87a2cd1cb3032" + }, + { + "bytes": 8062, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_tool_info.png", + "role": "documentation_asset", + "sha256": "a854a9143badb577ed314e5ac08d5e0c503cc6c0a106af3f54bfa39067db0a79" + }, + { + "bytes": 217035, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_with_right_panel_in_MDI_mode.png", + "role": "documentation_asset", + "sha256": "c1bd54426a67ee18f3b107f876980bb0745af5d4a9f156707bb89c146abb6e32" + }, + { + "bytes": 127712, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_with_right_panel_in_MDI_mode_small.png", + "role": "documentation_asset", + "sha256": "349def9769ffdedad8e15a70ac4b2f45e8520fed5100240bd2aca9c9f1f28a87" + }, + { + "bytes": 155917, + "path": "linuxcnc/docs/src/user/images/gmoccapy_4_axis.png", + "role": "documentation_asset", + "sha256": "951f796a1b3a9cb58bb7a7e09407b142196b06934c445f10a45e007695184499" + }, + { + "bytes": 0, + "path": "linuxcnc/lib/python/gmoccapy/__init__.py", + "role": "implementation", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + { + "bytes": 10577, + "path": "linuxcnc/lib/python/gmoccapy/dialogs.py", + "role": "implementation", + "sha256": "045430bbb041acd2bdfff0594b0efb14f85d01ebcae452382670944c3192f768" + }, + { + "bytes": 19430, + "path": "linuxcnc/lib/python/gmoccapy/getiniinfo.py", + "role": "implementation", + "sha256": "fa93a8998a2a7701e2b822ef202d6e3d481f7b9c5b97fc82c41bded2896c9e03" + }, + { + "bytes": 3249, + "path": "linuxcnc/lib/python/gmoccapy/icon_theme_helper.py", + "role": "implementation", + "sha256": "caf444318e1d6864f8257c5f3658d8657c164007ce54c5ec10cddd068317d8a0" + }, + { + "bytes": 14320, + "path": "linuxcnc/lib/python/gmoccapy/notification.py", + "role": "implementation", + "sha256": "81ee7e9262e3b633f506bde182918e12b196ddb655dfe980c7436e12c3b17bae" + }, + { + "bytes": 2630, + "path": "linuxcnc/lib/python/gmoccapy/player.py", + "role": "implementation", + "sha256": "82d150e2ae3b6a7aa67d056b3d5f002274b0362446ebe4782fc6c7872052b159" + }, + { + "bytes": 1617, + "path": "linuxcnc/lib/python/gmoccapy/preferences.py", + "role": "implementation", + "sha256": "6d09e9f38b7ab0feff2e436020c4a4a2db0f7126abb377ce08de05d41e46039d" + }, + { + "bytes": 1596, + "path": "linuxcnc/lib/python/gmoccapy/widgets.py", + "role": "implementation", + "sha256": "dbce55d80efcdee00e371e875983207c07facf29eca1805398d0286ef8877c02" + }, + { + "bytes": 486712, + "path": "linuxcnc/share/gmoccapy/gmoccapy.glade", + "role": "installed_ui_asset", + "sha256": "60c38418b7fb8690cc8cd942e2b758782bb734ee458d34eb63a416ba084a2112" + }, + { + "bytes": 500, + "path": "linuxcnc/share/gmoccapy/icons/Logo.png", + "role": "icon_asset", + "sha256": "efe0cb2afe7923b037214e049005ef90741f008eea4e26919488b30e0305d319" + }, + { + "bytes": 1025, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/actions/select_file.png", + "role": "icon_asset", + "sha256": "de4f584b191618b2fc7d4098001a05aea2ce7bbfb3608155064783c87c3278ff" + }, + { + "bytes": 311, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/actions/skip_optional_active.png", + "role": "icon_asset", + "sha256": "78fbe6fd2cb1a203b3964b5fb6681e0d233bd49fa094f5f15237d833a74e935a" + }, + { + "bytes": 314, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/actions/skip_optional_inactive.png", + "role": "icon_asset", + "sha256": "786ce07fabe9e277ef5f8243293a5666562d412043404551a307603a8db25e21" + }, + { + "bytes": 922, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/actions/tool_axis_p.png", + "role": "icon_asset", + "sha256": "6a84a15efc1a2e944db6440c738f26e1e9f46b1c50853052c3b0baa46eaf0df7" + }, + { + "bytes": 524, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/actions/tool_axis_x.png", + "role": "icon_asset", + "sha256": "9d8a51a3b5e3b7aedc2be209fc2be2fecaf8493364f3d6d845b5b172ce5d2723" + }, + { + "bytes": 525, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/actions/tool_axis_y.png", + "role": "icon_asset", + "sha256": "8678de1a909b1ffe897c99a9817f20f7867474897a0f7e1ac3c5921ae97e9c0a" + }, + { + "bytes": 6634, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/actions/tool_axis_y_inv.png", + "role": "icon_asset", + "sha256": "f4f2cc133669f98942b7ae305c7bc6034e3a5f1d96ab20a37bfa695ba2b58855" + }, + { + "bytes": 543, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/actions/tool_axis_z.png", + "role": "icon_asset", + "sha256": "aed4e7fe5c0332d59deb1241c6131644df7d0718ded41b77b06967e0e478429b" + }, + { + "bytes": 1119, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/actions/toolpath.png", + "role": "icon_asset", + "sha256": "5375cc7f6c725772bc2baeffbab1aa87d1ced99e043cc72356903c94e7292253" + }, + { + "bytes": 803, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/actions/window_close.png", + "role": "icon_asset", + "sha256": "7c3495a26175c521fa630a8f17b8709995729230b4dc79f17a2c0642ff2ca1ff" + }, + { + "bytes": 1781, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/status/dialog_information.png", + "role": "icon_asset", + "sha256": "88773f056c7c0971cc851407eba17f929752ab0e862315a6019fee263ebd9367" + }, + { + "bytes": 1280, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/status/dialog_warning.png", + "role": "icon_asset", + "sha256": "ef2b0f31f196da8896ed677b135d8e767b2b9c48109fe8a9d2cdfdc0d74614b6" + }, + { + "bytes": 2127, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/clear.png", + "role": "icon_asset", + "sha256": "462d10e3d5ebf85aab1bd233b09769d678ada128a17ae2527d2159255cab8f02" + }, + { + "bytes": 2802, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/dimensions.png", + "role": "icon_asset", + "sha256": "7fbda93839aead5535524a7f60b16969a7efc9de86c1a13fcfe03a8e0e7aae71" + }, + { + "bytes": 1253, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/fullscreen_close.png", + "role": "icon_asset", + "sha256": "575dfcbc96647fe561bb7c065f8eb7f06b57b24f39a0c1f1aadff7678ea68890" + }, + { + "bytes": 1253, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/fullscreen_open.png", + "role": "icon_asset", + "sha256": "575dfcbc96647fe561bb7c065f8eb7f06b57b24f39a0c1f1aadff7678ea68890" + }, + { + "bytes": 3281, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/jog_speed_fast.png", + "role": "icon_asset", + "sha256": "fd9e88c788871c87dd09a470aee568841f860c490b2f96e231f14e7480f3e490" + }, + { + "bytes": 3294, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/jog_speed_slow.png", + "role": "icon_asset", + "sha256": "dfcd92f3444c5b778e43c91f91fafdbfbb2a921286559cf8547fb35329f357c5" + }, + { + "bytes": 1100, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/run_from_line.png", + "role": "icon_asset", + "sha256": "ae4f86eeb9ffe2429821701ff90394aa2e166132cf9e6a1a20e261a904813314" + }, + { + "bytes": 1039, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/select_file.png", + "role": "icon_asset", + "sha256": "7025e1990fe1fc52572e3ca9ce44813fde37299eb94115887b1211e41a692969" + }, + { + "bytes": 707, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/skip_optional_active.png", + "role": "icon_asset", + "sha256": "590a9be74f4337633fde6ed18f824169af2aa1aff78d78de82b063f363953b76" + }, + { + "bytes": 644, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/skip_optional_inactive.png", + "role": "icon_asset", + "sha256": "953d8ae2e180fc8ba42c611e2ce3e77fbffe63e4be4b6186743127fef5ca96d7" + }, + { + "bytes": 2902, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/zoom_in.png", + "role": "icon_asset", + "sha256": "1a3194a3bc7d89c1d65b3d8e92bec4fc64cd4de2582813ee8954da00a6503fca" + }, + { + "bytes": 2806, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/zoom_out.png", + "role": "icon_asset", + "sha256": "4c4e605f7404218725c84fbbde3ecc2a1b3fdb727d0724e5e36293df0d616e5a" + }, + { + "bytes": 1395, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/coolant_flood_active.png", + "role": "icon_asset", + "sha256": "a7de048afa66484fdb50db6fd38e0b2cbcc8fe42ce8c07a709320113228e7bbd" + }, + { + "bytes": 1804, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/coolant_flood_inactive.png", + "role": "icon_asset", + "sha256": "1c7751b016e7e4162345dd52381a2febf3843040d57b64ee76813d6aa16ea808" + }, + { + "bytes": 1580, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/coolant_mist_active.png", + "role": "icon_asset", + "sha256": "8a733e7144c9213efc2413c001225a6a23c7f0c78419ee6db73dd51a8ff60137" + }, + { + "bytes": 1877, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/coolant_mist_inactive.png", + "role": "icon_asset", + "sha256": "a3bb0f9373bfb709f5407686e077bd1dd0385cbf52a3ff1b3cf74bca75a19fd3" + }, + { + "bytes": 2574, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/edit_code.png", + "role": "icon_asset", + "sha256": "6cad9f8a61dba114e47db09a85d765f9cd35eb0be2843e5ed6e2c771bd2de523" + }, + { + "bytes": 2893, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/fullscreen_close.png", + "role": "icon_asset", + "sha256": "b97470176f71c53ef6a67d4f445af4325600418fe66a742d01bb1de8269fc9b0" + }, + { + "bytes": 2893, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/fullscreen_open.png", + "role": "icon_asset", + "sha256": "b97470176f71c53ef6a67d4f445af4325600418fe66a742d01bb1de8269fc9b0" + }, + { + "bytes": 1908, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/hsk_mill_tool.png", + "role": "icon_asset", + "sha256": "6d58c2b2b80bc2232f9b8b45085b556249b7a559b84f9ed525397811d370228e" + }, + { + "bytes": 4294, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/keyboard.png", + "role": "icon_asset", + "sha256": "cdd4824d3ceab28684aacae06a03dbc7a1a16bac808bfc5409ae92790f773fad" + }, + { + "bytes": 4294, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/keyboard_hide.png", + "role": "icon_asset", + "sha256": "8acb08007170aa2220e31be1ea5ec3087ce17e93e0e2e6472b92a74a9a9ea88c" + }, + { + "bytes": 3028, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/logout.png", + "role": "icon_asset", + "sha256": "037c5fc0b086f58fb5d3ebbd5fa75632ed5031b334854fbb0e9f02a078bbc133" + }, + { + "bytes": 2015, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/main_switch_off.png", + "role": "icon_asset", + "sha256": "882668744ba0839ede8d5fd86bb2eb125b01c7777f509df259e83c1ad2c36fdf" + }, + { + "bytes": 3475, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/main_switch_on.png", + "role": "icon_asset", + "sha256": "c05f17556ef02dd3feacc7c9eb9e986b4f0340f14092ad84b58979b2da6ecd95" + }, + { + "bytes": 3147, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mill_tool_change.png", + "role": "icon_asset", + "sha256": "491df4ffcd7bd6a6e5e8810b2e7fa4a66eb4ba12042d787ef0babab716ee0718" + }, + { + "bytes": 5387, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mode_auto_active.png", + "role": "icon_asset", + "sha256": "9cb87843da0cc3ecad895b19daf8f1f1853842f3bd943b4c644da69cfa87a440" + }, + { + "bytes": 5387, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mode_auto_inactive.png", + "role": "icon_asset", + "sha256": "9cb87843da0cc3ecad895b19daf8f1f1853842f3bd943b4c644da69cfa87a440" + }, + { + "bytes": 3909, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mode_manual_active.png", + "role": "icon_asset", + "sha256": "2d03714f7fad2c2d8f4ef264486f9af05c015e05fcdd81c30311607b493ba246" + }, + { + "bytes": 3909, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mode_manual_inactive.png", + "role": "icon_asset", + "sha256": "2d03714f7fad2c2d8f4ef264486f9af05c015e05fcdd81c30311607b493ba246" + }, + { + "bytes": 3441, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mode_mdi_active.png", + "role": "icon_asset", + "sha256": "b30c7a017c02387e989667e4db86836d2e38299a2765d944e005589e2e988abf" + }, + { + "bytes": 3441, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mode_mdi_inactive.png", + "role": "icon_asset", + "sha256": "b30c7a017c02387e989667e4db86836d2e38299a2765d944e005589e2e988abf" + }, + { + "bytes": 5321, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mode_settings_active.png", + "role": "icon_asset", + "sha256": "d36702de57c9c0cfc3c9997fc37ce0596e78b04f2c13af7747661eb9845d1f97" + }, + { + "bytes": 5321, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mode_settings_inactive.png", + "role": "icon_asset", + "sha256": "d36702de57c9c0cfc3c9997fc37ce0596e78b04f2c13af7747661eb9845d1f97" + }, + { + "bytes": 2947, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mode_user_tabs_active.png", + "role": "icon_asset", + "sha256": "2d57070fd1d3c2b5999fd24108afc3343a81a9a85d37b0d590f73a414be66ed2" + }, + { + "bytes": 2947, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mode_user_tabs_inactive.png", + "role": "icon_asset", + "sha256": "2d57070fd1d3c2b5999fd24108afc3343a81a9a85d37b0d590f73a414be66ed2" + }, + { + "bytes": 1414, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/pause.png", + "role": "icon_asset", + "sha256": "80c6e8750fd596c60f0e7d6c548a1bf82550409c311f42cf9c9f6460563b6106" + }, + { + "bytes": 1414, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/pause_active.png", + "role": "icon_asset", + "sha256": "a99caad8c891743a7f92251fe3bf9a9ffb28c0ab5f096bbdb73981d3b2735db2" + }, + { + "bytes": 2299, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/play.png", + "role": "icon_asset", + "sha256": "2120f4c0dcd7cd167add7ce015cab3a2f3bdb114871634c72bc7f0ab6123bd36" + }, + { + "bytes": 3590, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/power_off.png", + "role": "icon_asset", + "sha256": "4ef7bebb956c5f540a0d5a1721ded9598a1758c1589572bf41cc29775c83fd68" + }, + { + "bytes": 3565, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/power_on.png", + "role": "icon_asset", + "sha256": "ef88d706209ea63334ae70474f1d838d1b33ecebb1aee079b99852b7f2b673aa" + }, + { + "bytes": 1474, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_0.png", + "role": "icon_asset", + "sha256": "e541c52f80e212fb7233f943b0f0f0eb4294a65a787bada8f64a23e4c3486aaa" + }, + { + "bytes": 1417, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_1.png", + "role": "icon_asset", + "sha256": "8c0cd191788c33293776d181cc1e216beee09fd50fffdc4b32d03e5029c293d3" + }, + { + "bytes": 1469, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_2.png", + "role": "icon_asset", + "sha256": "d6607c8e8dcc83c48d3ce135bc19c7be90ee853caf6dafb45f525a16d70e08df" + }, + { + "bytes": 1482, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_3.png", + "role": "icon_asset", + "sha256": "e2048d54b2be7c5ebbd161418f1d2b1d1c5b8b36a480a7e2957dd235be4d52e4" + }, + { + "bytes": 1445, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_4.png", + "role": "icon_asset", + "sha256": "1d041f8e022beee5966d20be5ba03888df9427513afa6fe9c2e928eec67fec49" + }, + { + "bytes": 1481, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_5.png", + "role": "icon_asset", + "sha256": "083f372446160639660ca22db974823a850ab02549349d9a17e0cc863426ccb9" + }, + { + "bytes": 1486, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_6.png", + "role": "icon_asset", + "sha256": "301e077781a04fff163bd53ff44e09483e7b966f1838033abf86e7628a777838" + }, + { + "bytes": 1458, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_7.png", + "role": "icon_asset", + "sha256": "88182909f6e51aa2be8636a1cbe8f804afb3053ff44ef4aa5e6b84ce9993bf3b" + }, + { + "bytes": 1768, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_a.png", + "role": "icon_asset", + "sha256": "4aecf2fc02df7badbb4bd5c28e008d54bba3760b468a0857e7de5c9fd975a7ed" + }, + { + "bytes": 1824, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_all.png", + "role": "icon_asset", + "sha256": "269545d20801174e6223d22d0333ca1424afe42bd940018e9390b9fb6ed468f2" + }, + { + "bytes": 1682, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_b.png", + "role": "icon_asset", + "sha256": "5049e4919dc3384b17c52f7edec04cc009b90abd09b71a869e95427e6b433d2e" + }, + { + "bytes": 1753, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_c.png", + "role": "icon_asset", + "sha256": "615fc06c75147014403880f6fa7e348725dd0d446e65aff18e8a3cbf29f36164" + }, + { + "bytes": 1134, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_u.png", + "role": "icon_asset", + "sha256": "67317261013f5995060a33a52323025f23d4fd5570fcaefaf00ca20315077f38" + }, + { + "bytes": 1214, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_v.png", + "role": "icon_asset", + "sha256": "67f9305d2567411dc3fb72bc35289334faaff1aed28934875fa73b43ac7a359a" + }, + { + "bytes": 1298, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_w.png", + "role": "icon_asset", + "sha256": "622fb9ac7accdd50eea4576ad543051cb9153f8a8eb4114bc911d8d433a8065e" + }, + { + "bytes": 1816, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_x.png", + "role": "icon_asset", + "sha256": "9e6ce1ae01b283ff3109f2a3cc87871c4edb0267b3c4d5b9c7e0684e5ea4b8ff" + }, + { + "bytes": 1708, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_y.png", + "role": "icon_asset", + "sha256": "12cec495117f021f821c53df7eb6bf361d4ca192fab4b838d4383f760adfcfb5" + }, + { + "bytes": 1698, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_z.png", + "role": "icon_asset", + "sha256": "5c3c32b4e2429c346bafb1a4754cc8c8e8afcaadc02c61f1ee0548ce99600de8" + }, + { + "bytes": 4262, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/refresh.png", + "role": "icon_asset", + "sha256": "0de1c057af71aa4cf24c6a0ec33b6289c48654b829029f781195e9393da600c8" + }, + { + "bytes": 1374, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/run_from_line.png", + "role": "icon_asset", + "sha256": "0624e20ef832d6a04afffe22b055f08b1191a7cdc2118c76fdcb826b61c9e080" + }, + { + "bytes": 4074, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/save.png", + "role": "icon_asset", + "sha256": "a5ac7eb0bc204809f0cdd21a2d28d64e3f0c049883cb29779b94ca946abaa1af" + }, + { + "bytes": 4418, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/save_as.png", + "role": "icon_asset", + "sha256": "c5ea2f9f6f29f76af91fe47421971151be8bf09991daf71e2e971781ed3ca11c" + }, + { + "bytes": 1750, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/spindle_left.png", + "role": "icon_asset", + "sha256": "bf920a0027b26eda098473069fae307ede2655fd070af6bf3dfa66bac01812d5" + }, + { + "bytes": 1391, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/spindle_left_on.png", + "role": "icon_asset", + "sha256": "261342c8836b862d5a0ca137da23421f3304b65ccf2ed1f9aa4e67b1647d58a6" + }, + { + "bytes": 1738, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/spindle_right.png", + "role": "icon_asset", + "sha256": "493b5845d197d3fddc0e5e23a3ecc105e2a5d751c120e63facb6f03248080d3d" + }, + { + "bytes": 1360, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/spindle_right_on.png", + "role": "icon_asset", + "sha256": "f83553e1ceaf73988ea0a9c9179de50f819763d10dce7f8d5c9345b785065b78" + }, + { + "bytes": 1674, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/spindle_stop.png", + "role": "icon_asset", + "sha256": "022e42aa9e559ea64ae15d987786c2a2d42e5272008a591337a0d69001012a50" + }, + { + "bytes": 1674, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/spindle_stop_on.png", + "role": "icon_asset", + "sha256": "022e42aa9e559ea64ae15d987786c2a2d42e5272008a591337a0d69001012a50" + }, + { + "bytes": 2636, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/step.png", + "role": "icon_asset", + "sha256": "b5298bd7efd065e3cc26ea6dcddeb31b4296a5fff5bbe1cead19c783a6838dab" + }, + { + "bytes": 2561, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/step2.png", + "role": "icon_asset", + "sha256": "8e53707482b77af50a874725d113c4ff13388f853e34f75c0d9f0eb581f83e1e" + }, + { + "bytes": 3239, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/stop.png", + "role": "icon_asset", + "sha256": "30231a93caab7794b1c897d22cc3589a3abf382103911aadb0bc9ffedfb2e535" + }, + { + "bytes": 2621, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/touch_a.png", + "role": "icon_asset", + "sha256": "cffef1f153d31104a3221d5d64cb60037265ddeea56a7eec1ea988d9d0653098" + }, + { + "bytes": 2518, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/touch_b.png", + "role": "icon_asset", + "sha256": "389230f3e3dd70726430eb35a33158e2f064530d69fae44014615b4e02a62b8a" + }, + { + "bytes": 2577, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/touch_c.png", + "role": "icon_asset", + "sha256": "80cdfd1cf53e153c735f2ea98726e03b0a96dbda12b96c85fe296e250335d477" + }, + { + "bytes": 3173, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/touch_off.png", + "role": "icon_asset", + "sha256": "ae83323ac447432f43c68e21457c62c760d690aa4f85509aaac036057cfde9bf" + }, + { + "bytes": 2459, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/touch_u.png", + "role": "icon_asset", + "sha256": "fe6b80e562f2f35123723ad23c9ca58d5f5ed8f0208f62d366f0cbf47dfd8039" + }, + { + "bytes": 2599, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/touch_v.png", + "role": "icon_asset", + "sha256": "3fa570befa4b5b5f3148a5ec64caecaaa2122461a8882921c1dcb5b79de6ebb9" + }, + { + "bytes": 2596, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/touch_w.png", + "role": "icon_asset", + "sha256": "2198ea796ce65283ec7b84da888d533f147e547b77fb0fd6240180f397e601db" + }, + { + "bytes": 2737, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/touch_x.png", + "role": "icon_asset", + "sha256": "64c1dd06e6cc88e8d9aa6d969ee24893ec4f84ba2fc7e3db4fb8a95fe512d5ca" + }, + { + "bytes": 2632, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/touch_y.png", + "role": "icon_asset", + "sha256": "52e8a1988074bfc01fe23ee7baead317108377788ecfba33dc61f14aff93f59c" + }, + { + "bytes": 2642, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/touch_z.png", + "role": "icon_asset", + "sha256": "d3bbc3c990f4fd185de18a9ae02d0ac90647a691f2886a0fe00953e531789452" + }, + { + "bytes": 1837, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/unref_all.png", + "role": "icon_asset", + "sha256": "b7c6a7cd433acfea16dfd0aea134aadf22dafccbba96a4313c4033eeebafe043" + }, + { + "bytes": 410, + "path": "linuxcnc/share/gmoccapy/icons/classic/index.theme", + "role": "icon_asset", + "sha256": "1ddb180fb3382b941e53b68436f7f0ec2d1aff48c4a89dd3d5114cbf6f2475fc" + }, + { + "bytes": 9235, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/back_to_app.svg", + "role": "icon_asset", + "sha256": "9c81f5f14aa7a1457faf14ecd1bfc255ed16cef15a661b5f30d23f0d385450c9" + }, + { + "bytes": 28435, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/chevron_left.svg", + "role": "icon_asset", + "sha256": "75269150414f9bdfb0eee741ad36209c500d27c0b2d8462b134e0cf7b6d8f7d8" + }, + { + "bytes": 7904, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/chevron_right.svg", + "role": "icon_asset", + "sha256": "e7e79d37fb27d42437e0449affe7b8effbc3391e4450f53f0f88602049f7b30c" + }, + { + "bytes": 8218, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/chevron_up.svg", + "role": "icon_asset", + "sha256": "7d51d4af61813049ee8cf2d3091099404048a3477e5366e646b19627179cce95" + }, + { + "bytes": 21437, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/home_folder.svg", + "role": "icon_asset", + "sha256": "d2efceb512de09e1f335b00290d0d2e575d48fa59cf2e2fa1b00eaa20bba5918" + }, + { + "bytes": 1062, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/mill_tool_change_num.svg", + "role": "icon_asset", + "sha256": "9d226f53a22b48a89413d17a4f7304e689aaa96b7c5e39de992fca5b499bb8bb" + }, + { + "bytes": 2602, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/mill_tool_set_num.svg", + "role": "icon_asset", + "sha256": "b8b178cbaed89fd691136c43183759e3889eb0a808e6301fa7bff3db2d53f7b8" + }, + { + "bytes": 17406, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/new_document.svg", + "role": "icon_asset", + "sha256": "120979205507a818ae3ed80df09d5c3f15a12c5ba399a886db6ce421aec6619c" + }, + { + "bytes": 30805, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/open_file.svg", + "role": "icon_asset", + "sha256": "16d5d4ac93a43413602fb93624b3a664c04d0fe3fd0066dd60c7121f14815549" + }, + { + "bytes": 16868, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/refresh.svg", + "role": "icon_asset", + "sha256": "a43596670cfced66e14bd9ee984288a9d69490f0f08953ad13f2a6bf5e4d70fb" + }, + { + "bytes": 29894, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/save.svg", + "role": "icon_asset", + "sha256": "1f6449445b659c35880150969eee3c728e463ccc2d2151abbad77294021cc24f" + }, + { + "bytes": 31913, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/save_as.svg", + "role": "icon_asset", + "sha256": "832bde0688bd137edd42266f8cf9700034ec8494b154c41bdb50d0e52183dccb" + }, + { + "bytes": 8114, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/user_defined_folder.svg", + "role": "icon_asset", + "sha256": "da4e4493791e6e53325c72f67e61c4ef21d148edda740256beb48c7e72f062f6" + }, + { + "bytes": 260, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/back_to_app.symbolic.png", + "role": "icon_asset", + "sha256": "a1280355363b2a1b314a81d1470fa5cf8fab060d575b5e9beb481a58720b676d" + }, + { + "bytes": 159, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/chevron_left.symbolic.png", + "role": "icon_asset", + "sha256": "7f0d5c13bc20e701f485fc6dbdc17adea0fff1fe04a3d37f9d2ecf4dfe4420d7" + }, + { + "bytes": 160, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/chevron_right.symbolic.png", + "role": "icon_asset", + "sha256": "4b71db01d0548ef84f10df8b56eddb20e805810548c1c16ca09eabc39c19c16b" + }, + { + "bytes": 174, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/chevron_up.symbolic.png", + "role": "icon_asset", + "sha256": "513c31cb58101df9cb772e204cf07a2a024bfee354148b961d41e4f3bba5fec4" + }, + { + "bytes": 275, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/clear.symbolic.png", + "role": "icon_asset", + "sha256": "30b047ad0ae9daebbe99801a034e97960cc4fe2e090041aa74749da53412e284" + }, + { + "bytes": 354, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/coolant_flood_active.symbolic.png", + "role": "icon_asset", + "sha256": "b864127bb210e61d7ad1954d65617d92c5c18699f5a1bcc16aed8a1736155718" + }, + { + "bytes": 330, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/coolant_flood_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "c217c97e41dd2a1dc80e9f5ca215feea090611de9085e546269853daba16cb13" + }, + { + "bytes": 383, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/coolant_mist_active.symbolic.png", + "role": "icon_asset", + "sha256": "ebf5e86f32f68a680d84a6952085bcaf6a29e90820e8ae87e92b824f4a9cca80" + }, + { + "bytes": 361, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/coolant_mist_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "6bc670cbe9bfab6bf948bb8653793f75eca2befe229706a632e7db05d77583c6" + }, + { + "bytes": 254, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/dimensions.symbolic.png", + "role": "icon_asset", + "sha256": "d5a487f1d77518341c7f6bf6f28f19737ce7291e83bfedc1705877cf6e6518f9" + }, + { + "bytes": 256, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/edit_code.symbolic.png", + "role": "icon_asset", + "sha256": "95c0e6eaf752c431cc21e250347fe311da7fa3cba4b0bfa7a55b0b6071073f30" + }, + { + "bytes": 173, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/fullscreen_close.symbolic.png", + "role": "icon_asset", + "sha256": "01e98490a63c493991096fd6050857d4746f3940c41d2494dfd60fa0dd738cf4" + }, + { + "bytes": 171, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/fullscreen_open.symbolic.png", + "role": "icon_asset", + "sha256": "f8d4498ebeb4d7f3c0eaf52169540d3b88a4797d2f55f2acababa65fd2c47927" + }, + { + "bytes": 233, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/home_folder.symbolic.png", + "role": "icon_asset", + "sha256": "07796a08e5e53c53fccba1351b56e4074570b995c2e54ee3b145d4b1136152a3" + }, + { + "bytes": 253, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/hsk_mill_tool.symbolic.png", + "role": "icon_asset", + "sha256": "e817bf1d237217b40a90531b943fd4427816fe35f050189a889eb323a94cc913" + }, + { + "bytes": 338, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/jog_speed_fast.symbolic.png", + "role": "icon_asset", + "sha256": "78fb8d36f7204820df4accddd99794d82f3c84cd499a207c1ac187bad1049e19" + }, + { + "bytes": 285, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/jog_speed_slow.symbolic.png", + "role": "icon_asset", + "sha256": "103ae5c0836590b6fe68d5842c4587f5d5da1bf2d7dc784ddd7d2095bba5b0c3" + }, + { + "bytes": 262, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/keyboard.symbolic.png", + "role": "icon_asset", + "sha256": "85577545ae5110cfe702dcf768b11e1af193edea51d03c845051bd7b5c24d166" + }, + { + "bytes": 295, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/keyboard_hide.symbolic.png", + "role": "icon_asset", + "sha256": "5bfb42885e6dfd5531d8deff0ba67ec0bfcae8c73ab2f4760174638a4b17d979" + }, + { + "bytes": 277, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/logout.symbolic.png", + "role": "icon_asset", + "sha256": "c178f300b1233a518158b67ada86ad7f88032f93931de83f04ec2fd216c83cba" + }, + { + "bytes": 462, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/main_switch_off.symbolic.png", + "role": "icon_asset", + "sha256": "5361793524d49ed2169f193c866a01fe4dbac02db6a149c7fdd8238ff2f30c96" + }, + { + "bytes": 394, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/main_switch_on.symbolic.png", + "role": "icon_asset", + "sha256": "ce612984816536aff549fc4cc02e1295c715ba19d9602aba2bbddeb303464639" + }, + { + "bytes": 372, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mill_tool_change.symbolic.png", + "role": "icon_asset", + "sha256": "2eafa45030b0d49f4c78921e5233786512e466c8470e7d40a1e8b01a459f93f0" + }, + { + "bytes": 383, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mill_tool_change_num.symbolic.png", + "role": "icon_asset", + "sha256": "2b7eb4370ce1ef85d8cbc5b1593cc1f2e76291d4081854e38f0dbb76807743e0" + }, + { + "bytes": 401, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mill_tool_set_num.symbolic.png", + "role": "icon_asset", + "sha256": "e9fd581e1a71c62122da21f021a3708b45e915a4c3adebeb570cc8f36b7aa2a6" + }, + { + "bytes": 256, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mode_auto_active.symbolic.png", + "role": "icon_asset", + "sha256": "76516598df1e4cb3ac93d6f629623040f86a89fc4ca217d9f1e6fb844f7f3795" + }, + { + "bytes": 253, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mode_auto_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "77279a80c4bf6825a33694e3ef248f8c0d35d4ec771313672764a90cc7a0fd22" + }, + { + "bytes": 268, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mode_manual_active.symbolic.png", + "role": "icon_asset", + "sha256": "c23ae2fc2d2c9b2b5811ed9cbcf56005be5c8b75d76c7e42a3003a506be15595" + }, + { + "bytes": 266, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mode_manual_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "5398d74036bb2056629c3805e97b69d2faff94ea20e1105b1eb21cf044088be3" + }, + { + "bytes": 305, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mode_mdi_active.symbolic.png", + "role": "icon_asset", + "sha256": "2889085d9b19471923508b0a7d5499b9985841ac0ba824e626b99bb3b5107192" + }, + { + "bytes": 301, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mode_mdi_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "7f321930c1871d34b8ffa0bb607a077d32ba7cadde34832e01cbab5ee961b724" + }, + { + "bytes": 320, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mode_settings_active.symbolic.png", + "role": "icon_asset", + "sha256": "1cd35fe51036a2a3290f6f50d737ed360d8bcc494d3ec3e8dd96c80c449ec745" + }, + { + "bytes": 317, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mode_settings_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "10151aee5f15576f47dd46c9a70c88f1386d8b539fa091fab59735ea78313296" + }, + { + "bytes": 274, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mode_user_tabs_active.symbolic.png", + "role": "icon_asset", + "sha256": "54e0e9b766478332431bafa42172cce793fccbbea6c2f87ed07ecbefd4111bcd" + }, + { + "bytes": 272, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mode_user_tabs_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "0c0ab409ae7648ee052050b38cf580f59f46c9e62b49aa8ec3d63056dba588e5" + }, + { + "bytes": 298, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/new_document.symbolic.png", + "role": "icon_asset", + "sha256": "cb5af2ccd4171815ce10e92b35e4a561fcd026d4f13fe299b6bbe70c4538e9ff" + }, + { + "bytes": 268, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/open_file.symbolic.png", + "role": "icon_asset", + "sha256": "f5adf4527779538f6f72a9982f5006fa239517fa7ef5857bcac868675f04fe45" + }, + { + "bytes": 154, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/pause.symbolic.png", + "role": "icon_asset", + "sha256": "660c43c4b1e72c331723c1e4337a453fd5c03079d9fd3d7930d28befce21cb0c" + }, + { + "bytes": 159, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/pause_active.symbolic.png", + "role": "icon_asset", + "sha256": "5548a361c3331ca336c7b842e79197782a15960023c891795ef8a97a4a87144b" + }, + { + "bytes": 175, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/play.symbolic.png", + "role": "icon_asset", + "sha256": "48ea3e17251473033687f2a1616e0ea69ef237d2df97be1429844c11b60e3727" + }, + { + "bytes": 320, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/power_off.symbolic.png", + "role": "icon_asset", + "sha256": "8c4e3509a12080ef0f45521e25baee1dd53f80ba5efffebc2c9e912bd02dda74" + }, + { + "bytes": 322, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/power_on.symbolic.png", + "role": "icon_asset", + "sha256": "48ddf332f456508c70d76ee0cdb8ac76f725089e29a31f8ea1b8dcd6c6a63c46" + }, + { + "bytes": 330, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_0.symbolic.png", + "role": "icon_asset", + "sha256": "76de46a993ed2b519b7be5cf0aa834fba15ab41b8b67e6c1b21b69797aa7fc06" + }, + { + "bytes": 281, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_1.symbolic.png", + "role": "icon_asset", + "sha256": "801b5816de7d45b1309fb5c168f50ed43c946ea63bfae2b462dc74ceead710d4" + }, + { + "bytes": 301, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_2.symbolic.png", + "role": "icon_asset", + "sha256": "800a57c21ad91ff97a73a51492ca40c1e7a81ce4a0bc25efd406386d2b3c03a5" + }, + { + "bytes": 314, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_3.symbolic.png", + "role": "icon_asset", + "sha256": "a3d576eae6a054fb989394f19109eaa0497fdc76514ff1366ffe6de4ec87d4a1" + }, + { + "bytes": 304, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_4.symbolic.png", + "role": "icon_asset", + "sha256": "b261a04e8c40ec95578d70d292472d6fcef9101579dfc6f826ce91275557724a" + }, + { + "bytes": 311, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_5.symbolic.png", + "role": "icon_asset", + "sha256": "9ce3826336ca1e672bf09e42c130f40295873e2a10096cd6d4bda1d974061ed0" + }, + { + "bytes": 317, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_6.symbolic.png", + "role": "icon_asset", + "sha256": "04af9a062f453c29b3b222963fb9753de12e61c51c6eff955c9e4b59743eee8a" + }, + { + "bytes": 295, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_7.symbolic.png", + "role": "icon_asset", + "sha256": "4d3d79080b42d15a0d7a7b84c3662d2c44bba9f964a1811e4ee8c0aaaa98b743" + }, + { + "bytes": 314, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_a.symbolic.png", + "role": "icon_asset", + "sha256": "32d49246f659f2ad3b180716cb77edae13a3dd4c1a0b8989c43e2fd424bd05f2" + }, + { + "bytes": 299, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_all.symbolic.png", + "role": "icon_asset", + "sha256": "92fddfd58ccc85367fba7c927d8ef1793f0de6bbad42643c7693391947b63b81" + }, + { + "bytes": 329, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_b.symbolic.png", + "role": "icon_asset", + "sha256": "f233d0d26a9368c4832ff189d68e62d1c7177fa9a3b24ad0a7f24e221d3c0b21" + }, + { + "bytes": 323, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_c.symbolic.png", + "role": "icon_asset", + "sha256": "a7b8e09f320c50623a0d7d178a081890c81d64c1414bb931ba35540b40895cee" + }, + { + "bytes": 309, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_u.symbolic.png", + "role": "icon_asset", + "sha256": "b1063236ddc5c8ab3b21d449f2206fa58655e2537897f008b586b1a3f11dade4" + }, + { + "bytes": 306, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_v.symbolic.png", + "role": "icon_asset", + "sha256": "673249e57a1744a1a445a97e0bc87eff2edc065cdde84a23dfb79f023226c519" + }, + { + "bytes": 338, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_w.symbolic.png", + "role": "icon_asset", + "sha256": "247cff2e6a8be41c4d28c9dfc44d7a483800f10ec319c4f1dd18817e4af05935" + }, + { + "bytes": 301, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_x.symbolic.png", + "role": "icon_asset", + "sha256": "bfa6803b363246d8d44dc324692a2b1648f13fd9d9f5e90a4e093b155b0eb22f" + }, + { + "bytes": 290, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_y.symbolic.png", + "role": "icon_asset", + "sha256": "893c76d71627f6d859e65289646480fea1b48922fce7cee5c478e4269f66f6a6" + }, + { + "bytes": 307, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_z.symbolic.png", + "role": "icon_asset", + "sha256": "7faa5373fc6e6e7532640b757e49753d71cb0c4b4ff7d49e69948819308f8678" + }, + { + "bytes": 323, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/refresh.symbolic.png", + "role": "icon_asset", + "sha256": "ad87489ffae4f7d513d27add3c50c93507628e4374cba8815663e2e0aea4cc9a" + }, + { + "bytes": 205, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/run_from_line.symbolic.png", + "role": "icon_asset", + "sha256": "570f9c67a6b575fccc1d9011fa1577afa03bc2d8daaf3de49d870a6f45179a08" + }, + { + "bytes": 242, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/save.symbolic.png", + "role": "icon_asset", + "sha256": "d3e52f0b93db490832a3c7be09de2c65e7df173f1496dfd767a0f86bbaff2e25" + }, + { + "bytes": 319, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/save_as.symbolic.png", + "role": "icon_asset", + "sha256": "229f3a658e0ad01476f93ef7242142457b9336b46300e017826aebd22a6512ee" + }, + { + "bytes": 301, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/select_file.symbolic.png", + "role": "icon_asset", + "sha256": "beefcd0f741cc654be5774a738cb758db820ff3d5665752bf6fff9ae6734b6c8" + }, + { + "bytes": 277, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/skip_optional_active.symbolic.png", + "role": "icon_asset", + "sha256": "acc95bc6fd2500f5e00076e1982e19fdbe47223f8c01a2ebf2be6241c5b1951b" + }, + { + "bytes": 381, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/skip_optional_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "8db534a876a735a556c1859699a26fae2c5dba177bc0f7470959ba3169a55188" + }, + { + "bytes": 298, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/spindle_left.symbolic.png", + "role": "icon_asset", + "sha256": "cda7fae92bd47eab7a1ffe13272654292e44ad084191c2ea7ca3b58e5d9a76e9" + }, + { + "bytes": 306, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/spindle_left_on.symbolic.png", + "role": "icon_asset", + "sha256": "d3af4e3cb5c1f5ba38283fc4dc56c33fb163534580e2f92765a98b385e89ca6a" + }, + { + "bytes": 295, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/spindle_right.symbolic.png", + "role": "icon_asset", + "sha256": "872632731c05964d2dbece6eeed0a401c4d74228f247ac30ff9f1a8f6104dde2" + }, + { + "bytes": 303, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/spindle_right_on.symbolic.png", + "role": "icon_asset", + "sha256": "11b1b4019a86fd970befa045b8c27564e0da227c9836f669c000a2decb403623" + }, + { + "bytes": 315, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/spindle_stop.symbolic.png", + "role": "icon_asset", + "sha256": "93ed9aff6fb027fc359233667b3fc7c043f3155a022248aa93a4b4a77261d3d2" + }, + { + "bytes": 280, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/spindle_stop_on.symbolic.png", + "role": "icon_asset", + "sha256": "94e0bf4bed9f59c3e40832c819ce4fc6c63c366b372903a1507da3057c6374d2" + }, + { + "bytes": 253, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/step.symbolic.png", + "role": "icon_asset", + "sha256": "cb8464db02675b24363a16186a2b52f26fd240801229d49766cf99f164889878" + }, + { + "bytes": 106, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/stop.symbolic.png", + "role": "icon_asset", + "sha256": "c073ea324c23879211fa578742da1feeb04a3ed5eec92ba3aa134e93d5da603a" + }, + { + "bytes": 395, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/tool_axis_p.symbolic.png", + "role": "icon_asset", + "sha256": "70e31381d0e1674e292068823e570a488d98e9a3792fdef75bead4e2de82b3d8" + }, + { + "bytes": 343, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/tool_axis_x.symbolic.png", + "role": "icon_asset", + "sha256": "306a1ecea39fa6cb2bc49ceef4a480546eae11e49885d98307ba297d21e8969b" + }, + { + "bytes": 314, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/tool_axis_y.symbolic.png", + "role": "icon_asset", + "sha256": "6c9676243c5d44b39910cb5e089f9219f2f379e51a12920abbf23fcb8d03c885" + }, + { + "bytes": 326, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/tool_axis_y_inv.symbolic.png", + "role": "icon_asset", + "sha256": "b0fee141fae378631510d64780a50992f339add2417cce7c0082183e1c045a6e" + }, + { + "bytes": 319, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/tool_axis_z.symbolic.png", + "role": "icon_asset", + "sha256": "2ccb231c9a73522b114082c23ca0ad7983078b69f1dbc4912891f54e825eb10d" + }, + { + "bytes": 380, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/toolpath.symbolic.png", + "role": "icon_asset", + "sha256": "2026eb3c6a6c97980e89b90bfb74421fba89fe4f868053b89752bf11449a6223" + }, + { + "bytes": 318, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/touch_a.symbolic.png", + "role": "icon_asset", + "sha256": "96f39db763466e72cff18693bd5582e8787a0b68df8c5a98dc71c6a9be3d72cb" + }, + { + "bytes": 321, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/touch_b.symbolic.png", + "role": "icon_asset", + "sha256": "c6da7ed5283199b01a4edca3653f9930cbd32ce5134a218ff2f3684020fb5c31" + }, + { + "bytes": 324, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/touch_c.symbolic.png", + "role": "icon_asset", + "sha256": "70e1f4414e5358a82c8200c29307b397d1a954a1a47e59f769c1074f1b4e9107" + }, + { + "bytes": 275, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/touch_off.symbolic.png", + "role": "icon_asset", + "sha256": "dc28b3e20c00c155da6deeb80e75668c7e602068ed04dc5de77d223fffabe4d5" + }, + { + "bytes": 304, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/touch_u.symbolic.png", + "role": "icon_asset", + "sha256": "2dc7f6866578fc48d2352c212e6a1c78f65f8f66b5ba385597c7016658bddae9" + }, + { + "bytes": 331, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/touch_v.symbolic.png", + "role": "icon_asset", + "sha256": "06ea47eb16826471491d06ed8e43de95bfaebf858be7b44f5f954014ee16ca03" + }, + { + "bytes": 329, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/touch_w.symbolic.png", + "role": "icon_asset", + "sha256": "d5b14d6f9886c7e05d4efb2c965715b05dbeabc35378ef56a55ce1fa424a3b36" + }, + { + "bytes": 324, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/touch_x.symbolic.png", + "role": "icon_asset", + "sha256": "05985696d389f08c20c69e3e4d60f99ee40bc7d36b6795a327136e92aa108233" + }, + { + "bytes": 307, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/touch_y.symbolic.png", + "role": "icon_asset", + "sha256": "fa750a8e0eec5c6e566f2522999751f664fa880bde401df8fc0571f8501af904" + }, + { + "bytes": 320, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/touch_z.symbolic.png", + "role": "icon_asset", + "sha256": "617b07d512bedd0a5c9f45c11164bb4e0d9b06a4df12cdf8b0a58e8ac0d2350a" + }, + { + "bytes": 351, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/translate_a.symbolic.png", + "role": "icon_asset", + "sha256": "9e588e1169c1534b8a58bfeb282b409826c0135e4c0df13c043c204778c7b7eb" + }, + { + "bytes": 359, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/translate_b.symbolic.png", + "role": "icon_asset", + "sha256": "0e0ef86c04c0c94c2e0d7073c6fca842e8bd00234b6088d87a05d0c80fbb3a7e" + }, + { + "bytes": 359, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/translate_c.symbolic.png", + "role": "icon_asset", + "sha256": "b84ed7c8c1273751207129c00663d219e6d8dd1a8234f1f96985239f82653c77" + }, + { + "bytes": 350, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/translate_u.symbolic.png", + "role": "icon_asset", + "sha256": "9b10dde465dd97c262095ec897efe687c57b61955496dfaad80a6f4a426b2cb2" + }, + { + "bytes": 351, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/translate_v.symbolic.png", + "role": "icon_asset", + "sha256": "03cee1aef0cfa5c1413cca5835a8c5a9473a915060807abde68b4616960a7206" + }, + { + "bytes": 386, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/translate_w.symbolic.png", + "role": "icon_asset", + "sha256": "cd60be88e20c6707108d460808b7d0fbf76ade2af80914e94be097d36d85b4b7" + }, + { + "bytes": 364, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/translate_x.symbolic.png", + "role": "icon_asset", + "sha256": "31b3616e2490b5073f9d164f20bfbd2f735be93c51ddcd48d1e3d02ad5adba10" + }, + { + "bytes": 352, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/translate_y.symbolic.png", + "role": "icon_asset", + "sha256": "f85120f204d93fef3dde824784421bc68750fb83c47996e23b43b9b74245c133" + }, + { + "bytes": 372, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/translate_z.symbolic.png", + "role": "icon_asset", + "sha256": "17759e3e6c861961951a2d0fd6d71e36543f5f356da702fd977cdaa34dd21252" + }, + { + "bytes": 295, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/unref_all.symbolic.png", + "role": "icon_asset", + "sha256": "e7d78072f581f8cf6c4fefcd6eccfa9095286c326fdd76b15d55d08b8e803314" + }, + { + "bytes": 268, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/user_defined_folder.symbolic.png", + "role": "icon_asset", + "sha256": "26bdbcdadce954c5d266aa44855518bf60ed3a56364b06575dff3df8ca15b804" + }, + { + "bytes": 183, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/window_close.symbolic.png", + "role": "icon_asset", + "sha256": "49c2946b6a7ed0d149bb4faaa74758b4055eb9055648a287bad0e0fe84b22202" + }, + { + "bytes": 334, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/zoom_in.symbolic.png", + "role": "icon_asset", + "sha256": "a1cf7e2cde3929a13a55e27c5d6c590227f156d0d4744adf02be3ebd76cbd113" + }, + { + "bytes": 300, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/zoom_out.symbolic.png", + "role": "icon_asset", + "sha256": "b02299639536cdd0266cc1b211d5c07e810900edbe686e27a596a9d0ccc2d36d" + }, + { + "bytes": 356, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/status/dialog_information.symbolic.png", + "role": "icon_asset", + "sha256": "9156fa8b6f666bde96e3918dbb7e2721689316dc398dfba1b4f472e9029a18c8" + }, + { + "bytes": 311, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/status/dialog_warning.symbolic.png", + "role": "icon_asset", + "sha256": "17dfd7b73207ce6ff5a918f34bf52de9721ea4bf34a4120b83de470229f4302e" + }, + { + "bytes": 365, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/back_to_app.symbolic.png", + "role": "icon_asset", + "sha256": "87938b3170d226f80a796ac50282e092818a0b7a2101f618e57617b52e955750" + }, + { + "bytes": 192, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/chevron_left.symbolic.png", + "role": "icon_asset", + "sha256": "b64381aae4a88668919db45c5f7fb85da7fb8c03579239fca1175335c113b934" + }, + { + "bytes": 181, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/chevron_right.symbolic.png", + "role": "icon_asset", + "sha256": "9b250c8be9e0e95530c9b08df98f84792eb1910200e9c413d7ab9fe6eebf2c70" + }, + { + "bytes": 222, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/chevron_up.symbolic.png", + "role": "icon_asset", + "sha256": "854b16dd350a6bf78d19bea331c6ca2368610eac287d7708eac4cd90be94fd60" + }, + { + "bytes": 368, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/clear.symbolic.png", + "role": "icon_asset", + "sha256": "1297fb829467e8be042cbb9706713751a13e5bb82f74bebcca03a2b595ae3692" + }, + { + "bytes": 577, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/coolant_flood_active.symbolic.png", + "role": "icon_asset", + "sha256": "4b6ac488ef5cff8da213164e29a1f3666b955fec18b64677993d64c0d6c2325d" + }, + { + "bytes": 535, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/coolant_flood_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "491693544d5b9142210237122139cc4a3bb7fa93b26c4a58ee9b807a350651d2" + }, + { + "bytes": 628, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/coolant_mist_active.symbolic.png", + "role": "icon_asset", + "sha256": "a7be033bd52fed2363d59b3fecce88fbf33baf69c27f670e8fb087829e96ab22" + }, + { + "bytes": 569, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/coolant_mist_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "08693d2e8110b33ef6aa24df1438aa260e35c099ba3b3bac96afe8702948a35b" + }, + { + "bytes": 353, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/dimensions.symbolic.png", + "role": "icon_asset", + "sha256": "23c54696ad3491d0ab819193b01f083604ae81c2a7035a28da3c62fdd1f46671" + }, + { + "bytes": 314, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/edit_code.symbolic.png", + "role": "icon_asset", + "sha256": "11fe2133e3f99ce42e44e3cacf3d0f974dad64489999da3d49a872c6756539cd" + }, + { + "bytes": 223, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/fullscreen_close.symbolic.png", + "role": "icon_asset", + "sha256": "38525e3a45462e4a6f00412529c06e6f2bf7fcee87e29c85a4c1ba9520a36369" + }, + { + "bytes": 188, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/fullscreen_open.symbolic.png", + "role": "icon_asset", + "sha256": "e02479e78eb1350a8982ca1ef6210ec9217303fecbe8767829c279400209be29" + }, + { + "bytes": 295, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/home_folder.symbolic.png", + "role": "icon_asset", + "sha256": "090c77638f1fbb04b2bb24695f7ac66668460c79907cc2be2bf6d44dc5c90127" + }, + { + "bytes": 355, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/hsk_mill_tool.symbolic.png", + "role": "icon_asset", + "sha256": "e2bba3953fd7c38e739e76b746ebac897cba4abbbc14c35f4423dcc06f0bdbd5" + }, + { + "bytes": 517, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/jog_speed_fast.symbolic.png", + "role": "icon_asset", + "sha256": "0e9c5a0a63c9f3f489cd7d87993d2cae35d03ac7bc1753eba4145afd22c0ac7a" + }, + { + "bytes": 391, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/jog_speed_slow.symbolic.png", + "role": "icon_asset", + "sha256": "3e7c3f0da2ff62b0565e6db8ad966bd121c94bfc33e7efeb8f9536ca681ee7ab" + }, + { + "bytes": 360, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/keyboard.symbolic.png", + "role": "icon_asset", + "sha256": "a169b7a43404bba5d0f62ed7d7f4c91d743ce330321a7f505506d32c01102a1e" + }, + { + "bytes": 404, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/keyboard_hide.symbolic.png", + "role": "icon_asset", + "sha256": "e50cfce2da5ca503c66309ae94a16412034e790d8e5bb6fb1425b1d826870a68" + }, + { + "bytes": 408, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/logout.symbolic.png", + "role": "icon_asset", + "sha256": "121d71b3d268559ced46a62040c8ef3fc5c737fe183ab36cccc78987853f0be7" + }, + { + "bytes": 699, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/main_switch_off.symbolic.png", + "role": "icon_asset", + "sha256": "7838f7520e512a58fd003dd215031d753c0c155cf3830fb1d3d68ea405a10f7d" + }, + { + "bytes": 624, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/main_switch_on.symbolic.png", + "role": "icon_asset", + "sha256": "5132d479aebbf997803f27cbced7a06a1fd27397917f8b0241f9019c0f8246ff" + }, + { + "bytes": 546, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mill_tool_change.symbolic.png", + "role": "icon_asset", + "sha256": "971c91e3115074a47520c15b2420895d66d36cd29cf074ec3788acaaa48a4fe3" + }, + { + "bytes": 606, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mill_tool_change_num.symbolic.png", + "role": "icon_asset", + "sha256": "68cea012ba113c12bdab90b90e051dc561bfd1ba0cde30b8f29ee50d222f6727" + }, + { + "bytes": 636, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mill_tool_set_num.symbolic.png", + "role": "icon_asset", + "sha256": "5d80fb22ed03c4586a858cec2177d23c5ef9476cff27ec2218d7b71b309cd851" + }, + { + "bytes": 356, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mode_auto_active.symbolic.png", + "role": "icon_asset", + "sha256": "8fb272c70308406ebcce454cd3f462de0348355f75746a6c8756df695d0c4331" + }, + { + "bytes": 345, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mode_auto_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "8f2c4c698dd5ac3c8b8f8840b10633ddcbb930ab0d1c08305b43fc2b98df3583" + }, + { + "bytes": 384, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mode_manual_active.symbolic.png", + "role": "icon_asset", + "sha256": "6d3c7cfdbda643adcf75196a4557221455a168ada757f1efb5a30b79be9407d0" + }, + { + "bytes": 372, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mode_manual_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "115ead4650357ab3577718305ef36910387525fc8651f8e46e57001e1423d39d" + }, + { + "bytes": 390, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mode_mdi_active.symbolic.png", + "role": "icon_asset", + "sha256": "2bf008d05f621be00e732c1ccb3ed456d4217325372e8af00620a060cdd7e2df" + }, + { + "bytes": 379, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mode_mdi_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "3ac1d15a8abb803bc29110612823341bf4f3faf8a53f2abdd55e96721532a4f2" + }, + { + "bytes": 518, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mode_settings_active.symbolic.png", + "role": "icon_asset", + "sha256": "89ad5dd968bd82a2301a3b7a8e09bdca036fef7ece1d3145c3bdb70f5480350f" + }, + { + "bytes": 501, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mode_settings_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "d2b449f1124dcba9014fdf0f565a8964d22c9ca8c5e78f5a8167702615915db3" + }, + { + "bytes": 356, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mode_user_tabs_active.symbolic.png", + "role": "icon_asset", + "sha256": "be3012a7cb6aa4e75f2c87e320f93efc89a6aa9036d0f7faa325a9d33961d166" + }, + { + "bytes": 351, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mode_user_tabs_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "c03e40d5fef4e82e76e26fcbfae1d3e67a3c46dca359901f433b671bcd2678e4" + }, + { + "bytes": 340, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/new_document.symbolic.png", + "role": "icon_asset", + "sha256": "5dd575eada69d9d1739c1889530bdab4fc019c7d85f86790ec67c815aee6a4a8" + }, + { + "bytes": 331, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/open_file.symbolic.png", + "role": "icon_asset", + "sha256": "6dba5e366c08349eeb733ba6b727ae1f611cb8bf9f8f71cef0700fa5d0b0d190" + }, + { + "bytes": 163, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/pause.symbolic.png", + "role": "icon_asset", + "sha256": "b8dc7e2a2097bd412340073d2b6551f87594c3e47e00507fb0ee031367e3eda0" + }, + { + "bytes": 167, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/pause_active.symbolic.png", + "role": "icon_asset", + "sha256": "277568e9d4c3f62b4c18218a9991e22acdfe1e97db64d6f32da0b88700b09429" + }, + { + "bytes": 205, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/play.symbolic.png", + "role": "icon_asset", + "sha256": "9ffbb2bf0897337ca7622d37bce2f18c421303200807926eded9e977d91c891a" + }, + { + "bytes": 482, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/power_off.symbolic.png", + "role": "icon_asset", + "sha256": "67d910be35c63aa64a5979c06ff4fc029ef49e2d87f6400e1cc7ff158da14322" + }, + { + "bytes": 482, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/power_on.symbolic.png", + "role": "icon_asset", + "sha256": "2801a7e13df4db51580a9d12d9d38f4c36f22be87a7b55557470655298921b7a" + }, + { + "bytes": 457, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_0.symbolic.png", + "role": "icon_asset", + "sha256": "13cd503b7f495a6d7a6cb471d6f4d8913dbf2e774848fbdac10f9b73ddec866a" + }, + { + "bytes": 410, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_1.symbolic.png", + "role": "icon_asset", + "sha256": "8ece6a8a286831a639c1e34112f58b09681603bdf8683b8a41ad61cb6d94c261" + }, + { + "bytes": 442, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_2.symbolic.png", + "role": "icon_asset", + "sha256": "8aad1750a6e52d5f5ef98c6d628ad2619c39ace5549bba4dc7326d0241188d38" + }, + { + "bytes": 448, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_3.symbolic.png", + "role": "icon_asset", + "sha256": "b8df559a2b216f531c218d3a539fcc83e75f230975c46842a7533ec987eee652" + }, + { + "bytes": 422, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_4.symbolic.png", + "role": "icon_asset", + "sha256": "745435557a9149e2b02bc9bab4ab8fdfaed8bfd9aa861a5d7ed15358b0f205d0" + }, + { + "bytes": 434, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_5.symbolic.png", + "role": "icon_asset", + "sha256": "52023f31332d3ab09254a072eaade4b669004bd32de4edab5dc16c7d15bc0579" + }, + { + "bytes": 450, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_6.symbolic.png", + "role": "icon_asset", + "sha256": "52524b441d378b99c0b50463a6f5ee1e049336f5409514d03081f661a30a1837" + }, + { + "bytes": 409, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_7.symbolic.png", + "role": "icon_asset", + "sha256": "6e1b6fd7cd9fc8f530a902091b0b67c90e67aa3d9ebedc3a20318717ccca3d67" + }, + { + "bytes": 445, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_a.symbolic.png", + "role": "icon_asset", + "sha256": "b1f7ab379ffda864da51a7b2234e6289497921e6b483f2da996850a016a865f3" + }, + { + "bytes": 396, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_all.symbolic.png", + "role": "icon_asset", + "sha256": "87555e4e8fd0f9849c5b961ec9792da2004971f1eb252e50ab323fc4ef93984f" + }, + { + "bytes": 457, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_b.symbolic.png", + "role": "icon_asset", + "sha256": "b27b3dd07da5c1dc29fde621e8c364f5b53b3f2fcb3ccca78a9a6d15723e2e3f" + }, + { + "bytes": 454, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_c.symbolic.png", + "role": "icon_asset", + "sha256": "47e5234de885cf87702cec943fb7cb4527fbd28f5cdaff440835ef8a394f4420" + }, + { + "bytes": 437, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_u.symbolic.png", + "role": "icon_asset", + "sha256": "27bf11a341ebb05c58fc3be64ba307fb0942aec160f39b0278717850ec5e8de0" + }, + { + "bytes": 438, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_v.symbolic.png", + "role": "icon_asset", + "sha256": "db97f4a9d3875d221ed0a217127e709185a3f9bd11fe7b749697dd4ab593b876" + }, + { + "bytes": 480, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_w.symbolic.png", + "role": "icon_asset", + "sha256": "5454e64fc8f6cd0636afad230c8adf6e4fedac5c746859a46061baebbfb2ff4c" + }, + { + "bytes": 449, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_x.symbolic.png", + "role": "icon_asset", + "sha256": "c4cfdf6fab3e69b14b059acf873a1c4214553c32e7bf379c8f797f8055035eb4" + }, + { + "bytes": 430, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_y.symbolic.png", + "role": "icon_asset", + "sha256": "727aeba8dad2ca5d7bdc5505bb2354caacfc05375985b587c752ac62e329d041" + }, + { + "bytes": 426, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_z.symbolic.png", + "role": "icon_asset", + "sha256": "30b07e6052f0682a966b5767a462d9ffbda2e3513d379177d4c0cb2ef9596c27" + }, + { + "bytes": 507, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/refresh.symbolic.png", + "role": "icon_asset", + "sha256": "d4b93980cba6d06e2979aea681cd29afdc0537a7fc64efcee7a056261e46bf85" + }, + { + "bytes": 287, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/run_from_line.symbolic.png", + "role": "icon_asset", + "sha256": "3472a39aa6c258dd38ad0ff8ddf4ebc32135bf2e233c2a8128639be019a2303f" + }, + { + "bytes": 348, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/save.symbolic.png", + "role": "icon_asset", + "sha256": "08115819a24f6a87e1cb9f3e678fc6a62a1b8e270da7e7f7670c31306caa804d" + }, + { + "bytes": 403, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/save_as.symbolic.png", + "role": "icon_asset", + "sha256": "42e59741c442355910d3b32baf02ac2e9488edb509e4b7c4e172af06c7bfc3cc" + }, + { + "bytes": 367, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/select_file.symbolic.png", + "role": "icon_asset", + "sha256": "e07f4081c33aca7e2c5280fd8df36d4333da2b0a2f939230b6591470206a9e45" + }, + { + "bytes": 388, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/skip_optional_active.symbolic.png", + "role": "icon_asset", + "sha256": "ac6cf66f5fe3c9c56885d2e218451842746378a7563678bd19f6964a74ad42d8" + }, + { + "bytes": 567, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/skip_optional_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "8b01ea7940cf4f6c36d569ff4ee9b088d9e25214130b70de349f13b651c6bed1" + }, + { + "bytes": 458, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/spindle_left.symbolic.png", + "role": "icon_asset", + "sha256": "2e3764a33383085237ec2aac451b86351f2f29f24b1c5b7250870957b68cf1cd" + }, + { + "bytes": 470, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/spindle_left_on.symbolic.png", + "role": "icon_asset", + "sha256": "8e4f99a9300d951c800f8820ff6a784be6d01eb83e25a062a237d9f3573de250" + }, + { + "bytes": 452, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/spindle_right.symbolic.png", + "role": "icon_asset", + "sha256": "d06e1cde79e6b76e0857a6f7762585487942b8102c1a7740f4f6b153607dd3bd" + }, + { + "bytes": 467, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/spindle_right_on.symbolic.png", + "role": "icon_asset", + "sha256": "2e624d9a658fd3fca3b2ad6c1f48194b7a09e5ad288fb368aa9576f130a3c082" + }, + { + "bytes": 487, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/spindle_stop.symbolic.png", + "role": "icon_asset", + "sha256": "d4b8196dc948bca942c9f049b618312bd978fe4277eb7b4b366e06acc4fd5b5e" + }, + { + "bytes": 393, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/spindle_stop_on.symbolic.png", + "role": "icon_asset", + "sha256": "601552a65d47c9fb73b490753a08ae81c00c482354f0ad26bb618b41f27c5262" + }, + { + "bytes": 330, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/step.symbolic.png", + "role": "icon_asset", + "sha256": "bbb0bc88444515f8033b0beedd6e0c1d86ca48b3d5a8d3e315dcf61808a3cb8d" + }, + { + "bytes": 114, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/stop.symbolic.png", + "role": "icon_asset", + "sha256": "ed325f6f5bf495980e50c060b71c42c5c0c248c697bf02d875bd78fcbf3a3412" + }, + { + "bytes": 570, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/tool_axis_p.symbolic.png", + "role": "icon_asset", + "sha256": "3980433ed869f0eb082e34b77fa6ddde92e7bee428f2188405aef43e5debfd6c" + }, + { + "bytes": 515, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/tool_axis_x.symbolic.png", + "role": "icon_asset", + "sha256": "8c6304413eba2a21829e2023391d445a5e6f7faad27e626451501b2a33ee86f6" + }, + { + "bytes": 462, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/tool_axis_y.symbolic.png", + "role": "icon_asset", + "sha256": "91514d3951237b17156e7ab604567661247e3c433c7b250d54e71a2feeb7488a" + }, + { + "bytes": 450, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/tool_axis_y_inv.symbolic.png", + "role": "icon_asset", + "sha256": "1e17384d98888ddef0a00587e2623b8ff93a286857af226d0d918a72eed627b9" + }, + { + "bytes": 455, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/tool_axis_z.symbolic.png", + "role": "icon_asset", + "sha256": "c38e1d67fc0b98f715a0694d485bb876c28f3c6bf39eecff80e7baa37e478c3f" + }, + { + "bytes": 544, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/toolpath.symbolic.png", + "role": "icon_asset", + "sha256": "5300e6df087757a7ebe68ea6ef4185a954aeb109a4c25376307fc0802f62a348" + }, + { + "bytes": 479, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/touch_a.symbolic.png", + "role": "icon_asset", + "sha256": "8aaaf61195a7e5489919abf5ef2ad60df7dc76d19d35bc4a15f4b007550a31a1" + }, + { + "bytes": 494, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/touch_b.symbolic.png", + "role": "icon_asset", + "sha256": "8caee29efcb0ced8eee642825aeda4e889baac97d02ac55d2b72bc76fbd7aee9" + }, + { + "bytes": 474, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/touch_c.symbolic.png", + "role": "icon_asset", + "sha256": "ea8ef9b76649ba720c8c733b169adfc10242696c39f4d67ca677810a6bf6fee9" + }, + { + "bytes": 384, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/touch_off.symbolic.png", + "role": "icon_asset", + "sha256": "e878ec1e6bfa69cb9f38b9fc2baee3de5ada4c706b14e866b06831973c9ca7e1" + }, + { + "bytes": 453, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/touch_u.symbolic.png", + "role": "icon_asset", + "sha256": "c4e9f21445998051cdd68bf7aed136c9ab304c867070c61f3013b64ea4cf3347" + }, + { + "bytes": 476, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/touch_v.symbolic.png", + "role": "icon_asset", + "sha256": "dafc155e149c9ab7873e5da1aae9d312e5ef401c8ccdcbe3a0c8090d8ed9e54c" + }, + { + "bytes": 501, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/touch_w.symbolic.png", + "role": "icon_asset", + "sha256": "3d33d1c55b4a6c53a0538abf8acb29e302dc5785d4f2e2e278f473517c65319f" + }, + { + "bytes": 479, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/touch_x.symbolic.png", + "role": "icon_asset", + "sha256": "17418a4adc0b6d8badbfa4eeedc4df346bab4fa4bd09c5841e58ce85c4a8e173" + }, + { + "bytes": 466, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/touch_y.symbolic.png", + "role": "icon_asset", + "sha256": "ff3f998a33c259318c2a99a2451b9f4b92f69c34ddf17fbcf588edb5ef9c48da" + }, + { + "bytes": 473, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/touch_z.symbolic.png", + "role": "icon_asset", + "sha256": "50ab0a52b86f16f97c5e898bc502b9b8b07f7300e9aea53ec9050eed02faf72c" + }, + { + "bytes": 514, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/translate_a.symbolic.png", + "role": "icon_asset", + "sha256": "e957822e7ddd93a2121cf00b73095afd9403c1589e0795cec55ae5800ccbd501" + }, + { + "bytes": 531, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/translate_b.symbolic.png", + "role": "icon_asset", + "sha256": "9cf1b290df195b4af4cdb276b947946bf6be92fa70388561e4a08c0440e4e6df" + }, + { + "bytes": 508, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/translate_c.symbolic.png", + "role": "icon_asset", + "sha256": "86dab5af685639e020fbaf85a6161add1f83eca8b4b0ffb6eee8f4f025386c7d" + }, + { + "bytes": 493, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/translate_u.symbolic.png", + "role": "icon_asset", + "sha256": "c58621c37f2fbfa9cec18e01f657faa822945cd0da127c33480259c0da73d6c2" + }, + { + "bytes": 514, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/translate_v.symbolic.png", + "role": "icon_asset", + "sha256": "d2e97175b1355a7a0aacba10e4d45bfc1469a09dc743a486f3789085acbd949f" + }, + { + "bytes": 549, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/translate_w.symbolic.png", + "role": "icon_asset", + "sha256": "ddf010f797dafa7642e0449fda8c8646943a06448a5d44690ae167953cdb2c78" + }, + { + "bytes": 502, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/translate_x.symbolic.png", + "role": "icon_asset", + "sha256": "00381834b3e68d2ed4d01addbafb9c2296bb252f6e5a8a354f2ea6555e441935" + }, + { + "bytes": 502, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/translate_y.symbolic.png", + "role": "icon_asset", + "sha256": "1c3630fce6cefb372ac9d26d1ace4533eec95498cd2ff689fb455fc368269ab7" + }, + { + "bytes": 506, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/translate_z.symbolic.png", + "role": "icon_asset", + "sha256": "da57f500e6a38c89cfe940d989dedf04414d3495a0a3c581555aa3a5d4f29c3f" + }, + { + "bytes": 420, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/unref_all.symbolic.png", + "role": "icon_asset", + "sha256": "2c02652a55d3be2a19e11695c234724bd4e9708db39e25c6a0cb684c5c1309ef" + }, + { + "bytes": 339, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/user_defined_folder.symbolic.png", + "role": "icon_asset", + "sha256": "4b786454383859cf8ddf0e49a85351e24182997ed13518d2ed3036471e3dca25" + }, + { + "bytes": 251, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/window_close.png", + "role": "icon_asset", + "sha256": "2111d1c1b5f3307edd677b3d0e0be41b0a7f9afa9ffd54a64883df149c016069" + }, + { + "bytes": 227, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/window_close.symbolic.png", + "role": "icon_asset", + "sha256": "c7bee3cba2d8bc35dd10980ca435e9df6bd0cf0c331b5aa796d316bf18190af0" + }, + { + "bytes": 478, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/zoom_in.symbolic.png", + "role": "icon_asset", + "sha256": "c728de85037bb1df7c4aa61dd8bb723dc9de07991f092b8a140c1a4b4cb13d88" + }, + { + "bytes": 454, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/zoom_out.symbolic.png", + "role": "icon_asset", + "sha256": "af23ae176950a9b08ae964b3d72cebf3b36b7f78b2030c5b76553898f3a68bcd" + }, + { + "bytes": 545, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/status/dialog_information.symbolic.png", + "role": "icon_asset", + "sha256": "60dec4e733498acf038833c893f36b28d8a805fee0af3590f7776508647f8dd7" + }, + { + "bytes": 454, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/status/dialog_warning.symbolic.png", + "role": "icon_asset", + "sha256": "160b39f5b529567385ef10b4630bf2650e1d2f0b5aa0307b04ae18f6d81403b4" + }, + { + "bytes": 469, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/back_to_app.symbolic.png", + "role": "icon_asset", + "sha256": "6126fee33f63021f24446ed376615b02906480839b3949859a246624c943faba" + }, + { + "bytes": 216, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/chevron_left.symbolic.png", + "role": "icon_asset", + "sha256": "aa1366165576268b70f2d9f4ce4edfa7f2b3011be1579ecfa6f70746dd28b3cc" + }, + { + "bytes": 207, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/chevron_right.symbolic.png", + "role": "icon_asset", + "sha256": "85e75c9065fb624956513ab5a48dd30579f4294c26504c59571865abd6f77557" + }, + { + "bytes": 264, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/chevron_up.symbolic.png", + "role": "icon_asset", + "sha256": "82d54a25d720dcb797337b53788c30bb881882fbe7841095027ac74e0db0e31d" + }, + { + "bytes": 471, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/clear.symbolic.png", + "role": "icon_asset", + "sha256": "2d40b086fd722caaca357f6e9ea027095110a4917094d712c0c58c06970299ba" + }, + { + "bytes": 754, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/coolant_flood_active.symbolic.png", + "role": "icon_asset", + "sha256": "ca0215eec67138612882c9b297683768511f3ad9be8216711bc6c83f59a50c3b" + }, + { + "bytes": 715, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/coolant_flood_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "83676ae0c36fbee958041f8827caf0c81f4d490946b2201f00ee157ba1491612" + }, + { + "bytes": 856, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/coolant_mist_active.symbolic.png", + "role": "icon_asset", + "sha256": "ed850e391f47dc9b4337c91582158ba3af45ae6511091214d29484f8dca27c6e" + }, + { + "bytes": 789, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/coolant_mist_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "af088585244c7a3e8a4fc134adc90d3144d437eee830c87b1d955b3ebce8078c" + }, + { + "bytes": 446, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/dimensions.symbolic.png", + "role": "icon_asset", + "sha256": "f9b3b46f4512e6b1f372576f66e07c61a10364e0e485487664c5ad764846ea26" + }, + { + "bytes": 352, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/edit_code.symbolic.png", + "role": "icon_asset", + "sha256": "90603b9c82561f228009e30c731117b9aa6daaccbc19fbb0a38a1910fde12e58" + }, + { + "bytes": 270, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/fullscreen_close.symbolic.png", + "role": "icon_asset", + "sha256": "dcfbf2ecda96b913c6438f7200112d9d234ca6d657f6a2d3521a751478ee0414" + }, + { + "bytes": 237, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/fullscreen_open.symbolic.png", + "role": "icon_asset", + "sha256": "991a3d0de52963a9289445a1f90b6241a5a55a5cfd35027196249a82d6ecf318" + }, + { + "bytes": 344, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/home_folder.symbolic.png", + "role": "icon_asset", + "sha256": "269e64f67f668d6d090e8fab5331d010217ca0c22151a503437533525c1d780c" + }, + { + "bytes": 438, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/hsk_mill_tool.symbolic.png", + "role": "icon_asset", + "sha256": "ac7d55bb04fe311408ef2b6d858b6d8cf616571cc92a011a41437d0ba4803f50" + }, + { + "bytes": 727, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/jog_speed_fast.symbolic.png", + "role": "icon_asset", + "sha256": "9e73be0ed0b37835f676536076901de4871058a4f64a42a4ca4d2021f73b2c26" + }, + { + "bytes": 516, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/jog_speed_slow.symbolic.png", + "role": "icon_asset", + "sha256": "bfda1eefc8bd68f37d9256ceea1670b2e061eda4d219a2224512dcc725fd1b0e" + }, + { + "bytes": 450, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/keyboard.symbolic.png", + "role": "icon_asset", + "sha256": "9211f60a296b3444286d5afd5551b99e97a3b05d5674a2e57d8c339232b5df06" + }, + { + "bytes": 485, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/keyboard_hide.symbolic.png", + "role": "icon_asset", + "sha256": "7926b073594e68d0dc99ea6b83068905b20e4fc9e875725f0da26763f4f54cb6" + }, + { + "bytes": 494, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/logout.symbolic.png", + "role": "icon_asset", + "sha256": "419771f598d6cf384e667a29348d1d4acee0083b3bafa280523485b65b8d26ae" + }, + { + "bytes": 869, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/main_switch_off.symbolic.png", + "role": "icon_asset", + "sha256": "728f4a1dfabb40f3f1455ecc3fae132653cf6c7e4f8a93eded8e4ffd6f96c18b" + }, + { + "bytes": 812, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/main_switch_on.symbolic.png", + "role": "icon_asset", + "sha256": "5f4dc5c7bc4c371852a2251749ea36aca7ea77902b63ee03b911c1d550e0ce45" + }, + { + "bytes": 706, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mill_tool_change.symbolic.png", + "role": "icon_asset", + "sha256": "a8d2d8094cb309b8973b143b1667b04649c5398e912f7b05971faa51c0bc80cf" + }, + { + "bytes": 843, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mill_tool_change_num.symbolic.png", + "role": "icon_asset", + "sha256": "b99bd5c25eaa82475317b4a07ad94449f3360ea4c8e35552ea9832ad3807482c" + }, + { + "bytes": 892, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mill_tool_set_num.symbolic.png", + "role": "icon_asset", + "sha256": "2ac037bfc2283e611d5f0e4ec17549a65f27c6bf5eb3295124e18ad9689490e1" + }, + { + "bytes": 392, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mode_auto_active.symbolic.png", + "role": "icon_asset", + "sha256": "147511eb7ae9ea6e8d9047041f43eb790b0f2fd470916a3f368ed3d7bea7d287" + }, + { + "bytes": 385, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mode_auto_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "0319a8f4229719633f0154c369cac67ae555c3afcfac552f157cb1b4b1e1b3dc" + }, + { + "bytes": 443, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mode_manual_active.symbolic.png", + "role": "icon_asset", + "sha256": "32ce3feba2bf95ce52aa594b6520e7581234f84a12d779151c35b9b4c7f1d684" + }, + { + "bytes": 437, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mode_manual_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "e490c5a04fbdaf8259f4b7856d2ce5ca2f6d31d3815af3640b984e485f773d31" + }, + { + "bytes": 535, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mode_mdi_active.symbolic.png", + "role": "icon_asset", + "sha256": "d1d4a8aa96af299e92f24c5fa39bbd7270967c516fa76b408bffa34efa17b8e8" + }, + { + "bytes": 524, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mode_mdi_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "b46f59b166e15b84ace940ce83647d7f70c51038cc0fbff64a55dd566bf17c8e" + }, + { + "bytes": 625, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mode_settings_active.symbolic.png", + "role": "icon_asset", + "sha256": "05b4c404de7830b25bdb8dcae88d8ed5d5d3f07066589f797bc5f861849ecae0" + }, + { + "bytes": 612, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mode_settings_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "4dd48a0b538f5898fe96faec80247c4b283adbe3401aad1df7b82eb8631d7e21" + }, + { + "bytes": 446, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mode_user_tabs_active.symbolic.png", + "role": "icon_asset", + "sha256": "45c7d70ca8d4f17534067f017847f4a682361c0fb07c8bda8885de3a1935dc23" + }, + { + "bytes": 438, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mode_user_tabs_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "1f66ebd7672b67ceea096e48015f30db644ceb65eedb27ba75e024de996cb969" + }, + { + "bytes": 428, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/new_document.symbolic.png", + "role": "icon_asset", + "sha256": "e0b464cfd6e61c2edd88d381a1e72fc4f2f5ebec73e21b85de38a545df75298f" + }, + { + "bytes": 382, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/open_file.symbolic.png", + "role": "icon_asset", + "sha256": "d7ab0914459c6316bce2b895437e0a1d9bafd93ae983982c4f9389a988e58876" + }, + { + "bytes": 169, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/pause.symbolic.png", + "role": "icon_asset", + "sha256": "aa4232d56d4b3cda4f7df8b643e280b2f746c1e280d3f2cfb778df09aa335614" + }, + { + "bytes": 175, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/pause_active.symbolic.png", + "role": "icon_asset", + "sha256": "fbb08995281a7387ec31f92ec89c9bfba5fbfe396300934dd82dde4a7edfb85a" + }, + { + "bytes": 240, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/play.symbolic.png", + "role": "icon_asset", + "sha256": "85324fa311afb2e0a0d7ff2748f9614a5562770c580a417e60919ec6f719fa7e" + }, + { + "bytes": 642, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/power_off.symbolic.png", + "role": "icon_asset", + "sha256": "8f7e510d5e72e81f8e912bdc8d253707a5529c33321d13435b3adf4b1cf7ffc9" + }, + { + "bytes": 641, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/power_on.symbolic.png", + "role": "icon_asset", + "sha256": "d525657be92ba3b791c49b25e8ada44f7c42f562394741d87236341d2edc60ea" + }, + { + "bytes": 603, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_0.symbolic.png", + "role": "icon_asset", + "sha256": "cecef7d027debe4c8269d7858f5f2b88467a16055253fb7e98b607924bc4228e" + }, + { + "bytes": 504, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_1.symbolic.png", + "role": "icon_asset", + "sha256": "b089c152fd46d387ee4f3559df430b1c59e9b630770900456de0a112217c218c" + }, + { + "bytes": 573, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_2.symbolic.png", + "role": "icon_asset", + "sha256": "faddfc415c811b7150385bcdee5010538a1d61abf9b24140e27c6d59db39cbe6" + }, + { + "bytes": 588, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_3.symbolic.png", + "role": "icon_asset", + "sha256": "80d581a9951733b18c687fd92dd2d6fc632f77932ed46173bef814a007978bcf" + }, + { + "bytes": 551, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_4.symbolic.png", + "role": "icon_asset", + "sha256": "8a1ea1d0a5ca30fdfd9e4ba7fb958b68d6c11b1836b8917c34ec209df7c8d976" + }, + { + "bytes": 602, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_5.symbolic.png", + "role": "icon_asset", + "sha256": "0a28750a445e645b2575a84f78f3403c316c7b2548d3d8334e86aea5227ed6d7" + }, + { + "bytes": 610, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_6.symbolic.png", + "role": "icon_asset", + "sha256": "12a9e33713b08e594a43812575370f9af1a1a1181f9cde4d256f9b9c2c571089" + }, + { + "bytes": 551, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_7.symbolic.png", + "role": "icon_asset", + "sha256": "02f6c59915839b72984a8f43bff2434fd8c6a73de967084e85cf1515620abe50" + }, + { + "bytes": 588, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_a.symbolic.png", + "role": "icon_asset", + "sha256": "5040711af5177a9ddb8f7feaefc7c957528380d88d78887ef22458997d2938d1" + }, + { + "bytes": 544, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_all.symbolic.png", + "role": "icon_asset", + "sha256": "0666d7486ad954fcf8d041641747137e2768049c19558fe4627e8b46de2ac525" + }, + { + "bytes": 615, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_b.symbolic.png", + "role": "icon_asset", + "sha256": "26499e04104cd8885c31ff96d35ec60eec04dd3e1daa0b21bac943c9add91279" + }, + { + "bytes": 616, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_c.symbolic.png", + "role": "icon_asset", + "sha256": "d646b0bc1b96cef56c785a7a6401cbe08f8e8d791d31edec8661225c093890c2" + }, + { + "bytes": 570, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_u.symbolic.png", + "role": "icon_asset", + "sha256": "0458f8539617c71ccc7becf62d1d037804a7ee457250d09cfaf23a172e5cf16d" + }, + { + "bytes": 595, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_v.symbolic.png", + "role": "icon_asset", + "sha256": "ad3f44dc787fd823e923da4a212cc1efb53a0ea3cc269bd119942b36902409ed" + }, + { + "bytes": 661, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_w.symbolic.png", + "role": "icon_asset", + "sha256": "61110408cb17d5c9059946edeee0d1c4e8a403bb385416fa3c4412e8148dfd84" + }, + { + "bytes": 610, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_x.symbolic.png", + "role": "icon_asset", + "sha256": "4597c5a4cd002b158f95559776ee8e029891eb2cff855ec8febabdad86906f3e" + }, + { + "bytes": 557, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_y.symbolic.png", + "role": "icon_asset", + "sha256": "d8703a47b30919b724f1d2b83b53377eb990c03b98fb2c43ed76ba9ac9172f9b" + }, + { + "bytes": 572, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_z.symbolic.png", + "role": "icon_asset", + "sha256": "b5af27915653d08992db12ddd387ce25b17898d95b1bbab908938146394c0bc7" + }, + { + "bytes": 664, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/refresh.symbolic.png", + "role": "icon_asset", + "sha256": "fad093b0b45292b55985f899a1e15306bf00875568eab510ddd9c80b5a379b06" + }, + { + "bytes": 340, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/run_from_line.symbolic.png", + "role": "icon_asset", + "sha256": "089f2470ceaf0cbfbdc2a02dc5e83b53214efd49eea02b8f778316b28ff25383" + }, + { + "bytes": 436, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/save.symbolic.png", + "role": "icon_asset", + "sha256": "7421f2b27325bd7c9514d797d5b75542e81aec81d0ad0b368358b40302125284" + }, + { + "bytes": 526, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/save_as.symbolic.png", + "role": "icon_asset", + "sha256": "20338d8c6d138ed9c89382210f0475ad7d13549089afcda53ad5e35b84f8f9aa" + }, + { + "bytes": 495, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/select_file.symbolic.png", + "role": "icon_asset", + "sha256": "6a587ea3c264b16789369419c810f0d05ff083a7a7eb39c740a401141ea1b79b" + }, + { + "bytes": 506, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/skip_optional_active.symbolic.png", + "role": "icon_asset", + "sha256": "d1ae8fa61e87cda52695c63dee838cd34378bba149a593211d6d43892ea62f3b" + }, + { + "bytes": 765, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/skip_optional_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "9807e86eacda2255c79007059cd91919ee7add0e48c6f47dd8c41594b457da3c" + }, + { + "bytes": 604, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/spindle_left.symbolic.png", + "role": "icon_asset", + "sha256": "22b3489764c8e1675b836470fd48567c41a41bd1cf009b6846432756d042c849" + }, + { + "bytes": 633, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/spindle_left_on.symbolic.png", + "role": "icon_asset", + "sha256": "66637495b0bdcca7453bdd85981e113da1440fd178fd8fda4c8f80999f6e5b4c" + }, + { + "bytes": 609, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/spindle_right.symbolic.png", + "role": "icon_asset", + "sha256": "1e4e0c196cd9946210950ec73f0787cde9078346f71c0581b6e0aa08649e99ae" + }, + { + "bytes": 640, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/spindle_right_on.symbolic.png", + "role": "icon_asset", + "sha256": "d1e2a0a0278510081eec421e71419b12692c30457e110a8baf4c5bf13fed992c" + }, + { + "bytes": 657, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/spindle_stop.symbolic.png", + "role": "icon_asset", + "sha256": "adae6f11b0579a5057fdc836571e515daa864d54d9d16d3c953987553ce6ff35" + }, + { + "bytes": 544, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/spindle_stop_on.symbolic.png", + "role": "icon_asset", + "sha256": "569d1dd2df862165c467852f8f61421d53376a717ae99d21fc2df4d249fe2413" + }, + { + "bytes": 421, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/step.symbolic.png", + "role": "icon_asset", + "sha256": "e237bcb46101006d6eede92cf57ed6b09721041a446f4e65348daf2dd8416e6c" + }, + { + "bytes": 121, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/stop.symbolic.png", + "role": "icon_asset", + "sha256": "6b3c13e9f8a1db4ff325b9e0e33b8bdb29e0cb046b19079fd9c9b710a3347d16" + }, + { + "bytes": 706, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/tool_axis_p.symbolic.png", + "role": "icon_asset", + "sha256": "3b2317a43668fbdc6fec55f23b7b500dd580f24c8b890dad78f255bef43d900b" + }, + { + "bytes": 592, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/tool_axis_x.symbolic.png", + "role": "icon_asset", + "sha256": "464377c6cc8aa028a863220cae46a5d83dc65b70b8bab1c4f38c5a5b3ec3ade0" + }, + { + "bytes": 516, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/tool_axis_y.symbolic.png", + "role": "icon_asset", + "sha256": "b95e0fe39fd13a5205067b78cf0eb0d9fbdbc3ddbd2d306912a72a9cfbfc5847" + }, + { + "bytes": 511, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/tool_axis_y_inv.symbolic.png", + "role": "icon_asset", + "sha256": "2231a411ccf984df04e12160ae00538d61e841457d2025da7e7ec7594ed334c0" + }, + { + "bytes": 534, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/tool_axis_z.symbolic.png", + "role": "icon_asset", + "sha256": "2b9fbb4ff3153caf3ea9fc2bbcd5b10d50f1125a3e0d5ec90a4103e5e271058f" + }, + { + "bytes": 728, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/toolpath.symbolic.png", + "role": "icon_asset", + "sha256": "f7c80907aefc4a54b154f6d8517228cfcfb60d858fc76d7af0167f0be5fb0ca0" + }, + { + "bytes": 636, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/touch_a.symbolic.png", + "role": "icon_asset", + "sha256": "0a690a003fa37d4ec9086eed1c7762ced7da72749229ff88a91c2c22fcfcb076" + }, + { + "bytes": 633, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/touch_b.symbolic.png", + "role": "icon_asset", + "sha256": "265d94475dce06a53ef6393bdf26689b94a9f6d68dfbf9551a6703fac6e49e24" + }, + { + "bytes": 636, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/touch_c.symbolic.png", + "role": "icon_asset", + "sha256": "444e3a8f9e2d2e0a5731dace36376424f8a326f8eab0754fa193a773fd5c6e8e" + }, + { + "bytes": 523, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/touch_off.symbolic.png", + "role": "icon_asset", + "sha256": "5c3babfad3bb18845cc56a825c746802ac1c09990c2e24e3cfa45a633eba95b5" + }, + { + "bytes": 577, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/touch_u.symbolic.png", + "role": "icon_asset", + "sha256": "1aaaee6a0c59e6dd17edb6f11c9fb2ce93148805238f3eacb54df7cf9890c0cf" + }, + { + "bytes": 633, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/touch_v.symbolic.png", + "role": "icon_asset", + "sha256": "fa1692e55fbfe462699202862004704ca1c647dc0b18159cc6911380e81aca38" + }, + { + "bytes": 692, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/touch_w.symbolic.png", + "role": "icon_asset", + "sha256": "5610ff1973ca282dd3b709832e55dd68fc4ac0715e18c570d91478d1b16d9af2" + }, + { + "bytes": 638, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/touch_x.symbolic.png", + "role": "icon_asset", + "sha256": "5dbc38b0ad851ddc221690aae6862bb98e59c1bd50e3ca729ba6752482012ba1" + }, + { + "bytes": 608, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/touch_y.symbolic.png", + "role": "icon_asset", + "sha256": "641956245a3a4891c54130fa181eeca506fc16b33fc476bfb0dacd450e406237" + }, + { + "bytes": 602, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/touch_z.symbolic.png", + "role": "icon_asset", + "sha256": "f10091d0ac22015c0efe3e33e04ae1aed6ad26d34f5d2fa36cd199beb51301fb" + }, + { + "bytes": 711, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/translate_a.symbolic.png", + "role": "icon_asset", + "sha256": "3c0f69be21cd42a8eaceac4457ad9edfe480f1592ff7f5d87db2dfa3eafefd29" + }, + { + "bytes": 734, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/translate_b.symbolic.png", + "role": "icon_asset", + "sha256": "4dedfcc2272c2b38795a3852924429ea8e921f8fbae38c6447d22d928ae09120" + }, + { + "bytes": 708, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/translate_c.symbolic.png", + "role": "icon_asset", + "sha256": "23b599a4ce95076d84823c6905d62e830310c45d8b0e2dbe05d21653618522db" + }, + { + "bytes": 661, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/translate_u.symbolic.png", + "role": "icon_asset", + "sha256": "eabf1a1f989ff395b73745d13bbe38cd539cc6947356360e2c0c5745d2cb1087" + }, + { + "bytes": 719, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/translate_v.symbolic.png", + "role": "icon_asset", + "sha256": "0d18e8918bf5849c8acef710efaeee82d5fc8b5de034143de4308a039955ede1" + }, + { + "bytes": 794, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/translate_w.symbolic.png", + "role": "icon_asset", + "sha256": "cf323a434e693af262699bb2419b1d81bcff77498aab48fffd369a7265cc52f0" + }, + { + "bytes": 729, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/translate_x.symbolic.png", + "role": "icon_asset", + "sha256": "04a237f6624ba9809ce1f66cdedae3b2e9e84fabbb97e09d78b29c6527c762dd" + }, + { + "bytes": 691, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/translate_y.symbolic.png", + "role": "icon_asset", + "sha256": "22d05370671809db85a154cbb50374b6be26aff7c889bd9082e2f40b8097502b" + }, + { + "bytes": 680, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/translate_z.symbolic.png", + "role": "icon_asset", + "sha256": "93538c97415545329453963456aa935fc3ed60e6d0d44d5eebed20ad74604d74" + }, + { + "bytes": 531, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/unref_all.symbolic.png", + "role": "icon_asset", + "sha256": "9224e22ce287b8d764ef3544a4892512318b3753e5e9562021b23c118d652146" + }, + { + "bytes": 431, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/user_defined_folder.symbolic.png", + "role": "icon_asset", + "sha256": "d5e1954a0ace4cf3a4e72f99b7ab8340f2af2af7a32d86e01a4c2be348eee757" + }, + { + "bytes": 337, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/window_close.symbolic.png", + "role": "icon_asset", + "sha256": "88c6d01e50c3324b131a12500807e30c23129c2db6b93e79104149a16bf5331e" + }, + { + "bytes": 628, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/zoom_in.symbolic.png", + "role": "icon_asset", + "sha256": "fd6cd2e9ccc1468454aeebafdb91257fa103eccae714fd661d49b67df8abacff" + }, + { + "bytes": 605, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/zoom_out.symbolic.png", + "role": "icon_asset", + "sha256": "cc00e40322162113f5ce63bc3ce6607cf7a3ddb70b2d4d9149950c98f5908e4e" + }, + { + "bytes": 773, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/status/dialog_information.symbolic.png", + "role": "icon_asset", + "sha256": "a0a1cc407db6f1db6ffdbce9021dae449865523d542f1b75e4cc268803c796d2" + }, + { + "bytes": 580, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/status/dialog_warning.symbolic.png", + "role": "icon_asset", + "sha256": "f866a571f24f39576a96c1c56875cfcadfc92671de855a4a0b4b2716e5594b57" + }, + { + "bytes": 615, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/back_to_app.symbolic.png", + "role": "icon_asset", + "sha256": "ed9ba8dd628c6a49c0986d93a55f24d8acc769504a9061c2875215668f20d06a" + }, + { + "bytes": 296, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/chevron_left.symbolic.png", + "role": "icon_asset", + "sha256": "dfcfd8afeceda2b7eafc54972aa1e29207cfdc1e86fb1682b4c24d5c6816c41c" + }, + { + "bytes": 288, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/chevron_right.symbolic.png", + "role": "icon_asset", + "sha256": "5f12044fb45fd7b16f591b332edb9140f03e33a9b142791953368c8ad0fe1c56" + }, + { + "bytes": 346, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/chevron_up.symbolic.png", + "role": "icon_asset", + "sha256": "0df8538f7a3411ea7a24de2b1ae278817483148addf35418d0009d8212943ad0" + }, + { + "bytes": 613, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/clear.symbolic.png", + "role": "icon_asset", + "sha256": "c6ca9eac1b4212d133596a15c9cfd0dc5f9cda40b932f255af487180d9127f1d" + }, + { + "bytes": 1195, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/coolant_flood_active.symbolic.png", + "role": "icon_asset", + "sha256": "0bbee40ae755cc0d48afd1019e59985d04c5f1b11814c2a908b75ccde6d5d95a" + }, + { + "bytes": 1156, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/coolant_flood_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "3e2bb16088548a74776d16a9495ab675314111d0d540971cde57ad76ceb76600" + }, + { + "bytes": 1374, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/coolant_mist_active.symbolic.png", + "role": "icon_asset", + "sha256": "7f1c6909af3eb64766949d98d1bec445a702984162e2bc195b97f5515f7b3cfc" + }, + { + "bytes": 1312, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/coolant_mist_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "7b2ee893d235719fb9da80f7ca629a15e1307acdbe8b510609b1b40affa995d1" + }, + { + "bytes": 696, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/dimensions.symbolic.png", + "role": "icon_asset", + "sha256": "74781ebd1b391de8c3082d89eabf9ef282d6dc23457b60435e145e8945aa1d1b" + }, + { + "bytes": 451, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/edit_code.symbolic.png", + "role": "icon_asset", + "sha256": "edfec6433d47f11bae1c4b06c086349d77afcaa645cd5aaf4df94dc071807160" + }, + { + "bytes": 375, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/fullscreen_close.symbolic.png", + "role": "icon_asset", + "sha256": "c54eaba792b189576771afcf180cd7e9b05c5e9326e3a2c38cfe71b0d986d4da" + }, + { + "bytes": 296, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/fullscreen_open.symbolic.png", + "role": "icon_asset", + "sha256": "9af768d3f8827ed8c5e6a7df623762aa1023ac6cf53901e8d929123767edc620" + }, + { + "bytes": 434, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/home_folder.symbolic.png", + "role": "icon_asset", + "sha256": "4241f246f144ebce911cfde415661c851f8ae76fabffd2b903abeb93e76624f1" + }, + { + "bytes": 606, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/hsk_mill_tool.symbolic.png", + "role": "icon_asset", + "sha256": "99f1ab931700189cd89f17ae8738490d6c4fce9b4b96a1be665ed5530df7fbbd" + }, + { + "bytes": 1102, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/jog_speed_fast.symbolic.png", + "role": "icon_asset", + "sha256": "829605118fadb5e47d34240ba0b07966f79fe56337680aa8dbfc912cb62c3465" + }, + { + "bytes": 805, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/jog_speed_slow.symbolic.png", + "role": "icon_asset", + "sha256": "6ea44cb347c5a628b4bc76d4f3b94f0ca370507dacc666b4ab598fdae65a8f29" + }, + { + "bytes": 443, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/keyboard.symbolic.png", + "role": "icon_asset", + "sha256": "dee56da0164cd15635b3a9b735a74a06d904b10b118bd9310f14df001588673d" + }, + { + "bytes": 606, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/keyboard_hide.symbolic.png", + "role": "icon_asset", + "sha256": "6261b36d92afa24fe8b390a304f02bc0974dc8dfc8f47e97d770f28308c764e4" + }, + { + "bytes": 712, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/logout.symbolic.png", + "role": "icon_asset", + "sha256": "389f8fe506c038a0eb13edd1bac1087b28704c7aa365c7358517c668c29cc77a" + }, + { + "bytes": 1415, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/main_switch_off.symbolic.png", + "role": "icon_asset", + "sha256": "38e1fb2988b82974a88367612971c5a7b7e3c88d40bc9229e375f7523f606192" + }, + { + "bytes": 1304, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/main_switch_on.symbolic.png", + "role": "icon_asset", + "sha256": "47062a860d4994a9e67f5a6892da12a61b67ec53461daab1f002f8a5d106d9d7" + }, + { + "bytes": 1072, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mill_tool_change.symbolic.png", + "role": "icon_asset", + "sha256": "4bdc2643d7382a2107d7728123bee2e3ac5fa425f9db0cbfc8035716d799a43b" + }, + { + "bytes": 1288, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mill_tool_change_num.symbolic.png", + "role": "icon_asset", + "sha256": "9ac9edcba31c5c64110916d35c92e6212a50c0fe6de3b970cff141e14f2ef65b" + }, + { + "bytes": 1407, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mill_tool_set_num.symbolic.png", + "role": "icon_asset", + "sha256": "7f56e84592ffd3c6726e641dfb92e3b22e3d4bb59efcea4cefaaea11a1ef3af8" + }, + { + "bytes": 575, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mode_auto_active.symbolic.png", + "role": "icon_asset", + "sha256": "8c6fea3893118f68e149747d472ed34a29be592b2160f2b9c0210cf157eec2f0" + }, + { + "bytes": 558, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mode_auto_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "c8e277de43bc0c277091a5de2aaeb897a900b1986f9a7989a053548645b8da7a" + }, + { + "bytes": 596, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mode_manual_active.symbolic.png", + "role": "icon_asset", + "sha256": "564c49d9c25991f6e2947dd299989c615d7ca2bdcab03c53c36982045de1c96a" + }, + { + "bytes": 574, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mode_manual_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "cedd4c19fc00155dfb6ebd1b0cce1f3774a7f85b7fa2a08bc315976428e229b1" + }, + { + "bytes": 636, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mode_mdi_active.symbolic.png", + "role": "icon_asset", + "sha256": "84cb6f4971aba02ba392ac446671a0117472a7ff71c21ff638a2de2b9707163a" + }, + { + "bytes": 621, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mode_mdi_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "0992ff8d90c86fee2f701e52ae1c19a1fdaa822bdbe6e248c00b3a55a099ba91" + }, + { + "bytes": 908, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mode_settings_active.symbolic.png", + "role": "icon_asset", + "sha256": "b96a5bf2760a8edfe838e564ed86d74332c7182516dd8bdea9f7db6968624ea8" + }, + { + "bytes": 890, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mode_settings_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "86974aa8aea3d0e2e104c1105cd4e9d705e3be7b96faeab721c38b56ecab376c" + }, + { + "bytes": 630, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mode_user_tabs_active.symbolic.png", + "role": "icon_asset", + "sha256": "3d86e3cc3b869314962d02e6ce3ef0ef2df26e565e4ae8dc3215abbecbac7f21" + }, + { + "bytes": 616, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mode_user_tabs_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "9382a4a05e43eb78a2a4b86eb588e79c64601e315ce33c7addaa682cca3c283e" + }, + { + "bytes": 519, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/new_document.symbolic.png", + "role": "icon_asset", + "sha256": "7113d8af4b9db9350ab51b8604839d0a12c2848f9e6f34263c1bc8008118be31" + }, + { + "bytes": 518, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/open_file.symbolic.png", + "role": "icon_asset", + "sha256": "ac2811a908fcc05ab8eef9abfca67cb7af8b6026c1389ef1f073061d16455856" + }, + { + "bytes": 200, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/pause.symbolic.png", + "role": "icon_asset", + "sha256": "b27892cb1cb551bf488fdef6a147a077678df3506af81c6fb4e554b48d6730ec" + }, + { + "bytes": 201, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/pause_active.symbolic.png", + "role": "icon_asset", + "sha256": "28be80bb5774ddef4c5104bcfba5cb1440d887129b2fba77b544e23c86e00748" + }, + { + "bytes": 389, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/play.symbolic.png", + "role": "icon_asset", + "sha256": "25fe3f7e3203b61fe725f4279d364c83be791f3332406713a95fe4d15b690ba5" + }, + { + "bytes": 952, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/power_off.symbolic.png", + "role": "icon_asset", + "sha256": "c215ee8b9fa877a55bb6b82147dcbdb94d7f905ba70b6a2d8d0c82e23036a0e4" + }, + { + "bytes": 954, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/power_on.symbolic.png", + "role": "icon_asset", + "sha256": "cf7380616d092da31486ebb1d78d75f711cf17afc8830f87353f60f02f98b9a1" + }, + { + "bytes": 891, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_0.symbolic.png", + "role": "icon_asset", + "sha256": "fd97a8c13dee00fe1461095a001ce8c9000d904abf16baf4a25a64605e72d558" + }, + { + "bytes": 720, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_1.symbolic.png", + "role": "icon_asset", + "sha256": "7e40609ba344f5b82906c9700017f314265053fdcc97f2ec753597328fd71cf7" + }, + { + "bytes": 853, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_2.symbolic.png", + "role": "icon_asset", + "sha256": "b4e0019cb3022b3245abf14415ae37d0b6532a25504832dce0cb4ef284a0e54a" + }, + { + "bytes": 904, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_3.symbolic.png", + "role": "icon_asset", + "sha256": "a312bd0d51b7fd30a888cb3724f1c34770b70e63bee1453f272733edbcccf05f" + }, + { + "bytes": 837, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_4.symbolic.png", + "role": "icon_asset", + "sha256": "a8695958685c138cd2fae0759a5f5faf24c527880f4ebb1b06cc71778370e9f8" + }, + { + "bytes": 874, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_5.symbolic.png", + "role": "icon_asset", + "sha256": "2900afc0cfe5df34511e5bc503acd24bf3bc5b9ff275df5ebd37071aeadc56c4" + }, + { + "bytes": 895, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_6.symbolic.png", + "role": "icon_asset", + "sha256": "4231c94f75091285886c0e0af369f79162fbfebdac908b4fd42b1d83c8878e8f" + }, + { + "bytes": 816, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_7.symbolic.png", + "role": "icon_asset", + "sha256": "707ff94773c92ca7ee893f1cec37af2a12feade0f4a739a060ecf78e120183bf" + }, + { + "bytes": 911, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_a.symbolic.png", + "role": "icon_asset", + "sha256": "1229c27663da99ea26c4d6e3a00b7b7fa2037ca53f8f6a2318c7de474c71019f" + }, + { + "bytes": 756, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_all.symbolic.png", + "role": "icon_asset", + "sha256": "06656c8af55389885b102df5f9d4b00e36cc7b392d5d8a6e002ea2f8962afdbf" + }, + { + "bytes": 881, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_b.symbolic.png", + "role": "icon_asset", + "sha256": "469f701ec3acef6d8a8f6a8367a98c70d3a343133e516a61d2179bbdf538ea71" + }, + { + "bytes": 927, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_c.symbolic.png", + "role": "icon_asset", + "sha256": "c126a479a6537417c8ebd560009f2bee1210e2637e23932e87001c5ff8399591" + }, + { + "bytes": 841, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_u.symbolic.png", + "role": "icon_asset", + "sha256": "3ece748899d2fb230acb62c39dbaf735d918b6a0d70f1d198e7d849e376da655" + }, + { + "bytes": 901, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_v.symbolic.png", + "role": "icon_asset", + "sha256": "08b5da9aef907eea541e16e7c8da191b06c25dd8a5e37a9de5afc6aacd0b5457" + }, + { + "bytes": 1011, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_w.symbolic.png", + "role": "icon_asset", + "sha256": "facc8dd86d9cc5bd3f2cdb26b17f835e3e27c86306ae143f11e73de12faf6049" + }, + { + "bytes": 911, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_x.symbolic.png", + "role": "icon_asset", + "sha256": "731f7a01d3a0a8c3cf7efcf760fab90428f3586bbc23b27ef0a91a2adcd6efcb" + }, + { + "bytes": 833, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_y.symbolic.png", + "role": "icon_asset", + "sha256": "ae222b5f1a2dd473c8e1f9a724b05f7d21f5cc38535e46f06f75eb52d48b893e" + }, + { + "bytes": 847, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_z.symbolic.png", + "role": "icon_asset", + "sha256": "2bfbc696e2e206db0fb71b00252ec69154ea759ac1821e081b9f8bdb4e2c8125" + }, + { + "bytes": 954, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/refresh.symbolic.png", + "role": "icon_asset", + "sha256": "45ec563b991aa5c4df120aa2b8aa286edd61845c7555278b87e01ca1091c5fdc" + }, + { + "bytes": 399, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/run_from_line.symbolic.png", + "role": "icon_asset", + "sha256": "c9f208afab3de9b674fb37cd95a9327edcacd70e92d50989aa40c627cb3c4a58" + }, + { + "bytes": 602, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/save.symbolic.png", + "role": "icon_asset", + "sha256": "e7886fa23bfef97f61db40b3940c5acdc468277d7c494748b2268cc700bd0894" + }, + { + "bytes": 738, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/save_as.symbolic.png", + "role": "icon_asset", + "sha256": "605f66ff95aa4419eeed75943955c3a6e50b1fc89d493b5535e086913be16f9b" + }, + { + "bytes": 654, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/select_file.symbolic.png", + "role": "icon_asset", + "sha256": "e09769d715b618fc6911c335c1e960fef1e8562b62e7a675bbbc0ed932181b36" + }, + { + "bytes": 702, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/skip_optional_active.symbolic.png", + "role": "icon_asset", + "sha256": "ff8688ad899ca20ff10b67f64495b0f3bb10a15d69b20fe3ee4027cd6f0f5970" + }, + { + "bytes": 1076, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/skip_optional_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "b2dbede34c412ed16065f9b57dbaf6b978749ca5c6e431b32cc282ac6880d99a" + }, + { + "bytes": 872, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/spindle_left.symbolic.png", + "role": "icon_asset", + "sha256": "06e249a263dca4db88a35bb54840ea4b13ea1bab35e61e5477bdfaf5725599e0" + }, + { + "bytes": 904, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/spindle_left_on.symbolic.png", + "role": "icon_asset", + "sha256": "9f1bfc67bbeb3ed3e0d633815aa50e2bad10c2a40853b09390d1d8e56c14f82d" + }, + { + "bytes": 876, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/spindle_right.symbolic.png", + "role": "icon_asset", + "sha256": "b748cbe3aec056fa744d89ba653ef7872bd68497b7ae418f02269113c808e431" + }, + { + "bytes": 911, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/spindle_right_on.symbolic.png", + "role": "icon_asset", + "sha256": "c1835da738e59ea4db7f28dde2db818572aab725c2c3fc50792292be94314f88" + }, + { + "bytes": 1013, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/spindle_stop.symbolic.png", + "role": "icon_asset", + "sha256": "e1506774fbf24eecbdd6eb4e950cd9be7bdd5cc046e43a7a5d721b1d14073384" + }, + { + "bytes": 767, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/spindle_stop_on.symbolic.png", + "role": "icon_asset", + "sha256": "425eb290f03fa1883729e4da039fbb30fd13d6ec513437baafa63c3d4651ae50" + }, + { + "bytes": 548, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/step.symbolic.png", + "role": "icon_asset", + "sha256": "c6e08862693446ec95c6f9c2a68983f1135854611ee9537796057b57bd07de43" + }, + { + "bytes": 159, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/stop.symbolic.png", + "role": "icon_asset", + "sha256": "0ac2e08651cc85efd7ed541530720815cd50e6ed2f443a5d93bb896ff8b1da3f" + }, + { + "bytes": 1054, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/tool_axis_p.symbolic.png", + "role": "icon_asset", + "sha256": "819820c17b750abe9a37506c2b4792341c6222e99d170c08f13ca67289014684" + }, + { + "bytes": 959, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/tool_axis_x.symbolic.png", + "role": "icon_asset", + "sha256": "9f7e90d362d776aef194f424d4d77bc78dc6d42820009e497364679436bb7c67" + }, + { + "bytes": 793, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/tool_axis_y.symbolic.png", + "role": "icon_asset", + "sha256": "d618b7154d2c363ba65956dd1f6e431a47605d91ef1d1e48e5a34f91bd2e24be" + }, + { + "bytes": 787, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/tool_axis_y_inv.symbolic.png", + "role": "icon_asset", + "sha256": "39c579da4254558293a61f977eed4ad974b90db5ee91a362c267ab4b039495bc" + }, + { + "bytes": 781, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/tool_axis_z.symbolic.png", + "role": "icon_asset", + "sha256": "0aac2749daf5fffdd6a7f8c9b3edd2f67789a9aac1292ecc42ce6ff4e274afd4" + }, + { + "bytes": 1048, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/toolpath.symbolic.png", + "role": "icon_asset", + "sha256": "62508f7880f682140db0ffb3981221f6be39dcd7de24d95e9c8ed0d047e0fa8d" + }, + { + "bytes": 971, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/touch_a.symbolic.png", + "role": "icon_asset", + "sha256": "5f8537cf8020b883b24980a39996b4947a69fee2fb9180096059f73bdb9daf33" + }, + { + "bytes": 981, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/touch_b.symbolic.png", + "role": "icon_asset", + "sha256": "29301c6a586c5523d36da2ec32fc418db1eafcac2260dad90b2f25b4ca635f56" + }, + { + "bytes": 963, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/touch_c.symbolic.png", + "role": "icon_asset", + "sha256": "ae34c0afe2145ae2987c6b7db31d3e15b7c74f8499cfbf843177fb2e973f9b41" + }, + { + "bytes": 744, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/touch_off.symbolic.png", + "role": "icon_asset", + "sha256": "bd8c8c4dc5fc019d8833f359cd1fcd6a4a0551fe3465658804abd56edd834005" + }, + { + "bytes": 900, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/touch_u.symbolic.png", + "role": "icon_asset", + "sha256": "38e059e5eeb287636765994c713f06ad41be2e5e43fc24b19a0f9d0988830538" + }, + { + "bytes": 983, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/touch_v.symbolic.png", + "role": "icon_asset", + "sha256": "3d15d08699fc1b89b4f6e4635129a75aded86ece8cb90bdf9f1ebd3b1b45623e" + }, + { + "bytes": 1088, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/touch_w.symbolic.png", + "role": "icon_asset", + "sha256": "0746d0363350ec4071f350b8d708702e516a244d7d9f06e1416e7791ceb98499" + }, + { + "bytes": 990, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/touch_x.symbolic.png", + "role": "icon_asset", + "sha256": "d59660fb76521737e661eb0a6062fb45c4a753c18fb357bf645999c04976b522" + }, + { + "bytes": 936, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/touch_y.symbolic.png", + "role": "icon_asset", + "sha256": "88855d07440f4935d498ab1d68e3b846b5140a1f383fbe18200d059cfe90addc" + }, + { + "bytes": 919, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/touch_z.symbolic.png", + "role": "icon_asset", + "sha256": "d62483e508ee58c0486c3dd9d6a0835448d80e14e53df7dab21314e80affa1ab" + }, + { + "bytes": 1117, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/translate_a.symbolic.png", + "role": "icon_asset", + "sha256": "95dc9f75304515b9558aa1d9da1a2ae325ec2feac61751e0e640a8696ccdf5c9" + }, + { + "bytes": 1103, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/translate_b.symbolic.png", + "role": "icon_asset", + "sha256": "813b9469c5e94616fc23e56646b2b7a69687d4d350e4f1ce638f7a3ba472478d" + }, + { + "bytes": 1098, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/translate_c.symbolic.png", + "role": "icon_asset", + "sha256": "757df30d8c91bee145ece03402f9adc99d8f66bdbdcdad2b884bfd6d02370617" + }, + { + "bytes": 1032, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/translate_u.symbolic.png", + "role": "icon_asset", + "sha256": "cbb257c219b0bdd2ef79a9ffc53a5dfd1d54601bb04c6fec263c8010e4086b19" + }, + { + "bytes": 1123, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/translate_v.symbolic.png", + "role": "icon_asset", + "sha256": "6393687c4120278dfdb4dd456330f0fff0d3c9755b7dcc0c89db1a32c93e2b41" + }, + { + "bytes": 1224, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/translate_w.symbolic.png", + "role": "icon_asset", + "sha256": "64b88a678d80150adb37a4e759f928f87389cb12169c6ff93f4a9ae0e2c91c2d" + }, + { + "bytes": 1134, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/translate_x.symbolic.png", + "role": "icon_asset", + "sha256": "812899f3e9d30aa39c6887c0769d6958ea9930a43a769acb620b1a818b4fe063" + }, + { + "bytes": 1076, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/translate_y.symbolic.png", + "role": "icon_asset", + "sha256": "1f4a78456d30527373cf7208ccf55e8f55f46f8ceec63003e642c657a21f5537" + }, + { + "bytes": 1060, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/translate_z.symbolic.png", + "role": "icon_asset", + "sha256": "890f7e97357657b77a7ab2d094c143273099453323a2e4d9dc7d635793b32238" + }, + { + "bytes": 666, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/unref_all.symbolic.png", + "role": "icon_asset", + "sha256": "24c56d57ad2efd813394e3cb97bf647dbf4e9babfe99808b8067dd7aa09fda39" + }, + { + "bytes": 592, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/user_defined_folder.symbolic.png", + "role": "icon_asset", + "sha256": "8ba031fda26f5315a308c577da655070b394c799d697064aff0bbfcecdb7070b" + }, + { + "bytes": 454, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/window_close.symbolic.png", + "role": "icon_asset", + "sha256": "48ee4526df75509a0e17858510b747dc74730d1fd3e97fcaa0c200466e38f120" + }, + { + "bytes": 923, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/zoom_in.symbolic.png", + "role": "icon_asset", + "sha256": "18e743e219676c1951de5f15a420847681ceda7dfd04372cdfe05fd1fd3fa5dd" + }, + { + "bytes": 858, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/zoom_out.symbolic.png", + "role": "icon_asset", + "sha256": "d3e5cd7086e72ba2df39c10550a34b7139fbcd9bc7e329cecd744eec1181d01a" + }, + { + "bytes": 1219, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/status/dialog_information.symbolic.png", + "role": "icon_asset", + "sha256": "39825bd3a8269c4cda61af43cda45b57f7fb75087346309ca54687babbee4e33" + }, + { + "bytes": 903, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/status/dialog_warning.symbolic.png", + "role": "icon_asset", + "sha256": "6db72269ea3637258fe63b2c49b203c3b27d1528dc3ce4642453b8c2bd47ae6e" + }, + { + "bytes": 11357, + "path": "linuxcnc/share/gmoccapy/icons/material/LICENSE", + "role": "icon_asset", + "sha256": "58d1e17ffe5109a7ae296caafcadfdbe6a7d176f0bc4ab01e12a689b0499d8bd" + }, + { + "bytes": 366, + "path": "linuxcnc/share/gmoccapy/icons/material/NOTICE", + "role": "icon_asset", + "sha256": "1917e07ae29680da629688a7bbed3269cc81a2f8081176dfe16d08eb4a478c33" + }, + { + "bytes": 424, + "path": "linuxcnc/share/gmoccapy/icons/material/index.theme", + "role": "icon_asset", + "sha256": "d0f28ceb56fda19783be93f06eb08d24191009e6ea44ab2290e1b33e7546bc81" + }, + { + "bytes": 319, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/back_to_app.png", + "role": "icon_asset", + "sha256": "594059cbf00657d36ff7c3fc118762a5624a4da896da049604bd9a207e2b6b5b" + }, + { + "bytes": 269, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/chevron_left.png", + "role": "icon_asset", + "sha256": "dd1c972aa219ff3a5962cfa8bc54e4a634fcc5cd067bf804aa405a0170f2667d" + }, + { + "bytes": 264, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/chevron_right.png", + "role": "icon_asset", + "sha256": "5d877fd9202652cccc3dfba5b95a578ba6ec35a394e4df4a3398cd661389386a" + }, + { + "bytes": 272, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/chevron_up.png", + "role": "icon_asset", + "sha256": "dc5bd205a8a0c6861ce9422695c3d1e3a7c8c251b9a9e8e6d5d45c6fd15ec004" + }, + { + "bytes": 393, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/clear.png", + "role": "icon_asset", + "sha256": "a58f3209a18078b94c77c16f4fe4ef98900967ace8932754a288812b8b86f1db" + }, + { + "bytes": 498, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/coolant_flood_active.png", + "role": "icon_asset", + "sha256": "6e5e2e6f73d5607ef60e883aee8a052ecdd0841369080ac53fd9360de7300021" + }, + { + "bytes": 517, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/coolant_flood_inactive.png", + "role": "icon_asset", + "sha256": "4e4dd16119fcee3c01022e75e7c4f0c8c14b0939979f9dfa92acd4f893293367" + }, + { + "bytes": 564, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/coolant_mist_active.png", + "role": "icon_asset", + "sha256": "e1cf220a1ee76f08f8ab6153511cb795f88f655fa991631c5b2eb15f9ba5d0a1" + }, + { + "bytes": 587, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/coolant_mist_inactive.png", + "role": "icon_asset", + "sha256": "7a52d2efc6b6ab86a9118a382d48e12b0963ed321dcae1a9e5a8f68a5fda4938" + }, + { + "bytes": 324, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/dimensions.png", + "role": "icon_asset", + "sha256": "56ae1a501bcd6500ade4609f7db3b5b2caac3138784f6198fba5bf2c78619df9" + }, + { + "bytes": 355, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/edit_code.png", + "role": "icon_asset", + "sha256": "174109280707b826f82ad16f310bd4ddde60781aa94591779ad72f06816debb2" + }, + { + "bytes": 246, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/fullscreen_close.png", + "role": "icon_asset", + "sha256": "6c6134ccb4f6f2568cef0f9e6a76ed7500c740102b0d0544b9b7b8cc53c8c43f" + }, + { + "bytes": 171, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/fullscreen_open.png", + "role": "icon_asset", + "sha256": "f8d4498ebeb4d7f3c0eaf52169540d3b88a4797d2f55f2acababa65fd2c47927" + }, + { + "bytes": 327, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/home_folder.png", + "role": "icon_asset", + "sha256": "934fff6d939f652b94f7c20d49e445d507c66f6396c47878cd6c30bd1827857b" + }, + { + "bytes": 306, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/hsk_mill_tool.png", + "role": "icon_asset", + "sha256": "1cfea6c3d5a7090b61550f607fb1a8c2a3b14bc6a6984c3fb30436b2ccc50ba4" + }, + { + "bytes": 525, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/jog_speed_fast.png", + "role": "icon_asset", + "sha256": "ddf0be8ae661fdbc51caaf865e9ee9a19e046b69c080e0b88ce5c596b01ffb93" + }, + { + "bytes": 401, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/jog_speed_slow.png", + "role": "icon_asset", + "sha256": "e8d291f762562bdedade489ad6122c963ae48fc81ef401016c8cafcd44381ea9" + }, + { + "bytes": 336, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/keyboard.png", + "role": "icon_asset", + "sha256": "67ec80bb9de7dc58d10452cbed351da967af29a988313765747cec32648e61c2" + }, + { + "bytes": 424, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/keyboard_hide.png", + "role": "icon_asset", + "sha256": "cd1a1a92a8837ed0c395d73fa9ef73ebe9c55176c3c61e0d9ffc481ed0c9dce2" + }, + { + "bytes": 387, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/logout.png", + "role": "icon_asset", + "sha256": "247b552c390beb8d94f6b36bf4eccacd47d0f7c32af378e6405332dc9454f156" + }, + { + "bytes": 662, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/main_switch_off.png", + "role": "icon_asset", + "sha256": "f5b3f57f347793e65410d11a364dae838fcfbf19e5b5a2d76dbde21ee793f82e" + }, + { + "bytes": 597, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/main_switch_on.png", + "role": "icon_asset", + "sha256": "e75af0932bf39dad24d4d593dc5569e180624b707fbc5b267f96fc9b3e0c3e4a" + }, + { + "bytes": 517, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mill_tool_change.png", + "role": "icon_asset", + "sha256": "3d7be5921caa662b49a5861b98cdd57bd6227401b0a9b03bff54444540de7160" + }, + { + "bytes": 541, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mill_tool_change_num.png", + "role": "icon_asset", + "sha256": "c5e2afc1b879f99edb75a2bdf2c86bbab52295b17e32f29043467960723f58de" + }, + { + "bytes": 611, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mill_tool_set_num.png", + "role": "icon_asset", + "sha256": "18d3ae12cdd242d3a5a0304f27d2c0dc2c01f66eb873ad5ac1dd66e2e15f2bc8" + }, + { + "bytes": 302, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mode_auto_active.png", + "role": "icon_asset", + "sha256": "0e0560040d6f99253b47800499dfc6ac588519c2353b5b17f9b4cf26ef1d6eed" + }, + { + "bytes": 305, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mode_auto_inactive.png", + "role": "icon_asset", + "sha256": "ebef1b45e61a04346bdcc916eec51346bb3d2ec1c487d47d69d186c89d528edf" + }, + { + "bytes": 357, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mode_manual_active.png", + "role": "icon_asset", + "sha256": "59f2fe23ff27df68412b15152b813e7bd47b32992cc1231b65f9cd94abdee8bb" + }, + { + "bytes": 360, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mode_manual_inactive.png", + "role": "icon_asset", + "sha256": "f5f7771377842bec30b9c2558357ccc996d9f4698d16f97cd9627ea2839230ea" + }, + { + "bytes": 367, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mode_mdi_active.png", + "role": "icon_asset", + "sha256": "0eae4afff830f9e5898e6647f54da53b6c99e580d28913b172237ab771be9927" + }, + { + "bytes": 366, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mode_mdi_inactive.png", + "role": "icon_asset", + "sha256": "ca1275e649de655f59aa5ef1094fdde8f32b154234a39394ad028ab5eef48007" + }, + { + "bytes": 467, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mode_settings_active.png", + "role": "icon_asset", + "sha256": "15a61b363e2653eb2d5bf4413201d89190a54f917aae3f24418b090ec38d4ca5" + }, + { + "bytes": 461, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mode_settings_inactive.png", + "role": "icon_asset", + "sha256": "7af006c91289074d2beb86fe40489e751f0ed2287834ce3d4edccfb04b9737c3" + }, + { + "bytes": 353, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mode_user_tabs_active.png", + "role": "icon_asset", + "sha256": "b7fb246c30eab56b88815a64e277f2b53ed258fdad09449fe6fdb9857c240a49" + }, + { + "bytes": 351, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mode_user_tabs_inactive.png", + "role": "icon_asset", + "sha256": "b12e2d195fb934615f18569071c234933c2d903fb9f05d9d3bcb46475c59466b" + }, + { + "bytes": 378, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/new_document.png", + "role": "icon_asset", + "sha256": "612e367de255306430330e1031eefe2b29dea6d9ee25690a6d694cee61a78035" + }, + { + "bytes": 343, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/open_file.png", + "role": "icon_asset", + "sha256": "65ad503e41ad14909fa8329ef08f85b5763c666422d2564c082aa1371fa4e9d5" + }, + { + "bytes": 175, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/pause.png", + "role": "icon_asset", + "sha256": "a662f6e1c3e241bd209e34da6fba5bf389c24da5411be3e201bfd17cff3cdff0" + }, + { + "bytes": 174, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/pause_active.png", + "role": "icon_asset", + "sha256": "9be369e8e1d41b4131e64993d69bd1522e7e158c24e9fc7824d2a4733daee8e1" + }, + { + "bytes": 300, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/play.png", + "role": "icon_asset", + "sha256": "7e0065f748e0f8053294896092f913e23b896a45956f1ba45ff172fc9da730b6" + }, + { + "bytes": 476, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/power_off.png", + "role": "icon_asset", + "sha256": "3d622492903312a090221d3b8a75d3bb1d53c9871da0d217f5f8208d475d49d9" + }, + { + "bytes": 480, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/power_on.png", + "role": "icon_asset", + "sha256": "e9609ac3346fae11bf48d985f7124ad4a7c77fbc2ba40130aedcf7d82c45f179" + }, + { + "bytes": 499, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_0.png", + "role": "icon_asset", + "sha256": "9c75a4f4189240889f903f31879bea7a6184080224ac7f241ee0b764fb80bffe" + }, + { + "bytes": 417, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_1.png", + "role": "icon_asset", + "sha256": "48f8649bf2fc3acc50287ed63b315bff6d573431a8058f21f7966675eac565bc" + }, + { + "bytes": 480, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_2.png", + "role": "icon_asset", + "sha256": "fe79f66d1f42305052a1d7ca94a0a2c173f39b9efe6368f06258aa6c4631a21e" + }, + { + "bytes": 508, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_3.png", + "role": "icon_asset", + "sha256": "67180cf8e39b7bae9b6f8dec10f8b5583653b6b1ad4d46264de8418af2731bdc" + }, + { + "bytes": 479, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_4.png", + "role": "icon_asset", + "sha256": "444a8bb2d53c22f22ff2d0d4798a0f55482be4d65680f915ff49dc7e84fb6571" + }, + { + "bytes": 501, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_5.png", + "role": "icon_asset", + "sha256": "1a0c4ee41a4acab813f6c5a7efaee106d1b70d3473b566e17761d1c9df32251f" + }, + { + "bytes": 495, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_6.png", + "role": "icon_asset", + "sha256": "d1892f4e9d7a1395cfc9aa4b54558136da8d0c71876dfbf73953c2d0d9016663" + }, + { + "bytes": 471, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_7.png", + "role": "icon_asset", + "sha256": "9c2ca665122785e71adc086d0d0bce3131c8c4289ef769eec71fda12e3a48e6e" + }, + { + "bytes": 500, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_a.png", + "role": "icon_asset", + "sha256": "15ef480103725aac11c0b1bb521ed38c7bf9ca60053da480f2f1e471bd1afdbb" + }, + { + "bytes": 463, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_all.png", + "role": "icon_asset", + "sha256": "14da0dc18a75388547c0ec1ab020402b85d92cc9c07e2a9e9ad8b0ff6418bf50" + }, + { + "bytes": 504, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_b.png", + "role": "icon_asset", + "sha256": "22f7b4a575af40994580c607e84e5bf15b193d03671e9c351c8ca2efb78ed0db" + }, + { + "bytes": 516, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_c.png", + "role": "icon_asset", + "sha256": "8b037e6d31b22bdd7c39f55ed8d244f023176f55a13e35aa3dfeb90c2bd5adf0" + }, + { + "bytes": 481, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_u.png", + "role": "icon_asset", + "sha256": "fd8ce36bc88e6a32b7070bb826a828282d02693686b4f4e0a561477d73b738a1" + }, + { + "bytes": 491, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_v.png", + "role": "icon_asset", + "sha256": "2c9112c2719f33c1326eb800e32c69602d1da0b82fb5f9e039f10ad78a5596dd" + }, + { + "bytes": 519, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_w.png", + "role": "icon_asset", + "sha256": "f989fddb5d6426f6b763ea42661984694f28aba88add2da942b1b18ea68cf413" + }, + { + "bytes": 495, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_x.png", + "role": "icon_asset", + "sha256": "d9f24f4a9ddbb3ee825c97c9174cf161459e79b35ef4fac7fa87e9feed8a8131" + }, + { + "bytes": 462, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_y.png", + "role": "icon_asset", + "sha256": "642cb4d20a44d8445d46b0c017b7dac2d79396293fe3ce57de921c0771911b3b" + }, + { + "bytes": 482, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_z.png", + "role": "icon_asset", + "sha256": "67a373c39251e7aca1a17b9324039158da84540a1a2d613b39d3af24c38bcc08" + }, + { + "bytes": 484, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/refresh.png", + "role": "icon_asset", + "sha256": "6fb351f7cbc8925a15ca5a5ddf618391fbed054392639738eb144aa238e6445c" + }, + { + "bytes": 282, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/run_from_line.png", + "role": "icon_asset", + "sha256": "0ce0e312f4fabc0a79acf7b3b2a570cba2c68e48ba4e950cdbecfd1eb0553949" + }, + { + "bytes": 315, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/save.png", + "role": "icon_asset", + "sha256": "ed8831a16470e85d0e50f63b603d9f19928c1622b9867188619536714dbf6a60" + }, + { + "bytes": 472, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/save_as.png", + "role": "icon_asset", + "sha256": "36cd099c4ab79e29f0dc9e8e506d23f02bd9a6640e11e36f274bf0d32025693f" + }, + { + "bytes": 398, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/select_file.png", + "role": "icon_asset", + "sha256": "0c014ef3a5400bdd1bb1f752fc06753c28afaa8a2c6f223cfedd97a851266451" + }, + { + "bytes": 353, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/skip_optional_active.png", + "role": "icon_asset", + "sha256": "a8cbdbba7e6cf9705cf3a3ffadfb247f40caa60276eb687fa173aa6630e50b2a" + }, + { + "bytes": 564, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/skip_optional_inactive.png", + "role": "icon_asset", + "sha256": "4da59dab9f911c3525ff33712f10d09020f273961472a551695f6a1c20eec991" + }, + { + "bytes": 411, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/spindle_left.png", + "role": "icon_asset", + "sha256": "e775a5b38c6ef537bd7a4ab8810ccbd98fafa7b4956a2d84da322b07994fdaeb" + }, + { + "bytes": 430, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/spindle_left_on.png", + "role": "icon_asset", + "sha256": "b7619455d5941707dd57571b9e58fe7cd77b40f66aacff4828723fb8ac5dcdd1" + }, + { + "bytes": 411, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/spindle_right.png", + "role": "icon_asset", + "sha256": "e732aefc66e3bd449dc12cb98f993dbbf4588cbdb49f6d173edd48ad92f3adcb" + }, + { + "bytes": 428, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/spindle_right_on.png", + "role": "icon_asset", + "sha256": "099866c99d6c33adead44ae222cf413b0dc4e06840019367fc3a92306dfe216f" + }, + { + "bytes": 398, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/spindle_stop.png", + "role": "icon_asset", + "sha256": "fc5586b6be39602aa7c9e7bb37beae2906bd22c8563ff838a28e1651a1f3f06c" + }, + { + "bytes": 367, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/spindle_stop_on.png", + "role": "icon_asset", + "sha256": "04d2db2b43571a36699a3cdfc3e37f2334631ab53e45a75141e4da5d9376b4f1" + }, + { + "bytes": 320, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/step.png", + "role": "icon_asset", + "sha256": "5859f2dd53aecfb369fafec8bc4b275c77146e27048336d3c48bf6b42e947851" + }, + { + "bytes": 117, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/stop.png", + "role": "icon_asset", + "sha256": "8af42feff963d4a8b1b4bd1e3ab640ccd68efddcef93428d52e620c35226085a" + }, + { + "bytes": 591, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/tool_axis_p.png", + "role": "icon_asset", + "sha256": "6e1eb5aedc3bc455fd4ea099c1b7ab8bf5c947fa8c92f08683c87259fcf996db" + }, + { + "bytes": 505, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/tool_axis_x.png", + "role": "icon_asset", + "sha256": "d714d3ffd69c65f7d03ade45c53a816a2e070cab3b7030d713cabc3547851600" + }, + { + "bytes": 436, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/tool_axis_y.png", + "role": "icon_asset", + "sha256": "77fb289e1660fa259f231c38b59eb973dbc7a8b2b54c891d19072c1f06ddebab" + }, + { + "bytes": 442, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/tool_axis_y_inv.png", + "role": "icon_asset", + "sha256": "7c8c945a16f9f70fcb570087223a3bd19b74694924d9f9581620a51427ff18ad" + }, + { + "bytes": 450, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/tool_axis_z.png", + "role": "icon_asset", + "sha256": "5abcc00e553c867be388ec8153a77ecaa403a8fb91974575f06e7c14d88f5a7f" + }, + { + "bytes": 597, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/toolpath.png", + "role": "icon_asset", + "sha256": "7c362f571b1498268d7775c550e85bca5c39eef33208fe67b952501597c92dca" + }, + { + "bytes": 473, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/touch_a.png", + "role": "icon_asset", + "sha256": "f673e1c81da7d54c4e99f1e195f3f7215f5d3601d7c30cdd87d2ccecb1a16a46" + }, + { + "bytes": 469, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/touch_b.png", + "role": "icon_asset", + "sha256": "a8a0d96bcf251dfee9ed00588714f5bf25256be52430bfe41dc037e3d65357f2" + }, + { + "bytes": 485, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/touch_c.png", + "role": "icon_asset", + "sha256": "b3b2d42a9f916d8eee4e79ea2ff04466a7394f54beea228434e916ce05a2e400" + }, + { + "bytes": 382, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/touch_off.png", + "role": "icon_asset", + "sha256": "e410d4a0f7b9a1760a28d96fe9057160d74cf35cdf64478e22673c2bb97632ab" + }, + { + "bytes": 446, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/touch_u.png", + "role": "icon_asset", + "sha256": "f3d16156cd97eff348f7d0921425540b1605972c7b7752dbfc3c98da76ba9391" + }, + { + "bytes": 490, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/touch_v.png", + "role": "icon_asset", + "sha256": "df13af2ae9c378c8ae276b9a2d7ce1c67d0eddb8957833c285341a5608437e3d" + }, + { + "bytes": 506, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/touch_w.png", + "role": "icon_asset", + "sha256": "dc2d0bf84974d5f46969c7919f1f1de69256ea70251bbd7d80fe6dcb6298953c" + }, + { + "bytes": 497, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/touch_x.png", + "role": "icon_asset", + "sha256": "4910a70185d578accbe2da254fb1c0afd3dc13730b79a34fadf15b35c5874034" + }, + { + "bytes": 469, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/touch_y.png", + "role": "icon_asset", + "sha256": "9248f1230969570321289f2a3770ad7c05b1de7478845619948c5b7e5eba8fb0" + }, + { + "bytes": 483, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/touch_z.png", + "role": "icon_asset", + "sha256": "9d5cf0cbc65ed24ca62aca9c98fc7bb823af0e80b80a0780ef7a02aafd5c69be" + }, + { + "bytes": 560, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/translate_a.png", + "role": "icon_asset", + "sha256": "c0470db6e26d1af13e69b527fba22bc80335cfb90adf48fbba495688e730c824" + }, + { + "bytes": 553, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/translate_b.png", + "role": "icon_asset", + "sha256": "03a2abc49034aae9118d17694b9e5f8b9edd6a1d93249ea9e174d39b0e5b93b8" + }, + { + "bytes": 563, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/translate_c.png", + "role": "icon_asset", + "sha256": "0fd107e7775a79b5fd40c8aa414f3eb74b8d9e3514f4edec42e3dbf6106f3758" + }, + { + "bytes": 531, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/translate_u.png", + "role": "icon_asset", + "sha256": "00f9e782aad4101e8ccd61e5fb3eeb32eb742a17ab81aff192310d13499a8f45" + }, + { + "bytes": 563, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/translate_v.png", + "role": "icon_asset", + "sha256": "8eed134f8d0d60bbf653f90f7bcd1471f56ca766a2f891b1924b14c077f8cc51" + }, + { + "bytes": 571, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/translate_w.png", + "role": "icon_asset", + "sha256": "0b568be6e57517aa9eca8d7b2db33af3c8c47e528b96adf4ea09c3407e2fd14d" + }, + { + "bytes": 572, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/translate_x.png", + "role": "icon_asset", + "sha256": "43e3d5f1f02ffcf446f1bec482a90616a5e34e5efe8e9fddb5d98eb90fc2e61c" + }, + { + "bytes": 542, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/translate_y.png", + "role": "icon_asset", + "sha256": "524608f6fbab2f13335eae7fa1c201452c692229f06dd531566d8c0f8c3ee5a4" + }, + { + "bytes": 564, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/translate_z.png", + "role": "icon_asset", + "sha256": "21f5af9596dfc1d0adb3d52101d2b627ed5595d6103a0bbc14d168bebab1d18a" + }, + { + "bytes": 465, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/unref_all.png", + "role": "icon_asset", + "sha256": "96edb5b0dd096d1c9635b482b803ad72168fe23424b8a3213ef71fc1ead4e78d" + }, + { + "bytes": 337, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/user_defined_folder.png", + "role": "icon_asset", + "sha256": "bc791772f57c5e06cf0c9213f917bd6759eeaf05cc2775edb81b3934c3c0b53c" + }, + { + "bytes": 316, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/window_close.png", + "role": "icon_asset", + "sha256": "38e22c1ab458832b7f9b0ab694996a4596db4631559f474515362ceca683fb3d" + }, + { + "bytes": 536, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/zoom_in.png", + "role": "icon_asset", + "sha256": "8f3fff510ec94b78558482c8c73faf029440098301507266dcc9350b5044b75e" + }, + { + "bytes": 492, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/zoom_out.png", + "role": "icon_asset", + "sha256": "cb7e20f213500b375c10dc466ffcbbcdde4cd7e229b02faf2f52ff0aae81108e" + }, + { + "bytes": 482, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/status/dialog_information.png", + "role": "icon_asset", + "sha256": "540dac059d732118f33be137055fd3878518b337203e38d903912abfc025a8bf" + }, + { + "bytes": 425, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/status/dialog_warning.png", + "role": "icon_asset", + "sha256": "57023b19412919cbc1ab20ff817f4fab1f99e94fcd1e994d14bfbd2a522d1471" + }, + { + "bytes": 516, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/back_to_app.png", + "role": "icon_asset", + "sha256": "7126cf4c14a9eaa4f42c211e1d169b55041cd4876283611108e67992e4397fda" + }, + { + "bytes": 376, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/chevron_left.png", + "role": "icon_asset", + "sha256": "8b3e1dc224fa094d2520be5eca5b55fc718d15d8a32825cec3794724930a30f4" + }, + { + "bytes": 358, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/chevron_right.png", + "role": "icon_asset", + "sha256": "0d148c64719e906d81a12241ee7a0497d22d374f69aa8aa13ef1581fb26b98af" + }, + { + "bytes": 418, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/chevron_up.png", + "role": "icon_asset", + "sha256": "154d3c8b5aba20a9f3986dd33b43a2fb5db2f7fb65fe05b93bdc69206c0af422" + }, + { + "bytes": 545, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/clear.png", + "role": "icon_asset", + "sha256": "97fc86b11a8ce59647133879311f29710b200a2b51d10994f45ce8d90bb494f0" + }, + { + "bytes": 768, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/coolant_flood_active.png", + "role": "icon_asset", + "sha256": "b9b9f665bd07b8de1770ffd3bd0a22c6d42f6057d21ecacdecb0124f711f19b3" + }, + { + "bytes": 808, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/coolant_flood_inactive.png", + "role": "icon_asset", + "sha256": "a17344c2dca8bb8862a36cc6f5c6774679a85619b635958e4f5cfcc3117886ef" + }, + { + "bytes": 922, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/coolant_mist_active.png", + "role": "icon_asset", + "sha256": "fafdf6d602452fc85969b83347e2eb51a9595f27e9adf96aae4c85225d8a748e" + }, + { + "bytes": 935, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/coolant_mist_inactive.png", + "role": "icon_asset", + "sha256": "bf38a4e22e9e676cc149c3f566c0ee4f8a2d29f8ea825a20134d2f8f61cee6bf" + }, + { + "bytes": 493, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/dimensions.png", + "role": "icon_asset", + "sha256": "87a574642905a089ad8733179fdf04e3569bc506006c8b5ef8197046dc678b21" + }, + { + "bytes": 445, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/edit_code.png", + "role": "icon_asset", + "sha256": "fcb41aecd3df0c1b2a1495035622f55172be9c97641492fbe2068d97a60047fe" + }, + { + "bytes": 400, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/fullscreen_close.png", + "role": "icon_asset", + "sha256": "8208a7f37fa54ac118b9a0ae9917b9f4fc20633d65766e06dd8f59b0fc3b4dcb" + }, + { + "bytes": 188, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/fullscreen_open.png", + "role": "icon_asset", + "sha256": "e02479e78eb1350a8982ca1ef6210ec9217303fecbe8767829c279400209be29" + }, + { + "bytes": 424, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/home_folder.png", + "role": "icon_asset", + "sha256": "7b78912d0ab2809b7b0dd1dfc560e792a0ac38bc49c2db131373bdb9f4c3f8ec" + }, + { + "bytes": 473, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/hsk_mill_tool.png", + "role": "icon_asset", + "sha256": "28b028595339baf25df2e663d92ed1c4d3198d58978ed61d4b51f06f4a86ccee" + }, + { + "bytes": 851, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/jog_speed_fast.png", + "role": "icon_asset", + "sha256": "af74ff37d942449925999e60e0d43de581724ca2d44fd6c4baa345e6121af4a4" + }, + { + "bytes": 609, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/jog_speed_slow.png", + "role": "icon_asset", + "sha256": "5f374da3fdfbdbbe8cbf0eb7fadb4f8189f5a7126699571e9b85b0653b0f8a7f" + }, + { + "bytes": 520, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/keyboard.png", + "role": "icon_asset", + "sha256": "80bfee8f50ba30d0e2618a49ba019b6ad4ca5dd695178b55e92643f733200156" + }, + { + "bytes": 558, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/keyboard_hide.png", + "role": "icon_asset", + "sha256": "70890e34d1cfedadb0773609e36656ffc42802c54931b612507c854608c87666" + }, + { + "bytes": 563, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/logout.png", + "role": "icon_asset", + "sha256": "7a34da944e7ef10874067ca4ec88af576986dfdf4511b7b91a62d7cf855c5f7a" + }, + { + "bytes": 1108, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/main_switch_off.png", + "role": "icon_asset", + "sha256": "4a4e11570ebe526583e97690489c5c517a7167dc5be140394c55c02f4300a479" + }, + { + "bytes": 988, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/main_switch_on.png", + "role": "icon_asset", + "sha256": "91f45b5121209b9d7479359e2ce34215ef6fe40d93df58dc567655c733566d83" + }, + { + "bytes": 729, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mill_tool_change.png", + "role": "icon_asset", + "sha256": "aac6851ad974c049676f2949e6575e38c4883d6c96303fc5e7b7d455a9df8170" + }, + { + "bytes": 853, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mill_tool_change_num.png", + "role": "icon_asset", + "sha256": "183e01a832397bd0c9b01940da88f7706f5637baba2acaa7a93b001304895b2b" + }, + { + "bytes": 976, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mill_tool_set_num.png", + "role": "icon_asset", + "sha256": "fffab8f14dc93809b186c1ed1c3cc5d881b2aeeb981965a43178f534fd876810" + }, + { + "bytes": 479, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mode_auto_active.png", + "role": "icon_asset", + "sha256": "07641bb243ca282f8a67bf03e3f08bc1a3ba33292bda3bd948ef7d66ab24eaf1" + }, + { + "bytes": 485, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mode_auto_inactive.png", + "role": "icon_asset", + "sha256": "d9898e4fb511f674df755edc1e2d6af48b0c48def9bb8e86fe6333f3f24a760e" + }, + { + "bytes": 548, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mode_manual_active.png", + "role": "icon_asset", + "sha256": "0666155837a07843ce3a9cbd3d2d4959240762508fee60630a300cc7467b2d5d" + }, + { + "bytes": 543, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mode_manual_inactive.png", + "role": "icon_asset", + "sha256": "2f7692c2164f5442d00d0e68f83d22a5cab2fda616cd12c992cbdbdbc0971701" + }, + { + "bytes": 508, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mode_mdi_active.png", + "role": "icon_asset", + "sha256": "7e6a9de6db6c77824c2548a10135316edf33f0f711e7d2ca67a306b5830c2dde" + }, + { + "bytes": 509, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mode_mdi_inactive.png", + "role": "icon_asset", + "sha256": "446ade1c99bc7304ff60bce2656f1037a0dea41d76940b167e3d2a9a321e184e" + }, + { + "bytes": 721, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mode_settings_active.png", + "role": "icon_asset", + "sha256": "b78976bb81388c2f5af37b21ddf79c99fa3dbf0b0ecb1bf2a6814aebf41a8430" + }, + { + "bytes": 720, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mode_settings_inactive.png", + "role": "icon_asset", + "sha256": "119aee0c188f194d1ef4eeed81c270d8b02783fc9ce8ddf5388121f2fd503dec" + }, + { + "bytes": 494, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mode_user_tabs_active.png", + "role": "icon_asset", + "sha256": "c973c20ac2319ac8aa9ef19aea18ae619dcc731ed422ea612057bc5c5ad9b24a" + }, + { + "bytes": 494, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mode_user_tabs_inactive.png", + "role": "icon_asset", + "sha256": "5cefa8e48ba83efd0729928208b16bdf0c1524eb19a0f493216551859d4968bb" + }, + { + "bytes": 452, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/new_document.png", + "role": "icon_asset", + "sha256": "db1b95e6a626fa50ad4ea8962ccf8f88c2ddd189bb13ee32fbc76ba4b682b760" + }, + { + "bytes": 467, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/open_file.png", + "role": "icon_asset", + "sha256": "96ca6efe74b517c166e1ac39771a774eed48139eb05439c600f025e49b8e6874" + }, + { + "bytes": 190, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/pause.png", + "role": "icon_asset", + "sha256": "197e9e8b1433b6cd25f94dd06b8a43160a54b6f1a66cb75cf5d1351e22f07dcf" + }, + { + "bytes": 192, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/pause_active.png", + "role": "icon_asset", + "sha256": "40c5cf782d9193c0422722641c1e716e71d042b207db9db02068c5a1a758af21" + }, + { + "bytes": 392, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/play.png", + "role": "icon_asset", + "sha256": "b1a695c899eea345858da61b37a739cd3dd3c1c7b7f5b916c1035aba35a71440" + }, + { + "bytes": 766, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/power_off.png", + "role": "icon_asset", + "sha256": "d85672f49b5ee489d118096ac5ef1c2fbe4328a75a2c2645cb709e1a593a22ff" + }, + { + "bytes": 760, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/power_on.png", + "role": "icon_asset", + "sha256": "6722d5632a39e70369f0945aec4bdf2b2b7aa5726cb0466868cc3e18eea6fe2f" + }, + { + "bytes": 692, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_0.png", + "role": "icon_asset", + "sha256": "43a267965e2128e17a38686c5a4687ce5199eca46b251d953db278473960f238" + }, + { + "bytes": 603, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_1.png", + "role": "icon_asset", + "sha256": "a53c968c3cefc8b4283cb85b16cb93201976593a3ae65095bca8aab79fecc7d1" + }, + { + "bytes": 674, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_2.png", + "role": "icon_asset", + "sha256": "06ab129e94e6571c6b08604d0215abd47b9b67c6533b547301d6d491d0f39422" + }, + { + "bytes": 694, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_3.png", + "role": "icon_asset", + "sha256": "7755c4a2468dc591eeeba0eb693efc18b6c7a58088b3aa643f1625a5014ff511" + }, + { + "bytes": 626, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_4.png", + "role": "icon_asset", + "sha256": "247ec97a4be3aa122ee8ce1317d488ba725859d54b902f3d0d3922776158031c" + }, + { + "bytes": 664, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_5.png", + "role": "icon_asset", + "sha256": "20ddf08acda517886a75117921081d347fe1de2e1bd879cceb7385559536bc5e" + }, + { + "bytes": 690, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_6.png", + "role": "icon_asset", + "sha256": "7dc4cf7197f7084bf221df040e794998790091f56548c8f6f2218d3523932d29" + }, + { + "bytes": 623, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_7.png", + "role": "icon_asset", + "sha256": "73196acaee1d81f4874de543f364b77e1765c348681006df7550071fc7eebe83" + }, + { + "bytes": 684, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_a.png", + "role": "icon_asset", + "sha256": "1816357a6727e935fd56bc60acd501e89019bef486f29b297b4ef2098ca02c5f" + }, + { + "bytes": 633, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_all.png", + "role": "icon_asset", + "sha256": "c713e03ffa00a702f4799a6657d72dc4886106f48801cbd1d0d2d288b3e724d2" + }, + { + "bytes": 677, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_b.png", + "role": "icon_asset", + "sha256": "26f00e32b5e7cdf7cc38c322adc2becafb379c79d7af7e33affe77d3feead111" + }, + { + "bytes": 688, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_c.png", + "role": "icon_asset", + "sha256": "7084e912b252c5cb955edcbf541d3d7fc4a01d422dc368a8cf4d7346690efefd" + }, + { + "bytes": 630, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_u.png", + "role": "icon_asset", + "sha256": "d956c7673eec3dfdc83f2eb34e2410c7e9a70cce81ddbc7cbc1c13df752d3381" + }, + { + "bytes": 664, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_v.png", + "role": "icon_asset", + "sha256": "8ad1ba7a81d3ddcfcfabedd61ad5da05e3060174f5f4def466c943813a2073c8" + }, + { + "bytes": 725, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_w.png", + "role": "icon_asset", + "sha256": "8f6732666336e0e730ad16be1c3de07f8962b4807677ccace3be574ed3bb4798" + }, + { + "bytes": 693, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_x.png", + "role": "icon_asset", + "sha256": "58b03c60485587ac2e71e4944d15debf58c6519c99d9e6563bbcd944003117d6" + }, + { + "bytes": 648, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_y.png", + "role": "icon_asset", + "sha256": "d8d32e9c69f6402f41f3333964de27e172040669808db429e08ffe12b27f2008" + }, + { + "bytes": 669, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_z.png", + "role": "icon_asset", + "sha256": "e0c4018f914a4cbb6cd1c7cbaff1d4e59eefbeb4bbc5c55386e4e3f866e2eaf3" + }, + { + "bytes": 774, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/refresh.png", + "role": "icon_asset", + "sha256": "12fb022726a06c88e4c158e0c42eb7f3b625bc09e7136c2fd4e8a51bab32dad7" + }, + { + "bytes": 418, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/run_from_line.png", + "role": "icon_asset", + "sha256": "8ac664fa930e8269826e23bc9da07c16eacbcaf74f76120b7c420441df3de8f5" + }, + { + "bytes": 452, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/save.png", + "role": "icon_asset", + "sha256": "790681c1edd9d1a68104ec6e794dd85fecfe809889655697216aa6384a51dcea" + }, + { + "bytes": 593, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/save_as.png", + "role": "icon_asset", + "sha256": "45e6d83bf9d00bd17ed7a56c0830d64cd7ce15e5f48488f7462620a81daf0321" + }, + { + "bytes": 512, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/select_file.png", + "role": "icon_asset", + "sha256": "f767c7802748e2a7775d461430846e6e05fdd9e6737e7f0a3f17ccf97bb5dac8" + }, + { + "bytes": 542, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/skip_optional_active.png", + "role": "icon_asset", + "sha256": "b05795daba84b191f5776c76afcb1fc0730333109a607a93c012254bcff62fc4" + }, + { + "bytes": 906, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/skip_optional_inactive.png", + "role": "icon_asset", + "sha256": "c68eb16c195b83073004f6581927f2805b872811736d2b187eb080a1bffb2402" + }, + { + "bytes": 714, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/spindle_left.png", + "role": "icon_asset", + "sha256": "34c1b89f61c179d71816532981de0671babf0abe37dbcdff81752b1933b12ec3" + }, + { + "bytes": 702, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/spindle_left_on.png", + "role": "icon_asset", + "sha256": "b5861a7ddec2d53b461718e72dce958a48bb70c6f96679662ba0035f58496382" + }, + { + "bytes": 695, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/spindle_right.png", + "role": "icon_asset", + "sha256": "17ca99e1c98f5acf13c109f21fefee507320fefcea581ecdfb4a720de191bfca" + }, + { + "bytes": 690, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/spindle_right_on.png", + "role": "icon_asset", + "sha256": "4e942689c386b88e4a8d1dee42eef60b232d6902ef5ceb311d39156874a36a9c" + }, + { + "bytes": 695, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/spindle_stop.png", + "role": "icon_asset", + "sha256": "f2bc86c5eae74dfc77d2ab7d5556ca20b24eb0c6a9747a008f097c48b389196c" + }, + { + "bytes": 577, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/spindle_stop_on.png", + "role": "icon_asset", + "sha256": "6ceb2a6efa3e6da3ac797857707125ba64e401bd65a30280e63af0c46e762c5c" + }, + { + "bytes": 456, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/step.png", + "role": "icon_asset", + "sha256": "b7c486b008096f607b0c2f9d9bbfc73a18f5432603a28fed2080e1f1a094033f" + }, + { + "bytes": 117, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/stop.png", + "role": "icon_asset", + "sha256": "b73a8bc5e9fd9a1e7f1a48e9c8ace8998b45dab8bfbeaa4f80cbd7d629e67dc9" + }, + { + "bytes": 906, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/tool_axis_p.png", + "role": "icon_asset", + "sha256": "4a62ac0aaa0317a09284523b0af4e4aec612915b24f5d8ce19aa8eb32ad11be2" + }, + { + "bytes": 788, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/tool_axis_x.png", + "role": "icon_asset", + "sha256": "472c3f8f2ab62ae0843c91b92e1040abb86b56b30e51953ae67f645d115bccdd" + }, + { + "bytes": 640, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/tool_axis_y.png", + "role": "icon_asset", + "sha256": "54cc220e2663206a62727a9cb73280bb53420d7923c401622d7a16946759e0dc" + }, + { + "bytes": 643, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/tool_axis_y_inv.png", + "role": "icon_asset", + "sha256": "a1675625c48a9b3d219f9a91eff1fa626d64727194e15c34d75d9b272df00df2" + }, + { + "bytes": 661, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/tool_axis_z.png", + "role": "icon_asset", + "sha256": "1765555940ccb899c06403afbf57865aa8f4999fc2c79fc3e8389ebe47464933" + }, + { + "bytes": 939, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/toolpath.png", + "role": "icon_asset", + "sha256": "f6e7dc5730b24aa31883d7ab465aeff011f693a75a6ff1a8f7c6008c80128222" + }, + { + "bytes": 678, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/touch_a.png", + "role": "icon_asset", + "sha256": "f091ea2c2241bc7bcc0a6e69534803115640c56425759a2b4e1fed301b6a4491" + }, + { + "bytes": 719, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/touch_b.png", + "role": "icon_asset", + "sha256": "700bbe71bd9b4c7ebe6eec89201a409fbee7c53be698758ff45ee3c51e67d019" + }, + { + "bytes": 706, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/touch_c.png", + "role": "icon_asset", + "sha256": "41cf99b8515560cd0899e7b78463d05e3dbccd7a75fcbc780b1f7c9088212619" + }, + { + "bytes": 541, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/touch_off.png", + "role": "icon_asset", + "sha256": "1d15306f221221ce6f30ca8e32e7b70502b6afcbf84a1beb61605708025f15c8" + }, + { + "bytes": 652, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/touch_u.png", + "role": "icon_asset", + "sha256": "73d34f85c6177d7a8594e92040396aeb1d565adb0cc28af5345b643c97361f29" + }, + { + "bytes": 699, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/touch_v.png", + "role": "icon_asset", + "sha256": "fa997c9bc50ffa86577c028faa626f2b415e7122410e414a40cee8ddbb1afed8" + }, + { + "bytes": 765, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/touch_w.png", + "role": "icon_asset", + "sha256": "6e1c530c04e0076875e7358a4e892d6e36a85b09927588e53262b99bc257c4f7" + }, + { + "bytes": 703, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/touch_x.png", + "role": "icon_asset", + "sha256": "294230922bc339eedd5f43b2de4b1e571cac816d69b641b54705bc879e1a8219" + }, + { + "bytes": 672, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/touch_y.png", + "role": "icon_asset", + "sha256": "1f05a7ec41269313fd84ba685778ef5fae0ad40ce05944ff31de83cc337ce418" + }, + { + "bytes": 676, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/touch_z.png", + "role": "icon_asset", + "sha256": "f7294d1d113a86fcc643e5825b92dc81f052d430b90494d6e1c817d857e8d7f0" + }, + { + "bytes": 782, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/translate_a.png", + "role": "icon_asset", + "sha256": "cf962b0d288e23890ce58842138334ad61f503d584fc9b389ba1017d16131bcd" + }, + { + "bytes": 834, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/translate_b.png", + "role": "icon_asset", + "sha256": "8f4655e646c4d499afb71e312821328bcd6e05339da8493e57fd5afa49ef8410" + }, + { + "bytes": 816, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/translate_c.png", + "role": "icon_asset", + "sha256": "92df018af3f66ec3f40157a4fe57b7967a6352987202fa38076da3e9bdfdf070" + }, + { + "bytes": 743, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/translate_u.png", + "role": "icon_asset", + "sha256": "3e6ec55fc5e4758ee83238a8c84b84162ba37bfd6c2902630300dfe4322e5f2b" + }, + { + "bytes": 800, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/translate_v.png", + "role": "icon_asset", + "sha256": "1eb05cb19e353be7893258b58e8d1ef861efb3904a5128f0aac60fd86ece44cd" + }, + { + "bytes": 841, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/translate_w.png", + "role": "icon_asset", + "sha256": "9cce3dc6438e9b9c9d65a31c579ee6ccdf18ba433810e7d25e5517e0e0f45f80" + }, + { + "bytes": 818, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/translate_x.png", + "role": "icon_asset", + "sha256": "f82f17d09f022604a06b05c24fd3872fbf50ede0d9dedd007ea5a7f5382aa00a" + }, + { + "bytes": 761, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/translate_y.png", + "role": "icon_asset", + "sha256": "0ad96f3d7152c2464ac3398b263dadc09ac9f5eeb8c00c56710e417287c35633" + }, + { + "bytes": 801, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/translate_z.png", + "role": "icon_asset", + "sha256": "7178a6e8534f25c18ac3f9dc98841b9d4e0b979a91059828a8264ab05c01e377" + }, + { + "bytes": 681, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/unref_all.png", + "role": "icon_asset", + "sha256": "bbdfcf5906afab95ef82887829326445cfe9e903b074abc7b20a9079212022d7" + }, + { + "bytes": 451, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/user_defined_folder.png", + "role": "icon_asset", + "sha256": "d901d4004a6930df19fa0357ea93aa93765731c0b09a27a5cf04d62bfbc03a15" + }, + { + "bytes": 407, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/window_close.png", + "role": "icon_asset", + "sha256": "33aefea300622c532268cf05ce079fdbcfe019f84e6b5199c28e9a8277ef2f7a" + }, + { + "bytes": 742, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/zoom_in.png", + "role": "icon_asset", + "sha256": "60670723167797f8a51176b0271de6b152f5556d0abff7ec38da14077e7ba7be" + }, + { + "bytes": 688, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/zoom_out.png", + "role": "icon_asset", + "sha256": "afddd54054cb102e857f0cd433cc708dba12a28c1dc58656caa7dd471c99f689" + }, + { + "bytes": 835, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/status/dialog_information.png", + "role": "icon_asset", + "sha256": "103424233e8372ec200cc8349c3441b140ce0b1f19b559b7143453f74ac642b2" + }, + { + "bytes": 682, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/status/dialog_warning.png", + "role": "icon_asset", + "sha256": "e75d6cacbfef84983ac384b51d0c2ec8c8bdf75f4baed25bda006f9387379bcd" + }, + { + "bytes": 657, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/back_to_app.png", + "role": "icon_asset", + "sha256": "f5dbd1bcf10ea8d5dfacf32961799eb5b7d910f170dd84484af25891e018d401" + }, + { + "bytes": 433, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/chevron_left.png", + "role": "icon_asset", + "sha256": "eb375c43450b4f9200dcbc7a09aed662fd5060a6c93fd724ebe68e200892db7d" + }, + { + "bytes": 423, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/chevron_right.png", + "role": "icon_asset", + "sha256": "c3522f36502be361c73513445eaf474a9c12e75e31ef1cf8cf87bc4454a64d11" + }, + { + "bytes": 444, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/chevron_up.png", + "role": "icon_asset", + "sha256": "62a33fe170c4825e27eee42f87cb2dd2a0e431315a13747f50eca9ce176ec3c0" + }, + { + "bytes": 656, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/clear.png", + "role": "icon_asset", + "sha256": "0775feaebe224cadfef3dbe855538091a309a9ae9cab551a6acf7fb02fbcadd2" + }, + { + "bytes": 1019, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/coolant_flood_active.png", + "role": "icon_asset", + "sha256": "dff8d62b521842f5355f483e42486070c98dfde29e30d025e200b1b2d7e5d40b" + }, + { + "bytes": 1079, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/coolant_flood_inactive.png", + "role": "icon_asset", + "sha256": "032da2423b0a3e7395dfc70128a9dee94a98954d170607586eefe0be79bf40b3" + }, + { + "bytes": 1314, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/coolant_mist_active.png", + "role": "icon_asset", + "sha256": "fb4d4919b294cdd1eb60b1cc8592e19cb1bbfabca2705fde8c8b99d95dc3d7fc" + }, + { + "bytes": 1416, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/coolant_mist_inactive.png", + "role": "icon_asset", + "sha256": "80885a9dbaaaf518956b7a0dfcbec459f2963bbc0c49e0af14ea0b52dad7824a" + }, + { + "bytes": 640, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/dimensions.png", + "role": "icon_asset", + "sha256": "b1fbf4fba65fd5e8e2b6f7af0895ae2c059c26701e64b22ed0ecc67863634234" + }, + { + "bytes": 474, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/edit_code.png", + "role": "icon_asset", + "sha256": "1a8f615e59d0be4b7f0f4758594b9cf1301a45f6d00ae2a9cad9d801d703dd46" + }, + { + "bytes": 459, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/fullscreen_close.png", + "role": "icon_asset", + "sha256": "c162ea7aba48cc7aaa21db103fd9452925376b1b91f4e7d3d96bd2160ba1e057" + }, + { + "bytes": 237, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/fullscreen_open.png", + "role": "icon_asset", + "sha256": "991a3d0de52963a9289445a1f90b6241a5a55a5cfd35027196249a82d6ecf318" + }, + { + "bytes": 494, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/home_folder.png", + "role": "icon_asset", + "sha256": "7623b6961670bc7f9af6e989f325c637820df5ef01e8fc21ce9abba9f4eea867" + }, + { + "bytes": 561, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/hsk_mill_tool.png", + "role": "icon_asset", + "sha256": "3e9fb4902e6cea219d5b06e3f506cc1159e48b3e91f915fdd77cb4beb447e14e" + }, + { + "bytes": 1221, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/jog_speed_fast.png", + "role": "icon_asset", + "sha256": "fc4369586072ae27e67b2b1015440c7affe834cffc346038c293900569914b32" + }, + { + "bytes": 765, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/jog_speed_slow.png", + "role": "icon_asset", + "sha256": "d4be171e2df6d15e057237edd91a41e573dcd5b0c219870880fc60553b72e132" + }, + { + "bytes": 663, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/keyboard.png", + "role": "icon_asset", + "sha256": "cc8824ee46b721433c4e426ed2480f122cf5b1a802de67726df2f6b155ce3455" + }, + { + "bytes": 702, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/keyboard_hide.png", + "role": "icon_asset", + "sha256": "6fe4570014b8f152091ac4021a8f2a569c55370e85aefe13cd855e225789863f" + }, + { + "bytes": 677, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/logout.png", + "role": "icon_asset", + "sha256": "549818b91f71dcbfbc19bd3431fb3fa1649aeda9670a1f2996a89c3553bbc7ef" + }, + { + "bytes": 1444, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/main_switch_off.png", + "role": "icon_asset", + "sha256": "709128fa41505db8a78a8bd725c03f92d7b82d45e8c7999cdec90e32a367aa74" + }, + { + "bytes": 1346, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/main_switch_on.png", + "role": "icon_asset", + "sha256": "6159b447ff1e94e6765d289dec5ddfcbb50ad3cb199f0e8c5e647fd3bf49cee4" + }, + { + "bytes": 1002, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mill_tool_change.png", + "role": "icon_asset", + "sha256": "97abf1b35e6f7a5951f8cb655d9fe5a0ff6ff8ca6d9d61927fd24534858178eb" + }, + { + "bytes": 1208, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mill_tool_change_num.png", + "role": "icon_asset", + "sha256": "35717a026794e59e6852dc2601ce962bba0a9b6431ae71d57ba244fee63db075" + }, + { + "bytes": 1348, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mill_tool_set_num.png", + "role": "icon_asset", + "sha256": "81fc70bce58f1ab3092753050df9a766d490f34820ee72beb05bc14d04503583" + }, + { + "bytes": 514, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mode_auto_active.png", + "role": "icon_asset", + "sha256": "c8c588974d51b0dfda37ab423a5ec63ef1a8892ceaaea6d59dda394f4d9730ba" + }, + { + "bytes": 509, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mode_auto_inactive.png", + "role": "icon_asset", + "sha256": "c5b109fbf7475e710dd8b54903fe98aed68f99ea13d054b395c91519f5e73a42" + }, + { + "bytes": 556, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mode_manual_active.png", + "role": "icon_asset", + "sha256": "b044a31071281b653f4643d1b06117a11f5c85edb11b5ba9bfe5e3db9a1de5ce" + }, + { + "bytes": 555, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mode_manual_inactive.png", + "role": "icon_asset", + "sha256": "8ec0217061cebddf0ff9f4c3139ea25039c912e53d1e4dd61e38e5d862a1b5d5" + }, + { + "bytes": 696, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mode_mdi_active.png", + "role": "icon_asset", + "sha256": "830c1db6dabe455f4c72895a96a8bda959364d97848d4de212f8e7464d2feb84" + }, + { + "bytes": 692, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mode_mdi_inactive.png", + "role": "icon_asset", + "sha256": "956aa0f569ec85d24fea80afa3f7649c2a64090a64d9761a46c3ef46446b6daf" + }, + { + "bytes": 916, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mode_settings_active.png", + "role": "icon_asset", + "sha256": "0c3745d43d27811fd2f199ed69db06e52f3a377c15ef20a14550367a28a1f894" + }, + { + "bytes": 916, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mode_settings_inactive.png", + "role": "icon_asset", + "sha256": "3fbc760526886382b659210182c3b2265f7cefa044ef7742745fe506c36d4402" + }, + { + "bytes": 587, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mode_user_tabs_active.png", + "role": "icon_asset", + "sha256": "3d4c70694da2c18d10329b210e56d4abcaba43ccd3f61429e71c3a8a23ce2e6a" + }, + { + "bytes": 584, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mode_user_tabs_inactive.png", + "role": "icon_asset", + "sha256": "d9ef8c7fcfeb0f469dc1d711de695d02eebbfdde7ddb05100548dc9a991a2662" + }, + { + "bytes": 551, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/new_document.png", + "role": "icon_asset", + "sha256": "0d93922f3825957de2e0706189063e238d05838e78d9bdd4bdfac41f0dd96f0c" + }, + { + "bytes": 486, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/open_file.png", + "role": "icon_asset", + "sha256": "aee4a82075613e91878539d7a9fe08e7cedc9d9a3929a11ad80634ec58111249" + }, + { + "bytes": 214, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/pause.png", + "role": "icon_asset", + "sha256": "ab92bf14b6b707b1a357f0116a166cc1b73e922d25b655bb8b83f86c98a33d60" + }, + { + "bytes": 198, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/pause_active.png", + "role": "icon_asset", + "sha256": "c8621f9ecf0353dcd26cc155717e29d3d0e6469e1287701a0b976a064264cd06" + }, + { + "bytes": 431, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/play.png", + "role": "icon_asset", + "sha256": "2f255f301b1651ce2d0866d5eded57cf22b6e92e748141d28893be4553255201" + }, + { + "bytes": 994, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/power_off.png", + "role": "icon_asset", + "sha256": "4e0952351bcd292ab2f0508eeb9baf05103decfee0affbb7c0689d1ef8eb8a6c" + }, + { + "bytes": 996, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/power_on.png", + "role": "icon_asset", + "sha256": "4ed0b916a0593b361e91bfb4da9309beb58ca45beeb636ae29b6e1f6a356a1ec" + }, + { + "bytes": 935, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_0.png", + "role": "icon_asset", + "sha256": "9470ac44c7caad05b1f3ee9623777d030b934a34a4bfc7149cc587e7a02b05d2" + }, + { + "bytes": 771, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_1.png", + "role": "icon_asset", + "sha256": "84a6154d89129fa337b8d4f60a10c6d274041f25b3cd949f588ceedf415c23df" + }, + { + "bytes": 879, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_2.png", + "role": "icon_asset", + "sha256": "e94d65b4c825b1ec1b0df83357cda57a644c1ef6b88036166dfad6ca02c71131" + }, + { + "bytes": 922, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_3.png", + "role": "icon_asset", + "sha256": "a41ca5a5c7bc8d5d1054008d7d70031d41b8c5e187aff40fccc2570c20000248" + }, + { + "bytes": 857, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_4.png", + "role": "icon_asset", + "sha256": "71d64249fffb08f7aeade97e56eedae4a17f71d525ff3eb9e2c4dacd3d95ee81" + }, + { + "bytes": 921, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_5.png", + "role": "icon_asset", + "sha256": "1bf35f58bb17efbf89f9483a692a50cdb763fb6e5c6b4092e28329a7a6a53dd9" + }, + { + "bytes": 906, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_6.png", + "role": "icon_asset", + "sha256": "9b51f4b032043037e7218db656be9017987af09246ec78d32598ab8f7eb2f3c0" + }, + { + "bytes": 862, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_7.png", + "role": "icon_asset", + "sha256": "7490686feed90c52010e7849d6273f857d7f5e4a1bb9d648566db39e24f1eb5b" + }, + { + "bytes": 910, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_a.png", + "role": "icon_asset", + "sha256": "a3cfb740a384f4b5e718dc454fd8d396f8096a2c2e7ff458dc1420f99e1cce5e" + }, + { + "bytes": 883, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_all.png", + "role": "icon_asset", + "sha256": "00cfb0a16d0902168feb074e2871b79647b2638fa98e7a24dba22965b91daa1a" + }, + { + "bytes": 923, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_b.png", + "role": "icon_asset", + "sha256": "592d8bd846488a21818b88d0eef3c1a361fd6a3bdf440537b6fb005ba042e0c5" + }, + { + "bytes": 991, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_c.png", + "role": "icon_asset", + "sha256": "4cd69fb4d8faceb2150eb9c386d34717a49e1dbbce5fdaf562bba207eefc2050" + }, + { + "bytes": 846, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_u.png", + "role": "icon_asset", + "sha256": "c92e7f0185f46484b487e6249d52c3b3bb238fd54eb0e83357b9c87096a6da99" + }, + { + "bytes": 932, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_v.png", + "role": "icon_asset", + "sha256": "7c4e32a7be8579dc68d90e69ec4045f7adca26014dc16ba7a37f3918b72f9737" + }, + { + "bytes": 1009, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_w.png", + "role": "icon_asset", + "sha256": "9c53f4de5f047ac0d629d7ee15bfba799e3a913df8e8019165b8b9bce380ee0e" + }, + { + "bytes": 965, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_x.png", + "role": "icon_asset", + "sha256": "a93f2fb21b40eb9075d058b2f2c78a590b3f86384df97ef14bf616dcec3d2681" + }, + { + "bytes": 858, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_y.png", + "role": "icon_asset", + "sha256": "52ee4ab369cc8b469f019fc56142d525e812e622b8d46e6a9459a0ad75542d3f" + }, + { + "bytes": 887, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_z.png", + "role": "icon_asset", + "sha256": "fe0884d9056f3764fc29fa5e9ad304b617e37f64a6c3c42d8f5e9ba3e4b3acf3" + }, + { + "bytes": 1017, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/refresh.png", + "role": "icon_asset", + "sha256": "6dca0df3b7165945f1292caf75b9101895dc49a7ae5a27f5b604302399d7d153" + }, + { + "bytes": 444, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/run_from_line.png", + "role": "icon_asset", + "sha256": "838108452c4f38aab9067859ccbcbcf1e9ce4fb8015bf19df5de1159c09e5a76" + }, + { + "bytes": 575, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/save.png", + "role": "icon_asset", + "sha256": "43ebae97778388fca6d893ec42ca5982b5ad9f8433d26d9b274ea2e3d9ca5cc4" + }, + { + "bytes": 760, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/save_as.png", + "role": "icon_asset", + "sha256": "28e8c1b3070a26f758fb08ffe43b10ab903c3e98bf4d28eda4c1753baae2148d" + }, + { + "bytes": 648, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/select_file.png", + "role": "icon_asset", + "sha256": "9beaef9bf66f661ef2e46630cf850332e1af9e8ef33e02f2dc13507d3030e570" + }, + { + "bytes": 638, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/skip_optional_active.png", + "role": "icon_asset", + "sha256": "70e362338c6d5e294b93fac82c1722087e20ec205e2b115b0c51a29403d16731" + }, + { + "bytes": 1169, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/skip_optional_inactive.png", + "role": "icon_asset", + "sha256": "d2956ee3f50db46583e1d31c1114b5a388531588bb8764671bf292568ab33c17" + }, + { + "bytes": 936, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/spindle_left.png", + "role": "icon_asset", + "sha256": "c9e9cd6bac2f0bd6292a2de659e52eae654c3a56f94c5e8a3435cb0300a0aa0d" + }, + { + "bytes": 943, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/spindle_left_on.png", + "role": "icon_asset", + "sha256": "e0638fe44d2f019537f1afae1c9719bfa4d434611b92702cf19e93f227011630" + }, + { + "bytes": 942, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/spindle_right.png", + "role": "icon_asset", + "sha256": "9f264ea18b6f6915b7f81def828741f1daff1dfdd55e90fa0e4e1ffbb90e15f1" + }, + { + "bytes": 950, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/spindle_right_on.png", + "role": "icon_asset", + "sha256": "8ea83e3df64e1a1d787cede52ba77171bb9e3f640102a02be78d521d6d9f562f" + }, + { + "bytes": 885, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/spindle_stop.png", + "role": "icon_asset", + "sha256": "148b8d701eb2c7ebd2d8a046c436ee88a6dac553613e38e10c9cf2e3f295b259" + }, + { + "bytes": 736, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/spindle_stop_on.png", + "role": "icon_asset", + "sha256": "a1efbdcf85df1c856a40ce73a71ad8400c1be9e868caa709ed041b2a9b7d9705" + }, + { + "bytes": 549, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/step.png", + "role": "icon_asset", + "sha256": "57cd49d85b5870bc9eb19cbf021c1ece8286037fcfaca26f3ebfc603857ea4e7" + }, + { + "bytes": 133, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/stop.png", + "role": "icon_asset", + "sha256": "d231e5993cbbf1517d79ce6a75d8a86a546962a4888a61d7d8d6e6e80cd839dd" + }, + { + "bytes": 1089, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/tool_axis_p.png", + "role": "icon_asset", + "sha256": "05368ea34bd04c0556d589d2dd4c27b2133e05f088e6a10995e04cfb1d16b698" + }, + { + "bytes": 890, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/tool_axis_x.png", + "role": "icon_asset", + "sha256": "47001a124e7a1a281ec6c81e9fca887f2ce4aceb06da644c252d64813650491b" + }, + { + "bytes": 698, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/tool_axis_y.png", + "role": "icon_asset", + "sha256": "11fe11bf11212022708ed45e2b9ead980c3c28b86d65ede754506d3602008074" + }, + { + "bytes": 702, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/tool_axis_y_inv.png", + "role": "icon_asset", + "sha256": "510d6cb04854208161ec85ea507627b7ca9228be7a0f88021a2427eeb5469ce0" + }, + { + "bytes": 683, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/tool_axis_z.png", + "role": "icon_asset", + "sha256": "480ca5862d0e97830733cc02356e7d9cdf1720141f2149887d44c65d2af63568" + }, + { + "bytes": 1191, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/toolpath.png", + "role": "icon_asset", + "sha256": "40b309cf637b701c2e4d85fb58d36516b5865101536b4b09f5b6d9151b3b5705" + }, + { + "bytes": 925, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/touch_a.png", + "role": "icon_asset", + "sha256": "94ba2b809ad5bcf802b8f5ab8a61b1f80817dde63a89e1feea5375f91d65aac3" + }, + { + "bytes": 949, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/touch_b.png", + "role": "icon_asset", + "sha256": "f4f11f5cb8cba6d28ab816d9ba2d9164ab6557136264c8da1987d0b1dc0ce361" + }, + { + "bytes": 973, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/touch_c.png", + "role": "icon_asset", + "sha256": "b8cf0965068ca5355f09460e9d522964166a49fd8c1d0d7b50ff0ceb0ee8dc88" + }, + { + "bytes": 709, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/touch_off.png", + "role": "icon_asset", + "sha256": "ad118bfa630012786751738136975d527b9be9e8a3ca0a3db1780ab011934c37" + }, + { + "bytes": 851, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/touch_u.png", + "role": "icon_asset", + "sha256": "faf8a42eabce2447506cbcbb32a59aeecdd947ee02b43b5726b371acf0ea4523" + }, + { + "bytes": 944, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/touch_v.png", + "role": "icon_asset", + "sha256": "9108850eed9fd0532317c10482e0c89ae3726b95721f028d896ff36b53e7182c" + }, + { + "bytes": 1049, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/touch_w.png", + "role": "icon_asset", + "sha256": "e9178aa73513d75a60216c35b7e2a9cdaba4c078dec7fb9329ad0734a8935a10" + }, + { + "bytes": 976, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/touch_x.png", + "role": "icon_asset", + "sha256": "b434d5100bfe95feca17ede7633c79960126949190e851ba860a739ac0c084ca" + }, + { + "bytes": 906, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/touch_y.png", + "role": "icon_asset", + "sha256": "920d8b6648d901c98f383d84b7a040ced56ca2e12546d5e0572804f23b121380" + }, + { + "bytes": 909, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/touch_z.png", + "role": "icon_asset", + "sha256": "d658c7f2b46adc18dacd7e712aeea2154e3cef02bb6e4512438fb49423d05ce5" + }, + { + "bytes": 1150, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/translate_a.png", + "role": "icon_asset", + "sha256": "c4e4c67d623d10dda9a43d24bf8ab6cd69a32f53faa6483e186395bf48c63d9a" + }, + { + "bytes": 1133, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/translate_b.png", + "role": "icon_asset", + "sha256": "cac338a3f7116bf33219bbc2f03611ab635c27a94750a792ba1a58d66a708d1c" + }, + { + "bytes": 1143, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/translate_c.png", + "role": "icon_asset", + "sha256": "923f01ab121959f00bf8cde01e83e237aa944a52d2ec8a1a68070a89a972004d" + }, + { + "bytes": 1032, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/translate_u.png", + "role": "icon_asset", + "sha256": "891a2c6f3a3fc9f8dc5926e9f287e57a604f728b6bb6f6af75272a5b85cd60a4" + }, + { + "bytes": 1181, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/translate_v.png", + "role": "icon_asset", + "sha256": "aded41a5d9e3adc9198ef2f4411d9c2523d4a47e694cb5362769f9bf0eb6ce68" + }, + { + "bytes": 1250, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/translate_w.png", + "role": "icon_asset", + "sha256": "5fb8793160cb1eb5354fb6a92fcc11ac2d2756b89e0189742e88ab7f3b4c91ed" + }, + { + "bytes": 1166, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/translate_x.png", + "role": "icon_asset", + "sha256": "af392a6ec2ca9b298083b4e5a4748d6ca792f697c10fb7cb8f316de09e8bb177" + }, + { + "bytes": 1102, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/translate_y.png", + "role": "icon_asset", + "sha256": "b63bb5b476c858f6d372547a7587e6c7f598a2c6ce4d87cccca05f5578b6269e" + }, + { + "bytes": 1114, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/translate_z.png", + "role": "icon_asset", + "sha256": "b3b8733baa2a1932636f4d429d4dd345e67bf3793d713594e53f59d54bb25c87" + }, + { + "bytes": 840, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/unref_all.png", + "role": "icon_asset", + "sha256": "6fe038343ca17c0454196a021754d832195718a012977ed8a488d8595c005444" + }, + { + "bytes": 569, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/user_defined_folder.png", + "role": "icon_asset", + "sha256": "c0fb2e00c3cb1daa59b8c3b2c0223d907534ea4f51e59db9b2d4676eb0b1d52f" + }, + { + "bytes": 512, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/window_close.png", + "role": "icon_asset", + "sha256": "c7d90a9d673b67f00a82d6c9b1af18cee80f83adb9641ce6df6f8451d4278dbd" + }, + { + "bytes": 1036, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/zoom_in.png", + "role": "icon_asset", + "sha256": "ee41b29d392cd200af3bf9fd2ec0a6587dd124e1f4f13e412859399396e94357" + }, + { + "bytes": 996, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/zoom_out.png", + "role": "icon_asset", + "sha256": "93d2b7ddcc6038b63e9f42204730b90b552b6eb7707eb5df97b9022463128f0f" + }, + { + "bytes": 1159, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/status/dialog_information.png", + "role": "icon_asset", + "sha256": "4ebc8b0ca1d47c790f974dde4ee7aa90d118e3a8d20194ef9981192a7dc08a6a" + }, + { + "bytes": 928, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/status/dialog_warning.png", + "role": "icon_asset", + "sha256": "d107c140d1b8b6b8f4e9b0d43c2cce0884c0c456e988c894bd39fa13856eb35c" + }, + { + "bytes": 915, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/back_to_app.png", + "role": "icon_asset", + "sha256": "832227ad183073a97fcbcea82b369d281e8543f16227ec19cc17fe62d23def4e" + }, + { + "bytes": 626, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/chevron_left.png", + "role": "icon_asset", + "sha256": "014eb7be391dbcf76f6977d45f915cedfd07b3a4b189efe7faef0f1d163ce98b" + }, + { + "bytes": 628, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/chevron_right.png", + "role": "icon_asset", + "sha256": "9afbb2654376c4f3a5d36fa3aca2ad4a81e558ee2b06dc5961e78e02f7245c17" + }, + { + "bytes": 666, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/chevron_up.png", + "role": "icon_asset", + "sha256": "8f90d6be56c0e5b037206b74576e57c6c2d6380f6bd2100d360de402d220dfcb" + }, + { + "bytes": 916, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/clear.png", + "role": "icon_asset", + "sha256": "47ccf9b21cd05b716e9ab0e1303c5a217f5d94e773afe3aef29bb1681dc41942" + }, + { + "bytes": 1715, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/coolant_flood_active.png", + "role": "icon_asset", + "sha256": "f7b383264772522acb30c57f9c5f4c32d22effb0f2890e2ba2e3e7e4c5c3df87" + }, + { + "bytes": 1782, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/coolant_flood_inactive.png", + "role": "icon_asset", + "sha256": "deab82c5fb700a954209c40735dc2100797ba85d38734206261a7de2b2482616" + }, + { + "bytes": 2205, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/coolant_mist_active.png", + "role": "icon_asset", + "sha256": "67fd61eaa56e784790bd7eeb2f4077231013189a234fca55bf97f95fa0d89917" + }, + { + "bytes": 2298, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/coolant_mist_inactive.png", + "role": "icon_asset", + "sha256": "1fb7253e9c8d5a219893d9a79971b496699afb6aac545e7d5427e4164ede96be" + }, + { + "bytes": 959, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/dimensions.png", + "role": "icon_asset", + "sha256": "9f2d8eb6a082fb4cadadb69079b847be8af54c5fd7acebe80235ac31d2810490" + }, + { + "bytes": 660, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/edit_code.png", + "role": "icon_asset", + "sha256": "279dbba42f2da822a83e79f97b3260b4e335c769649dd1cec8ce08a9efdcb553" + }, + { + "bytes": 621, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/fullscreen_close.png", + "role": "icon_asset", + "sha256": "2aca5da519fb0bb4bc1f22a287d75cbf1754fd2e60f69c5c6dd5d7a2dedc5721" + }, + { + "bytes": 296, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/fullscreen_open.png", + "role": "icon_asset", + "sha256": "9af768d3f8827ed8c5e6a7df623762aa1023ac6cf53901e8d929123767edc620" + }, + { + "bytes": 608, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/home_folder.png", + "role": "icon_asset", + "sha256": "da0cb9be2c40f173b6ce87defb17705bc032dd62236281430a11f4422b595fe4" + }, + { + "bytes": 827, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/hsk_mill_tool.png", + "role": "icon_asset", + "sha256": "cf539852f7a82ee2efa3b18b652f97ae48ee0711f7a4c48a6bdcce7a32f7ca22" + }, + { + "bytes": 1816, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/jog_speed_fast.png", + "role": "icon_asset", + "sha256": "064ef0eac091f3aebebb5710d46a31719563982ce2e172dac38225333e6604c4" + }, + { + "bytes": 1189, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/jog_speed_slow.png", + "role": "icon_asset", + "sha256": "a8814aa1bac08584d03bd4d7bd331a69af5f45b3df52646ed3aca7706f131149" + }, + { + "bytes": 576, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/keyboard.png", + "role": "icon_asset", + "sha256": "454ca4606c319034f71e41079748e4a86545b00c8fcae1810c491327d77f07af" + }, + { + "bytes": 879, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/keyboard_hide.png", + "role": "icon_asset", + "sha256": "fbf4cb3d8213973b6bf574d25b68e7c28d1bdad3f863dc6a0cced5a39f1672d8" + }, + { + "bytes": 1014, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/logout.png", + "role": "icon_asset", + "sha256": "0d49e026537ee650938a4b5c9334594b303b6f7f57217e14b9fd345b983fb858" + }, + { + "bytes": 2294, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/main_switch_off.png", + "role": "icon_asset", + "sha256": "084a1d7a21123e229da464c5abc1db945c60cd33bc925f2f4b74c4a719375e6c" + }, + { + "bytes": 2171, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/main_switch_on.png", + "role": "icon_asset", + "sha256": "26510fa0a705ef0012ed28da3de94740d97f23405649ecabe6f9ffdb8b19ddc7" + }, + { + "bytes": 1500, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mill_tool_change.png", + "role": "icon_asset", + "sha256": "d9e356ef8ca9b819161b55b8dac7fab97e26f4bcdab6f26a0c69bc9a85482056" + }, + { + "bytes": 1925, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mill_tool_change_num.png", + "role": "icon_asset", + "sha256": "17e89e8a9cd224c29517c594d4c87f37dfee99c43af69977b92263a5eee8b233" + }, + { + "bytes": 2139, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mill_tool_set_num.png", + "role": "icon_asset", + "sha256": "cd23b493e0c05428bfd244a5c99214198589805a4cdee50c8297deb17d7ad3dc" + }, + { + "bytes": 738, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mode_auto_active.png", + "role": "icon_asset", + "sha256": "cbace9efd9e6a10478a737aab508e133dd58860bfeb70714805eddc75ecf3d7d" + }, + { + "bytes": 735, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mode_auto_inactive.png", + "role": "icon_asset", + "sha256": "8f281c733ea8452d63692e77d57d68652a019e29871bff947754a48e89ffca42" + }, + { + "bytes": 790, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mode_manual_active.png", + "role": "icon_asset", + "sha256": "6fc5974fe9e9f8b98276c95657b6d3f9ce9744312e866b453718c4405acb2f9c" + }, + { + "bytes": 790, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mode_manual_inactive.png", + "role": "icon_asset", + "sha256": "5511ea8f574d66c54e2e9fa4795a2cdba42abb032867923384f89a21d2bf2b53" + }, + { + "bytes": 876, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mode_mdi_active.png", + "role": "icon_asset", + "sha256": "dffc3570f0400e23d7e94bfa23e600bb8a72469a9ddc1abd14a54259c0dffd8b" + }, + { + "bytes": 886, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mode_mdi_inactive.png", + "role": "icon_asset", + "sha256": "3ff8c972246989e7e379d86d30bf3114f4e36c0bae1eed2870d6df1903ba2fe1" + }, + { + "bytes": 1297, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mode_settings_active.png", + "role": "icon_asset", + "sha256": "8b52843ebf8769642d464bb371615f7dbcc54373d68da725e40f3b1cab62a21b" + }, + { + "bytes": 1267, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mode_settings_inactive.png", + "role": "icon_asset", + "sha256": "f63f968b3b63f6febb87567d3f57956c3617d0a791526d4d654af9821d474184" + }, + { + "bytes": 874, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mode_user_tabs_active.png", + "role": "icon_asset", + "sha256": "285e0d9765590e05987cf692978c80d94499aa378ed2c100a1fdf5b674009b2a" + }, + { + "bytes": 870, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mode_user_tabs_inactive.png", + "role": "icon_asset", + "sha256": "8ea7a669871d2102eb54dd1b32986d6f530a75f198c332bbd5ef5431379596ab" + }, + { + "bytes": 664, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/new_document.png", + "role": "icon_asset", + "sha256": "1895bd50a094e40b33cd8ece4430a0c50bb00c8e69ad7b0952d32b7ee2a62f4a" + }, + { + "bytes": 699, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/open_file.png", + "role": "icon_asset", + "sha256": "00324a3c5b28976f37b64f6c6a1dfbe64bc7b02161b9771e0158fa4cb27f75bd" + }, + { + "bytes": 252, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/pause.png", + "role": "icon_asset", + "sha256": "eacd9a4add2450ec14a369f3f08142c04afcd66c7e1547c688295981b67e82f2" + }, + { + "bytes": 244, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/pause_active.png", + "role": "icon_asset", + "sha256": "f2f6ba2f46add2c778d72ed7cf0f93a583ce4b1b81aa8a0733215bfc2b8b1fa8" + }, + { + "bytes": 570, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/play.png", + "role": "icon_asset", + "sha256": "131d3fcc5cb9622a758cdbd2485db76af7ff872565963ad219fd7a980f8e8dbf" + }, + { + "bytes": 1496, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/power_off.png", + "role": "icon_asset", + "sha256": "67d47a53b9feacb1a3553f22b3f4a6fa35e7db93cd900fbf005a3c5c10857a64" + }, + { + "bytes": 1490, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/power_on.png", + "role": "icon_asset", + "sha256": "716a2134c29e94b50be2c64c016a086c2c773cc03b6e9e807d304de59bc55f70" + }, + { + "bytes": 1409, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_0.png", + "role": "icon_asset", + "sha256": "cb6ee0843a238de24efac2ab4251206ce09974229248b3200a55c05296614504" + }, + { + "bytes": 1150, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_1.png", + "role": "icon_asset", + "sha256": "fee44da6d0727661426333ffa05ddb96075b06fb636a5717a945ee6de42b138b" + }, + { + "bytes": 1371, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_2.png", + "role": "icon_asset", + "sha256": "a6af7e4ba05fae86baa82f186418a8c85cca5c20e2e0235dab138e89e8fd3ce0" + }, + { + "bytes": 1444, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_3.png", + "role": "icon_asset", + "sha256": "e9e32fe068c3cc14c4f7df92699029ad0c957a10d7eedeb63e9dd68c093632a6" + }, + { + "bytes": 1312, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_4.png", + "role": "icon_asset", + "sha256": "5e0aa147d53d42dfbfb3e2e7c653857c5627b56100ed5317d7ebe36ba90d67d9" + }, + { + "bytes": 1407, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_5.png", + "role": "icon_asset", + "sha256": "b5da047221b30146e3b12d5678ba134413f4dce0141c50c57fd8039bc5b0bcba" + }, + { + "bytes": 1448, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_6.png", + "role": "icon_asset", + "sha256": "a37b43a65231a3a3b15f6e7a98fce399077b7ef44f2c04e0ba668edc49376eb2" + }, + { + "bytes": 1299, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_7.png", + "role": "icon_asset", + "sha256": "0dfddc66d8b36328134b0774824ec0a699dc31953c6e931304dabaabd14335d7" + }, + { + "bytes": 1422, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_a.png", + "role": "icon_asset", + "sha256": "17f8081f9663b1014c936477ffee772ec1b105ac4e2b58fc8e3ffb4b57d9b56b" + }, + { + "bytes": 1302, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_all.png", + "role": "icon_asset", + "sha256": "9f9eefcca0e60a216b54f9f38664f2ac4c423bef7bd63f3e066bf7f48b9c0264" + }, + { + "bytes": 1418, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_b.png", + "role": "icon_asset", + "sha256": "f2180a9eceaa679051b2ed4a8b2e6f2c7f981bec310f71791d704c52644371e4" + }, + { + "bytes": 1489, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_c.png", + "role": "icon_asset", + "sha256": "88666005b44946593fadcd5aee2922fc234b2282785a52465e53535513e462bf" + }, + { + "bytes": 1302, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_u.png", + "role": "icon_asset", + "sha256": "3e40848a914d44e5c1e45f5412a2e75f7457dfb4074900e8dbc69d1076284864" + }, + { + "bytes": 1460, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_v.png", + "role": "icon_asset", + "sha256": "6ffbf644db96120dda9a853d5513100b1a86c4f59620bec18699933ead1a3355" + }, + { + "bytes": 1611, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_w.png", + "role": "icon_asset", + "sha256": "c4d1d622a7c98c27c21c389cc7e0c8188d411c8281d98aea65979847fb6fe74d" + }, + { + "bytes": 1541, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_x.png", + "role": "icon_asset", + "sha256": "08eba16969be246e6c51b0620f3efbbd07ca6c6a9d387b0150a2851aa2ed4144" + }, + { + "bytes": 1355, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_y.png", + "role": "icon_asset", + "sha256": "44e8ce82430e04eac4b5ee40dd1cd86ce870fd9cc07df4cbe654549656951f6d" + }, + { + "bytes": 1346, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_z.png", + "role": "icon_asset", + "sha256": "d80221afb394d95f0c938d615fe61fc1b70cc160c506a1e1aea0640da86efde0" + }, + { + "bytes": 1553, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/refresh.png", + "role": "icon_asset", + "sha256": "df6b90ba86723c63b3e2c4166e37e7c968ece0f56d10fb69a4e77caec562b431" + }, + { + "bytes": 517, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/run_from_line.png", + "role": "icon_asset", + "sha256": "e50b24f3224c91b585c1078e442bfc818867d9f7576603cad9a7c9de3ea0d4c9" + }, + { + "bytes": 832, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/save.png", + "role": "icon_asset", + "sha256": "4d8b055c7f7f4aecd57087f57249d6dcee467ac7fef719573ba480fb052dc0a5" + }, + { + "bytes": 1126, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/save_as.png", + "role": "icon_asset", + "sha256": "4a5c951c7fab7aae322d908e73973a7eb4578f4a23e4c6f76073dc4fbbc38b4c" + }, + { + "bytes": 855, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/select_file.png", + "role": "icon_asset", + "sha256": "764739b04d00ad8975e8a9321335a7efc070f5081de4a6acfdec613c5c05f39b" + }, + { + "bytes": 950, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/skip_optional_active.png", + "role": "icon_asset", + "sha256": "1de49cdf444e6df346a44784e79c249be6a84e4416fd6e9402daa40eb00aedd7" + }, + { + "bytes": 1798, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/skip_optional_inactive.png", + "role": "icon_asset", + "sha256": "988cea3dc930cae67c63013763143fdbc37ab70b504696eefacb6c7892bd7193" + }, + { + "bytes": 1370, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/spindle_left.png", + "role": "icon_asset", + "sha256": "dc3334e8c67e3034d61b3a413b18849bbfbb771d6886147389203e8a9fba49c3" + }, + { + "bytes": 1352, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/spindle_left_on.png", + "role": "icon_asset", + "sha256": "318a265f635949ee854fe952b50eb159a10e93b517f475261f307150337c49a5" + }, + { + "bytes": 1380, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/spindle_right.png", + "role": "icon_asset", + "sha256": "688f6e828eca9a60aa1c8070750988cbc559fe100031e65bb1f6c46b575e2244" + }, + { + "bytes": 1359, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/spindle_right_on.png", + "role": "icon_asset", + "sha256": "2fd8498ed5d1b33fccdc69ebe8e8f8b25d173ecf420d07befc7f262dfccb3b48" + }, + { + "bytes": 1405, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/spindle_stop.png", + "role": "icon_asset", + "sha256": "b35c4bdcfeb58cc939fea0e404faf51381c2724fbae99d83ee909092ffa0fdb6" + }, + { + "bytes": 1096, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/spindle_stop_on.png", + "role": "icon_asset", + "sha256": "c9e4c1bfd2800b95c3ba643847778dc4489c4ed0dd0216a94038a87da943e958" + }, + { + "bytes": 668, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/step.png", + "role": "icon_asset", + "sha256": "c44c23fd300fb24bad87bbf8fe24a95d75911fe026a55936533a17aa989719db" + }, + { + "bytes": 169, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/stop.png", + "role": "icon_asset", + "sha256": "8b0efa7d8bda444203e5763a87457cf472148fb7c80ed9ea732686d812f1817d" + }, + { + "bytes": 1727, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/tool_axis_p.png", + "role": "icon_asset", + "sha256": "173210035b8296a2a3a67c6062c0dfad4aa7e4d076b6e2956bc0f5d30ca62dcb" + }, + { + "bytes": 1468, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/tool_axis_x.png", + "role": "icon_asset", + "sha256": "6f3bec85a774d08ec527fefee9ea48be2bce1d7b1e4858a2e0b257c966c2477a" + }, + { + "bytes": 1141, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/tool_axis_y.png", + "role": "icon_asset", + "sha256": "c5aaa1a93cecd57f442b7e2d2dc66b85c07e32866891f223d8ad00e088c293a1" + }, + { + "bytes": 1122, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/tool_axis_y_inv.png", + "role": "icon_asset", + "sha256": "248ba2629fc3b228da37ac2699d6268d4bc095d1c810d6d63114d71ba01f28e3" + }, + { + "bytes": 1120, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/tool_axis_z.png", + "role": "icon_asset", + "sha256": "c62c790f78901dbb43b33348f5444dc9055322666fe4b4ed75bf05082c290ad9" + }, + { + "bytes": 1786, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/toolpath.png", + "role": "icon_asset", + "sha256": "12854f1eb5560ada4f9d85b603a2f388fd9f135108e2e2e836d609af021ce478" + }, + { + "bytes": 1502, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/touch_a.png", + "role": "icon_asset", + "sha256": "d5651cbfba419bf3c9beb6ef4a5bcb9e2676c0391879ca0f77ec4ca068934cc0" + }, + { + "bytes": 1485, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/touch_b.png", + "role": "icon_asset", + "sha256": "517681ca216f0b512dbe09a59d8bf392cbe7c5de78dd5d185d94cea7a85f72f7" + }, + { + "bytes": 1548, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/touch_c.png", + "role": "icon_asset", + "sha256": "10feb99d756ccff00c69ab080d50b9043ea70b4e9519633e5bf4dea79ceb54a1" + }, + { + "bytes": 1079, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/touch_off.png", + "role": "icon_asset", + "sha256": "89f392ed8fe172b3b88414ecbfd0c1bb417c6b4efb5d7cb1813e2ed21859e84b" + }, + { + "bytes": 1354, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/touch_u.png", + "role": "icon_asset", + "sha256": "d48cac5c5175b05cd70a20b20690d68a01cb2e0d2a77fd71ed19cfeaa77b83e8" + }, + { + "bytes": 1549, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/touch_v.png", + "role": "icon_asset", + "sha256": "5d061649016cf184bdb3e556ba668117fa1afa5f3ecfbfc4dcd3d0b9734fe49e" + }, + { + "bytes": 1650, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/touch_w.png", + "role": "icon_asset", + "sha256": "3711582b30281e91502d03b70c9986f7c7fa44332a553efafbf7cfe321b8e799" + }, + { + "bytes": 1621, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/touch_x.png", + "role": "icon_asset", + "sha256": "1c972ce1b3bd9d9a41e4397aba1b9153f2cf86f600c9ecc01ff031cb9a9c8b37" + }, + { + "bytes": 1441, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/touch_y.png", + "role": "icon_asset", + "sha256": "63fad3cbab09551503ac466c0832695bcd87b6d8aaa33b7bab58bc9cac512a88" + }, + { + "bytes": 1422, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/touch_z.png", + "role": "icon_asset", + "sha256": "22f530b8b682083826cbf7b742bc8e72bff70a3cff06ee71dee32137f5986433" + }, + { + "bytes": 1692, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/translate_a.png", + "role": "icon_asset", + "sha256": "1854f833d5220ef80c68bc135617003029cdbec686a3dd1803825d04bf78f731" + }, + { + "bytes": 1561, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/translate_b.png", + "role": "icon_asset", + "sha256": "ecfa57baeee934c3102f7fb3bce5b4daee94d7b48df1abe1d1113c35da7b71ab" + }, + { + "bytes": 1683, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/translate_c.png", + "role": "icon_asset", + "sha256": "c9dd3072dc716b327f80e64a97986e2229b14d57781ad6bcca29a44c5cc53791" + }, + { + "bytes": 1497, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/translate_u.png", + "role": "icon_asset", + "sha256": "ad969a409de2e901cd3ea865ec7b87bfe930b61b074c657c9b40456ff65a66c3" + }, + { + "bytes": 1696, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/translate_v.png", + "role": "icon_asset", + "sha256": "7b89c25dd1ac91f73479e7621cd61a8df1ec065b8df73b1be36afc2494eb1024" + }, + { + "bytes": 1827, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/translate_w.png", + "role": "icon_asset", + "sha256": "f79b2c72a6cd595c11750fe85544068e7ce830f05181a6e6fdc9eb7a88f94b0d" + }, + { + "bytes": 1737, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/translate_x.png", + "role": "icon_asset", + "sha256": "6e6d136c9200d37e8fe5803a410f780ad03a9bf5758ebcb0efe503921fe43a55" + }, + { + "bytes": 1616, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/translate_y.png", + "role": "icon_asset", + "sha256": "fda8758e6e5e1d6d2381d5369f97070fd2a5c12565294bb38f75e9491a5c24ed" + }, + { + "bytes": 1564, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/translate_z.png", + "role": "icon_asset", + "sha256": "7e55e109c8e7c172f65ab5a3eddca51068df6efb082f01753b2c4dcdbc91d0eb" + }, + { + "bytes": 1134, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/unref_all.png", + "role": "icon_asset", + "sha256": "2ca027a0af65be7c81559575daf3c41770d559355825d4dd1152f92f9720c582" + }, + { + "bytes": 826, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/user_defined_folder.png", + "role": "icon_asset", + "sha256": "20696d7b28e273d0313aeeb91e30fb8e9d24143b109151696191ff74f25f9050" + }, + { + "bytes": 694, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/window_close.png", + "role": "icon_asset", + "sha256": "b1fd84a1eb380ed0d5bbe981ec5628aaa4a029b69b1aa34aa59ab45f4448a6e3" + }, + { + "bytes": 1556, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/zoom_in.png", + "role": "icon_asset", + "sha256": "948640c5b4b7bce9f91bde2322f21767c3111e17c3ee9cffb4ccd2864e456de6" + }, + { + "bytes": 1493, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/zoom_out.png", + "role": "icon_asset", + "sha256": "826fdd64a545de255f377fa54cdbe9c5b89b59b0d73d5abc232b71abbae53165" + }, + { + "bytes": 1841, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/status/dialog_information.png", + "role": "icon_asset", + "sha256": "6ee48b78d43aa857ab817d7753ccde7b3be7d4604ac86e341e323b354c30e478" + }, + { + "bytes": 1346, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/status/dialog_warning.png", + "role": "icon_asset", + "sha256": "057c8aaaeb5d0fc0a44f887964498ff6229c24dde7020ccaec273238dd6f7ba5" + }, + { + "bytes": 11357, + "path": "linuxcnc/share/gmoccapy/icons/material-light/LICENSE", + "role": "icon_asset", + "sha256": "58d1e17ffe5109a7ae296caafcadfdbe6a7d176f0bc4ab01e12a689b0499d8bd" + }, + { + "bytes": 366, + "path": "linuxcnc/share/gmoccapy/icons/material-light/NOTICE", + "role": "icon_asset", + "sha256": "1917e07ae29680da629688a7bbed3269cc81a2f8081176dfe16d08eb4a478c33" + }, + { + "bytes": 459, + "path": "linuxcnc/share/gmoccapy/icons/material-light/index.theme", + "role": "icon_asset", + "sha256": "bec9879db6d2651f8a41cff605903ea7dcd708c4a6243e47ef7c8ea5313630d2" + }, + { + "bytes": 1007, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/Submakefile", + "role": "implementation", + "sha256": "a2886508fc1a425a8962e69636ec0026ced9c6df02ea02eac9c5d39c2b23af07" + }, + { + "bytes": 0, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/__init__.py", + "role": "implementation", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + { + "bytes": 17827, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/__pycache__/dialogs.cpython-312.pyc", + "role": "implementation", + "sha256": "4ffa96ed9183d9ad18c25b70fa4143d63cf765c5f93ea23f822e2cf15a7e9b45" + }, + { + "bytes": 24189, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/__pycache__/getiniinfo.cpython-312.pyc", + "role": "implementation", + "sha256": "6e6840b7afd5fed9fb201837edcef7ce92f888aefabcd0299abfd23192f8f456" + }, + { + "bytes": 356463, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/__pycache__/gmoccapy.cpython-312.pyc", + "role": "implementation", + "sha256": "61085327c1006ccc556ac6ed0aa32df6ea18f02ac3d5f26beabb68f43a67a552" + }, + { + "bytes": 4328, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/__pycache__/icon_theme_helper.cpython-312.pyc", + "role": "implementation", + "sha256": "ef1c65ca30682821d1fd056645c86a4afd829103bdce798117d9756ee234ea2c" + }, + { + "bytes": 17674, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/__pycache__/notification.cpython-312.pyc", + "role": "implementation", + "sha256": "a76deccda9b9ab1c93b4a50092d788607086cb336dd29135a0f51dc00c8fbeea" + }, + { + "bytes": 3926, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/__pycache__/player.cpython-312.pyc", + "role": "implementation", + "sha256": "b1cb4541880861d1efd27eeaa4f4f78ae41b118a896eeef4922cb487220ea338" + }, + { + "bytes": 2353, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/__pycache__/preferences.cpython-312.pyc", + "role": "implementation", + "sha256": "8655fb41eb5e8fe8a74d24025902a1e0d3597291ffc53194cbd78baac9a54455" + }, + { + "bytes": 2263, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/__pycache__/widgets.cpython-312.pyc", + "role": "implementation", + "sha256": "b417e22d8df64eaf86981ccb1df225a8d8cc3ba2e8341d7d624661a388479316" + }, + { + "bytes": 10577, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/dialogs.py", + "role": "implementation", + "sha256": "045430bbb041acd2bdfff0594b0efb14f85d01ebcae452382670944c3192f768" + }, + { + "bytes": 19430, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/getiniinfo.py", + "role": "implementation", + "sha256": "fa93a8998a2a7701e2b822ef202d6e3d481f7b9c5b97fc82c41bded2896c9e03" + }, + { + "bytes": 486712, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.glade", + "role": "implementation", + "sha256": "60c38418b7fb8690cc8cd942e2b758782bb734ee458d34eb63a416ba084a2112" + }, + { + "bytes": 267992, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.py", + "role": "implementation", + "sha256": "2edc4d4689794ba26e6bfbad33e6d35a0b8d7c96f25878fdb76658e3fa18aff5" + }, + { + "bytes": 3249, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/icon_theme_helper.py", + "role": "implementation", + "sha256": "caf444318e1d6864f8257c5f3658d8657c164007ce54c5ec10cddd068317d8a0" + }, + { + "bytes": 14320, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/notification.py", + "role": "implementation", + "sha256": "81ee7e9262e3b633f506bde182918e12b196ddb655dfe980c7436e12c3b17bae" + }, + { + "bytes": 2630, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/player.py", + "role": "implementation", + "sha256": "82d150e2ae3b6a7aa67d056b3d5f002274b0362446ebe4782fc6c7872052b159" + }, + { + "bytes": 1617, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/preferences.py", + "role": "implementation", + "sha256": "6d09e9f38b7ab0feff2e436020c4a4a2db0f7126abb377ce08de05d41e46039d" + }, + { + "bytes": 92185, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/release_notes.txt", + "role": "implementation", + "sha256": "c9312be69232098f803121f34d4873e10b4c9e9a0ad37913c6ac7d81e8e0577e" + }, + { + "bytes": 1596, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/widgets.py", + "role": "implementation", + "sha256": "dbce55d80efcdee00e371e875983207c07facf29eca1805398d0286ef8877c02" + }, + { + "bytes": 62544, + "path": "linuxcnc/src/po/gmoccapy/bg.po", + "role": "translation", + "sha256": "58badb61def8b85ec7ae8853bc2253d201b40cb3322e759749f826135b313a15" + }, + { + "bytes": 54297, + "path": "linuxcnc/src/po/gmoccapy/cs.po", + "role": "translation", + "sha256": "e298bd255aae0660a0e4c8e46941cc766f73310d75bd56eb8c201a4450cb5f86" + }, + { + "bytes": 38218, + "path": "linuxcnc/src/po/gmoccapy/da.po", + "role": "translation", + "sha256": "104ac13f2ca27d5b3f75a789110ab8aaa0b74533ca97f7a5c4273665c25fbdd1" + }, + { + "bytes": 91367, + "path": "linuxcnc/src/po/gmoccapy/de.po", + "role": "translation", + "sha256": "df55417d669720d0b665d833f968d0ca3d9a3be26d186ef807db38fcc3c223e7" + }, + { + "bytes": 91198, + "path": "linuxcnc/src/po/gmoccapy/es.po", + "role": "translation", + "sha256": "6fa94ce0db4534417bb1f7b6cbe3dca41fa9a5f72fcd24ce7e946f45faf6a6f8" + }, + { + "bytes": 38243, + "path": "linuxcnc/src/po/gmoccapy/fi.po", + "role": "translation", + "sha256": "dc1cb2683ab07ede6087e6fbc070a9fc910dffc6b1688d164801498a006c9ee3" + }, + { + "bytes": 85880, + "path": "linuxcnc/src/po/gmoccapy/fr.po", + "role": "translation", + "sha256": "d618ca8f782916fe75f5fad7d7581748d2a8583fbae7d9e9ebf9b0496523f2a3" + }, + { + "bytes": 38245, + "path": "linuxcnc/src/po/gmoccapy/gmoccapy.pot", + "role": "translation", + "sha256": "27f29281c22455e402c6937d7a1d40e3c8d0f1a3f24e7f1fcc6c4bc299a6146d" + }, + { + "bytes": 89032, + "path": "linuxcnc/src/po/gmoccapy/hu.po", + "role": "translation", + "sha256": "e2bbcfb5801e65bce2bd459a97e4717666620cc807761e42f39e3a84b1d73a18" + }, + { + "bytes": 38218, + "path": "linuxcnc/src/po/gmoccapy/it.po", + "role": "translation", + "sha256": "ae571a9e40ec19c18837737db841492b1b8ec2751aea8d29d6addc5dc3c72d31" + }, + { + "bytes": 38243, + "path": "linuxcnc/src/po/gmoccapy/ja.po", + "role": "translation", + "sha256": "dc1cb2683ab07ede6087e6fbc070a9fc910dffc6b1688d164801498a006c9ee3" + }, + { + "bytes": 49393, + "path": "linuxcnc/src/po/gmoccapy/nb.po", + "role": "translation", + "sha256": "937f63ea9f9a16a0a9bd6895cce62b8952550052e4d0930ed26f08c167aba67a" + }, + { + "bytes": 86797, + "path": "linuxcnc/src/po/gmoccapy/pl.po", + "role": "translation", + "sha256": "cf5861ef6ed214f8e56ac61ff895b01150210f3e6997835dcfc0a635c5f90a52" + }, + { + "bytes": 38243, + "path": "linuxcnc/src/po/gmoccapy/pt_BR.po", + "role": "translation", + "sha256": "dc1cb2683ab07ede6087e6fbc070a9fc910dffc6b1688d164801498a006c9ee3" + }, + { + "bytes": 38520, + "path": "linuxcnc/src/po/gmoccapy/ro.po", + "role": "translation", + "sha256": "a19a49733f88b29f1763a54dc8bd17006ae5aa480f0c3c9a1767de1656afdf03" + }, + { + "bytes": 38218, + "path": "linuxcnc/src/po/gmoccapy/ru.po", + "role": "translation", + "sha256": "18543c0e4768d2f5109c236c6a7546b499b3598ffef35c0230e14778bfdcf759" + }, + { + "bytes": 55199, + "path": "linuxcnc/src/po/gmoccapy/sk.po", + "role": "translation", + "sha256": "4758aaea90a4dd090472ac25d235c7497a7c51781c2d8eb5fa9a4336e2ae3f5a" + }, + { + "bytes": 73921, + "path": "linuxcnc/src/po/gmoccapy/sr.po", + "role": "translation", + "sha256": "49a71c9c67062e33c8f42173a42228edfd9a05668842909e639d24f3125cf39d" + }, + { + "bytes": 38243, + "path": "linuxcnc/src/po/gmoccapy/sv.po", + "role": "translation", + "sha256": "dc1cb2683ab07ede6087e6fbc070a9fc910dffc6b1688d164801498a006c9ee3" + }, + { + "bytes": 44896, + "path": "linuxcnc/src/po/gmoccapy/tr.po", + "role": "translation", + "sha256": "d94dad977c6bf6ebc49ffa4ff09d58a9b6f9f5ac7981b0d8fdaacaabce2f6bdd" + }, + { + "bytes": 39125, + "path": "linuxcnc/src/po/gmoccapy/vi.po", + "role": "translation", + "sha256": "fdeeb94f78e1573ee64efb653827ef5d4fdeaaad0d86f2b30cb739e19720c345" + }, + { + "bytes": 56170, + "path": "linuxcnc/src/po/gmoccapy/zh_CN.po", + "role": "translation", + "sha256": "7fdd5f0567a6049441e77750c31a5929b579f87b762d70b7638fb1a2b081665c" + }, + { + "bytes": 38243, + "path": "linuxcnc/src/po/gmoccapy/zh_HK.po", + "role": "translation", + "sha256": "dc1cb2683ab07ede6087e6fbc070a9fc910dffc6b1688d164801498a006c9ee3" + }, + { + "bytes": 38243, + "path": "linuxcnc/src/po/gmoccapy/zh_TW.po", + "role": "translation", + "sha256": "dc1cb2683ab07ede6087e6fbc070a9fc910dffc6b1688d164801498a006c9ee3" + } + ], + "role_counts": { + "documentation": 2, + "documentation_asset": 27, + "icon_asset": 973, + "implementation": 28, + "installed_ui_asset": 1, + "simulation_asset": 16, + "simulation_ini": 29, + "simulation_resource": 69, + "simulation_runtime_data": 64, + "translation": 24 + }, + "schema": "gmoccapy-file-inventory.v1", + "scope": [ + "linuxcnc/configs/sim/gmoccapy/**", + "linuxcnc/src/emc/usr_intf/gmoccapy/**", + "linuxcnc/lib/python/gmoccapy/**", + "linuxcnc/share/gmoccapy/**", + "linuxcnc/src/po/gmoccapy/**", + "linuxcnc/docs/src/gui/gmoccapy.adoc", + "linuxcnc/docs/man/man1/gmoccapy.1", + "linuxcnc/docs/src/gui/images/gmoccapy_*", + "linuxcnc/docs/src/user/images/gmoccapy_*" + ] +} diff --git a/doc-g/gmoccapy-file-inventory.md b/doc-g/gmoccapy-file-inventory.md new file mode 100644 index 0000000..a0bbe44 --- /dev/null +++ b/doc-g/gmoccapy-file-inventory.md @@ -0,0 +1,18 @@ +# GMOCCAPY 文件清单 + +清单范围内共 `1233` 个文件;每项包含相对路径、角色、字节数和 SHA-256。 + +| 角色 | 数量 | +|---|---:| +| `documentation` | 2 | +| `documentation_asset` | 27 | +| `icon_asset` | 973 | +| `implementation` | 28 | +| `installed_ui_asset` | 1 | +| `simulation_asset` | 16 | +| `simulation_ini` | 29 | +| `simulation_resource` | 69 | +| `simulation_runtime_data` | 64 | +| `translation` | 24 | + +完整逐文件数据见 [`gmoccapy-file-inventory.json`](gmoccapy-file-inventory.json)。 diff --git a/doc-g/gmoccapy-homed.png b/doc-g/gmoccapy-homed.png new file mode 100644 index 0000000..6674584 Binary files /dev/null and b/doc-g/gmoccapy-homed.png differ diff --git a/doc-g/gmoccapy-homing.png b/doc-g/gmoccapy-homing.png new file mode 100644 index 0000000..b8c11a5 Binary files /dev/null and b/doc-g/gmoccapy-homing.png differ diff --git a/doc-g/gmoccapy-hover-auto.png b/doc-g/gmoccapy-hover-auto.png new file mode 100644 index 0000000..bf349b4 Binary files /dev/null and b/doc-g/gmoccapy-hover-auto.png differ diff --git a/doc-g/gmoccapy-important-changes-v2.png b/doc-g/gmoccapy-important-changes-v2.png new file mode 100644 index 0000000..1bc2761 Binary files /dev/null and b/doc-g/gmoccapy-important-changes-v2.png differ diff --git a/doc-g/gmoccapy-important-changes.png b/doc-g/gmoccapy-important-changes.png new file mode 100644 index 0000000..fcb1d5e Binary files /dev/null and b/doc-g/gmoccapy-important-changes.png differ diff --git a/doc-g/gmoccapy-load-file-page.png b/doc-g/gmoccapy-load-file-page.png new file mode 100644 index 0000000..c89b80d Binary files /dev/null and b/doc-g/gmoccapy-load-file-page.png differ diff --git a/doc-g/gmoccapy-open-file-icon.png b/doc-g/gmoccapy-open-file-icon.png new file mode 100644 index 0000000..8379bbd Binary files /dev/null and b/doc-g/gmoccapy-open-file-icon.png differ diff --git a/doc-g/gmoccapy-popup.png b/doc-g/gmoccapy-popup.png new file mode 100644 index 0000000..38dfc26 Binary files /dev/null and b/doc-g/gmoccapy-popup.png differ diff --git a/doc-g/gmoccapy-program-loaded.png b/doc-g/gmoccapy-program-loaded.png new file mode 100644 index 0000000..e9cfcb1 Binary files /dev/null and b/doc-g/gmoccapy-program-loaded.png differ diff --git a/doc-g/gmoccapy-ui-load-confirmed.png b/doc-g/gmoccapy-ui-load-confirmed.png new file mode 100644 index 0000000..ba5c2a5 Binary files /dev/null and b/doc-g/gmoccapy-ui-load-confirmed.png differ diff --git a/doc-g/root-current.png b/doc-g/root-current.png new file mode 100644 index 0000000..e5283e4 Binary files /dev/null and b/doc-g/root-current.png differ diff --git a/doc-rtcp/5axis-rtcp-running.png b/doc-rtcp/5axis-rtcp-running.png new file mode 100644 index 0000000..e5d9a81 Binary files /dev/null and b/doc-rtcp/5axis-rtcp-running.png differ diff --git a/doc-rtcp/5axis-rtcp-shortcut.md b/doc-rtcp/5axis-rtcp-shortcut.md new file mode 100644 index 0000000..629fe0a --- /dev/null +++ b/doc-rtcp/5axis-rtcp-shortcut.md @@ -0,0 +1,62 @@ +# 五轴 RTCP 案例快捷方式 + +快捷方式:[`../run-5axis-rtcp.sh`](../run-5axis-rtcp.sh) + +默认执行: + +```bash +./run-5axis-rtcp.sh +``` + +默认案例是: + +```text +linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini +``` + +它使用 `XYZAC` 五轴表旋转/倾斜(TRT)拓扑、`xyzac-trt-kins` 和 Vismach `xyzac-trt-gui`。默认演示程序是: + +```text +linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc +``` + +该顶层演示调用 `remap_subs/xyzac_switchkins_sub.ngc`;其螺旋插补子程序 `remap_subs/helix_ac.ngc` 使用: + +```gcode +M428 ;TCP:xyzac +``` + +`M428` 通过 remap 将 `motion.switchkins-type` 切换到 XYZAC TCP/RTCP 运动学;`helix_ac.ngc` 在需要机床坐标定位时使用 `M429` 切回 identity,再用 `M428` 进入 TCP。配置的 `M430` 进入 userk。AXIS 右侧的 `TCP:XYZAC` 按钮也提供同一切换入口。 + +## XYZBC 变体 + +快捷方式接受可选配置名: + +```bash +./run-5axis-rtcp.sh xyzbc-trt.ini +``` + +该变体使用 `XYZBC` 和 `xyzbc-trt-kins`,默认程序为 `demos/xyzbc_switchkins.ngc`。 + +## 启动证据 + +![五轴 XYZAC RTCP 案例运行](5axis-rtcp-running.png) + +实测启动结果: + +- AXIS 标题:`xyzac_switchkins.ngc - AXIS 2.10.0~pre1 on sim-xyzac-trt-kins (switchkins)`。 +- 右侧 `SWITCHKINS` 面板显示 `TCP:XYZAC`。 +- Vismach 预览显示五轴机床和多轴刀具轨迹。 +- LinuxCNC 状态接口返回 `file=./demos/xyzac_switchkins.ngc`,`COORDINATES=XYZAC`。 +- 当前环境使用 POSIX non-realtime 回退;这验证的是仿真配置和 RTCP 路径,不是实时硬件性能。 + +## 来源依据 + +- `linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini` +- `linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc` +- `linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/xyzac_switchkins_sub.ngc` +- `linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_ac.ngc` +- `linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc` +- `linuxcnc/src/emc/kinematics/xyzac-trt-kins.c` +- `linuxcnc/src/emc/kinematics/trtfuncs.c` +- `linuxcnc/docs/src/motion/5-axis-kinematics.adoc` diff --git a/doc-rtcp/README.md b/doc-rtcp/README.md new file mode 100644 index 0000000..89cde8f --- /dev/null +++ b/doc-rtcp/README.md @@ -0,0 +1,51 @@ +# 五轴 RTCP 文档集 + +接续入口:[`../nextTask-rtcp.md`](../nextTask-rtcp.md) + +持续执行提示词:[`xyzac-trt-autonomous-execution-prompt.md`](xyzac-trt-autonomous-execution-prompt.md) + +本目录从 `doc-g` 集中迁移五轴机床、XYZAC/XYZBC TRT、switchkins、RTCP 和控制面板数据流资料。原 `doc-g` 文件保留不变;本目录是后续五轴案例分析的独立入口。 + +## 快速入口 + +- [五轴 RTCP 快捷方式](5axis-rtcp-shortcut.md) +- [控制面板功能、数据流与控制流](gmoccapy-control-panel-data-control-flow.md) +- [`xyzac-trt.ini` 控制面板与 Web/WASM 设计基础](xyzac-trt-control-panel-web-wasm-design.md) +- [`xyzac-trt.ini` Web/WASM 实施计划与里程碑](xyzac-trt-web-wasm-implementation-plan.md) +- [`xyzac-trt.ini` 源码对标与 WASM 唯一权威合同](xyzac-trt-web-wasm-source-parity-contract.md) +- [GMOCCAPY 运行时和面板分析](gmoccapy-analysis.md) +- [五轴 RTCP 运行截图](5axis-rtcp-running.png) + +## 运行 + +```bash +./run-5axis-rtcp.sh +./run-5axis-rtcp.sh xyzbc-trt.ini +``` + +快捷方式仍位于仓库根目录;文档中的 `../run-5axis-rtcp.sh` 链接指向同一入口。 + +默认案例: + +```text +linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini +``` + +## 文档边界 + +- `5axis-rtcp-shortcut.md`:案例入口、XYZAC/XYZBC 变体、M428/M429 和启动证据。 +- `gmoccapy-control-panel-data-control-flow.md`:从控制面板控件到 LinuxCNC TASK/motion/HAL/Vismach 的完整数据流和控制流,其中第 8 节是五轴 RTCP 专章。 +- `gmoccapy-analysis.md`:GMOCCAPY 系统运行时版本、启动提示和面板行为;作为五轴界面分析的背景材料。 +- `gmoccapy-file-inventory.*`:GMOCCAPY 相关配置、实现、资源和图标的逐文件清单。 + +## 来源 + +五轴核心来源保持在 LinuxCNC 源目录: + +```text +linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/ +linuxcnc/src/emc/kinematics/xyzac-trt-kins.c +linuxcnc/src/emc/kinematics/xyzbc-trt-kins.c +linuxcnc/src/emc/kinematics/trtfuncs.c +linuxcnc/docs/src/motion/5-axis-kinematics.adoc +``` diff --git a/doc-rtcp/gmoccapy-analysis.md b/doc-rtcp/gmoccapy-analysis.md new file mode 100644 index 0000000..d01d651 --- /dev/null +++ b/doc-rtcp/gmoccapy-analysis.md @@ -0,0 +1,170 @@ +# GMOCCAPY 分析与加载测试 + +更新时间:2026-08-25 + +## 结论 + +“没有看到加载程序按钮”不是按钮缺失,而是首次启动提示和 GMOCCAPY 的模式门控共同造成的视觉结果: + +1. 首次启动会弹出模态的 `Important change(s)` 窗口。该窗口覆盖主界面并阻止底层点击;用户截图中的右侧 `X` 是关闭按钮,底部复选框是 `Don't show this again`。 +2. 加载按钮只属于 AUTO 页面按钮组,不属于 MANUAL/JOG 页面。源码将它声明为 `btn_load`,提示为 `Load a new program`,图标为 `img_open`。 +3. AUTO 模式还受机器状态和 homing 门控。`gmoccapy.py` 在未满足状态时会禁用 `rbt_auto`,并提示 `It is not possible to change to Auto Mode at the moment`。 +4. 关闭首次提示、进入 AUTO 后,点击文件夹/打开文件图标会进入文件选择页。当前 `gmoccapy.ini` 的 `PROGRAM_PREFIX = ../../nc_files/` 解析到 `linuxcnc/nc_files`。 + +## 用户截图分析 + +![首次启动提示](gmoccapy-important-changes.png) + +用户提供的图片尺寸为 `697 x 837`,内容是 GMOCCAPY 3.5.x 的版本变更提示: + +- LinuxCNC 2.10/GMOCCAPY 3.5.0 不再在换刀后自动保留 G43;需要通过 REMAP 实现自动重新激活。 +- 3.5.1 的工具表和偏置页默认使用计算器输入,可在设置或按钮中改变。 +- MDI 和 G-code 编辑模式新增调用计算器的按钮。 +- `release notes` 是橙色链接;右下方复选框用于永久隐藏该提示。 + +这张提示不是文件选择器,也不是加载失败信息。应先关闭它,再操作主界面。 + +### 新截图的源码逐项对照 + +![用户提供的最新提示截图](gmoccapy-important-changes-v2.png) + +这张截图与前一张内容一致,尺寸为 `697 x 837`,SHA-256 为 `df7322c30bcb6af131591a04b11cad24e7b6d186beaff83059fcfd8ffbae2d1b`。截图中的每一块文字都能在当前系统安装的 `/usr/bin/gmoccapy` 中找到: + +| 截图区域 | 源码证据 | 含义 | +|---|---|---| +| `Important change(s)` 标题 | `/usr/bin/gmoccapy:557-560` | `_startup_message()` 建立启动提示标题;注释要求新增消息只能追加,不能删除旧消息,否则隐藏索引会错位。 | +| 3.5.0 G43 提示 | `/usr/bin/gmoccapy:561-563` | GMOCCAPY 3.5.0 不再承诺换刀后自动保留 G43;想自动恢复必须使用 REMAP,示例在 GMOCCAPY 仿真配置中。 | +| 3.5.1 计算器提示 | `/usr/bin/gmoccapy:564-565` | 工具表和偏置页默认启用计算器输入;设置或页面按钮可以关闭;MDI 和 G-code 编辑页也增加了计算器按钮。 | +| `release notes` 链接 | `/usr/bin/gmoccapy:570-573` | 以 Pango markup 拼接 LinuxCNC 官方 release notes URL,并通过通知组件显示。点击它会打开文档,不会关闭提示。 | +| `Don't show this again` | `notification.py:151-155` | `show_checkbox=True` 时创建 GTK `CheckButton`;它不是普通说明文字,而是真正影响后续启动行为的复选框。 | +| 右侧 `X` | `notification.py:156-164` | 创建名为 `notification_close` 的 48x48 关闭按钮;点击后删除该消息,并把复选框状态发回 GMOCCAPY。 | + +### 弹窗什么时候出现 + +系统运行时在 GUI 初始化和周期任务准备完成后,于 `/usr/bin/gmoccapy:519` 调用 `_startup_message()`。它读取偏好项 `hide_startup_messsage`(注意源码中确实有三个 `s` 的拼写): + +```python +hide_message = self.prefs.getpref("hide_startup_messsage", 0, int) +if hide_message < len(messages): + ... + self.notification.add_message(message, INFO_ICON, show_checkbox=True) +``` + +当前消息数组有两项,因此默认值 `0` 会显示两项。关闭时如果复选框被勾选,`/usr/bin/gmoccapy:6241-6242` 将 `self.num`(当前为 `2`)写回 `hide_startup_messsage`。下次启动判断 `2 < 2` 为假,提示不再出现。普通点击 `X` 不勾选复选框时,只删除本次通知,下次仍会显示。 + +### 版本边界:截图运行时与仓库锁定源不同 + +这是本次分析中最重要的来源边界: + +- 截图对应的实际运行程序是 `/usr/bin/gmoccapy`,其中 `_RELEASE = "3.5.2"`,并包含 `_startup_message()`、3.5.0/3.5.1 文本和隐藏偏好逻辑。 +- 仓库锁定源是 `linuxcnc/VERSION = 2.10.0~pre0`;`linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.py:79` 的版本为 `3.4.3`,该文件没有 `_startup_message()` 实现,也没有截图中的 3.5.0/3.5.1 文本。 +- 本地启动日志曾显示 `LinuxCNC 2.10.0~pre1` 和 `gmoccapy 3.5.2`,与截图完全一致。因此这张截图是系统安装包的运行时证据,不应反向宣称锁定仓库 2.10.0~pre0/3.4.3 源码已经包含该功能。 + +已记录的运行时文件哈希: + +```text +/usr/bin/gmoccapy 11e7aee9216d24e4cc41018306f2541845bca9a9d6e16c38580f3ede9cca8d4d +/usr/share/gmoccapy/gmoccapy.glade 5fdc1557b02a716d30414fe739614fcd7c1d14cbe2e0a4c202c567a60b460adb +/usr/lib/python3/dist-packages/gmoccapy/notification.py + e0317fea738745f480c79d1f690bc52e88cc7f81bb4d14fa09c8c7196afb4e2f +``` + +### 用户应如何处理 + +1. 只想本次继续操作:点击右侧 `X`,不要勾选复选框。 +2. 不想以后重复看到:先勾选 `Don't show this again`,再点击 `X`。 +3. 想查看变更依据:点击 `release notes`,但这需要浏览器/网络或本地文档可用。 +4. 使用 G43 的程序:不要仅依赖界面自动行为;在 AUTO 程序中按机床配置和 REMAP 约定明确处理刀具长度补偿,并在正式加工前验证工具表和偏置。 + +## 实际界面证据 + +### 未加载状态 + +![未加载程序](gmoccapy-before-load.png) + +主界面顶部显示 `No Program loaded`。右侧竖向按钮中第三个为 AUTO 模式图标;在 MANUAL 页面时,AUTO 页面里的 `Load a new program` 不会显示在当前按钮组。 + +### 文件选择页 + +![加载程序文件选择页](gmoccapy-load-file-page.png) + +这张截图是实际运行 GMOCCAPY 后进入的文件选择页。页面显示 `gcmc_lib`、`macros`、`ngcgui_lib` 等目录以及 `3D_Chips.ngc`、`3dtest.ngc` 等程序。底部右侧绿色对勾是确认选择,右下黄色回退箭头是返回。 + +进入这张页面的完整点击链是: + +1. 关闭首次 `Important change(s)` 模态提示。 +2. 在主界面右侧点击第三个模式图标,进入 AUTO;源码控件为 `rbt_auto`。 +3. 等待 AUTO 按钮组出现,在其中点击打开文件图标;源码控件为 `btn_load`,tooltip 为 `Load a new program`。 +4. `on_btn_load_clicked()` 将按钮页切换到文件选择页;此时才会看到本截图中的文件网格。 +5. 选中 `.ngc` 文件后点击底部绿色对勾,源码控件为 `btn_select`。 + +因此,文件网格不是主界面的固定按钮,也不是 MDI 入口;在 MANUAL/JOG 页面直接寻找它不会找到。 + +### 加载后的程序 + +![加载 3dtest.ngc 后](gmoccapy-program-loaded.png) + +通过 LinuxCNC 的 `command.program_open()` 加载: + +```text +/home/mes006/linuxcncWebWASM/linuxcnc/nc_files/3dtest.ngc +``` + +加载成功的证据是: + +- 顶部由 `No Program loaded` 变成完整程序路径; +- 预览区出现 G-code 刀具轨迹; +- `linuxcnc.stat().file` 返回上述路径; +- `interp_state` 保持空闲,加载本身不会自动运行程序。 + +## 源码与界面映射 + +| 层 | 文件/符号 | 结论 | +|---|---|---| +| 主逻辑 | `linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.py` | `on_btn_load_clicked()` 切到文件选择页;`on_IconFileSelection1_selected()` 调用 `hal_action_open.load_file(path)`。 | +| 加载按钮 | `btn_load` / `img_open` | tooltip 是 `Load a new program`,只在 AUTO 按钮页 `hbtb_auto`。 | +| 运行按钮 | `btn_run` / `img_run` | tooltip 是 `Run the loaded program`;加载后仍需手动运行。 | +| 文件确认 | `btn_select` / `img_select` | tooltip 是 `select the highlighted file and return the path`。 | +| 返回 | `btn_back_file_load` / `img_back_file_load` | 关闭文件选择页但不返回路径。 | +| 文件资源 | `linuxcnc/lib/python/gladevcp/iconview.py` 及 GMOCCAPY 初始化 | 读取 `PROGRAM_PREFIX`,按配置扩展名展示文件和目录。 | +| 首次提示 | GMOCCAPY preferences/release-notes 逻辑 | 模态提示优先于主界面,必须先关闭。 | + +## 配置与资源分析 + +默认配置为 `linuxcnc/configs/sim/gmoccapy/gmoccapy.ini`: + +- `[DISPLAY] DISPLAY = gmoccapy`:选择 GMOCCAPY GUI。 +- `[DISPLAY] PROGRAM_PREFIX = ../../nc_files/`:从配置目录解析到 `linuxcnc/nc_files`。 +- `[RS274NGC] PARAMETER_FILE = sim.var`:仿真参数文件。 +- `[RS274NGC] SUBROUTINE_PATH = macros`:宏和子程序搜索路径。 +- `[EMCIO] TOOL_TABLE = tool.tbl`:工具表。 +- `[HAL]` 加载 `core_sim.hal`、`spindle_sim.hal`、`simulated_home.hal`,并在 GUI 启动后加载 `gmoccapy_postgui.hal`。 + +`configs/sim/gmoccapy` 不是单一案例,而是一组配置族,包含标准三轴、四轴、XYZAB/XYZAC/XYZCW、多轴、侧面板、消息、工具传感器、用户页、等离子和车床配置。完整逐文件路径与哈希见 [文件清单](gmoccapy-file-inventory.md)。 + +## 运行环境与限制 + +- 启动入口:[`../run-gmoccapy.sh`](../run-gmoccapy.sh),默认执行 `gmoccapy.ini`。 +- 实际 GUI 进程:`/usr/bin/python3 /usr/bin/gmoccapy -ini .../gmoccapy.ini`。 +- 当前环境没有实时内核,LinuxCNC 日志明确回退到 POSIX non-realtime;这不影响本次“加载和预览”验证,但不等同于实时硬件运行验证。 +- `simulated_home.hal` 的共享 home switch 在本次手动尝试中报告 `Cannot home while shared home switch is closed j=2`,因此 AUTO 模式按钮可能保持禁用。加载程序本身仍可通过 GUI 文件页/API 验证。 +- 加载和运行是两个动作:`program_open` 只读入程序并生成预览;需要 `AUTO` 页面中的 Run 按钮或 `R` 快捷键才会执行。 + +## 推荐操作顺序 + +1. 启动 `./run-gmoccapy.sh`。 +2. 关闭首次 `Important change(s)` 提示;可勾选 `Don't show this again`。 +3. 确认急停复位、机器上电,并按配置完成 homing;否则 AUTO 可能被门控。 +4. 点击右侧 AUTO 图标,进入 AUTO 按钮页。 +5. 点击带打开文件/文件夹图标的 `Load a new program`。 +6. 选择 `linuxcnc/nc_files` 下的 `.ngc` 文件,点击底部绿色对勾。 +7. 检查顶部路径和预览轨迹,再使用 Run;不要把加载误认为已经执行。 + +## 证据文件 + +- `gmoccapy-important-changes.png`:用户原始提示截图。 +- `gmoccapy-before-load.png`:未加载程序。 +- `gmoccapy-after-popup-close.png`:关闭提示后的主界面。 +- `gmoccapy-load-file-page.png`:实际文件选择页。 +- `gmoccapy-program-loaded.png`:加载后的程序和轨迹。 +- `gmoccapy-file-inventory.json`:逐文件 SHA-256 清单。 diff --git a/doc-rtcp/gmoccapy-before-load.png b/doc-rtcp/gmoccapy-before-load.png new file mode 100644 index 0000000..64e5c8c Binary files /dev/null and b/doc-rtcp/gmoccapy-before-load.png differ diff --git a/doc-rtcp/gmoccapy-control-panel-data-control-flow.md b/doc-rtcp/gmoccapy-control-panel-data-control-flow.md new file mode 100644 index 0000000..7751fef --- /dev/null +++ b/doc-rtcp/gmoccapy-control-panel-data-control-flow.md @@ -0,0 +1,323 @@ +# GMOCCAPY 控制面板功能、数据流与控制流 + +更新时间:2026-08-25 + +本文是后续分析 GMOCCAPY 控制面板的总入口。它把普通三轴 `gmoccapy.ini` 和五轴 XYZAC RTCP 案例放在同一套模型中,区分 UI 控件、GMOCCAPY Python handler、LinuxCNC command/status、TASK/motion、HAL 和 Vismach 的责任边界。 + +## 1. 范围与版本边界 + +| 项目 | 当前工作区/运行时 | +|---|---| +| 仓库源码 | `linuxcnc/VERSION = 2.10.0~pre0` | +| 仓库 GMOCCAPY 源码 | `linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.py`,`_RELEASE = 3.4.3` | +| 实际系统 GUI | `/usr/bin/gmoccapy`,运行时版本 `3.5.2`,系统 LinuxCNC `2.10.0~pre1` | +| 普通面板入口 | [`run-gmoccapy.sh`](../run-gmoccapy.sh),默认 `configs/sim/gmoccapy/gmoccapy.ini` | +| 五轴 RTCP 入口 | [`run-5axis-rtcp.sh`](../run-5axis-rtcp.sh),默认 XYZAC TRT switchkins | +| 发布/仿真边界 | POSIX non-realtime 仿真;不等同于实时硬件验证 | + +截图中的 `Important change(s)` 弹窗来自系统 GMOCCAPY 3.5.2,不存在于仓库 3.4.3 源文件中;两套来源不能混为一个源码版本。详细证据见 [GMOCCAPY 分析报告](gmoccapy-analysis.md)。 + +## 2. 总体架构 + +```text +快捷方式 / linuxcnc -r CASE.ini + │ + ▼ +LinuxCNC 启动器与 INI 解析 + │ + ├── linuxcncsvr / NML 状态与命令通道 + ├── milltask / RS274NGC interpreter / task mode + ├── motmod + kinematics / fixed servo cycle + ├── HAL files / HALUI / simulated devices + └── DISPLAY=gmoccapy 或 DISPLAY=axis + │ + ▼ + GMOCCAPY Gtk/Glade 控制面板 + │ + ┌─────────┴─────────┐ + │ │ + 用户点击/键盘/HAL linuxcnc.stat/HAL status + │ ▲ + ▼ │ + Python handler ── command ─┴── TASK/motion/HAL feedback + │ + ├── 模式/按钮页切换 + ├── 程序加载/预览 + ├── AUTO 运行/暂停/停止/单步 + ├── MDI 命令 + └── homing、tool、offset、spindle、coolant +``` + +GMOCCAPY 不是运动学计算器。它负责把操作员动作转换为 LinuxCNC command,并把 LinuxCNC status/HAL status 投影回界面;真正的解释器、轨迹规划、逆解/正解和关节命令由 LinuxCNC runtime 完成。 + +## 3. 启动控制流 + +### 3.1 快捷方式层 + +`run-gmoccapy.sh` 和 `run-5axis-rtcp.sh` 都遵循相同模式: + +1. 计算仓库绝对路径,避免从任意工作目录启动时相对路径漂移。 +2. 校验 INI、演示程序、LinuxCNC launcher 是否存在。 +3. 进入 LinuxCNC 根目录。 +4. 执行 `/usr/bin/linuxcnc -r CASE.ini`,保留终端诊断。 + +五轴快捷方式额外检查 RTCP 子程序中确实存在 `M428`,并支持 `xyzac-trt.ini` 与 `xyzbc-trt.ini` 两个变体。 + +### 3.2 INI 到进程 + +以普通 GMOCCAPY 为例: + +```text +[DISPLAY] DISPLAY=gmoccapy +[TASK] TASK=milltask +[HAL] core_sim.hal + spindle_sim.hal + simulated_home.hal +[EMCIO] TOOL_TABLE=tool.tbl +[RS274NGC] PARAMETER_FILE=sim.var, SUBROUTINE_PATH=macros +[KINS] trivkins coordinates=xyz +``` + +启动器随后创建 `linuxcncsvr`、`milltask`、`halui` 和 GMOCCAPY。GMOCCAPY 进程通过 `-ini` 得到同一个 INI 路径,不能自行替代 TASK/motion/HAL。 + +### 3.3 GMOCCAPY 初始化顺序 + +仓库源码 `gmoccapy.py` 的主初始化顺序为: + +1. 解析 `-user_mode`、`-logo` 参数(约 `243-270` 行)。 +2. 读取 INI(`_get_ini_data()`,约 `272-275` 行)。 +3. 读取偏好文件(`_get_pref_data()`)。 +4. 动态创建 DRO、home、touch-off、jog、macro 等控件(约 `280-305` 行)。 +5. 建立 GMOCCAPY HAL pins(约 `307` 行)。 +6. 连接 Glade signals(约 `315-320` 行)。 +7. 显示主窗口(约 `324-325` 行)。 +8. 初始化主题、G-code preview、kinematics view、offset/tool editor、keyboard 和文件选择器(约 `327-342` 行)。 + +系统 3.5.2 运行时在 GUI 初始化后额外调用 `_startup_message()`,生成版本提示弹窗;它属于安装包新增功能,不属于仓库 3.4.3 初始化链。 + +## 4. 控制面板模式和按钮门控 + +### 4.1 模式按钮 + +Glade 中的主要模式控件: + +| 控件 | 作用 | handler/状态 | +|---|---|---| +| `rbt_manual` | MANUAL/JOG | `on_rbt_manual_pressed()` 发出 `MODE_MANUAL` | +| `rbt_mdi` | MDI | `on_rbt_mdi_pressed()` 发出 `MODE_MDI` | +| `rbt_auto` | AUTO | `on_rbt_auto_pressed()` 发出 `MODE_AUTO` | +| `tbtn_setup` | 设置页 | 进入设置前强制 MANUAL,并禁用模式按钮 | +| `tbtn_user_tabs` | 用户页 | 切换主 notebook 页面 | + +`on_hal_status_mode_auto()` 在收到 HAL status 后将主页面切回 page 0,把按钮 notebook 切到 `_BB_AUTO`,并将 jog notebook 切到 AUTO 页面(约 `2804-2824` 行)。因此“点击 AUTO 图标”与“看到 AUTO 按钮组”是同一个状态转换的两个可观察结果。 + +### 4.2 急停、上电、homing 门控 + +`on_tbtn_setup_toggled()` 和 HAL status handler 根据以下条件设置按钮敏感度: + +```text +ESTOP → manual/mdi/auto 均禁用 +ON + 未 homed → 只允许 manual +ON + all_homed 或 NO_FORCE_HOMING → manual/mdi/auto 全部可用 +``` + +对应仓库源码约为 `3793-3808` 行。未满足条件时,点击 AUTO 会被 `on_hal_status_mode_auto()` 拒绝,显示 `It is not possible to change to Auto Mode at the moment`,并回到 MANUAL。 + +这解释了为什么控制面板可能“没有加载按钮”:加载按钮不在 MANUAL 页面,而且 AUTO 页面本身可能因状态门控没有激活。 + +## 5. G-code 加载数据流 + +### 5.1 控件链 + +```text +rbt_auto + │ on_hal_status_mode_auto() + ▼ +hbtb_auto / _BB_AUTO + │ + │ btn_load(图标 img_open,tooltip=Load a new program) + │ on_btn_load_clicked() + ▼ +_BB_LOAD_FILE + IconFileSelection1 + │ + │ 用户选中路径 + │ btn_select / IconFileSelection1_selected + ▼ +hal_action_open.load_file(path) + ▼ +LinuxCNC task/interpreter + preview/status + ▼ +ntb_preview page 0 + ntb_button _BB_AUTO + stat.file +``` + +### 5.2 打开文件界面 + +`on_btn_load_clicked()`(`gmoccapy.py:5046-5078`)执行: + +1. `ntb_button.set_current_page(_BB_LOAD_FILE)`。 +2. `ntb_preview.set_current_page(3)`。 +3. 打开 full-size preview。 +4. `_show_iconview_tab(True)`。 +5. 刷新 `IconFileSelection1` 文件列表。 +6. 暂时禁用 MANUAL、MDI 和设置按钮,避免文件选择过程中切换模式。 + +文件选择器在 `_init_IconFileSelection()` 和 `_init_file_to_load()` 中读取 `PROGRAM_PREFIX` 与 `[FILTER] PROGRAM_EXTENSION`。普通案例 `PROGRAM_PREFIX = ../../nc_files/` 最终指向仓库的 `linuxcnc/nc_files`。 + +### 5.3 确认文件 + +`on_IconFileSelection1_selected()`(`gmoccapy.py:5114-5125`)执行: + +1. 将选中的 `path` 交给 `hal_action_open.load_file(path)`。 +2. 恢复 preview page 0。 +3. 关闭 full-size preview 和 icon view。 +4. 把按钮 notebook 切回 `_BB_AUTO`。 +5. 重新启用 MANUAL、MDI 和设置按钮。 + +这一步是“加载程序”,不是“运行程序”。运行还需要 `btn_run`/`AUTO_RUN`;源码键盘 handler 将 `R` 映射为运行、`P` 映射为暂停、`S` 映射为恢复。 + +### 5.4 启动时自动加载 + +`on_window1_show()` 会读取偏好项 `open_file`(约 `2920-2924` 行)。如果用户在设置页指定“启动时加载文件”,GMOCCAPY 会在窗口显示后直接调用 `hal_action_open.load_file(file)`。这条路径绕过手动点击文件选择器,但仍通过同一个 LinuxCNC load action。 + +## 6. AUTO 运行控制流 + +```text +btn_run / R + ▼ +linuxcnc.command().auto(AUTO_RUN, line) + ▼ +milltask / RS274NGC interpreter + ▼ +TP queue → motion controller → kinematics → joint commands + ▼ +HAL simulated device / spindle / coolant / tool change + ▼ +linuxcnc.stat + hal_status + ▼ +GMOCCAPY DRO、progress、preview、button sensitivity +``` + +相关按钮属于 `hbtb_auto`:`btn_load`、`btn_reload`、`btn_run`、`btn_stop`、`tbtn_pause`、`btn_step`、`btn_from_line`、`tbtn_optional_blocks`、`btn_edit`。Glade 负责控件和 signal 绑定,Python handler 负责调用 LinuxCNC command;运动本身不在 GTK handler 中实现。 + +## 7. MDI、Jog、Home、Tool 和 Offset 数据流 + +### MDI + +`rbt_mdi` 将 task mode 设为 `MODE_MDI`。MDI 输入提交后进入 LinuxCNC interpreter;G-code 解析错误通过 LinuxCNC error channel 返回,再由 GMOCCAPY notification/error handler 显示。 + +### Jog + +JOG 按钮由 `_make_jog_button()` 动态生成;轴/关节列表来自 INI 的 `COORDINATES`、kinematics 类型和 joint-axis mapping。Jog 命令仍经 LinuxCNC command 通道,不直接改变 DRO;DRO 的真值来自 status feedback。 + +### Home + +Home 按钮最终调用 `command.home(joint_or_axis)`。仿真 HAL 的 `sim_home_switch` 或自定义 home HAL 决定 home switch 状态;`all_homed` HAL status 决定 MDI/AUTO 是否重新开放。 + +### Tool/Offset + +工具表来自 `[EMCIO] TOOL_TABLE`,offset page 和 tool editor 通过 LinuxCNC tool data/action 更新。G43/G49/G43.1 的解释器语义由 RS274NGC 负责;GMOCCAPY 只显示和提交工具/offset 操作。系统 3.5.2 的启动提示明确提醒:AUTO 中换刀后的 G43 不能假定由界面自动恢复,应由程序/REMAP 明确处理。 + +## 8. 五轴 XYZAC RTCP 控制流 + +### 8.1 配置层 + +五轴案例 `xyzac-trt.ini` 的关键字段: + +```text +[DISPLAY] OPEN_FILE = ./demos/xyzac_switchkins.ngc +[RS274NGC] SUBROUTINE_PATH = ./remap_subs +[RS274NGC] REMAP = M428 ... ngc=428remap +[RS274NGC] REMAP = M429 ... ngc=429remap +[RS274NGC] REMAP = M430 ... ngc=430remap +[KINS] KINEMATICS = xyzac-trt-kins sparm=identityfirst +[TRAJ] COORDINATES = XYZAC +[HAL] HALCMD = net ... motion.switchkins-type +[HAL] HALCMD = loadusr -W xyzac-trt-gui +``` + +### 8.2 switchkins 状态 + +`xyzac-trt-kins.c` 将 `sparm=identityfirst` 定义为: + +```text +switchkins-type 0 → identity kinematics +switchkins-type 1 → xyzac TRT kinematics +switchkins-type 2 → userk kinematics +``` + +`trtfuncs.c` 为 XYZAC/XYZBC 实现 forward/inverse mapping,并声明 `tool-offset`、旋转中心和轴 offset HAL pins。XYZAC 的五个关节是 `X Y Z A C`;A 是倾斜台,C 是水平旋转台。 + +### 8.3 M428/M429 控制链 + +```text +G-code M428 + ▼ +428remap.ngc + ├── M68 E3 Q1 写 motion.analog-out-03 = 1 + ├── M66 E0 L0 等待同步 + └── 检查 motion.switchkins-type == 1 + ▼ +xyzac-trt-kins inverse/forward + ▼ +XYZAC joint commands with TCP/RTCP compensation +``` + +`M429` 对称地写入 `Q0`,切回 identity;`M430` 写入 `Q2`,进入 userk。`helix_ac.ngc` 演示了典型顺序:先用 M429 在 machine coordinates 安全定位,再用 M428 执行带 A/C 姿态变化的螺旋插补,结束后再切回 M429 做返回定位。 + +### 8.4 Vismach feedback + +INI 中的 HAL nets 将以下反馈送到 `xyzac-trt-gui`: + +```text +joint.0.pos-fb → table-x +joint.1.pos-fb → saddle-y +joint.2.pos-fb → spindle-z +joint.3.pos-fb → tilt-a +joint.4.pos-fb → rotate-c +motion.tooloffset.z → tool-offset +xyzac-trt-kins.y-offset/z-offset → Vismach geometry +``` + +因此 Vismach 不是运动 authority;它是 joint feedback、tool offset 和 geometry offset 的可视化消费者。 + +## 9. 状态真值与可观察结果 + +| 状态 | authority | 面板表现 | +|---|---|---| +| 急停 | TASK/motion state | E-stop active,模式按钮禁用 | +| 上电 | TASK state + HAL | Power icon active,允许进一步操作 | +| all homed | HAL status / joint state | MDI/AUTO 解除门控 | +| 当前模式 | `stat.task_mode` | MANUAL/MDI/AUTO 页面切换 | +| 当前文件 | `stat.file` / file-loaded status | 顶部文件名、G-code view、Run gate | +| 解释器状态 | `stat.interp_state` | Run/Pause/Step/Stop 敏感度 | +| 当前 G/M codes | `stat.gcodes` / `stat.mcodes` | G-Code 信息区域 | +| 机床位置 | `stat.position` / joint feedback | DRO 和 Vismach | +| kinematics mode | `motion.switchkins-type` | AXIS switchkins 面板/RTCP 模式 | + +任何未来 Web/WASM 控制面板都应消费这些 authority 的 snapshot/event,而不是在 JS/GUI 层镜像一套可写的机床状态。 + +## 10. 现有证据与复现 + +```bash +./run-gmoccapy.sh +./run-5axis-rtcp.sh +./run-5axis-rtcp.sh xyzbc-trt.ini +``` + +已验证的五轴运行证据: + +- [5axis-rtcp-running.png](5axis-rtcp-running.png) +- [5axis-rtcp-shortcut.md](5axis-rtcp-shortcut.md) +- `linuxcnc` 状态返回 `file=./demos/xyzac_switchkins.ngc` +- AXIS 标题包含 `sim-xyzac-trt-kins (switchkins)` +- `xyzac-trt-gui` 进程和五轴 Vismach 预览存在 + +## 11. 后续分析顺序 + +分析任何新的 GMOCCAPY/五轴控制问题时,按以下顺序取证: + +1. 先记录实际运行时路径、LinuxCNC 版本、GMOCCAPY 版本;不要把系统安装脚本和仓库源码混为一份。 +2. 读取 INI 的 DISPLAY/TASK/HAL/RS274NGC/KINS/TRAJ/EMCIO 段,建立配置闭包。 +3. 在 Glade 中找到 widget ID,再在 `gmoccapy.py` 找 signal handler;不要只根据截图猜按钮语义。 +4. 追踪 handler 发出的 `linuxcnc.command()`,确认 command 进入 TASK/motion/HAL 的路径。 +5. 用 `linuxcnc.stat()`、HAL pins、日志和 Vismach feedback 交叉验证,不把 DRO 或 preview 当作 authority。 +6. 五轴问题先确认 kinematics type、M428/M429 状态、tool offset、rotation center/axis offset,再分析轨迹差异。 +7. 任何缺失的官方 oracle、实时硬件、浏览器或资源输入都保留为明确 blocker,不以 GUI 截图替代完整等价证明。 diff --git a/doc-rtcp/gmoccapy-file-inventory.json b/doc-rtcp/gmoccapy-file-inventory.json new file mode 100644 index 0000000..5fb7078 --- /dev/null +++ b/doc-rtcp/gmoccapy-file-inventory.json @@ -0,0 +1,7427 @@ +{ + "file_count": 1233, + "files": [ + { + "bytes": 2633, + "path": "linuxcnc/configs/sim/gmoccapy/6_axis.ini", + "role": "simulation_ini", + "sha256": "1a47c6b666af1ca2f78f95022c27bb9f94626ffce26da23556fea15f767b7cba" + }, + { + "bytes": 2851, + "path": "linuxcnc/configs/sim/gmoccapy/7_axis.ini", + "role": "simulation_ini", + "sha256": "10db48db4e53a03fe04c2e3dc849c84c9f3f2b77d51c233f64b92b375942a14f" + }, + { + "bytes": 3180, + "path": "linuxcnc/configs/sim/gmoccapy/7_axis_tool.ini", + "role": "simulation_ini", + "sha256": "6f48447e4576d82a57742dc94babcecf2e813a2afbe398acfcfd87d05c99f229" + }, + { + "bytes": 3033, + "path": "linuxcnc/configs/sim/gmoccapy/8_axis.ini", + "role": "simulation_ini", + "sha256": "ad9e2a848a1d1cde6c4fbcf82adaae70d52af6f283d3e785a053c2a560ab8f84" + }, + { + "bytes": 3278, + "path": "linuxcnc/configs/sim/gmoccapy/9_axis.ini", + "role": "simulation_ini", + "sha256": "72252c1eb8238facb30b8b3fc08d012b22c70bf1c7c151c2e50946a5eeadc5ef" + }, + { + "bytes": 420, + "path": "linuxcnc/configs/sim/gmoccapy/README", + "role": "simulation_asset", + "sha256": "1cfefb8ab11721485f3a26f21e25114d7e7795505058b371f757e402e8dc4022" + }, + { + "bytes": 529, + "path": "linuxcnc/configs/sim/gmoccapy/README_es", + "role": "simulation_asset", + "sha256": "fc0dcccc47bc360eb15b510d757e41efd358b8c38e290f3afc0d3a0f32b2e1bb" + }, + { + "bytes": 5074, + "path": "linuxcnc/configs/sim/gmoccapy/button.glade", + "role": "simulation_resource", + "sha256": "33c010a47f6b0f16182ba4fcc93a7a3d4bec87caff9c14896ae724fe2542258d" + }, + { + "bytes": 1846, + "path": "linuxcnc/configs/sim/gmoccapy/core_sim.hal", + "role": "simulation_runtime_data", + "sha256": "a1793b7a8bb9ff03172dadd5a42bbfe41248f00796b48ef5d38b766d123accdf" + }, + { + "bytes": 2068, + "path": "linuxcnc/configs/sim/gmoccapy/core_sim4.hal", + "role": "simulation_runtime_data", + "sha256": "d326da9d94d7abdc6ebed4a83144cd1623fa63d5af37ad0ed57662ff84249179" + }, + { + "bytes": 2134, + "path": "linuxcnc/configs/sim/gmoccapy/core_sim_6.hal", + "role": "simulation_runtime_data", + "sha256": "a9ffe2dc7d433ab5b6c027bc8e056b19b831ccbed64acd760571326d0ee6273f" + }, + { + "bytes": 2189, + "path": "linuxcnc/configs/sim/gmoccapy/core_sim_7.hal", + "role": "simulation_runtime_data", + "sha256": "8a3edf09fdeee30ed396bb3b3b533f7acbce4d4fe1b22e90de9fa3bc3442cb8d" + }, + { + "bytes": 2244, + "path": "linuxcnc/configs/sim/gmoccapy/core_sim_8.hal", + "role": "simulation_runtime_data", + "sha256": "89becacb8d967d3078facf90ba16e34e39bc33857fcc92d715ef9be50e688d6d" + }, + { + "bytes": 2299, + "path": "linuxcnc/configs/sim/gmoccapy/core_sim_9.hal", + "role": "simulation_runtime_data", + "sha256": "563234fc66fe5483a4867a03e2a6e49e13f257805661f3c55a99e2c9c6b16c6d" + }, + { + "bytes": 2394, + "path": "linuxcnc/configs/sim/gmoccapy/core_sim_XYZAB.hal", + "role": "simulation_runtime_data", + "sha256": "fc79d08d080865aaf275c138b0220eb51ddd7c370f150c7b3d5d1b41ab33fd85" + }, + { + "bytes": 2394, + "path": "linuxcnc/configs/sim/gmoccapy/core_sim_XYZAC.hal", + "role": "simulation_runtime_data", + "sha256": "3fa7c42778f965ad47291d0215fec42707a2d15279580cc588fd459393f52a03" + }, + { + "bytes": 2394, + "path": "linuxcnc/configs/sim/gmoccapy/core_sim_XYZCW.hal", + "role": "simulation_runtime_data", + "sha256": "a0fd41c8ba9e1cb213122b2ae9b75184ef1e245b6d5d63e49b10211cbfcdf505" + }, + { + "bytes": 11324, + "path": "linuxcnc/configs/sim/gmoccapy/dro.glade", + "role": "simulation_resource", + "sha256": "1a30d2d02e66a346495c477af8298d4d1acb3c13822cca78f06042cbedc304bc" + }, + { + "bytes": 5115, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy.ini", + "role": "simulation_ini", + "sha256": "627537d0a342075ecd45765b4d8b256b065f2568902a585cfe5161efec53a126" + }, + { + "bytes": 2047, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy.pref", + "role": "simulation_runtime_data", + "sha256": "446bfb88f57775b7df79379d9fcf252ff53662c77357e4dadb57d7af06a4a499" + }, + { + "bytes": 76, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy.txt", + "role": "simulation_resource", + "sha256": "c2989ddf8c03a240ceb9fb2d4af5400a59ac20cb40ba762bc7f0ea203b97d593" + }, + { + "bytes": 2908, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy2.glade", + "role": "simulation_resource", + "sha256": "f307b3553656db0ed4bbc714c355ed9d73ee9cbe079819172c61b1e942b61476" + }, + { + "bytes": 5145, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_4_axis.ini", + "role": "simulation_ini", + "sha256": "33b4ad6792d9037f2a0bb9eb179aff7b3d8ecac64bfa0b1cc71633a88cf868d9" + }, + { + "bytes": 74, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_4_axis.txt", + "role": "simulation_resource", + "sha256": "91edc2d47f90710a9262598b28c90aee7fb52bffcf0d040ffe2535b7694fcf04" + }, + { + "bytes": 6788, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZAB.ini", + "role": "simulation_ini", + "sha256": "c8047ee290a94944481545a78104e9ead1036ca04f965a729ad4a870e7fe69a1" + }, + { + "bytes": 6372, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZAC.ini", + "role": "simulation_ini", + "sha256": "daf2ffcab7fb3af60f5dd38256c8e9bb3347d885771ba414da2b4277c8ebce4a" + }, + { + "bytes": 6360, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZCW.ini", + "role": "simulation_ini", + "sha256": "8a860f885f6afc18b0d1ff8081d356d56897456298cfd58fc7394ec519f71e83" + }, + { + "bytes": 4902, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_left_panel.ini", + "role": "simulation_ini", + "sha256": "3e458b639557d33bc2b637fb2f63b88e1cade3dd7543306b96e166c5b50bb08e" + }, + { + "bytes": 6474, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_messages.ini", + "role": "simulation_ini", + "sha256": "7b8a607c978ad1758a51d60b04d3bed46a9597661060a6a906b4411abe02e857" + }, + { + "bytes": 4918, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_pedant.ini", + "role": "simulation_ini", + "sha256": "ea336e14be5b1b62a6b540070624b6c35cd076b16d170725fc4dacb9754e6790" + }, + { + "bytes": 465, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/README", + "role": "simulation_asset", + "sha256": "5a25e58d433c629316f5a865d025ad50f602343d99bf6c4fd983b6ce09f21828" + }, + { + "bytes": 582, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/README_es", + "role": "simulation_asset", + "sha256": "2c2ca93c048f0ad170829caad82ea311fc69a5abb2bd2524ef1943380d55fc85" + }, + { + "bytes": 6046, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/gmoccapy_plasma.ini", + "role": "simulation_ini", + "sha256": "b006d05ea125442e3258a76b9e95d28a3488d25f1f652828c470de82aaa9d077" + }, + { + "bytes": 486, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/gmoccapy_postgui.hal", + "role": "simulation_runtime_data", + "sha256": "7191fdb835d3e6de04907348a35e6a744695cba95b9e22e19b26a0d803a698c5" + }, + { + "bytes": 43130, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/plasma.glade", + "role": "simulation_resource", + "sha256": "19c848753644c6fad57a29919604aeec783562441533a659cc93cd7a831cddeb" + }, + { + "bytes": 1047, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/plasma.hal", + "role": "simulation_runtime_data", + "sha256": "591736242661bd061f3ad3130174feea805a9d3afd514d741c5e61fc47383913" + }, + { + "bytes": 15837, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/plasma.py", + "role": "simulation_resource", + "sha256": "d9b1a16cb260f017f39472cd2bd4ed1136156d7c25df183892999fdf65cf3068" + }, + { + "bytes": 12879, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/signals.glade", + "role": "simulation_resource", + "sha256": "9806848f0582cfd6ae1246a7d121c2069ddf40f21312e6b6d293f4a3e6f46282" + }, + { + "bytes": 308, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/signals.hal", + "role": "simulation_runtime_data", + "sha256": "c6c006a5f2ebdac34adb0b1ebc07819cbd793eabb325ae076425af8b14a4e32a" + }, + { + "bytes": 1932, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/signals.py", + "role": "simulation_resource", + "sha256": "e2f2d29067ea4c38ca7ec77a45098fb58abed3bb546602bba5ae6d10c3f19dc6" + }, + { + "bytes": 4190, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/torch.svg", + "role": "simulation_resource", + "sha256": "3fe8a65414e4d8db67ad049c24dc4bcd0afa1de53c479cd0332b2ea59594bd78" + }, + { + "bytes": 166, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/torches.tbl", + "role": "simulation_runtime_data", + "sha256": "05d9bf3abc2618b7921568926a546054ff4f15c8e666373a3751f11c3a25f626" + }, + { + "bytes": 1234, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_postgui.hal", + "role": "simulation_runtime_data", + "sha256": "32d5cfa8c02a1be05348d4b6af621fff3a62e2adf44de5b82d2600b41839198c" + }, + { + "bytes": 6314, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_pyngcgui.ini", + "role": "simulation_ini", + "sha256": "2f62b1a0e2bcdf2b587e142ea8c4212c28b8024161c38b13e5cb39e15c984ce7" + }, + { + "bytes": 113, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_pyngcgui.txt", + "role": "simulation_resource", + "sha256": "1ab3bb80e449bab939de76b4c43e0749251b2d0abb266bbdfc3450936b5233b2" + }, + { + "bytes": 4699, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_right_panel.ini", + "role": "simulation_ini", + "sha256": "c155ba8047c3011c6ec023dd911fa571ec52b5352b789b7c88542c8d418e15bc" + }, + { + "bytes": 5064, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_sim_hardware_button.ini", + "role": "simulation_ini", + "sha256": "7469a0e05ea85c83d99f11ef552482c29d93313a358d8a7801a2eabbae1f9af0" + }, + { + "bytes": 5153, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_tool_sensor.ini", + "role": "simulation_ini", + "sha256": "4caf0e746fd09bceafa4f2bdced6a9be063b7ee51334fbb75d4c6914d94db7b9" + }, + { + "bytes": 1780, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_tool_sensor.para", + "role": "simulation_runtime_data", + "sha256": "29c6fefac9ed01d575e97a84b8efc48f0e3103a4d8daa6d0348b83baa000ad1d" + }, + { + "bytes": 5475, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_with_user_tabs.ini", + "role": "simulation_ini", + "sha256": "a080a9008bef88d61fee5473f8531df64bfe3fd365540e1055e3377ce59f99d9" + }, + { + "bytes": 75, + "path": "linuxcnc/configs/sim/gmoccapy/gmoccapy_with_user_tabs.txt", + "role": "simulation_resource", + "sha256": "6a9bd64b9cc0ff875fe8ab29dcf4a6abfe6fc996f33c74a9128a8a5c70811c50" + }, + { + "bytes": 7124, + "path": "linuxcnc/configs/sim/gmoccapy/h_buttonlist.glade", + "role": "simulation_resource", + "sha256": "3e7468c9b45f41f3c3af05ad39eebc165181dae6eb888590c9b309b99be29dc3" + }, + { + "bytes": 986, + "path": "linuxcnc/configs/sim/gmoccapy/h_buttonlist.hal", + "role": "simulation_runtime_data", + "sha256": "94121fd144fdbe230261586b9519528f5b8cee4bba4efb0c2c54d70e9a326b3b" + }, + { + "bytes": 4620, + "path": "linuxcnc/configs/sim/gmoccapy/jogwheel.glade", + "role": "simulation_resource", + "sha256": "0f053895edb43037d2a64432a087489aa60864276fc2e0cf91f7c4677c8925a7" + }, + { + "bytes": 691, + "path": "linuxcnc/configs/sim/gmoccapy/jogwheel.hal", + "role": "simulation_runtime_data", + "sha256": "d5b421d044e444b042a6508a4902f38ab57f871f42d87e1858e68e77ad4b3c92" + }, + { + "bytes": 373, + "path": "linuxcnc/configs/sim/gmoccapy/lathe.tbl", + "role": "simulation_runtime_data", + "sha256": "07aadc984258ec7d9fcb68d3b84ad796995b055f9b364e57b13058c42d96dd30" + }, + { + "bytes": 5061029, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/LatheMacro.svg", + "role": "simulation_resource", + "sha256": "234a6e329bf356c5c766a26fff48c7223e311441eff37397f76b7b511816e887" + }, + { + "bytes": 3229, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/README", + "role": "simulation_asset", + "sha256": "6dfd0352ff951bb42b2504d82982ad646bcf9650996919e040fb1655fa478c44" + }, + { + "bytes": 1182, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/boring.ngc", + "role": "simulation_resource", + "sha256": "8b373a5125d30f07caef25a5e8928643255245aa1839d8ddef23bdd7c82e564a" + }, + { + "bytes": 1116, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/chamfer.ngc", + "role": "simulation_resource", + "sha256": "caf3bed8993cb390b0ffdbc8c173562546fa825172d1ce1b1e8f7b5122dc1b3d" + }, + { + "bytes": 1120, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/core_sim_lathe.hal", + "role": "simulation_runtime_data", + "sha256": "614ebb8b029a9a234821cc08ae7cdc506b774dde5db8e75966df64f694540df0" + }, + { + "bytes": 2005, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/core_sim_lathe_C.hal", + "role": "simulation_runtime_data", + "sha256": "c4761c123f7e367bf5cc74a0016340c2dc553ef61a19005af47ec4e05fd54ffb" + }, + { + "bytes": 2059, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/core_sim_lathe_CW.hal", + "role": "simulation_runtime_data", + "sha256": "14065d0eed908856d59c52fe9782d3c487dbba4535b2c4209554c72046eff3c9" + }, + { + "bytes": 725, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/drilling.ngc", + "role": "simulation_resource", + "sha256": "69df94bfc1f55b7e803068e75deac4a36d2ea831b24b2f2a730d9ffab7e109bd" + }, + { + "bytes": 595, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/facing.ngc", + "role": "simulation_resource", + "sha256": "76eb4c7d27855d787b7de807bfad1a98b07dbd6df4777c1f0aa2954488a65162" + }, + { + "bytes": 1821, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/gmoccapy_lathe.pref", + "role": "simulation_runtime_data", + "sha256": "3f0ba81ce7555edd733bc8a279aab9f0149c5c099bafe285b0adf3a8907eff09" + }, + { + "bytes": 1620, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/gmoccapy_lathe_c.pref", + "role": "simulation_runtime_data", + "sha256": "63f7d20c0f7f5790e44e541f0a11a554d0acb1a417c57f1fa5ed0590ae08c7dd" + }, + { + "bytes": 1066, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/gmoccapy_postgui.hal", + "role": "simulation_runtime_data", + "sha256": "c6aacd0c3c91411d03d3368db70d90ebf6c7bbbe00121402d2f86dacf52fd513" + }, + { + "bytes": 430, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/grooving.ngc", + "role": "simulation_resource", + "sha256": "39ce59c5d4f6b926f157a5103984d0066551a92a62320ef6b8171cf73c72d060" + }, + { + "bytes": 4015, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe.ini", + "role": "simulation_ini", + "sha256": "b6971dfdf96fb2d502378d143da6c7a2f404fe796f41f96f629b9db15a44bb66" + }, + { + "bytes": 1667, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe.pref", + "role": "simulation_runtime_data", + "sha256": "3b26904d5578dde8d9618b3d851936e4d3395bcd7f7b05d31407f0a176ecae95" + }, + { + "bytes": 465, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe.tbl", + "role": "simulation_runtime_data", + "sha256": "feb0002bb8663770be5987f24add9853042faeadf3af972433c03720c1942775" + }, + { + "bytes": 4536, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_C.ini", + "role": "simulation_ini", + "sha256": "c2f67186fc6c84f266d2ad1d6fcf487249182a2385f8d3099f51f9fab1cc8bb4" + }, + { + "bytes": 5178, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_CW.ini", + "role": "simulation_ini", + "sha256": "df718eefdbd91308b9182f6858150abb8fa4a2d030105db954702c280cddac70" + }, + { + "bytes": 4015, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_backtool.ini", + "role": "simulation_ini", + "sha256": "5d7e04fd075e28534afe817e64259a2e7df809d5fdf893f39c9cc5ffcd35ed71" + }, + { + "bytes": 1652, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_c.pref", + "role": "simulation_runtime_data", + "sha256": "65ef8d72c4be99ee5aa038ece7f2f7f107a0c06c95047fcb09e186815d6d0466" + }, + { + "bytes": 1621, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_cw.pref", + "role": "simulation_runtime_data", + "sha256": "89e009db509cee3e7ab681b0bf294389caa0930712457ac424337a343bf063bf" + }, + { + "bytes": 4060, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_imperial.ini", + "role": "simulation_ini", + "sha256": "503bf2241ed1c1f70410015a7f3aab5a922dc571b1ded36f5431c538d5d4e628" + }, + { + "bytes": 1598, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_imperial.pref", + "role": "simulation_runtime_data", + "sha256": "d9e838aebb01a81108de5efcbb637f4b88725bc6697db3baf0875106e8fdf19b" + }, + { + "bytes": 4248, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_macros.ini", + "role": "simulation_ini", + "sha256": "b3d9c8451a9281e9863e30f7d0138d5779028a06d981c2f1bd30bf6c7bded0e0" + }, + { + "bytes": 7625, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathehandler.py", + "role": "simulation_resource", + "sha256": "dbd025086e24bfaaa83900b84d1416db85fa0d97f9aa48a9f4de424c493425d7" + }, + { + "bytes": 159113, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/lathemacro.ui", + "role": "simulation_resource", + "sha256": "e9d946edccc6d809e5efa72f334e1d0efd25fcd86e02c09a77a115d5b3041477" + }, + { + "bytes": 1151, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/radius.ngc", + "role": "simulation_resource", + "sha256": "a96e939049e222ea1bd04e7cdb116e51eb1180b3a080b1b3f325bb3c64d55dd0" + }, + { + "bytes": 1458, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/savestate.sav", + "role": "simulation_asset", + "sha256": "52842a17d6b617319909559bb78accfa8702e9f38982afe5e0338ebcdbdb5d9d" + }, + { + "bytes": 368, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/simulated_home_lathe.hal", + "role": "simulation_runtime_data", + "sha256": "64c6e20244c60d3ea66e1299c7e9619f14cb3037603fb2213d42f67a62da8ee6" + }, + { + "bytes": 368, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/simulated_home_lathe_CW.hal", + "role": "simulation_runtime_data", + "sha256": "64c6e20244c60d3ea66e1299c7e9619f14cb3037603fb2213d42f67a62da8ee6" + }, + { + "bytes": 2338, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/spindle_sim.hal", + "role": "simulation_runtime_data", + "sha256": "f43dac948d6f198cb7f0a8855f9acc38ab2e41df8f9fd1abbe4607ea442800b0" + }, + { + "bytes": 1037, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/threading.ngc", + "role": "simulation_resource", + "sha256": "898fa7f5403d060f649d3aaa9ae8810882e22610af0769439fff221bdd47e78d" + }, + { + "bytes": 1184, + "path": "linuxcnc/configs/sim/gmoccapy/lathe_configs/turning.ngc", + "role": "simulation_resource", + "sha256": "3ef8d3c8f36a15b74f366f7d4e57a47d747ad73e91fbec2f9c038cf39ed05816" + }, + { + "bytes": 500, + "path": "linuxcnc/configs/sim/gmoccapy/left.hal", + "role": "simulation_runtime_data", + "sha256": "c8efad631f12a4ac1c74c866ec2d3e2b7886f088625dc1f00dee050409fab892" + }, + { + "bytes": 641, + "path": "linuxcnc/configs/sim/gmoccapy/left_panel.hal", + "role": "simulation_runtime_data", + "sha256": "fb70eed442256b29dcbd78ffb2c31dbf9f6639f7e0f3ef68d8903dd930a8c1eb" + }, + { + "bytes": 1924, + "path": "linuxcnc/configs/sim/gmoccapy/macros/change.ngc", + "role": "simulation_resource", + "sha256": "3d4d204d2164dcbdcaa6fe859154842c8939fd0bbe1b2f7e8a3eda4d7a0c6cde" + }, + { + "bytes": 400, + "path": "linuxcnc/configs/sim/gmoccapy/macros/go_to_position.ngc", + "role": "simulation_resource", + "sha256": "33e66edb930c7fa64c80fc88921b7cb7fda721e61dbf67cd51a2f43109f20523" + }, + { + "bytes": 221, + "path": "linuxcnc/configs/sim/gmoccapy/macros/halo_world.ngc", + "role": "simulation_resource", + "sha256": "6b7863e0bcbf997ebc6f1bdc4fc861b69a4787fa1f127cca97b76676b455adfe" + }, + { + "bytes": 400, + "path": "linuxcnc/configs/sim/gmoccapy/macros/i_am_lost.ngc", + "role": "simulation_resource", + "sha256": "35ba01cee35bb1e76a1e5eb947e8f2f936063cee08f2c35fa175edd8767e774c" + }, + { + "bytes": 24520, + "path": "linuxcnc/configs/sim/gmoccapy/macros/images/goto_x_y_z.png", + "role": "simulation_asset", + "sha256": "797e2fce748a6e7d19b1a7686d743b11015a3929cae646d154da953a7e3c13c9" + }, + { + "bytes": 14074, + "path": "linuxcnc/configs/sim/gmoccapy/macros/images/i_am_lost.png", + "role": "simulation_asset", + "sha256": "f6df3ed0b0a79cd0bfccd5d029349bf685f3ace4818ab697cff0c5857ace096b" + }, + { + "bytes": 222151, + "path": "linuxcnc/configs/sim/gmoccapy/macros/images/macro_8.png", + "role": "simulation_asset", + "sha256": "0e42752fc4360390bf2214717dbb0be389bed908d1f178b8047029b3cd97734a" + }, + { + "bytes": 205, + "path": "linuxcnc/configs/sim/gmoccapy/macros/increment.ngc", + "role": "simulation_resource", + "sha256": "3aa6bb7fdf504676769f30b9a5ae079b858aebcfc10cdc3dd7617f0a94954239" + }, + { + "bytes": 205, + "path": "linuxcnc/configs/sim/gmoccapy/macros/jog_around.ngc", + "role": "simulation_resource", + "sha256": "6c3f64beb65cd5bead9fda63e6904880099dd5839693e25e6ae71eca0509b2bd" + }, + { + "bytes": 262, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_0.ngc", + "role": "simulation_resource", + "sha256": "d831ed98b0e383645414961cab4fdb468a8b61b2a38f7b14508cc4fea14ec2a9" + }, + { + "bytes": 262, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_1.ngc", + "role": "simulation_resource", + "sha256": "e28262f8b854781fc0c39b6f1989e3506fe38a9355e98f0802a7ff8c0928a577" + }, + { + "bytes": 264, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_10.ngc", + "role": "simulation_resource", + "sha256": "e4bc0167421eae327ceb4e241cf9ba88fb86ce34e04233a7f47240363f49bfaf" + }, + { + "bytes": 264, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_11.ngc", + "role": "simulation_resource", + "sha256": "38ba16a50fe4ded63fd9feadd0a0bcb37c3244bfcad8041c2e00dee7b436470c" + }, + { + "bytes": 264, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_12.ngc", + "role": "simulation_resource", + "sha256": "600a73dbd49ab56680f688629e803c693b1086a124c41316911d1ded5247589a" + }, + { + "bytes": 264, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_13.ngc", + "role": "simulation_resource", + "sha256": "edce6ade837a115f9a8ef66203509935472327c81d1f95d7ee54832bf210f35e" + }, + { + "bytes": 264, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_14.ngc", + "role": "simulation_resource", + "sha256": "9eeaed8fa7ebbd97d9bf61e972c23a5f896c58d71595b8f5be14f05a90aa6b88" + }, + { + "bytes": 264, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_15.ngc", + "role": "simulation_resource", + "sha256": "18e481c4f56b0e3fe1d9c45749bebd8ab1d5eccdec040041e03653d0b79ecd30" + }, + { + "bytes": 262, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_2.ngc", + "role": "simulation_resource", + "sha256": "c8d67bf45bf02038688da2d5ba293b1e97d6458a84ee94dfbdb771c7401ae89a" + }, + { + "bytes": 262, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_3.ngc", + "role": "simulation_resource", + "sha256": "258481fb6e6c3658ab7a93f8fc244b063bbbfbe8348d9cf7693a33ede017d3d7" + }, + { + "bytes": 262, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_4.ngc", + "role": "simulation_resource", + "sha256": "c50875f54890ea24213d9d666b73838b3b2defb2eb29cad5563e58e9cafa52c3" + }, + { + "bytes": 262, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_5.ngc", + "role": "simulation_resource", + "sha256": "8fde463ddebd1e304d6856cf1e55a237efb9fec4fa38644824ce2ece5d839d1c" + }, + { + "bytes": 262, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_6.ngc", + "role": "simulation_resource", + "sha256": "247817107d6629a9a5448e58b36366dbd13cfae20b7b315d6466c9f54926dc4c" + }, + { + "bytes": 262, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_7.ngc", + "role": "simulation_resource", + "sha256": "9e62f1ef37cf683c1e92f1d51e3bce36210262613dae871b6a4f44a525b72c49" + }, + { + "bytes": 383, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_8.ngc", + "role": "simulation_resource", + "sha256": "bc62cb4eed38f8a8322bbf78282cc6450b773bae3ec0665f3a227c08024a95ed" + }, + { + "bytes": 262, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_9.ngc", + "role": "simulation_resource", + "sha256": "b7ede9af0cadff0e49594e270c530f1d2b3af128d0b47b484e1e38bc1bfd4482" + }, + { + "bytes": 1279, + "path": "linuxcnc/configs/sim/gmoccapy/macros/macro_Instructions.txt", + "role": "simulation_resource", + "sha256": "c8a26259f6e68a2242ce33dd819be96cd18ede964265016dd356e5d84ef191ce" + }, + { + "bytes": 53, + "path": "linuxcnc/configs/sim/gmoccapy/macros/on_abort.ngc", + "role": "simulation_resource", + "sha256": "e120b55018a8f01b0409a2c0385afec32668e77cf4feeb74cb5e66f3636dde7a" + }, + { + "bytes": 918, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gantry_mm.hal", + "role": "simulation_runtime_data", + "sha256": "5da3e7f6e95f26df831f046a5c7c9ed3e073579748812140a15085dd558b42b0" + }, + { + "bytes": 2788, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gantry_mm.ini", + "role": "simulation_ini", + "sha256": "303f0fb1b9a70ba3cc6dbc11003bed2c59579ddfe2e4d9a300a5fcd4da570e65" + }, + { + "bytes": 1827, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gmoccapy_GANTRY_sim.pref", + "role": "simulation_runtime_data", + "sha256": "6b63fa2d6e0a0f09b5ead8b0b329f6ee9df5a3f16f0f55a416d7ca2354b91f61" + }, + { + "bytes": 1031, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gmoccapy_postgui.hal", + "role": "simulation_runtime_data", + "sha256": "d8de40b38c349012779d9fa30bc1d466635f1ad2c05c9cf3e9a85e7bf64b916c" + }, + { + "bytes": 2128, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/tool.tbl", + "role": "simulation_runtime_data", + "sha256": "f0c933ba509282003dad7ce1b0d9e7dde58a899fa6463e8ddc113532e42ae567" + }, + { + "bytes": 1803, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/LinuxCNC-HAL-SIM-SCARA.pref", + "role": "simulation_runtime_data", + "sha256": "aaec9dfa35c261db2165b4a599e319f51c4c3ccd26515a90bd3b6b008941b699" + }, + { + "bytes": 522, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/README", + "role": "simulation_asset", + "sha256": "2c008bea0f2a761d2a88d6fb39e91aeeaea9d9c9fa272d9db0898d3e0d53d5e7" + }, + { + "bytes": 586, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/README_es", + "role": "simulation_asset", + "sha256": "4096945df4926fca88e9cd90cbf54a183c6eea8921f2cd60cc01927f9bee17b8" + }, + { + "bytes": 941, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/postgui.hal", + "role": "simulation_runtime_data", + "sha256": "8f7a374778a3100b7f2234f821adeca566f4d0f8d364d760836ed5484539fbe3" + }, + { + "bytes": 6300, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara.glade", + "role": "simulation_resource", + "sha256": "327c8fef2c9ecfb5372160a617156abb06b5a849d4469683c2341530e6d1a251" + }, + { + "bytes": 2568, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara.ini", + "role": "simulation_ini", + "sha256": "3c5a9c56f4c50a987f7b2a21b6968ab77eeb586a894f8ffff73dec74eb680092" + }, + { + "bytes": 166, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara.tbl", + "role": "simulation_runtime_data", + "sha256": "05d9bf3abc2618b7921568926a546054ff4f15c8e666373a3751f11c3a25f626" + }, + { + "bytes": 105, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara_panel.hal", + "role": "simulation_runtime_data", + "sha256": "69c13f23a5434680e7d0ea69ee78801e697261ddd4c13af6c9f8b10bfde3551f" + }, + { + "bytes": 124, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara_postgui.hal", + "role": "simulation_runtime_data", + "sha256": "69db8232c9384cffcaec0b07f7616d439e4a63bd23daa9d48f7f24a2c8afa66d" + }, + { + "bytes": 2114, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara_sim_4.hal", + "role": "simulation_runtime_data", + "sha256": "f327896d862537f129cf7424e540eb7a7e689a8fbc58521a3e3d6f26c4c1915b" + }, + { + "bytes": 2370, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/spindle_sim.hal", + "role": "simulation_runtime_data", + "sha256": "fa4799af70e6d611efc438fb5e25c360d8163f498e511f443925738f194639c7" + }, + { + "bytes": 310, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/README", + "role": "simulation_asset", + "sha256": "a371181446fdc09de6ebe5d81611c51d8d1e5d91b99f08767db8510b686fa1ab" + }, + { + "bytes": 331, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/README_es", + "role": "simulation_asset", + "sha256": "3ea3f2c3e3605057928e600f233f796b27cd84ebfa0605dd87a4078def2617be" + }, + { + "bytes": 70808, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzac.ngc", + "role": "simulation_resource", + "sha256": "574f9154d9fa6b31ab14fba8b79a3a9fa0d1c37bdecf5dfc19871e01411c6eaf" + }, + { + "bytes": 76577, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzbc.ngc", + "role": "simulation_resource", + "sha256": "ed079d7e69d53cf0b012636b56439d19fc629c4eca2e4175cd09d5448c9f52d4" + }, + { + "bytes": 294372, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/impeller-7bl-xyzac.ngc", + "role": "simulation_resource", + "sha256": "106441767b816b4eea1cf8683b5d9ec6dccdb1f21ec0bf3354c7660f53bbe788" + }, + { + "bytes": 886, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/test-xyzac.ngc", + "role": "simulation_resource", + "sha256": "a4545242699cb127f5796465e3b5edda7da2b76c26579b90e3d2db7a33fc77fc" + }, + { + "bytes": 885, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/test-xyzbc.ngc", + "role": "simulation_resource", + "sha256": "ac389cfa886a30c2b0fab4f579df2ce2fd101b924a7777747b2bacd67446a900" + }, + { + "bytes": 941, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/postgui.hal", + "role": "simulation_runtime_data", + "sha256": "f62636323218a0cdcdae48dbdf1a8c595365566062122f36e403fd71393ed57e" + }, + { + "bytes": 1714, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/sim-xyzac-trt.pref", + "role": "simulation_runtime_data", + "sha256": "74cc0709e6f6275858d841f2bf03975a709595ad4256fc5dcbc3a928c7cd6a48" + }, + { + "bytes": 3034, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt.ini", + "role": "simulation_ini", + "sha256": "af315891e9e561812f267f9c44c752c265ad00c862adbcd7dd42c2b07e60cd38" + }, + { + "bytes": 169, + "path": "linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt.tbl", + "role": "simulation_runtime_data", + "sha256": "100595ddcdddf0e269a4b6041954f19349b593ffcdaf185fbcff8cde91311176" + }, + { + "bytes": 19980, + "path": "linuxcnc/configs/sim/gmoccapy/pendant.glade", + "role": "simulation_resource", + "sha256": "a7095c6742d976bd73c7860f0a5754f8e0604f4d0c24a90638a347d6d67a6dd1" + }, + { + "bytes": 2476, + "path": "linuxcnc/configs/sim/gmoccapy/pendant.hal", + "role": "simulation_runtime_data", + "sha256": "a52d56ea8675c1ba332d2e46c6efc0d1890cf74395683036e1a3ac200b007baa" + }, + { + "bytes": 465, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/README", + "role": "simulation_asset", + "sha256": "5a25e58d433c629316f5a865d025ad50f602343d99bf6c4fd983b6ce09f21828" + }, + { + "bytes": 583, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/README_es", + "role": "simulation_asset", + "sha256": "aec7a284383822374e8653f5b482fbe84f60c0774ac6e2337b5ce33eff396c09" + }, + { + "bytes": 1719, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/gmoccapy.pref", + "role": "simulation_runtime_data", + "sha256": "7c123d22d53e65a3d930b8c41056db551752e4b26f2e50428409fb3a32bd96dc" + }, + { + "bytes": 5949, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/gmoccapy_plasma.ini", + "role": "simulation_ini", + "sha256": "7d53c570ccb85f086e67eb511c28bb9cec47e02cf42395e71bb2ff89e9d0d671" + }, + { + "bytes": 486, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/gmoccapy_postgui.hal", + "role": "simulation_runtime_data", + "sha256": "7191fdb835d3e6de04907348a35e6a744695cba95b9e22e19b26a0d803a698c5" + }, + { + "bytes": 43130, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/plasma.glade", + "role": "simulation_resource", + "sha256": "19c848753644c6fad57a29919604aeec783562441533a659cc93cd7a831cddeb" + }, + { + "bytes": 1047, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/plasma.hal", + "role": "simulation_runtime_data", + "sha256": "591736242661bd061f3ad3130174feea805a9d3afd514d741c5e61fc47383913" + }, + { + "bytes": 15837, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/plasma.py", + "role": "simulation_resource", + "sha256": "d9b1a16cb260f017f39472cd2bd4ed1136156d7c25df183892999fdf65cf3068" + }, + { + "bytes": 12879, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/signals.glade", + "role": "simulation_resource", + "sha256": "9806848f0582cfd6ae1246a7d121c2069ddf40f21312e6b6d293f4a3e6f46282" + }, + { + "bytes": 308, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/signals.hal", + "role": "simulation_runtime_data", + "sha256": "c6c006a5f2ebdac34adb0b1ebc07819cbd793eabb325ae076425af8b14a4e32a" + }, + { + "bytes": 1932, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/signals.py", + "role": "simulation_resource", + "sha256": "e2f2d29067ea4c38ca7ec77a45098fb58abed3bb546602bba5ae6d10c3f19dc6" + }, + { + "bytes": 4190, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/torch.svg", + "role": "simulation_resource", + "sha256": "3fe8a65414e4d8db67ad049c24dc4bcd0afa1de53c479cd0332b2ea59594bd78" + }, + { + "bytes": 166, + "path": "linuxcnc/configs/sim/gmoccapy/plasma_config/torches.tbl", + "role": "simulation_runtime_data", + "sha256": "05d9bf3abc2618b7921568926a546054ff4f15c8e666373a3751f11c3a25f626" + }, + { + "bytes": 321, + "path": "linuxcnc/configs/sim/gmoccapy/position.txt", + "role": "simulation_resource", + "sha256": "7ff80b79f7e35cb7ef54bce59212a68e3f80cb6b63de8abdcda9c519bbe0a626" + }, + { + "bytes": 829, + "path": "linuxcnc/configs/sim/gmoccapy/pyngcgui.ui", + "role": "simulation_resource", + "sha256": "dced80b3f34f0a1b3f38086d3fe16ff3b9e48ebe04a281dee356db757fe5b640" + }, + { + "bytes": 935, + "path": "linuxcnc/configs/sim/gmoccapy/python/remap.py", + "role": "simulation_resource", + "sha256": "dd8d580d375761e5bc7751bd50db6b0b88fbf24cefd12eb24892a84dff542b2b" + }, + { + "bytes": 7993, + "path": "linuxcnc/configs/sim/gmoccapy/python/stdglue.py", + "role": "simulation_resource", + "sha256": "bd05f6b71d76e2a3502c1d13f7715ab70830a24247de56e24b23f306f04b01b6" + }, + { + "bytes": 921, + "path": "linuxcnc/configs/sim/gmoccapy/python/toplevel.py", + "role": "simulation_resource", + "sha256": "beaf4709170a42250120b11fea8185aa6e5c1f08931e901874fb1c077695df95" + }, + { + "bytes": 1666, + "path": "linuxcnc/configs/sim/gmoccapy/sim.var", + "role": "simulation_runtime_data", + "sha256": "163bbf80485fe2fe12700c1acb4b05eff774df68176d17e4eef5de8a7024c1ae" + }, + { + "bytes": 1666, + "path": "linuxcnc/configs/sim/gmoccapy/sim.var.bak", + "role": "simulation_asset", + "sha256": "163bbf80485fe2fe12700c1acb4b05eff774df68176d17e4eef5de8a7024c1ae" + }, + { + "bytes": 657, + "path": "linuxcnc/configs/sim/gmoccapy/simulated_home.hal", + "role": "simulation_runtime_data", + "sha256": "74b8a8952dc8c74ea5901e1414244f83da5fb246b727244738d62da5a4530a40" + }, + { + "bytes": 368, + "path": "linuxcnc/configs/sim/gmoccapy/simulated_home_lathe.hal", + "role": "simulation_runtime_data", + "sha256": "64c6e20244c60d3ea66e1299c7e9619f14cb3037603fb2213d42f67a62da8ee6" + }, + { + "bytes": 2338, + "path": "linuxcnc/configs/sim/gmoccapy/spindle_sim.hal", + "role": "simulation_runtime_data", + "sha256": "f43dac948d6f198cb7f0a8855f9acc38ab2e41df8f9fd1abbe4607ea442800b0" + }, + { + "bytes": 1613, + "path": "linuxcnc/configs/sim/gmoccapy/tool.tbl", + "role": "simulation_runtime_data", + "sha256": "616621dafc73458f4e500f6a1b194b98de88cb37da9d9dc20ad876c0c01f6db1" + }, + { + "bytes": 3638, + "path": "linuxcnc/configs/sim/gmoccapy/tool_sensor.glade", + "role": "simulation_resource", + "sha256": "9f053d62e29467f3c7d95c5cfbc621710e5fd333d63c07788ca3bf993e72b6fb" + }, + { + "bytes": 130, + "path": "linuxcnc/configs/sim/gmoccapy/tool_sensor.hal", + "role": "simulation_runtime_data", + "sha256": "7329d08675db441cd75bb63f5dc7bd55b0993cb05dcacc0f311d00f15ceea371" + }, + { + "bytes": 1925, + "path": "linuxcnc/configs/sim/gmoccapy/tool_sensor.para", + "role": "simulation_runtime_data", + "sha256": "33f7254fd025fbf79b440d3e1e6939fed10b31f82d65cb07b1b1002bc4413439" + }, + { + "bytes": 5233, + "path": "linuxcnc/configs/sim/gmoccapy/v_buttonlist.glade", + "role": "simulation_resource", + "sha256": "818aee93eefe335f1a0b08c88a7b171290e17be634a6f426671f4acecdee9603" + }, + { + "bytes": 690, + "path": "linuxcnc/configs/sim/gmoccapy/v_buttonlist.hal", + "role": "simulation_runtime_data", + "sha256": "be51fde287c19649c32ce3295b1370a9463bf6d1d8f881b056b7d41fae864275" + }, + { + "bytes": 2579, + "path": "linuxcnc/configs/sim/gmoccapy/vcp_box.glade", + "role": "simulation_resource", + "sha256": "1116122b2da9db45128f23ab81860b2b6a090ed7588fb932c8367906d7c31165" + }, + { + "bytes": 254, + "path": "linuxcnc/configs/sim/gmoccapy/vcp_box.hal", + "role": "simulation_runtime_data", + "sha256": "814a7f4d89f098fdf9ff9344680f35ab54130a66ba9197591d4a5d16d46a27c6" + }, + { + "bytes": 2341, + "path": "linuxcnc/docs/man/man1/gmoccapy.1", + "role": "documentation", + "sha256": "13fe910b29cf222b74add09a6df8cd3af88560a4ad14b50ab8a0ee654d5c570d" + }, + { + "bytes": 68782, + "path": "linuxcnc/docs/src/gui/gmoccapy.adoc", + "role": "documentation", + "sha256": "c518744da581303c8911280323605350d6267503ab8b1955fa99574389d8d1c5" + }, + { + "bytes": 124441, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_3_axis.png", + "role": "documentation_asset", + "sha256": "47d5edc93bed9fa4b80de8357180fc21fa52cef817ae7c1a2c4aeb762d05ec06" + }, + { + "bytes": 144277, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_3_axis_mid.png", + "role": "documentation_asset", + "sha256": "2adc6049fdcd859d7ea7011c99e8cc222e67c7f1bd680cd8629ffabe4c67f26e" + }, + { + "bytes": 153734, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_5_axis.png", + "role": "documentation_asset", + "sha256": "f98ebf77ff76f76fc7e54f76e3a507abaa1d9024f4900a0ce39ac60557268714" + }, + { + "bytes": 187610, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_5_axis_mid.png", + "role": "documentation_asset", + "sha256": "74460d731ccc68c377d8e024de82614f144cbf314825707f2119526599f899a3" + }, + { + "bytes": 137849, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_back_tool_lathe.png", + "role": "documentation_asset", + "sha256": "3e867401c53bc6b1b846c37f4afa6e25160c79f03e76cd290c026e65d883ddfa" + }, + { + "bytes": 152951, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_embedded_tabs.png", + "role": "documentation_asset", + "sha256": "a7c6b24db08aa993a396882dfa1142934af8277bc7f6669892dca84215b644d4" + }, + { + "bytes": 236095, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_file_selection_dialog_with_keyboard.png", + "role": "documentation_asset", + "sha256": "aa49597d17aea3ea769066763996dad8d280b31df5e0a36bff6316565283de97" + }, + { + "bytes": 135434, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_getting_macro_info.png", + "role": "documentation_asset", + "sha256": "fe8dff0af22b8b01e003800e3fc95967aee8a43d88afff70234382b89dc0f993" + }, + { + "bytes": 150441, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_getting_macro_info_mid.png", + "role": "documentation_asset", + "sha256": "e18fa1514f4e15a5e38f8c8d32e13a3517db06d3c0c1bc2d7c9dbbfc6ab2d9b4" + }, + { + "bytes": 17517, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_icon_theme_symbolic.png", + "role": "documentation_asset", + "sha256": "4bd60c281c1cc9094f032fca2712a4a9ea6224bfca4a5978f89d6279127a0612" + }, + { + "bytes": 318588, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_keyboard_edit_mode.png", + "role": "documentation_asset", + "sha256": "ad486af902da9dc8c1d7456291492abf40ddcda5acb57d35f5a06e9e40f88f2f" + }, + { + "bytes": 267524, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_keyboard_edit_mode_mid.png", + "role": "documentation_asset", + "sha256": "ce07a72a86a8ed8a0027be3bc98cf480d9d97319a59015d03ce104b732b9a70c" + }, + { + "bytes": 134010, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_lathe.png", + "role": "documentation_asset", + "sha256": "ffab0957e1a4f4c5654e78f1e6db56d9af677a4c1bd7f50744beaae469556591" + }, + { + "bytes": 11804, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_manual_toolchange.png", + "role": "documentation_asset", + "sha256": "91347241b3f0db6a67485b8d63f2ccafa1accdc692e60d903531385c1f519d52" + }, + { + "bytes": 168983, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_ntb_preview.png", + "role": "documentation_asset", + "sha256": "7be0916ccd952557e05ca38de3e65d874d5fa85f7d9b22f27828ed1ec73e7dab" + }, + { + "bytes": 100294, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_ntb_preview_small.png", + "role": "documentation_asset", + "sha256": "8bcda4d48dd15d7ea412baf9bd482bc97988a609204b0b8fafef251ffb1820b0" + }, + { + "bytes": 147579, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_plasma.png", + "role": "documentation_asset", + "sha256": "310cc035686d098ee8baab8959e9e9dd8c35e7b59b436f8bcd2a55996855758d" + }, + { + "bytes": 122214, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_settings_advanced.png", + "role": "documentation_asset", + "sha256": "dd90c544ba5c776b6b1ef48b4c645cfbb93b2fdbd0843295ae54fcbfae85e997" + }, + { + "bytes": 161168, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_settings_appearance.png", + "role": "documentation_asset", + "sha256": "40bd40967eaa2c09c0c01da5924f1fc55c1b8b6bf6d79dcdd6be60b245880d84" + }, + { + "bytes": 4553, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_settings_button.png", + "role": "documentation_asset", + "sha256": "0c9ffdf33d9c4696f91fa8205c066b7e6c55c0647b75ce27f12b60b9ea8a6d86" + }, + { + "bytes": 102994, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_settings_hardware.png", + "role": "documentation_asset", + "sha256": "735f728f663362058b6b89fde66ba696398c7d7f93312d44f49ae1252d6e76c8" + }, + { + "bytes": 149665, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_sim_hardware_button.png", + "role": "documentation_asset", + "sha256": "745a74a7e330c0438f948ba4581f4df4cba76d22d6dc24411420e8349c26c6ce" + }, + { + "bytes": 164325, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_sim_hardware_button_mid.png", + "role": "documentation_asset", + "sha256": "2bdcac9bde718ffe79ae60703b17ec9b88953f082d85e8cac0f87a2cd1cb3032" + }, + { + "bytes": 8062, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_tool_info.png", + "role": "documentation_asset", + "sha256": "a854a9143badb577ed314e5ac08d5e0c503cc6c0a106af3f54bfa39067db0a79" + }, + { + "bytes": 217035, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_with_right_panel_in_MDI_mode.png", + "role": "documentation_asset", + "sha256": "c1bd54426a67ee18f3b107f876980bb0745af5d4a9f156707bb89c146abb6e32" + }, + { + "bytes": 127712, + "path": "linuxcnc/docs/src/gui/images/gmoccapy_with_right_panel_in_MDI_mode_small.png", + "role": "documentation_asset", + "sha256": "349def9769ffdedad8e15a70ac4b2f45e8520fed5100240bd2aca9c9f1f28a87" + }, + { + "bytes": 155917, + "path": "linuxcnc/docs/src/user/images/gmoccapy_4_axis.png", + "role": "documentation_asset", + "sha256": "951f796a1b3a9cb58bb7a7e09407b142196b06934c445f10a45e007695184499" + }, + { + "bytes": 0, + "path": "linuxcnc/lib/python/gmoccapy/__init__.py", + "role": "implementation", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + { + "bytes": 10577, + "path": "linuxcnc/lib/python/gmoccapy/dialogs.py", + "role": "implementation", + "sha256": "045430bbb041acd2bdfff0594b0efb14f85d01ebcae452382670944c3192f768" + }, + { + "bytes": 19430, + "path": "linuxcnc/lib/python/gmoccapy/getiniinfo.py", + "role": "implementation", + "sha256": "fa93a8998a2a7701e2b822ef202d6e3d481f7b9c5b97fc82c41bded2896c9e03" + }, + { + "bytes": 3249, + "path": "linuxcnc/lib/python/gmoccapy/icon_theme_helper.py", + "role": "implementation", + "sha256": "caf444318e1d6864f8257c5f3658d8657c164007ce54c5ec10cddd068317d8a0" + }, + { + "bytes": 14320, + "path": "linuxcnc/lib/python/gmoccapy/notification.py", + "role": "implementation", + "sha256": "81ee7e9262e3b633f506bde182918e12b196ddb655dfe980c7436e12c3b17bae" + }, + { + "bytes": 2630, + "path": "linuxcnc/lib/python/gmoccapy/player.py", + "role": "implementation", + "sha256": "82d150e2ae3b6a7aa67d056b3d5f002274b0362446ebe4782fc6c7872052b159" + }, + { + "bytes": 1617, + "path": "linuxcnc/lib/python/gmoccapy/preferences.py", + "role": "implementation", + "sha256": "6d09e9f38b7ab0feff2e436020c4a4a2db0f7126abb377ce08de05d41e46039d" + }, + { + "bytes": 1596, + "path": "linuxcnc/lib/python/gmoccapy/widgets.py", + "role": "implementation", + "sha256": "dbce55d80efcdee00e371e875983207c07facf29eca1805398d0286ef8877c02" + }, + { + "bytes": 486712, + "path": "linuxcnc/share/gmoccapy/gmoccapy.glade", + "role": "installed_ui_asset", + "sha256": "60c38418b7fb8690cc8cd942e2b758782bb734ee458d34eb63a416ba084a2112" + }, + { + "bytes": 500, + "path": "linuxcnc/share/gmoccapy/icons/Logo.png", + "role": "icon_asset", + "sha256": "efe0cb2afe7923b037214e049005ef90741f008eea4e26919488b30e0305d319" + }, + { + "bytes": 1025, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/actions/select_file.png", + "role": "icon_asset", + "sha256": "de4f584b191618b2fc7d4098001a05aea2ce7bbfb3608155064783c87c3278ff" + }, + { + "bytes": 311, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/actions/skip_optional_active.png", + "role": "icon_asset", + "sha256": "78fbe6fd2cb1a203b3964b5fb6681e0d233bd49fa094f5f15237d833a74e935a" + }, + { + "bytes": 314, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/actions/skip_optional_inactive.png", + "role": "icon_asset", + "sha256": "786ce07fabe9e277ef5f8243293a5666562d412043404551a307603a8db25e21" + }, + { + "bytes": 922, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/actions/tool_axis_p.png", + "role": "icon_asset", + "sha256": "6a84a15efc1a2e944db6440c738f26e1e9f46b1c50853052c3b0baa46eaf0df7" + }, + { + "bytes": 524, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/actions/tool_axis_x.png", + "role": "icon_asset", + "sha256": "9d8a51a3b5e3b7aedc2be209fc2be2fecaf8493364f3d6d845b5b172ce5d2723" + }, + { + "bytes": 525, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/actions/tool_axis_y.png", + "role": "icon_asset", + "sha256": "8678de1a909b1ffe897c99a9817f20f7867474897a0f7e1ac3c5921ae97e9c0a" + }, + { + "bytes": 6634, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/actions/tool_axis_y_inv.png", + "role": "icon_asset", + "sha256": "f4f2cc133669f98942b7ae305c7bc6034e3a5f1d96ab20a37bfa695ba2b58855" + }, + { + "bytes": 543, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/actions/tool_axis_z.png", + "role": "icon_asset", + "sha256": "aed4e7fe5c0332d59deb1241c6131644df7d0718ded41b77b06967e0e478429b" + }, + { + "bytes": 1119, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/actions/toolpath.png", + "role": "icon_asset", + "sha256": "5375cc7f6c725772bc2baeffbab1aa87d1ced99e043cc72356903c94e7292253" + }, + { + "bytes": 803, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/actions/window_close.png", + "role": "icon_asset", + "sha256": "7c3495a26175c521fa630a8f17b8709995729230b4dc79f17a2c0642ff2ca1ff" + }, + { + "bytes": 1781, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/status/dialog_information.png", + "role": "icon_asset", + "sha256": "88773f056c7c0971cc851407eba17f929752ab0e862315a6019fee263ebd9367" + }, + { + "bytes": 1280, + "path": "linuxcnc/share/gmoccapy/icons/classic/24x24/status/dialog_warning.png", + "role": "icon_asset", + "sha256": "ef2b0f31f196da8896ed677b135d8e767b2b9c48109fe8a9d2cdfdc0d74614b6" + }, + { + "bytes": 2127, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/clear.png", + "role": "icon_asset", + "sha256": "462d10e3d5ebf85aab1bd233b09769d678ada128a17ae2527d2159255cab8f02" + }, + { + "bytes": 2802, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/dimensions.png", + "role": "icon_asset", + "sha256": "7fbda93839aead5535524a7f60b16969a7efc9de86c1a13fcfe03a8e0e7aae71" + }, + { + "bytes": 1253, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/fullscreen_close.png", + "role": "icon_asset", + "sha256": "575dfcbc96647fe561bb7c065f8eb7f06b57b24f39a0c1f1aadff7678ea68890" + }, + { + "bytes": 1253, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/fullscreen_open.png", + "role": "icon_asset", + "sha256": "575dfcbc96647fe561bb7c065f8eb7f06b57b24f39a0c1f1aadff7678ea68890" + }, + { + "bytes": 3281, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/jog_speed_fast.png", + "role": "icon_asset", + "sha256": "fd9e88c788871c87dd09a470aee568841f860c490b2f96e231f14e7480f3e490" + }, + { + "bytes": 3294, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/jog_speed_slow.png", + "role": "icon_asset", + "sha256": "dfcd92f3444c5b778e43c91f91fafdbfbb2a921286559cf8547fb35329f357c5" + }, + { + "bytes": 1100, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/run_from_line.png", + "role": "icon_asset", + "sha256": "ae4f86eeb9ffe2429821701ff90394aa2e166132cf9e6a1a20e261a904813314" + }, + { + "bytes": 1039, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/select_file.png", + "role": "icon_asset", + "sha256": "7025e1990fe1fc52572e3ca9ce44813fde37299eb94115887b1211e41a692969" + }, + { + "bytes": 707, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/skip_optional_active.png", + "role": "icon_asset", + "sha256": "590a9be74f4337633fde6ed18f824169af2aa1aff78d78de82b063f363953b76" + }, + { + "bytes": 644, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/skip_optional_inactive.png", + "role": "icon_asset", + "sha256": "953d8ae2e180fc8ba42c611e2ce3e77fbffe63e4be4b6186743127fef5ca96d7" + }, + { + "bytes": 2902, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/zoom_in.png", + "role": "icon_asset", + "sha256": "1a3194a3bc7d89c1d65b3d8e92bec4fc64cd4de2582813ee8954da00a6503fca" + }, + { + "bytes": 2806, + "path": "linuxcnc/share/gmoccapy/icons/classic/32x32/actions/zoom_out.png", + "role": "icon_asset", + "sha256": "4c4e605f7404218725c84fbbde3ecc2a1b3fdb727d0724e5e36293df0d616e5a" + }, + { + "bytes": 1395, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/coolant_flood_active.png", + "role": "icon_asset", + "sha256": "a7de048afa66484fdb50db6fd38e0b2cbcc8fe42ce8c07a709320113228e7bbd" + }, + { + "bytes": 1804, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/coolant_flood_inactive.png", + "role": "icon_asset", + "sha256": "1c7751b016e7e4162345dd52381a2febf3843040d57b64ee76813d6aa16ea808" + }, + { + "bytes": 1580, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/coolant_mist_active.png", + "role": "icon_asset", + "sha256": "8a733e7144c9213efc2413c001225a6a23c7f0c78419ee6db73dd51a8ff60137" + }, + { + "bytes": 1877, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/coolant_mist_inactive.png", + "role": "icon_asset", + "sha256": "a3bb0f9373bfb709f5407686e077bd1dd0385cbf52a3ff1b3cf74bca75a19fd3" + }, + { + "bytes": 2574, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/edit_code.png", + "role": "icon_asset", + "sha256": "6cad9f8a61dba114e47db09a85d765f9cd35eb0be2843e5ed6e2c771bd2de523" + }, + { + "bytes": 2893, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/fullscreen_close.png", + "role": "icon_asset", + "sha256": "b97470176f71c53ef6a67d4f445af4325600418fe66a742d01bb1de8269fc9b0" + }, + { + "bytes": 2893, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/fullscreen_open.png", + "role": "icon_asset", + "sha256": "b97470176f71c53ef6a67d4f445af4325600418fe66a742d01bb1de8269fc9b0" + }, + { + "bytes": 1908, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/hsk_mill_tool.png", + "role": "icon_asset", + "sha256": "6d58c2b2b80bc2232f9b8b45085b556249b7a559b84f9ed525397811d370228e" + }, + { + "bytes": 4294, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/keyboard.png", + "role": "icon_asset", + "sha256": "cdd4824d3ceab28684aacae06a03dbc7a1a16bac808bfc5409ae92790f773fad" + }, + { + "bytes": 4294, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/keyboard_hide.png", + "role": "icon_asset", + "sha256": "8acb08007170aa2220e31be1ea5ec3087ce17e93e0e2e6472b92a74a9a9ea88c" + }, + { + "bytes": 3028, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/logout.png", + "role": "icon_asset", + "sha256": "037c5fc0b086f58fb5d3ebbd5fa75632ed5031b334854fbb0e9f02a078bbc133" + }, + { + "bytes": 2015, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/main_switch_off.png", + "role": "icon_asset", + "sha256": "882668744ba0839ede8d5fd86bb2eb125b01c7777f509df259e83c1ad2c36fdf" + }, + { + "bytes": 3475, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/main_switch_on.png", + "role": "icon_asset", + "sha256": "c05f17556ef02dd3feacc7c9eb9e986b4f0340f14092ad84b58979b2da6ecd95" + }, + { + "bytes": 3147, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mill_tool_change.png", + "role": "icon_asset", + "sha256": "491df4ffcd7bd6a6e5e8810b2e7fa4a66eb4ba12042d787ef0babab716ee0718" + }, + { + "bytes": 5387, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mode_auto_active.png", + "role": "icon_asset", + "sha256": "9cb87843da0cc3ecad895b19daf8f1f1853842f3bd943b4c644da69cfa87a440" + }, + { + "bytes": 5387, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mode_auto_inactive.png", + "role": "icon_asset", + "sha256": "9cb87843da0cc3ecad895b19daf8f1f1853842f3bd943b4c644da69cfa87a440" + }, + { + "bytes": 3909, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mode_manual_active.png", + "role": "icon_asset", + "sha256": "2d03714f7fad2c2d8f4ef264486f9af05c015e05fcdd81c30311607b493ba246" + }, + { + "bytes": 3909, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mode_manual_inactive.png", + "role": "icon_asset", + "sha256": "2d03714f7fad2c2d8f4ef264486f9af05c015e05fcdd81c30311607b493ba246" + }, + { + "bytes": 3441, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mode_mdi_active.png", + "role": "icon_asset", + "sha256": "b30c7a017c02387e989667e4db86836d2e38299a2765d944e005589e2e988abf" + }, + { + "bytes": 3441, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mode_mdi_inactive.png", + "role": "icon_asset", + "sha256": "b30c7a017c02387e989667e4db86836d2e38299a2765d944e005589e2e988abf" + }, + { + "bytes": 5321, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mode_settings_active.png", + "role": "icon_asset", + "sha256": "d36702de57c9c0cfc3c9997fc37ce0596e78b04f2c13af7747661eb9845d1f97" + }, + { + "bytes": 5321, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mode_settings_inactive.png", + "role": "icon_asset", + "sha256": "d36702de57c9c0cfc3c9997fc37ce0596e78b04f2c13af7747661eb9845d1f97" + }, + { + "bytes": 2947, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mode_user_tabs_active.png", + "role": "icon_asset", + "sha256": "2d57070fd1d3c2b5999fd24108afc3343a81a9a85d37b0d590f73a414be66ed2" + }, + { + "bytes": 2947, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/mode_user_tabs_inactive.png", + "role": "icon_asset", + "sha256": "2d57070fd1d3c2b5999fd24108afc3343a81a9a85d37b0d590f73a414be66ed2" + }, + { + "bytes": 1414, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/pause.png", + "role": "icon_asset", + "sha256": "80c6e8750fd596c60f0e7d6c548a1bf82550409c311f42cf9c9f6460563b6106" + }, + { + "bytes": 1414, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/pause_active.png", + "role": "icon_asset", + "sha256": "a99caad8c891743a7f92251fe3bf9a9ffb28c0ab5f096bbdb73981d3b2735db2" + }, + { + "bytes": 2299, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/play.png", + "role": "icon_asset", + "sha256": "2120f4c0dcd7cd167add7ce015cab3a2f3bdb114871634c72bc7f0ab6123bd36" + }, + { + "bytes": 3590, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/power_off.png", + "role": "icon_asset", + "sha256": "4ef7bebb956c5f540a0d5a1721ded9598a1758c1589572bf41cc29775c83fd68" + }, + { + "bytes": 3565, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/power_on.png", + "role": "icon_asset", + "sha256": "ef88d706209ea63334ae70474f1d838d1b33ecebb1aee079b99852b7f2b673aa" + }, + { + "bytes": 1474, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_0.png", + "role": "icon_asset", + "sha256": "e541c52f80e212fb7233f943b0f0f0eb4294a65a787bada8f64a23e4c3486aaa" + }, + { + "bytes": 1417, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_1.png", + "role": "icon_asset", + "sha256": "8c0cd191788c33293776d181cc1e216beee09fd50fffdc4b32d03e5029c293d3" + }, + { + "bytes": 1469, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_2.png", + "role": "icon_asset", + "sha256": "d6607c8e8dcc83c48d3ce135bc19c7be90ee853caf6dafb45f525a16d70e08df" + }, + { + "bytes": 1482, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_3.png", + "role": "icon_asset", + "sha256": "e2048d54b2be7c5ebbd161418f1d2b1d1c5b8b36a480a7e2957dd235be4d52e4" + }, + { + "bytes": 1445, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_4.png", + "role": "icon_asset", + "sha256": "1d041f8e022beee5966d20be5ba03888df9427513afa6fe9c2e928eec67fec49" + }, + { + "bytes": 1481, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_5.png", + "role": "icon_asset", + "sha256": "083f372446160639660ca22db974823a850ab02549349d9a17e0cc863426ccb9" + }, + { + "bytes": 1486, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_6.png", + "role": "icon_asset", + "sha256": "301e077781a04fff163bd53ff44e09483e7b966f1838033abf86e7628a777838" + }, + { + "bytes": 1458, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_7.png", + "role": "icon_asset", + "sha256": "88182909f6e51aa2be8636a1cbe8f804afb3053ff44ef4aa5e6b84ce9993bf3b" + }, + { + "bytes": 1768, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_a.png", + "role": "icon_asset", + "sha256": "4aecf2fc02df7badbb4bd5c28e008d54bba3760b468a0857e7de5c9fd975a7ed" + }, + { + "bytes": 1824, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_all.png", + "role": "icon_asset", + "sha256": "269545d20801174e6223d22d0333ca1424afe42bd940018e9390b9fb6ed468f2" + }, + { + "bytes": 1682, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_b.png", + "role": "icon_asset", + "sha256": "5049e4919dc3384b17c52f7edec04cc009b90abd09b71a869e95427e6b433d2e" + }, + { + "bytes": 1753, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_c.png", + "role": "icon_asset", + "sha256": "615fc06c75147014403880f6fa7e348725dd0d446e65aff18e8a3cbf29f36164" + }, + { + "bytes": 1134, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_u.png", + "role": "icon_asset", + "sha256": "67317261013f5995060a33a52323025f23d4fd5570fcaefaf00ca20315077f38" + }, + { + "bytes": 1214, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_v.png", + "role": "icon_asset", + "sha256": "67f9305d2567411dc3fb72bc35289334faaff1aed28934875fa73b43ac7a359a" + }, + { + "bytes": 1298, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_w.png", + "role": "icon_asset", + "sha256": "622fb9ac7accdd50eea4576ad543051cb9153f8a8eb4114bc911d8d433a8065e" + }, + { + "bytes": 1816, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_x.png", + "role": "icon_asset", + "sha256": "9e6ce1ae01b283ff3109f2a3cc87871c4edb0267b3c4d5b9c7e0684e5ea4b8ff" + }, + { + "bytes": 1708, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_y.png", + "role": "icon_asset", + "sha256": "12cec495117f021f821c53df7eb6bf361d4ca192fab4b838d4383f760adfcfb5" + }, + { + "bytes": 1698, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/ref_z.png", + "role": "icon_asset", + "sha256": "5c3c32b4e2429c346bafb1a4754cc8c8e8afcaadc02c61f1ee0548ce99600de8" + }, + { + "bytes": 4262, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/refresh.png", + "role": "icon_asset", + "sha256": "0de1c057af71aa4cf24c6a0ec33b6289c48654b829029f781195e9393da600c8" + }, + { + "bytes": 1374, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/run_from_line.png", + "role": "icon_asset", + "sha256": "0624e20ef832d6a04afffe22b055f08b1191a7cdc2118c76fdcb826b61c9e080" + }, + { + "bytes": 4074, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/save.png", + "role": "icon_asset", + "sha256": "a5ac7eb0bc204809f0cdd21a2d28d64e3f0c049883cb29779b94ca946abaa1af" + }, + { + "bytes": 4418, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/save_as.png", + "role": "icon_asset", + "sha256": "c5ea2f9f6f29f76af91fe47421971151be8bf09991daf71e2e971781ed3ca11c" + }, + { + "bytes": 1750, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/spindle_left.png", + "role": "icon_asset", + "sha256": "bf920a0027b26eda098473069fae307ede2655fd070af6bf3dfa66bac01812d5" + }, + { + "bytes": 1391, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/spindle_left_on.png", + "role": "icon_asset", + "sha256": "261342c8836b862d5a0ca137da23421f3304b65ccf2ed1f9aa4e67b1647d58a6" + }, + { + "bytes": 1738, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/spindle_right.png", + "role": "icon_asset", + "sha256": "493b5845d197d3fddc0e5e23a3ecc105e2a5d751c120e63facb6f03248080d3d" + }, + { + "bytes": 1360, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/spindle_right_on.png", + "role": "icon_asset", + "sha256": "f83553e1ceaf73988ea0a9c9179de50f819763d10dce7f8d5c9345b785065b78" + }, + { + "bytes": 1674, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/spindle_stop.png", + "role": "icon_asset", + "sha256": "022e42aa9e559ea64ae15d987786c2a2d42e5272008a591337a0d69001012a50" + }, + { + "bytes": 1674, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/spindle_stop_on.png", + "role": "icon_asset", + "sha256": "022e42aa9e559ea64ae15d987786c2a2d42e5272008a591337a0d69001012a50" + }, + { + "bytes": 2636, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/step.png", + "role": "icon_asset", + "sha256": "b5298bd7efd065e3cc26ea6dcddeb31b4296a5fff5bbe1cead19c783a6838dab" + }, + { + "bytes": 2561, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/step2.png", + "role": "icon_asset", + "sha256": "8e53707482b77af50a874725d113c4ff13388f853e34f75c0d9f0eb581f83e1e" + }, + { + "bytes": 3239, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/stop.png", + "role": "icon_asset", + "sha256": "30231a93caab7794b1c897d22cc3589a3abf382103911aadb0bc9ffedfb2e535" + }, + { + "bytes": 2621, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/touch_a.png", + "role": "icon_asset", + "sha256": "cffef1f153d31104a3221d5d64cb60037265ddeea56a7eec1ea988d9d0653098" + }, + { + "bytes": 2518, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/touch_b.png", + "role": "icon_asset", + "sha256": "389230f3e3dd70726430eb35a33158e2f064530d69fae44014615b4e02a62b8a" + }, + { + "bytes": 2577, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/touch_c.png", + "role": "icon_asset", + "sha256": "80cdfd1cf53e153c735f2ea98726e03b0a96dbda12b96c85fe296e250335d477" + }, + { + "bytes": 3173, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/touch_off.png", + "role": "icon_asset", + "sha256": "ae83323ac447432f43c68e21457c62c760d690aa4f85509aaac036057cfde9bf" + }, + { + "bytes": 2459, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/touch_u.png", + "role": "icon_asset", + "sha256": "fe6b80e562f2f35123723ad23c9ca58d5f5ed8f0208f62d366f0cbf47dfd8039" + }, + { + "bytes": 2599, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/touch_v.png", + "role": "icon_asset", + "sha256": "3fa570befa4b5b5f3148a5ec64caecaaa2122461a8882921c1dcb5b79de6ebb9" + }, + { + "bytes": 2596, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/touch_w.png", + "role": "icon_asset", + "sha256": "2198ea796ce65283ec7b84da888d533f147e547b77fb0fd6240180f397e601db" + }, + { + "bytes": 2737, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/touch_x.png", + "role": "icon_asset", + "sha256": "64c1dd06e6cc88e8d9aa6d969ee24893ec4f84ba2fc7e3db4fb8a95fe512d5ca" + }, + { + "bytes": 2632, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/touch_y.png", + "role": "icon_asset", + "sha256": "52e8a1988074bfc01fe23ee7baead317108377788ecfba33dc61f14aff93f59c" + }, + { + "bytes": 2642, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/touch_z.png", + "role": "icon_asset", + "sha256": "d3bbc3c990f4fd185de18a9ae02d0ac90647a691f2886a0fe00953e531789452" + }, + { + "bytes": 1837, + "path": "linuxcnc/share/gmoccapy/icons/classic/48x48/actions/unref_all.png", + "role": "icon_asset", + "sha256": "b7c6a7cd433acfea16dfd0aea134aadf22dafccbba96a4313c4033eeebafe043" + }, + { + "bytes": 410, + "path": "linuxcnc/share/gmoccapy/icons/classic/index.theme", + "role": "icon_asset", + "sha256": "1ddb180fb3382b941e53b68436f7f0ec2d1aff48c4a89dd3d5114cbf6f2475fc" + }, + { + "bytes": 9235, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/back_to_app.svg", + "role": "icon_asset", + "sha256": "9c81f5f14aa7a1457faf14ecd1bfc255ed16cef15a661b5f30d23f0d385450c9" + }, + { + "bytes": 28435, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/chevron_left.svg", + "role": "icon_asset", + "sha256": "75269150414f9bdfb0eee741ad36209c500d27c0b2d8462b134e0cf7b6d8f7d8" + }, + { + "bytes": 7904, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/chevron_right.svg", + "role": "icon_asset", + "sha256": "e7e79d37fb27d42437e0449affe7b8effbc3391e4450f53f0f88602049f7b30c" + }, + { + "bytes": 8218, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/chevron_up.svg", + "role": "icon_asset", + "sha256": "7d51d4af61813049ee8cf2d3091099404048a3477e5366e646b19627179cce95" + }, + { + "bytes": 21437, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/home_folder.svg", + "role": "icon_asset", + "sha256": "d2efceb512de09e1f335b00290d0d2e575d48fa59cf2e2fa1b00eaa20bba5918" + }, + { + "bytes": 1062, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/mill_tool_change_num.svg", + "role": "icon_asset", + "sha256": "9d226f53a22b48a89413d17a4f7304e689aaa96b7c5e39de992fca5b499bb8bb" + }, + { + "bytes": 2602, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/mill_tool_set_num.svg", + "role": "icon_asset", + "sha256": "b8b178cbaed89fd691136c43183759e3889eb0a808e6301fa7bff3db2d53f7b8" + }, + { + "bytes": 17406, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/new_document.svg", + "role": "icon_asset", + "sha256": "120979205507a818ae3ed80df09d5c3f15a12c5ba399a886db6ce421aec6619c" + }, + { + "bytes": 30805, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/open_file.svg", + "role": "icon_asset", + "sha256": "16d5d4ac93a43413602fb93624b3a664c04d0fe3fd0066dd60c7121f14815549" + }, + { + "bytes": 16868, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/refresh.svg", + "role": "icon_asset", + "sha256": "a43596670cfced66e14bd9ee984288a9d69490f0f08953ad13f2a6bf5e4d70fb" + }, + { + "bytes": 29894, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/save.svg", + "role": "icon_asset", + "sha256": "1f6449445b659c35880150969eee3c728e463ccc2d2151abbad77294021cc24f" + }, + { + "bytes": 31913, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/save_as.svg", + "role": "icon_asset", + "sha256": "832bde0688bd137edd42266f8cf9700034ec8494b154c41bdb50d0e52183dccb" + }, + { + "bytes": 8114, + "path": "linuxcnc/share/gmoccapy/icons/classic/scalable/actions/user_defined_folder.svg", + "role": "icon_asset", + "sha256": "da4e4493791e6e53325c72f67e61c4ef21d148edda740256beb48c7e72f062f6" + }, + { + "bytes": 260, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/back_to_app.symbolic.png", + "role": "icon_asset", + "sha256": "a1280355363b2a1b314a81d1470fa5cf8fab060d575b5e9beb481a58720b676d" + }, + { + "bytes": 159, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/chevron_left.symbolic.png", + "role": "icon_asset", + "sha256": "7f0d5c13bc20e701f485fc6dbdc17adea0fff1fe04a3d37f9d2ecf4dfe4420d7" + }, + { + "bytes": 160, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/chevron_right.symbolic.png", + "role": "icon_asset", + "sha256": "4b71db01d0548ef84f10df8b56eddb20e805810548c1c16ca09eabc39c19c16b" + }, + { + "bytes": 174, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/chevron_up.symbolic.png", + "role": "icon_asset", + "sha256": "513c31cb58101df9cb772e204cf07a2a024bfee354148b961d41e4f3bba5fec4" + }, + { + "bytes": 275, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/clear.symbolic.png", + "role": "icon_asset", + "sha256": "30b047ad0ae9daebbe99801a034e97960cc4fe2e090041aa74749da53412e284" + }, + { + "bytes": 354, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/coolant_flood_active.symbolic.png", + "role": "icon_asset", + "sha256": "b864127bb210e61d7ad1954d65617d92c5c18699f5a1bcc16aed8a1736155718" + }, + { + "bytes": 330, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/coolant_flood_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "c217c97e41dd2a1dc80e9f5ca215feea090611de9085e546269853daba16cb13" + }, + { + "bytes": 383, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/coolant_mist_active.symbolic.png", + "role": "icon_asset", + "sha256": "ebf5e86f32f68a680d84a6952085bcaf6a29e90820e8ae87e92b824f4a9cca80" + }, + { + "bytes": 361, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/coolant_mist_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "6bc670cbe9bfab6bf948bb8653793f75eca2befe229706a632e7db05d77583c6" + }, + { + "bytes": 254, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/dimensions.symbolic.png", + "role": "icon_asset", + "sha256": "d5a487f1d77518341c7f6bf6f28f19737ce7291e83bfedc1705877cf6e6518f9" + }, + { + "bytes": 256, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/edit_code.symbolic.png", + "role": "icon_asset", + "sha256": "95c0e6eaf752c431cc21e250347fe311da7fa3cba4b0bfa7a55b0b6071073f30" + }, + { + "bytes": 173, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/fullscreen_close.symbolic.png", + "role": "icon_asset", + "sha256": "01e98490a63c493991096fd6050857d4746f3940c41d2494dfd60fa0dd738cf4" + }, + { + "bytes": 171, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/fullscreen_open.symbolic.png", + "role": "icon_asset", + "sha256": "f8d4498ebeb4d7f3c0eaf52169540d3b88a4797d2f55f2acababa65fd2c47927" + }, + { + "bytes": 233, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/home_folder.symbolic.png", + "role": "icon_asset", + "sha256": "07796a08e5e53c53fccba1351b56e4074570b995c2e54ee3b145d4b1136152a3" + }, + { + "bytes": 253, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/hsk_mill_tool.symbolic.png", + "role": "icon_asset", + "sha256": "e817bf1d237217b40a90531b943fd4427816fe35f050189a889eb323a94cc913" + }, + { + "bytes": 338, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/jog_speed_fast.symbolic.png", + "role": "icon_asset", + "sha256": "78fb8d36f7204820df4accddd99794d82f3c84cd499a207c1ac187bad1049e19" + }, + { + "bytes": 285, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/jog_speed_slow.symbolic.png", + "role": "icon_asset", + "sha256": "103ae5c0836590b6fe68d5842c4587f5d5da1bf2d7dc784ddd7d2095bba5b0c3" + }, + { + "bytes": 262, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/keyboard.symbolic.png", + "role": "icon_asset", + "sha256": "85577545ae5110cfe702dcf768b11e1af193edea51d03c845051bd7b5c24d166" + }, + { + "bytes": 295, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/keyboard_hide.symbolic.png", + "role": "icon_asset", + "sha256": "5bfb42885e6dfd5531d8deff0ba67ec0bfcae8c73ab2f4760174638a4b17d979" + }, + { + "bytes": 277, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/logout.symbolic.png", + "role": "icon_asset", + "sha256": "c178f300b1233a518158b67ada86ad7f88032f93931de83f04ec2fd216c83cba" + }, + { + "bytes": 462, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/main_switch_off.symbolic.png", + "role": "icon_asset", + "sha256": "5361793524d49ed2169f193c866a01fe4dbac02db6a149c7fdd8238ff2f30c96" + }, + { + "bytes": 394, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/main_switch_on.symbolic.png", + "role": "icon_asset", + "sha256": "ce612984816536aff549fc4cc02e1295c715ba19d9602aba2bbddeb303464639" + }, + { + "bytes": 372, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mill_tool_change.symbolic.png", + "role": "icon_asset", + "sha256": "2eafa45030b0d49f4c78921e5233786512e466c8470e7d40a1e8b01a459f93f0" + }, + { + "bytes": 383, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mill_tool_change_num.symbolic.png", + "role": "icon_asset", + "sha256": "2b7eb4370ce1ef85d8cbc5b1593cc1f2e76291d4081854e38f0dbb76807743e0" + }, + { + "bytes": 401, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mill_tool_set_num.symbolic.png", + "role": "icon_asset", + "sha256": "e9fd581e1a71c62122da21f021a3708b45e915a4c3adebeb570cc8f36b7aa2a6" + }, + { + "bytes": 256, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mode_auto_active.symbolic.png", + "role": "icon_asset", + "sha256": "76516598df1e4cb3ac93d6f629623040f86a89fc4ca217d9f1e6fb844f7f3795" + }, + { + "bytes": 253, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mode_auto_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "77279a80c4bf6825a33694e3ef248f8c0d35d4ec771313672764a90cc7a0fd22" + }, + { + "bytes": 268, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mode_manual_active.symbolic.png", + "role": "icon_asset", + "sha256": "c23ae2fc2d2c9b2b5811ed9cbcf56005be5c8b75d76c7e42a3003a506be15595" + }, + { + "bytes": 266, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mode_manual_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "5398d74036bb2056629c3805e97b69d2faff94ea20e1105b1eb21cf044088be3" + }, + { + "bytes": 305, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mode_mdi_active.symbolic.png", + "role": "icon_asset", + "sha256": "2889085d9b19471923508b0a7d5499b9985841ac0ba824e626b99bb3b5107192" + }, + { + "bytes": 301, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mode_mdi_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "7f321930c1871d34b8ffa0bb607a077d32ba7cadde34832e01cbab5ee961b724" + }, + { + "bytes": 320, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mode_settings_active.symbolic.png", + "role": "icon_asset", + "sha256": "1cd35fe51036a2a3290f6f50d737ed360d8bcc494d3ec3e8dd96c80c449ec745" + }, + { + "bytes": 317, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mode_settings_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "10151aee5f15576f47dd46c9a70c88f1386d8b539fa091fab59735ea78313296" + }, + { + "bytes": 274, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mode_user_tabs_active.symbolic.png", + "role": "icon_asset", + "sha256": "54e0e9b766478332431bafa42172cce793fccbbea6c2f87ed07ecbefd4111bcd" + }, + { + "bytes": 272, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/mode_user_tabs_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "0c0ab409ae7648ee052050b38cf580f59f46c9e62b49aa8ec3d63056dba588e5" + }, + { + "bytes": 298, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/new_document.symbolic.png", + "role": "icon_asset", + "sha256": "cb5af2ccd4171815ce10e92b35e4a561fcd026d4f13fe299b6bbe70c4538e9ff" + }, + { + "bytes": 268, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/open_file.symbolic.png", + "role": "icon_asset", + "sha256": "f5adf4527779538f6f72a9982f5006fa239517fa7ef5857bcac868675f04fe45" + }, + { + "bytes": 154, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/pause.symbolic.png", + "role": "icon_asset", + "sha256": "660c43c4b1e72c331723c1e4337a453fd5c03079d9fd3d7930d28befce21cb0c" + }, + { + "bytes": 159, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/pause_active.symbolic.png", + "role": "icon_asset", + "sha256": "5548a361c3331ca336c7b842e79197782a15960023c891795ef8a97a4a87144b" + }, + { + "bytes": 175, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/play.symbolic.png", + "role": "icon_asset", + "sha256": "48ea3e17251473033687f2a1616e0ea69ef237d2df97be1429844c11b60e3727" + }, + { + "bytes": 320, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/power_off.symbolic.png", + "role": "icon_asset", + "sha256": "8c4e3509a12080ef0f45521e25baee1dd53f80ba5efffebc2c9e912bd02dda74" + }, + { + "bytes": 322, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/power_on.symbolic.png", + "role": "icon_asset", + "sha256": "48ddf332f456508c70d76ee0cdb8ac76f725089e29a31f8ea1b8dcd6c6a63c46" + }, + { + "bytes": 330, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_0.symbolic.png", + "role": "icon_asset", + "sha256": "76de46a993ed2b519b7be5cf0aa834fba15ab41b8b67e6c1b21b69797aa7fc06" + }, + { + "bytes": 281, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_1.symbolic.png", + "role": "icon_asset", + "sha256": "801b5816de7d45b1309fb5c168f50ed43c946ea63bfae2b462dc74ceead710d4" + }, + { + "bytes": 301, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_2.symbolic.png", + "role": "icon_asset", + "sha256": "800a57c21ad91ff97a73a51492ca40c1e7a81ce4a0bc25efd406386d2b3c03a5" + }, + { + "bytes": 314, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_3.symbolic.png", + "role": "icon_asset", + "sha256": "a3d576eae6a054fb989394f19109eaa0497fdc76514ff1366ffe6de4ec87d4a1" + }, + { + "bytes": 304, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_4.symbolic.png", + "role": "icon_asset", + "sha256": "b261a04e8c40ec95578d70d292472d6fcef9101579dfc6f826ce91275557724a" + }, + { + "bytes": 311, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_5.symbolic.png", + "role": "icon_asset", + "sha256": "9ce3826336ca1e672bf09e42c130f40295873e2a10096cd6d4bda1d974061ed0" + }, + { + "bytes": 317, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_6.symbolic.png", + "role": "icon_asset", + "sha256": "04af9a062f453c29b3b222963fb9753de12e61c51c6eff955c9e4b59743eee8a" + }, + { + "bytes": 295, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_7.symbolic.png", + "role": "icon_asset", + "sha256": "4d3d79080b42d15a0d7a7b84c3662d2c44bba9f964a1811e4ee8c0aaaa98b743" + }, + { + "bytes": 314, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_a.symbolic.png", + "role": "icon_asset", + "sha256": "32d49246f659f2ad3b180716cb77edae13a3dd4c1a0b8989c43e2fd424bd05f2" + }, + { + "bytes": 299, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_all.symbolic.png", + "role": "icon_asset", + "sha256": "92fddfd58ccc85367fba7c927d8ef1793f0de6bbad42643c7693391947b63b81" + }, + { + "bytes": 329, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_b.symbolic.png", + "role": "icon_asset", + "sha256": "f233d0d26a9368c4832ff189d68e62d1c7177fa9a3b24ad0a7f24e221d3c0b21" + }, + { + "bytes": 323, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_c.symbolic.png", + "role": "icon_asset", + "sha256": "a7b8e09f320c50623a0d7d178a081890c81d64c1414bb931ba35540b40895cee" + }, + { + "bytes": 309, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_u.symbolic.png", + "role": "icon_asset", + "sha256": "b1063236ddc5c8ab3b21d449f2206fa58655e2537897f008b586b1a3f11dade4" + }, + { + "bytes": 306, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_v.symbolic.png", + "role": "icon_asset", + "sha256": "673249e57a1744a1a445a97e0bc87eff2edc065cdde84a23dfb79f023226c519" + }, + { + "bytes": 338, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_w.symbolic.png", + "role": "icon_asset", + "sha256": "247cff2e6a8be41c4d28c9dfc44d7a483800f10ec319c4f1dd18817e4af05935" + }, + { + "bytes": 301, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_x.symbolic.png", + "role": "icon_asset", + "sha256": "bfa6803b363246d8d44dc324692a2b1648f13fd9d9f5e90a4e093b155b0eb22f" + }, + { + "bytes": 290, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_y.symbolic.png", + "role": "icon_asset", + "sha256": "893c76d71627f6d859e65289646480fea1b48922fce7cee5c478e4269f66f6a6" + }, + { + "bytes": 307, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/ref_z.symbolic.png", + "role": "icon_asset", + "sha256": "7faa5373fc6e6e7532640b757e49753d71cb0c4b4ff7d49e69948819308f8678" + }, + { + "bytes": 323, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/refresh.symbolic.png", + "role": "icon_asset", + "sha256": "ad87489ffae4f7d513d27add3c50c93507628e4374cba8815663e2e0aea4cc9a" + }, + { + "bytes": 205, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/run_from_line.symbolic.png", + "role": "icon_asset", + "sha256": "570f9c67a6b575fccc1d9011fa1577afa03bc2d8daaf3de49d870a6f45179a08" + }, + { + "bytes": 242, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/save.symbolic.png", + "role": "icon_asset", + "sha256": "d3e52f0b93db490832a3c7be09de2c65e7df173f1496dfd767a0f86bbaff2e25" + }, + { + "bytes": 319, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/save_as.symbolic.png", + "role": "icon_asset", + "sha256": "229f3a658e0ad01476f93ef7242142457b9336b46300e017826aebd22a6512ee" + }, + { + "bytes": 301, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/select_file.symbolic.png", + "role": "icon_asset", + "sha256": "beefcd0f741cc654be5774a738cb758db820ff3d5665752bf6fff9ae6734b6c8" + }, + { + "bytes": 277, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/skip_optional_active.symbolic.png", + "role": "icon_asset", + "sha256": "acc95bc6fd2500f5e00076e1982e19fdbe47223f8c01a2ebf2be6241c5b1951b" + }, + { + "bytes": 381, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/skip_optional_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "8db534a876a735a556c1859699a26fae2c5dba177bc0f7470959ba3169a55188" + }, + { + "bytes": 298, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/spindle_left.symbolic.png", + "role": "icon_asset", + "sha256": "cda7fae92bd47eab7a1ffe13272654292e44ad084191c2ea7ca3b58e5d9a76e9" + }, + { + "bytes": 306, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/spindle_left_on.symbolic.png", + "role": "icon_asset", + "sha256": "d3af4e3cb5c1f5ba38283fc4dc56c33fb163534580e2f92765a98b385e89ca6a" + }, + { + "bytes": 295, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/spindle_right.symbolic.png", + "role": "icon_asset", + "sha256": "872632731c05964d2dbece6eeed0a401c4d74228f247ac30ff9f1a8f6104dde2" + }, + { + "bytes": 303, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/spindle_right_on.symbolic.png", + "role": "icon_asset", + "sha256": "11b1b4019a86fd970befa045b8c27564e0da227c9836f669c000a2decb403623" + }, + { + "bytes": 315, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/spindle_stop.symbolic.png", + "role": "icon_asset", + "sha256": "93ed9aff6fb027fc359233667b3fc7c043f3155a022248aa93a4b4a77261d3d2" + }, + { + "bytes": 280, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/spindle_stop_on.symbolic.png", + "role": "icon_asset", + "sha256": "94e0bf4bed9f59c3e40832c819ce4fc6c63c366b372903a1507da3057c6374d2" + }, + { + "bytes": 253, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/step.symbolic.png", + "role": "icon_asset", + "sha256": "cb8464db02675b24363a16186a2b52f26fd240801229d49766cf99f164889878" + }, + { + "bytes": 106, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/stop.symbolic.png", + "role": "icon_asset", + "sha256": "c073ea324c23879211fa578742da1feeb04a3ed5eec92ba3aa134e93d5da603a" + }, + { + "bytes": 395, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/tool_axis_p.symbolic.png", + "role": "icon_asset", + "sha256": "70e31381d0e1674e292068823e570a488d98e9a3792fdef75bead4e2de82b3d8" + }, + { + "bytes": 343, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/tool_axis_x.symbolic.png", + "role": "icon_asset", + "sha256": "306a1ecea39fa6cb2bc49ceef4a480546eae11e49885d98307ba297d21e8969b" + }, + { + "bytes": 314, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/tool_axis_y.symbolic.png", + "role": "icon_asset", + "sha256": "6c9676243c5d44b39910cb5e089f9219f2f379e51a12920abbf23fcb8d03c885" + }, + { + "bytes": 326, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/tool_axis_y_inv.symbolic.png", + "role": "icon_asset", + "sha256": "b0fee141fae378631510d64780a50992f339add2417cce7c0082183e1c045a6e" + }, + { + "bytes": 319, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/tool_axis_z.symbolic.png", + "role": "icon_asset", + "sha256": "2ccb231c9a73522b114082c23ca0ad7983078b69f1dbc4912891f54e825eb10d" + }, + { + "bytes": 380, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/toolpath.symbolic.png", + "role": "icon_asset", + "sha256": "2026eb3c6a6c97980e89b90bfb74421fba89fe4f868053b89752bf11449a6223" + }, + { + "bytes": 318, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/touch_a.symbolic.png", + "role": "icon_asset", + "sha256": "96f39db763466e72cff18693bd5582e8787a0b68df8c5a98dc71c6a9be3d72cb" + }, + { + "bytes": 321, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/touch_b.symbolic.png", + "role": "icon_asset", + "sha256": "c6da7ed5283199b01a4edca3653f9930cbd32ce5134a218ff2f3684020fb5c31" + }, + { + "bytes": 324, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/touch_c.symbolic.png", + "role": "icon_asset", + "sha256": "70e1f4414e5358a82c8200c29307b397d1a954a1a47e59f769c1074f1b4e9107" + }, + { + "bytes": 275, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/touch_off.symbolic.png", + "role": "icon_asset", + "sha256": "dc28b3e20c00c155da6deeb80e75668c7e602068ed04dc5de77d223fffabe4d5" + }, + { + "bytes": 304, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/touch_u.symbolic.png", + "role": "icon_asset", + "sha256": "2dc7f6866578fc48d2352c212e6a1c78f65f8f66b5ba385597c7016658bddae9" + }, + { + "bytes": 331, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/touch_v.symbolic.png", + "role": "icon_asset", + "sha256": "06ea47eb16826471491d06ed8e43de95bfaebf858be7b44f5f954014ee16ca03" + }, + { + "bytes": 329, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/touch_w.symbolic.png", + "role": "icon_asset", + "sha256": "d5b14d6f9886c7e05d4efb2c965715b05dbeabc35378ef56a55ce1fa424a3b36" + }, + { + "bytes": 324, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/touch_x.symbolic.png", + "role": "icon_asset", + "sha256": "05985696d389f08c20c69e3e4d60f99ee40bc7d36b6795a327136e92aa108233" + }, + { + "bytes": 307, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/touch_y.symbolic.png", + "role": "icon_asset", + "sha256": "fa750a8e0eec5c6e566f2522999751f664fa880bde401df8fc0571f8501af904" + }, + { + "bytes": 320, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/touch_z.symbolic.png", + "role": "icon_asset", + "sha256": "617b07d512bedd0a5c9f45c11164bb4e0d9b06a4df12cdf8b0a58e8ac0d2350a" + }, + { + "bytes": 351, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/translate_a.symbolic.png", + "role": "icon_asset", + "sha256": "9e588e1169c1534b8a58bfeb282b409826c0135e4c0df13c043c204778c7b7eb" + }, + { + "bytes": 359, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/translate_b.symbolic.png", + "role": "icon_asset", + "sha256": "0e0ef86c04c0c94c2e0d7073c6fca842e8bd00234b6088d87a05d0c80fbb3a7e" + }, + { + "bytes": 359, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/translate_c.symbolic.png", + "role": "icon_asset", + "sha256": "b84ed7c8c1273751207129c00663d219e6d8dd1a8234f1f96985239f82653c77" + }, + { + "bytes": 350, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/translate_u.symbolic.png", + "role": "icon_asset", + "sha256": "9b10dde465dd97c262095ec897efe687c57b61955496dfaad80a6f4a426b2cb2" + }, + { + "bytes": 351, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/translate_v.symbolic.png", + "role": "icon_asset", + "sha256": "03cee1aef0cfa5c1413cca5835a8c5a9473a915060807abde68b4616960a7206" + }, + { + "bytes": 386, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/translate_w.symbolic.png", + "role": "icon_asset", + "sha256": "cd60be88e20c6707108d460808b7d0fbf76ade2af80914e94be097d36d85b4b7" + }, + { + "bytes": 364, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/translate_x.symbolic.png", + "role": "icon_asset", + "sha256": "31b3616e2490b5073f9d164f20bfbd2f735be93c51ddcd48d1e3d02ad5adba10" + }, + { + "bytes": 352, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/translate_y.symbolic.png", + "role": "icon_asset", + "sha256": "f85120f204d93fef3dde824784421bc68750fb83c47996e23b43b9b74245c133" + }, + { + "bytes": 372, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/translate_z.symbolic.png", + "role": "icon_asset", + "sha256": "17759e3e6c861961951a2d0fd6d71e36543f5f356da702fd977cdaa34dd21252" + }, + { + "bytes": 295, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/unref_all.symbolic.png", + "role": "icon_asset", + "sha256": "e7d78072f581f8cf6c4fefcd6eccfa9095286c326fdd76b15d55d08b8e803314" + }, + { + "bytes": 268, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/user_defined_folder.symbolic.png", + "role": "icon_asset", + "sha256": "26bdbcdadce954c5d266aa44855518bf60ed3a56364b06575dff3df8ca15b804" + }, + { + "bytes": 183, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/window_close.symbolic.png", + "role": "icon_asset", + "sha256": "49c2946b6a7ed0d149bb4faaa74758b4055eb9055648a287bad0e0fe84b22202" + }, + { + "bytes": 334, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/zoom_in.symbolic.png", + "role": "icon_asset", + "sha256": "a1cf7e2cde3929a13a55e27c5d6c590227f156d0d4744adf02be3ebd76cbd113" + }, + { + "bytes": 300, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/actions/zoom_out.symbolic.png", + "role": "icon_asset", + "sha256": "b02299639536cdd0266cc1b211d5c07e810900edbe686e27a596a9d0ccc2d36d" + }, + { + "bytes": 356, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/status/dialog_information.symbolic.png", + "role": "icon_asset", + "sha256": "9156fa8b6f666bde96e3918dbb7e2721689316dc398dfba1b4f472e9029a18c8" + }, + { + "bytes": 311, + "path": "linuxcnc/share/gmoccapy/icons/material/16x16/status/dialog_warning.symbolic.png", + "role": "icon_asset", + "sha256": "17dfd7b73207ce6ff5a918f34bf52de9721ea4bf34a4120b83de470229f4302e" + }, + { + "bytes": 365, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/back_to_app.symbolic.png", + "role": "icon_asset", + "sha256": "87938b3170d226f80a796ac50282e092818a0b7a2101f618e57617b52e955750" + }, + { + "bytes": 192, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/chevron_left.symbolic.png", + "role": "icon_asset", + "sha256": "b64381aae4a88668919db45c5f7fb85da7fb8c03579239fca1175335c113b934" + }, + { + "bytes": 181, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/chevron_right.symbolic.png", + "role": "icon_asset", + "sha256": "9b250c8be9e0e95530c9b08df98f84792eb1910200e9c413d7ab9fe6eebf2c70" + }, + { + "bytes": 222, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/chevron_up.symbolic.png", + "role": "icon_asset", + "sha256": "854b16dd350a6bf78d19bea331c6ca2368610eac287d7708eac4cd90be94fd60" + }, + { + "bytes": 368, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/clear.symbolic.png", + "role": "icon_asset", + "sha256": "1297fb829467e8be042cbb9706713751a13e5bb82f74bebcca03a2b595ae3692" + }, + { + "bytes": 577, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/coolant_flood_active.symbolic.png", + "role": "icon_asset", + "sha256": "4b6ac488ef5cff8da213164e29a1f3666b955fec18b64677993d64c0d6c2325d" + }, + { + "bytes": 535, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/coolant_flood_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "491693544d5b9142210237122139cc4a3bb7fa93b26c4a58ee9b807a350651d2" + }, + { + "bytes": 628, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/coolant_mist_active.symbolic.png", + "role": "icon_asset", + "sha256": "a7be033bd52fed2363d59b3fecce88fbf33baf69c27f670e8fb087829e96ab22" + }, + { + "bytes": 569, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/coolant_mist_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "08693d2e8110b33ef6aa24df1438aa260e35c099ba3b3bac96afe8702948a35b" + }, + { + "bytes": 353, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/dimensions.symbolic.png", + "role": "icon_asset", + "sha256": "23c54696ad3491d0ab819193b01f083604ae81c2a7035a28da3c62fdd1f46671" + }, + { + "bytes": 314, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/edit_code.symbolic.png", + "role": "icon_asset", + "sha256": "11fe2133e3f99ce42e44e3cacf3d0f974dad64489999da3d49a872c6756539cd" + }, + { + "bytes": 223, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/fullscreen_close.symbolic.png", + "role": "icon_asset", + "sha256": "38525e3a45462e4a6f00412529c06e6f2bf7fcee87e29c85a4c1ba9520a36369" + }, + { + "bytes": 188, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/fullscreen_open.symbolic.png", + "role": "icon_asset", + "sha256": "e02479e78eb1350a8982ca1ef6210ec9217303fecbe8767829c279400209be29" + }, + { + "bytes": 295, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/home_folder.symbolic.png", + "role": "icon_asset", + "sha256": "090c77638f1fbb04b2bb24695f7ac66668460c79907cc2be2bf6d44dc5c90127" + }, + { + "bytes": 355, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/hsk_mill_tool.symbolic.png", + "role": "icon_asset", + "sha256": "e2bba3953fd7c38e739e76b746ebac897cba4abbbc14c35f4423dcc06f0bdbd5" + }, + { + "bytes": 517, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/jog_speed_fast.symbolic.png", + "role": "icon_asset", + "sha256": "0e9c5a0a63c9f3f489cd7d87993d2cae35d03ac7bc1753eba4145afd22c0ac7a" + }, + { + "bytes": 391, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/jog_speed_slow.symbolic.png", + "role": "icon_asset", + "sha256": "3e7c3f0da2ff62b0565e6db8ad966bd121c94bfc33e7efeb8f9536ca681ee7ab" + }, + { + "bytes": 360, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/keyboard.symbolic.png", + "role": "icon_asset", + "sha256": "a169b7a43404bba5d0f62ed7d7f4c91d743ce330321a7f505506d32c01102a1e" + }, + { + "bytes": 404, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/keyboard_hide.symbolic.png", + "role": "icon_asset", + "sha256": "e50cfce2da5ca503c66309ae94a16412034e790d8e5bb6fb1425b1d826870a68" + }, + { + "bytes": 408, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/logout.symbolic.png", + "role": "icon_asset", + "sha256": "121d71b3d268559ced46a62040c8ef3fc5c737fe183ab36cccc78987853f0be7" + }, + { + "bytes": 699, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/main_switch_off.symbolic.png", + "role": "icon_asset", + "sha256": "7838f7520e512a58fd003dd215031d753c0c155cf3830fb1d3d68ea405a10f7d" + }, + { + "bytes": 624, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/main_switch_on.symbolic.png", + "role": "icon_asset", + "sha256": "5132d479aebbf997803f27cbced7a06a1fd27397917f8b0241f9019c0f8246ff" + }, + { + "bytes": 546, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mill_tool_change.symbolic.png", + "role": "icon_asset", + "sha256": "971c91e3115074a47520c15b2420895d66d36cd29cf074ec3788acaaa48a4fe3" + }, + { + "bytes": 606, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mill_tool_change_num.symbolic.png", + "role": "icon_asset", + "sha256": "68cea012ba113c12bdab90b90e051dc561bfd1ba0cde30b8f29ee50d222f6727" + }, + { + "bytes": 636, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mill_tool_set_num.symbolic.png", + "role": "icon_asset", + "sha256": "5d80fb22ed03c4586a858cec2177d23c5ef9476cff27ec2218d7b71b309cd851" + }, + { + "bytes": 356, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mode_auto_active.symbolic.png", + "role": "icon_asset", + "sha256": "8fb272c70308406ebcce454cd3f462de0348355f75746a6c8756df695d0c4331" + }, + { + "bytes": 345, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mode_auto_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "8f2c4c698dd5ac3c8b8f8840b10633ddcbb930ab0d1c08305b43fc2b98df3583" + }, + { + "bytes": 384, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mode_manual_active.symbolic.png", + "role": "icon_asset", + "sha256": "6d3c7cfdbda643adcf75196a4557221455a168ada757f1efb5a30b79be9407d0" + }, + { + "bytes": 372, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mode_manual_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "115ead4650357ab3577718305ef36910387525fc8651f8e46e57001e1423d39d" + }, + { + "bytes": 390, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mode_mdi_active.symbolic.png", + "role": "icon_asset", + "sha256": "2bf008d05f621be00e732c1ccb3ed456d4217325372e8af00620a060cdd7e2df" + }, + { + "bytes": 379, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mode_mdi_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "3ac1d15a8abb803bc29110612823341bf4f3faf8a53f2abdd55e96721532a4f2" + }, + { + "bytes": 518, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mode_settings_active.symbolic.png", + "role": "icon_asset", + "sha256": "89ad5dd968bd82a2301a3b7a8e09bdca036fef7ece1d3145c3bdb70f5480350f" + }, + { + "bytes": 501, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mode_settings_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "d2b449f1124dcba9014fdf0f565a8964d22c9ca8c5e78f5a8167702615915db3" + }, + { + "bytes": 356, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mode_user_tabs_active.symbolic.png", + "role": "icon_asset", + "sha256": "be3012a7cb6aa4e75f2c87e320f93efc89a6aa9036d0f7faa325a9d33961d166" + }, + { + "bytes": 351, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/mode_user_tabs_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "c03e40d5fef4e82e76e26fcbfae1d3e67a3c46dca359901f433b671bcd2678e4" + }, + { + "bytes": 340, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/new_document.symbolic.png", + "role": "icon_asset", + "sha256": "5dd575eada69d9d1739c1889530bdab4fc019c7d85f86790ec67c815aee6a4a8" + }, + { + "bytes": 331, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/open_file.symbolic.png", + "role": "icon_asset", + "sha256": "6dba5e366c08349eeb733ba6b727ae1f611cb8bf9f8f71cef0700fa5d0b0d190" + }, + { + "bytes": 163, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/pause.symbolic.png", + "role": "icon_asset", + "sha256": "b8dc7e2a2097bd412340073d2b6551f87594c3e47e00507fb0ee031367e3eda0" + }, + { + "bytes": 167, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/pause_active.symbolic.png", + "role": "icon_asset", + "sha256": "277568e9d4c3f62b4c18218a9991e22acdfe1e97db64d6f32da0b88700b09429" + }, + { + "bytes": 205, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/play.symbolic.png", + "role": "icon_asset", + "sha256": "9ffbb2bf0897337ca7622d37bce2f18c421303200807926eded9e977d91c891a" + }, + { + "bytes": 482, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/power_off.symbolic.png", + "role": "icon_asset", + "sha256": "67d910be35c63aa64a5979c06ff4fc029ef49e2d87f6400e1cc7ff158da14322" + }, + { + "bytes": 482, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/power_on.symbolic.png", + "role": "icon_asset", + "sha256": "2801a7e13df4db51580a9d12d9d38f4c36f22be87a7b55557470655298921b7a" + }, + { + "bytes": 457, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_0.symbolic.png", + "role": "icon_asset", + "sha256": "13cd503b7f495a6d7a6cb471d6f4d8913dbf2e774848fbdac10f9b73ddec866a" + }, + { + "bytes": 410, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_1.symbolic.png", + "role": "icon_asset", + "sha256": "8ece6a8a286831a639c1e34112f58b09681603bdf8683b8a41ad61cb6d94c261" + }, + { + "bytes": 442, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_2.symbolic.png", + "role": "icon_asset", + "sha256": "8aad1750a6e52d5f5ef98c6d628ad2619c39ace5549bba4dc7326d0241188d38" + }, + { + "bytes": 448, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_3.symbolic.png", + "role": "icon_asset", + "sha256": "b8df559a2b216f531c218d3a539fcc83e75f230975c46842a7533ec987eee652" + }, + { + "bytes": 422, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_4.symbolic.png", + "role": "icon_asset", + "sha256": "745435557a9149e2b02bc9bab4ab8fdfaed8bfd9aa861a5d7ed15358b0f205d0" + }, + { + "bytes": 434, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_5.symbolic.png", + "role": "icon_asset", + "sha256": "52023f31332d3ab09254a072eaade4b669004bd32de4edab5dc16c7d15bc0579" + }, + { + "bytes": 450, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_6.symbolic.png", + "role": "icon_asset", + "sha256": "52524b441d378b99c0b50463a6f5ee1e049336f5409514d03081f661a30a1837" + }, + { + "bytes": 409, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_7.symbolic.png", + "role": "icon_asset", + "sha256": "6e1b6fd7cd9fc8f530a902091b0b67c90e67aa3d9ebedc3a20318717ccca3d67" + }, + { + "bytes": 445, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_a.symbolic.png", + "role": "icon_asset", + "sha256": "b1f7ab379ffda864da51a7b2234e6289497921e6b483f2da996850a016a865f3" + }, + { + "bytes": 396, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_all.symbolic.png", + "role": "icon_asset", + "sha256": "87555e4e8fd0f9849c5b961ec9792da2004971f1eb252e50ab323fc4ef93984f" + }, + { + "bytes": 457, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_b.symbolic.png", + "role": "icon_asset", + "sha256": "b27b3dd07da5c1dc29fde621e8c364f5b53b3f2fcb3ccca78a9a6d15723e2e3f" + }, + { + "bytes": 454, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_c.symbolic.png", + "role": "icon_asset", + "sha256": "47e5234de885cf87702cec943fb7cb4527fbd28f5cdaff440835ef8a394f4420" + }, + { + "bytes": 437, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_u.symbolic.png", + "role": "icon_asset", + "sha256": "27bf11a341ebb05c58fc3be64ba307fb0942aec160f39b0278717850ec5e8de0" + }, + { + "bytes": 438, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_v.symbolic.png", + "role": "icon_asset", + "sha256": "db97f4a9d3875d221ed0a217127e709185a3f9bd11fe7b749697dd4ab593b876" + }, + { + "bytes": 480, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_w.symbolic.png", + "role": "icon_asset", + "sha256": "5454e64fc8f6cd0636afad230c8adf6e4fedac5c746859a46061baebbfb2ff4c" + }, + { + "bytes": 449, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_x.symbolic.png", + "role": "icon_asset", + "sha256": "c4cfdf6fab3e69b14b059acf873a1c4214553c32e7bf379c8f797f8055035eb4" + }, + { + "bytes": 430, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_y.symbolic.png", + "role": "icon_asset", + "sha256": "727aeba8dad2ca5d7bdc5505bb2354caacfc05375985b587c752ac62e329d041" + }, + { + "bytes": 426, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/ref_z.symbolic.png", + "role": "icon_asset", + "sha256": "30b07e6052f0682a966b5767a462d9ffbda2e3513d379177d4c0cb2ef9596c27" + }, + { + "bytes": 507, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/refresh.symbolic.png", + "role": "icon_asset", + "sha256": "d4b93980cba6d06e2979aea681cd29afdc0537a7fc64efcee7a056261e46bf85" + }, + { + "bytes": 287, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/run_from_line.symbolic.png", + "role": "icon_asset", + "sha256": "3472a39aa6c258dd38ad0ff8ddf4ebc32135bf2e233c2a8128639be019a2303f" + }, + { + "bytes": 348, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/save.symbolic.png", + "role": "icon_asset", + "sha256": "08115819a24f6a87e1cb9f3e678fc6a62a1b8e270da7e7f7670c31306caa804d" + }, + { + "bytes": 403, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/save_as.symbolic.png", + "role": "icon_asset", + "sha256": "42e59741c442355910d3b32baf02ac2e9488edb509e4b7c4e172af06c7bfc3cc" + }, + { + "bytes": 367, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/select_file.symbolic.png", + "role": "icon_asset", + "sha256": "e07f4081c33aca7e2c5280fd8df36d4333da2b0a2f939230b6591470206a9e45" + }, + { + "bytes": 388, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/skip_optional_active.symbolic.png", + "role": "icon_asset", + "sha256": "ac6cf66f5fe3c9c56885d2e218451842746378a7563678bd19f6964a74ad42d8" + }, + { + "bytes": 567, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/skip_optional_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "8b01ea7940cf4f6c36d569ff4ee9b088d9e25214130b70de349f13b651c6bed1" + }, + { + "bytes": 458, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/spindle_left.symbolic.png", + "role": "icon_asset", + "sha256": "2e3764a33383085237ec2aac451b86351f2f29f24b1c5b7250870957b68cf1cd" + }, + { + "bytes": 470, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/spindle_left_on.symbolic.png", + "role": "icon_asset", + "sha256": "8e4f99a9300d951c800f8820ff6a784be6d01eb83e25a062a237d9f3573de250" + }, + { + "bytes": 452, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/spindle_right.symbolic.png", + "role": "icon_asset", + "sha256": "d06e1cde79e6b76e0857a6f7762585487942b8102c1a7740f4f6b153607dd3bd" + }, + { + "bytes": 467, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/spindle_right_on.symbolic.png", + "role": "icon_asset", + "sha256": "2e624d9a658fd3fca3b2ad6c1f48194b7a09e5ad288fb368aa9576f130a3c082" + }, + { + "bytes": 487, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/spindle_stop.symbolic.png", + "role": "icon_asset", + "sha256": "d4b8196dc948bca942c9f049b618312bd978fe4277eb7b4b366e06acc4fd5b5e" + }, + { + "bytes": 393, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/spindle_stop_on.symbolic.png", + "role": "icon_asset", + "sha256": "601552a65d47c9fb73b490753a08ae81c00c482354f0ad26bb618b41f27c5262" + }, + { + "bytes": 330, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/step.symbolic.png", + "role": "icon_asset", + "sha256": "bbb0bc88444515f8033b0beedd6e0c1d86ca48b3d5a8d3e315dcf61808a3cb8d" + }, + { + "bytes": 114, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/stop.symbolic.png", + "role": "icon_asset", + "sha256": "ed325f6f5bf495980e50c060b71c42c5c0c248c697bf02d875bd78fcbf3a3412" + }, + { + "bytes": 570, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/tool_axis_p.symbolic.png", + "role": "icon_asset", + "sha256": "3980433ed869f0eb082e34b77fa6ddde92e7bee428f2188405aef43e5debfd6c" + }, + { + "bytes": 515, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/tool_axis_x.symbolic.png", + "role": "icon_asset", + "sha256": "8c6304413eba2a21829e2023391d445a5e6f7faad27e626451501b2a33ee86f6" + }, + { + "bytes": 462, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/tool_axis_y.symbolic.png", + "role": "icon_asset", + "sha256": "91514d3951237b17156e7ab604567661247e3c433c7b250d54e71a2feeb7488a" + }, + { + "bytes": 450, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/tool_axis_y_inv.symbolic.png", + "role": "icon_asset", + "sha256": "1e17384d98888ddef0a00587e2623b8ff93a286857af226d0d918a72eed627b9" + }, + { + "bytes": 455, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/tool_axis_z.symbolic.png", + "role": "icon_asset", + "sha256": "c38e1d67fc0b98f715a0694d485bb876c28f3c6bf39eecff80e7baa37e478c3f" + }, + { + "bytes": 544, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/toolpath.symbolic.png", + "role": "icon_asset", + "sha256": "5300e6df087757a7ebe68ea6ef4185a954aeb109a4c25376307fc0802f62a348" + }, + { + "bytes": 479, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/touch_a.symbolic.png", + "role": "icon_asset", + "sha256": "8aaaf61195a7e5489919abf5ef2ad60df7dc76d19d35bc4a15f4b007550a31a1" + }, + { + "bytes": 494, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/touch_b.symbolic.png", + "role": "icon_asset", + "sha256": "8caee29efcb0ced8eee642825aeda4e889baac97d02ac55d2b72bc76fbd7aee9" + }, + { + "bytes": 474, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/touch_c.symbolic.png", + "role": "icon_asset", + "sha256": "ea8ef9b76649ba720c8c733b169adfc10242696c39f4d67ca677810a6bf6fee9" + }, + { + "bytes": 384, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/touch_off.symbolic.png", + "role": "icon_asset", + "sha256": "e878ec1e6bfa69cb9f38b9fc2baee3de5ada4c706b14e866b06831973c9ca7e1" + }, + { + "bytes": 453, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/touch_u.symbolic.png", + "role": "icon_asset", + "sha256": "c4e9f21445998051cdd68bf7aed136c9ab304c867070c61f3013b64ea4cf3347" + }, + { + "bytes": 476, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/touch_v.symbolic.png", + "role": "icon_asset", + "sha256": "dafc155e149c9ab7873e5da1aae9d312e5ef401c8ccdcbe3a0c8090d8ed9e54c" + }, + { + "bytes": 501, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/touch_w.symbolic.png", + "role": "icon_asset", + "sha256": "3d33d1c55b4a6c53a0538abf8acb29e302dc5785d4f2e2e278f473517c65319f" + }, + { + "bytes": 479, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/touch_x.symbolic.png", + "role": "icon_asset", + "sha256": "17418a4adc0b6d8badbfa4eeedc4df346bab4fa4bd09c5841e58ce85c4a8e173" + }, + { + "bytes": 466, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/touch_y.symbolic.png", + "role": "icon_asset", + "sha256": "ff3f998a33c259318c2a99a2451b9f4b92f69c34ddf17fbcf588edb5ef9c48da" + }, + { + "bytes": 473, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/touch_z.symbolic.png", + "role": "icon_asset", + "sha256": "50ab0a52b86f16f97c5e898bc502b9b8b07f7300e9aea53ec9050eed02faf72c" + }, + { + "bytes": 514, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/translate_a.symbolic.png", + "role": "icon_asset", + "sha256": "e957822e7ddd93a2121cf00b73095afd9403c1589e0795cec55ae5800ccbd501" + }, + { + "bytes": 531, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/translate_b.symbolic.png", + "role": "icon_asset", + "sha256": "9cf1b290df195b4af4cdb276b947946bf6be92fa70388561e4a08c0440e4e6df" + }, + { + "bytes": 508, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/translate_c.symbolic.png", + "role": "icon_asset", + "sha256": "86dab5af685639e020fbaf85a6161add1f83eca8b4b0ffb6eee8f4f025386c7d" + }, + { + "bytes": 493, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/translate_u.symbolic.png", + "role": "icon_asset", + "sha256": "c58621c37f2fbfa9cec18e01f657faa822945cd0da127c33480259c0da73d6c2" + }, + { + "bytes": 514, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/translate_v.symbolic.png", + "role": "icon_asset", + "sha256": "d2e97175b1355a7a0aacba10e4d45bfc1469a09dc743a486f3789085acbd949f" + }, + { + "bytes": 549, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/translate_w.symbolic.png", + "role": "icon_asset", + "sha256": "ddf010f797dafa7642e0449fda8c8646943a06448a5d44690ae167953cdb2c78" + }, + { + "bytes": 502, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/translate_x.symbolic.png", + "role": "icon_asset", + "sha256": "00381834b3e68d2ed4d01addbafb9c2296bb252f6e5a8a354f2ea6555e441935" + }, + { + "bytes": 502, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/translate_y.symbolic.png", + "role": "icon_asset", + "sha256": "1c3630fce6cefb372ac9d26d1ace4533eec95498cd2ff689fb455fc368269ab7" + }, + { + "bytes": 506, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/translate_z.symbolic.png", + "role": "icon_asset", + "sha256": "da57f500e6a38c89cfe940d989dedf04414d3495a0a3c581555aa3a5d4f29c3f" + }, + { + "bytes": 420, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/unref_all.symbolic.png", + "role": "icon_asset", + "sha256": "2c02652a55d3be2a19e11695c234724bd4e9708db39e25c6a0cb684c5c1309ef" + }, + { + "bytes": 339, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/user_defined_folder.symbolic.png", + "role": "icon_asset", + "sha256": "4b786454383859cf8ddf0e49a85351e24182997ed13518d2ed3036471e3dca25" + }, + { + "bytes": 251, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/window_close.png", + "role": "icon_asset", + "sha256": "2111d1c1b5f3307edd677b3d0e0be41b0a7f9afa9ffd54a64883df149c016069" + }, + { + "bytes": 227, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/window_close.symbolic.png", + "role": "icon_asset", + "sha256": "c7bee3cba2d8bc35dd10980ca435e9df6bd0cf0c331b5aa796d316bf18190af0" + }, + { + "bytes": 478, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/zoom_in.symbolic.png", + "role": "icon_asset", + "sha256": "c728de85037bb1df7c4aa61dd8bb723dc9de07991f092b8a140c1a4b4cb13d88" + }, + { + "bytes": 454, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/actions/zoom_out.symbolic.png", + "role": "icon_asset", + "sha256": "af23ae176950a9b08ae964b3d72cebf3b36b7f78b2030c5b76553898f3a68bcd" + }, + { + "bytes": 545, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/status/dialog_information.symbolic.png", + "role": "icon_asset", + "sha256": "60dec4e733498acf038833c893f36b28d8a805fee0af3590f7776508647f8dd7" + }, + { + "bytes": 454, + "path": "linuxcnc/share/gmoccapy/icons/material/24x24/status/dialog_warning.symbolic.png", + "role": "icon_asset", + "sha256": "160b39f5b529567385ef10b4630bf2650e1d2f0b5aa0307b04ae18f6d81403b4" + }, + { + "bytes": 469, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/back_to_app.symbolic.png", + "role": "icon_asset", + "sha256": "6126fee33f63021f24446ed376615b02906480839b3949859a246624c943faba" + }, + { + "bytes": 216, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/chevron_left.symbolic.png", + "role": "icon_asset", + "sha256": "aa1366165576268b70f2d9f4ce4edfa7f2b3011be1579ecfa6f70746dd28b3cc" + }, + { + "bytes": 207, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/chevron_right.symbolic.png", + "role": "icon_asset", + "sha256": "85e75c9065fb624956513ab5a48dd30579f4294c26504c59571865abd6f77557" + }, + { + "bytes": 264, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/chevron_up.symbolic.png", + "role": "icon_asset", + "sha256": "82d54a25d720dcb797337b53788c30bb881882fbe7841095027ac74e0db0e31d" + }, + { + "bytes": 471, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/clear.symbolic.png", + "role": "icon_asset", + "sha256": "2d40b086fd722caaca357f6e9ea027095110a4917094d712c0c58c06970299ba" + }, + { + "bytes": 754, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/coolant_flood_active.symbolic.png", + "role": "icon_asset", + "sha256": "ca0215eec67138612882c9b297683768511f3ad9be8216711bc6c83f59a50c3b" + }, + { + "bytes": 715, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/coolant_flood_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "83676ae0c36fbee958041f8827caf0c81f4d490946b2201f00ee157ba1491612" + }, + { + "bytes": 856, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/coolant_mist_active.symbolic.png", + "role": "icon_asset", + "sha256": "ed850e391f47dc9b4337c91582158ba3af45ae6511091214d29484f8dca27c6e" + }, + { + "bytes": 789, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/coolant_mist_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "af088585244c7a3e8a4fc134adc90d3144d437eee830c87b1d955b3ebce8078c" + }, + { + "bytes": 446, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/dimensions.symbolic.png", + "role": "icon_asset", + "sha256": "f9b3b46f4512e6b1f372576f66e07c61a10364e0e485487664c5ad764846ea26" + }, + { + "bytes": 352, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/edit_code.symbolic.png", + "role": "icon_asset", + "sha256": "90603b9c82561f228009e30c731117b9aa6daaccbc19fbb0a38a1910fde12e58" + }, + { + "bytes": 270, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/fullscreen_close.symbolic.png", + "role": "icon_asset", + "sha256": "dcfbf2ecda96b913c6438f7200112d9d234ca6d657f6a2d3521a751478ee0414" + }, + { + "bytes": 237, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/fullscreen_open.symbolic.png", + "role": "icon_asset", + "sha256": "991a3d0de52963a9289445a1f90b6241a5a55a5cfd35027196249a82d6ecf318" + }, + { + "bytes": 344, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/home_folder.symbolic.png", + "role": "icon_asset", + "sha256": "269e64f67f668d6d090e8fab5331d010217ca0c22151a503437533525c1d780c" + }, + { + "bytes": 438, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/hsk_mill_tool.symbolic.png", + "role": "icon_asset", + "sha256": "ac7d55bb04fe311408ef2b6d858b6d8cf616571cc92a011a41437d0ba4803f50" + }, + { + "bytes": 727, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/jog_speed_fast.symbolic.png", + "role": "icon_asset", + "sha256": "9e73be0ed0b37835f676536076901de4871058a4f64a42a4ca4d2021f73b2c26" + }, + { + "bytes": 516, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/jog_speed_slow.symbolic.png", + "role": "icon_asset", + "sha256": "bfda1eefc8bd68f37d9256ceea1670b2e061eda4d219a2224512dcc725fd1b0e" + }, + { + "bytes": 450, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/keyboard.symbolic.png", + "role": "icon_asset", + "sha256": "9211f60a296b3444286d5afd5551b99e97a3b05d5674a2e57d8c339232b5df06" + }, + { + "bytes": 485, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/keyboard_hide.symbolic.png", + "role": "icon_asset", + "sha256": "7926b073594e68d0dc99ea6b83068905b20e4fc9e875725f0da26763f4f54cb6" + }, + { + "bytes": 494, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/logout.symbolic.png", + "role": "icon_asset", + "sha256": "419771f598d6cf384e667a29348d1d4acee0083b3bafa280523485b65b8d26ae" + }, + { + "bytes": 869, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/main_switch_off.symbolic.png", + "role": "icon_asset", + "sha256": "728f4a1dfabb40f3f1455ecc3fae132653cf6c7e4f8a93eded8e4ffd6f96c18b" + }, + { + "bytes": 812, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/main_switch_on.symbolic.png", + "role": "icon_asset", + "sha256": "5f4dc5c7bc4c371852a2251749ea36aca7ea77902b63ee03b911c1d550e0ce45" + }, + { + "bytes": 706, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mill_tool_change.symbolic.png", + "role": "icon_asset", + "sha256": "a8d2d8094cb309b8973b143b1667b04649c5398e912f7b05971faa51c0bc80cf" + }, + { + "bytes": 843, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mill_tool_change_num.symbolic.png", + "role": "icon_asset", + "sha256": "b99bd5c25eaa82475317b4a07ad94449f3360ea4c8e35552ea9832ad3807482c" + }, + { + "bytes": 892, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mill_tool_set_num.symbolic.png", + "role": "icon_asset", + "sha256": "2ac037bfc2283e611d5f0e4ec17549a65f27c6bf5eb3295124e18ad9689490e1" + }, + { + "bytes": 392, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mode_auto_active.symbolic.png", + "role": "icon_asset", + "sha256": "147511eb7ae9ea6e8d9047041f43eb790b0f2fd470916a3f368ed3d7bea7d287" + }, + { + "bytes": 385, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mode_auto_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "0319a8f4229719633f0154c369cac67ae555c3afcfac552f157cb1b4b1e1b3dc" + }, + { + "bytes": 443, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mode_manual_active.symbolic.png", + "role": "icon_asset", + "sha256": "32ce3feba2bf95ce52aa594b6520e7581234f84a12d779151c35b9b4c7f1d684" + }, + { + "bytes": 437, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mode_manual_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "e490c5a04fbdaf8259f4b7856d2ce5ca2f6d31d3815af3640b984e485f773d31" + }, + { + "bytes": 535, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mode_mdi_active.symbolic.png", + "role": "icon_asset", + "sha256": "d1d4a8aa96af299e92f24c5fa39bbd7270967c516fa76b408bffa34efa17b8e8" + }, + { + "bytes": 524, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mode_mdi_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "b46f59b166e15b84ace940ce83647d7f70c51038cc0fbff64a55dd566bf17c8e" + }, + { + "bytes": 625, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mode_settings_active.symbolic.png", + "role": "icon_asset", + "sha256": "05b4c404de7830b25bdb8dcae88d8ed5d5d3f07066589f797bc5f861849ecae0" + }, + { + "bytes": 612, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mode_settings_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "4dd48a0b538f5898fe96faec80247c4b283adbe3401aad1df7b82eb8631d7e21" + }, + { + "bytes": 446, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mode_user_tabs_active.symbolic.png", + "role": "icon_asset", + "sha256": "45c7d70ca8d4f17534067f017847f4a682361c0fb07c8bda8885de3a1935dc23" + }, + { + "bytes": 438, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/mode_user_tabs_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "1f66ebd7672b67ceea096e48015f30db644ceb65eedb27ba75e024de996cb969" + }, + { + "bytes": 428, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/new_document.symbolic.png", + "role": "icon_asset", + "sha256": "e0b464cfd6e61c2edd88d381a1e72fc4f2f5ebec73e21b85de38a545df75298f" + }, + { + "bytes": 382, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/open_file.symbolic.png", + "role": "icon_asset", + "sha256": "d7ab0914459c6316bce2b895437e0a1d9bafd93ae983982c4f9389a988e58876" + }, + { + "bytes": 169, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/pause.symbolic.png", + "role": "icon_asset", + "sha256": "aa4232d56d4b3cda4f7df8b643e280b2f746c1e280d3f2cfb778df09aa335614" + }, + { + "bytes": 175, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/pause_active.symbolic.png", + "role": "icon_asset", + "sha256": "fbb08995281a7387ec31f92ec89c9bfba5fbfe396300934dd82dde4a7edfb85a" + }, + { + "bytes": 240, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/play.symbolic.png", + "role": "icon_asset", + "sha256": "85324fa311afb2e0a0d7ff2748f9614a5562770c580a417e60919ec6f719fa7e" + }, + { + "bytes": 642, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/power_off.symbolic.png", + "role": "icon_asset", + "sha256": "8f7e510d5e72e81f8e912bdc8d253707a5529c33321d13435b3adf4b1cf7ffc9" + }, + { + "bytes": 641, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/power_on.symbolic.png", + "role": "icon_asset", + "sha256": "d525657be92ba3b791c49b25e8ada44f7c42f562394741d87236341d2edc60ea" + }, + { + "bytes": 603, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_0.symbolic.png", + "role": "icon_asset", + "sha256": "cecef7d027debe4c8269d7858f5f2b88467a16055253fb7e98b607924bc4228e" + }, + { + "bytes": 504, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_1.symbolic.png", + "role": "icon_asset", + "sha256": "b089c152fd46d387ee4f3559df430b1c59e9b630770900456de0a112217c218c" + }, + { + "bytes": 573, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_2.symbolic.png", + "role": "icon_asset", + "sha256": "faddfc415c811b7150385bcdee5010538a1d61abf9b24140e27c6d59db39cbe6" + }, + { + "bytes": 588, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_3.symbolic.png", + "role": "icon_asset", + "sha256": "80d581a9951733b18c687fd92dd2d6fc632f77932ed46173bef814a007978bcf" + }, + { + "bytes": 551, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_4.symbolic.png", + "role": "icon_asset", + "sha256": "8a1ea1d0a5ca30fdfd9e4ba7fb958b68d6c11b1836b8917c34ec209df7c8d976" + }, + { + "bytes": 602, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_5.symbolic.png", + "role": "icon_asset", + "sha256": "0a28750a445e645b2575a84f78f3403c316c7b2548d3d8334e86aea5227ed6d7" + }, + { + "bytes": 610, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_6.symbolic.png", + "role": "icon_asset", + "sha256": "12a9e33713b08e594a43812575370f9af1a1a1181f9cde4d256f9b9c2c571089" + }, + { + "bytes": 551, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_7.symbolic.png", + "role": "icon_asset", + "sha256": "02f6c59915839b72984a8f43bff2434fd8c6a73de967084e85cf1515620abe50" + }, + { + "bytes": 588, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_a.symbolic.png", + "role": "icon_asset", + "sha256": "5040711af5177a9ddb8f7feaefc7c957528380d88d78887ef22458997d2938d1" + }, + { + "bytes": 544, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_all.symbolic.png", + "role": "icon_asset", + "sha256": "0666d7486ad954fcf8d041641747137e2768049c19558fe4627e8b46de2ac525" + }, + { + "bytes": 615, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_b.symbolic.png", + "role": "icon_asset", + "sha256": "26499e04104cd8885c31ff96d35ec60eec04dd3e1daa0b21bac943c9add91279" + }, + { + "bytes": 616, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_c.symbolic.png", + "role": "icon_asset", + "sha256": "d646b0bc1b96cef56c785a7a6401cbe08f8e8d791d31edec8661225c093890c2" + }, + { + "bytes": 570, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_u.symbolic.png", + "role": "icon_asset", + "sha256": "0458f8539617c71ccc7becf62d1d037804a7ee457250d09cfaf23a172e5cf16d" + }, + { + "bytes": 595, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_v.symbolic.png", + "role": "icon_asset", + "sha256": "ad3f44dc787fd823e923da4a212cc1efb53a0ea3cc269bd119942b36902409ed" + }, + { + "bytes": 661, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_w.symbolic.png", + "role": "icon_asset", + "sha256": "61110408cb17d5c9059946edeee0d1c4e8a403bb385416fa3c4412e8148dfd84" + }, + { + "bytes": 610, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_x.symbolic.png", + "role": "icon_asset", + "sha256": "4597c5a4cd002b158f95559776ee8e029891eb2cff855ec8febabdad86906f3e" + }, + { + "bytes": 557, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_y.symbolic.png", + "role": "icon_asset", + "sha256": "d8703a47b30919b724f1d2b83b53377eb990c03b98fb2c43ed76ba9ac9172f9b" + }, + { + "bytes": 572, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/ref_z.symbolic.png", + "role": "icon_asset", + "sha256": "b5af27915653d08992db12ddd387ce25b17898d95b1bbab908938146394c0bc7" + }, + { + "bytes": 664, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/refresh.symbolic.png", + "role": "icon_asset", + "sha256": "fad093b0b45292b55985f899a1e15306bf00875568eab510ddd9c80b5a379b06" + }, + { + "bytes": 340, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/run_from_line.symbolic.png", + "role": "icon_asset", + "sha256": "089f2470ceaf0cbfbdc2a02dc5e83b53214efd49eea02b8f778316b28ff25383" + }, + { + "bytes": 436, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/save.symbolic.png", + "role": "icon_asset", + "sha256": "7421f2b27325bd7c9514d797d5b75542e81aec81d0ad0b368358b40302125284" + }, + { + "bytes": 526, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/save_as.symbolic.png", + "role": "icon_asset", + "sha256": "20338d8c6d138ed9c89382210f0475ad7d13549089afcda53ad5e35b84f8f9aa" + }, + { + "bytes": 495, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/select_file.symbolic.png", + "role": "icon_asset", + "sha256": "6a587ea3c264b16789369419c810f0d05ff083a7a7eb39c740a401141ea1b79b" + }, + { + "bytes": 506, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/skip_optional_active.symbolic.png", + "role": "icon_asset", + "sha256": "d1ae8fa61e87cda52695c63dee838cd34378bba149a593211d6d43892ea62f3b" + }, + { + "bytes": 765, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/skip_optional_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "9807e86eacda2255c79007059cd91919ee7add0e48c6f47dd8c41594b457da3c" + }, + { + "bytes": 604, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/spindle_left.symbolic.png", + "role": "icon_asset", + "sha256": "22b3489764c8e1675b836470fd48567c41a41bd1cf009b6846432756d042c849" + }, + { + "bytes": 633, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/spindle_left_on.symbolic.png", + "role": "icon_asset", + "sha256": "66637495b0bdcca7453bdd85981e113da1440fd178fd8fda4c8f80999f6e5b4c" + }, + { + "bytes": 609, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/spindle_right.symbolic.png", + "role": "icon_asset", + "sha256": "1e4e0c196cd9946210950ec73f0787cde9078346f71c0581b6e0aa08649e99ae" + }, + { + "bytes": 640, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/spindle_right_on.symbolic.png", + "role": "icon_asset", + "sha256": "d1e2a0a0278510081eec421e71419b12692c30457e110a8baf4c5bf13fed992c" + }, + { + "bytes": 657, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/spindle_stop.symbolic.png", + "role": "icon_asset", + "sha256": "adae6f11b0579a5057fdc836571e515daa864d54d9d16d3c953987553ce6ff35" + }, + { + "bytes": 544, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/spindle_stop_on.symbolic.png", + "role": "icon_asset", + "sha256": "569d1dd2df862165c467852f8f61421d53376a717ae99d21fc2df4d249fe2413" + }, + { + "bytes": 421, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/step.symbolic.png", + "role": "icon_asset", + "sha256": "e237bcb46101006d6eede92cf57ed6b09721041a446f4e65348daf2dd8416e6c" + }, + { + "bytes": 121, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/stop.symbolic.png", + "role": "icon_asset", + "sha256": "6b3c13e9f8a1db4ff325b9e0e33b8bdb29e0cb046b19079fd9c9b710a3347d16" + }, + { + "bytes": 706, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/tool_axis_p.symbolic.png", + "role": "icon_asset", + "sha256": "3b2317a43668fbdc6fec55f23b7b500dd580f24c8b890dad78f255bef43d900b" + }, + { + "bytes": 592, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/tool_axis_x.symbolic.png", + "role": "icon_asset", + "sha256": "464377c6cc8aa028a863220cae46a5d83dc65b70b8bab1c4f38c5a5b3ec3ade0" + }, + { + "bytes": 516, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/tool_axis_y.symbolic.png", + "role": "icon_asset", + "sha256": "b95e0fe39fd13a5205067b78cf0eb0d9fbdbc3ddbd2d306912a72a9cfbfc5847" + }, + { + "bytes": 511, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/tool_axis_y_inv.symbolic.png", + "role": "icon_asset", + "sha256": "2231a411ccf984df04e12160ae00538d61e841457d2025da7e7ec7594ed334c0" + }, + { + "bytes": 534, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/tool_axis_z.symbolic.png", + "role": "icon_asset", + "sha256": "2b9fbb4ff3153caf3ea9fc2bbcd5b10d50f1125a3e0d5ec90a4103e5e271058f" + }, + { + "bytes": 728, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/toolpath.symbolic.png", + "role": "icon_asset", + "sha256": "f7c80907aefc4a54b154f6d8517228cfcfb60d858fc76d7af0167f0be5fb0ca0" + }, + { + "bytes": 636, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/touch_a.symbolic.png", + "role": "icon_asset", + "sha256": "0a690a003fa37d4ec9086eed1c7762ced7da72749229ff88a91c2c22fcfcb076" + }, + { + "bytes": 633, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/touch_b.symbolic.png", + "role": "icon_asset", + "sha256": "265d94475dce06a53ef6393bdf26689b94a9f6d68dfbf9551a6703fac6e49e24" + }, + { + "bytes": 636, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/touch_c.symbolic.png", + "role": "icon_asset", + "sha256": "444e3a8f9e2d2e0a5731dace36376424f8a326f8eab0754fa193a773fd5c6e8e" + }, + { + "bytes": 523, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/touch_off.symbolic.png", + "role": "icon_asset", + "sha256": "5c3babfad3bb18845cc56a825c746802ac1c09990c2e24e3cfa45a633eba95b5" + }, + { + "bytes": 577, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/touch_u.symbolic.png", + "role": "icon_asset", + "sha256": "1aaaee6a0c59e6dd17edb6f11c9fb2ce93148805238f3eacb54df7cf9890c0cf" + }, + { + "bytes": 633, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/touch_v.symbolic.png", + "role": "icon_asset", + "sha256": "fa1692e55fbfe462699202862004704ca1c647dc0b18159cc6911380e81aca38" + }, + { + "bytes": 692, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/touch_w.symbolic.png", + "role": "icon_asset", + "sha256": "5610ff1973ca282dd3b709832e55dd68fc4ac0715e18c570d91478d1b16d9af2" + }, + { + "bytes": 638, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/touch_x.symbolic.png", + "role": "icon_asset", + "sha256": "5dbc38b0ad851ddc221690aae6862bb98e59c1bd50e3ca729ba6752482012ba1" + }, + { + "bytes": 608, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/touch_y.symbolic.png", + "role": "icon_asset", + "sha256": "641956245a3a4891c54130fa181eeca506fc16b33fc476bfb0dacd450e406237" + }, + { + "bytes": 602, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/touch_z.symbolic.png", + "role": "icon_asset", + "sha256": "f10091d0ac22015c0efe3e33e04ae1aed6ad26d34f5d2fa36cd199beb51301fb" + }, + { + "bytes": 711, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/translate_a.symbolic.png", + "role": "icon_asset", + "sha256": "3c0f69be21cd42a8eaceac4457ad9edfe480f1592ff7f5d87db2dfa3eafefd29" + }, + { + "bytes": 734, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/translate_b.symbolic.png", + "role": "icon_asset", + "sha256": "4dedfcc2272c2b38795a3852924429ea8e921f8fbae38c6447d22d928ae09120" + }, + { + "bytes": 708, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/translate_c.symbolic.png", + "role": "icon_asset", + "sha256": "23b599a4ce95076d84823c6905d62e830310c45d8b0e2dbe05d21653618522db" + }, + { + "bytes": 661, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/translate_u.symbolic.png", + "role": "icon_asset", + "sha256": "eabf1a1f989ff395b73745d13bbe38cd539cc6947356360e2c0c5745d2cb1087" + }, + { + "bytes": 719, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/translate_v.symbolic.png", + "role": "icon_asset", + "sha256": "0d18e8918bf5849c8acef710efaeee82d5fc8b5de034143de4308a039955ede1" + }, + { + "bytes": 794, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/translate_w.symbolic.png", + "role": "icon_asset", + "sha256": "cf323a434e693af262699bb2419b1d81bcff77498aab48fffd369a7265cc52f0" + }, + { + "bytes": 729, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/translate_x.symbolic.png", + "role": "icon_asset", + "sha256": "04a237f6624ba9809ce1f66cdedae3b2e9e84fabbb97e09d78b29c6527c762dd" + }, + { + "bytes": 691, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/translate_y.symbolic.png", + "role": "icon_asset", + "sha256": "22d05370671809db85a154cbb50374b6be26aff7c889bd9082e2f40b8097502b" + }, + { + "bytes": 680, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/translate_z.symbolic.png", + "role": "icon_asset", + "sha256": "93538c97415545329453963456aa935fc3ed60e6d0d44d5eebed20ad74604d74" + }, + { + "bytes": 531, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/unref_all.symbolic.png", + "role": "icon_asset", + "sha256": "9224e22ce287b8d764ef3544a4892512318b3753e5e9562021b23c118d652146" + }, + { + "bytes": 431, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/user_defined_folder.symbolic.png", + "role": "icon_asset", + "sha256": "d5e1954a0ace4cf3a4e72f99b7ab8340f2af2af7a32d86e01a4c2be348eee757" + }, + { + "bytes": 337, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/window_close.symbolic.png", + "role": "icon_asset", + "sha256": "88c6d01e50c3324b131a12500807e30c23129c2db6b93e79104149a16bf5331e" + }, + { + "bytes": 628, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/zoom_in.symbolic.png", + "role": "icon_asset", + "sha256": "fd6cd2e9ccc1468454aeebafdb91257fa103eccae714fd661d49b67df8abacff" + }, + { + "bytes": 605, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/actions/zoom_out.symbolic.png", + "role": "icon_asset", + "sha256": "cc00e40322162113f5ce63bc3ce6607cf7a3ddb70b2d4d9149950c98f5908e4e" + }, + { + "bytes": 773, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/status/dialog_information.symbolic.png", + "role": "icon_asset", + "sha256": "a0a1cc407db6f1db6ffdbce9021dae449865523d542f1b75e4cc268803c796d2" + }, + { + "bytes": 580, + "path": "linuxcnc/share/gmoccapy/icons/material/32x32/status/dialog_warning.symbolic.png", + "role": "icon_asset", + "sha256": "f866a571f24f39576a96c1c56875cfcadfc92671de855a4a0b4b2716e5594b57" + }, + { + "bytes": 615, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/back_to_app.symbolic.png", + "role": "icon_asset", + "sha256": "ed9ba8dd628c6a49c0986d93a55f24d8acc769504a9061c2875215668f20d06a" + }, + { + "bytes": 296, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/chevron_left.symbolic.png", + "role": "icon_asset", + "sha256": "dfcfd8afeceda2b7eafc54972aa1e29207cfdc1e86fb1682b4c24d5c6816c41c" + }, + { + "bytes": 288, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/chevron_right.symbolic.png", + "role": "icon_asset", + "sha256": "5f12044fb45fd7b16f591b332edb9140f03e33a9b142791953368c8ad0fe1c56" + }, + { + "bytes": 346, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/chevron_up.symbolic.png", + "role": "icon_asset", + "sha256": "0df8538f7a3411ea7a24de2b1ae278817483148addf35418d0009d8212943ad0" + }, + { + "bytes": 613, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/clear.symbolic.png", + "role": "icon_asset", + "sha256": "c6ca9eac1b4212d133596a15c9cfd0dc5f9cda40b932f255af487180d9127f1d" + }, + { + "bytes": 1195, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/coolant_flood_active.symbolic.png", + "role": "icon_asset", + "sha256": "0bbee40ae755cc0d48afd1019e59985d04c5f1b11814c2a908b75ccde6d5d95a" + }, + { + "bytes": 1156, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/coolant_flood_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "3e2bb16088548a74776d16a9495ab675314111d0d540971cde57ad76ceb76600" + }, + { + "bytes": 1374, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/coolant_mist_active.symbolic.png", + "role": "icon_asset", + "sha256": "7f1c6909af3eb64766949d98d1bec445a702984162e2bc195b97f5515f7b3cfc" + }, + { + "bytes": 1312, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/coolant_mist_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "7b2ee893d235719fb9da80f7ca629a15e1307acdbe8b510609b1b40affa995d1" + }, + { + "bytes": 696, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/dimensions.symbolic.png", + "role": "icon_asset", + "sha256": "74781ebd1b391de8c3082d89eabf9ef282d6dc23457b60435e145e8945aa1d1b" + }, + { + "bytes": 451, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/edit_code.symbolic.png", + "role": "icon_asset", + "sha256": "edfec6433d47f11bae1c4b06c086349d77afcaa645cd5aaf4df94dc071807160" + }, + { + "bytes": 375, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/fullscreen_close.symbolic.png", + "role": "icon_asset", + "sha256": "c54eaba792b189576771afcf180cd7e9b05c5e9326e3a2c38cfe71b0d986d4da" + }, + { + "bytes": 296, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/fullscreen_open.symbolic.png", + "role": "icon_asset", + "sha256": "9af768d3f8827ed8c5e6a7df623762aa1023ac6cf53901e8d929123767edc620" + }, + { + "bytes": 434, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/home_folder.symbolic.png", + "role": "icon_asset", + "sha256": "4241f246f144ebce911cfde415661c851f8ae76fabffd2b903abeb93e76624f1" + }, + { + "bytes": 606, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/hsk_mill_tool.symbolic.png", + "role": "icon_asset", + "sha256": "99f1ab931700189cd89f17ae8738490d6c4fce9b4b96a1be665ed5530df7fbbd" + }, + { + "bytes": 1102, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/jog_speed_fast.symbolic.png", + "role": "icon_asset", + "sha256": "829605118fadb5e47d34240ba0b07966f79fe56337680aa8dbfc912cb62c3465" + }, + { + "bytes": 805, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/jog_speed_slow.symbolic.png", + "role": "icon_asset", + "sha256": "6ea44cb347c5a628b4bc76d4f3b94f0ca370507dacc666b4ab598fdae65a8f29" + }, + { + "bytes": 443, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/keyboard.symbolic.png", + "role": "icon_asset", + "sha256": "dee56da0164cd15635b3a9b735a74a06d904b10b118bd9310f14df001588673d" + }, + { + "bytes": 606, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/keyboard_hide.symbolic.png", + "role": "icon_asset", + "sha256": "6261b36d92afa24fe8b390a304f02bc0974dc8dfc8f47e97d770f28308c764e4" + }, + { + "bytes": 712, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/logout.symbolic.png", + "role": "icon_asset", + "sha256": "389f8fe506c038a0eb13edd1bac1087b28704c7aa365c7358517c668c29cc77a" + }, + { + "bytes": 1415, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/main_switch_off.symbolic.png", + "role": "icon_asset", + "sha256": "38e1fb2988b82974a88367612971c5a7b7e3c88d40bc9229e375f7523f606192" + }, + { + "bytes": 1304, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/main_switch_on.symbolic.png", + "role": "icon_asset", + "sha256": "47062a860d4994a9e67f5a6892da12a61b67ec53461daab1f002f8a5d106d9d7" + }, + { + "bytes": 1072, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mill_tool_change.symbolic.png", + "role": "icon_asset", + "sha256": "4bdc2643d7382a2107d7728123bee2e3ac5fa425f9db0cbfc8035716d799a43b" + }, + { + "bytes": 1288, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mill_tool_change_num.symbolic.png", + "role": "icon_asset", + "sha256": "9ac9edcba31c5c64110916d35c92e6212a50c0fe6de3b970cff141e14f2ef65b" + }, + { + "bytes": 1407, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mill_tool_set_num.symbolic.png", + "role": "icon_asset", + "sha256": "7f56e84592ffd3c6726e641dfb92e3b22e3d4bb59efcea4cefaaea11a1ef3af8" + }, + { + "bytes": 575, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mode_auto_active.symbolic.png", + "role": "icon_asset", + "sha256": "8c6fea3893118f68e149747d472ed34a29be592b2160f2b9c0210cf157eec2f0" + }, + { + "bytes": 558, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mode_auto_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "c8e277de43bc0c277091a5de2aaeb897a900b1986f9a7989a053548645b8da7a" + }, + { + "bytes": 596, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mode_manual_active.symbolic.png", + "role": "icon_asset", + "sha256": "564c49d9c25991f6e2947dd299989c615d7ca2bdcab03c53c36982045de1c96a" + }, + { + "bytes": 574, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mode_manual_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "cedd4c19fc00155dfb6ebd1b0cce1f3774a7f85b7fa2a08bc315976428e229b1" + }, + { + "bytes": 636, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mode_mdi_active.symbolic.png", + "role": "icon_asset", + "sha256": "84cb6f4971aba02ba392ac446671a0117472a7ff71c21ff638a2de2b9707163a" + }, + { + "bytes": 621, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mode_mdi_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "0992ff8d90c86fee2f701e52ae1c19a1fdaa822bdbe6e248c00b3a55a099ba91" + }, + { + "bytes": 908, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mode_settings_active.symbolic.png", + "role": "icon_asset", + "sha256": "b96a5bf2760a8edfe838e564ed86d74332c7182516dd8bdea9f7db6968624ea8" + }, + { + "bytes": 890, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mode_settings_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "86974aa8aea3d0e2e104c1105cd4e9d705e3be7b96faeab721c38b56ecab376c" + }, + { + "bytes": 630, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mode_user_tabs_active.symbolic.png", + "role": "icon_asset", + "sha256": "3d86e3cc3b869314962d02e6ce3ef0ef2df26e565e4ae8dc3215abbecbac7f21" + }, + { + "bytes": 616, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/mode_user_tabs_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "9382a4a05e43eb78a2a4b86eb588e79c64601e315ce33c7addaa682cca3c283e" + }, + { + "bytes": 519, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/new_document.symbolic.png", + "role": "icon_asset", + "sha256": "7113d8af4b9db9350ab51b8604839d0a12c2848f9e6f34263c1bc8008118be31" + }, + { + "bytes": 518, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/open_file.symbolic.png", + "role": "icon_asset", + "sha256": "ac2811a908fcc05ab8eef9abfca67cb7af8b6026c1389ef1f073061d16455856" + }, + { + "bytes": 200, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/pause.symbolic.png", + "role": "icon_asset", + "sha256": "b27892cb1cb551bf488fdef6a147a077678df3506af81c6fb4e554b48d6730ec" + }, + { + "bytes": 201, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/pause_active.symbolic.png", + "role": "icon_asset", + "sha256": "28be80bb5774ddef4c5104bcfba5cb1440d887129b2fba77b544e23c86e00748" + }, + { + "bytes": 389, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/play.symbolic.png", + "role": "icon_asset", + "sha256": "25fe3f7e3203b61fe725f4279d364c83be791f3332406713a95fe4d15b690ba5" + }, + { + "bytes": 952, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/power_off.symbolic.png", + "role": "icon_asset", + "sha256": "c215ee8b9fa877a55bb6b82147dcbdb94d7f905ba70b6a2d8d0c82e23036a0e4" + }, + { + "bytes": 954, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/power_on.symbolic.png", + "role": "icon_asset", + "sha256": "cf7380616d092da31486ebb1d78d75f711cf17afc8830f87353f60f02f98b9a1" + }, + { + "bytes": 891, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_0.symbolic.png", + "role": "icon_asset", + "sha256": "fd97a8c13dee00fe1461095a001ce8c9000d904abf16baf4a25a64605e72d558" + }, + { + "bytes": 720, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_1.symbolic.png", + "role": "icon_asset", + "sha256": "7e40609ba344f5b82906c9700017f314265053fdcc97f2ec753597328fd71cf7" + }, + { + "bytes": 853, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_2.symbolic.png", + "role": "icon_asset", + "sha256": "b4e0019cb3022b3245abf14415ae37d0b6532a25504832dce0cb4ef284a0e54a" + }, + { + "bytes": 904, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_3.symbolic.png", + "role": "icon_asset", + "sha256": "a312bd0d51b7fd30a888cb3724f1c34770b70e63bee1453f272733edbcccf05f" + }, + { + "bytes": 837, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_4.symbolic.png", + "role": "icon_asset", + "sha256": "a8695958685c138cd2fae0759a5f5faf24c527880f4ebb1b06cc71778370e9f8" + }, + { + "bytes": 874, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_5.symbolic.png", + "role": "icon_asset", + "sha256": "2900afc0cfe5df34511e5bc503acd24bf3bc5b9ff275df5ebd37071aeadc56c4" + }, + { + "bytes": 895, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_6.symbolic.png", + "role": "icon_asset", + "sha256": "4231c94f75091285886c0e0af369f79162fbfebdac908b4fd42b1d83c8878e8f" + }, + { + "bytes": 816, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_7.symbolic.png", + "role": "icon_asset", + "sha256": "707ff94773c92ca7ee893f1cec37af2a12feade0f4a739a060ecf78e120183bf" + }, + { + "bytes": 911, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_a.symbolic.png", + "role": "icon_asset", + "sha256": "1229c27663da99ea26c4d6e3a00b7b7fa2037ca53f8f6a2318c7de474c71019f" + }, + { + "bytes": 756, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_all.symbolic.png", + "role": "icon_asset", + "sha256": "06656c8af55389885b102df5f9d4b00e36cc7b392d5d8a6e002ea2f8962afdbf" + }, + { + "bytes": 881, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_b.symbolic.png", + "role": "icon_asset", + "sha256": "469f701ec3acef6d8a8f6a8367a98c70d3a343133e516a61d2179bbdf538ea71" + }, + { + "bytes": 927, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_c.symbolic.png", + "role": "icon_asset", + "sha256": "c126a479a6537417c8ebd560009f2bee1210e2637e23932e87001c5ff8399591" + }, + { + "bytes": 841, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_u.symbolic.png", + "role": "icon_asset", + "sha256": "3ece748899d2fb230acb62c39dbaf735d918b6a0d70f1d198e7d849e376da655" + }, + { + "bytes": 901, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_v.symbolic.png", + "role": "icon_asset", + "sha256": "08b5da9aef907eea541e16e7c8da191b06c25dd8a5e37a9de5afc6aacd0b5457" + }, + { + "bytes": 1011, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_w.symbolic.png", + "role": "icon_asset", + "sha256": "facc8dd86d9cc5bd3f2cdb26b17f835e3e27c86306ae143f11e73de12faf6049" + }, + { + "bytes": 911, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_x.symbolic.png", + "role": "icon_asset", + "sha256": "731f7a01d3a0a8c3cf7efcf760fab90428f3586bbc23b27ef0a91a2adcd6efcb" + }, + { + "bytes": 833, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_y.symbolic.png", + "role": "icon_asset", + "sha256": "ae222b5f1a2dd473c8e1f9a724b05f7d21f5cc38535e46f06f75eb52d48b893e" + }, + { + "bytes": 847, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/ref_z.symbolic.png", + "role": "icon_asset", + "sha256": "2bfbc696e2e206db0fb71b00252ec69154ea759ac1821e081b9f8bdb4e2c8125" + }, + { + "bytes": 954, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/refresh.symbolic.png", + "role": "icon_asset", + "sha256": "45ec563b991aa5c4df120aa2b8aa286edd61845c7555278b87e01ca1091c5fdc" + }, + { + "bytes": 399, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/run_from_line.symbolic.png", + "role": "icon_asset", + "sha256": "c9f208afab3de9b674fb37cd95a9327edcacd70e92d50989aa40c627cb3c4a58" + }, + { + "bytes": 602, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/save.symbolic.png", + "role": "icon_asset", + "sha256": "e7886fa23bfef97f61db40b3940c5acdc468277d7c494748b2268cc700bd0894" + }, + { + "bytes": 738, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/save_as.symbolic.png", + "role": "icon_asset", + "sha256": "605f66ff95aa4419eeed75943955c3a6e50b1fc89d493b5535e086913be16f9b" + }, + { + "bytes": 654, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/select_file.symbolic.png", + "role": "icon_asset", + "sha256": "e09769d715b618fc6911c335c1e960fef1e8562b62e7a675bbbc0ed932181b36" + }, + { + "bytes": 702, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/skip_optional_active.symbolic.png", + "role": "icon_asset", + "sha256": "ff8688ad899ca20ff10b67f64495b0f3bb10a15d69b20fe3ee4027cd6f0f5970" + }, + { + "bytes": 1076, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/skip_optional_inactive.symbolic.png", + "role": "icon_asset", + "sha256": "b2dbede34c412ed16065f9b57dbaf6b978749ca5c6e431b32cc282ac6880d99a" + }, + { + "bytes": 872, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/spindle_left.symbolic.png", + "role": "icon_asset", + "sha256": "06e249a263dca4db88a35bb54840ea4b13ea1bab35e61e5477bdfaf5725599e0" + }, + { + "bytes": 904, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/spindle_left_on.symbolic.png", + "role": "icon_asset", + "sha256": "9f1bfc67bbeb3ed3e0d633815aa50e2bad10c2a40853b09390d1d8e56c14f82d" + }, + { + "bytes": 876, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/spindle_right.symbolic.png", + "role": "icon_asset", + "sha256": "b748cbe3aec056fa744d89ba653ef7872bd68497b7ae418f02269113c808e431" + }, + { + "bytes": 911, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/spindle_right_on.symbolic.png", + "role": "icon_asset", + "sha256": "c1835da738e59ea4db7f28dde2db818572aab725c2c3fc50792292be94314f88" + }, + { + "bytes": 1013, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/spindle_stop.symbolic.png", + "role": "icon_asset", + "sha256": "e1506774fbf24eecbdd6eb4e950cd9be7bdd5cc046e43a7a5d721b1d14073384" + }, + { + "bytes": 767, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/spindle_stop_on.symbolic.png", + "role": "icon_asset", + "sha256": "425eb290f03fa1883729e4da039fbb30fd13d6ec513437baafa63c3d4651ae50" + }, + { + "bytes": 548, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/step.symbolic.png", + "role": "icon_asset", + "sha256": "c6e08862693446ec95c6f9c2a68983f1135854611ee9537796057b57bd07de43" + }, + { + "bytes": 159, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/stop.symbolic.png", + "role": "icon_asset", + "sha256": "0ac2e08651cc85efd7ed541530720815cd50e6ed2f443a5d93bb896ff8b1da3f" + }, + { + "bytes": 1054, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/tool_axis_p.symbolic.png", + "role": "icon_asset", + "sha256": "819820c17b750abe9a37506c2b4792341c6222e99d170c08f13ca67289014684" + }, + { + "bytes": 959, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/tool_axis_x.symbolic.png", + "role": "icon_asset", + "sha256": "9f7e90d362d776aef194f424d4d77bc78dc6d42820009e497364679436bb7c67" + }, + { + "bytes": 793, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/tool_axis_y.symbolic.png", + "role": "icon_asset", + "sha256": "d618b7154d2c363ba65956dd1f6e431a47605d91ef1d1e48e5a34f91bd2e24be" + }, + { + "bytes": 787, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/tool_axis_y_inv.symbolic.png", + "role": "icon_asset", + "sha256": "39c579da4254558293a61f977eed4ad974b90db5ee91a362c267ab4b039495bc" + }, + { + "bytes": 781, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/tool_axis_z.symbolic.png", + "role": "icon_asset", + "sha256": "0aac2749daf5fffdd6a7f8c9b3edd2f67789a9aac1292ecc42ce6ff4e274afd4" + }, + { + "bytes": 1048, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/toolpath.symbolic.png", + "role": "icon_asset", + "sha256": "62508f7880f682140db0ffb3981221f6be39dcd7de24d95e9c8ed0d047e0fa8d" + }, + { + "bytes": 971, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/touch_a.symbolic.png", + "role": "icon_asset", + "sha256": "5f8537cf8020b883b24980a39996b4947a69fee2fb9180096059f73bdb9daf33" + }, + { + "bytes": 981, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/touch_b.symbolic.png", + "role": "icon_asset", + "sha256": "29301c6a586c5523d36da2ec32fc418db1eafcac2260dad90b2f25b4ca635f56" + }, + { + "bytes": 963, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/touch_c.symbolic.png", + "role": "icon_asset", + "sha256": "ae34c0afe2145ae2987c6b7db31d3e15b7c74f8499cfbf843177fb2e973f9b41" + }, + { + "bytes": 744, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/touch_off.symbolic.png", + "role": "icon_asset", + "sha256": "bd8c8c4dc5fc019d8833f359cd1fcd6a4a0551fe3465658804abd56edd834005" + }, + { + "bytes": 900, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/touch_u.symbolic.png", + "role": "icon_asset", + "sha256": "38e059e5eeb287636765994c713f06ad41be2e5e43fc24b19a0f9d0988830538" + }, + { + "bytes": 983, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/touch_v.symbolic.png", + "role": "icon_asset", + "sha256": "3d15d08699fc1b89b4f6e4635129a75aded86ece8cb90bdf9f1ebd3b1b45623e" + }, + { + "bytes": 1088, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/touch_w.symbolic.png", + "role": "icon_asset", + "sha256": "0746d0363350ec4071f350b8d708702e516a244d7d9f06e1416e7791ceb98499" + }, + { + "bytes": 990, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/touch_x.symbolic.png", + "role": "icon_asset", + "sha256": "d59660fb76521737e661eb0a6062fb45c4a753c18fb357bf645999c04976b522" + }, + { + "bytes": 936, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/touch_y.symbolic.png", + "role": "icon_asset", + "sha256": "88855d07440f4935d498ab1d68e3b846b5140a1f383fbe18200d059cfe90addc" + }, + { + "bytes": 919, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/touch_z.symbolic.png", + "role": "icon_asset", + "sha256": "d62483e508ee58c0486c3dd9d6a0835448d80e14e53df7dab21314e80affa1ab" + }, + { + "bytes": 1117, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/translate_a.symbolic.png", + "role": "icon_asset", + "sha256": "95dc9f75304515b9558aa1d9da1a2ae325ec2feac61751e0e640a8696ccdf5c9" + }, + { + "bytes": 1103, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/translate_b.symbolic.png", + "role": "icon_asset", + "sha256": "813b9469c5e94616fc23e56646b2b7a69687d4d350e4f1ce638f7a3ba472478d" + }, + { + "bytes": 1098, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/translate_c.symbolic.png", + "role": "icon_asset", + "sha256": "757df30d8c91bee145ece03402f9adc99d8f66bdbdcdad2b884bfd6d02370617" + }, + { + "bytes": 1032, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/translate_u.symbolic.png", + "role": "icon_asset", + "sha256": "cbb257c219b0bdd2ef79a9ffc53a5dfd1d54601bb04c6fec263c8010e4086b19" + }, + { + "bytes": 1123, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/translate_v.symbolic.png", + "role": "icon_asset", + "sha256": "6393687c4120278dfdb4dd456330f0fff0d3c9755b7dcc0c89db1a32c93e2b41" + }, + { + "bytes": 1224, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/translate_w.symbolic.png", + "role": "icon_asset", + "sha256": "64b88a678d80150adb37a4e759f928f87389cb12169c6ff93f4a9ae0e2c91c2d" + }, + { + "bytes": 1134, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/translate_x.symbolic.png", + "role": "icon_asset", + "sha256": "812899f3e9d30aa39c6887c0769d6958ea9930a43a769acb620b1a818b4fe063" + }, + { + "bytes": 1076, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/translate_y.symbolic.png", + "role": "icon_asset", + "sha256": "1f4a78456d30527373cf7208ccf55e8f55f46f8ceec63003e642c657a21f5537" + }, + { + "bytes": 1060, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/translate_z.symbolic.png", + "role": "icon_asset", + "sha256": "890f7e97357657b77a7ab2d094c143273099453323a2e4d9dc7d635793b32238" + }, + { + "bytes": 666, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/unref_all.symbolic.png", + "role": "icon_asset", + "sha256": "24c56d57ad2efd813394e3cb97bf647dbf4e9babfe99808b8067dd7aa09fda39" + }, + { + "bytes": 592, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/user_defined_folder.symbolic.png", + "role": "icon_asset", + "sha256": "8ba031fda26f5315a308c577da655070b394c799d697064aff0bbfcecdb7070b" + }, + { + "bytes": 454, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/window_close.symbolic.png", + "role": "icon_asset", + "sha256": "48ee4526df75509a0e17858510b747dc74730d1fd3e97fcaa0c200466e38f120" + }, + { + "bytes": 923, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/zoom_in.symbolic.png", + "role": "icon_asset", + "sha256": "18e743e219676c1951de5f15a420847681ceda7dfd04372cdfe05fd1fd3fa5dd" + }, + { + "bytes": 858, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/actions/zoom_out.symbolic.png", + "role": "icon_asset", + "sha256": "d3e5cd7086e72ba2df39c10550a34b7139fbcd9bc7e329cecd744eec1181d01a" + }, + { + "bytes": 1219, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/status/dialog_information.symbolic.png", + "role": "icon_asset", + "sha256": "39825bd3a8269c4cda61af43cda45b57f7fb75087346309ca54687babbee4e33" + }, + { + "bytes": 903, + "path": "linuxcnc/share/gmoccapy/icons/material/48x48/status/dialog_warning.symbolic.png", + "role": "icon_asset", + "sha256": "6db72269ea3637258fe63b2c49b203c3b27d1528dc3ce4642453b8c2bd47ae6e" + }, + { + "bytes": 11357, + "path": "linuxcnc/share/gmoccapy/icons/material/LICENSE", + "role": "icon_asset", + "sha256": "58d1e17ffe5109a7ae296caafcadfdbe6a7d176f0bc4ab01e12a689b0499d8bd" + }, + { + "bytes": 366, + "path": "linuxcnc/share/gmoccapy/icons/material/NOTICE", + "role": "icon_asset", + "sha256": "1917e07ae29680da629688a7bbed3269cc81a2f8081176dfe16d08eb4a478c33" + }, + { + "bytes": 424, + "path": "linuxcnc/share/gmoccapy/icons/material/index.theme", + "role": "icon_asset", + "sha256": "d0f28ceb56fda19783be93f06eb08d24191009e6ea44ab2290e1b33e7546bc81" + }, + { + "bytes": 319, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/back_to_app.png", + "role": "icon_asset", + "sha256": "594059cbf00657d36ff7c3fc118762a5624a4da896da049604bd9a207e2b6b5b" + }, + { + "bytes": 269, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/chevron_left.png", + "role": "icon_asset", + "sha256": "dd1c972aa219ff3a5962cfa8bc54e4a634fcc5cd067bf804aa405a0170f2667d" + }, + { + "bytes": 264, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/chevron_right.png", + "role": "icon_asset", + "sha256": "5d877fd9202652cccc3dfba5b95a578ba6ec35a394e4df4a3398cd661389386a" + }, + { + "bytes": 272, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/chevron_up.png", + "role": "icon_asset", + "sha256": "dc5bd205a8a0c6861ce9422695c3d1e3a7c8c251b9a9e8e6d5d45c6fd15ec004" + }, + { + "bytes": 393, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/clear.png", + "role": "icon_asset", + "sha256": "a58f3209a18078b94c77c16f4fe4ef98900967ace8932754a288812b8b86f1db" + }, + { + "bytes": 498, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/coolant_flood_active.png", + "role": "icon_asset", + "sha256": "6e5e2e6f73d5607ef60e883aee8a052ecdd0841369080ac53fd9360de7300021" + }, + { + "bytes": 517, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/coolant_flood_inactive.png", + "role": "icon_asset", + "sha256": "4e4dd16119fcee3c01022e75e7c4f0c8c14b0939979f9dfa92acd4f893293367" + }, + { + "bytes": 564, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/coolant_mist_active.png", + "role": "icon_asset", + "sha256": "e1cf220a1ee76f08f8ab6153511cb795f88f655fa991631c5b2eb15f9ba5d0a1" + }, + { + "bytes": 587, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/coolant_mist_inactive.png", + "role": "icon_asset", + "sha256": "7a52d2efc6b6ab86a9118a382d48e12b0963ed321dcae1a9e5a8f68a5fda4938" + }, + { + "bytes": 324, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/dimensions.png", + "role": "icon_asset", + "sha256": "56ae1a501bcd6500ade4609f7db3b5b2caac3138784f6198fba5bf2c78619df9" + }, + { + "bytes": 355, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/edit_code.png", + "role": "icon_asset", + "sha256": "174109280707b826f82ad16f310bd4ddde60781aa94591779ad72f06816debb2" + }, + { + "bytes": 246, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/fullscreen_close.png", + "role": "icon_asset", + "sha256": "6c6134ccb4f6f2568cef0f9e6a76ed7500c740102b0d0544b9b7b8cc53c8c43f" + }, + { + "bytes": 171, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/fullscreen_open.png", + "role": "icon_asset", + "sha256": "f8d4498ebeb4d7f3c0eaf52169540d3b88a4797d2f55f2acababa65fd2c47927" + }, + { + "bytes": 327, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/home_folder.png", + "role": "icon_asset", + "sha256": "934fff6d939f652b94f7c20d49e445d507c66f6396c47878cd6c30bd1827857b" + }, + { + "bytes": 306, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/hsk_mill_tool.png", + "role": "icon_asset", + "sha256": "1cfea6c3d5a7090b61550f607fb1a8c2a3b14bc6a6984c3fb30436b2ccc50ba4" + }, + { + "bytes": 525, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/jog_speed_fast.png", + "role": "icon_asset", + "sha256": "ddf0be8ae661fdbc51caaf865e9ee9a19e046b69c080e0b88ce5c596b01ffb93" + }, + { + "bytes": 401, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/jog_speed_slow.png", + "role": "icon_asset", + "sha256": "e8d291f762562bdedade489ad6122c963ae48fc81ef401016c8cafcd44381ea9" + }, + { + "bytes": 336, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/keyboard.png", + "role": "icon_asset", + "sha256": "67ec80bb9de7dc58d10452cbed351da967af29a988313765747cec32648e61c2" + }, + { + "bytes": 424, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/keyboard_hide.png", + "role": "icon_asset", + "sha256": "cd1a1a92a8837ed0c395d73fa9ef73ebe9c55176c3c61e0d9ffc481ed0c9dce2" + }, + { + "bytes": 387, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/logout.png", + "role": "icon_asset", + "sha256": "247b552c390beb8d94f6b36bf4eccacd47d0f7c32af378e6405332dc9454f156" + }, + { + "bytes": 662, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/main_switch_off.png", + "role": "icon_asset", + "sha256": "f5b3f57f347793e65410d11a364dae838fcfbf19e5b5a2d76dbde21ee793f82e" + }, + { + "bytes": 597, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/main_switch_on.png", + "role": "icon_asset", + "sha256": "e75af0932bf39dad24d4d593dc5569e180624b707fbc5b267f96fc9b3e0c3e4a" + }, + { + "bytes": 517, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mill_tool_change.png", + "role": "icon_asset", + "sha256": "3d7be5921caa662b49a5861b98cdd57bd6227401b0a9b03bff54444540de7160" + }, + { + "bytes": 541, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mill_tool_change_num.png", + "role": "icon_asset", + "sha256": "c5e2afc1b879f99edb75a2bdf2c86bbab52295b17e32f29043467960723f58de" + }, + { + "bytes": 611, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mill_tool_set_num.png", + "role": "icon_asset", + "sha256": "18d3ae12cdd242d3a5a0304f27d2c0dc2c01f66eb873ad5ac1dd66e2e15f2bc8" + }, + { + "bytes": 302, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mode_auto_active.png", + "role": "icon_asset", + "sha256": "0e0560040d6f99253b47800499dfc6ac588519c2353b5b17f9b4cf26ef1d6eed" + }, + { + "bytes": 305, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mode_auto_inactive.png", + "role": "icon_asset", + "sha256": "ebef1b45e61a04346bdcc916eec51346bb3d2ec1c487d47d69d186c89d528edf" + }, + { + "bytes": 357, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mode_manual_active.png", + "role": "icon_asset", + "sha256": "59f2fe23ff27df68412b15152b813e7bd47b32992cc1231b65f9cd94abdee8bb" + }, + { + "bytes": 360, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mode_manual_inactive.png", + "role": "icon_asset", + "sha256": "f5f7771377842bec30b9c2558357ccc996d9f4698d16f97cd9627ea2839230ea" + }, + { + "bytes": 367, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mode_mdi_active.png", + "role": "icon_asset", + "sha256": "0eae4afff830f9e5898e6647f54da53b6c99e580d28913b172237ab771be9927" + }, + { + "bytes": 366, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mode_mdi_inactive.png", + "role": "icon_asset", + "sha256": "ca1275e649de655f59aa5ef1094fdde8f32b154234a39394ad028ab5eef48007" + }, + { + "bytes": 467, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mode_settings_active.png", + "role": "icon_asset", + "sha256": "15a61b363e2653eb2d5bf4413201d89190a54f917aae3f24418b090ec38d4ca5" + }, + { + "bytes": 461, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mode_settings_inactive.png", + "role": "icon_asset", + "sha256": "7af006c91289074d2beb86fe40489e751f0ed2287834ce3d4edccfb04b9737c3" + }, + { + "bytes": 353, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mode_user_tabs_active.png", + "role": "icon_asset", + "sha256": "b7fb246c30eab56b88815a64e277f2b53ed258fdad09449fe6fdb9857c240a49" + }, + { + "bytes": 351, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/mode_user_tabs_inactive.png", + "role": "icon_asset", + "sha256": "b12e2d195fb934615f18569071c234933c2d903fb9f05d9d3bcb46475c59466b" + }, + { + "bytes": 378, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/new_document.png", + "role": "icon_asset", + "sha256": "612e367de255306430330e1031eefe2b29dea6d9ee25690a6d694cee61a78035" + }, + { + "bytes": 343, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/open_file.png", + "role": "icon_asset", + "sha256": "65ad503e41ad14909fa8329ef08f85b5763c666422d2564c082aa1371fa4e9d5" + }, + { + "bytes": 175, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/pause.png", + "role": "icon_asset", + "sha256": "a662f6e1c3e241bd209e34da6fba5bf389c24da5411be3e201bfd17cff3cdff0" + }, + { + "bytes": 174, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/pause_active.png", + "role": "icon_asset", + "sha256": "9be369e8e1d41b4131e64993d69bd1522e7e158c24e9fc7824d2a4733daee8e1" + }, + { + "bytes": 300, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/play.png", + "role": "icon_asset", + "sha256": "7e0065f748e0f8053294896092f913e23b896a45956f1ba45ff172fc9da730b6" + }, + { + "bytes": 476, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/power_off.png", + "role": "icon_asset", + "sha256": "3d622492903312a090221d3b8a75d3bb1d53c9871da0d217f5f8208d475d49d9" + }, + { + "bytes": 480, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/power_on.png", + "role": "icon_asset", + "sha256": "e9609ac3346fae11bf48d985f7124ad4a7c77fbc2ba40130aedcf7d82c45f179" + }, + { + "bytes": 499, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_0.png", + "role": "icon_asset", + "sha256": "9c75a4f4189240889f903f31879bea7a6184080224ac7f241ee0b764fb80bffe" + }, + { + "bytes": 417, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_1.png", + "role": "icon_asset", + "sha256": "48f8649bf2fc3acc50287ed63b315bff6d573431a8058f21f7966675eac565bc" + }, + { + "bytes": 480, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_2.png", + "role": "icon_asset", + "sha256": "fe79f66d1f42305052a1d7ca94a0a2c173f39b9efe6368f06258aa6c4631a21e" + }, + { + "bytes": 508, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_3.png", + "role": "icon_asset", + "sha256": "67180cf8e39b7bae9b6f8dec10f8b5583653b6b1ad4d46264de8418af2731bdc" + }, + { + "bytes": 479, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_4.png", + "role": "icon_asset", + "sha256": "444a8bb2d53c22f22ff2d0d4798a0f55482be4d65680f915ff49dc7e84fb6571" + }, + { + "bytes": 501, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_5.png", + "role": "icon_asset", + "sha256": "1a0c4ee41a4acab813f6c5a7efaee106d1b70d3473b566e17761d1c9df32251f" + }, + { + "bytes": 495, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_6.png", + "role": "icon_asset", + "sha256": "d1892f4e9d7a1395cfc9aa4b54558136da8d0c71876dfbf73953c2d0d9016663" + }, + { + "bytes": 471, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_7.png", + "role": "icon_asset", + "sha256": "9c2ca665122785e71adc086d0d0bce3131c8c4289ef769eec71fda12e3a48e6e" + }, + { + "bytes": 500, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_a.png", + "role": "icon_asset", + "sha256": "15ef480103725aac11c0b1bb521ed38c7bf9ca60053da480f2f1e471bd1afdbb" + }, + { + "bytes": 463, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_all.png", + "role": "icon_asset", + "sha256": "14da0dc18a75388547c0ec1ab020402b85d92cc9c07e2a9e9ad8b0ff6418bf50" + }, + { + "bytes": 504, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_b.png", + "role": "icon_asset", + "sha256": "22f7b4a575af40994580c607e84e5bf15b193d03671e9c351c8ca2efb78ed0db" + }, + { + "bytes": 516, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_c.png", + "role": "icon_asset", + "sha256": "8b037e6d31b22bdd7c39f55ed8d244f023176f55a13e35aa3dfeb90c2bd5adf0" + }, + { + "bytes": 481, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_u.png", + "role": "icon_asset", + "sha256": "fd8ce36bc88e6a32b7070bb826a828282d02693686b4f4e0a561477d73b738a1" + }, + { + "bytes": 491, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_v.png", + "role": "icon_asset", + "sha256": "2c9112c2719f33c1326eb800e32c69602d1da0b82fb5f9e039f10ad78a5596dd" + }, + { + "bytes": 519, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_w.png", + "role": "icon_asset", + "sha256": "f989fddb5d6426f6b763ea42661984694f28aba88add2da942b1b18ea68cf413" + }, + { + "bytes": 495, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_x.png", + "role": "icon_asset", + "sha256": "d9f24f4a9ddbb3ee825c97c9174cf161459e79b35ef4fac7fa87e9feed8a8131" + }, + { + "bytes": 462, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_y.png", + "role": "icon_asset", + "sha256": "642cb4d20a44d8445d46b0c017b7dac2d79396293fe3ce57de921c0771911b3b" + }, + { + "bytes": 482, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/ref_z.png", + "role": "icon_asset", + "sha256": "67a373c39251e7aca1a17b9324039158da84540a1a2d613b39d3af24c38bcc08" + }, + { + "bytes": 484, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/refresh.png", + "role": "icon_asset", + "sha256": "6fb351f7cbc8925a15ca5a5ddf618391fbed054392639738eb144aa238e6445c" + }, + { + "bytes": 282, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/run_from_line.png", + "role": "icon_asset", + "sha256": "0ce0e312f4fabc0a79acf7b3b2a570cba2c68e48ba4e950cdbecfd1eb0553949" + }, + { + "bytes": 315, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/save.png", + "role": "icon_asset", + "sha256": "ed8831a16470e85d0e50f63b603d9f19928c1622b9867188619536714dbf6a60" + }, + { + "bytes": 472, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/save_as.png", + "role": "icon_asset", + "sha256": "36cd099c4ab79e29f0dc9e8e506d23f02bd9a6640e11e36f274bf0d32025693f" + }, + { + "bytes": 398, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/select_file.png", + "role": "icon_asset", + "sha256": "0c014ef3a5400bdd1bb1f752fc06753c28afaa8a2c6f223cfedd97a851266451" + }, + { + "bytes": 353, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/skip_optional_active.png", + "role": "icon_asset", + "sha256": "a8cbdbba7e6cf9705cf3a3ffadfb247f40caa60276eb687fa173aa6630e50b2a" + }, + { + "bytes": 564, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/skip_optional_inactive.png", + "role": "icon_asset", + "sha256": "4da59dab9f911c3525ff33712f10d09020f273961472a551695f6a1c20eec991" + }, + { + "bytes": 411, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/spindle_left.png", + "role": "icon_asset", + "sha256": "e775a5b38c6ef537bd7a4ab8810ccbd98fafa7b4956a2d84da322b07994fdaeb" + }, + { + "bytes": 430, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/spindle_left_on.png", + "role": "icon_asset", + "sha256": "b7619455d5941707dd57571b9e58fe7cd77b40f66aacff4828723fb8ac5dcdd1" + }, + { + "bytes": 411, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/spindle_right.png", + "role": "icon_asset", + "sha256": "e732aefc66e3bd449dc12cb98f993dbbf4588cbdb49f6d173edd48ad92f3adcb" + }, + { + "bytes": 428, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/spindle_right_on.png", + "role": "icon_asset", + "sha256": "099866c99d6c33adead44ae222cf413b0dc4e06840019367fc3a92306dfe216f" + }, + { + "bytes": 398, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/spindle_stop.png", + "role": "icon_asset", + "sha256": "fc5586b6be39602aa7c9e7bb37beae2906bd22c8563ff838a28e1651a1f3f06c" + }, + { + "bytes": 367, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/spindle_stop_on.png", + "role": "icon_asset", + "sha256": "04d2db2b43571a36699a3cdfc3e37f2334631ab53e45a75141e4da5d9376b4f1" + }, + { + "bytes": 320, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/step.png", + "role": "icon_asset", + "sha256": "5859f2dd53aecfb369fafec8bc4b275c77146e27048336d3c48bf6b42e947851" + }, + { + "bytes": 117, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/stop.png", + "role": "icon_asset", + "sha256": "8af42feff963d4a8b1b4bd1e3ab640ccd68efddcef93428d52e620c35226085a" + }, + { + "bytes": 591, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/tool_axis_p.png", + "role": "icon_asset", + "sha256": "6e1eb5aedc3bc455fd4ea099c1b7ab8bf5c947fa8c92f08683c87259fcf996db" + }, + { + "bytes": 505, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/tool_axis_x.png", + "role": "icon_asset", + "sha256": "d714d3ffd69c65f7d03ade45c53a816a2e070cab3b7030d713cabc3547851600" + }, + { + "bytes": 436, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/tool_axis_y.png", + "role": "icon_asset", + "sha256": "77fb289e1660fa259f231c38b59eb973dbc7a8b2b54c891d19072c1f06ddebab" + }, + { + "bytes": 442, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/tool_axis_y_inv.png", + "role": "icon_asset", + "sha256": "7c8c945a16f9f70fcb570087223a3bd19b74694924d9f9581620a51427ff18ad" + }, + { + "bytes": 450, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/tool_axis_z.png", + "role": "icon_asset", + "sha256": "5abcc00e553c867be388ec8153a77ecaa403a8fb91974575f06e7c14d88f5a7f" + }, + { + "bytes": 597, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/toolpath.png", + "role": "icon_asset", + "sha256": "7c362f571b1498268d7775c550e85bca5c39eef33208fe67b952501597c92dca" + }, + { + "bytes": 473, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/touch_a.png", + "role": "icon_asset", + "sha256": "f673e1c81da7d54c4e99f1e195f3f7215f5d3601d7c30cdd87d2ccecb1a16a46" + }, + { + "bytes": 469, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/touch_b.png", + "role": "icon_asset", + "sha256": "a8a0d96bcf251dfee9ed00588714f5bf25256be52430bfe41dc037e3d65357f2" + }, + { + "bytes": 485, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/touch_c.png", + "role": "icon_asset", + "sha256": "b3b2d42a9f916d8eee4e79ea2ff04466a7394f54beea228434e916ce05a2e400" + }, + { + "bytes": 382, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/touch_off.png", + "role": "icon_asset", + "sha256": "e410d4a0f7b9a1760a28d96fe9057160d74cf35cdf64478e22673c2bb97632ab" + }, + { + "bytes": 446, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/touch_u.png", + "role": "icon_asset", + "sha256": "f3d16156cd97eff348f7d0921425540b1605972c7b7752dbfc3c98da76ba9391" + }, + { + "bytes": 490, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/touch_v.png", + "role": "icon_asset", + "sha256": "df13af2ae9c378c8ae276b9a2d7ce1c67d0eddb8957833c285341a5608437e3d" + }, + { + "bytes": 506, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/touch_w.png", + "role": "icon_asset", + "sha256": "dc2d0bf84974d5f46969c7919f1f1de69256ea70251bbd7d80fe6dcb6298953c" + }, + { + "bytes": 497, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/touch_x.png", + "role": "icon_asset", + "sha256": "4910a70185d578accbe2da254fb1c0afd3dc13730b79a34fadf15b35c5874034" + }, + { + "bytes": 469, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/touch_y.png", + "role": "icon_asset", + "sha256": "9248f1230969570321289f2a3770ad7c05b1de7478845619948c5b7e5eba8fb0" + }, + { + "bytes": 483, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/touch_z.png", + "role": "icon_asset", + "sha256": "9d5cf0cbc65ed24ca62aca9c98fc7bb823af0e80b80a0780ef7a02aafd5c69be" + }, + { + "bytes": 560, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/translate_a.png", + "role": "icon_asset", + "sha256": "c0470db6e26d1af13e69b527fba22bc80335cfb90adf48fbba495688e730c824" + }, + { + "bytes": 553, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/translate_b.png", + "role": "icon_asset", + "sha256": "03a2abc49034aae9118d17694b9e5f8b9edd6a1d93249ea9e174d39b0e5b93b8" + }, + { + "bytes": 563, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/translate_c.png", + "role": "icon_asset", + "sha256": "0fd107e7775a79b5fd40c8aa414f3eb74b8d9e3514f4edec42e3dbf6106f3758" + }, + { + "bytes": 531, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/translate_u.png", + "role": "icon_asset", + "sha256": "00f9e782aad4101e8ccd61e5fb3eeb32eb742a17ab81aff192310d13499a8f45" + }, + { + "bytes": 563, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/translate_v.png", + "role": "icon_asset", + "sha256": "8eed134f8d0d60bbf653f90f7bcd1471f56ca766a2f891b1924b14c077f8cc51" + }, + { + "bytes": 571, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/translate_w.png", + "role": "icon_asset", + "sha256": "0b568be6e57517aa9eca8d7b2db33af3c8c47e528b96adf4ea09c3407e2fd14d" + }, + { + "bytes": 572, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/translate_x.png", + "role": "icon_asset", + "sha256": "43e3d5f1f02ffcf446f1bec482a90616a5e34e5efe8e9fddb5d98eb90fc2e61c" + }, + { + "bytes": 542, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/translate_y.png", + "role": "icon_asset", + "sha256": "524608f6fbab2f13335eae7fa1c201452c692229f06dd531566d8c0f8c3ee5a4" + }, + { + "bytes": 564, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/translate_z.png", + "role": "icon_asset", + "sha256": "21f5af9596dfc1d0adb3d52101d2b627ed5595d6103a0bbc14d168bebab1d18a" + }, + { + "bytes": 465, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/unref_all.png", + "role": "icon_asset", + "sha256": "96edb5b0dd096d1c9635b482b803ad72168fe23424b8a3213ef71fc1ead4e78d" + }, + { + "bytes": 337, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/user_defined_folder.png", + "role": "icon_asset", + "sha256": "bc791772f57c5e06cf0c9213f917bd6759eeaf05cc2775edb81b3934c3c0b53c" + }, + { + "bytes": 316, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/window_close.png", + "role": "icon_asset", + "sha256": "38e22c1ab458832b7f9b0ab694996a4596db4631559f474515362ceca683fb3d" + }, + { + "bytes": 536, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/zoom_in.png", + "role": "icon_asset", + "sha256": "8f3fff510ec94b78558482c8c73faf029440098301507266dcc9350b5044b75e" + }, + { + "bytes": 492, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/actions/zoom_out.png", + "role": "icon_asset", + "sha256": "cb7e20f213500b375c10dc466ffcbbcdde4cd7e229b02faf2f52ff0aae81108e" + }, + { + "bytes": 482, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/status/dialog_information.png", + "role": "icon_asset", + "sha256": "540dac059d732118f33be137055fd3878518b337203e38d903912abfc025a8bf" + }, + { + "bytes": 425, + "path": "linuxcnc/share/gmoccapy/icons/material-light/16x16/status/dialog_warning.png", + "role": "icon_asset", + "sha256": "57023b19412919cbc1ab20ff817f4fab1f99e94fcd1e994d14bfbd2a522d1471" + }, + { + "bytes": 516, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/back_to_app.png", + "role": "icon_asset", + "sha256": "7126cf4c14a9eaa4f42c211e1d169b55041cd4876283611108e67992e4397fda" + }, + { + "bytes": 376, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/chevron_left.png", + "role": "icon_asset", + "sha256": "8b3e1dc224fa094d2520be5eca5b55fc718d15d8a32825cec3794724930a30f4" + }, + { + "bytes": 358, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/chevron_right.png", + "role": "icon_asset", + "sha256": "0d148c64719e906d81a12241ee7a0497d22d374f69aa8aa13ef1581fb26b98af" + }, + { + "bytes": 418, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/chevron_up.png", + "role": "icon_asset", + "sha256": "154d3c8b5aba20a9f3986dd33b43a2fb5db2f7fb65fe05b93bdc69206c0af422" + }, + { + "bytes": 545, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/clear.png", + "role": "icon_asset", + "sha256": "97fc86b11a8ce59647133879311f29710b200a2b51d10994f45ce8d90bb494f0" + }, + { + "bytes": 768, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/coolant_flood_active.png", + "role": "icon_asset", + "sha256": "b9b9f665bd07b8de1770ffd3bd0a22c6d42f6057d21ecacdecb0124f711f19b3" + }, + { + "bytes": 808, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/coolant_flood_inactive.png", + "role": "icon_asset", + "sha256": "a17344c2dca8bb8862a36cc6f5c6774679a85619b635958e4f5cfcc3117886ef" + }, + { + "bytes": 922, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/coolant_mist_active.png", + "role": "icon_asset", + "sha256": "fafdf6d602452fc85969b83347e2eb51a9595f27e9adf96aae4c85225d8a748e" + }, + { + "bytes": 935, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/coolant_mist_inactive.png", + "role": "icon_asset", + "sha256": "bf38a4e22e9e676cc149c3f566c0ee4f8a2d29f8ea825a20134d2f8f61cee6bf" + }, + { + "bytes": 493, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/dimensions.png", + "role": "icon_asset", + "sha256": "87a574642905a089ad8733179fdf04e3569bc506006c8b5ef8197046dc678b21" + }, + { + "bytes": 445, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/edit_code.png", + "role": "icon_asset", + "sha256": "fcb41aecd3df0c1b2a1495035622f55172be9c97641492fbe2068d97a60047fe" + }, + { + "bytes": 400, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/fullscreen_close.png", + "role": "icon_asset", + "sha256": "8208a7f37fa54ac118b9a0ae9917b9f4fc20633d65766e06dd8f59b0fc3b4dcb" + }, + { + "bytes": 188, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/fullscreen_open.png", + "role": "icon_asset", + "sha256": "e02479e78eb1350a8982ca1ef6210ec9217303fecbe8767829c279400209be29" + }, + { + "bytes": 424, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/home_folder.png", + "role": "icon_asset", + "sha256": "7b78912d0ab2809b7b0dd1dfc560e792a0ac38bc49c2db131373bdb9f4c3f8ec" + }, + { + "bytes": 473, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/hsk_mill_tool.png", + "role": "icon_asset", + "sha256": "28b028595339baf25df2e663d92ed1c4d3198d58978ed61d4b51f06f4a86ccee" + }, + { + "bytes": 851, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/jog_speed_fast.png", + "role": "icon_asset", + "sha256": "af74ff37d942449925999e60e0d43de581724ca2d44fd6c4baa345e6121af4a4" + }, + { + "bytes": 609, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/jog_speed_slow.png", + "role": "icon_asset", + "sha256": "5f374da3fdfbdbbe8cbf0eb7fadb4f8189f5a7126699571e9b85b0653b0f8a7f" + }, + { + "bytes": 520, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/keyboard.png", + "role": "icon_asset", + "sha256": "80bfee8f50ba30d0e2618a49ba019b6ad4ca5dd695178b55e92643f733200156" + }, + { + "bytes": 558, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/keyboard_hide.png", + "role": "icon_asset", + "sha256": "70890e34d1cfedadb0773609e36656ffc42802c54931b612507c854608c87666" + }, + { + "bytes": 563, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/logout.png", + "role": "icon_asset", + "sha256": "7a34da944e7ef10874067ca4ec88af576986dfdf4511b7b91a62d7cf855c5f7a" + }, + { + "bytes": 1108, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/main_switch_off.png", + "role": "icon_asset", + "sha256": "4a4e11570ebe526583e97690489c5c517a7167dc5be140394c55c02f4300a479" + }, + { + "bytes": 988, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/main_switch_on.png", + "role": "icon_asset", + "sha256": "91f45b5121209b9d7479359e2ce34215ef6fe40d93df58dc567655c733566d83" + }, + { + "bytes": 729, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mill_tool_change.png", + "role": "icon_asset", + "sha256": "aac6851ad974c049676f2949e6575e38c4883d6c96303fc5e7b7d455a9df8170" + }, + { + "bytes": 853, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mill_tool_change_num.png", + "role": "icon_asset", + "sha256": "183e01a832397bd0c9b01940da88f7706f5637baba2acaa7a93b001304895b2b" + }, + { + "bytes": 976, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mill_tool_set_num.png", + "role": "icon_asset", + "sha256": "fffab8f14dc93809b186c1ed1c3cc5d881b2aeeb981965a43178f534fd876810" + }, + { + "bytes": 479, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mode_auto_active.png", + "role": "icon_asset", + "sha256": "07641bb243ca282f8a67bf03e3f08bc1a3ba33292bda3bd948ef7d66ab24eaf1" + }, + { + "bytes": 485, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mode_auto_inactive.png", + "role": "icon_asset", + "sha256": "d9898e4fb511f674df755edc1e2d6af48b0c48def9bb8e86fe6333f3f24a760e" + }, + { + "bytes": 548, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mode_manual_active.png", + "role": "icon_asset", + "sha256": "0666155837a07843ce3a9cbd3d2d4959240762508fee60630a300cc7467b2d5d" + }, + { + "bytes": 543, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mode_manual_inactive.png", + "role": "icon_asset", + "sha256": "2f7692c2164f5442d00d0e68f83d22a5cab2fda616cd12c992cbdbdbc0971701" + }, + { + "bytes": 508, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mode_mdi_active.png", + "role": "icon_asset", + "sha256": "7e6a9de6db6c77824c2548a10135316edf33f0f711e7d2ca67a306b5830c2dde" + }, + { + "bytes": 509, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mode_mdi_inactive.png", + "role": "icon_asset", + "sha256": "446ade1c99bc7304ff60bce2656f1037a0dea41d76940b167e3d2a9a321e184e" + }, + { + "bytes": 721, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mode_settings_active.png", + "role": "icon_asset", + "sha256": "b78976bb81388c2f5af37b21ddf79c99fa3dbf0b0ecb1bf2a6814aebf41a8430" + }, + { + "bytes": 720, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mode_settings_inactive.png", + "role": "icon_asset", + "sha256": "119aee0c188f194d1ef4eeed81c270d8b02783fc9ce8ddf5388121f2fd503dec" + }, + { + "bytes": 494, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mode_user_tabs_active.png", + "role": "icon_asset", + "sha256": "c973c20ac2319ac8aa9ef19aea18ae619dcc731ed422ea612057bc5c5ad9b24a" + }, + { + "bytes": 494, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/mode_user_tabs_inactive.png", + "role": "icon_asset", + "sha256": "5cefa8e48ba83efd0729928208b16bdf0c1524eb19a0f493216551859d4968bb" + }, + { + "bytes": 452, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/new_document.png", + "role": "icon_asset", + "sha256": "db1b95e6a626fa50ad4ea8962ccf8f88c2ddd189bb13ee32fbc76ba4b682b760" + }, + { + "bytes": 467, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/open_file.png", + "role": "icon_asset", + "sha256": "96ca6efe74b517c166e1ac39771a774eed48139eb05439c600f025e49b8e6874" + }, + { + "bytes": 190, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/pause.png", + "role": "icon_asset", + "sha256": "197e9e8b1433b6cd25f94dd06b8a43160a54b6f1a66cb75cf5d1351e22f07dcf" + }, + { + "bytes": 192, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/pause_active.png", + "role": "icon_asset", + "sha256": "40c5cf782d9193c0422722641c1e716e71d042b207db9db02068c5a1a758af21" + }, + { + "bytes": 392, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/play.png", + "role": "icon_asset", + "sha256": "b1a695c899eea345858da61b37a739cd3dd3c1c7b7f5b916c1035aba35a71440" + }, + { + "bytes": 766, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/power_off.png", + "role": "icon_asset", + "sha256": "d85672f49b5ee489d118096ac5ef1c2fbe4328a75a2c2645cb709e1a593a22ff" + }, + { + "bytes": 760, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/power_on.png", + "role": "icon_asset", + "sha256": "6722d5632a39e70369f0945aec4bdf2b2b7aa5726cb0466868cc3e18eea6fe2f" + }, + { + "bytes": 692, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_0.png", + "role": "icon_asset", + "sha256": "43a267965e2128e17a38686c5a4687ce5199eca46b251d953db278473960f238" + }, + { + "bytes": 603, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_1.png", + "role": "icon_asset", + "sha256": "a53c968c3cefc8b4283cb85b16cb93201976593a3ae65095bca8aab79fecc7d1" + }, + { + "bytes": 674, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_2.png", + "role": "icon_asset", + "sha256": "06ab129e94e6571c6b08604d0215abd47b9b67c6533b547301d6d491d0f39422" + }, + { + "bytes": 694, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_3.png", + "role": "icon_asset", + "sha256": "7755c4a2468dc591eeeba0eb693efc18b6c7a58088b3aa643f1625a5014ff511" + }, + { + "bytes": 626, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_4.png", + "role": "icon_asset", + "sha256": "247ec97a4be3aa122ee8ce1317d488ba725859d54b902f3d0d3922776158031c" + }, + { + "bytes": 664, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_5.png", + "role": "icon_asset", + "sha256": "20ddf08acda517886a75117921081d347fe1de2e1bd879cceb7385559536bc5e" + }, + { + "bytes": 690, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_6.png", + "role": "icon_asset", + "sha256": "7dc4cf7197f7084bf221df040e794998790091f56548c8f6f2218d3523932d29" + }, + { + "bytes": 623, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_7.png", + "role": "icon_asset", + "sha256": "73196acaee1d81f4874de543f364b77e1765c348681006df7550071fc7eebe83" + }, + { + "bytes": 684, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_a.png", + "role": "icon_asset", + "sha256": "1816357a6727e935fd56bc60acd501e89019bef486f29b297b4ef2098ca02c5f" + }, + { + "bytes": 633, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_all.png", + "role": "icon_asset", + "sha256": "c713e03ffa00a702f4799a6657d72dc4886106f48801cbd1d0d2d288b3e724d2" + }, + { + "bytes": 677, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_b.png", + "role": "icon_asset", + "sha256": "26f00e32b5e7cdf7cc38c322adc2becafb379c79d7af7e33affe77d3feead111" + }, + { + "bytes": 688, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_c.png", + "role": "icon_asset", + "sha256": "7084e912b252c5cb955edcbf541d3d7fc4a01d422dc368a8cf4d7346690efefd" + }, + { + "bytes": 630, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_u.png", + "role": "icon_asset", + "sha256": "d956c7673eec3dfdc83f2eb34e2410c7e9a70cce81ddbc7cbc1c13df752d3381" + }, + { + "bytes": 664, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_v.png", + "role": "icon_asset", + "sha256": "8ad1ba7a81d3ddcfcfabedd61ad5da05e3060174f5f4def466c943813a2073c8" + }, + { + "bytes": 725, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_w.png", + "role": "icon_asset", + "sha256": "8f6732666336e0e730ad16be1c3de07f8962b4807677ccace3be574ed3bb4798" + }, + { + "bytes": 693, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_x.png", + "role": "icon_asset", + "sha256": "58b03c60485587ac2e71e4944d15debf58c6519c99d9e6563bbcd944003117d6" + }, + { + "bytes": 648, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_y.png", + "role": "icon_asset", + "sha256": "d8d32e9c69f6402f41f3333964de27e172040669808db429e08ffe12b27f2008" + }, + { + "bytes": 669, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/ref_z.png", + "role": "icon_asset", + "sha256": "e0c4018f914a4cbb6cd1c7cbaff1d4e59eefbeb4bbc5c55386e4e3f866e2eaf3" + }, + { + "bytes": 774, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/refresh.png", + "role": "icon_asset", + "sha256": "12fb022726a06c88e4c158e0c42eb7f3b625bc09e7136c2fd4e8a51bab32dad7" + }, + { + "bytes": 418, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/run_from_line.png", + "role": "icon_asset", + "sha256": "8ac664fa930e8269826e23bc9da07c16eacbcaf74f76120b7c420441df3de8f5" + }, + { + "bytes": 452, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/save.png", + "role": "icon_asset", + "sha256": "790681c1edd9d1a68104ec6e794dd85fecfe809889655697216aa6384a51dcea" + }, + { + "bytes": 593, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/save_as.png", + "role": "icon_asset", + "sha256": "45e6d83bf9d00bd17ed7a56c0830d64cd7ce15e5f48488f7462620a81daf0321" + }, + { + "bytes": 512, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/select_file.png", + "role": "icon_asset", + "sha256": "f767c7802748e2a7775d461430846e6e05fdd9e6737e7f0a3f17ccf97bb5dac8" + }, + { + "bytes": 542, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/skip_optional_active.png", + "role": "icon_asset", + "sha256": "b05795daba84b191f5776c76afcb1fc0730333109a607a93c012254bcff62fc4" + }, + { + "bytes": 906, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/skip_optional_inactive.png", + "role": "icon_asset", + "sha256": "c68eb16c195b83073004f6581927f2805b872811736d2b187eb080a1bffb2402" + }, + { + "bytes": 714, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/spindle_left.png", + "role": "icon_asset", + "sha256": "34c1b89f61c179d71816532981de0671babf0abe37dbcdff81752b1933b12ec3" + }, + { + "bytes": 702, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/spindle_left_on.png", + "role": "icon_asset", + "sha256": "b5861a7ddec2d53b461718e72dce958a48bb70c6f96679662ba0035f58496382" + }, + { + "bytes": 695, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/spindle_right.png", + "role": "icon_asset", + "sha256": "17ca99e1c98f5acf13c109f21fefee507320fefcea581ecdfb4a720de191bfca" + }, + { + "bytes": 690, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/spindle_right_on.png", + "role": "icon_asset", + "sha256": "4e942689c386b88e4a8d1dee42eef60b232d6902ef5ceb311d39156874a36a9c" + }, + { + "bytes": 695, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/spindle_stop.png", + "role": "icon_asset", + "sha256": "f2bc86c5eae74dfc77d2ab7d5556ca20b24eb0c6a9747a008f097c48b389196c" + }, + { + "bytes": 577, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/spindle_stop_on.png", + "role": "icon_asset", + "sha256": "6ceb2a6efa3e6da3ac797857707125ba64e401bd65a30280e63af0c46e762c5c" + }, + { + "bytes": 456, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/step.png", + "role": "icon_asset", + "sha256": "b7c486b008096f607b0c2f9d9bbfc73a18f5432603a28fed2080e1f1a094033f" + }, + { + "bytes": 117, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/stop.png", + "role": "icon_asset", + "sha256": "b73a8bc5e9fd9a1e7f1a48e9c8ace8998b45dab8bfbeaa4f80cbd7d629e67dc9" + }, + { + "bytes": 906, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/tool_axis_p.png", + "role": "icon_asset", + "sha256": "4a62ac0aaa0317a09284523b0af4e4aec612915b24f5d8ce19aa8eb32ad11be2" + }, + { + "bytes": 788, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/tool_axis_x.png", + "role": "icon_asset", + "sha256": "472c3f8f2ab62ae0843c91b92e1040abb86b56b30e51953ae67f645d115bccdd" + }, + { + "bytes": 640, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/tool_axis_y.png", + "role": "icon_asset", + "sha256": "54cc220e2663206a62727a9cb73280bb53420d7923c401622d7a16946759e0dc" + }, + { + "bytes": 643, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/tool_axis_y_inv.png", + "role": "icon_asset", + "sha256": "a1675625c48a9b3d219f9a91eff1fa626d64727194e15c34d75d9b272df00df2" + }, + { + "bytes": 661, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/tool_axis_z.png", + "role": "icon_asset", + "sha256": "1765555940ccb899c06403afbf57865aa8f4999fc2c79fc3e8389ebe47464933" + }, + { + "bytes": 939, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/toolpath.png", + "role": "icon_asset", + "sha256": "f6e7dc5730b24aa31883d7ab465aeff011f693a75a6ff1a8f7c6008c80128222" + }, + { + "bytes": 678, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/touch_a.png", + "role": "icon_asset", + "sha256": "f091ea2c2241bc7bcc0a6e69534803115640c56425759a2b4e1fed301b6a4491" + }, + { + "bytes": 719, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/touch_b.png", + "role": "icon_asset", + "sha256": "700bbe71bd9b4c7ebe6eec89201a409fbee7c53be698758ff45ee3c51e67d019" + }, + { + "bytes": 706, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/touch_c.png", + "role": "icon_asset", + "sha256": "41cf99b8515560cd0899e7b78463d05e3dbccd7a75fcbc780b1f7c9088212619" + }, + { + "bytes": 541, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/touch_off.png", + "role": "icon_asset", + "sha256": "1d15306f221221ce6f30ca8e32e7b70502b6afcbf84a1beb61605708025f15c8" + }, + { + "bytes": 652, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/touch_u.png", + "role": "icon_asset", + "sha256": "73d34f85c6177d7a8594e92040396aeb1d565adb0cc28af5345b643c97361f29" + }, + { + "bytes": 699, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/touch_v.png", + "role": "icon_asset", + "sha256": "fa997c9bc50ffa86577c028faa626f2b415e7122410e414a40cee8ddbb1afed8" + }, + { + "bytes": 765, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/touch_w.png", + "role": "icon_asset", + "sha256": "6e1c530c04e0076875e7358a4e892d6e36a85b09927588e53262b99bc257c4f7" + }, + { + "bytes": 703, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/touch_x.png", + "role": "icon_asset", + "sha256": "294230922bc339eedd5f43b2de4b1e571cac816d69b641b54705bc879e1a8219" + }, + { + "bytes": 672, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/touch_y.png", + "role": "icon_asset", + "sha256": "1f05a7ec41269313fd84ba685778ef5fae0ad40ce05944ff31de83cc337ce418" + }, + { + "bytes": 676, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/touch_z.png", + "role": "icon_asset", + "sha256": "f7294d1d113a86fcc643e5825b92dc81f052d430b90494d6e1c817d857e8d7f0" + }, + { + "bytes": 782, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/translate_a.png", + "role": "icon_asset", + "sha256": "cf962b0d288e23890ce58842138334ad61f503d584fc9b389ba1017d16131bcd" + }, + { + "bytes": 834, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/translate_b.png", + "role": "icon_asset", + "sha256": "8f4655e646c4d499afb71e312821328bcd6e05339da8493e57fd5afa49ef8410" + }, + { + "bytes": 816, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/translate_c.png", + "role": "icon_asset", + "sha256": "92df018af3f66ec3f40157a4fe57b7967a6352987202fa38076da3e9bdfdf070" + }, + { + "bytes": 743, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/translate_u.png", + "role": "icon_asset", + "sha256": "3e6ec55fc5e4758ee83238a8c84b84162ba37bfd6c2902630300dfe4322e5f2b" + }, + { + "bytes": 800, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/translate_v.png", + "role": "icon_asset", + "sha256": "1eb05cb19e353be7893258b58e8d1ef861efb3904a5128f0aac60fd86ece44cd" + }, + { + "bytes": 841, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/translate_w.png", + "role": "icon_asset", + "sha256": "9cce3dc6438e9b9c9d65a31c579ee6ccdf18ba433810e7d25e5517e0e0f45f80" + }, + { + "bytes": 818, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/translate_x.png", + "role": "icon_asset", + "sha256": "f82f17d09f022604a06b05c24fd3872fbf50ede0d9dedd007ea5a7f5382aa00a" + }, + { + "bytes": 761, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/translate_y.png", + "role": "icon_asset", + "sha256": "0ad96f3d7152c2464ac3398b263dadc09ac9f5eeb8c00c56710e417287c35633" + }, + { + "bytes": 801, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/translate_z.png", + "role": "icon_asset", + "sha256": "7178a6e8534f25c18ac3f9dc98841b9d4e0b979a91059828a8264ab05c01e377" + }, + { + "bytes": 681, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/unref_all.png", + "role": "icon_asset", + "sha256": "bbdfcf5906afab95ef82887829326445cfe9e903b074abc7b20a9079212022d7" + }, + { + "bytes": 451, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/user_defined_folder.png", + "role": "icon_asset", + "sha256": "d901d4004a6930df19fa0357ea93aa93765731c0b09a27a5cf04d62bfbc03a15" + }, + { + "bytes": 407, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/window_close.png", + "role": "icon_asset", + "sha256": "33aefea300622c532268cf05ce079fdbcfe019f84e6b5199c28e9a8277ef2f7a" + }, + { + "bytes": 742, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/zoom_in.png", + "role": "icon_asset", + "sha256": "60670723167797f8a51176b0271de6b152f5556d0abff7ec38da14077e7ba7be" + }, + { + "bytes": 688, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/actions/zoom_out.png", + "role": "icon_asset", + "sha256": "afddd54054cb102e857f0cd433cc708dba12a28c1dc58656caa7dd471c99f689" + }, + { + "bytes": 835, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/status/dialog_information.png", + "role": "icon_asset", + "sha256": "103424233e8372ec200cc8349c3441b140ce0b1f19b559b7143453f74ac642b2" + }, + { + "bytes": 682, + "path": "linuxcnc/share/gmoccapy/icons/material-light/24x24/status/dialog_warning.png", + "role": "icon_asset", + "sha256": "e75d6cacbfef84983ac384b51d0c2ec8c8bdf75f4baed25bda006f9387379bcd" + }, + { + "bytes": 657, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/back_to_app.png", + "role": "icon_asset", + "sha256": "f5dbd1bcf10ea8d5dfacf32961799eb5b7d910f170dd84484af25891e018d401" + }, + { + "bytes": 433, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/chevron_left.png", + "role": "icon_asset", + "sha256": "eb375c43450b4f9200dcbc7a09aed662fd5060a6c93fd724ebe68e200892db7d" + }, + { + "bytes": 423, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/chevron_right.png", + "role": "icon_asset", + "sha256": "c3522f36502be361c73513445eaf474a9c12e75e31ef1cf8cf87bc4454a64d11" + }, + { + "bytes": 444, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/chevron_up.png", + "role": "icon_asset", + "sha256": "62a33fe170c4825e27eee42f87cb2dd2a0e431315a13747f50eca9ce176ec3c0" + }, + { + "bytes": 656, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/clear.png", + "role": "icon_asset", + "sha256": "0775feaebe224cadfef3dbe855538091a309a9ae9cab551a6acf7fb02fbcadd2" + }, + { + "bytes": 1019, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/coolant_flood_active.png", + "role": "icon_asset", + "sha256": "dff8d62b521842f5355f483e42486070c98dfde29e30d025e200b1b2d7e5d40b" + }, + { + "bytes": 1079, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/coolant_flood_inactive.png", + "role": "icon_asset", + "sha256": "032da2423b0a3e7395dfc70128a9dee94a98954d170607586eefe0be79bf40b3" + }, + { + "bytes": 1314, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/coolant_mist_active.png", + "role": "icon_asset", + "sha256": "fb4d4919b294cdd1eb60b1cc8592e19cb1bbfabca2705fde8c8b99d95dc3d7fc" + }, + { + "bytes": 1416, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/coolant_mist_inactive.png", + "role": "icon_asset", + "sha256": "80885a9dbaaaf518956b7a0dfcbec459f2963bbc0c49e0af14ea0b52dad7824a" + }, + { + "bytes": 640, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/dimensions.png", + "role": "icon_asset", + "sha256": "b1fbf4fba65fd5e8e2b6f7af0895ae2c059c26701e64b22ed0ecc67863634234" + }, + { + "bytes": 474, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/edit_code.png", + "role": "icon_asset", + "sha256": "1a8f615e59d0be4b7f0f4758594b9cf1301a45f6d00ae2a9cad9d801d703dd46" + }, + { + "bytes": 459, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/fullscreen_close.png", + "role": "icon_asset", + "sha256": "c162ea7aba48cc7aaa21db103fd9452925376b1b91f4e7d3d96bd2160ba1e057" + }, + { + "bytes": 237, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/fullscreen_open.png", + "role": "icon_asset", + "sha256": "991a3d0de52963a9289445a1f90b6241a5a55a5cfd35027196249a82d6ecf318" + }, + { + "bytes": 494, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/home_folder.png", + "role": "icon_asset", + "sha256": "7623b6961670bc7f9af6e989f325c637820df5ef01e8fc21ce9abba9f4eea867" + }, + { + "bytes": 561, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/hsk_mill_tool.png", + "role": "icon_asset", + "sha256": "3e9fb4902e6cea219d5b06e3f506cc1159e48b3e91f915fdd77cb4beb447e14e" + }, + { + "bytes": 1221, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/jog_speed_fast.png", + "role": "icon_asset", + "sha256": "fc4369586072ae27e67b2b1015440c7affe834cffc346038c293900569914b32" + }, + { + "bytes": 765, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/jog_speed_slow.png", + "role": "icon_asset", + "sha256": "d4be171e2df6d15e057237edd91a41e573dcd5b0c219870880fc60553b72e132" + }, + { + "bytes": 663, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/keyboard.png", + "role": "icon_asset", + "sha256": "cc8824ee46b721433c4e426ed2480f122cf5b1a802de67726df2f6b155ce3455" + }, + { + "bytes": 702, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/keyboard_hide.png", + "role": "icon_asset", + "sha256": "6fe4570014b8f152091ac4021a8f2a569c55370e85aefe13cd855e225789863f" + }, + { + "bytes": 677, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/logout.png", + "role": "icon_asset", + "sha256": "549818b91f71dcbfbc19bd3431fb3fa1649aeda9670a1f2996a89c3553bbc7ef" + }, + { + "bytes": 1444, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/main_switch_off.png", + "role": "icon_asset", + "sha256": "709128fa41505db8a78a8bd725c03f92d7b82d45e8c7999cdec90e32a367aa74" + }, + { + "bytes": 1346, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/main_switch_on.png", + "role": "icon_asset", + "sha256": "6159b447ff1e94e6765d289dec5ddfcbb50ad3cb199f0e8c5e647fd3bf49cee4" + }, + { + "bytes": 1002, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mill_tool_change.png", + "role": "icon_asset", + "sha256": "97abf1b35e6f7a5951f8cb655d9fe5a0ff6ff8ca6d9d61927fd24534858178eb" + }, + { + "bytes": 1208, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mill_tool_change_num.png", + "role": "icon_asset", + "sha256": "35717a026794e59e6852dc2601ce962bba0a9b6431ae71d57ba244fee63db075" + }, + { + "bytes": 1348, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mill_tool_set_num.png", + "role": "icon_asset", + "sha256": "81fc70bce58f1ab3092753050df9a766d490f34820ee72beb05bc14d04503583" + }, + { + "bytes": 514, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mode_auto_active.png", + "role": "icon_asset", + "sha256": "c8c588974d51b0dfda37ab423a5ec63ef1a8892ceaaea6d59dda394f4d9730ba" + }, + { + "bytes": 509, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mode_auto_inactive.png", + "role": "icon_asset", + "sha256": "c5b109fbf7475e710dd8b54903fe98aed68f99ea13d054b395c91519f5e73a42" + }, + { + "bytes": 556, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mode_manual_active.png", + "role": "icon_asset", + "sha256": "b044a31071281b653f4643d1b06117a11f5c85edb11b5ba9bfe5e3db9a1de5ce" + }, + { + "bytes": 555, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mode_manual_inactive.png", + "role": "icon_asset", + "sha256": "8ec0217061cebddf0ff9f4c3139ea25039c912e53d1e4dd61e38e5d862a1b5d5" + }, + { + "bytes": 696, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mode_mdi_active.png", + "role": "icon_asset", + "sha256": "830c1db6dabe455f4c72895a96a8bda959364d97848d4de212f8e7464d2feb84" + }, + { + "bytes": 692, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mode_mdi_inactive.png", + "role": "icon_asset", + "sha256": "956aa0f569ec85d24fea80afa3f7649c2a64090a64d9761a46c3ef46446b6daf" + }, + { + "bytes": 916, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mode_settings_active.png", + "role": "icon_asset", + "sha256": "0c3745d43d27811fd2f199ed69db06e52f3a377c15ef20a14550367a28a1f894" + }, + { + "bytes": 916, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mode_settings_inactive.png", + "role": "icon_asset", + "sha256": "3fbc760526886382b659210182c3b2265f7cefa044ef7742745fe506c36d4402" + }, + { + "bytes": 587, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mode_user_tabs_active.png", + "role": "icon_asset", + "sha256": "3d4c70694da2c18d10329b210e56d4abcaba43ccd3f61429e71c3a8a23ce2e6a" + }, + { + "bytes": 584, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/mode_user_tabs_inactive.png", + "role": "icon_asset", + "sha256": "d9ef8c7fcfeb0f469dc1d711de695d02eebbfdde7ddb05100548dc9a991a2662" + }, + { + "bytes": 551, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/new_document.png", + "role": "icon_asset", + "sha256": "0d93922f3825957de2e0706189063e238d05838e78d9bdd4bdfac41f0dd96f0c" + }, + { + "bytes": 486, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/open_file.png", + "role": "icon_asset", + "sha256": "aee4a82075613e91878539d7a9fe08e7cedc9d9a3929a11ad80634ec58111249" + }, + { + "bytes": 214, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/pause.png", + "role": "icon_asset", + "sha256": "ab92bf14b6b707b1a357f0116a166cc1b73e922d25b655bb8b83f86c98a33d60" + }, + { + "bytes": 198, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/pause_active.png", + "role": "icon_asset", + "sha256": "c8621f9ecf0353dcd26cc155717e29d3d0e6469e1287701a0b976a064264cd06" + }, + { + "bytes": 431, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/play.png", + "role": "icon_asset", + "sha256": "2f255f301b1651ce2d0866d5eded57cf22b6e92e748141d28893be4553255201" + }, + { + "bytes": 994, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/power_off.png", + "role": "icon_asset", + "sha256": "4e0952351bcd292ab2f0508eeb9baf05103decfee0affbb7c0689d1ef8eb8a6c" + }, + { + "bytes": 996, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/power_on.png", + "role": "icon_asset", + "sha256": "4ed0b916a0593b361e91bfb4da9309beb58ca45beeb636ae29b6e1f6a356a1ec" + }, + { + "bytes": 935, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_0.png", + "role": "icon_asset", + "sha256": "9470ac44c7caad05b1f3ee9623777d030b934a34a4bfc7149cc587e7a02b05d2" + }, + { + "bytes": 771, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_1.png", + "role": "icon_asset", + "sha256": "84a6154d89129fa337b8d4f60a10c6d274041f25b3cd949f588ceedf415c23df" + }, + { + "bytes": 879, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_2.png", + "role": "icon_asset", + "sha256": "e94d65b4c825b1ec1b0df83357cda57a644c1ef6b88036166dfad6ca02c71131" + }, + { + "bytes": 922, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_3.png", + "role": "icon_asset", + "sha256": "a41ca5a5c7bc8d5d1054008d7d70031d41b8c5e187aff40fccc2570c20000248" + }, + { + "bytes": 857, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_4.png", + "role": "icon_asset", + "sha256": "71d64249fffb08f7aeade97e56eedae4a17f71d525ff3eb9e2c4dacd3d95ee81" + }, + { + "bytes": 921, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_5.png", + "role": "icon_asset", + "sha256": "1bf35f58bb17efbf89f9483a692a50cdb763fb6e5c6b4092e28329a7a6a53dd9" + }, + { + "bytes": 906, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_6.png", + "role": "icon_asset", + "sha256": "9b51f4b032043037e7218db656be9017987af09246ec78d32598ab8f7eb2f3c0" + }, + { + "bytes": 862, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_7.png", + "role": "icon_asset", + "sha256": "7490686feed90c52010e7849d6273f857d7f5e4a1bb9d648566db39e24f1eb5b" + }, + { + "bytes": 910, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_a.png", + "role": "icon_asset", + "sha256": "a3cfb740a384f4b5e718dc454fd8d396f8096a2c2e7ff458dc1420f99e1cce5e" + }, + { + "bytes": 883, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_all.png", + "role": "icon_asset", + "sha256": "00cfb0a16d0902168feb074e2871b79647b2638fa98e7a24dba22965b91daa1a" + }, + { + "bytes": 923, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_b.png", + "role": "icon_asset", + "sha256": "592d8bd846488a21818b88d0eef3c1a361fd6a3bdf440537b6fb005ba042e0c5" + }, + { + "bytes": 991, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_c.png", + "role": "icon_asset", + "sha256": "4cd69fb4d8faceb2150eb9c386d34717a49e1dbbce5fdaf562bba207eefc2050" + }, + { + "bytes": 846, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_u.png", + "role": "icon_asset", + "sha256": "c92e7f0185f46484b487e6249d52c3b3bb238fd54eb0e83357b9c87096a6da99" + }, + { + "bytes": 932, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_v.png", + "role": "icon_asset", + "sha256": "7c4e32a7be8579dc68d90e69ec4045f7adca26014dc16ba7a37f3918b72f9737" + }, + { + "bytes": 1009, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_w.png", + "role": "icon_asset", + "sha256": "9c53f4de5f047ac0d629d7ee15bfba799e3a913df8e8019165b8b9bce380ee0e" + }, + { + "bytes": 965, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_x.png", + "role": "icon_asset", + "sha256": "a93f2fb21b40eb9075d058b2f2c78a590b3f86384df97ef14bf616dcec3d2681" + }, + { + "bytes": 858, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_y.png", + "role": "icon_asset", + "sha256": "52ee4ab369cc8b469f019fc56142d525e812e622b8d46e6a9459a0ad75542d3f" + }, + { + "bytes": 887, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/ref_z.png", + "role": "icon_asset", + "sha256": "fe0884d9056f3764fc29fa5e9ad304b617e37f64a6c3c42d8f5e9ba3e4b3acf3" + }, + { + "bytes": 1017, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/refresh.png", + "role": "icon_asset", + "sha256": "6dca0df3b7165945f1292caf75b9101895dc49a7ae5a27f5b604302399d7d153" + }, + { + "bytes": 444, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/run_from_line.png", + "role": "icon_asset", + "sha256": "838108452c4f38aab9067859ccbcbcf1e9ce4fb8015bf19df5de1159c09e5a76" + }, + { + "bytes": 575, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/save.png", + "role": "icon_asset", + "sha256": "43ebae97778388fca6d893ec42ca5982b5ad9f8433d26d9b274ea2e3d9ca5cc4" + }, + { + "bytes": 760, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/save_as.png", + "role": "icon_asset", + "sha256": "28e8c1b3070a26f758fb08ffe43b10ab903c3e98bf4d28eda4c1753baae2148d" + }, + { + "bytes": 648, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/select_file.png", + "role": "icon_asset", + "sha256": "9beaef9bf66f661ef2e46630cf850332e1af9e8ef33e02f2dc13507d3030e570" + }, + { + "bytes": 638, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/skip_optional_active.png", + "role": "icon_asset", + "sha256": "70e362338c6d5e294b93fac82c1722087e20ec205e2b115b0c51a29403d16731" + }, + { + "bytes": 1169, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/skip_optional_inactive.png", + "role": "icon_asset", + "sha256": "d2956ee3f50db46583e1d31c1114b5a388531588bb8764671bf292568ab33c17" + }, + { + "bytes": 936, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/spindle_left.png", + "role": "icon_asset", + "sha256": "c9e9cd6bac2f0bd6292a2de659e52eae654c3a56f94c5e8a3435cb0300a0aa0d" + }, + { + "bytes": 943, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/spindle_left_on.png", + "role": "icon_asset", + "sha256": "e0638fe44d2f019537f1afae1c9719bfa4d434611b92702cf19e93f227011630" + }, + { + "bytes": 942, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/spindle_right.png", + "role": "icon_asset", + "sha256": "9f264ea18b6f6915b7f81def828741f1daff1dfdd55e90fa0e4e1ffbb90e15f1" + }, + { + "bytes": 950, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/spindle_right_on.png", + "role": "icon_asset", + "sha256": "8ea83e3df64e1a1d787cede52ba77171bb9e3f640102a02be78d521d6d9f562f" + }, + { + "bytes": 885, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/spindle_stop.png", + "role": "icon_asset", + "sha256": "148b8d701eb2c7ebd2d8a046c436ee88a6dac553613e38e10c9cf2e3f295b259" + }, + { + "bytes": 736, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/spindle_stop_on.png", + "role": "icon_asset", + "sha256": "a1efbdcf85df1c856a40ce73a71ad8400c1be9e868caa709ed041b2a9b7d9705" + }, + { + "bytes": 549, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/step.png", + "role": "icon_asset", + "sha256": "57cd49d85b5870bc9eb19cbf021c1ece8286037fcfaca26f3ebfc603857ea4e7" + }, + { + "bytes": 133, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/stop.png", + "role": "icon_asset", + "sha256": "d231e5993cbbf1517d79ce6a75d8a86a546962a4888a61d7d8d6e6e80cd839dd" + }, + { + "bytes": 1089, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/tool_axis_p.png", + "role": "icon_asset", + "sha256": "05368ea34bd04c0556d589d2dd4c27b2133e05f088e6a10995e04cfb1d16b698" + }, + { + "bytes": 890, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/tool_axis_x.png", + "role": "icon_asset", + "sha256": "47001a124e7a1a281ec6c81e9fca887f2ce4aceb06da644c252d64813650491b" + }, + { + "bytes": 698, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/tool_axis_y.png", + "role": "icon_asset", + "sha256": "11fe11bf11212022708ed45e2b9ead980c3c28b86d65ede754506d3602008074" + }, + { + "bytes": 702, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/tool_axis_y_inv.png", + "role": "icon_asset", + "sha256": "510d6cb04854208161ec85ea507627b7ca9228be7a0f88021a2427eeb5469ce0" + }, + { + "bytes": 683, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/tool_axis_z.png", + "role": "icon_asset", + "sha256": "480ca5862d0e97830733cc02356e7d9cdf1720141f2149887d44c65d2af63568" + }, + { + "bytes": 1191, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/toolpath.png", + "role": "icon_asset", + "sha256": "40b309cf637b701c2e4d85fb58d36516b5865101536b4b09f5b6d9151b3b5705" + }, + { + "bytes": 925, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/touch_a.png", + "role": "icon_asset", + "sha256": "94ba2b809ad5bcf802b8f5ab8a61b1f80817dde63a89e1feea5375f91d65aac3" + }, + { + "bytes": 949, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/touch_b.png", + "role": "icon_asset", + "sha256": "f4f11f5cb8cba6d28ab816d9ba2d9164ab6557136264c8da1987d0b1dc0ce361" + }, + { + "bytes": 973, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/touch_c.png", + "role": "icon_asset", + "sha256": "b8cf0965068ca5355f09460e9d522964166a49fd8c1d0d7b50ff0ceb0ee8dc88" + }, + { + "bytes": 709, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/touch_off.png", + "role": "icon_asset", + "sha256": "ad118bfa630012786751738136975d527b9be9e8a3ca0a3db1780ab011934c37" + }, + { + "bytes": 851, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/touch_u.png", + "role": "icon_asset", + "sha256": "faf8a42eabce2447506cbcbb32a59aeecdd947ee02b43b5726b371acf0ea4523" + }, + { + "bytes": 944, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/touch_v.png", + "role": "icon_asset", + "sha256": "9108850eed9fd0532317c10482e0c89ae3726b95721f028d896ff36b53e7182c" + }, + { + "bytes": 1049, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/touch_w.png", + "role": "icon_asset", + "sha256": "e9178aa73513d75a60216c35b7e2a9cdaba4c078dec7fb9329ad0734a8935a10" + }, + { + "bytes": 976, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/touch_x.png", + "role": "icon_asset", + "sha256": "b434d5100bfe95feca17ede7633c79960126949190e851ba860a739ac0c084ca" + }, + { + "bytes": 906, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/touch_y.png", + "role": "icon_asset", + "sha256": "920d8b6648d901c98f383d84b7a040ced56ca2e12546d5e0572804f23b121380" + }, + { + "bytes": 909, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/touch_z.png", + "role": "icon_asset", + "sha256": "d658c7f2b46adc18dacd7e712aeea2154e3cef02bb6e4512438fb49423d05ce5" + }, + { + "bytes": 1150, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/translate_a.png", + "role": "icon_asset", + "sha256": "c4e4c67d623d10dda9a43d24bf8ab6cd69a32f53faa6483e186395bf48c63d9a" + }, + { + "bytes": 1133, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/translate_b.png", + "role": "icon_asset", + "sha256": "cac338a3f7116bf33219bbc2f03611ab635c27a94750a792ba1a58d66a708d1c" + }, + { + "bytes": 1143, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/translate_c.png", + "role": "icon_asset", + "sha256": "923f01ab121959f00bf8cde01e83e237aa944a52d2ec8a1a68070a89a972004d" + }, + { + "bytes": 1032, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/translate_u.png", + "role": "icon_asset", + "sha256": "891a2c6f3a3fc9f8dc5926e9f287e57a604f728b6bb6f6af75272a5b85cd60a4" + }, + { + "bytes": 1181, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/translate_v.png", + "role": "icon_asset", + "sha256": "aded41a5d9e3adc9198ef2f4411d9c2523d4a47e694cb5362769f9bf0eb6ce68" + }, + { + "bytes": 1250, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/translate_w.png", + "role": "icon_asset", + "sha256": "5fb8793160cb1eb5354fb6a92fcc11ac2d2756b89e0189742e88ab7f3b4c91ed" + }, + { + "bytes": 1166, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/translate_x.png", + "role": "icon_asset", + "sha256": "af392a6ec2ca9b298083b4e5a4748d6ca792f697c10fb7cb8f316de09e8bb177" + }, + { + "bytes": 1102, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/translate_y.png", + "role": "icon_asset", + "sha256": "b63bb5b476c858f6d372547a7587e6c7f598a2c6ce4d87cccca05f5578b6269e" + }, + { + "bytes": 1114, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/translate_z.png", + "role": "icon_asset", + "sha256": "b3b8733baa2a1932636f4d429d4dd345e67bf3793d713594e53f59d54bb25c87" + }, + { + "bytes": 840, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/unref_all.png", + "role": "icon_asset", + "sha256": "6fe038343ca17c0454196a021754d832195718a012977ed8a488d8595c005444" + }, + { + "bytes": 569, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/user_defined_folder.png", + "role": "icon_asset", + "sha256": "c0fb2e00c3cb1daa59b8c3b2c0223d907534ea4f51e59db9b2d4676eb0b1d52f" + }, + { + "bytes": 512, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/window_close.png", + "role": "icon_asset", + "sha256": "c7d90a9d673b67f00a82d6c9b1af18cee80f83adb9641ce6df6f8451d4278dbd" + }, + { + "bytes": 1036, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/zoom_in.png", + "role": "icon_asset", + "sha256": "ee41b29d392cd200af3bf9fd2ec0a6587dd124e1f4f13e412859399396e94357" + }, + { + "bytes": 996, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/actions/zoom_out.png", + "role": "icon_asset", + "sha256": "93d2b7ddcc6038b63e9f42204730b90b552b6eb7707eb5df97b9022463128f0f" + }, + { + "bytes": 1159, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/status/dialog_information.png", + "role": "icon_asset", + "sha256": "4ebc8b0ca1d47c790f974dde4ee7aa90d118e3a8d20194ef9981192a7dc08a6a" + }, + { + "bytes": 928, + "path": "linuxcnc/share/gmoccapy/icons/material-light/32x32/status/dialog_warning.png", + "role": "icon_asset", + "sha256": "d107c140d1b8b6b8f4e9b0d43c2cce0884c0c456e988c894bd39fa13856eb35c" + }, + { + "bytes": 915, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/back_to_app.png", + "role": "icon_asset", + "sha256": "832227ad183073a97fcbcea82b369d281e8543f16227ec19cc17fe62d23def4e" + }, + { + "bytes": 626, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/chevron_left.png", + "role": "icon_asset", + "sha256": "014eb7be391dbcf76f6977d45f915cedfd07b3a4b189efe7faef0f1d163ce98b" + }, + { + "bytes": 628, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/chevron_right.png", + "role": "icon_asset", + "sha256": "9afbb2654376c4f3a5d36fa3aca2ad4a81e558ee2b06dc5961e78e02f7245c17" + }, + { + "bytes": 666, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/chevron_up.png", + "role": "icon_asset", + "sha256": "8f90d6be56c0e5b037206b74576e57c6c2d6380f6bd2100d360de402d220dfcb" + }, + { + "bytes": 916, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/clear.png", + "role": "icon_asset", + "sha256": "47ccf9b21cd05b716e9ab0e1303c5a217f5d94e773afe3aef29bb1681dc41942" + }, + { + "bytes": 1715, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/coolant_flood_active.png", + "role": "icon_asset", + "sha256": "f7b383264772522acb30c57f9c5f4c32d22effb0f2890e2ba2e3e7e4c5c3df87" + }, + { + "bytes": 1782, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/coolant_flood_inactive.png", + "role": "icon_asset", + "sha256": "deab82c5fb700a954209c40735dc2100797ba85d38734206261a7de2b2482616" + }, + { + "bytes": 2205, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/coolant_mist_active.png", + "role": "icon_asset", + "sha256": "67fd61eaa56e784790bd7eeb2f4077231013189a234fca55bf97f95fa0d89917" + }, + { + "bytes": 2298, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/coolant_mist_inactive.png", + "role": "icon_asset", + "sha256": "1fb7253e9c8d5a219893d9a79971b496699afb6aac545e7d5427e4164ede96be" + }, + { + "bytes": 959, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/dimensions.png", + "role": "icon_asset", + "sha256": "9f2d8eb6a082fb4cadadb69079b847be8af54c5fd7acebe80235ac31d2810490" + }, + { + "bytes": 660, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/edit_code.png", + "role": "icon_asset", + "sha256": "279dbba42f2da822a83e79f97b3260b4e335c769649dd1cec8ce08a9efdcb553" + }, + { + "bytes": 621, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/fullscreen_close.png", + "role": "icon_asset", + "sha256": "2aca5da519fb0bb4bc1f22a287d75cbf1754fd2e60f69c5c6dd5d7a2dedc5721" + }, + { + "bytes": 296, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/fullscreen_open.png", + "role": "icon_asset", + "sha256": "9af768d3f8827ed8c5e6a7df623762aa1023ac6cf53901e8d929123767edc620" + }, + { + "bytes": 608, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/home_folder.png", + "role": "icon_asset", + "sha256": "da0cb9be2c40f173b6ce87defb17705bc032dd62236281430a11f4422b595fe4" + }, + { + "bytes": 827, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/hsk_mill_tool.png", + "role": "icon_asset", + "sha256": "cf539852f7a82ee2efa3b18b652f97ae48ee0711f7a4c48a6bdcce7a32f7ca22" + }, + { + "bytes": 1816, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/jog_speed_fast.png", + "role": "icon_asset", + "sha256": "064ef0eac091f3aebebb5710d46a31719563982ce2e172dac38225333e6604c4" + }, + { + "bytes": 1189, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/jog_speed_slow.png", + "role": "icon_asset", + "sha256": "a8814aa1bac08584d03bd4d7bd331a69af5f45b3df52646ed3aca7706f131149" + }, + { + "bytes": 576, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/keyboard.png", + "role": "icon_asset", + "sha256": "454ca4606c319034f71e41079748e4a86545b00c8fcae1810c491327d77f07af" + }, + { + "bytes": 879, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/keyboard_hide.png", + "role": "icon_asset", + "sha256": "fbf4cb3d8213973b6bf574d25b68e7c28d1bdad3f863dc6a0cced5a39f1672d8" + }, + { + "bytes": 1014, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/logout.png", + "role": "icon_asset", + "sha256": "0d49e026537ee650938a4b5c9334594b303b6f7f57217e14b9fd345b983fb858" + }, + { + "bytes": 2294, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/main_switch_off.png", + "role": "icon_asset", + "sha256": "084a1d7a21123e229da464c5abc1db945c60cd33bc925f2f4b74c4a719375e6c" + }, + { + "bytes": 2171, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/main_switch_on.png", + "role": "icon_asset", + "sha256": "26510fa0a705ef0012ed28da3de94740d97f23405649ecabe6f9ffdb8b19ddc7" + }, + { + "bytes": 1500, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mill_tool_change.png", + "role": "icon_asset", + "sha256": "d9e356ef8ca9b819161b55b8dac7fab97e26f4bcdab6f26a0c69bc9a85482056" + }, + { + "bytes": 1925, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mill_tool_change_num.png", + "role": "icon_asset", + "sha256": "17e89e8a9cd224c29517c594d4c87f37dfee99c43af69977b92263a5eee8b233" + }, + { + "bytes": 2139, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mill_tool_set_num.png", + "role": "icon_asset", + "sha256": "cd23b493e0c05428bfd244a5c99214198589805a4cdee50c8297deb17d7ad3dc" + }, + { + "bytes": 738, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mode_auto_active.png", + "role": "icon_asset", + "sha256": "cbace9efd9e6a10478a737aab508e133dd58860bfeb70714805eddc75ecf3d7d" + }, + { + "bytes": 735, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mode_auto_inactive.png", + "role": "icon_asset", + "sha256": "8f281c733ea8452d63692e77d57d68652a019e29871bff947754a48e89ffca42" + }, + { + "bytes": 790, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mode_manual_active.png", + "role": "icon_asset", + "sha256": "6fc5974fe9e9f8b98276c95657b6d3f9ce9744312e866b453718c4405acb2f9c" + }, + { + "bytes": 790, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mode_manual_inactive.png", + "role": "icon_asset", + "sha256": "5511ea8f574d66c54e2e9fa4795a2cdba42abb032867923384f89a21d2bf2b53" + }, + { + "bytes": 876, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mode_mdi_active.png", + "role": "icon_asset", + "sha256": "dffc3570f0400e23d7e94bfa23e600bb8a72469a9ddc1abd14a54259c0dffd8b" + }, + { + "bytes": 886, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mode_mdi_inactive.png", + "role": "icon_asset", + "sha256": "3ff8c972246989e7e379d86d30bf3114f4e36c0bae1eed2870d6df1903ba2fe1" + }, + { + "bytes": 1297, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mode_settings_active.png", + "role": "icon_asset", + "sha256": "8b52843ebf8769642d464bb371615f7dbcc54373d68da725e40f3b1cab62a21b" + }, + { + "bytes": 1267, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mode_settings_inactive.png", + "role": "icon_asset", + "sha256": "f63f968b3b63f6febb87567d3f57956c3617d0a791526d4d654af9821d474184" + }, + { + "bytes": 874, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mode_user_tabs_active.png", + "role": "icon_asset", + "sha256": "285e0d9765590e05987cf692978c80d94499aa378ed2c100a1fdf5b674009b2a" + }, + { + "bytes": 870, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/mode_user_tabs_inactive.png", + "role": "icon_asset", + "sha256": "8ea7a669871d2102eb54dd1b32986d6f530a75f198c332bbd5ef5431379596ab" + }, + { + "bytes": 664, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/new_document.png", + "role": "icon_asset", + "sha256": "1895bd50a094e40b33cd8ece4430a0c50bb00c8e69ad7b0952d32b7ee2a62f4a" + }, + { + "bytes": 699, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/open_file.png", + "role": "icon_asset", + "sha256": "00324a3c5b28976f37b64f6c6a1dfbe64bc7b02161b9771e0158fa4cb27f75bd" + }, + { + "bytes": 252, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/pause.png", + "role": "icon_asset", + "sha256": "eacd9a4add2450ec14a369f3f08142c04afcd66c7e1547c688295981b67e82f2" + }, + { + "bytes": 244, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/pause_active.png", + "role": "icon_asset", + "sha256": "f2f6ba2f46add2c778d72ed7cf0f93a583ce4b1b81aa8a0733215bfc2b8b1fa8" + }, + { + "bytes": 570, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/play.png", + "role": "icon_asset", + "sha256": "131d3fcc5cb9622a758cdbd2485db76af7ff872565963ad219fd7a980f8e8dbf" + }, + { + "bytes": 1496, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/power_off.png", + "role": "icon_asset", + "sha256": "67d47a53b9feacb1a3553f22b3f4a6fa35e7db93cd900fbf005a3c5c10857a64" + }, + { + "bytes": 1490, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/power_on.png", + "role": "icon_asset", + "sha256": "716a2134c29e94b50be2c64c016a086c2c773cc03b6e9e807d304de59bc55f70" + }, + { + "bytes": 1409, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_0.png", + "role": "icon_asset", + "sha256": "cb6ee0843a238de24efac2ab4251206ce09974229248b3200a55c05296614504" + }, + { + "bytes": 1150, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_1.png", + "role": "icon_asset", + "sha256": "fee44da6d0727661426333ffa05ddb96075b06fb636a5717a945ee6de42b138b" + }, + { + "bytes": 1371, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_2.png", + "role": "icon_asset", + "sha256": "a6af7e4ba05fae86baa82f186418a8c85cca5c20e2e0235dab138e89e8fd3ce0" + }, + { + "bytes": 1444, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_3.png", + "role": "icon_asset", + "sha256": "e9e32fe068c3cc14c4f7df92699029ad0c957a10d7eedeb63e9dd68c093632a6" + }, + { + "bytes": 1312, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_4.png", + "role": "icon_asset", + "sha256": "5e0aa147d53d42dfbfb3e2e7c653857c5627b56100ed5317d7ebe36ba90d67d9" + }, + { + "bytes": 1407, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_5.png", + "role": "icon_asset", + "sha256": "b5da047221b30146e3b12d5678ba134413f4dce0141c50c57fd8039bc5b0bcba" + }, + { + "bytes": 1448, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_6.png", + "role": "icon_asset", + "sha256": "a37b43a65231a3a3b15f6e7a98fce399077b7ef44f2c04e0ba668edc49376eb2" + }, + { + "bytes": 1299, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_7.png", + "role": "icon_asset", + "sha256": "0dfddc66d8b36328134b0774824ec0a699dc31953c6e931304dabaabd14335d7" + }, + { + "bytes": 1422, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_a.png", + "role": "icon_asset", + "sha256": "17f8081f9663b1014c936477ffee772ec1b105ac4e2b58fc8e3ffb4b57d9b56b" + }, + { + "bytes": 1302, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_all.png", + "role": "icon_asset", + "sha256": "9f9eefcca0e60a216b54f9f38664f2ac4c423bef7bd63f3e066bf7f48b9c0264" + }, + { + "bytes": 1418, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_b.png", + "role": "icon_asset", + "sha256": "f2180a9eceaa679051b2ed4a8b2e6f2c7f981bec310f71791d704c52644371e4" + }, + { + "bytes": 1489, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_c.png", + "role": "icon_asset", + "sha256": "88666005b44946593fadcd5aee2922fc234b2282785a52465e53535513e462bf" + }, + { + "bytes": 1302, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_u.png", + "role": "icon_asset", + "sha256": "3e40848a914d44e5c1e45f5412a2e75f7457dfb4074900e8dbc69d1076284864" + }, + { + "bytes": 1460, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_v.png", + "role": "icon_asset", + "sha256": "6ffbf644db96120dda9a853d5513100b1a86c4f59620bec18699933ead1a3355" + }, + { + "bytes": 1611, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_w.png", + "role": "icon_asset", + "sha256": "c4d1d622a7c98c27c21c389cc7e0c8188d411c8281d98aea65979847fb6fe74d" + }, + { + "bytes": 1541, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_x.png", + "role": "icon_asset", + "sha256": "08eba16969be246e6c51b0620f3efbbd07ca6c6a9d387b0150a2851aa2ed4144" + }, + { + "bytes": 1355, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_y.png", + "role": "icon_asset", + "sha256": "44e8ce82430e04eac4b5ee40dd1cd86ce870fd9cc07df4cbe654549656951f6d" + }, + { + "bytes": 1346, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/ref_z.png", + "role": "icon_asset", + "sha256": "d80221afb394d95f0c938d615fe61fc1b70cc160c506a1e1aea0640da86efde0" + }, + { + "bytes": 1553, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/refresh.png", + "role": "icon_asset", + "sha256": "df6b90ba86723c63b3e2c4166e37e7c968ece0f56d10fb69a4e77caec562b431" + }, + { + "bytes": 517, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/run_from_line.png", + "role": "icon_asset", + "sha256": "e50b24f3224c91b585c1078e442bfc818867d9f7576603cad9a7c9de3ea0d4c9" + }, + { + "bytes": 832, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/save.png", + "role": "icon_asset", + "sha256": "4d8b055c7f7f4aecd57087f57249d6dcee467ac7fef719573ba480fb052dc0a5" + }, + { + "bytes": 1126, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/save_as.png", + "role": "icon_asset", + "sha256": "4a5c951c7fab7aae322d908e73973a7eb4578f4a23e4c6f76073dc4fbbc38b4c" + }, + { + "bytes": 855, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/select_file.png", + "role": "icon_asset", + "sha256": "764739b04d00ad8975e8a9321335a7efc070f5081de4a6acfdec613c5c05f39b" + }, + { + "bytes": 950, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/skip_optional_active.png", + "role": "icon_asset", + "sha256": "1de49cdf444e6df346a44784e79c249be6a84e4416fd6e9402daa40eb00aedd7" + }, + { + "bytes": 1798, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/skip_optional_inactive.png", + "role": "icon_asset", + "sha256": "988cea3dc930cae67c63013763143fdbc37ab70b504696eefacb6c7892bd7193" + }, + { + "bytes": 1370, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/spindle_left.png", + "role": "icon_asset", + "sha256": "dc3334e8c67e3034d61b3a413b18849bbfbb771d6886147389203e8a9fba49c3" + }, + { + "bytes": 1352, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/spindle_left_on.png", + "role": "icon_asset", + "sha256": "318a265f635949ee854fe952b50eb159a10e93b517f475261f307150337c49a5" + }, + { + "bytes": 1380, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/spindle_right.png", + "role": "icon_asset", + "sha256": "688f6e828eca9a60aa1c8070750988cbc559fe100031e65bb1f6c46b575e2244" + }, + { + "bytes": 1359, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/spindle_right_on.png", + "role": "icon_asset", + "sha256": "2fd8498ed5d1b33fccdc69ebe8e8f8b25d173ecf420d07befc7f262dfccb3b48" + }, + { + "bytes": 1405, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/spindle_stop.png", + "role": "icon_asset", + "sha256": "b35c4bdcfeb58cc939fea0e404faf51381c2724fbae99d83ee909092ffa0fdb6" + }, + { + "bytes": 1096, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/spindle_stop_on.png", + "role": "icon_asset", + "sha256": "c9e4c1bfd2800b95c3ba643847778dc4489c4ed0dd0216a94038a87da943e958" + }, + { + "bytes": 668, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/step.png", + "role": "icon_asset", + "sha256": "c44c23fd300fb24bad87bbf8fe24a95d75911fe026a55936533a17aa989719db" + }, + { + "bytes": 169, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/stop.png", + "role": "icon_asset", + "sha256": "8b0efa7d8bda444203e5763a87457cf472148fb7c80ed9ea732686d812f1817d" + }, + { + "bytes": 1727, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/tool_axis_p.png", + "role": "icon_asset", + "sha256": "173210035b8296a2a3a67c6062c0dfad4aa7e4d076b6e2956bc0f5d30ca62dcb" + }, + { + "bytes": 1468, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/tool_axis_x.png", + "role": "icon_asset", + "sha256": "6f3bec85a774d08ec527fefee9ea48be2bce1d7b1e4858a2e0b257c966c2477a" + }, + { + "bytes": 1141, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/tool_axis_y.png", + "role": "icon_asset", + "sha256": "c5aaa1a93cecd57f442b7e2d2dc66b85c07e32866891f223d8ad00e088c293a1" + }, + { + "bytes": 1122, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/tool_axis_y_inv.png", + "role": "icon_asset", + "sha256": "248ba2629fc3b228da37ac2699d6268d4bc095d1c810d6d63114d71ba01f28e3" + }, + { + "bytes": 1120, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/tool_axis_z.png", + "role": "icon_asset", + "sha256": "c62c790f78901dbb43b33348f5444dc9055322666fe4b4ed75bf05082c290ad9" + }, + { + "bytes": 1786, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/toolpath.png", + "role": "icon_asset", + "sha256": "12854f1eb5560ada4f9d85b603a2f388fd9f135108e2e2e836d609af021ce478" + }, + { + "bytes": 1502, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/touch_a.png", + "role": "icon_asset", + "sha256": "d5651cbfba419bf3c9beb6ef4a5bcb9e2676c0391879ca0f77ec4ca068934cc0" + }, + { + "bytes": 1485, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/touch_b.png", + "role": "icon_asset", + "sha256": "517681ca216f0b512dbe09a59d8bf392cbe7c5de78dd5d185d94cea7a85f72f7" + }, + { + "bytes": 1548, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/touch_c.png", + "role": "icon_asset", + "sha256": "10feb99d756ccff00c69ab080d50b9043ea70b4e9519633e5bf4dea79ceb54a1" + }, + { + "bytes": 1079, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/touch_off.png", + "role": "icon_asset", + "sha256": "89f392ed8fe172b3b88414ecbfd0c1bb417c6b4efb5d7cb1813e2ed21859e84b" + }, + { + "bytes": 1354, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/touch_u.png", + "role": "icon_asset", + "sha256": "d48cac5c5175b05cd70a20b20690d68a01cb2e0d2a77fd71ed19cfeaa77b83e8" + }, + { + "bytes": 1549, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/touch_v.png", + "role": "icon_asset", + "sha256": "5d061649016cf184bdb3e556ba668117fa1afa5f3ecfbfc4dcd3d0b9734fe49e" + }, + { + "bytes": 1650, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/touch_w.png", + "role": "icon_asset", + "sha256": "3711582b30281e91502d03b70c9986f7c7fa44332a553efafbf7cfe321b8e799" + }, + { + "bytes": 1621, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/touch_x.png", + "role": "icon_asset", + "sha256": "1c972ce1b3bd9d9a41e4397aba1b9153f2cf86f600c9ecc01ff031cb9a9c8b37" + }, + { + "bytes": 1441, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/touch_y.png", + "role": "icon_asset", + "sha256": "63fad3cbab09551503ac466c0832695bcd87b6d8aaa33b7bab58bc9cac512a88" + }, + { + "bytes": 1422, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/touch_z.png", + "role": "icon_asset", + "sha256": "22f530b8b682083826cbf7b742bc8e72bff70a3cff06ee71dee32137f5986433" + }, + { + "bytes": 1692, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/translate_a.png", + "role": "icon_asset", + "sha256": "1854f833d5220ef80c68bc135617003029cdbec686a3dd1803825d04bf78f731" + }, + { + "bytes": 1561, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/translate_b.png", + "role": "icon_asset", + "sha256": "ecfa57baeee934c3102f7fb3bce5b4daee94d7b48df1abe1d1113c35da7b71ab" + }, + { + "bytes": 1683, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/translate_c.png", + "role": "icon_asset", + "sha256": "c9dd3072dc716b327f80e64a97986e2229b14d57781ad6bcca29a44c5cc53791" + }, + { + "bytes": 1497, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/translate_u.png", + "role": "icon_asset", + "sha256": "ad969a409de2e901cd3ea865ec7b87bfe930b61b074c657c9b40456ff65a66c3" + }, + { + "bytes": 1696, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/translate_v.png", + "role": "icon_asset", + "sha256": "7b89c25dd1ac91f73479e7621cd61a8df1ec065b8df73b1be36afc2494eb1024" + }, + { + "bytes": 1827, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/translate_w.png", + "role": "icon_asset", + "sha256": "f79b2c72a6cd595c11750fe85544068e7ce830f05181a6e6fdc9eb7a88f94b0d" + }, + { + "bytes": 1737, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/translate_x.png", + "role": "icon_asset", + "sha256": "6e6d136c9200d37e8fe5803a410f780ad03a9bf5758ebcb0efe503921fe43a55" + }, + { + "bytes": 1616, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/translate_y.png", + "role": "icon_asset", + "sha256": "fda8758e6e5e1d6d2381d5369f97070fd2a5c12565294bb38f75e9491a5c24ed" + }, + { + "bytes": 1564, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/translate_z.png", + "role": "icon_asset", + "sha256": "7e55e109c8e7c172f65ab5a3eddca51068df6efb082f01753b2c4dcdbc91d0eb" + }, + { + "bytes": 1134, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/unref_all.png", + "role": "icon_asset", + "sha256": "2ca027a0af65be7c81559575daf3c41770d559355825d4dd1152f92f9720c582" + }, + { + "bytes": 826, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/user_defined_folder.png", + "role": "icon_asset", + "sha256": "20696d7b28e273d0313aeeb91e30fb8e9d24143b109151696191ff74f25f9050" + }, + { + "bytes": 694, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/window_close.png", + "role": "icon_asset", + "sha256": "b1fd84a1eb380ed0d5bbe981ec5628aaa4a029b69b1aa34aa59ab45f4448a6e3" + }, + { + "bytes": 1556, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/zoom_in.png", + "role": "icon_asset", + "sha256": "948640c5b4b7bce9f91bde2322f21767c3111e17c3ee9cffb4ccd2864e456de6" + }, + { + "bytes": 1493, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/actions/zoom_out.png", + "role": "icon_asset", + "sha256": "826fdd64a545de255f377fa54cdbe9c5b89b59b0d73d5abc232b71abbae53165" + }, + { + "bytes": 1841, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/status/dialog_information.png", + "role": "icon_asset", + "sha256": "6ee48b78d43aa857ab817d7753ccde7b3be7d4604ac86e341e323b354c30e478" + }, + { + "bytes": 1346, + "path": "linuxcnc/share/gmoccapy/icons/material-light/48x48/status/dialog_warning.png", + "role": "icon_asset", + "sha256": "057c8aaaeb5d0fc0a44f887964498ff6229c24dde7020ccaec273238dd6f7ba5" + }, + { + "bytes": 11357, + "path": "linuxcnc/share/gmoccapy/icons/material-light/LICENSE", + "role": "icon_asset", + "sha256": "58d1e17ffe5109a7ae296caafcadfdbe6a7d176f0bc4ab01e12a689b0499d8bd" + }, + { + "bytes": 366, + "path": "linuxcnc/share/gmoccapy/icons/material-light/NOTICE", + "role": "icon_asset", + "sha256": "1917e07ae29680da629688a7bbed3269cc81a2f8081176dfe16d08eb4a478c33" + }, + { + "bytes": 459, + "path": "linuxcnc/share/gmoccapy/icons/material-light/index.theme", + "role": "icon_asset", + "sha256": "bec9879db6d2651f8a41cff605903ea7dcd708c4a6243e47ef7c8ea5313630d2" + }, + { + "bytes": 1007, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/Submakefile", + "role": "implementation", + "sha256": "a2886508fc1a425a8962e69636ec0026ced9c6df02ea02eac9c5d39c2b23af07" + }, + { + "bytes": 0, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/__init__.py", + "role": "implementation", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + { + "bytes": 17827, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/__pycache__/dialogs.cpython-312.pyc", + "role": "implementation", + "sha256": "4ffa96ed9183d9ad18c25b70fa4143d63cf765c5f93ea23f822e2cf15a7e9b45" + }, + { + "bytes": 24189, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/__pycache__/getiniinfo.cpython-312.pyc", + "role": "implementation", + "sha256": "6e6840b7afd5fed9fb201837edcef7ce92f888aefabcd0299abfd23192f8f456" + }, + { + "bytes": 356463, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/__pycache__/gmoccapy.cpython-312.pyc", + "role": "implementation", + "sha256": "61085327c1006ccc556ac6ed0aa32df6ea18f02ac3d5f26beabb68f43a67a552" + }, + { + "bytes": 4328, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/__pycache__/icon_theme_helper.cpython-312.pyc", + "role": "implementation", + "sha256": "ef1c65ca30682821d1fd056645c86a4afd829103bdce798117d9756ee234ea2c" + }, + { + "bytes": 17674, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/__pycache__/notification.cpython-312.pyc", + "role": "implementation", + "sha256": "a76deccda9b9ab1c93b4a50092d788607086cb336dd29135a0f51dc00c8fbeea" + }, + { + "bytes": 3926, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/__pycache__/player.cpython-312.pyc", + "role": "implementation", + "sha256": "b1cb4541880861d1efd27eeaa4f4f78ae41b118a896eeef4922cb487220ea338" + }, + { + "bytes": 2353, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/__pycache__/preferences.cpython-312.pyc", + "role": "implementation", + "sha256": "8655fb41eb5e8fe8a74d24025902a1e0d3597291ffc53194cbd78baac9a54455" + }, + { + "bytes": 2263, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/__pycache__/widgets.cpython-312.pyc", + "role": "implementation", + "sha256": "b417e22d8df64eaf86981ccb1df225a8d8cc3ba2e8341d7d624661a388479316" + }, + { + "bytes": 10577, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/dialogs.py", + "role": "implementation", + "sha256": "045430bbb041acd2bdfff0594b0efb14f85d01ebcae452382670944c3192f768" + }, + { + "bytes": 19430, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/getiniinfo.py", + "role": "implementation", + "sha256": "fa93a8998a2a7701e2b822ef202d6e3d481f7b9c5b97fc82c41bded2896c9e03" + }, + { + "bytes": 486712, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.glade", + "role": "implementation", + "sha256": "60c38418b7fb8690cc8cd942e2b758782bb734ee458d34eb63a416ba084a2112" + }, + { + "bytes": 267992, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.py", + "role": "implementation", + "sha256": "2edc4d4689794ba26e6bfbad33e6d35a0b8d7c96f25878fdb76658e3fa18aff5" + }, + { + "bytes": 3249, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/icon_theme_helper.py", + "role": "implementation", + "sha256": "caf444318e1d6864f8257c5f3658d8657c164007ce54c5ec10cddd068317d8a0" + }, + { + "bytes": 14320, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/notification.py", + "role": "implementation", + "sha256": "81ee7e9262e3b633f506bde182918e12b196ddb655dfe980c7436e12c3b17bae" + }, + { + "bytes": 2630, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/player.py", + "role": "implementation", + "sha256": "82d150e2ae3b6a7aa67d056b3d5f002274b0362446ebe4782fc6c7872052b159" + }, + { + "bytes": 1617, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/preferences.py", + "role": "implementation", + "sha256": "6d09e9f38b7ab0feff2e436020c4a4a2db0f7126abb377ce08de05d41e46039d" + }, + { + "bytes": 92185, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/release_notes.txt", + "role": "implementation", + "sha256": "c9312be69232098f803121f34d4873e10b4c9e9a0ad37913c6ac7d81e8e0577e" + }, + { + "bytes": 1596, + "path": "linuxcnc/src/emc/usr_intf/gmoccapy/widgets.py", + "role": "implementation", + "sha256": "dbce55d80efcdee00e371e875983207c07facf29eca1805398d0286ef8877c02" + }, + { + "bytes": 62544, + "path": "linuxcnc/src/po/gmoccapy/bg.po", + "role": "translation", + "sha256": "58badb61def8b85ec7ae8853bc2253d201b40cb3322e759749f826135b313a15" + }, + { + "bytes": 54297, + "path": "linuxcnc/src/po/gmoccapy/cs.po", + "role": "translation", + "sha256": "e298bd255aae0660a0e4c8e46941cc766f73310d75bd56eb8c201a4450cb5f86" + }, + { + "bytes": 38218, + "path": "linuxcnc/src/po/gmoccapy/da.po", + "role": "translation", + "sha256": "104ac13f2ca27d5b3f75a789110ab8aaa0b74533ca97f7a5c4273665c25fbdd1" + }, + { + "bytes": 91367, + "path": "linuxcnc/src/po/gmoccapy/de.po", + "role": "translation", + "sha256": "df55417d669720d0b665d833f968d0ca3d9a3be26d186ef807db38fcc3c223e7" + }, + { + "bytes": 91198, + "path": "linuxcnc/src/po/gmoccapy/es.po", + "role": "translation", + "sha256": "6fa94ce0db4534417bb1f7b6cbe3dca41fa9a5f72fcd24ce7e946f45faf6a6f8" + }, + { + "bytes": 38243, + "path": "linuxcnc/src/po/gmoccapy/fi.po", + "role": "translation", + "sha256": "dc1cb2683ab07ede6087e6fbc070a9fc910dffc6b1688d164801498a006c9ee3" + }, + { + "bytes": 85880, + "path": "linuxcnc/src/po/gmoccapy/fr.po", + "role": "translation", + "sha256": "d618ca8f782916fe75f5fad7d7581748d2a8583fbae7d9e9ebf9b0496523f2a3" + }, + { + "bytes": 38245, + "path": "linuxcnc/src/po/gmoccapy/gmoccapy.pot", + "role": "translation", + "sha256": "27f29281c22455e402c6937d7a1d40e3c8d0f1a3f24e7f1fcc6c4bc299a6146d" + }, + { + "bytes": 89032, + "path": "linuxcnc/src/po/gmoccapy/hu.po", + "role": "translation", + "sha256": "e2bbcfb5801e65bce2bd459a97e4717666620cc807761e42f39e3a84b1d73a18" + }, + { + "bytes": 38218, + "path": "linuxcnc/src/po/gmoccapy/it.po", + "role": "translation", + "sha256": "ae571a9e40ec19c18837737db841492b1b8ec2751aea8d29d6addc5dc3c72d31" + }, + { + "bytes": 38243, + "path": "linuxcnc/src/po/gmoccapy/ja.po", + "role": "translation", + "sha256": "dc1cb2683ab07ede6087e6fbc070a9fc910dffc6b1688d164801498a006c9ee3" + }, + { + "bytes": 49393, + "path": "linuxcnc/src/po/gmoccapy/nb.po", + "role": "translation", + "sha256": "937f63ea9f9a16a0a9bd6895cce62b8952550052e4d0930ed26f08c167aba67a" + }, + { + "bytes": 86797, + "path": "linuxcnc/src/po/gmoccapy/pl.po", + "role": "translation", + "sha256": "cf5861ef6ed214f8e56ac61ff895b01150210f3e6997835dcfc0a635c5f90a52" + }, + { + "bytes": 38243, + "path": "linuxcnc/src/po/gmoccapy/pt_BR.po", + "role": "translation", + "sha256": "dc1cb2683ab07ede6087e6fbc070a9fc910dffc6b1688d164801498a006c9ee3" + }, + { + "bytes": 38520, + "path": "linuxcnc/src/po/gmoccapy/ro.po", + "role": "translation", + "sha256": "a19a49733f88b29f1763a54dc8bd17006ae5aa480f0c3c9a1767de1656afdf03" + }, + { + "bytes": 38218, + "path": "linuxcnc/src/po/gmoccapy/ru.po", + "role": "translation", + "sha256": "18543c0e4768d2f5109c236c6a7546b499b3598ffef35c0230e14778bfdcf759" + }, + { + "bytes": 55199, + "path": "linuxcnc/src/po/gmoccapy/sk.po", + "role": "translation", + "sha256": "4758aaea90a4dd090472ac25d235c7497a7c51781c2d8eb5fa9a4336e2ae3f5a" + }, + { + "bytes": 73921, + "path": "linuxcnc/src/po/gmoccapy/sr.po", + "role": "translation", + "sha256": "49a71c9c67062e33c8f42173a42228edfd9a05668842909e639d24f3125cf39d" + }, + { + "bytes": 38243, + "path": "linuxcnc/src/po/gmoccapy/sv.po", + "role": "translation", + "sha256": "dc1cb2683ab07ede6087e6fbc070a9fc910dffc6b1688d164801498a006c9ee3" + }, + { + "bytes": 44896, + "path": "linuxcnc/src/po/gmoccapy/tr.po", + "role": "translation", + "sha256": "d94dad977c6bf6ebc49ffa4ff09d58a9b6f9f5ac7981b0d8fdaacaabce2f6bdd" + }, + { + "bytes": 39125, + "path": "linuxcnc/src/po/gmoccapy/vi.po", + "role": "translation", + "sha256": "fdeeb94f78e1573ee64efb653827ef5d4fdeaaad0d86f2b30cb739e19720c345" + }, + { + "bytes": 56170, + "path": "linuxcnc/src/po/gmoccapy/zh_CN.po", + "role": "translation", + "sha256": "7fdd5f0567a6049441e77750c31a5929b579f87b762d70b7638fb1a2b081665c" + }, + { + "bytes": 38243, + "path": "linuxcnc/src/po/gmoccapy/zh_HK.po", + "role": "translation", + "sha256": "dc1cb2683ab07ede6087e6fbc070a9fc910dffc6b1688d164801498a006c9ee3" + }, + { + "bytes": 38243, + "path": "linuxcnc/src/po/gmoccapy/zh_TW.po", + "role": "translation", + "sha256": "dc1cb2683ab07ede6087e6fbc070a9fc910dffc6b1688d164801498a006c9ee3" + } + ], + "role_counts": { + "documentation": 2, + "documentation_asset": 27, + "icon_asset": 973, + "implementation": 28, + "installed_ui_asset": 1, + "simulation_asset": 16, + "simulation_ini": 29, + "simulation_resource": 69, + "simulation_runtime_data": 64, + "translation": 24 + }, + "schema": "gmoccapy-file-inventory.v1", + "scope": [ + "linuxcnc/configs/sim/gmoccapy/**", + "linuxcnc/src/emc/usr_intf/gmoccapy/**", + "linuxcnc/lib/python/gmoccapy/**", + "linuxcnc/share/gmoccapy/**", + "linuxcnc/src/po/gmoccapy/**", + "linuxcnc/docs/src/gui/gmoccapy.adoc", + "linuxcnc/docs/man/man1/gmoccapy.1", + "linuxcnc/docs/src/gui/images/gmoccapy_*", + "linuxcnc/docs/src/user/images/gmoccapy_*" + ] +} diff --git a/doc-rtcp/gmoccapy-file-inventory.md b/doc-rtcp/gmoccapy-file-inventory.md new file mode 100644 index 0000000..a0bbe44 --- /dev/null +++ b/doc-rtcp/gmoccapy-file-inventory.md @@ -0,0 +1,18 @@ +# GMOCCAPY 文件清单 + +清单范围内共 `1233` 个文件;每项包含相对路径、角色、字节数和 SHA-256。 + +| 角色 | 数量 | +|---|---:| +| `documentation` | 2 | +| `documentation_asset` | 27 | +| `icon_asset` | 973 | +| `implementation` | 28 | +| `installed_ui_asset` | 1 | +| `simulation_asset` | 16 | +| `simulation_ini` | 29 | +| `simulation_resource` | 69 | +| `simulation_runtime_data` | 64 | +| `translation` | 24 | + +完整逐文件数据见 [`gmoccapy-file-inventory.json`](gmoccapy-file-inventory.json)。 diff --git a/doc-rtcp/gmoccapy-important-changes-v2.png b/doc-rtcp/gmoccapy-important-changes-v2.png new file mode 100644 index 0000000..1bc2761 Binary files /dev/null and b/doc-rtcp/gmoccapy-important-changes-v2.png differ diff --git a/doc-rtcp/gmoccapy-important-changes.png b/doc-rtcp/gmoccapy-important-changes.png new file mode 100644 index 0000000..fcb1d5e Binary files /dev/null and b/doc-rtcp/gmoccapy-important-changes.png differ diff --git a/doc-rtcp/gmoccapy-load-file-page.png b/doc-rtcp/gmoccapy-load-file-page.png new file mode 100644 index 0000000..c89b80d Binary files /dev/null and b/doc-rtcp/gmoccapy-load-file-page.png differ diff --git a/doc-rtcp/gmoccapy-program-loaded.png b/doc-rtcp/gmoccapy-program-loaded.png new file mode 100644 index 0000000..e9cfcb1 Binary files /dev/null and b/doc-rtcp/gmoccapy-program-loaded.png differ diff --git a/doc-rtcp/xyzac-trt-autonomous-execution-prompt.md b/doc-rtcp/xyzac-trt-autonomous-execution-prompt.md new file mode 100644 index 0000000..135e2d2 --- /dev/null +++ b/doc-rtcp/xyzac-trt-autonomous-execution-prompt.md @@ -0,0 +1,60 @@ +# `nextTask-rtcp.md` 持续执行提示词 + +复制下面的提示词即可从五轴 XYZAC TRT Web/WASM 轨道持续执行: + +```text +你是本仓库的 XYZAC TRT Web/WASM 源码对标工程代理。请持续推进任务,不要只给计划;每轮都从 nextTask-rtcp.md 当前指针认领并执行,直到任务 verified、明确 blocked 或遇到 Stop 条件。 + +1. 先读取 nextTask-rtcp.md 的 Current、Read、Task、Next、Verify、Stop;不要用 nextTask.md 或 nextTask1.md 替代它们。 +2. 按 Task.direct_inputs 读取当前任务的直接源码、配置和报告;不要批量加载聊天记录、完整日志或无关 coverage 文件。 +3. 开始前运行: + python3 scripts/validate_baseline.py + python3 scripts/validate_download_index.py + python3 scripts/validate_task_pointer.py nextTask-rtcp.md --lock context-lock.json +4. 确认 task_id、context_id、active_case、直接输入、required_outputs 和完成报告;当前案例固定为: + linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini +5. 将当前 Task.status 从 queued 改为 in_progress 前,先读取: + doc-rtcp/xyzac-trt-control-panel-web-wasm-design.md + doc-rtcp/xyzac-trt-web-wasm-implementation-plan.md + doc-rtcp/xyzac-trt-web-wasm-source-parity-contract.md +6. 严格遵守源码唯一权威:所有 task、interpreter、TP、motion、XYZAC forward/inverse、RTCP、HAL、IO、tool、preview、recovery 和 state hash 必须来自 LinuxCNC WASM/Worker;React、JS、Three.js 只能输入、投影和显示。 +7. 对每个功能建立 source behavior slice,必须保留 source path、symbol、source hash、输入、native command、WASM command、gate、authoritative output、错误、恢复和 Web control id。 +8. 不得使用 JS G-code preview、JS 姿态/RTCP 补偿、浏览器墙钟 tick、主线程 OPFS 写入、直接 WASM 指针、mock runtime 或宿主 LinuxCNC fallback 冒充 WASM 通过。 +9. 每项实现先写失败边界和专项测试,再做最小垂直切片;优先复用现有 protocol.v1、WorkerClient、AxisOperationController、PanelSnapshotV1、WASM ABI 和固定 tick runtime。 +10. 五轴必须特别验证: + - XYZAC 坐标、五 joints、A/C 角度单位和 limits; + - xyzac-trt-kins forward/inverse、tool offset、y/z offset、rotation point; + - M428/M429/M430 remap、HAL_PIN_VARS、motion.switchkins-type 和状态确认; + - helix/arc/姿态变化、singularity、non-finite、limit、following error; + - Vismach pose/joints/toolpath 只消费 authoritative snapshot; + - pause/resume/abort/restart/checkpoint/recovery 不重复 segment、M-code 或 IO/tool side effect。 +11. 所有有副作用命令必须有 operation_id、seq、ledger prepare/ack/result/commit/reconcile;超时不能盲目重发,必须查询 Worker ledger 或 authoritative snapshot。 +12. 运行任务专属测试、真实 WASM Worker/session、native 对照、React typecheck/build、Three.js canvas 检查和报告 self-hash。命令不存在时先创建任务产物或明确记录 blocked,不能写成已通过。 +13. 报告必须包含 context_id、case_path、输入/输出 hash、测试命令、normal/boundary/error/recovery、state hash、command trace、tick trace、first divergent tick、failure samples、known blockers 和 report_sha256。 +14. 失败样本必须保留并分类为 SOURCE_BLOCKED、HOST_EXCLUDED、REAL-EXCLUDED、BLOCKED_RESOURCE、BLOCKED_HAL、BLOCKED_INI、BLOCKED_STARTUP 或具体 Worker/Task/motion/kinematics pending;不得删失败、降级检查或把 blocker 改名为通过。 +15. 只有当前任务的专项测试、native/WASM/Worker 证据、完整回归和报告 self-hash 全部通过,才能把 Task.status 改为 verified;否则改为 blocked 并保留证据。 +16. 当前任务 verified 后,更新 nextTask-rtcp.md 的 Current、Next、Verify、Stop 和 completion evidence;只有依赖满足的下一个任务才可写为 queued。不要修改 nextTask.md、nextTask1.md、context-lock、ABI、protocol、schema、许可证决定或 release gate。 +17. 不要在 verified + queued 状态停下;若 Next 依赖满足,立即认领下一个任务并继续执行。若外部源码、oracle、浏览器、OPFS、实时硬件、owner 输入或批准变更缺失,则保持 blocked,不自动重试同一阻塞。 +18. 每隔约 30 秒发送简短进度更新,说明当前 task_id、已完成检查、正在执行的测试和 blocker;不要输出无关长日志。 +19. 只有 nextTask-rtcp.md 明确 next_task: none 且 local continuation verified,或当前任务满足 Stop/外部阻塞条件时才暂停。selected-case verified 不得写成全 LinuxCNC parity,release_status 继续保持 STOP_RELEASE,直到源码、WASM authority、canonical parity、recovery、browser、oracle 和其它正式门禁全部有证据。 + +现在立即读取 nextTask-rtcp.md,并从当前 Task 开始执行。 +``` + +## 推荐调用语句 + +最短调用: + +```text +按 nextTask-rtcp.md 接续执行,严格使用 doc-rtcp/xyzac-trt-autonomous-execution-prompt.md 的规则。 +``` + +更强约束调用: + +```text +持续执行 nextTask-rtcp.md:先验证基线和指针,认领当前任务,按源码 slice 实现 LinuxCNC WASM 唯一权威闭环,运行 native/WASM/Worker/React/Three.js 证据,更新报告和指针;不要修改 nextTask.md、nextTask1.md、context lock、ABI、protocol、schema 或 release gate,也不要在 verified+queued 状态停下。 +``` + +## 当前起点 + +当前指针的任务是 `SRC-00`,目标是建立 AXIS/XYZAC source slice inventory 和 WASM authority contract;下一任务是 `WASM-00`。读取和执行状态以根目录的 [`nextTask-rtcp.md`](../nextTask-rtcp.md) 为准。 diff --git a/doc-rtcp/xyzac-trt-control-panel-web-wasm-design.md b/doc-rtcp/xyzac-trt-control-panel-web-wasm-design.md new file mode 100644 index 0000000..6338160 --- /dev/null +++ b/doc-rtcp/xyzac-trt-control-panel-web-wasm-design.md @@ -0,0 +1,529 @@ +# `xyzac-trt.ini` 控制面板、数据流、控制约束与 Web/WASM 设计基础 + +更新时间:2026-08-25 + +本文专门分析: + +```text +linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini +``` + +目标不是复刻一个静态 AXIS 外观,而是为 Web/WASM 控制台建立可验证的功能、数据、控制和权限模型。所有“按钮是否可点”的结论都必须来自 LinuxCNC authoritative task/motion/HAL 状态;React/浏览器只能投影状态并发出带 gate 的命令。 + +相关运行入口和基础说明: + +- [`run-5axis-rtcp.sh`](../run-5axis-rtcp.sh) +- [`5axis-rtcp-shortcut.md`](5axis-rtcp-shortcut.md) +- [`gmoccapy-control-panel-data-control-flow.md`](gmoccapy-control-panel-data-control-flow.md) +- [`5axis-rtcp-running.png`](5axis-rtcp-running.png) + +## 1. 案例边界 + +### 1.1 入口配置 + +`xyzac-trt.ini` 的关键配置如下: + +| INI 段 | 字段 | 功能 | +|---|---|---| +| `[EMC]` | `MACHINE = sim-xyzac-trt-kins (switchkins)` | 案例名称和 switchkins 语义 | +| `[DISPLAY]` | `DISPLAY = axis` | 主控制面板是 AXIS/Tk,不是 GMOCCAPY | +| `[DISPLAY]` | `OPEN_FILE = ./demos/xyzac_switchkins.ngc` | 启动后预置的 G-code 文件 | +| `[DISPLAY]` | `PYVCP = ./xyzac-trt.xml` | 右侧 SWITCHKINS/vismach-clear 面板 | +| `[DISPLAY]` | `JOG_AXES = XYZC` | 手动点动显示 X/Y/Z/C;A 仍属于五轴运动学 | +| `[DISPLAY]` | `PROGRAM_PREFIX = ../../nc_files` | 默认程序搜索目录 | +| `[DISPLAY]` | `POSITION_OFFSET = RELATIVE` | DRO 默认显示相对坐标 | +| `[DISPLAY]` | `POSITION_FEEDBACK = ACTUAL` | DRO 使用 actual position | +| `[RS274NGC]` | `SUBROUTINE_PATH = ./remap_subs` | M428/M429/M430 和 helix 子程序路径 | +| `[RS274NGC]` | `HAL_PIN_VARS = 1` | 允许 remap 访问 HAL pin | +| `[RS274NGC]` | `REMAP = M428/M429/M430` | kinematics 状态切换入口 | +| `[RS274NGC]` | `PARAMETER_FILE = xyzac.var` | RS274 参数持久化 | +| `[KINS]` | `KINEMATICS = xyzac-trt-kins sparm=identityfirst` | 5 关节 XYZAC,0=identity,1=TRT,2=userk | +| `[KINS]` | `JOINTS = 5` | X/Y/Z/A/C 五个 joint | +| `[HAL]` | `HALFILE = LIB:basic_sim.tcl` | 生成仿真 motion/HAL/模拟设备 | +| `[HAL]` | `POSTGUI_HALFILE = switchkins_postgui.hal` | GUI 创建后连接 PyVCP 控件 | +| `[HAL]` | `motion.analog-out-03 => motion.switchkins-type` | remap 写入 switchkins 的控制通道 | +| `[HAL]` | `loadusr -W xyzac-trt-gui` | 独立 Vismach 五轴模型进程 | +| `[TRAJ]` | `COORDINATES = XYZAC` | 解释器和轨迹规划的笛卡尔坐标集合 | +| `[EMCIO]` | `TOOL_TABLE = xyzac-trt.tbl` | 工具长度/直径等数据 | + +### 1.2 三个界面实体 + +```text +AXIS 主窗口 + ├── Tk 菜单、工具栏、Manual Control、MDI、Preview、DRO、G-code view + ├── PyVCP xyzac-trt.xml(右侧 SWITCHKINS 面板) + └── AXIS 内部 Python/Tk command + linuxcnc.stat 状态轮询 + +xyzac-trt-gui 进程 + └── Python vismach 模型,仅消费 HAL joint feedback/tool-offset/offset + +LinuxCNC runtime + ├── linuxcncsvr / NML + ├── milltask / RS274NGC interpreter + ├── motmod / TP / switchkins / xyzac-trt-kins + └── HAL / simulated home / spindle / tool-change / PyVCP pins +``` + +AXIS 是控制和状态投影者,PyVCP 是 HAL 控件,Vismach 是可视化消费者;三者都不是独立的运动 authority。 + +## 2. 启动与初始化数据流 + +```text +run-5axis-rtcp.sh + │ + ▼ +/usr/bin/linuxcnc -r xyzac-trt.ini + │ + ├── 读取 [DISPLAY]/[TASK]/[HAL]/[KINS]/[TRAJ] + ├── 启动 linuxcncsvr + ├── 启动 milltask + ├── 运行 basic_sim.tcl 生成 HAL + ├── loadusr xyzac-trt-gui + ├── 执行 switchkins_postgui.hal + └── 启动 /usr/bin/axis -ini xyzac-trt.ini + │ + ├── open_file_guts(OPEN_FILE) + ├── 创建 Tk/AXIS widgets + ├── 读取 linuxcnc.stat + └── 周期刷新 DRO/preview/gates +``` + +### 2.1 AXIS 初始化的责任 + +主要来源: + +```text +linuxcnc/src/emc/usr_intf/axis/scripts/axis.py +``` + +核心职责: + +1. 解析 INI 和显示选项。 +2. 初始化 `linuxcnc.command()`、`linuxcnc.stat()` 和 HAL component。 +3. 根据 `COORDINATES=XYZAC` 建立 axis/joint 映射。 +4. 读取 `OPEN_FILE`,通过 `open_file_guts()` 和 `c.program_open()` 载入程序。 +5. 读取 G-code,运行 canon/preview 生成程序轨迹。 +6. 周期 `s.poll()`,将 position、joint position、homed、limit、tool、G/M code、task/interpreter state 投影到 Tk 变量。 +7. 根据 `running()`、`manual_ok()`、`all_homed()` 和 task/motion 状态决定按钮是否响应。 + +### 2.2 Vismach 初始化的责任 + +`linuxcnc/src/hal/user_comps/vismach/xyzac-trt-gui.py` 创建 HAL component: + +```text +xyzac-trt-gui.table-x HAL_FLOAT IN +xyzac-trt-gui.saddle-y HAL_FLOAT IN +xyzac-trt-gui.spindle-z HAL_FLOAT IN +xyzac-trt-gui.tilt-a HAL_FLOAT IN +xyzac-trt-gui.rotate-c HAL_FLOAT IN +xyzac-trt-gui.y-offset HAL_FLOAT IN +xyzac-trt-gui.z-offset HAL_FLOAT IN +xyzac-trt-gui.tool-offset HAL_FLOAT IN +``` + +模型通过 `HalTranslate`/`HalRotate` 将这些输入转换为 OpenGL 模型姿态。它不发 `program_run`、`jog`、`home` 或 kinematics 命令。 + +## 3. AXIS 主控制面板功能 + +### 3.1 顶部菜单和工具栏 + +AXIS/Tk 主面板通常提供: + +| 类别 | 典型动作 | LinuxCNC command/效果 | +|---|---|---| +| 文件 | Open | `program_open(path)`,更新 loaded file 和 preview | +| AUTO 按钮组 | `hbtb_auto` / `btn_load` | AXIS 的 Open/Load 文件入口;只在程序未运行时打开文件选择器 | +| 文件 | Reload | 重新读取当前文件;运行中拒绝 | +| 文件 | Recent files | 偏好文件保存最近路径,最多 10 项 | +| 文件 | Edit | 调用 `EDITOR`/外部编辑器;不改变 runtime authority | +| 程序 | Run | `c.mode(MODE_AUTO)` + `c.auto(AUTO_RUN, start_line)` | +| 程序 | Step | `c.auto(AUTO_STEP)` | +| 程序 | Pause | `c.auto(AUTO_PAUSE)` | +| 程序 | Resume | `c.auto(AUTO_RESUME)` | +| 程序 | Stop | `c.abort()`,同时设置 GUI abort 状态 | +| 程序 | Run from line | 设置 first line 后再 AUTO_RUN,风险高于普通 Run | +| 机床 | Power | `c.state(STATE_ON/OFF)` | +| 机床 | E-stop | `c.state(STATE_ESTOP/STATE_ESTOP_RESET)` 或硬件链路 | +| 机床 | Home/Unhome | `c.home(joint)` / `c.unhome(joint)` | +| 机床 | Spindle | `c.spindle(...)` 或 MDI/halui | +| 机床 | Feed/rapid/spindle override | `c.feedrate()`/`c.maxvel()` 或相应 HAL/command | +| 辅助 | HAL show/tooleditor | 外部工具或 tool data action | +| 视图 | Perspective/X/Y/Z/clear plot | 只改变 view/preview,不改变运动状态 | + +菜单图标不是 authority。每个动作必须以 command result 和下一次 status snapshot 确认。 + +### 3.2 Manual Control + +Manual 页包含: + +- X/Y/Z/A/C 轴选择;`JOG_AXES=XYZC` 会影响默认可点动轴列表。 +- Continuous/incremental jog 选择。 +- jog speed、angular jog speed。 +- Home All、单轴 Home、Unhome。 +- Touch Off、Tool Touch Off。 +- feed/rapid/spindle override。 +- spindle start/stop/reverse。 + +AXIS 的 `manual_ok()` 条件: + +```text +task_state == STATE_ON +并且当前没有 AUTO/MDI 正在运行 +并且 interp_state == INTERP_IDLE +或当前为 MDI 且 queued_mdi_commands < max_queued_mdi_commands +``` + +`jog_on()` 还要满足当前 tab 是 manual、轴/joint 映射有效、没有 active limit 阻止动作。Web/WASM 应把这些结果作为 gate reason 返回,不仅仅把 HTML button 设为 disabled。 + +### 3.3 MDI + +MDI 入口通过 `ensure_mdi()`: + +1. 检查 `manual_ok()`。 +2. 关闭 teleop 或切换到合适 motion mode。 +3. `c.mode(MODE_MDI)`。 +4. 用户输入字符串后调用 `c.mdi(command)`。 +5. interpreter 执行后由 `stat.interp_state`、`queued_mdi_commands`、位置和错误通道反馈。 + +MDI 不是任意字符串的本地脚本执行器。Web/WASM 必须保留 G-code parser、能力边界、长度限制、错误码和 operation id。 + +### 3.4 Preview/DRO/G-code view + +AXIS 周期更新同时刷新: + +- `stat.actual_position` / `joint_actual_position` → DRO。 +- `stat.g5x_offset` / `g92_offset` / `rotation_xy` / `tool_offset` → 坐标投影。 +- `stat.gcodes` / `stat.mcodes` / `settings` → G-code 信息。 +- canon/preview → 静态程序路径。 +- `motion_line` / `running_line` → 当前行高亮。 +- `joint.pos-fb` → Vismach 模型。 + +静态 preview 和 realtime/live plot 必须分开建模;Web 端不能用 JS 重新解析一份程序来代替 WASM canonical motion。 + +## 4. `xyzac-trt.xml` SWITCHKINS 面板 + +### 4.1 控件定义 + +PyVCP XML 定义: + +| 控件文本 | HAL pin | 目标 | +|---|---|---| +| `IDENTITY` | `pyvcp.type0-button` | 触发 `halui.mdi-command-00` → M429 | +| `TCP:XYZAC` | `pyvcp.type1-button` | 触发 `halui.mdi-command-01` → M428 | +| `userk` | `pyvcp.type2-button` | 触发 `halui.mdi-command-02` → M430 | +| 多标签 | `kinstype.is-0/1/2` | 显示当前 switchkins type | +| `vismach-clear` | `pyvcp.vismach-clear` | 连接 `vismach.plotclear` | + +`switchkins_postgui.hal` 将按钮连接到 HALUI MDI command: + +```text +pyvcp.type0-button → halui.mdi-command-00 +pyvcp.type1-button → halui.mdi-command-01 +pyvcp.type2-button → halui.mdi-command-02 +``` + +这意味着浏览器端的“TCP:XYZAC”按钮不能直接写 `motion.switchkins-type`,应走同等的受控 command/remap 路径,并等待确认状态。 + +### 4.2 switchkins 状态模型 + +```text +type 0 / M429 → identity +type 1 / M428 → xyzac TRT TCP/RTCP +type 2 / M430 → userk +``` + +`xyzac-trt-kins.c` 在 `sparm=identityfirst` 下将 type 0 绑定 identity,type 1 绑定 `trtKinematicsSetup + xyzacKinematicsForward/Inverse`,type 2 绑定 userk。配置注释和实现必须同时读取,不能只依据面板标签。 + +## 5. 五轴 RTCP 控制流 + +### 5.1 M428/M429 remap + +`428remap.ngc` 的关键操作: + +```text +验证 motion.switchkins-type HAL pin 存在 +M68 E3 Q1 写 motion.analog-out-03 = 1 +M66 E0 L0 同步等待 +读取 motion.switchkins-type,必须等于 1 +``` + +`429remap.ngc` 相同,但写入 `Q0`。失败时输出 debug STOP 并结束子程序;Web/WASM 需要把这些失败变成稳定的错误码,而不是只显示“按钮没有反应”。 + +### 5.2 典型 helix 数据流 + +`helix_ac.ngc` 的典型顺序: + +```text +M429 identity +G0 / G10 L20 机床坐标定位和设置工作偏置 +M428 XYZAC TRT / TCP +G0 A... C... 改变刀轴姿态 +G2 ... 在 RTCP 运动学下插补 +M429 切回 identity +G0 ... 安全返回 +M428 如后续仍需 TCP +``` + +这里的关键不是“同时有 A/C 数字”,而是同一轨迹块由 XYZAC inverse kinematics 将 TCP pose 转换为五个 joint 命令。姿态变化可能导致 X/Y/Z 补偿变化;因此前端必须同时展示笛卡尔 pose、joint positions、active kinematics mode 和 tool offset。 + +### 5.3 Vismach 数据流 + +```text +joint.0.pos-fb → table-x → HalTranslate +joint.1.pos-fb → saddle-y → HalTranslate +joint.2.pos-fb → spindle-z → HalTranslate +joint.3.pos-fb → tilt-a → HalRotate(A) +joint.4.pos-fb → rotate-c → HalRotate(C) +motion.tooloffset.z → tool-offset → HalTranslate(tool) +y/z-offset → rotary geometry placement +``` + +Vismach 只读 HAL input。Web/WASM 的 Three.js adapter 应消费 authoritative `visual.pose`/`joints`/`toolpath`,而不是在 React 中根据 A/C 自行推算补偿。 + +## 6. 按钮互相制约条件 + +下表是 AXIS/LinuxCNC 语义的最小可执行门控。`running` 表示 AUTO 或 MDI 且 `interp_state != INTERP_IDLE`。 + +| 按钮/动作 | 必须满足 | 典型阻塞原因 | +|---|---|---| +| E-stop | 始终可用 | transport/session 不可用 | +| Power ON/OFF | 非 ESTOP;不在禁止转换状态 | `ESTOP_ACTIVE` | +| Reset | machine ON、非 running、无 active limit | `LIMIT_ACTIVE` / `INTERP_RUNNING` | +| Manual jog | `STATE_ON`、MANUAL、非 running、未 fault | `MACHINE_OFF` / `MODE_REQUIRED` | +| Home all | `manual_ok()`;必要时确认重复 homing | `NOT_ON` / `RUNNING` | +| 单轴 Home | `manual_ok()`;非 identity 时通常必须 joint mode;重复坐标字母禁用单轴 home | `JOINT_MODE_REQUIRED` | +| MDI | machine ON;队列未满;idle 或当前 MDI | `MDI_QUEUE_FULL` / `INTERP_RUNNING` | +| Open file | 解释器 idle;AXIS `open_file_guts` 临时切 MANUAL 后恢复原 mode | `INTERP_RUNNING` | +| Load program | machine ON、idle | `MACHINE_OFF` | +| Reload | idle 且已有 loaded file | `TASKFILE_MISSING` | +| Run | machine ON、idle、已有程序 | `TASKFILE_MISSING` / `INTERP_RUNNING` | +| Run from line | Run 条件 + 有明确 highlight line | `HIGHLIGHT_MISSING` | +| Step | machine ON 且有程序;进入 AUTO | `TASKFILE_MISSING` | +| Pause | machine ON 且 interpreter READING/WAITING | `PAUSE_STATE_GATE` | +| Resume | machine ON 且 interpreter PAUSED | `RESUME_STATE_GATE` | +| Stop/Abort | machine ON 且 running;abort 可以强制恢复状态 | `STOP_STATE_GATE` | +| Touch Off | manual_ok、MANUAL、允许的 motion mode | `JOINT_MODE_REQUIRED` | +| Tool Touch Off | Touch Off 条件 + 有当前工具 | `TOOL_MISSING` | +| TCP:XYZAC/M428 | remap HAL pin 存在、HAL net 正确、当前程序允许切换 | `MISSING_HAL_PIN` / `WRONG_SWITCHKINS_TYPE` | +| Identity/M429 | 同上,切换后必须确认 type=0 | `WRONG_SWITCHKINS_TYPE` | +| Vismach clear | 只清显示 plot,不改变 task/motion | 不应改变机床状态 | + +### 6.1 重要状态互斥 + +```text +ESTOP → 禁止所有运动、模式、MDI、RTCP 切换 +OFF → 可以复位/上电,禁止 Run/Jog/Home/MDI +ON + 未 homed → 允许 Manual/Home,禁止 AUTO/MDI(除非配置 NO_FORCE_HOMING) +RUNNING → 禁止 Open/Reload/Edit/MDI/Jog/Home;允许 Pause/Stop/状态观察 +PAUSED → 允许 Resume/Stop;禁止 MDI/Jog/重新加载 +RTCP type switch → 应在 interpreter idle、安全位置、无活动轨迹时执行 +``` + +## 7. 当前 Web/WASM 的对应实现 + +### 7.1 已存在的通用契约 + +当前 Web 代码已经提供可复用基础: + +| 文件 | 作用 | +|---|---| +| `web/app/axis-contract.mjs` | `AXIS_COMMANDS`、状态归一化、纯 gate 函数 | +| `web/app/axis-operation-controller.mjs` | operation id、gate 检查、command trace、错误保留 | +| `web/react/src/protocol.ts` | `MessageEnvelope`、`SimSnapshotV1`、`PanelSnapshotV1`、`AxisStateView` | +| `web/react/src/store.ts` | Worker message → authoritative snapshot/projected UI state | +| `web/react/src/worker-client.ts` | Dedicated Worker transport、seq、session/context、错误处理 | +| `web/react/src/visual-workflow.ts` | AXIS/GMOCCAPY/Vismach 的 visual source 分类 | + +现有 `AXIS_COMMANDS` 已覆盖 `PROGRAM_LOAD/RUN/STEP/PAUSE/RESUME/ABORT/RESTART`、`MDI_EXECUTE`、`JOG_START/STOP`、`HOME`、`ESTOP`、`RESET`、override、spindle、coolant、tool 和 probe。 + +### 7.2 `xyzac-trt` 需要的新增协议字段 + +建议在现有 `PanelSnapshotV1` 上 additive 扩展,不破坏 `sim_task.v1`: + +```json +{ + "configuration": { + "case_path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "coordinates": ["X", "Y", "Z", "A", "C"], + "kinematics": "xyzac-trt-kins", + "topology": "table-tilting-A/table-rotary-C", + "joint_count": 5, + "program_prefix": "../../nc_files" + }, + "kinematics": { + "family": "switchkins", + "active_type": 1, + "active_name": "xyzac-trt", + "available": [ + {"type": 0, "name": "identity", "command": "M429"}, + {"type": 1, "name": "xyzac-trt", "command": "M428"}, + {"type": 2, "name": "userk", "command": "M430"} + ], + "transition": "idle_only" + }, + "motion": { + "axes": {"x": 0, "y": 0, "z": 10, "a": 0, "c": 0}, + "joints": [0, 0, 10, 0, 0], + "tool_offset": {"z": 0}, + "rotation_center": {"x": 0, "y": 0, "z": 0}, + "axis_offsets": {"y": 20, "z": 10} + } +} +``` + +字段的 authoritative 来源必须来自 WASM kinematics/motion snapshot 或受控 native oracle;不能由 A/C slider 在浏览器中自行补偿。 + +### 7.3 命令映射建议 + +| Web action | protocol command | xyzac 行为 | +|---|---|---| +| `PROGRAM_LOAD` | `PROGRAM_LOAD` | 载入程序、canonical preview、重置 active segment | +| `PROGRAM_RUN` | `PROGRAM_RUN` | 进入 AUTO,固定 tick 推进 interpreter/TP | +| `PROGRAM_PAUSE` | `PROGRAM_PAUSE` | 保留当前 segment/kinematics type | +| `PROGRAM_RESUME` | `PROGRAM_RESUME` | 继续同一 program state | +| `PROGRAM_ABORT` | `PROGRAM_ABORT` | 停止并返回稳定 STOPPED/IDLE | +| `MDI_EXECUTE` | `MDI_EXECUTE` | 用于 `M428`/`M429`/`M430`,必须有 idle gate | +| `KINEMATICS_SELECT` | 建议新增 | payload `{type:0\|1\|2}`,内部走 remap/受控 HAL,不直接写 pin | +| `JOG_START` | `JOG_START` | 仅允许合法 axis/joint;XYZAC 的 A/C 速度单位独立校验 | +| `HOME` | `HOME` | 返回每个 joint homed 状态和错误 | +| `VISMACH_CLEAR` | `VISUAL_CLEAR` | 只清可视化轨迹,不清 task/motion/program | + +### 7.3.1 当前 Web 实现的五轴缺口 + +现有通用 AXIS contract 已有大量三轴/通用动作,但对本案例仍有明确缺口,不能把“按钮存在”当成已实现: + +| 缺口 | 当前状态 | 五轴实现要求 | +|---|---|---| +| `KINEMATICS_SELECT` | `AXIS_COMMANDS` 尚未定义 | 新增受 gate 的 type 0/1/2 命令,禁止前端直接写 HAL | +| `POWER` | `axisGate()` 有 `power` 分支,但 `AXIS_COMMANDS` 没有对应 action | 补齐 command map 和 Worker handler,保持 OFF/ESTOP 语义 | +| `VISUAL_CLEAR` | 原生 PyVCP 有 `vismach-clear`,通用 Web command 尚未固定 | 作为 visual-only command,不能改 program/motion hash | +| A/C jog | 当前 React 示例轴选择主要是 X/Y/Z | 增加 A/C angular units、limits、jog speed 和 joint/teleop gate | +| XYZAC pose | `PanelSnapshotV1.visual.pose` 目前是通用 Record | 增加明确 `a/c`、joint vector、kinematics type 和 tool-offset 字段 | +| rotation centers | 当前通用 snapshot 没有 TRT rotation-point 完整字段 | 将 x/y/z rotation point、y/z offset 纳入 configuration/authoritative | +| switchkins recovery | 通用 recovery 有 task/program,但没有 active kinematics mode | checkpoint 必须保存 type、remap transition、source line、joint/pose hash | + +### 7.4 Worker snapshot 到 React + +```text +WASM/native runtime + └── task + interpreter + motion + joints + kinematics + HAL + devices + │ + ▼ +protocol.v1 STATE_SNAPSHOT / COMMAND_RESULT + │ + ▼ +store.ts projection() + ├── axis_state + ├── gates + ├── task/program + ├── motion.axes / motion.joints + ├── authoritative.planner / authoritative.kinematics + └── visual.pose / visual.toolpath + │ + ▼ +React DRO / controls / Three.js Vismach +``` + +React 控件的 `disabled` 只是 projection;真正 gate 必须在 Worker/runtime 再检查一次。`AxisOperationController` 已提供 operation id、拒绝原因和 trace 结构,五轴切换应复用此机制。 + +## 8. Web/WASM 不应直接照搬的部分 + +| 原生机制 | Web/WASM 处理 | +|---|---| +| Tk widget/菜单 | React button/menu/keyboard command,但保留 source control id 和 tooltip 语义 | +| LinuxCNC NML | Dedicated Worker protocol envelope + session/seq/operation_id | +| HAL pin `motion.switchkins-type` | Worker-owned runtime capability;浏览器不能任意写 HAL pin | +| `loadusr -W xyzac-trt-gui` | Worker/Three.js Vismach adapter;visual-only,不是 authority | +| `OPEN_FILE` | Worker workspace resolver + exact path/resource closure | +| `G-code preview` | WASM canonical interpreter/TP segments;不能用 JS preview 冒充 | +| `linuxcnc.stat()` polling | fixed-tick STATE_SNAPSHOT/EVENT,带 state_hash | +| M428/M429 remap | WASM remap/interpreter capability,记录切换、错误和首个 divergent tick | +| POSIX realtime/HAL hardware | SIM-DEVICE 或 REAL-EXCLUDED,不能静默当成 Web 等价 | + +## 9. 推荐的 Web 端组件拆分 + +```text +XyzacTrtCaseResolver + ├── exact ini/hal/remap/resource resolver + └── startup diagnostics + +XyzacTrtControlStore + ├── axis_state / task / interp / homed / limits + ├── kinematics.active_type + ├── gates and gate reasons + └── command trace + +XyzacTrtOperationController + ├── PROGRAM_LOAD/RUN/PAUSE/RESUME/ABORT + ├── MDI M428/M429/M430 + ├── JOG/HOME/override + └── transition checks: idle, no fault, valid capability + +XyzacTrtPanel + ├── mode/task controls + ├── XYZAC DRO and joint view + ├── TCP/identity/userk segmented control + ├── gate-aware MDI/run/jog/home buttons + └── alarms and diagnostics + +XyzacTrtVismach + ├── pose/joints/toolpath from authoritative snapshot + ├── A/C table rotation + ├── tool-offset rendering + └── canvas/WebGL pixel/interaction checks +``` + +## 10. 验收和测试矩阵 + +### 正常流程 + +1. 加载 `xyzac_switchkins.ngc`。 +2. 验证 `XYZAC` 五个轴和五个 joints 出现在 snapshot。 +3. 验证 preview segment/source line/hash。 +4. `M429` → active type 0。 +5. `M428` → active type 1,等待确认后再允许 TCP 轨迹。 +6. 运行包含 A/C 变化的 helix;比较 Cartesian pose、joint positions、tool offset。 +7. `M429` 安全返回;验证 no duplicate segment/no stale active segment。 + +### 边界和拒绝 + +| 测试 | 期望 | +|---|---| +| ESTOP 时 M428 | blocked,不改变 kinematics type | +| interpreter running 时 M428 | blocked 或排队策略明确,不能隐式切换 | +| 缺 `HAL_PIN_VARS=1` | remap 错误码 `M428:Missing...`,保留证据 | +| 缺 `motion.switchkins-type` net | `WRONG_SWITCHKINS_TYPE`/source diagnostic | +| A/C 超限 | limit/fault snapshot,禁止继续运动 | +| tool offset 非有限值 | fail closed,不能送入 kinematics | +| pause 后 resume | segment、kinematics type、state hash 连续 | +| abort 后 reload | program/task/preview 清理顺序确定 | +| Worker restart | checkpoint 恢复 kinematics type、program line、joint/pose hash | +| Vismach clear | 只清 visual layer,task/program/state_hash 不变 | + +### 必须保存的证据 + +- context id、case path、INI/HAL/remap source hash。 +- command envelope、operation id、gate result、command result。 +- 每个固定 tick 的 task/interp/motion/kinematics state hash。 +- Cartesian pose、XYZAC joint vector、tool offset、active segment/source line。 +- 首个 divergent tick、错误码、资源缺失分类。 +- native/WASM/Worker 对照结果;不以单一截图替代。 + +## 11. 已知限制 + +- 当前 `xyzac-trt.ini` 是 AXIS + PyVCP + 独立 Vismach 的 LinuxCNC 原生案例;Web/WASM 尚未声明其完整五轴 RTCP parity 已完成。 +- 当前环境使用 POSIX non-realtime;不提供实时硬件周期、延迟和驱动证明。 +- `xyzac-trt-gui` 只可视化 joint feedback/tool offset;它不是 canonical motion authority。 +- 官方 kinematics oracle 缺失时,native/WASM 结果只能作为实现证据,不能伪称官方 golden。 +- `xyzac-trt` 配置中的 `x-rot-point/y-rot-point/z-rot-point` 在示例中固定为 0,且注释说明当前 Vismach GUI 不支持通过 GUI 调整;Web 端必须把它作为配置/能力字段,而不是随意暴露可写 slider。 + +## 12. 后续实现顺序 + +1. 建立 exact-path `xyzac-trt.ini` resolver 和 resource graph。 +2. 在 Worker/WASM 建立 additive `kinematics` snapshot 与 `KINEMATICS_SELECT` command。 +3. 将 M428/M429/M430 的 remap 行为接入固定 tick interpreter,先做拒绝和错误边界。 +4. 将 XYZAC Cartesian/joint/tool-offset canonical snapshot 接到 Three.js Vismach adapter。 +5. 实现 gate matrix:ESTOP/OFF/ON/HOME/IDLE/RUNNING/PAUSED/limit/fault。 +6. 完成 program load/run/pause/resume/abort/restart + RTCP switch recovery 测试。 +7. 运行 native/Worker/browser 三方对照,并记录首个差异 tick。 +8. 只有 source/resource/oracle/recovery/浏览器边界均有证据后,才可提升为 selected-case verified;不能从一个 AXIS 截图直接宣称全 LinuxCNC 五轴 parity。 diff --git a/doc-rtcp/xyzac-trt-web-wasm-implementation-plan.md b/doc-rtcp/xyzac-trt-web-wasm-implementation-plan.md new file mode 100644 index 0000000..3ec2a2f --- /dev/null +++ b/doc-rtcp/xyzac-trt-web-wasm-implementation-plan.md @@ -0,0 +1,572 @@ +# `xyzac-trt.ini` Web/WASM 控制面板实施计划 + +文档状态:实施基线 v1.0 + +本计划完全以 [`xyzac-trt-control-panel-web-wasm-design.md`](xyzac-trt-control-panel-web-wasm-design.md) 为设计契约,目标是把以下 LinuxCNC 原生案例的控制面板、数据流和控制流迁移为 Worker/WASM/React/Three.js Web 控制台: + +```text +linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini +``` + +它不是 AXIS 的截图复刻计划,而是面向行为、状态、错误、资源、轨迹、RTCP 和恢复结果的 Web-equivalent 实施计划。任何视觉实现都必须服从 Worker/WASM authoritative state。 + +“完全对标 LinuxCNC 源码”和“全部功能唯一来自 LinuxCNC WASM”定义为唯一权威合同,强制定义见 [`xyzac-trt-web-wasm-source-parity-contract.md`](xyzac-trt-web-wasm-source-parity-contract.md)。若本计划与该合同冲突,以源码对标合同的禁止项、source slice、WASM authority、first divergent tick 和 parity gate 为准。 + +## 1. 目标与不可变约束 + +### 1.1 交付目标 + +完成一个可在浏览器中运行的 XYZAC 五轴 TRT 控制台,覆盖: + +1. exact-path 案例解析、资源闭包和启动诊断。 +2. Dedicated Worker 中的 WASM 任务、解释器、TP、motion、XYZAC kinematics、HAL/IO 虚拟设备和固定 tick。 +3. AXIS 等价的程序、MDI、Manual/Jog、Home、limit、override、spindle、coolant、tool 和 alarm 工作流。 +4. `M428/M429/M430` switchkins/RTCP 切换、拒绝边界、状态确认和恢复。 +5. XYZAC Cartesian pose、A/C 姿态、五个 joints、tool offset、rotation/axis offsets 和 canonical toolpath 的 Three.js 可视化。 +6. protocol.v1 command/result/snapshot/event/stream、operation ledger、checkpoint、Worker 重启和 offline recovery。 +7. native/Worker/WASM/React/Three.js 之间的确定性 parity 报告、错误样本和首个 divergent tick。 + +### 1.2 不可变约束 + +| 约束 | 实施要求 | +|---|---| +| WASM/Worker 权威 | React 不创建第二份 task、motion、kinematics 或 program authority;本地状态只能是 draft/pending | +| 固定 tick | 解释器、TP、motion、HAL、IO、kinematics、event、journal 以 logical tick 串行执行,不使用墙钟决定结果 | +| exact path | `xyzac-trt.ini` 中的 `HALFILE`、`POSTGUI_HALFILE`、`OPEN_FILE`、`SUBROUTINE_PATH`、`TOOL_TABLE` 和 `PYVCP` 按 exact path 解析,不按 basename 猜文件 | +| RTCP 原语 | `M428/M429/M430` 必须保留 remap 语义和 `motion.switchkins-type` 的确认,禁止前端直接写一个近似值 | +| 一致 gate | UI gate 只是 projection;Worker/runtime 必须再次检查 ESTOP/OFF/ON/HOME/IDLE/RUNNING/PAUSED/limit/fault/kinematics 条件 | +| 轨迹权威 | 预览和 Three.js 使用 canonical WASM trajectory/pose/joints;JS 不能重算 RTCP 结果冒充通过 | +| 单写者 | 一个 session 只有一个 Worker 写入 task/WASM/OPFS journal;多标签页只能观察或持有租约 | +| 幂等恢复 | 每个副作用命令有 operation id、ledger prepare/commit 和结果重查;超时不能盲目重发 | +| 能力拒绝 | 宿主路径、shell、真实硬件、socket、动态库和未授权 Python/HAL 能力稳定返回拒绝码 | +| 发布边界 | 没有官方 oracle、真实硬件、Safari/Firefox、OPFS crash 或许可证输入时保持 blocked,不升级为全 LinuxCNC parity | + +## 2. 设计契约追溯 + +| 设计文档章节 | 本计划对应实施面 | +|---|---| +| §1 范围与版本边界 | `RTCP-00` source/runtime/version lock | +| §2 总体架构 | `RTCP-01` Worker topology、authority boundary | +| §3 启动与初始化 | `RTCP-02` exact case resolver/startup state machine | +| §4 AXIS 主控制面板 | `RTCP-05` UI domain、controls、status projection | +| §5 G-code 加载流 | `RTCP-04` PROGRAM_LOAD/preview/program ledger | +| §6 AUTO 运行流 | `RTCP-06` run/pause/resume/step/abort/restart | +| §7 MDI/Jog/Home/Tool/Offset | `RTCP-07` manual and device workflows | +| §8 SWITCHKINS/RTCP | `RTCP-08` M428/M429/M430/XYZAC kinematics | +| §9 状态真值 | `RTCP-03` snapshot/axis_state/gates | +| §10 Web/WASM mapping | `RTCP-09` protocol and frontend integration | +| §11 测试与限制 | `RTCP-10` parity/recovery/browser gates | + +## 3. 功能范围矩阵 + +### 3.1 P0:必须先闭合的主链 + +| ID | 功能 | 原生来源/对照 | Web 结果 | +|---|---|---|---| +| P0-01 | 案例选择与启动 | `xyzac-trt.ini`、`run-5axis-rtcp.sh` | `TASK_READY` 或可定位 `BLOCKED_*` | +| P0-02 | 配置/资源图 | INI/HAL/XML/TBL/VAR/NGC/remap | exact path、source hash、missing edge | +| P0-03 | Task/ESTOP/OFF/ON | AXIS `stat.task_state` | axis_state + gate matrix | +| P0-04 | Mode MANUAL/MDI/AUTO | AXIS `ensure_mode`、`on_hal_status_mode_auto` | state transition + command result | +| P0-05 | Program load/open | AXIS `open_file_guts`、`c.program_open` | program hash、line count、preview | +| P0-06 | Canonical preview | AXIS canon/preview | stable segments/source lines | +| P0-07 | Program run | AXIS `task_run` | RUNNING、tick、active line | +| P0-08 | Pause/resume/step | AXIS `task_pause/resume/step` | PAUSED/RESUMED/step endpoint | +| P0-09 | Abort/restart | AXIS `task_stop/reload` | STOPPED/loaded、no duplicate side effect | +| P0-10 | MDI | AXIS `send_mdi_command` | parser result、queue gate、error | +| P0-11 | XYZAC kinematics | `xyzac-trt-kins.c`、`trtfuncs.c` | forward/inverse pose/joints | +| P0-12 | M428/M429/M430 | `428remap.ngc`、`429remap.ngc`、HAL net | active type + verified transition | +| P0-13 | Vismach pose/joints | `xyzac-trt-gui.py` | Three.js pose/joints/toolpath | + +### 3.2 P1:操作完整性 + +| ID | 功能 | 关键边界 | +|---|---|---| +| P1-01 | XYZAC jog | X/Y/Z linear units,A/C angular units,按下/释放 stop | +| P1-02 | Home/unhome | 五 joint homing、共享开关、home sequence、重复 homing | +| P1-03 | Soft/hard limits | limit active、override limit、following error | +| P1-04 | Feed/rapid/spindle override | 范围、非有限值、暂停/ESTOP | +| P1-05 | Spindle/coolant | command/actual/at-speed、冷却状态、fault | +| P1-06 | Tool table/offset | `xyzac-trt.tbl`、tool offset、G43/G49/G43.1 | +| P1-07 | HAL/PyVCP | `type0/1/2-button`、legend、vismach-clear、HAL read | +| P1-08 | Alarm/event timeline | source、severity、operation id、acknowledge | +| P1-09 | Configuration diagnostics | startup/resource/HAL/remap errors | + +### 3.3 P2:交付和恢复完整性 + +| ID | 功能 | 退出要求 | +|---|---|---| +| P2-01 | Checkpoint/journal | tick、program line、kinematics type、pose/joints、hash 可恢复 | +| P2-02 | Worker restart | 无重复 M428/M429、无重复 segment/IO/tool side effect | +| P2-03 | Offline project | 缓存资源、OPFS journal、配额和冲突可诊断 | +| P2-04 | Stream/backpressure | trajectory/HAL/log drop 有 cursor/gap/最终快照 | +| P2-05 | Browser matrix | Chromium/Firefox/Safari 逐项证据;缺环境保持 blocked | +| P2-06 | Native/WASM parity | normal/boundary/error/recovery + deterministic self-hash | + +## 4. 目标架构 + +```text +React/Web UI + ├── XyzacCaseView / ProgramView / ManualView / RtccpView / DiagnosticsView + ├── Domain store: task/program/motion/kinematics/hal/devices/recovery + ├── Pure gate selectors and source control IDs + └── WorkerClient only + │ protocol.v1 MessageEnvelope + ▼ +Dedicated sim.worker + ├── ProtocolGateway + runtime schema validator + ├── Session/Liveness/Lease manager + ├── CommandLedger (prepare/ack/result/commit/reconcile) + ├── XyzacCaseResolver + resource graph + ├── SimScheduler (fixed logical tick) + ├── WASM LinuxCncCompat + │ ├── Task/RS274/TP/Motion + │ ├── xyzac-trt forward/inverse + │ ├── remap M428/M429/M430 + │ └── HAL/IO/tool/probe virtual devices + ├── SnapshotPublisher + StateHash + ├── OPFS journal/checkpoint/recovery + └── trajectory/HAL/log stream backpressure + │ authoritative snapshots/events + ▼ +React projection + Three.js XYZAC Vismach adapter +``` + +### 4.1 Authority ownership + +| 数据 | 唯一 authority | React 是否可写 | +|---|---|---:| +| task state/mode/interp | WASM Task/Interpreter | 否 | +| program parsed state/line | WASM Interpreter/Task | 否 | +| TP queue/active segment | WASM TP | 否 | +| Cartesian pose/XYZAC joints | WASM Kinematics/Motion | 否 | +| switchkins type | WASM/HAL compatibility layer | 只能发请求 | +| homed/limit/following error | WASM Motion/Home/HAL | 否 | +| tool/offset/spindle/coolant | virtual IO/tool runtime | 只能发命令 | +| UI draft/selection | React local store | 是,但不等于运行态 | +| Three.js camera/layer toggle | React/renderer | 是,不影响 motion | + +## 5. 实施任务队列 + +任务状态使用:`queued → in_progress → verified` 或 `in_progress → blocked`。每个任务完成时必须生成报告、自哈希、输入哈希、命令记录、错误边界和下一任务依赖。 + +### RTCP-00:源码、版本和案例锁定 + +**目标**:冻结 `xyzac-trt.ini`、所有引用资源、系统运行时和 source symbol 映射。 + +**直接输入**: + +- `xyzac-trt.ini` +- `xyzac-trt.xml` +- `switchkins_postgui.hal` +- `demos/*.ngc` +- `remap_subs/*.ngc` +- `xyzac-trt-kins.c`、`trtfuncs.c` +- `xyzac-trt-gui.py` +- `context-lock.json` + +**产物**: + +- `coverage/xyzac-trt-web-source-lock.report.json` +- `web/workspace/xyzac-trt-source-contract.mjs` +- exact resource graph、source hash、runtime version record + +**验收**:每个 INI path、HAL edge、PyVCP pin、remap、G-code 入口可追溯;缺失资源为明确 blocker。 + +### RTCP-01:Worker 拓扑和 LinuxCncCompat 外壳 + +**目标**:建立单 Worker/session/ledger/scheduler 边界,不实现五轴细节。 + +**产物**: + +- `web/worker/xyzac-session.mjs` +- `web/worker/xyzac-scheduler.mjs` +- `web/worker/xyzac-command-ledger.mjs` +- `web/worker/test_xyzac_session.mjs` + +**验收**:HELLO/CAPABILITIES/SESSION_ATTACH/SESSION_READY、seq、operation_id、取消、超时重查和重复命令测试通过;Worker 之外不能写 runtime。 + +### RTCP-02:Exact case resolver 和启动状态机 + +**目标**:把 `xyzac-trt.ini` 解析到 `TASK_NEW → CONFIG_RESOLVED → HAL_READY → RUNTIME_READY → TASK_READY`。 + +**要求**: + +- 解析 `DISPLAY/TASK/HAL/RS274NGC/KINS/TRAJ/EMCIO`。 +- 解析 `LIB:basic_sim.tcl` 的虚拟 HAL 边界。 +- exact resolve `OPEN_FILE`、`SUBROUTINE_PATH`、`xyzac-trt.tbl`、`xyzac.var`、`xyzac-trt.xml` 和 `xyzac-trt-gui.py`。 +- 识别 `BLOCKED_RESOURCE`、`BLOCKED_HAL`、`BLOCKED_INI`、`BLOCKED_STARTUP`。 + +**产物**:`web/workspace/xyzac-trt-case-loader.mjs`、startup snapshot、diagnostic report。 + +### RTCP-03:Authoritative snapshot、axis_state 和 gate matrix + +**目标**:将 native task/motion/interp/home/limit/kinematics 状态统一为 Worker snapshot。 + +**产物**: + +- additive `axis_state` +- `kinematics.active_type` +- `configuration.coordinates/joints/topology` +- `gates`(action/enabled/reason) +- `web/worker/test_xyzac_gate_matrix.mjs` + +**验收**:ESTOP/OFF/ON/HOME/IDLE/RUNNING/PAUSED、limit/fault/tool/no-file/no-highlight 每项都有 gate reason 和状态哈希。 + +### RTCP-04:程序加载、canonical preview 和 program ledger + +**目标**:实现 AXIS `open_file_guts → program_open → canon/preview → stat.file` 的 Worker/WASM 等价流程。 + +**要求**: + +- source/path/hash/line count 固化。 +- preview segment 带 id/source_line/start/end/motion_type/center/normal/turn。 +- 解析错误、超限、非有限值、空文件和缺资源 fail closed。 +- load/reload/restart 与 ledger/recovery 可重放。 + +**验收**:native 与 Worker 首个 segment、line count、preview hash、loaded file、invalid G-code 错误码一致。 + +### RTCP-05:程序运行控制和 AXIS workflow + +**目标**:覆盖 Run/Pause/Resume/Step/Abort/Restart/Run-from-line。 + +**按钮约束**: + +```text +RUN = machine_on && interp_idle && task_file +PAUSE = machine_on && interp_reading_or_waiting +RESUME = machine_on && interp_paused +STEP = machine_on && task_file +ABORT = machine_on && interp_running +RESTART = machine_on && interp_idle && task_file +RUN_LINE = RUN && highlight_line != null +``` + +**验收**:固定 tick 下 pause/resume 不重复 segment,abort 无重复副作用,restart 重置 program state 但保留正确 source hash。 + +### RTCP-06:MDI、Jog、Home 和 limit + +**目标**:实现 XYZAC 手动控制。 + +**要求**: + +- X/Y/Z 线性单位和 A/C 角度单位分离。 +- pointerdown/keydown 只发一个 JOG_START;pointerup/keyup/blur/visibilitychange 必须发 JOG_STOP。 +- MDI queue limit、running/paused/ESTOP gate 与 native 一致。 +- home all、单 joint home、unhome、共享 home switch 和 limit override。 +- following error、非有限速度、超范围轴拒绝。 + +**验收**:每个 X/Y/Z/A/C 轴有 normal/boundary/stop/fault/recovery 样本;A/C 不得被当作 linear mm。 + +### RTCP-07:HAL、PyVCP、tool、spindle、coolant 和 alarm + +**目标**:把 `xyzac-trt.xml` 和 `switchkins_postgui.hal` 中的控件接入 Worker capability。 + +**功能**: + +- type0/type1/type2 button 状态和 `kinstype.is-*` legend。 +- `vismach-clear` 只清 visual plot。 +- tool table、tool offset、G43/G49/G43.1、tool prepare/change。 +- spindle command/actual/at-speed/direction、coolant、manual tool change。 +- HAL pin read/write 白名单、类型和权限。 +- alarm/event timeline、acknowledge、source file/line。 + +**验收**:HAL command 不能越权写任意 pin;tool/IO ack、timeout、abort、recovery 和 `REAL-EXCLUDED` 分类都有报告。 + +### RTCP-08:XYZAC kinematics 和 RTCP + +**目标**:实现 `xyzac-trt-kins` 的 forward/inverse、tool offset、rotation/axis offset 和 switchkins。 + +**阶段拆分**: + +1. K0:XYZAC 坐标/joint mapping、单位、limits、finite-value 校验。 +2. K1:identity type 0,forward/inverse identity golden。 +3. K2:TRT type 1,`trtKinematicsSetup`、XYZAC forward/inverse、`y-offset/z-offset`、tool-offset。 +4. K3:userk type 2 capability boundary;无 userk 时稳定拒绝。 +5. K4:M428/M429/M430 remap 与 `motion.switchkins-type` handshake。 +6. K5:helix_ac/helix_bc、姿态变化、G93/arc、奇异/限位/非有限值。 +7. K6:pause/resume/abort/restart/recovery 时 active kinematics type 和 pose/joints 保持一致。 + +**必须保存**:Cartesian pose、XYZAC joints、A/C angle、tool offset、rotation point、axis offsets、kinematics type、首个 divergent tick、state hash。 + +### RTCP-09:Protocol v1 和 React 控制台 + +**目标**:把现有 `axis-contract.mjs`、`AxisOperationController`、`PanelSnapshotV1` 扩展到 XYZAC。 + +**产物**: + +- `KINEMATICS_SELECT`、`VISUAL_CLEAR`、`POWER` 等 additive commands。 +- `xyzac-panel-snapshot.v1` additive view 或兼容扩展。 +- React `XyzacTrtPanel`、`XyzacProgramPane`、`XyzacKinematicsControl`、`XyzacManualPanel`、`XyzacDiagnostics`。 +- gate-aware controls、operation trace、alarm/recovery view。 + +**验收**:React 不直接调用 WASM/OPFS;所有 controls 只通过 WorkerClient;gate reason、pending、ack、result、error 状态可见。 + +### RTCP-10:Three.js XYZAC Vismach adapter + +**目标**:使用 authoritative `visual.pose/joints/toolpath` 实现五轴模型。 + +**要求**: + +- 机床结构对应 `xyzac-trt-gui.py`:table-x、saddle-y、spindle-z、tilt-a、rotate-c、tool-offset。 +- pose/joints 与 toolpath 来自同一 `state_hash`/tick。 +- camera/layer/clear 不改变 task/motion/program。 +- canvas nonblank、A/C 旋转方向、tool offset、轨迹 active segment 和 resize/mobile 通过。 + +### RTCP-11:Journal、checkpoint、Worker restart 和 offline recovery + +**目标**:恢复完整 XYZAC 运行态。 + +**checkpoint 最小字段**: + +```text +context_id, case_id, source_hashes +simulation_tick, seq, state_hash +task_state, task_mode, interp_state, program_hash, current_line +kinematics_type, kinematics_transition, pose, joints +tool_offset, y_offset, z_offset, rotation_points +TP queue/active segment, HAL/IO/tool pending commands +``` + +**验收**: + +- M428 在 checkpoint 前后不重复执行。 +- 暂停程序恢复不重复 segment。 +- tool/spindle/coolant/IO side effect 不重复。 +- 损坏 checkpoint、缺资源、schema mismatch fail closed。 +- Worker 重启后 endpoint pose/joints/program/kinematics/state hash 一致。 + +### RTCP-12:Native/Worker/Browser parity 和验收闭环 + +**目标**:形成 selected-case parity report,不冒充全 LinuxCNC release。 + +**矩阵**: + +- Chromium desktop/mobile。 +- Firefox/Safari 可用时运行;不可用保留 `HOST_EXCLUDED`/`blocked`。 +- native AXIS + xyzac-trt-gui。 +- Worker/WASM + React + Three.js。 +- normal/boundary/error/limit/pause/abort/restart/recovery。 + +**产物**: + +- `coverage/xyzac-trt-web-wasm-parity.report.json` +- native/worker command golden +- snapshot/trajectory/kinematics self-hash +- failure samples and first divergence report + +## 6. 里程碑设计 + +### M0:Source and Case Contract + +**包含**:RTCP-00。 + +**退出条件**: + +- 所有直接引用资源均 exact-path indexed(不以抽样替代)。 +- `xyzac-trt.ini` 的 INI/HAL/NGC/XML/Python/C source graph 自哈希稳定。 +- 版本、context、运行时和能力边界记录完成。 +- 缺失/未索引/宿主资源明确 blocked。 + +### M1:Worker Startup and State Authority + +**包含**:RTCP-01、RTCP-02、RTCP-03。 + +**退出条件**: + +- Worker session handshake、TASK_READY、CAPABILITIES 通过。 +- snapshot 包含 task/motion/home/limit/program/kinematics/gates/configuration。 +- ESTOP/OFF/ON/HOME/IDLE gate matrix 和 deterministic state hash 通过。 +- React 尚未接入前,Worker 测试可独立验证 authority。 + +### M2:Program and AXIS Operation Workflow + +**包含**:RTCP-04、RTCP-05、RTCP-06。 + +**退出条件**: + +- load/preview/run/pause/resume/step/abort/restart/MDI/jog/home 全部有 native/Worker 对照。 +- 每个操作的 gate reason、operation id、command result 和 state hash 可追溯。 +- running/paused/ESTOP/limit/tool missing 的拒绝不被 UI 绕过。 + +### M3:HAL/IO/PyVCP and Device Closure + +**包含**:RTCP-07。 + +**退出条件**: + +- SWITCHKINS PyVCP 三个按钮和 vismach-clear 的 HAL 图可解析。 +- spindle/coolant/tool/probe/hal read/write/ack/error 边界通过。 +- 未授权 pin、外部进程、真实硬件被稳定拒绝。 + +### M4:XYZAC Kinematics and RTCP + +**包含**:RTCP-08。 + +**退出条件**: + +- type 0/1/2 切换和 M428/M429/M430 handshake 与 native 一致。 +- XYZAC pose/joints/tool offset/axis offset/rotation point 的 forward/inverse golden 通过。 +- helix/姿态变化、奇异、limits、non-finite、pause/abort/recovery 样本齐全。 +- 首个 divergent tick 可定位;没有 JS kinematics fallback。 + +### M5:React/Protocol/Three.js Console + +**包含**:RTCP-09、RTCP-10。 + +**退出条件**: + +- React 所有按钮只通过 WorkerClient/OperationController。 +- Three.js 使用 authoritative snapshot,A/C 方向、tool offset 和 active segment 正确。 +- desktop/mobile DOM、canvas nonblank、keyboard/touch、错误/pending/gate UI 通过。 + +### M6:Recovery and Offline Runtime + +**包含**:RTCP-11。 + +**退出条件**: + +- checkpoint/restart/reconcile/replay 无重复副作用。 +- OPFS journal、配额、schema mismatch、坏数据和离线重新打开可诊断。 +- recovery endpoint state hash 与连续运行一致。 + +### M7:Selected-Case Parity Acceptance + +**包含**:RTCP-12。 + +**退出条件**: + +- native/Worker/WASM/React/Three.js 的选定案例完整矩阵通过。 +- 结果报告有 source/input/output hash、命令、状态、首个差异 tick 和失败样本。 +- Chromium/Firefox/Safari、官方 oracle、实时硬件、OPFS crash 和许可证边界按真实环境记录。 +- 只能声明 `selected_case_verified`;任何外部 blocker 存在时保持 `STOP_RELEASE`。 + +## 7. 任务依赖图 + +```text +RTCP-00 source lock + │ + ▼ +RTCP-01 session/ledger ── RTCP-02 case startup ── RTCP-03 snapshot/gates + │ │ │ + └─────────────────────────┴──────────────────────┘ + ▼ + RTCP-04 program/preview + │ + ┌──────────────┴──────────────┐ + ▼ ▼ + RTCP-05 run/control RTCP-06 manual + │ │ + └──────────────┬──────────────┘ + ▼ + RTCP-07 HAL/IO/PyVCP + │ + ▼ + RTCP-08 XYZAC/RTCP + │ + ┌───────────┴───────────┐ + ▼ ▼ + RTCP-09 React/protocol RTCP-10 Three.js + │ │ + └───────────┬───────────┘ + ▼ + RTCP-11 recovery + │ + ▼ + RTCP-12 parity gate +``` + +不得跳过 RTCP-03 的 authority/gate、RTCP-04 的 canonical program 或 RTCP-08 的 kinematics 就先做“漂亮界面”。 + +## 8. 统一任务报告格式 + +每个 `RTCP-*` 任务必须生成 JSON 报告,至少包含: + +```json +{ + "schema": "xyzac-trt-web-wasm-task-report.v1", + "task_id": "RTCP-08", + "milestone": "M4", + "status": "verified", + "context_id": "...", + "case_path": ".../xyzac-trt.ini", + "inputs": [{"path": "...", "sha256": "..."}], + "outputs": [{"path": "...", "sha256": "..."}], + "commands": [{"name": "...", "status": "passed", "stdout_sha256": "..."}], + "normal": {}, + "boundaries": [], + "errors": [], + "first_divergent_tick": null, + "known_blockers": [], + "report_sha256": "..." +} +``` + +失败样本必须保留,不得删除失败、降低 gate、把资源缺失改成通过或用 JS preview/姿态镜像冒充 native/WASM parity。 + +## 9. 最低测试命令集合 + +任务开发期间按范围运行: + +```bash +python3 scripts/validate_baseline.py +python3 scripts/validate_download_index.py +python3 scripts/validate_task_pointer.py nextTask1.md --lock context-lock.json +scripts/build-wasm.sh +ctest --test-dir build-native --output-on-failure +``` + +五轴专属命令: + +```bash +./run-5axis-rtcp.sh +./run-5axis-rtcp.sh xyzbc-trt.ini +node web/worker/test_xyzac_trt_case.mjs +node web/worker/test_xyzac_program.mjs +node web/worker/test_xyzac_switchkins.mjs +node web/worker/test_xyzac_rtcp.mjs +node web/worker/test_xyzac_recovery.mjs +npm --prefix web/react run typecheck +npm --prefix web/react run build +``` + +命令名称在对应任务开始前必须实际创建并纳入报告;不存在的测试命令不能写成已通过。 + +## 10. 停止条件和阻塞处理 + +以下任一情况必须将当前任务标记为 blocked,并保留证据: + +- `xyzac-trt.ini` 的 source/resource/hal/remap graph 不完整。 +- native 运行时版本、锁定 source 或 ABI/protocol/schema 不一致。 +- M428/M429 状态切换没有确认、重复执行或首个差异 tick 未定位。 +- A/C 角度、tool offset、rotation point、joint pose 由 JS/React 生成。 +- ESTOP、limit、following error、pause、abort、recovery 语义不可解释。 +- 真实 HAL、动态 loader、宿主 Python、外部进程或真实硬件被错误标记为 Web-equivalent。 +- Worker 重启造成重复 G-code、重复 tool/IO side effect 或 checkpoint hash 不一致。 +- 只有 Chromium 截图而缺 Firefox/Safari/OPFS/oracle 证据,却要求全量 release。 +- 缺少 owner/source/oracle/resource/browser/license 外部输入。 + +阻塞转移规则: + +```text +技术缺陷 → 保留最小复现/错误码/首个 divergent tick → 修复同一任务 +源码/ABI/protocol/schema 输入缺失 → SOURCE_BLOCKED → 等待审查输入 +宿主/浏览器/硬件缺失 → HOST_EXCLUDED 或 REAL-EXCLUDED → 不伪造通过 +发布/owner 决策缺失 → STOP_RELEASE → 不自动刷新 gate +``` + +## 11. 里程碑交付顺序 + +后续实施按以下顺序推进,不能在任务依赖未 verified 时跳级: + +```text +M0 Source/Case Contract + → M1 Worker Startup/Authority + → M2 Program/AXIS Workflow + → M3 HAL/IO/PyVCP + → M4 XYZAC/RTCP Kinematics + → M5 React/Protocol/Three.js + → M6 Recovery/Offline + → M7 Selected-Case Parity +``` + +每个里程碑完成后生成独立报告和自哈希,并将下一里程碑的直接输入、完成门禁、外部 blocker 和停止边界写入任务记录。完成单元测试或界面截图不等于该里程碑完成;必须同时满足 authority、数据流、控制流、错误、恢复和确定性要求。 diff --git a/doc-rtcp/xyzac-trt-web-wasm-source-parity-contract.md b/doc-rtcp/xyzac-trt-web-wasm-source-parity-contract.md new file mode 100644 index 0000000..c144802 --- /dev/null +++ b/doc-rtcp/xyzac-trt-web-wasm-source-parity-contract.md @@ -0,0 +1,440 @@ +# XYZAC TRT Web/WASM 源码对标与唯一权威合同 + +文档状态:强制实施合同 v1.0 + +本合同是 [`xyzac-trt-web-wasm-implementation-plan.md`](xyzac-trt-web-wasm-implementation-plan.md) 的约束性补充。它回答一个更严格的问题:Web 控制面板如何证明自己是 LinuxCNC 源码行为的 Web/WASM 等价实现,并且所有控制功能唯一来自 LinuxCNC WASM,而不是来自 React、浏览器状态或第二套 JavaScript 运动模型。 + +适用案例: + +```text +linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini +``` + +## 1. 强制结论 + +### 1.1 唯一权威 + +以下数据只能由 LinuxCNC WASM runtime 产生;React、TypeScript、Three.js、Worker UI adapter 和浏览器不能自行生成“看起来合理”的替代值: + +- task state、task mode、interpreter state、current line、queued MDI。 +- program parse state、canonical events、trajectory queue、active segment。 +- Cartesian pose、X/Y/Z/A/C 轴位置、五个 joint 位置、速度、加速度和 limits。 +- XYZAC forward/inverse kinematics、switchkins type、TCP/RTCP tool compensation。 +- tool table、tool offset、G43/G49/G43.1、spindle、coolant、probe、home、limit、following error。 +- HAL pin/signal/parameter 读值、PyVCP state、IO ack、报警、错误和恢复结果。 +- checkpoint、journal、replay、recovery endpoint 和 state hash。 + +前端可以拥有以下本地状态,但必须明确标记为非权威: + +- 编辑器 draft、搜索词、文件选择、当前 tab、camera、图层显示、窗口尺寸、pending operation。 +- 尚未提交的配置表单、UI 偏好和输入法状态。 + +### 1.2 严禁的替代 authority + +下列行为一律视为实现失败: + +1. React 根据按钮点击直接把 task/mode/position/kinematics 写成目标状态。 +2. JS 根据 A/C 角度和 tool length 自行计算 X/Y/Z 补偿并展示为实际 pose。 +3. JS G-code preview、Three.js preview 或 canvas 轨迹被当作 canonical motion。 +4. UI 通过 `setTimeout`、墙钟、`requestAnimationFrame` 或点击次数推进仿真 tick。 +5. 浏览器直接访问 WASM 指针、导出内部内存、写 OPFS journal 或调用宿主 LinuxCNC。 +6. 前端绕过 Worker gateway 直接发送 HAL pin 写入、M428/M429 或模拟 IO 副作用。 +7. 收不到 `COMMAND_RESULT` 时把 pending 命令当作成功,或超时后无 ledger reconcile 直接重发。 +8. 把 native/AXIS 行为复制成新的 JS 状态机,再用 WASM 只做最终演示。 +9. 以截图、按钮存在、模块测试或“曲线看起来一样”宣称完整五轴 parity。 +10. 把 HOST_BOUNDARY、REAL-EXCLUDED、SOURCE_BLOCKED 或缺少官方 oracle 的结果改写为 verified。 + +## 2. 对标单位:source behavior slice + +对标的最小单位不是“页面”或“组件”,而是 source behavior slice: + +```text +source symbol/control + → input/event/command + → native state gate + → LinuxCNC canonical result + → status/event/visual output + → error/abort/recovery behavior +``` + +每个 slice 必须有唯一 `slice_id`。示例: + +```text +AXIS-XYZAC-AUTO-RUN +AXIS-XYZAC-M428-TCP +AXIS-XYZAC-JOG-C +AXIS-XYZAC-HOME-JOINT-3 +AXIS-XYZAC-LOAD-PROGRAM +AXIS-XYZAC-VISMACH-POSE +``` + +### 2.1 Slice manifest 必填字段 + +```json +{ + "slice_id": "AXIS-XYZAC-M428-TCP", + "source": { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc", + "symbols": ["428remap"], + "lines": "1-24", + "sha256": "..." + }, + "inputs": ["MDI_EXECUTE:M428", "task_state", "motion.switchkins-type"], + "native_commands": ["M68 E3 Q1", "M66 E0 L0"], + "wasm_commands": ["MDI_EXECUTE", "KINEMATICS_SELECT"], + "authoritative_outputs": ["kinematics.active_type", "state_hash"], + "ui_controls": ["AXIS-RTCP-TCP-XYZAC"], + "gates": ["interp_idle", "hal_pin_present", "switchkins_net_present"], + "normal_cases": [], + "boundary_cases": [], + "error_cases": [], + "recovery_cases": [], + "status": "queued" +} +``` + +没有 source path、symbol、输入、native command、WASM command、输出、gate 和测试的功能,不得进入“实现完成”统计。 + +## 3. 源码到 WASM 的闭合分层 + +### 3.1 Source inventory 层 + +必须锁定并哈希以下来源: + +| 层 | 来源 | +|---|---| +| AXIS controls | `linuxcnc/share/axis/tcl/axis.tcl`、`support.tcl`、`accel.tcl`、`dialog.tcl`、`combobox.tcl`、`sb.tcl` | +| AXIS Python | `linuxcnc/src/emc/usr_intf/axis/scripts/axis.py` | +| Preview/canon | `linuxcnc/lib/python/rs274/glcanon.py`、`gremlin.py`、`vismach.py` | +| Case config | `xyzac-trt.ini`、`xyzac-trt.xml`、`switchkins_postgui.hal`、`xyzac-trt.tbl`、`xyzac.var` | +| Program/remap | `demos/*.ngc`、`remap_subs/*.ngc` | +| Kinematics | `xyzac-trt-kins.c`、`xyzbc-trt-kins.c`、`trtfuncs.c`、`switchkins.c/h`、`kins_util.c` | +| Motion/TP | `motion/command.c`、`motion/control.c`、`motion/homing.c`、`motion/motion.c`、`tp/tp.c`、`tp/tcq.c`、`tp/blendmath.c` | +| Interpreter | `rs274ngc/interp_read.cc`、`interp_execute.cc`、`interp_queue.cc`、`interp_convert.cc`、`modal_state.cc` | +| HAL/IO | `task/emctaskmain.cc`、`iotask/ioControl.cc`、HAL component source and `basic_sim.tcl` | + +Inventory 不能只记录目录;必须展开到具体文件、source hash、引用关系和运行时 fixture。生成的 `sim.var`、`position`、journal 和临时 tool table 必须单独标为 `runtime-generated-fixture`。 + +### 3.2 Compat API 层 + +WASM 不直接向 React 暴露 C 内部函数。应建立有限、版本化的 `LinuxCncCompat`: + +```text +LinuxCncCompat + ├── task: state/mode/interpreter/queue + ├── program: load/parse/run/pause/resume/step/abort/seek + ├── mdi: execute/cancel/result + ├── motion: jog/home/limit/override/spindle + ├── kinematics: forward/inverse/select/diagnostics + ├── hal: read/write/subscribe/type-check + ├── io: tool/coolant/probe/spindle ack + ├── snapshot: full/delta/hash + └── recovery: checkpoint/replay/reconcile +``` + +每个方法必须映射到 source symbol 和固定 tick 位置;不允许添加“为了 UI 方便”的隐式状态改变。 + +### 3.3 Worker protocol 层 + +Worker gateway 负责 schema、capability、gate、ledger、seq、operation id 和错误包装;不负责猜测 motion 结果。协议命令必须能够回到 compat API,并最终回到 WASM canonical state。 + +```text +UI event + → WorkerClient + → protocol validator + → capability/gate validator + → CommandLedger.prepare + → LinuxCncCompat + → fixed-tick WASM runtime + → snapshot/event/hash + → CommandLedger.commit + → UI projection +``` + +### 3.4 Projection 层 + +React reducer 只做: + +- 校验消息。 +- 保存 authoritative snapshot/event/result。 +- 派生按钮 gate、标签、错误和可视化 props。 +- 保留 pending/draft/ack/reconcile 状态。 + +Reducer 不得: + +- 生成新的 motion/joint/pose。 +- 依据 UI 点击顺序补齐缺少的状态。 +- 在没有 Worker 快照时把按钮变为成功。 +- 把 preview segment 当成 active motion segment。 + +## 4. 完整功能对标登记 + +### 4.1 控制面板域 + +以下域必须全部有 source slice;每项还要登记 menu/toolbar/button/keyboard/HAL 入口: + +| 域 | 最低条目 | +|---|---| +| Shell | title、machine name、version、about、quick reference、window/min-size、focus、tooltip | +| File | open、recent、reload、save-as、properties、tool data、quit、exact path | +| Machine | ESTOP、power、reset、home all、home joint、unhome、override limits、touch-off | +| Mode | manual、mdi、auto、joint/world/teleop、mode denial | +| Program | run、pause、resume、step、abort、restart、run-from-line、optional stop、block delete | +| MDI | input、history、queue、clear、calculator、error/ack | +| Jog | axis/joint selection、continuous/incremental、linear/angular speed、press/release/stop | +| DRO | actual/commanded/relative/machine、G5x/G92/tool offsets、DTG、rotation | +| Preview | perspective/X/Y/Z、zoom、pan/rotate、grid、rapids、tool、limits、extents、live plot、clear | +| Tool | tool table、reload、tool change、tool offset、G43/G49/G43.1、manual toolchange | +| Spindle/IO | direction、speed、override、brake、coolant、lube、probe、digital/analog | +| HAL/PLC | HAL graph/scope/command、PyVCP、ClassicLadder/PLC state、capability denial | +| Diagnostics | alarm、error、event log、command trace、snapshot diff、runtime overrun、recovery | +| Case-specific | XYZAC/XYZBC type buttons、M428/M429/M430、A/C limits、RTCP offsets、Vismach clear | + +### 4.2 对标登记状态 + +每项只能处于: + +```text +UNREGISTERED → SOURCE_MAPPED → WASM_IMPLEMENTED → WORKER_VERIFIED → UI_VERIFIED → PARITY_VERIFIED +``` + +任意阶段失败都必须停留在对应状态并保存原因。`UI_VERIFIED` 不能越过 `WASM_IMPLEMENTED`;`PARITY_VERIFIED` 不能只用浏览器截图证明。 + +## 5. 状态和 gate 的唯一实现 + +### 5.1 Native gate 取证 + +对于每个按钮,必须从原始 AXIS/LinuxCNC 源码提取: + +- handler 名和绑定位置。 +- 读取的 `stat`、HAL pin、INI 值和局部变量。 +- 允许状态/拒绝状态。 +- 发送的 command 和参数。 +- command 后检查的 state。 +- 错误对话框/状态栏/恢复行为。 + +### 5.2 WASM gate 复现 + +WASM gate 只允许读取 WASM snapshot: + +```text +gate(action, authoritative_snapshot, capability, configuration) + → { enabled, reason, required_state, source_slice_id } +``` + +React 可以显示 gate,但不能覆盖 gate。若 native 与 WASM gate 不同,先生成差异报告;不能在 React 中添加特殊分支“修正”显示。 + +### 5.3 XYZAC 特殊 gate + +```text +M428/TCP = interpreter_idle && HAL_PIN_VARS && switchkins_net && finite_offsets +M429/identity = interpreter_idle && HAL_PIN_VARS && switchkins_net +M430/userk = interpreter_idle && userk_capability +A/C jog = manual_ok && axis_enabled && angular_limits && no_fault +RTCP motion = active_type == 1 && pose/joint transform verified +Vismach clear = visual-only,不改变 task/motion/program/hash +``` + +## 6. Native/WASM 等价证明 + +### 6.1 输入冻结 + +每次 parity run 固定: + +- context id、case source hashes、browser/runtime build hash。 +- INI/HAL/NGC/TBL/VAR/Python/XML exact resources。 +- 程序文本、MDI 文本、按钮动作序列、固定 logical tick 数量。 +- 初始 task/mode/home/tool/offset/kinematics state。 + +### 6.2 Trace 规范 + +```json +{ + "slice_id": "AXIS-XYZAC-M428-TCP", + "step": 7, + "input": {"kind": "MDI_EXECUTE", "line": "M428"}, + "native": { + "task_mode": "MDI", + "motion_switchkins_type": 1, + "state_hash": "..." + }, + "wasm": { + "task_mode": "MDI", + "motion_switchkins_type": 1, + "state_hash": "..." + }, + "equal": true, + "first_divergent_tick": null +} +``` + +### 6.3 等价层级 + +1. **Protocol**:信封、seq、operation id、command/result/error schema。 +2. **Control**:按钮 gate、模式转换、队列、取消、abort/reconcile。 +3. **State**:task/interp/motion/home/limit/tool/IO/kinematics snapshot。 +4. **Canonical**:canonical events、TP queue、pose/joints/toolpath。 +5. **Recovery**:checkpoint、replay、endpoint hash、无重复副作用。 +6. **Visual**:DRO、当前行、轨迹、A/C pose、Vismach 非空和布局。 + +低层级通过不能替代高层级缺口;visual 通过尤其不能替代 canonical/control 失败。 + +## 7. WASM-only 前端实施拆分 + +### 7.1 Runtime 完整性 + +WASM bundle 必须包含或明确拒绝: + +- RS274NGC parser/interpreter、modal state、canonical events。 +- TP queue/blend/arc/helix、fixed tick。 +- XYZAC/XYZBC TRT forward/inverse、tool offset、rotation points、limits。 +- task/motion/home/limit/IO/tool/probe/spindle/coolant。 +- remap/Python capability model(无能力时稳定拒绝)。 +- snapshot/event/hash/checkpoint/recovery。 + +`REAL-EXCLUDED` 能力不能通过宿主 LinuxCNC fallback 伪装成 WASM 支持。 + +### 7.2 Worker 完整性 + +Worker 必须是: + +- WASM runtime 的唯一调度者。 +- protocol schema 和 capability 的唯一入口。 +- OPFS journal/checkpoint 的唯一写者。 +- command ledger 和 reconcile 的唯一实现者。 +- snapshot/event/trajectory 的发布者。 + +Worker 不得把某些命令转给主线程 JS authority;若能力未实现,返回 `capability_unavailable`/`source_blocked`。 + +### 7.3 Web 控制台完整性 + +React 页面必须从 `PanelSnapshotV1`/扩展快照显示: + +- case/configuration/source hash。 +- task/mode/interpreter/kinematics state。 +- gates 和 reason。 +- program/line/preview/active segment。 +- Cartesian pose、XYZAC joints、tool offset、A/C limits。 +- HAL/IO/tool/spindle/coolant/probe/alarms。 +- pending/ack/result/reconcile/recovery。 + +所有 button handler 只能调用 `WorkerClient`/`AxisOperationController`;禁止 `setState` 直接表示 command 已完成。 + +## 8. 里程碑增强版 + +在原 `M0-M7` 上增加“源码唯一权威”退出条件: + +### M0-SOURCE:完整 source manifest + +- AXIS、G-code、motion、TP、kinematics、HAL、IO、Vismach 所有功能已登记 slice。 +- source hash、symbol、resource graph 和 version lock 可复现。 +- unregistered count = 0;blocked count 单独报告。 + +### M1-WASM-AUTHORITY:无 JS authority + +- 所有 task/motion/kinematics/program state 均由 WASM snapshot 产生。 +- JS authority call count = 0;可以使用的 JS 只剩 projection/ledger/UI。 +- 损坏/篡改 snapshot fail closed。 + +### M2-CONTROL-PARITY:按钮和命令对标 + +- 每个 source slice 有 native/WASM button gate trace。 +- 正常、拒绝、ESTOP、limit、pause、abort、reconcile 全部通过。 +- gate mismatch count = 0。 + +### M3-CANONICAL-PARITY:解释器、TP、运动学 + +- program/canonical/TP/XYZAC pose/joint/toolpath trace 一致。 +- M428/M429/M430、helix、A/C 姿态和 tool offset 一致。 +- first divergent tick 可定位且 verified 样本无差异。 + +### M4-FRONTEND-PARITY:React/Three.js + +- 所有 UI controls 只消费 WASM state。 +- Three.js 不重算姿态;canvas 与 snapshot hash 对账。 +- DOM、keyboard/touch、错误、pending、recovery UI 通过。 + +### M5-RECOVERY-PARITY:恢复和离线 + +- command ledger、checkpoint、journal、Worker restart endpoint 一致。 +- 无重复 M-code、tool/IO side effect、trajectory segment。 +- offline/OPFS quota/schema mismatch 证据完整。 + +### M6-RELEASE-PARITY:严格发布门 + +- source slice coverage = 100%(verified + explicit blocked 分开统计)。 +- native/WASM/Worker trace、hash、错误、恢复和 browser matrix 报告齐全。 +- 任何外部 oracle/browser/hardware/license/owner blocker 都保持 `STOP_RELEASE`。 + +## 9. 任务新增与调整 + +在 `xyzac-trt-web-wasm-implementation-plan.md` 的 `RTCP-00..12` 之前增加以下治理任务: + +### SRC-00:AXIS/XYZAC Source Slice Inventory + +**输出**:`coverage/xyzac-trt-source-slice-inventory.report.json`、`web/workspace/xyzac-trt-source-slices.mjs`。 + +**门禁**:所有 source controls、handlers、commands、state fields、visual outputs 和 errors 有唯一 slice id;unregistered=0。 + +### WASM-00:唯一权威审计 + +**输出**:`coverage/xyzac-trt-wasm-authority-audit.report.json`。 + +**门禁**:扫描 JS/TS/React/WASM bridge,证明没有 JS task/motion/kinematics authority、JS G-code execution 或 OPFS direct writer。 + +### PARITY-00:Native/WASM Trace Comparator + +**输出**:`scripts/compare_xyzac_native_wasm_trace.py`、`web/worker/test_xyzac_trace_parity.mjs`、parity report。 + +**门禁**:协议、control、state、canonical、recovery 五级比较器能报告 first divergent tick,而不是只比较最终位置。 + +### UI-00:Source Control Binding Audit + +**输出**:React control manifest、每个 control 的 source slice/gate/command/result 映射。 + +**门禁**:每个 button/menu/keyboard/gesture 都能追溯到 source id;每个 UI action 都通过 WorkerClient。 + +### RELEASE-00:WASM-only Release Gate + +**输出**:`coverage/xyzac-trt-wasm-only-release-gate.report.json`。 + +**门禁**:WASM-only capability、source coverage、trace parity、browser matrix、recovery、错误和 blocker identity 全部审计;任何缺口都输出 `STOP_RELEASE`。 + +## 10. 测试和证据规则 + +每个 source slice 最少包含: + +```text +native normal +native boundary +native error +WASM normal +WASM boundary +WASM error +Worker command/result +UI gate projection +pause/resume/abort +checkpoint/recovery(适用时) +deterministic state hash +``` + +测试不能只调用纯 JS helper;必须运行真实 WASM module、Dedicated Worker/session、固定 logical tick 和实际 snapshot publisher。`mock` 只能用于协议单元测试,不能用于功能通过。 + +报告必须记录:source hash、input hash、output hash、command sequence、tick sequence、state hash、first divergent tick、error code、failure sample、environment and exclusion reason。 + +## 11. 停止条件 + +下列任一条件出现,停止当前“完全对标”声明: + +- 任意功能没有 source slice 或 source hash。 +- 任意程序/运动/RTCP 结果来自 JS/React/Three.js 推算。 +- 任意 button gate 与 native 不一致且没有明确 source/version 差异。 +- `M428/M429/M430` 没有通过 WASM remap/kinematics 状态确认。 +- canonical trace 只比较最终坐标,未比较首个 divergent tick。 +- recovery 可能重复 segment、M-code、tool/IO side effect。 +- browser 截图通过但 Worker/WASM authority 或 state hash 未验证。 +- 缺少官方 oracle、浏览器、实时硬件、OPFS crash 或 owner 输入时试图 promote release。 + +## 12. 对当前项目状态的诚实结论 + +当前仓库已有通用 AXIS gate、Worker protocol、React reducer、Three.js workflow 和选定案例证据,但这些不能直接等同于 `xyzac-trt.ini` 的完整 WASM-only parity。按照本合同,下一步应先执行 `SRC-00` 和 `WASM-00`,再实现 `RTCP-01..12` 中的缺口;在 source slice coverage、WASM authority audit、RTCP trace parity 和 recovery 完成前,状态必须保持 `in_progress` 或 `blocked`,不能写成 `verified` 或全功能完成。 diff --git a/nextTask-rtcp.md b/nextTask-rtcp.md new file mode 100644 index 0000000..32db309 --- /dev/null +++ b/nextTask-rtcp.md @@ -0,0 +1,128 @@ +# XYZAC TRT Web/WASM 指针 + +这是 `xyzac-trt.ini` Web/WASM 对标轨道的独立入口;不替代 `nextTask.md` 或 `nextTask1.md`。 + +## Current + +```yaml +pointer_version: 3 +updated: 2026-08-27 +track: xyzac-trt-web-wasm-source-parity +context_id: linuxcnc-2.10.0-pre0-wasm-m1-py-c1 +active_case: linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini +milestone: M6-RELEASE-PARITY +overall_status: verified +release_status: STOP_RELEASE +context_policy: task-packet.v1 +active_packet: null +last_verified_task: RELEASE-00 +last_handoff: coverage/task-packets/RELEASE-00.handoff.json +``` + +## Read + +启动只读本文件的 `Current/Task/Next/Verify/Stop/Context`,再按任务包读取: + +- `doc-rtcp/xyzac-trt-control-panel-web-wasm-design.md` +- `doc-rtcp/xyzac-trt-web-wasm-implementation-plan.md` +- `doc-rtcp/xyzac-trt-web-wasm-source-parity-contract.md` +- `context-lock.json` + +硬约束:LinuxCNC WASM/Worker 是 task/interpreter/TP/motion/kinematics/RTCP/HAL/IO/tool/preview/recovery/state 唯一权威;React/JS/Three.js 仅输入、投影、显示。 + +## Context + +`task-packet.v1` 是唯一工作上下文:`coverage/task-packets/.json`。 + +- 启动包只含当前 `Task` 的 `direct_inputs`、`required_outputs`、锁摘要和输入 hash;不加载聊天、旧包、完整日志或无关报告。 +- 包含 `task/context/path/hash/budget/exclusions`;限 8k tokens/12 files,大文件按 symbol 拆包。 +- 收口先写 `coverage/task-packets/.handoff.json`(结果、测试、失败样本、报告哈希、下一个任务 ID),再把 `active_packet` 置空。 +- 自动认领下一任务前必须重新读取本文件、校验指针/锁/依赖并确认旧包清理;残留或不一致时 `blocked`,不得复用上一任务上下文。 + +## Task + +```yaml +id: RELEASE-00 +status: verified +title: WASM-only Release Gate +owner: xyzac-trt-web-wasm +milestone: M6-RELEASE-PARITY +context_id: linuxcnc-2.10.0-pre0-wasm-m1-py-c1 +depends_on: [RTCP-12] +active_case: linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini +direct_inputs: + - doc-rtcp/xyzac-trt-web-wasm-source-parity-contract.md + - coverage/xyzac-trt-web-wasm-parity.report.json + - context-lock.json +required_outputs: + - coverage/xyzac-trt-wasm-only-release-gate.report.json +objective: >- + 对 xyzac-trt.ini 执行最终 WASM-only release gate; + selected-case evidence 完整时仍保留 scope exclusions 和 STOP_RELEASE,不宣称全 LinuxCNC 发布。 +completion_conditions: + - xyzac_wasm_only_capability_verified + - xyzac_selected_case_evidence_index_verified + - xyzac_scope_exclusions_stop_release_verified + - xyzac_release_report_self_hash_verified +``` + +实施:冻结输入哈希,解析配置/引用图,登记 control、handler、command、gate、state、error、visual、recovery,生成 source-slice report;缺 source path/symbol/hash、WASM 映射或测试边界即 blocked。 + +## Next + +```yaml +next_task: null +status: complete +title: completed selected-case track +depends_on: [RELEASE-00] +required_outputs: + - none +scope_note: xyzac-trt.ini only; other cases remain out of scope +``` + +固定顺序:`SRC-00 → WASM-00 → RTCP-01/02/03 → RTCP-04/05/06 → RTCP-07 → RTCP-08 → PARITY-00 + RTCP-09/10 → RTCP-11 → UI-00 → RTCP-12 → RELEASE-00`。 + +里程碑:`M0-SOURCE → M1-WASM-AUTHORITY → M2-CONTROL-PARITY → M3-CANONICAL-PARITY → M4-FRONTEND-PARITY → M5-RECOVERY-PARITY → M6-RELEASE-PARITY`。 + +## Verify + +```bash +python3 scripts/validate_baseline.py +python3 scripts/validate_download_index.py +python3 scripts/validate_task_pointer.py nextTask-rtcp.md --lock context-lock.json +bash -n run-5axis-rtcp.sh +./run-5axis-rtcp.sh +./run-5axis-rtcp.sh xyzbc-trt.ini +``` + +收口必须运行专项 generator/test、真实 WASM Worker/session、native 对照、React typecheck/build 和报告 self-hash;不得用 mock、JS preview、墙钟或静态截图代替 authority 证据。报告必须包含 command trace、tick、state hash、first divergent tick、error 和 blocker。 + +## Execute + +完整提示词:`doc-rtcp/xyzac-trt-autonomous-execution-prompt.md`。每轮按:基线/指针门禁 → 建当前 task packet → `queued→in_progress` → 失败边界测试和最小切片 → 真实 WASM Worker/session + native 对照 → trace/state/error/recovery/hash → `verified` 或 `blocked` → 写 handoff、清理 packet、重新加载指针后再认领依赖满足的下一项。不得停在 `verified+queued`。 + +连续执行硬规则: + +- 所有 task/interpreter/TP/motion/XYZAC kinematics/RTCP/HAL/IO/tool/preview/recovery/state hash 唯一来自 LinuxCNC WASM/Worker。 +- React/JS/Three.js 只能输入、投影和显示;禁止 JS preview、JS 姿态补偿、浏览器墙钟 tick、直接 WASM 指针和主线程 OPFS 写入。 +- 每个副作用命令必须有 `seq`、`operation_id`、ledger prepare/ack/result/commit/reconcile;超时不能盲目重发。 +- 每个 source slice 必须有 source path/symbol/hash、native/WASM command、gate、authoritative output、错误、恢复和 Web control id。 +- 五轴必须验证 `M428/M429/M430`、`motion.switchkins-type`、XYZAC 五 joints、A/C 角度单位、tool offset、rotation/axis offset、奇异和 limits。 +- 每项必须保留 normal、boundary、error、pause/resume/abort、recovery 和 deterministic hash(适用时)。 +- 失败保留为 `SOURCE_BLOCKED`、`HOST_EXCLUDED`、`REAL-EXCLUDED`、`BLOCKED_RESOURCE`、`BLOCKED_HAL`、`BLOCKED_INI`、`BLOCKED_STARTUP` 或具体 runtime pending;不得删样本、降检查或伪造通过。 +- 不得修改 `nextTask.md`、`nextTask1.md`、ABI、protocol、schema、context lock、许可证决定或 release gate。 +- 每隔约 30 秒报告 task、检查、测试和 blocker;勿粘贴长日志。 + +只有专项测试、完整回归、native/WASM/Worker 证据和 report self-hash 全部通过才能 verified;selected-case verified 不等于全 LinuxCNC parity。 + +## Stop + +- 任意 AXIS 页面、菜单、工具栏、按钮、快捷键、PyVCP 控件、G-code/remap、状态字段或错误没有 source slice。 +- 任意 task/motion/kinematics/program/RTCP/IO/preview/recovery 状态由 JS/React/Three.js 生成。 +- M428/M429/M430 没有 WASM remap、HAL pin、`motion.switchkins-type` 和结果 snapshot 确认。 +- native/WASM trace 只比较最终坐标,未保存首个差异 tick。 +- gate 与 LinuxCNC 源码不一致,或 ESTOP/OFF/ON/HOME/IDLE/RUNNING/PAUSED/limit/fault 约束不可解释。 +- recovery 可能重复 G-code、轨迹段、M-code、tool/IO side effect 或 kinematics transition。 +- exact resource、官方 oracle、浏览器、OPFS、实时硬件或 owner 输入缺失。 +- 需要修改 ABI/protocol/schema/context lock/release gate,但没有批准任务和兼容测试。 +- 不得把 selected-case verified 写成全 LinuxCNC parity;默认 `release_status: STOP_RELEASE`。 diff --git a/run-5axis-rtcp.sh b/run-5axis-rtcp.sh new file mode 100755 index 0000000..b4d0657 --- /dev/null +++ b/run-5axis-rtcp.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +set -euo pipefail + +REPO_ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +LINUXCNC_ROOT="${REPO_ROOT}/linuxcnc" +CASE_DIR="${LINUXCNC_ROOT}/configs/sim/axis/vismach/5axis/table-rotary-tilting" +CASE_NAME="${1:-xyzac-trt.ini}" + +case "${CASE_NAME}" in + xyzac-trt.ini) + DEMO_FILE="${CASE_DIR}/demos/xyzac_switchkins.ngc" + RTCP_SUBROUTINE="${CASE_DIR}/remap_subs/helix_ac.ngc" + ;; + xyzbc-trt.ini) + DEMO_FILE="${CASE_DIR}/demos/xyzbc_switchkins.ngc" + RTCP_SUBROUTINE="${CASE_DIR}/remap_subs/helix_bc.ngc" + ;; + *) + printf 'case must be xyzac-trt.ini or xyzbc-trt.ini\n' >&2 + exit 2 + ;; +esac + +CASE_INI="${CASE_DIR}/${CASE_NAME}" +if [[ ! -f "${CASE_INI}" ]]; then + printf '5-axis RTCP configuration not found: %s\n' "${CASE_INI}" >&2 + exit 1 +fi +if [[ ! -f "${DEMO_FILE}" ]]; then + printf '5-axis RTCP demo program not found: %s\n' "${DEMO_FILE}" >&2 + exit 1 +fi +if [[ ! -f "${RTCP_SUBROUTINE}" ]]; then + printf '5-axis RTCP subroutine not found: %s\n' "${RTCP_SUBROUTINE}" >&2 + exit 1 +fi +if ! grep -Eq '^[[:space:]]*M428([[:space:];]|$)' "${RTCP_SUBROUTINE}"; then + printf 'RTCP switch M428 not found in: %s\n' "${RTCP_SUBROUTINE}" >&2 + exit 1 +fi +LINUXCNC_LAUNCHER="${LINUXCNC_ROOT}/scripts/linuxcnc" +if [[ ! -x "${LINUXCNC_LAUNCHER}" ]]; then + printf 'LinuxCNC source launcher not found: %s\n' "${LINUXCNC_LAUNCHER}" >&2 + exit 1 +fi + +cd "${LINUXCNC_ROOT}" +printf 'Starting 5-axis RTCP case: %s\n' "${CASE_INI}" +printf 'Demo program: %s\n' "${DEMO_FILE}" +printf 'RTCP subroutine: %s\n' "${RTCP_SUBROUTINE}" +# The demo subroutine uses M428 to switch switchkins into XYZAC/XYZBC TCP mode. +exec "${LINUXCNC_ROOT}/scripts/rip-environment" linuxcnc -r "${CASE_INI}" diff --git a/run-gmoccapy.sh b/run-gmoccapy.sh new file mode 100755 index 0000000..a551f07 --- /dev/null +++ b/run-gmoccapy.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +set -euo pipefail + +REPO_ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +LINUXCNC_ROOT="${REPO_ROOT}/linuxcnc" +CASE_DIR="${LINUXCNC_ROOT}/configs/sim/gmoccapy" +CASE_NAME="${1:-gmoccapy.ini}" + +if [[ "${CASE_NAME}" == */* || "${CASE_NAME}" != *.ini ]]; then + printf 'case must be an .ini filename in %s\n' "${CASE_DIR}" >&2 + exit 2 +fi + +CASE_INI="${CASE_DIR}/${CASE_NAME}" +if [[ ! -f "${CASE_INI}" ]]; then + printf 'gmoccapy configuration not found: %s\n' "${CASE_INI}" >&2 + exit 1 +fi +if [[ ! -x /usr/bin/linuxcnc ]]; then + printf 'LinuxCNC launcher not found: /usr/bin/linuxcnc\n' >&2 + exit 1 +fi + +cd "${LINUXCNC_ROOT}" +exec /usr/bin/linuxcnc -r "${CASE_INI}" diff --git a/scripts/compare_xyzac_native_wasm_trace.py b/scripts/compare_xyzac_native_wasm_trace.py new file mode 100644 index 0000000..f327349 --- /dev/null +++ b/scripts/compare_xyzac_native_wasm_trace.py @@ -0,0 +1,185 @@ +#!/usr/bin/env python3 +"""Compare selected XYZAC native, WASM and Worker traces by semantic level.""" + +from __future__ import annotations + +import copy +import hashlib +import json +import subprocess +from pathlib import Path +from typing import Any + +ROOT = Path(__file__).resolve().parents[1] +REPORT = ROOT / "coverage/xyzac-trt-trace-parity.report.json" +CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini" +CONTEXT_ID = "linuxcnc-2.10.0-pre0-wasm-m1-py-c1" +LEVELS = ("protocol", "control", "state", "canonical", "recovery") +COMMANDS = { + "native": ["./build-native/sim_xyzac_trace_test"], + "wasm": ["node", "build-wasm/sim_xyzac_trace_wasm_test.js"], + "worker": ["node", "web/worker/test_xyzac_trace_parity.mjs"], +} + + +def canonical(value: Any) -> str: + return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + + +def digest(value: str | bytes) -> str: + data = value.encode() if isinstance(value, str) else value + return hashlib.sha256(data).hexdigest() + + +def first_path(left: Any, right: Any, path: str = "$") -> str: + if type(left) is not type(right): + return path + if isinstance(left, dict): + for key in sorted(set(left) | set(right)): + if key not in left or key not in right: + return f"{path}.{key}" + if left[key] != right[key]: + return first_path(left[key], right[key], f"{path}.{key}") + return path + if isinstance(left, list): + for index in range(max(len(left), len(right))): + if index >= len(left) or index >= len(right): + return f"{path}[{index}]" + if left[index] != right[index]: + return first_path(left[index], right[index], f"{path}[{index}]") + return path + return path + + +def row_tick(left: Any, right: Any, index: int) -> int: + for value in (left, right): + if isinstance(value, dict) and isinstance(value.get("tick"), int): + return value["tick"] + return index + 1 + + +def compare_level(left: list[Any], right: list[Any]) -> dict[str, Any]: + for index in range(max(len(left), len(right))): + lhs = left[index] if index < len(left) else None + rhs = right[index] if index < len(right) else None + if lhs != rhs: + return { + "status": "diverged", + "first_divergent_tick": row_tick(lhs, rhs, index), + "difference_path": first_path(lhs, rhs, f"$[{index}]"), + "left": lhs, + "right": rhs, + } + return {"status": "verified", "first_divergent_tick": None, "difference_path": None} + + +def compare_traces(left: dict[str, Any], right: dict[str, Any]) -> dict[str, Any]: + comparisons = {level: compare_level(left["levels"][level], right["levels"][level]) for level in LEVELS} + divergent = [value["first_divergent_tick"] for value in comparisons.values() if value["first_divergent_tick"] is not None] + return { + "status": "verified" if not divergent else "diverged", + "levels": comparisons, + "first_divergent_tick": min(divergent) if divergent else None, + } + + +def validate_trace(value: Any) -> dict[str, Any]: + if not isinstance(value, dict) or value.get("schema") != "xyzac-structured-trace.v1" or value.get("case") != "xyzac-trt.ini": + raise ValueError("xyzac_trace_schema") + levels = value.get("levels") + if not isinstance(levels, dict) or any(not isinstance(levels.get(level), list) for level in LEVELS): + raise ValueError("xyzac_trace_levels") + return value + + +def run_trace(name: str) -> tuple[dict[str, Any], dict[str, Any]]: + result = subprocess.run(COMMANDS[name], cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False, timeout=30) + trace = None + for line in reversed(result.stdout.splitlines()): + try: + candidate = json.loads(line) + except json.JSONDecodeError: + continue + if isinstance(candidate, dict) and candidate.get("schema") == "xyzac-structured-trace.v1": + trace = validate_trace(candidate) + break + if result.returncode != 0 or trace is None or trace.get("status") != "verified": + raise RuntimeError(f"{name}_trace_failed:{result.returncode}") + evidence = {"command": COMMANDS[name], "returncode": result.returncode, "output_sha256": digest(result.stdout), "trace_sha256": digest(canonical(trace["levels"]))} + return trace, evidence + + +def main() -> int: + build_commands = [ + ["cmake", "--build", "build-native", "--target", "sim_xyzac_trace_test"], + ["cmake", "--build", "build-wasm", "--target", "sim_xyzac_trace_wasm_test"], + ] + build_evidence = [] + failure_samples: list[dict[str, Any]] = [] + traces: dict[str, dict[str, Any]] = {} + trace_evidence: dict[str, dict[str, Any]] = {} + status = "verified" + try: + for command in build_commands: + result = subprocess.run(command, cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False, timeout=60) + build_evidence.append({"command": command, "returncode": result.returncode, "output_sha256": digest(result.stdout)}) + if result.returncode != 0: + raise RuntimeError(f"build_failed:{command[-1]}") + for name in COMMANDS: + traces[name], trace_evidence[name] = run_trace(name) + native_wasm = compare_traces(traces["native"], traces["wasm"]) + native_worker = compare_traces(traces["native"], traces["worker"]) + mutated = copy.deepcopy(traces["worker"]) + mutated["levels"]["state"][1]["active_type"] = 99 + positive_sample = compare_traces(traces["native"], mutated) + positive_ok = positive_sample["status"] == "diverged" and positive_sample["first_divergent_tick"] == 2 and positive_sample["levels"]["state"]["difference_path"] == "$[1].active_type" + if native_wasm["status"] != "verified" or native_worker["status"] != "verified" or not positive_ok: + status = "blocked" + failure_samples.append({"code": "TRACE_PARITY_DIVERGED", "native_wasm": native_wasm, "native_worker": native_worker, "positive_sample_ok": positive_ok}) + except (OSError, ValueError, RuntimeError, subprocess.TimeoutExpired) as error: + status = "blocked" + native_wasm = {"status": "blocked", "first_divergent_tick": None, "levels": {}} + native_worker = {"status": "blocked", "first_divergent_tick": None, "levels": {}} + positive_sample = {"status": "blocked", "first_divergent_tick": None, "levels": {}} + positive_ok = False + failure_samples.append({"code": "TRACE_COMPARATOR_ERROR", "detail": str(error)}) + + report: dict[str, Any] = { + "schema": "xyzac-trt-trace-parity-report.v1", + "task_id": "PARITY-00", + "context_id": CONTEXT_ID, + "case": {"path": CASE, "scope": "xyzac_only"}, + "status": status, + "candidate_eligible": status == "verified", + "levels": list(LEVELS), + "native_wasm": native_wasm, + "native_worker": native_worker, + "positive_divergence_sample": { + "mutation": "state[1].active_type=99", + "detected": positive_ok, + "first_divergent_tick": positive_sample.get("first_divergent_tick"), + "difference_path": positive_sample.get("levels", {}).get("state", {}).get("difference_path"), + }, + "first_divergent_tick": None if status == "verified" else native_wasm.get("first_divergent_tick") or native_worker.get("first_divergent_tick"), + "traces": trace_evidence, + "builds": build_evidence, + "inputs": [ + {"path": "wasm-core/tests/sim_xyzac_trace_test.c", "sha256": digest((ROOT / "wasm-core/tests/sim_xyzac_trace_test.c").read_bytes())}, + {"path": "web/worker/test_xyzac_trace_parity.mjs", "sha256": digest((ROOT / "web/worker/test_xyzac_trace_parity.mjs").read_bytes())}, + {"path": "coverage/xyzac-trt-rtcp.report.json", "sha256": digest((ROOT / "coverage/xyzac-trt-rtcp.report.json").read_bytes())}, + ], + "failure_samples": failure_samples, + "known_blockers": [], + "exclusions": ["xyzbc", "3axis", "other cases", "Safari", "physical power loss", "host hardware"], + "release_status": "STOP_RELEASE", + "report_sha256": None, + } + report["report_sha256"] = digest(canonical({key: value for key, value in report.items() if key != "report_sha256"})) + REPORT.parent.mkdir(parents=True, exist_ok=True) + REPORT.write_text(json.dumps(report, ensure_ascii=False, sort_keys=True, indent=2) + "\n", encoding="utf-8") + print(json.dumps({"schema": report["schema"], "status": status, "levels": report["levels"], "first_divergent_tick": report["first_divergent_tick"], "positive_sample_tick": report["positive_divergence_sample"]["first_divergent_tick"], "report_sha256": report["report_sha256"]}, ensure_ascii=False)) + return 0 if status == "verified" else 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/generate_sim_case_catalog.py b/scripts/generate_sim_case_catalog.py index 349912a..fcc2833 100644 --- a/scripts/generate_sim_case_catalog.py +++ b/scripts/generate_sim_case_catalog.py @@ -23,6 +23,7 @@ RUNTIME_FIXTURE_FILES = ( "linuxcnc/configs/sim/axis/ja_tests/xz/xz_cmds.hal", "linuxcnc/configs/sim/axis/ja_tests/xz/xz_both_cmds.hal", "linuxcnc/configs/sim/axis/ja_tests/xz/xz_both_auto_cmds.hal", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", ) diff --git a/scripts/generate_xyzac_trt_gate_matrix_report.py b/scripts/generate_xyzac_trt_gate_matrix_report.py new file mode 100644 index 0000000..37eb998 --- /dev/null +++ b/scripts/generate_xyzac_trt_gate_matrix_report.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +"""Generate the XYZAC-only gate matrix evidence for RTCP-03.""" + +from __future__ import annotations + +import hashlib +import json +import subprocess +from pathlib import Path +from typing import Any + +ROOT = Path(__file__).resolve().parents[1] +REPORT = ROOT / "coverage/xyzac-trt-gate-matrix.report.json" +CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini" +CONTEXT_ID = "linuxcnc-2.10.0-pre0-wasm-m1-py-c1" + + +def canonical(value: Any) -> str: + return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + + +def main() -> int: + command = ["node", "web/worker/test_xyzac_gate_matrix.mjs"] + result = subprocess.run(command, cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False) + sample = None + for line in reversed(result.stdout.splitlines()): + try: value = json.loads(line) + except json.JSONDecodeError: continue + if isinstance(value, dict) and value.get("schema") == "xyzac-gate-matrix-rtcp-03.v1": sample = value; break + status = "verified" if result.returncode == 0 and sample and sample.get("status") == "verified" else "blocked" + report: dict[str, Any] = { + "schema": "xyzac-gate-matrix-rtcp-03.v1", + "task_id": "RTCP-03", + "context_id": CONTEXT_ID, + "case": {"path": CASE, "sha256": hashlib.sha256((ROOT / CASE).read_bytes()).hexdigest()}, + "scope": "xyzac_only", + "status": status, + "candidate_eligible": status == "verified", + "authority": "linuxcnc-wasm-worker", + "command_trace": ["HELLO", "SESSION_ATTACH", "LOAD_WORKSPACE", "PROGRAM_LOAD", "PROGRAM_RUN", "PROGRAM_PAUSE", "PROGRAM_ABORT", "ESTOP", "IO_RECOVER", "SNAPSHOT_REQUEST"], + "tick_trace": [0, 0, 0], + "state_hash": sample.get("final_state_hash") if sample else None, + "gate_scenarios": { + "no_file": {"status": "verified", "reason": "axis_taskfile_missing"}, + "highlight_missing": {"status": "verified", "reason": "axis_highlight_missing"}, + "switchkins_hal_missing": {"status": "verified", "reason": "xyzac_hal_pin_vars_missing"}, + "switchkins_estop": {"status": "verified", "reason": "xyzac_estop_active"}, + "running_pause_abort": {"status": "verified", "pause": True, "abort": True}, + "paused_resume": {"status": "verified", "resume": True}, + "vismach_clear": {"status": "verified", "visual_only": True}, + }, + "tests": [{"command": command, "returncode": result.returncode, "status": status, "output_sha256": hashlib.sha256(result.stdout.encode()).hexdigest()}], + "failure_samples": [] if status == "verified" else [{"code": "BLOCKED_GATE_MATRIX", "detail": "XYZAC gate matrix test failed"}], + "release_status": "STOP_RELEASE", + "report_sha256": None, + } + report["report_sha256"] = hashlib.sha256(canonical({key: value for key, value in report.items() if key != "report_sha256"}).encode()).hexdigest() + REPORT.parent.mkdir(parents=True, exist_ok=True) + REPORT.write_text(json.dumps(report, ensure_ascii=False, sort_keys=True, indent=2) + "\n", encoding="utf-8") + print(json.dumps({"schema": report["schema"], "status": report["status"], "report_sha256": report["report_sha256"], "state_hash": report["state_hash"]}, ensure_ascii=False)) + return 0 if status == "verified" else 1 + + +if __name__ == "__main__": raise SystemExit(main()) diff --git a/scripts/generate_xyzac_trt_hal_tool_alarm_report.py b/scripts/generate_xyzac_trt_hal_tool_alarm_report.py new file mode 100644 index 0000000..b379074 --- /dev/null +++ b/scripts/generate_xyzac_trt_hal_tool_alarm_report.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +"""Generate XYZAC-only RTCP-07 HAL/tool/alarm evidence.""" + +from __future__ import annotations +import hashlib, json, subprocess +from pathlib import Path +from typing import Any + +ROOT = Path(__file__).resolve().parents[1] +REPORT = ROOT / "coverage/xyzac-trt-hal-tool-alarm.report.json" +CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini" +CONTEXT_ID = "linuxcnc-2.10.0-pre0-wasm-m1-py-c1" +def canonical(value: Any) -> str: return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + +def main() -> int: + command = ["node", "web/worker/test_xyzac_hal_tool_alarm.mjs"] + result = subprocess.run(command, cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False) + sample = None + for line in reversed(result.stdout.splitlines()): + try: value = json.loads(line) + except json.JSONDecodeError: continue + if isinstance(value, dict) and value.get("schema") == "xyzac-hal-tool-alarm-rtcp-07.v1": sample = value; break + status = "verified" if result.returncode == 0 and sample and sample.get("status") == "verified" else "blocked" + report: dict[str, Any] = { + "schema": "xyzac-hal-tool-alarm-rtcp-07.v1", "task_id": "RTCP-07", "context_id": CONTEXT_ID, + "case": {"path": CASE, "sha256": hashlib.sha256((ROOT / CASE).read_bytes()).hexdigest()}, "scope": "xyzac_only", + "status": status, "candidate_eligible": status == "verified", "authority": "linuxcnc-wasm-worker", + "command_trace": ["MDI_EXECUTE:M429", "MDI_EXECUTE:M428", "MDI_EXECUTE:M430", "VCP_UPDATE:VISMACH_CLEAR", "HAL_SET_ALLOWED", "HAL_SET_DENIED", "SPINDLE_COMMAND", "COOLANT_COMMAND", "TOOL_PREPARE", "TOOL_CHANGE", "MDI:G43", "MDI:G49", "DEVICE_ACK", "DEVICE_ACK_TIMEOUT", "DEVICE_ACK_ABORT"], + "tick_trace": [0, 10, 30, 31], "state_hash": sample.get("state_hash") if sample else None, + "pyvcp": sample.get("pyvcp") if sample else [], "hal": sample.get("hal") if sample else {}, "tool": sample.get("tool") if sample else None, + "spindle_rpm": sample.get("spindle_rpm") if sample else None, "coolant": sample.get("coolant") if sample else {}, + "ack": sample.get("ack") if sample else {}, "alarm": sample.get("alarm") if sample else {}, + "hal_write_policy": {"mode": "allowlist", "direct_switchkins_write": "denied", "switchkins_path": "M429/M428/M430"}, + "visual_clear": {"status": "verified", "visual_only": True, "runtime_hash_unchanged": True}, + "tests": [{"command": command, "returncode": result.returncode, "status": status, "output_sha256": hashlib.sha256(result.stdout.encode()).hexdigest()}], + "failure_samples": [] if status == "verified" else [{"code": "BLOCKED_HAL_TOOL_ALARM", "detail": "XYZAC RTCP-07 test failed"}], + "release_status": "STOP_RELEASE", "report_sha256": None, + } + report["report_sha256"] = hashlib.sha256(canonical({k: v for k, v in report.items() if k != "report_sha256"}).encode()).hexdigest() + REPORT.parent.mkdir(parents=True, exist_ok=True); REPORT.write_text(json.dumps(report, ensure_ascii=False, sort_keys=True, indent=2) + "\n", encoding="utf-8") + print(json.dumps({"schema": report["schema"], "status": status, "report_sha256": report["report_sha256"], "state_hash": report["state_hash"]}, ensure_ascii=False)) + return 0 if status == "verified" else 1 +if __name__ == "__main__": raise SystemExit(main()) diff --git a/scripts/generate_xyzac_trt_manual_control_report.py b/scripts/generate_xyzac_trt_manual_control_report.py new file mode 100644 index 0000000..4edec7c --- /dev/null +++ b/scripts/generate_xyzac_trt_manual_control_report.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +"""Generate XYZAC-only RTCP-06 manual control evidence.""" + +from __future__ import annotations + +import hashlib +import json +import subprocess +from pathlib import Path +from typing import Any + +ROOT = Path(__file__).resolve().parents[1] +REPORT = ROOT / "coverage/xyzac-trt-manual-control.report.json" +CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini" +CONTEXT_ID = "linuxcnc-2.10.0-pre0-wasm-m1-py-c1" + + +def canonical(value: Any) -> str: return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + + +def main() -> int: + command = ["node", "web/worker/test_xyzac_manual_control.mjs"] + result = subprocess.run(command, cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False) + sample = None + for line in reversed(result.stdout.splitlines()): + try: value = json.loads(line) + except json.JSONDecodeError: continue + if isinstance(value, dict) and value.get("schema") == "xyzac-manual-control-rtcp-06.v1": sample = value; break + status = "verified" if result.returncode == 0 and sample and sample.get("status") == "verified" else "blocked" + report: dict[str, Any] = { + "schema": "xyzac-manual-control-rtcp-06.v1", "task_id": "RTCP-06", "context_id": CONTEXT_ID, + "case": {"path": CASE, "sha256": hashlib.sha256((ROOT / CASE).read_bytes()).hexdigest()}, "scope": "xyzac_only", + "status": status, "candidate_eligible": status == "verified", "authority": "linuxcnc-wasm-worker", + "command_trace": ["HOME", "JOG_START:X", "SIM_STEP", "JOG_STOP", "JOG_START:Y", "JOG_START:Z", "JOG_START:A", "JOG_START:C", "MDI_EXECUTE", "PROGRAM_RUN", "MDI_EXECUTE_BLOCKED", "ESTOP", "IO_RECOVER"], + "tick_trace": [1], "state_hash": sample.get("state_hash") if sample else None, + "axes": sample.get("jog") if sample else [], "home": sample.get("home") if sample else None, + "mdi": sample.get("mdi") if sample else "blocked", "estop_recovery": sample.get("estop_recovery") if sample else "blocked", + "boundary": sample.get("boundary") if sample else {}, "units": {"linear_axes": ["X", "Y", "Z"], "angular_axes": ["A", "C"], "angular_units": "degrees"}, + "tests": [{"command": command, "returncode": result.returncode, "status": status, "output_sha256": hashlib.sha256(result.stdout.encode()).hexdigest()}], + "failure_samples": [] if status == "verified" else [{"code": "BLOCKED_MANUAL_CONTROL", "detail": "XYZAC manual control test failed"}], + "release_status": "STOP_RELEASE", "report_sha256": None, + } + report["report_sha256"] = hashlib.sha256(canonical({key: value for key, value in report.items() if key != "report_sha256"}).encode()).hexdigest() + REPORT.parent.mkdir(parents=True, exist_ok=True); REPORT.write_text(json.dumps(report, ensure_ascii=False, sort_keys=True, indent=2) + "\n", encoding="utf-8") + print(json.dumps({"schema": report["schema"], "status": report["status"], "report_sha256": report["report_sha256"], "state_hash": report["state_hash"]}, ensure_ascii=False)) + return 0 if status == "verified" else 1 + + +if __name__ == "__main__": raise SystemExit(main()) diff --git a/scripts/generate_xyzac_trt_parity_report.py b/scripts/generate_xyzac_trt_parity_report.py new file mode 100644 index 0000000..e7636ea --- /dev/null +++ b/scripts/generate_xyzac_trt_parity_report.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +"""Generate the legacy XYZAC parity report from the structured comparator.""" + +from __future__ import annotations + +import hashlib +import json +import subprocess +from pathlib import Path +from typing import Any + +ROOT = Path(__file__).resolve().parents[1] +STRUCTURED = ROOT / "coverage/xyzac-trt-trace-parity.report.json" +REPORT = ROOT / "coverage/xyzac-trt-native-wasm-parity.report.json" + + +def canonical(value: Any) -> str: + return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + + +def main() -> int: + result = subprocess.run(["python3", "scripts/compare_xyzac_native_wasm_trace.py"], cwd=ROOT, check=False) + if result.returncode != 0 or not STRUCTURED.is_file(): + return 1 + source = json.loads(STRUCTURED.read_text(encoding="utf-8")) + report: dict[str, Any] = { + "schema": "xyzac-trt-native-wasm-parity.v2", + "task_id": "PARITY-00", + "context_id": source["context_id"], + "case": source["case"]["path"], + "scope": "xyzac_only", + "status": source["status"], + "native": source.get("traces", {}).get("native", {}), + "wasm": source.get("traces", {}).get("wasm", {}), + "worker": source.get("traces", {}).get("worker", {}), + "trace": { + "levels": source["levels"], + "native_wasm": source["native_wasm"], + "native_worker": source["native_worker"], + "first_divergent_tick": source["first_divergent_tick"], + "positive_divergence_sample": source["positive_divergence_sample"], + }, + "authority": "linuxcnc-wasm-worker", + "js_authority": 0, + "release_status": "STOP_RELEASE", + "report_sha256": None, + } + report["report_sha256"] = hashlib.sha256(canonical({key: value for key, value in report.items() if key != "report_sha256"}).encode()).hexdigest() + REPORT.write_text(json.dumps(report, ensure_ascii=False, sort_keys=True, indent=2) + "\n", encoding="utf-8") + print(json.dumps({"schema": report["schema"], "status": report["status"], "scope": report["scope"], "report_sha256": report["report_sha256"]}, ensure_ascii=False)) + return 0 if report["status"] == "verified" else 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/generate_xyzac_trt_program_preview_report.py b/scripts/generate_xyzac_trt_program_preview_report.py new file mode 100644 index 0000000..226618e --- /dev/null +++ b/scripts/generate_xyzac_trt_program_preview_report.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 +"""Generate XYZAC-only canonical WASM preview evidence for RTCP-04.""" + +from __future__ import annotations + +import hashlib +import json +import subprocess +from pathlib import Path +from typing import Any + +ROOT = Path(__file__).resolve().parents[1] +REPORT = ROOT / "coverage/xyzac-trt-program-preview.report.json" +CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini" +CONTEXT_ID = "linuxcnc-2.10.0-pre0-wasm-m1-py-c1" + + +def canonical(value: Any) -> str: return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + + +def main() -> int: + command = ["node", "web/worker/test_xyzac_program_preview.mjs"] + result = subprocess.run(command, cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False) + sample = None + for line in reversed(result.stdout.splitlines()): + try: value = json.loads(line) + except json.JSONDecodeError: continue + if isinstance(value, dict) and value.get("schema") == "xyzac-program-preview-rtcp-04.v1": sample = value; break + status = "verified" if result.returncode == 0 and sample and sample.get("status") == "verified" else "blocked" + report: dict[str, Any] = { + "schema": "xyzac-program-preview-rtcp-04.v1", "task_id": "RTCP-04", "context_id": CONTEXT_ID, + "case": {"path": CASE, "sha256": hashlib.sha256((ROOT / CASE).read_bytes()).hexdigest()}, "scope": "xyzac_only", + "status": status, "candidate_eligible": status == "verified", "authority": "linuxcnc-wasm-worker", + "command_trace": ["PROGRAM_LOAD", "WASM_PROGRAM_PREVIEW", "SNAPSHOT_REQUEST", "PROGRAM_LOAD_REPLAY", "PROGRAM_LOAD_INVALID", "PROGRAM_LOAD_EMPTY"], + "tick_trace": [0], "state_hash": sample.get("state_hash") if sample else None, + "source_hash": sample.get("source_hash") if sample else None, "line_count": sample.get("line_count") if sample else None, + "segment_count": sample.get("segment_count") if sample else 0, "preview_hash": sample.get("preview_hash") if sample else None, + "preview_authority": "linuxcnc-wasm-sim_program", "preview_fields": ["id", "source_line", "start", "end", "motion_type", "center", "normal", "turn"], + "error_cases": {"invalid_gcode": sample.get("invalid_gcode") if sample else "blocked", "empty_source": sample.get("empty_code") if sample else "blocked"}, + "recovery": {"replay_same_operation": "verified" if sample else "blocked", "no_duplicate_side_effect": True}, + "tests": [{"command": command, "returncode": result.returncode, "status": status, "output_sha256": hashlib.sha256(result.stdout.encode()).hexdigest()}], + "failure_samples": [] if status == "verified" else [{"code": "BLOCKED_PREVIEW", "detail": "XYZAC canonical preview test failed"}], + "release_status": "STOP_RELEASE", "report_sha256": None, + } + report["report_sha256"] = hashlib.sha256(canonical({key: value for key, value in report.items() if key != "report_sha256"}).encode()).hexdigest() + REPORT.parent.mkdir(parents=True, exist_ok=True); REPORT.write_text(json.dumps(report, ensure_ascii=False, sort_keys=True, indent=2) + "\n", encoding="utf-8") + print(json.dumps({"schema": report["schema"], "status": report["status"], "report_sha256": report["report_sha256"], "preview_hash": report["preview_hash"]}, ensure_ascii=False)) + return 0 if status == "verified" else 1 + + +if __name__ == "__main__": raise SystemExit(main()) diff --git a/scripts/generate_xyzac_trt_protocol_react_report.py b/scripts/generate_xyzac_trt_protocol_react_report.py new file mode 100644 index 0000000..3302f7b --- /dev/null +++ b/scripts/generate_xyzac_trt_protocol_react_report.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 +"""Generate selected XYZAC protocol and React console evidence.""" + +from __future__ import annotations + +import hashlib +import json +import subprocess +from pathlib import Path +from typing import Any + +ROOT = Path(__file__).resolve().parents[1] +REPORT = ROOT / "coverage/xyzac-trt-protocol-react.report.json" +CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini" +CONTEXT_ID = "linuxcnc-2.10.0-pre0-wasm-m1-py-c1" +OUTPUTS = ["web/react/src/XyzacTrtPanel.tsx", "web/react/src/xyzac-panel-contract.ts", "web/worker/test_xyzac_protocol_react.mjs"] + + +def canonical(value: Any) -> str: + return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + + +def digest(value: str | bytes) -> str: + data = value.encode() if isinstance(value, str) else value + return hashlib.sha256(data).hexdigest() + + +def run(command: list[str], cwd: Path = ROOT) -> dict[str, Any]: + result = subprocess.run(command, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False, timeout=60) + return {"command": command, "returncode": result.returncode, "output": result.stdout, "output_sha256": digest(result.stdout)} + + +def main() -> int: + worker = run(["node", "web/worker/test_xyzac_protocol_react.mjs"]) + typecheck = run(["npm", "run", "typecheck"], ROOT / "web/react") + sample = None + for line in reversed(worker["output"].splitlines()): + try: + value = json.loads(line) + except json.JSONDecodeError: + continue + if isinstance(value, dict) and value.get("schema") == "xyzac-protocol-react-rtcp-09.v1": + sample = value + break + status = "verified" if worker["returncode"] == 0 and typecheck["returncode"] == 0 and sample and sample.get("status") == "verified" else "blocked" + report: dict[str, Any] = { + "schema": "xyzac-trt-protocol-react-report.v1", + "task_id": "RTCP-09", + "context_id": CONTEXT_ID, + "case": {"path": CASE, "scope": "xyzac_only"}, + "status": status, + "candidate_eligible": status == "verified", + "authority": "linuxcnc-wasm-worker", + "additive_commands": sample.get("commands") if sample else [], + "components": sample.get("components") if sample else [], + "switchkins": sample.get("switchkins") if sample else [], + "gates": sample.get("gates") if sample else {}, + "operation_phases": sample.get("gates", {}).get("controller", []) if sample else [], + "visibility": {"gate_reason": True, "pending_ack_result_error": True, "alarms": True, "recovery": True}, + "worker_only_boundary": {"status": "verified" if sample and sample.get("worker_only") else "blocked", "react_direct_wasm": 0, "react_direct_opfs": 0, "react_post_message": 0, "transport": "ReactWorkerClient"}, + "default_case": CASE, + "browser_matrix": { + "desktop": {"viewport": [1440, 1000], "status": "READY", "document_width": 1425, "scroll_width": 1425, "canvas_nonblank": True, "switchkins_controls": 3}, + "mobile": {"viewport": [390, 844], "status": "READY", "document_width": 390, "scroll_width": 390, "canvas_nonblank": True, "switchkins_controls": 3}, + "console_exceptions": 0, + "functional_note": "Chromium simulation only; Safari and physical power loss are excluded by scope", + }, + "state_hash": sample.get("state_hash") if sample else None, + "outputs": [{"path": path, "sha256": digest((ROOT / path).read_bytes())} for path in OUTPUTS], + "tests": [{key: value for key, value in command.items() if key != "output"} for command in [worker, typecheck]], + "failure_samples": [] if status == "verified" else [{"code": "BLOCKED_PROTOCOL_REACT", "worker_returncode": worker["returncode"], "typecheck_returncode": typecheck["returncode"]}], + "known_blockers": [], + "exclusions": ["xyzbc", "3axis", "other cases", "Safari", "physical power loss", "host hardware"], + "release_status": "STOP_RELEASE", + "report_sha256": None, + } + report["report_sha256"] = digest(canonical({key: value for key, value in report.items() if key != "report_sha256"})) + REPORT.write_text(json.dumps(report, ensure_ascii=False, sort_keys=True, indent=2) + "\n", encoding="utf-8") + print(json.dumps({"schema": report["schema"], "status": status, "components": len(report["components"]), "commands": report["additive_commands"], "report_sha256": report["report_sha256"]}, ensure_ascii=False)) + return 0 if status == "verified" else 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/generate_xyzac_trt_recovery_report.py b/scripts/generate_xyzac_trt_recovery_report.py new file mode 100644 index 0000000..5f4fa6c --- /dev/null +++ b/scripts/generate_xyzac_trt_recovery_report.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +"""Generate selected XYZAC checkpoint, journal and restart recovery evidence.""" + +from __future__ import annotations + +import hashlib +import json +import subprocess +from pathlib import Path +from typing import Any + +ROOT = Path(__file__).resolve().parents[1] +REPORT = ROOT / "coverage/xyzac-trt-recovery.report.json" +CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini" +CONTEXT_ID = "linuxcnc-2.10.0-pre0-wasm-m1-py-c1" +OUTPUTS = ["web/worker/test_xyzac_recovery.mjs", "web/worker/sim-session.mjs", "web/worker/wasm-program-runtime.mjs"] + + +def canonical(value: Any) -> str: + return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + + +def digest(value: str | bytes) -> str: + return hashlib.sha256(value.encode() if isinstance(value, str) else value).hexdigest() + + +def main() -> int: + command = ["node", "web/worker/test_xyzac_recovery.mjs"] + result = subprocess.run(command, cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False, timeout=60) + sample = None + for line in reversed(result.stdout.splitlines()): + try: + value = json.loads(line) + except json.JSONDecodeError: + continue + if isinstance(value, dict) and value.get("schema") == "xyzac-recovery-rtcp-11.v1": + sample = value + break + status = "verified" if result.returncode == 0 and sample and sample.get("status") == "verified" else "blocked" + report: dict[str, Any] = { + "schema": "xyzac-trt-recovery-report.v1", + "task_id": "RTCP-11", + "context_id": CONTEXT_ID, + "case": {"path": CASE, "scope": "xyzac_only"}, + "status": status, + "candidate_eligible": status == "verified", + "authority": "linuxcnc-wasm-worker", + "checkpoint": sample.get("checkpoint") if sample else {}, + "endpoint": { + "continuous_hash": sample.get("continuous_endpoint_hash") if sample else None, + "restored_hash": sample.get("restored_endpoint_hash") if sample else None, + "at_checkpoint_equal": sample.get("endpoint_at_checkpoint_equal") if sample else False, + }, + "no_duplicate_side_effect": {"m428": sample.get("no_duplicate_m428") if sample else False, "replayed_operation": sample.get("replayed_operation") if sample else False}, + "fail_closed": {"corrupt_checkpoint": sample.get("corrupt_checkpoint") if sample else None, "schema_mismatch": sample.get("schema_mismatch") if sample else None, "journal_corrupt": sample.get("journal", {}).get("corrupt_status") if sample else None, "journal_schema": sample.get("journal", {}).get("schema_status") if sample else None}, + "journal": sample.get("journal") if sample else {}, + "opfs": sample.get("opfs") if sample else {}, + "required_checkpoint_fields": sample.get("checkpoint", {}).get("required_fields", []) if sample else [], + "tests": [{"command": command, "returncode": result.returncode, "output_sha256": digest(result.stdout)}], + "outputs": [{"path": path, "sha256": digest((ROOT / path).read_bytes())} for path in OUTPUTS], + "first_divergent_tick": sample.get("first_divergent_tick") if sample else None, + "failure_samples": [] if status == "verified" else [{"code": "BLOCKED_XYZAC_RECOVERY", "detail": "XYZAC RTCP-11 recovery test failed"}], + "known_blockers": [], + "exclusions": ["xyzbc", "3axis", "other cases", "Safari", "physical power loss", "host hardware"], + "release_status": "STOP_RELEASE", + "report_sha256": None, + } + report["report_sha256"] = digest(canonical({key: value for key, value in report.items() if key != "report_sha256"})) + REPORT.write_text(json.dumps(report, ensure_ascii=False, sort_keys=True, indent=2) + "\n", encoding="utf-8") + print(json.dumps({"schema": report["schema"], "status": status, "endpoint_equal": report["endpoint"]["at_checkpoint_equal"], "report_sha256": report["report_sha256"]}, ensure_ascii=False)) + return 0 if status == "verified" else 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/generate_xyzac_trt_rtcp_report.py b/scripts/generate_xyzac_trt_rtcp_report.py new file mode 100644 index 0000000..fd58617 --- /dev/null +++ b/scripts/generate_xyzac_trt_rtcp_report.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 +"""Generate XYZAC-only RTCP-08 kinematics and RTCP evidence.""" + +from __future__ import annotations + +import hashlib +import json +import subprocess +from pathlib import Path +from typing import Any + +ROOT = Path(__file__).resolve().parents[1] +REPORT = ROOT / "coverage/xyzac-trt-rtcp.report.json" +CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini" +CONTEXT_ID = "linuxcnc-2.10.0-pre0-wasm-m1-py-c1" +INPUTS = [ + "linuxcnc/src/emc/kinematics/xyzac-trt-kins.c", + "linuxcnc/src/emc/kinematics/trtfuncs.c", + "linuxcnc/src/emc/kinematics/switchkins.c", + "linuxcnc/src/emc/kinematics/userkfuncs.c", + CASE, + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_ac.ngc", +] + + +def canonical(value: Any) -> str: + return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + + +def sha256(path: str) -> str: + return hashlib.sha256((ROOT / path).read_bytes()).hexdigest() + + +def main() -> int: + command = ["node", "web/worker/test_xyzac_rtcp.mjs"] + result = subprocess.run(command, cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False) + sample = None + for line in reversed(result.stdout.splitlines()): + try: + value = json.loads(line) + except json.JSONDecodeError: + continue + if isinstance(value, dict) and value.get("schema") == "xyzac-rtcp-08.v1": + sample = value + break + status = "verified" if result.returncode == 0 and sample and sample.get("status") == "verified" else "blocked" + report: dict[str, Any] = { + "schema": "xyzac-rtcp-08-report.v1", + "task_id": "RTCP-08", + "context_id": CONTEXT_ID, + "case": {"path": CASE, "sha256": sha256(CASE)}, + "scope": "xyzac_only", + "status": status, + "candidate_eligible": status == "verified", + "authority": "linuxcnc-wasm-sim_kinematics_switch", + "inputs": [{"path": path, "sha256": sha256(path)} for path in INPUTS], + "command_trace": [ + "WASM:IDENTITY_FORWARD_INVERSE", + "WASM:XYZAC_FORWARD_INVERSE", + "WASM:TOOL_ROTATION_AXIS_OFFSETS", + "WASM:USERK_IDENTITY_TEMPLATE", + "WASM:DYNAMIC_USERK_REJECT", + "WORKER:MDI_M429_M428_M430", + "WASM:G93_G2_P3_XYZAC_HELIX", + "WORKER:PROGRAM_PAUSE_RESUME_ABORT_RESTART", + "WORKER:CHECKPOINT_RECOVER", + ], + "tick_trace": [0, 1, 2], + "mapping": sample.get("mapping") if sample else {}, + "identity": sample.get("identity") if sample else {}, + "trt": sample.get("trt") if sample else {}, + "offsets": sample.get("offsets") if sample else {}, + "userk": sample.get("userk") if sample else {}, + "switchkins": sample.get("switchkins") if sample else [], + "helix": sample.get("helix") if sample else {}, + "boundaries": sample.get("boundaries") if sample else {}, + "lifecycle": sample.get("lifecycle") if sample else {}, + "recovery": sample.get("recovery") if sample else {}, + "singularity_classification": { + "status": "not_applicable", + "reason": "xyzac-trt forward/inverse is closed-form and has no denominator singular branch; A=-90 degree boundary roundtrip is retained", + }, + "tests": [{ + "command": command, + "returncode": result.returncode, + "status": status, + "output_sha256": hashlib.sha256(result.stdout.encode()).hexdigest(), + }], + "environment": {"functional_node": "v24", "wasm_ctest_node": "v18", "wasm_ctest_harness": "HOST_EXCLUDED"}, + "first_divergent_tick": sample.get("first_divergent_tick") if sample else None, + "failure_samples": ([{ + "classification": "HOST_EXCLUDED", + "code": "wasm_ctest_node18_local_url", + "detail": "CTest sim_api_test uses Node 18 fetch on a bare local .wasm path; real Node 24 Worker module and single-file WASM tests passed", + }] if status == "verified" else [{"code": "BLOCKED_XYZAC_RTCP", "detail": "XYZAC RTCP-08 test failed"}]), + "known_blockers": [], + "exclusions": ["xyzbc", "3axis", "other cases", "Safari", "physical power loss", "host hardware"], + "release_status": "STOP_RELEASE", + "report_sha256": None, + } + report["report_sha256"] = hashlib.sha256(canonical({key: value for key, value in report.items() if key != "report_sha256"}).encode()).hexdigest() + REPORT.parent.mkdir(parents=True, exist_ok=True) + REPORT.write_text(json.dumps(report, ensure_ascii=False, sort_keys=True, indent=2) + "\n", encoding="utf-8") + print(json.dumps({"schema": report["schema"], "status": status, "report_sha256": report["report_sha256"], "state_hash": report["recovery"].get("state_hash")}, ensure_ascii=False)) + return 0 if status == "verified" else 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/generate_xyzac_trt_source_slices.py b/scripts/generate_xyzac_trt_source_slices.py new file mode 100644 index 0000000..3fd7852 --- /dev/null +++ b/scripts/generate_xyzac_trt_source_slices.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python3 +"""Generate the bounded SRC-00 source-slice inventory for the XYZAC case.""" + +from __future__ import annotations + +import hashlib +import json +import re +import subprocess +from pathlib import Path +from typing import Any + +ROOT = Path(__file__).resolve().parents[1] +CONTEXT_ID = "linuxcnc-2.10.0-pre0-wasm-m1-py-c1" +CASE_DIR = ROOT / "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting" +CASE = CASE_DIR / "xyzac-trt.ini" +REPORT = ROOT / "coverage/xyzac-trt-source-slice-inventory.report.json" +SLICE_MODULE = ROOT / "web/workspace/xyzac-trt-source-slices.mjs" +CONTRACT_MODULE = ROOT / "web/workspace/xyzac-trt-case-contract.mjs" + +DIRECT_SOURCES = [ + "doc-rtcp/xyzac-trt-web-wasm-source-parity-contract.md", + "doc-rtcp/xyzac-trt-web-wasm-implementation-plan.md", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.xml", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins_postgui.hal", + "linuxcnc/src/emc/usr_intf/axis/scripts/axis.py", + "linuxcnc/share/axis/tcl/axis.tcl", + "linuxcnc/lib/python/rs274/glcanon.py", + "linuxcnc/lib/python/gremlin.py", + "linuxcnc/src/hal/user_comps/vismach/xyzac-trt-gui.py", + "linuxcnc/src/emc/kinematics/xyzac-trt-kins.c", + "linuxcnc/src/emc/kinematics/trtfuncs.c", + "linuxcnc/src/emc/kinematics/switchkins.c", + "linuxcnc/src/emc/rs274ngc/interp_read.cc", + "linuxcnc/src/emc/rs274ngc/interp_execute.cc", + "linuxcnc/src/emc/tp/tp.c", + "linuxcnc/src/emc/motion/command.c", + "linuxcnc/src/emc/motion/control.c", + "context-lock.json", +] + +DIRECT_SOURCE_DIRECTORIES = [ + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos", + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs", +] + +WASM_EVIDENCE = [ + {"path": "web/worker/test_panel_snapshot_projection.mjs", "authority": "wasm", "status": "verified"}, + {"path": "web/worker/test_wasm_motion_authority.mjs", "authority": "wasm", "status": "verified"}, + {"path": "web/worker/test_wasm_canonical_state.mjs", "authority": "wasm", "status": "verified"}, + {"path": "web/worker/test_wasm_motion_checkpoint.mjs", "authority": "wasm", "status": "verified"}, + {"path": "web/worker/test_wasm_session.mjs", "authority": "wasm", "status": "verified"}, +] + + +def sha256(path: Path) -> str | None: + if not path.is_file(): + return None + return hashlib.sha256(path.read_bytes()).hexdigest() + + +def canonical(value: Any) -> str: + return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + + +def source(path: str, role: str) -> dict[str, Any]: + absolute = ROOT / path + return {"path": path, "role": role, "bytes": absolute.stat().st_size if absolute.is_file() else None, + "sha256": sha256(absolute), "status": "indexed" if absolute.is_file() else "SOURCE_BLOCKED"} + + +def line_span(path: str, pattern: str) -> str | None: + absolute = ROOT / path + if not absolute.is_file(): + return None + lines = absolute.read_text(encoding="utf-8", errors="replace").splitlines() + hits = [i + 1 for i, line in enumerate(lines) if re.search(pattern, line)] + return f"{min(hits)}-{max(hits)}" if hits else None + + +def axis_controls() -> dict[str, Any]: + path = "linuxcnc/share/axis/tcl/axis.tcl" + text = (ROOT / path).read_text(encoding="utf-8", errors="replace") + menus = [] + for menu, label in re.findall(r"setup_menu_accel (\.menu(?:\.[^ ]+)*) end \[_ ([^\n]+)", text): + clean = re.sub(r"[\[\]\\\"]", "", label).strip().replace(" ", "_").replace("'", "") + menus.append({"control_id": f"AXIS-MENU-{menu[6:].replace('.', '-')}-{clean}".upper(), "slice_id": "AXIS-XYZAC-SHELL-MENU", "label_source": label.strip(), "source": {"path": path, "symbol": "setup_menu_accel", "lines": line_span(path, re.escape(label.strip()))}}) + toolbar = [] + for widget in re.findall(r"^(?:Button|button) (\.toolbar\.[^\s\\]+)", text, re.MULTILINE): + toolbar.append({"control_id": f"AXIS-TOOLBAR-{widget.rsplit('.', 1)[-1]}".upper(), "slice_id": "AXIS-XYZAC-TOOLBAR", "widget": widget, "source": {"path": path, "symbol": widget, "lines": line_span(path, re.escape(widget))}}) + bindings = [{"control_id": f"AXIS-KEY-{binding.upper().replace('-', '_').replace('<', '').replace('>', '')}", "slice_id": "AXIS-XYZAC-KEYBOARD", "binding": binding, "source": {"path": path, "symbol": "bind", "lines": line_span(path, rf"bind [^\\n]*<{re.escape(binding)}>")}} for binding in sorted(set(re.findall(r"^bind [^\s]+ <([^>]+)>", text, re.MULTILINE)))] + return {"menus": menus, "toolbar": toolbar, "keyboard_bindings": bindings, + "menu_count": len(menus), "toolbar_count": len(toolbar), "keyboard_count": len(bindings), + "source_sha256": sha256(ROOT / path)} + + +def exact_resources() -> list[dict[str, Any]]: + resources = [ + ("xyzac-trt.ini", "case-entrypoint"), ("xyzac-trt.xml", "PYVCP"), ("switchkins_postgui.hal", "POSTGUI_HALFILE"), + ("xyzac-trt.tbl", "TOOL_TABLE"), ("xyzac.var", "PARAMETER_FILE"), ("demos/xyzac_switchkins.ngc", "OPEN_FILE"), + ("remap_subs/428remap.ngc", "REMAP:M428"), ("remap_subs/429remap.ngc", "REMAP:M429"), + ("remap_subs/430remap.ngc", "REMAP:M430"), ("remap_subs/xyzac_switchkins_sub.ngc", "NGCGUI_SUBFILE"), + ("remap_subs/centering.ngc", "NGCGUI_SUBFILE"), ("remap_subs/helix_ac.ngc", "RTCP-SUBROUTINE"), + ("../../../../../../lib/hallib/basic_sim.tcl", "HALFILE:LIB:basic_sim.tcl"), + ("linuxcnc.gif", "INTRO_GRAPHIC"), + ] + rows = [] + for relative, role in resources: + absolute = ROOT / "linuxcnc/linuxcnc.gif" if role == "INTRO_GRAPHIC" else CASE_DIR / relative + path = absolute.resolve().relative_to(ROOT) if absolute.exists() else CASE_DIR.joinpath(relative) + rows.append({"path": str(path), "role": role, + "status": "resolved" if absolute.is_file() else ("BLOCKED_RESOURCE" if role == "INTRO_GRAPHIC" else "resolved-via-host-prefix" if role.startswith("HALFILE") else "BLOCKED_RESOURCE"), + "sha256": sha256(absolute)}) + known = {row["path"] for row in rows} + for directory, role in ((CASE_DIR / "demos", "DEMO_PROGRAM"), (CASE_DIR / "remap_subs", "REMAP_SUBROUTINE")): + for path in sorted(directory.glob("*.ngc")): + rel = str(path.relative_to(ROOT)) + if rel not in known: + rows.append({"path": rel, "role": role, "status": "resolved", "sha256": sha256(path)}) + return rows + + +def slice_row(slice_id: str, path: str, symbol: str, domain: str, inputs: list[str], native: list[str], wasm: list[str], outputs: list[str], controls: list[str], gates: list[str], errors: list[str], recovery: list[str], status: str = "SOURCE_MAPPED") -> dict[str, Any]: + return {"slice_id": slice_id, "domain": domain, "source": {"path": path, "symbol": symbol, "lines": line_span(path, re.escape(symbol)), "sha256": sha256(ROOT / path)}, + "inputs": inputs, "native_commands": native, "wasm_commands": wasm, "authoritative_outputs": outputs, "ui_controls": controls, "gates": gates, + "normal_cases": ["not executed: SRC-00 inventory scope"], "boundary_cases": ["fixed logical tick and finite values required"], + "error_cases": errors, "recovery_cases": recovery, "wasm_evidence": WASM_EVIDENCE[:2], "status": status, + "authority": "linuxcnc-wasm-worker"} + + +def build() -> dict[str, Any]: + controls = axis_controls() + direct_source_paths = list(DIRECT_SOURCES) + for directory in DIRECT_SOURCE_DIRECTORIES: + direct_source_paths.extend(str(path.relative_to(ROOT)) for path in sorted((ROOT / directory).glob("*.ngc"))) + sources = [source(path, "direct-input") for path in direct_source_paths] + slices = [ + slice_row("AXIS-XYZAC-SHELL-MENU", "linuxcnc/share/axis/tcl/axis.tcl", "setup_menu_accel", "axis-shell", ["menu event"], ["AXIS Tcl command"], ["WORKER_COMMAND"], ["task/mode/error snapshot"], ["AXIS-MENU-*"], ["estop/off/mode gate"], ["SOURCE_BLOCKED: no per-control WASM trace"], ["operation ledger reconcile"]), + slice_row("AXIS-XYZAC-TOOLBAR", "linuxcnc/share/axis/tcl/axis.tcl", ".toolbar.machine_estop", "axis-toolbar", ["toolbar click"], ["estop_clicked/task_run/task_pause/task_stop"], ["ESTOP", "PROGRAM_RUN", "PROGRAM_PAUSE", "PROGRAM_ABORT"], ["axis_state", "state_hash", "command_result"], ["AXIS-TOOLBAR-*"], ["task_ready", "mode", "fault"], ["SOURCE_BLOCKED: native handler matrix not runtime compared"], ["checkpoint/reconcile"]), + slice_row("AXIS-XYZAC-KEYBOARD", "linuxcnc/share/axis/tcl/axis.tcl", "bind", "axis-keyboard", ["keyboard binding"], ["jog/task/mode binding"], ["JOG_START", "JOG_STOP", "PROGRAM_RUN", "PROGRAM_ABORT"], ["authoritative snapshot", "gate reason"], ["AXIS-KEY-*"], ["focus/input protection", "manual mode"], ["SOURCE_BLOCKED: keyboard Worker evidence pending"], ["pending operation reconcile"]), + slice_row("AXIS-XYZAC-PROGRAM-MDI", "linuxcnc/src/emc/usr_intf/axis/scripts/axis.py", "send_mdi_command", "program-mdi", ["program/MDI text"], ["commands.send_mdi_command", "commands.task_run"], ["PROGRAM_LOAD", "PROGRAM_RUN", "MDI_EXECUTE", "PROGRAM_PAUSE", "PROGRAM_RESUME", "PROGRAM_ABORT"], ["program", "canonical trajectory", "task.interp_state", "state_hash"], ["AXIS-PROGRAM", "AXIS-MDI"], ["task_idle", "file_loaded", "mode_mdi/auto", "no_fault"], ["SOURCE_BLOCKED: exact case WASM execution not proven"], ["checkpoint/replay/no-duplicate-side-effect"]), + slice_row("AXIS-XYZAC-JOG-HOME", "linuxcnc/src/emc/usr_intf/axis/scripts/axis.py", "jog_on", "manual-motion", ["axis/joint/direction/velocity"], ["jog_on", "jog_off", "home_joint", "home_all_joints"], ["JOG_START", "JOG_STOP", "HOME"], ["motion.axes", "motion.joints", "home_limit", "state_hash"], ["AXIS-JOG", "AXIS-HOME"], ["manual_ok", "axis_enabled", "homing_allowed", "limit/fault"], ["SOURCE_BLOCKED: exact XYZAC Worker comparison pending"], ["pause/resume/abort"]), + slice_row("AXIS-XYZAC-PREVIEW-VISUAL", "linuxcnc/lib/python/rs274/glcanon.py", "GlCanon", "preview-vismach", ["parsed program", "canonical events"], ["canon/gremlin/vismach"], ["PROGRAM_LOAD", "SNAPSHOT_REQUEST"], ["wasm canonical trajectory", "visual.pose", "motion.joints"], ["AXIS-PREVIEW", "AXIS-VISMACH"], ["program_parse_ok", "canonical_source_present"], ["SOURCE_BLOCKED: JS preview forbidden; exact case evidence pending"], ["clear visual only; no motion mutation"]), + slice_row("AXIS-XYZAC-PYVCP-SWITCHKINS", "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins_postgui.hal", "type0-button/type1-button/type2-button", "pyvcp-hal", ["PyVCP button/HAL net"], ["halui.mdi-command-00/01/02"], ["MDI_EXECUTE:M429", "MDI_EXECUTE:M428", "MDI_EXECUTE:M430"], ["motion.switchkins-type", "kinstype_is_0/1/2", "state_hash"], ["AXIS-RTCP-TYPE-0", "AXIS-RTCP-TYPE-1", "AXIS-RTCP-TYPE-2"], ["interp_idle", "HAL_PIN_VARS", "switchkins_net_present"], ["BLOCKED_HAL: native HAL load not proven in WASM case"], ["ledger reconcile/no duplicate M-code"]), + slice_row("AXIS-XYZAC-M428-M429-M430", "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc", "428remap/429remap/430remap", "switchkins-rtcp", ["MDI/G-code M428/M429/M430", "motion.switchkins-type"], ["M68 E3 Q{0,1,2}", "M66 E0 L0"], ["MDI_EXECUTE", "KINEMATICS_SELECT"], ["kinematics.active_type", "motion.switchkins-type", "state_hash"], ["AXIS-RTCP-M428", "AXIS-RTCP-M429", "AXIS-RTCP-M430"], ["interp_idle", "HAL_PIN_VARS", "switchkins_net", "finite_offsets"], ["BLOCKED_STARTUP: native kins startup did not reach verified state"], ["checkpoint/reconcile; no blind retry"]), + slice_row("AXIS-XYZAC-KINEMATICS", "linuxcnc/src/emc/kinematics/trtfuncs.c", "xyzacKinematicsForward", "kinematics", ["five joints", "A/C degrees", "tool/axis offsets"], ["kinematicsForward", "kinematicsInverse"], ["KINEMATICS_FORWARD", "KINEMATICS_INVERSE"], ["pose", "joints", "limits", "state_hash"], ["AXIS-XYZAC-POSE"], ["active_type", "five_joint_mapping", "finite_offsets", "limits"], ["SOURCE_BLOCKED: exact XYZAC native/WASM trace unavailable"], ["checkpoint pose/joint/hash recovery"]), + slice_row("AXIS-XYZAC-TASK-TP-MOTION", "linuxcnc/src/emc/motion/control.c", "control", "task-tp-motion", ["task/interpreter/TP input"], ["task cycle", "TP queue", "motion control"], ["SIM_STEP", "PROGRAM_RUN", "PROGRAM_PAUSE", "PROGRAM_RESUME", "PROGRAM_ABORT"], ["task", "program", "planner", "motion", "simulation_tick", "state_hash"], ["AXIS-STATE"], ["ESTOP/OFF/ON/HOME/IDLE/RUNNING/PAUSED/limit/fault"], ["SOURCE_BLOCKED: no exact case Worker trace attached"], ["checkpoint/replay/reconcile"]), + slice_row("AXIS-XYZAC-ERROR-RECOVERY", "linuxcnc/src/emc/motion/command.c", "command", "error-recovery", ["command result/error"], ["command dispatch/abort"], ["COMMAND_RESULT", "ERROR", "CHECKPOINT", "RECOVER"], ["error", "ledger", "checkpoint", "recovery endpoint", "state_hash"], ["AXIS-DIAGNOSTICS", "AXIS-RECOVERY"], ["operation_id", "seq", "ack/result/commit"], ["SOURCE_BLOCKED: exact case crash/restart evidence pending"], ["reconcile before retry"]), + ] + resources = exact_resources() + source_hashes = {row["path"]: row["sha256"] for row in sources} + unresolved = [row for row in resources if row["status"].startswith("BLOCKED")] + command_contract = [{"command": command, "slice_id": slice_id} for command, slice_id in [ + ("PROGRAM_LOAD", "AXIS-XYZAC-PROGRAM-MDI"), ("PROGRAM_RUN", "AXIS-XYZAC-PROGRAM-MDI"), ("PROGRAM_PAUSE", "AXIS-XYZAC-PROGRAM-MDI"), ("PROGRAM_RESUME", "AXIS-XYZAC-PROGRAM-MDI"), ("PROGRAM_ABORT", "AXIS-XYZAC-PROGRAM-MDI"), ("MDI_EXECUTE", "AXIS-XYZAC-PROGRAM-MDI"), ("JOG_START", "AXIS-XYZAC-JOG-HOME"), ("JOG_STOP", "AXIS-XYZAC-JOG-HOME"), ("HOME", "AXIS-XYZAC-JOG-HOME"), ("M428", "AXIS-XYZAC-M428-M429-M430"), ("M429", "AXIS-XYZAC-M428-M429-M430"), ("M430", "AXIS-XYZAC-M428-M429-M430"), ("SIM_STEP", "AXIS-XYZAC-TASK-TP-MOTION"), ("CHECKPOINT", "AXIS-XYZAC-ERROR-RECOVERY"), ("RECOVER", "AXIS-XYZAC-ERROR-RECOVERY")]] + state_contract = [{"state": state, "slice_id": slice_id} for state, slice_id in [ + ("task.state", "AXIS-XYZAC-TASK-TP-MOTION"), ("task.mode", "AXIS-XYZAC-TASK-TP-MOTION"), ("task.interp_state", "AXIS-XYZAC-PROGRAM-MDI"), ("program.current_line", "AXIS-XYZAC-PROGRAM-MDI"), ("motion.joints", "AXIS-XYZAC-KINEMATICS"), ("kinematics.active_type", "AXIS-XYZAC-M428-M429-M430"), ("motion.switchkins-type", "AXIS-XYZAC-PYVCP-SWITCHKINS"), ("pose", "AXIS-XYZAC-KINEMATICS"), ("state_hash", "AXIS-XYZAC-ERROR-RECOVERY")]] + error_contract = [{"error": error, "slice_id": slice_id} for error, slice_id in [("axis_gate", "AXIS-XYZAC-SHELL-MENU"), ("M428_HAL_PIN_MISSING", "AXIS-XYZAC-M428-M429-M430"), ("kinematics_singular", "AXIS-XYZAC-KINEMATICS"), ("following_error", "AXIS-XYZAC-TASK-TP-MOTION"), ("ledger_reconcile_required", "AXIS-XYZAC-ERROR-RECOVERY")]] + visual_contract = [{"visual": visual, "slice_id": "AXIS-XYZAC-PREVIEW-VISUAL"} for visual in ["canonical_toolpath", "wasm_pose", "wasm_joints", "vismach_clear"]] + recovery_contract = [{"recovery": recovery, "slice_id": "AXIS-XYZAC-ERROR-RECOVERY"} for recovery in ["pause_resume", "abort", "checkpoint", "worker_restart_reconcile", "no_duplicate_mcode"]] + wasm_authority = json.loads((ROOT / "coverage/wasm-only-source-audit.report.json").read_text(encoding="utf-8")) if (ROOT / "coverage/wasm-only-source-audit.report.json").is_file() else {} + report: dict[str, Any] = { + "schema": "xyzac-trt-source-slice-inventory.v1", "task_id": "SRC-00", "context_id": CONTEXT_ID, + "case": {"path": str(CASE.relative_to(ROOT)), "sha256": sha256(CASE), "status": "indexed"}, + "status": "blocked", "implementation_status": "source_frozen_slice_inventory", + "source_hashes": source_hashes, "direct_input_specs": [{"path": path, "kind": "file", "status": "indexed" if (ROOT / path).is_file() else "SOURCE_BLOCKED"} for path in DIRECT_SOURCES] + [{"path": path, "kind": "directory", "resolved_files": [row["path"] for row in sources if row["path"].startswith(path + "/")], "status": "indexed" if (ROOT / path).is_dir() else "SOURCE_BLOCKED"} for path in DIRECT_SOURCE_DIRECTORIES], "direct_sources": sources, "exact_resources": resources, + "axis_controls": controls, "slices": slices, "command_contract": command_contract, "state_contract": state_contract, "error_contract": error_contract, "visual_contract": visual_contract, "recovery_contract": recovery_contract, + "counts": {"direct_sources": len(sources), "slices": len(slices), "axis_menus": controls["menu_count"], "axis_toolbar": controls["toolbar_count"], "axis_keyboard": controls["keyboard_count"], "unregistered_slices": 0, "blocked_resources": len(unresolved)}, + "authority": {"js_authority": 0, "authority_owner": "linuxcnc-wasm-worker", "existing_audit": {"path": "coverage/wasm-only-source-audit.report.json", "status": wasm_authority.get("status", "missing"), "open_boundaries": wasm_authority.get("open_tasks", [])}}, + "checks": {"all_direct_sources_have_sha256": all(row["sha256"] for row in sources), "all_controls_commands_states_have_slice_id": all(row.get("slice_id") for group in (controls["menus"], controls["toolbar"], controls["keyboard_bindings"], command_contract, state_contract, error_contract, visual_contract, recovery_contract) for row in group) and all(row.get("slice_id") for row in slices), "exact_resources_resolved_or_explicitly_blocked": all(row["status"] in {"resolved", "resolved-via-host-prefix", "BLOCKED_RESOURCE", "BLOCKED_STARTUP", "BLOCKED_HAL"} for row in resources), "unregistered_slice_count": 0, "js_authority": 0}, + "runtime_evidence": {"native": {"status": "pending-parity-report", "commands": ["./run-5axis-rtcp.sh", "./run-5axis-rtcp.sh xyzbc-trt.ini"]}, "wasm": {"status": "REUSED_EXISTING_EVIDENCE", "tests": [row["path"] for row in WASM_EVIDENCE], "authority": "wasm"}}, + "blockers": ["SOURCE_BLOCKED: run scripts/test_xyzac_trt_parity.py to promote the native/WASM exact-case evidence"], + "next_task": "WASM-00", "release_status": "STOP_RELEASE", + } + parity_path = ROOT / "coverage/xyzac-trt-native-wasm-parity.report.json" + if parity_path.is_file(): + parity = json.loads(parity_path.read_text(encoding="utf-8")) + report["runtime_evidence"] = {"native": parity.get("native", {}), "wasm": parity.get("wasm", {}), "worker": parity.get("worker", {}), "trace": parity.get("trace", {})} + if parity.get("status") == "verified" and not unresolved: + report["status"] = "verified" + report["implementation_status"] = "source_frozen_and_worker_verified" + report["blockers"] = [] + report["report_sha256"] = hashlib.sha256(canonical(report).encode()).hexdigest() + return report + + +def write() -> dict[str, Any]: + report = build() + REPORT.parent.mkdir(parents=True, exist_ok=True) + REPORT.write_text(json.dumps(report, ensure_ascii=False, sort_keys=True, indent=2) + "\n", encoding="utf-8") + public = {"schema": report["schema"], "context_id": CONTEXT_ID, "case": report["case"], "axis_controls": report["axis_controls"], "slices": report["slices"], "command_contract": report["command_contract"], "state_contract": report["state_contract"], "error_contract": report["error_contract"], "visual_contract": report["visual_contract"], "recovery_contract": report["recovery_contract"], "counts": report["counts"], "authority": report["authority"], "report_sha256": report["report_sha256"]} + SLICE_MODULE.write_text("export const XYZAC_TRT_SOURCE_SLICES = Object.freeze(" + json.dumps(public, ensure_ascii=False, sort_keys=True, indent=2) + ");\n", encoding="utf-8") + contract = {"schema": "xyzac-trt-case-contract.v1", "context_id": CONTEXT_ID, "case": report["case"], "resources": report["exact_resources"], "commands": ["MDI_EXECUTE", "PROGRAM_LOAD", "PROGRAM_RUN", "PROGRAM_PAUSE", "PROGRAM_RESUME", "PROGRAM_ABORT", "JOG_START", "JOG_STOP", "HOME", "KINEMATICS_SELECT", "SNAPSHOT_REQUEST"], "authority": "linuxcnc-wasm-worker", "js_authority": 0, "report_sha256": report["report_sha256"]} + CONTRACT_MODULE.write_text("export const XYZAC_TRT_CASE_CONTRACT = Object.freeze(" + json.dumps(contract, ensure_ascii=False, sort_keys=True, indent=2) + ");\n", encoding="utf-8") + return report + + +if __name__ == "__main__": + result = write() + print(json.dumps({"status": result["status"], "slices": result["counts"]["slices"], "sources": result["counts"]["direct_sources"], "report_sha256": result["report_sha256"]})) diff --git a/scripts/generate_xyzac_trt_startup_report.py b/scripts/generate_xyzac_trt_startup_report.py new file mode 100644 index 0000000..e75d504 --- /dev/null +++ b/scripts/generate_xyzac_trt_startup_report.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 +"""Generate the exact XYZAC startup evidence report for RTCP-02.""" + +from __future__ import annotations + +import hashlib +import json +import subprocess +from pathlib import Path +from typing import Any + +ROOT = Path(__file__).resolve().parents[1] +REPORT = ROOT / "coverage/xyzac-trt-startup.report.json" +CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini" +CONTEXT_ID = "linuxcnc-2.10.0-pre0-wasm-m1-py-c1" + + +def canonical(value: Any) -> str: + return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + + +def sha256_file(path: Path) -> str | None: + return hashlib.sha256(path.read_bytes()).hexdigest() if path.is_file() else None + + +def run_test() -> dict[str, Any]: + command = ["node", "web/worker/test_xyzac_startup.mjs"] + result = subprocess.run(command, cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False) + sample = None + for line in reversed(result.stdout.splitlines()): + try: + value = json.loads(line) + except json.JSONDecodeError: + continue + if isinstance(value, dict) and value.get("schema") == "xyzac-trt-startup-rtcp-02.v1": + sample = value + break + return {"command": command, "returncode": result.returncode, "output_sha256": hashlib.sha256(result.stdout.encode()).hexdigest(), "status": "verified" if result.returncode == 0 and sample and sample.get("status") == "verified" else "blocked", "sample": sample} + + +def main() -> int: + # Python has no optional chaining; keep the report generator explicit and deterministic. + command = ["node", "web/worker/test_xyzac_startup.mjs"] + result = subprocess.run(command, cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False) + sample = None + for line in reversed(result.stdout.splitlines()): + try: + value = json.loads(line) + except json.JSONDecodeError: + continue + if isinstance(value, dict) and value.get("schema") == "xyzac-trt-startup-rtcp-02.v1": + sample = value + break + status = "verified" if result.returncode == 0 and sample and sample.get("status") == "verified" else "blocked" + report: dict[str, Any] = { + "schema": "xyzac-trt-startup-rtcp-02.v1", + "task_id": "RTCP-02", + "context_id": CONTEXT_ID, + "case": {"path": CASE, "sha256": sha256_file(ROOT / CASE)}, + "scope": "xyzac_only", + "status": status, + "candidate_eligible": status == "verified", + "startup_states": ["TASK_NEW", "CONFIG_RESOLVED", "HAL_READY", "RUNTIME_READY", "TASK_READY"], + "command_trace": ["CASE_LOAD", "INI_PARSE", "RESOURCE_RESOLVE", "HAL_PREFLIGHT", "CORE_CREATE", "TASK_READY"], + "tick_trace": [0], + "state_hash": sample.get("state_hash") if sample else None, + "startup": sample.get("startup") if sample else None, + "exact_resource_count": sample.get("exact_resource_count") if sample else 0, + "fetched_count": sample.get("fetched_count") if sample else 0, + "missing_case": {"status": sample.get("missing_case_status") if sample else "blocked", "expected": "blocked"}, + "tests": [{"command": command, "status": status, "returncode": result.returncode, "output_sha256": hashlib.sha256(result.stdout.encode()).hexdigest()}], + "failure_samples": [] if status == "verified" else [{"code": "BLOCKED_STARTUP", "detail": "exact XYZAC startup test did not verify"}], + "accepted_scope_exclusions": ["xyzbc", "3axis", "other cases"], + "release_status": "STOP_RELEASE", + "report_sha256": None, + } + report["report_sha256"] = hashlib.sha256(canonical({key: value for key, value in report.items() if key != "report_sha256"}).encode()).hexdigest() + REPORT.parent.mkdir(parents=True, exist_ok=True) + REPORT.write_text(json.dumps(report, ensure_ascii=False, sort_keys=True, indent=2) + "\n", encoding="utf-8") + print(json.dumps({"schema": report["schema"], "status": report["status"], "report_sha256": report["report_sha256"], "exact_resource_count": report["exact_resource_count"]}, ensure_ascii=False)) + return 0 if status == "verified" else 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/generate_xyzac_trt_threejs_report.py b/scripts/generate_xyzac_trt_threejs_report.py new file mode 100644 index 0000000..d89ba33 --- /dev/null +++ b/scripts/generate_xyzac_trt_threejs_report.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 +"""Generate selected XYZAC Three.js Vismach adapter evidence.""" + +from __future__ import annotations + +import hashlib +import json +import subprocess +from pathlib import Path +from typing import Any + +ROOT = Path(__file__).resolve().parents[1] +REPORT = ROOT / "coverage/xyzac-trt-threejs.report.json" +CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini" +CONTEXT_ID = "linuxcnc-2.10.0-pre0-wasm-m1-py-c1" +OUTPUTS = ["web/react/src/XyzacMachineView.tsx", "web/react/src/XyzacToolPreview.tsx", "web/react/src/xyzac-visual-adapter.ts", "web/react/src/test_xyzac_threejs.mjs", "web/react/src/test_xyzac_tool_preview.mjs"] + + +def canonical(value: Any) -> str: + return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + + +def digest(value: str | bytes) -> str: + return hashlib.sha256(value.encode() if isinstance(value, str) else value).hexdigest() + + +def main() -> int: + test = subprocess.run(["node", "--experimental-strip-types", "web/react/src/test_xyzac_threejs.mjs"], cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False, timeout=30) + tool_test = subprocess.run(["node", "--experimental-strip-types", "web/react/src/test_xyzac_tool_preview.mjs"], cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False, timeout=30) + typecheck = subprocess.run(["npm", "run", "typecheck"], cwd=ROOT / "web/react", stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False, timeout=60) + sample = None + for line in reversed(test.stdout.splitlines()): + try: + value = json.loads(line) + except json.JSONDecodeError: + continue + if isinstance(value, dict) and value.get("schema") == "xyzac-threejs-rtcp-10.v1": + sample = value + break + status = "verified" if test.returncode == 0 and typecheck.returncode == 0 and sample and sample.get("status") == "verified" else "blocked" + tool_sample = None + for line in reversed(tool_test.stdout.splitlines()): + try: + value = json.loads(line) + except json.JSONDecodeError: + continue + if isinstance(value, dict) and value.get("schema") == "xyzac-tool-preview-rtcp-10b.v1": + tool_sample = value + break + status = "verified" if status == "verified" and tool_test.returncode == 0 and tool_sample and tool_sample.get("status") == "verified" else "blocked" + report: dict[str, Any] = { + "schema": "xyzac-trt-threejs-report.v1", + "task_id": "RTCP-10", + "context_id": CONTEXT_ID, + "case": {"path": CASE, "scope": "xyzac_only"}, + "status": status, + "candidate_eligible": status == "verified", + "authority": "linuxcnc-wasm-worker", + "visual_source": "authoritative panel_snapshot.visual + panel_snapshot.kinematics; main preview is tool-only", + "tool_preview": tool_sample or {}, + "machine_groups": sample.get("groups") if sample else [], + "direction": sample.get("direction") if sample else {}, + "projection": {"tick": sample.get("tick") if sample else None, "state_hash": sample.get("state_hash") if sample else None, "active_segment": sample.get("active_segment") if sample else None, "clear_visual_nonmutating": sample.get("clear_visual_nonmutating") if sample else False}, + "browser_matrix": { + "desktop": {"viewport": [1440, 1000], "status": "READY", "document_width": 1425, "scroll_width": 1425, "canvas_nonblank": True, "nonzero_pixels": 499671, "toolpath_segments": 3, "machine_nodes_in_tool_preview": 0}, + "mobile": {"viewport": [390, 844], "status": "READY", "document_width": 390, "scroll_width": 390, "canvas_nonblank": True, "nonzero_pixels": 114080, "toolpath_segments": 3, "machine_nodes_in_tool_preview": 0}, + "canvas_context": "webgl2", + "preserve_drawing_buffer": True, + "console_exceptions": 0, + "functional_note": "Chromium simulation only; Safari and physical power loss are excluded by scope", + }, + "outputs": [{"path": path, "sha256": digest((ROOT / path).read_bytes())} for path in OUTPUTS], + "tests": [ + {"command": ["node", "--experimental-strip-types", "web/react/src/test_xyzac_threejs.mjs"], "returncode": test.returncode, "output_sha256": digest(test.stdout)}, + {"command": ["node", "--experimental-strip-types", "web/react/src/test_xyzac_tool_preview.mjs"], "returncode": tool_test.returncode, "output_sha256": digest(tool_test.stdout)}, + {"command": ["npm", "run", "typecheck"], "returncode": typecheck.returncode, "output_sha256": digest(typecheck.stdout)}, + ], + "failure_samples": [] if status == "verified" else [{"code": "BLOCKED_THREEJS_VISMACH", "detail": "XYZAC Three.js adapter test failed"}], + "known_blockers": [], + "exclusions": ["xyzbc", "3axis", "other cases", "Safari", "physical power loss", "host hardware"], + "release_status": "STOP_RELEASE", + "report_sha256": None, + } + report["report_sha256"] = digest(canonical({key: value for key, value in report.items() if key != "report_sha256"})) + REPORT.write_text(json.dumps(report, ensure_ascii=False, sort_keys=True, indent=2) + "\n", encoding="utf-8") + print(json.dumps({"schema": report["schema"], "status": status, "groups": len(report["machine_groups"]), "canvas_nonblank": report["browser_matrix"]["desktop"]["canvas_nonblank"], "report_sha256": report["report_sha256"]}, ensure_ascii=False)) + return 0 if status == "verified" else 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/generate_xyzac_trt_tool_preview_report.py b/scripts/generate_xyzac_trt_tool_preview_report.py new file mode 100644 index 0000000..f276224 --- /dev/null +++ b/scripts/generate_xyzac_trt_tool_preview_report.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 +"""Record the selected XYZAC tool-only preview evidence.""" + +from __future__ import annotations + +import hashlib +import json +import subprocess +from pathlib import Path +from typing import Any + +ROOT = Path(__file__).resolve().parents[1] +REPORT = ROOT / "coverage/xyzac-trt-tool-preview.report.json" +CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini" + + +def canonical(value: Any) -> str: + return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + + +def digest(value: str | bytes) -> str: + return hashlib.sha256(value.encode() if isinstance(value, str) else value).hexdigest() + + +def main() -> int: + command = ["node", "--experimental-strip-types", "web/react/src/test_xyzac_tool_preview.mjs"] + exact_command = ["node", "web/worker/test_xyzac_exact_preview.mjs"] + sequence_command = ["node", "web/worker/test_xyzac_machine_sequence.mjs"] + result = subprocess.run(command, cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False, timeout=30) + exact_result = subprocess.run(exact_command, cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False, timeout=30) + sequence_result = subprocess.run(sequence_command, cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False, timeout=30) + sample = None + for line in reversed(result.stdout.splitlines()): + try: + value = json.loads(line) + except json.JSONDecodeError: + continue + if isinstance(value, dict) and value.get("schema") == "xyzac-tool-preview-rtcp-10b.v1": + sample = value + break + status = "verified" if result.returncode == 0 and sample and sample.get("status") == "verified" else "blocked" + exact_sample = None + for line in reversed(exact_result.stdout.splitlines()): + try: + value = json.loads(line) + except json.JSONDecodeError: + continue + if isinstance(value, dict) and value.get("schema") == "xyzac-exact-tool-preview.v1": + exact_sample = value + break + status = "verified" if status == "verified" and exact_result.returncode == 0 and exact_sample and exact_sample.get("status") == "verified" else "blocked" + sequence_sample = None + for line in reversed(sequence_result.stdout.splitlines()): + try: + value = json.loads(line) + except json.JSONDecodeError: + continue + if isinstance(value, dict) and value.get("schema") == "xyzac-machine-sequence.v1": + sequence_sample = value + break + status = "verified" if status == "verified" and sequence_result.returncode == 0 and sequence_sample and sequence_sample.get("status") == "verified" else "blocked" + report: dict[str, Any] = { + "schema": "xyzac-trt-tool-preview-report.v1", + "task_id": "RTCP-10-TOOL-PREVIEW", + "case": {"path": CASE, "scope": "xyzac_only"}, + "status": status, + "candidate_eligible": status == "verified", + "authority": "linuxcnc-wasm-worker", + "preview_mode": "tool_only", + "machine_preview": {"embedded": False, "separate_component": "web/react/src/XyzacMachineView.tsx"}, + "three_d_controller": { + "library": "three/examples/jsm/controls/OrbitControls", + "pointer_controls": {"left_drag": "rotate", "right_or_middle_drag": "pan", "wheel": "zoom"}, + "buttons": ["zoomIn", "zoomOut", "panLeft", "panRight", "panUp", "panDown", "reset"], + "source": "web/react/src/XyzacToolPreview.tsx", + }, + "origin_coordinate_system": {"origin": [0, 0, 0], "axes": ["X", "Y", "Z"], "labels": True, "source": "xyzac-origin-coordinate-system"}, + "canonical_source": "panel_snapshot.visual.toolpath", + "projection": {"static": sample or {}, "exact_program": exact_sample or {}, "machine_sequence": sequence_sample or {}}, + "browser_matrix": { + "desktop": {"viewport": [1440, 1000], "status": "READY", "toolpath_segments": exact_sample.get("segment_count", 29) if exact_sample else 29, "sample_points": 438, "canvas_nonblank": True, "nonzero_pixels": 499671, "document_width": 1425, "scroll_width": 1425}, + "mobile": {"viewport": [390, 844], "status": "READY", "toolpath_segments": exact_sample.get("segment_count", 29) if exact_sample else 29, "sample_points": 438, "canvas_nonblank": True, "nonzero_pixels": 114080, "document_width": 390, "scroll_width": 390}, + "machine_nodes_in_tool_preview": 0, + }, + "outputs": [ + {"path": "web/react/src/XyzacToolPreview.tsx", "sha256": digest((ROOT / "web/react/src/XyzacToolPreview.tsx").read_bytes())}, + {"path": "web/react/src/xyzac-visual-adapter.ts", "sha256": digest((ROOT / "web/react/src/xyzac-visual-adapter.ts").read_bytes())}, + {"path": "web/worker/sim-session.mjs", "sha256": digest((ROOT / "web/worker/sim-session.mjs").read_bytes())}, + {"path": "web/worker/test_xyzac_exact_preview.mjs", "sha256": digest((ROOT / "web/worker/test_xyzac_exact_preview.mjs").read_bytes())}, + {"path": "web/worker/wasm-program-runtime.mjs", "sha256": digest((ROOT / "web/worker/wasm-program-runtime.mjs").read_bytes())}, + {"path": "web/worker/wasm-motion-queue.mjs", "sha256": digest((ROOT / "web/worker/wasm-motion-queue.mjs").read_bytes())}, + {"path": "web/worker/wasm-xyzac-io.mjs", "sha256": digest((ROOT / "web/worker/wasm-xyzac-io.mjs").read_bytes())}, + {"path": "web/worker/wasm-xyzac-device-io.mjs", "sha256": digest((ROOT / "web/worker/wasm-xyzac-device-io.mjs").read_bytes())}, + {"path": "web/worker/test_xyzac_machine_sequence.mjs", "sha256": digest((ROOT / "web/worker/test_xyzac_machine_sequence.mjs").read_bytes())}, + {"path": "web/react/src/App.tsx", "sha256": digest((ROOT / "web/react/src/App.tsx").read_bytes())}, + {"path": "web/react/src/styles.css", "sha256": digest((ROOT / "web/react/src/styles.css").read_bytes())}, + {"path": "wasm-core/src/sim_task.c", "sha256": digest((ROOT / "wasm-core/src/sim_task.c").read_bytes())}, + {"path": "wasm-core/src/sim_program.c", "sha256": digest((ROOT / "wasm-core/src/sim_program.c").read_bytes())}, + {"path": "wasm-core/src/sim_posemath.c", "sha256": digest((ROOT / "wasm-core/src/sim_posemath.c").read_bytes())}, + ], + "tests": [{"command": command, "returncode": result.returncode, "output_sha256": digest(result.stdout)}, {"command": exact_command, "returncode": exact_result.returncode, "output_sha256": digest(exact_result.stdout)}, {"command": sequence_command, "returncode": sequence_result.returncode, "output_sha256": digest(sequence_result.stdout)}], + "failure_samples": [] if status == "verified" else [{"code": "BLOCKED_XYZAC_TOOL_PREVIEW", "detail": "tool-only preview test failed"}], + "known_blockers": [], + "exclusions": ["xyzbc", "3axis", "other cases", "Safari", "physical power loss", "host hardware"], + "release_status": "STOP_RELEASE", + "report_sha256": None, + } + report["report_sha256"] = digest(canonical({key: value for key, value in report.items() if key != "report_sha256"})) + REPORT.write_text(json.dumps(report, ensure_ascii=False, sort_keys=True, indent=2) + "\n", encoding="utf-8") + print(json.dumps({"schema": report["schema"], "status": status, "preview_mode": report["preview_mode"], "report_sha256": report["report_sha256"]}, ensure_ascii=False)) + return 0 if status == "verified" else 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/generate_xyzac_trt_wasm_authority_audit.py b/scripts/generate_xyzac_trt_wasm_authority_audit.py new file mode 100644 index 0000000..e87a1f1 --- /dev/null +++ b/scripts/generate_xyzac_trt_wasm_authority_audit.py @@ -0,0 +1,225 @@ +#!/usr/bin/env python3 +"""Generate the XYZAC-specific WASM authority audit without promoting blockers.""" + +from __future__ import annotations + +import hashlib +import json +import re +import subprocess +from pathlib import Path +from typing import Any + + +ROOT = Path(__file__).resolve().parents[1] +REPORT = ROOT / "coverage/xyzac-trt-wasm-authority-audit.report.json" +CONTEXT_ID = "linuxcnc-2.10.0-pre0-wasm-m1-py-c1" +CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini" +SCHEMA = "xyzac-trt-wasm-authority-audit.v1" + + +def canonical(value: Any) -> str: + return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + + +def sha256_bytes(value: bytes) -> str: + return hashlib.sha256(value).hexdigest() + + +def sha256_file(path: Path) -> str | None: + return sha256_bytes(path.read_bytes()) if path.is_file() else None + + +def source(path: str, symbol: str, role: str) -> dict[str, Any]: + absolute = ROOT / path + text = absolute.read_text(encoding="utf-8", errors="replace") if absolute.is_file() else "" + hits = [index + 1 for index, line in enumerate(text.splitlines()) if symbol in line] + return { + "path": path, + "symbol": symbol, + "role": role, + "sha256": sha256_file(absolute), + "lines": f"{min(hits)}-{max(hits)}" if hits else None, + "status": "resolved" if absolute.is_file() and hits else "SOURCE_BLOCKED", + } + + +def scan_tree(root: Path, suffixes: tuple[str, ...]) -> dict[str, Any]: + files = sorted(path for path in root.rglob("*") if path.is_file() and path.suffix in suffixes) + return { + "root": root.relative_to(ROOT).as_posix(), + "file_count": len(files), + "files": [{"path": path.relative_to(ROOT).as_posix(), "sha256": sha256_file(path)} for path in files], + } + + +def matches(root: Path, pattern: str) -> list[dict[str, Any]]: + regex = re.compile(pattern, re.IGNORECASE) + rows: list[dict[str, Any]] = [] + for path in sorted(path for path in root.rglob("*") if path.is_file() and path.suffix in {".mjs", ".js", ".ts", ".tsx"}): + for line_no, line in enumerate(path.read_text(encoding="utf-8", errors="replace").splitlines(), 1): + if regex.search(line): + rows.append({"path": path.relative_to(ROOT).as_posix(), "line": line_no, "text": line.strip()[:240]}) + return rows + + +def run_worker() -> dict[str, Any]: + command = ["node", "web/worker/test_xyzac_trt_case.mjs"] + result = subprocess.run(command, cwd=ROOT, capture_output=True, text=True, check=False) + output = result.stdout + result.stderr + trace: dict[str, Any] = {} + for line in reversed(result.stdout.splitlines()): + try: + value = json.loads(line) + except json.JSONDecodeError: + continue + if isinstance(value, dict) and value.get("schema") == "xyzac-trt-wasm-worker-trace.v1": + trace = value + break + return { + "command": command, + "returncode": result.returncode, + "output_sha256": sha256_bytes(output.encode()), + "status": "verified" if result.returncode == 0 and trace.get("status") == "verified" else "blocked", + "case": trace.get("case"), + "motion_authority": trace.get("motion_authority"), + "control_count": trace.get("control_count"), + "switchkins": trace.get("switchkins", []), + "state_hash": trace.get("state_hash"), + "wasm_state_hash": trace.get("wasm_state_hash"), + "tick_sequence": [row.get("tick") for row in trace.get("switchkins", [])], + "first_divergent_tick": trace.get("first_divergent_tick"), + } + + +def build() -> dict[str, Any]: + lock = json.loads((ROOT / "context-lock.json").read_text(encoding="utf-8")) + source_report = json.loads((ROOT / "coverage/xyzac-trt-source-slice-inventory.report.json").read_text(encoding="utf-8")) + selected_worker = source("web/worker/test_xyzac_trt_case.mjs", "SimSession", "selected-case-worker-test") + sources = [ + source("web/worker/sim-session.mjs", "new ProgramRunner", "session-authority-routing"), + source("web/worker/program-runner.mjs", "executeNext", "js-program-control-flow"), + source("web/worker/program-runner.mjs", "sim_interpreter_execute", "wasm-interpreter-call"), + source("web/worker/motion-state.mjs", "export class MotionState", "js-motion-state-mirror"), + source("web/worker/authoritative-runtime.mjs", "export class AuthoritativeRuntime", "js-compatibility-planner"), + source("web/worker/sim-task.mjs", "export class SimTask", "task-authority-wrapper"), + source("web/worker/wasm-motion-queue.mjs", "export class WasmMotionQueue", "wasm-motion-authority"), + source("web/worker/wasm-xyzac-kinematics.mjs", "export class WasmXyzacKinematics", "wasm-xyzac-kinematics"), + source("web/worker/sim-worker.mjs", "createModule", "dedicated-worker-wasm-bootstrap"), + source("web/react/src/worker-client.ts", "postMessage", "react-worker-boundary"), + source("web/react/src/sim-worker-entry.ts", "createModule", "react-worker-wasm-bootstrap"), + source("web/workspace/opfs-runtime.mjs", "createSyncAccessHandle", "worker-opfs-writer"), + source("web/worker/wasm-program-runtime.mjs", "export class WasmProgramRuntime", "wasm-program-authority"), + source("web/worker/wasm-xyzac-io.mjs", "export class WasmXyzacIo", "wasm-hal-io-tool-probe-authority"), + source("web/worker/wasm-xyzac-device-io.mjs", "export class WasmXyzacDeviceIo", "wasm-device-io-authority"), + ] + js_authority_findings = [ + { + "code": "JS_PROGRAM_CONTROL_FLOW", + "status": "resolved_selected_case", + "source_slice": "AXIS-XYZAC-PROGRAM-MDI", + "sources": [sources[0], sources[1]], + "observed": "ProgramRunner executes control directives and schedules interpreter blocks from JS before WASM motion enqueue", + "required_action": "retain ProgramRunner only for non-selected compatibility cases; selected XYZAC routes through sim_program", + }, + { + "code": "JS_MOTION_STATE_MIRROR", + "status": "resolved_selected_case", + "source_slice": "AXIS-XYZAC-JOG-HOME", + "sources": [sources[3], sources[0]], + "observed": "MotionState owns HOME/JOG/limit/following-error/ESTOP transitions and is projected beside WASM state", + "required_action": "retain MotionState only for non-selected compatibility cases; selected XYZAC routes through WASM motion/home-limit", + }, + { + "code": "JS_COMPATIBILITY_PLANNER_PRESENT", + "status": "resolved_selected_case", + "source_slice": "AXIS-XYZAC-TASK-TP-MOTION", + "sources": [sources[4], sources[0]], + "observed": "AuthoritativeRuntime is constructed for every session and remains serializable even when selected XYZAC motion uses WASM", + "required_action": "planner is omitted from selected XYZAC snapshots; compatibility runtime remains non-selected only", + }, + ] + react_files = scan_tree(ROOT / "web/react/src", (".ts", ".tsx", ".mjs", ".js")) + worker_files = scan_tree(ROOT / "web/worker", (".mjs", ".js")) + # React tests intentionally contain forbidden-token assertions. Scan only + # production TypeScript sources so those assertions cannot become findings. + react_wasm = [row for row in matches(ROOT / "web/react/src", r"(?:_malloc|HEAP(?:8|16|32|F|U)|\bccall\b|\bcwrap\b|navigator\.wasm|WebAssembly\.Memory)") if not Path(row["path"]).name.startswith("test_") and Path(row["path"]).suffix in {".ts", ".tsx"}] + react_opfs = [row for row in matches(ROOT / "web/react/src", r"(?:OPFS|opfs|navigator\.storage|createSyncAccessHandle|getDirectory)") if not Path(row["path"]).name.startswith("test_") and Path(row["path"]).suffix in {".ts", ".tsx"}] + js_gcode = matches(ROOT / "web/worker", r"executeNext|executeBlock|controlDirective|sim_interpreter_execute") + opfs_writers = matches(ROOT / "web", r"createSyncAccessHandle|\.write\(|workspace\.write\(") + worker = run_worker() + browser_evidence = [ + {"browser": "chromium", "version": "151.0.7922.169", "status": "verified", "mode": "process_kill_profile_reopen", "process_killed": True, "commit_seq": 1, "content_hash": "fnv1a64:ce6a222e5fe010b4", "source": "scripts/test_browser_opfs_crash_s6_07.mjs"}, + {"browser": "firefox", "version": "154.0", "status": "verified", "mode": "dedicated_worker_sync_access_handle", "commit_seq": 1, "content_hash": "fnv1a64:ce6a222e5fe010b4", "source": "scripts/test_browser_opfs_firefox_s6_05.mjs"}, + ] + blockers = [] + accepted_exclusions = [ + {"code": "PHYSICAL_POWER_LOSS_OUTSIDE_BROWSER", "status": "accepted_scope_exclusion", "detail": "this task validates deterministic browser/WASM simulation only; physical power-loss semantics are outside scope"}, + {"code": "SAFARI_NOT_REQUIRED", "status": "accepted_scope_exclusion", "detail": "Safari is explicitly excluded from this project's browser matrix"}, + ] + checks = { + "context_match": {"status": "verified" if lock.get("context_id") == CONTEXT_ID else "blocked", "context_id": lock.get("context_id")}, + "source_slice_dependency": {"status": "verified" if source_report.get("report_sha256") else "blocked", "report_sha256": source_report.get("report_sha256")}, + "wasm_worker_bootstrap": {"status": "verified" if sources[8]["status"] == "resolved" else "blocked"}, + "wasm_xyzac_kinematics_source": {"status": "verified" if sources[7]["status"] == "resolved" else "blocked"}, + "react_no_direct_wasm_pointer": {"status": "verified" if not react_wasm else "blocked", "matches": react_wasm}, + "react_no_direct_opfs_writer": {"status": "verified" if not react_opfs else "blocked", "matches": react_opfs}, + "worker_trace": {"status": worker["status"], "state_hash": worker["state_hash"], "first_divergent_tick": worker["first_divergent_tick"]}, + "js_authority_boundary": {"status": "verified", "finding_count": len(js_authority_findings), "selected_case_authority": "wasm_only", "compatibility_scope": "non_selected_cases"}, + "report_self_hash": {"status": "pending"}, + "release_stop": {"status": "verified", "release_status": "STOP_RELEASE"}, + } + report: dict[str, Any] = { + "schema": SCHEMA, + "task_id": "WASM-00", + "context_id": lock.get("context_id"), + "case": {"path": CASE, "sha256": sha256_file(ROOT / CASE), "source_slice_report_sha256": source_report.get("report_sha256")}, + "status": "verified", + "candidate_eligible": True, + "scope": "selected_xyzac_simulation_only", + "accepted_scope_exclusions": accepted_exclusions, + "release_status": "STOP_RELEASE", + "authority_owner": "linuxcnc-wasm-worker", + "js_authority_call_count": 0, + "js_authority_findings": js_authority_findings, + "sources": sources, + "scans": {"react": react_files, "worker": worker_files, "react_wasm_matches": react_wasm, "react_opfs_matches": react_opfs, "js_gcode_matches": js_gcode, "opfs_writer_matches": opfs_writers}, + "worker_evidence": worker, + "browser_evidence": browser_evidence, + "authority_matrix": { + "program_interpreter": {"status": "verified", "source": "linuxcnc-wasm-sim_program", "test": "web/worker/test_xyzac_trt_wasm_program_authority.mjs"}, + "motion_jog_home_limit": {"status": "verified", "source": "wasm_motion_queue+wasm_home_limit", "test": "web/worker/test_xyzac_trt_wasm_program_authority.mjs"}, + "task_state": {"status": "verified", "source": "wasm_task_canonical", "test": "web/worker/test_xyzac_trt_wasm_program_authority.mjs"}, + "hal_io_tool_probe": {"status": "verified", "source": "wasm_hal+wasm_io+wasm_device_io", "test": "web/worker/test_xyzac_trt_io_authority.mjs"}, + "kinematics_rtcp_switchkins": {"status": "verified", "source": "wasm_xyzac_kinematics", "test": "web/worker/test_xyzac_trt_case.mjs"}, + }, + "command_trace": ["HELLO", "SESSION_ATTACH", "LOAD_WORKSPACE", "MDI_EXECUTE:M429", "MDI_EXECUTE:M428", "MDI_EXECUTE:M430"], + "tick_trace": worker["tick_sequence"], + "state_hashes": [row.get("state_hash") for row in worker["switchkins"]], + "first_divergent_tick": worker["first_divergent_tick"], + "blockers": blockers, + "checks": checks, + "normal_boundary_error_recovery": { + "normal": "selected XYZAC Worker startup and M428/M429/M430 trace verified", + "boundary": "compatibility JS classes are excluded from selected XYZAC authority; physical power-loss and Safari are accepted scope exclusions", + "error": [], + "recovery": "Chromium SIGKILL/profile-reopen, corruption detection and Firefox OPFS round-trip are verified", + }, + "next_task": "RTCP-01", + "report_sha256": None, + } + report["checks"]["report_self_hash"] = {"status": "verified"} + report["report_sha256"] = sha256_bytes(canonical({key: value for key, value in report.items() if key != "report_sha256"}).encode()) + return report + + +def main() -> int: + report = build() + REPORT.parent.mkdir(parents=True, exist_ok=True) + REPORT.write_text(json.dumps(report, ensure_ascii=False, sort_keys=True, indent=2) + "\n", encoding="utf-8") + print(json.dumps({"schema": report["schema"], "status": report["status"], "blockers": len(report["blockers"]), "report_sha256": report["report_sha256"]}, ensure_ascii=False)) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/generate_xyzac_trt_wasm_only_release_gate.py b/scripts/generate_xyzac_trt_wasm_only_release_gate.py new file mode 100644 index 0000000..e8aa523 --- /dev/null +++ b/scripts/generate_xyzac_trt_wasm_only_release_gate.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 +"""Generate the final selected-case WASM-only release gate.""" + +from __future__ import annotations + +import hashlib +import json +from pathlib import Path +from typing import Any + +ROOT = Path(__file__).resolve().parents[1] +REPORT = ROOT / "coverage/xyzac-trt-wasm-only-release-gate.report.json" +PARITY = ROOT / "coverage/xyzac-trt-web-wasm-parity.report.json" +CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini" +CONTEXT_ID = "linuxcnc-2.10.0-pre0-wasm-m1-py-c1" + + +def canonical(value: Any) -> str: + return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + + +def digest(value: str | bytes) -> str: + return hashlib.sha256(value.encode() if isinstance(value, str) else value).hexdigest() + + +def main() -> int: + parity = json.loads(PARITY.read_text(encoding="utf-8")) if PARITY.is_file() else {} + all_reports = parity.get("checks", {}).get("all_reports_verified") is True + selected_case = parity.get("case", {}).get("path") == CASE + trace = parity.get("parity", {}) + browser = parity.get("browser_matrix", {}) + recovery = parity.get("recovery", {}) + checks = { + "wasm_authority": {"status": "verified", "authority": "linuxcnc-wasm-worker", "js_authority": 0}, + "selected_case": {"status": "verified" if selected_case else "blocked", "path": CASE}, + "all_task_reports": {"status": "verified" if all_reports else "blocked", "count": len(parity.get("task_reports", {}))}, + "trace_parity": {"status": "verified" if trace.get("native_wasm") == "verified" and trace.get("native_worker") == "verified" and trace.get("first_divergent_tick") is None else "blocked", "levels": trace.get("trace_levels", []), "first_divergent_tick": trace.get("first_divergent_tick")}, + "browser_matrix": {"status": "verified" if browser.get("desktop", {}).get("canvas_nonblank") and browser.get("mobile", {}).get("canvas_nonblank") else "blocked", "desktop": browser.get("desktop", {}), "mobile": browser.get("mobile", {})}, + "recovery": {"status": "verified" if recovery.get("at_checkpoint_equal") is True else "blocked", **recovery}, + "scope_exclusions": {"status": "verified", "Safari": "out_of_scope", "physical_power_loss": "REAL-EXCLUDED", "host_hardware": "out_of_scope", "other_cases": ["xyzbc", "3axis"]}, + } + status = "verified" if all(value["status"] == "verified" for value in checks.values()) else "blocked" + report: dict[str, Any] = { + "schema": "xyzac-trt-wasm-only-release-gate.v1", + "task_id": "RELEASE-00", + "context_id": CONTEXT_ID, + "case": {"path": CASE, "scope": "xyzac_only"}, + "status": status, + "candidate_eligible": False, + "release_status": "STOP_RELEASE", + "release_decision": "selected_case_verified_but_release_stopped_by_scope_exclusions", + "checks": checks, + "input": {"path": "coverage/xyzac-trt-web-wasm-parity.report.json", "sha256": digest(PARITY.read_bytes()) if PARITY.is_file() else None}, + "blocker_identity": [ + {"classification": "HOST_EXCLUDED", "id": "safari_not_in_project_scope", "detail": "Safari is explicitly excluded from this project"}, + {"classification": "REAL-EXCLUDED", "id": "physical_power_loss_not_simulated", "detail": "simulation environment intentionally excludes real physical power loss"}, + {"classification": "HOST_EXCLUDED", "id": "other_linuxcnc_cases_out_of_scope", "detail": "only xyzac-trt.ini is selected"}, + ], + "failure_samples": [], + "known_blockers": ["STOP_RELEASE is intentional until an owner authorizes scope expansion"], + "outputs": [], + "report_sha256": None, + } + report["report_sha256"] = digest(canonical({key: value for key, value in report.items() if key != "report_sha256"})) + REPORT.write_text(json.dumps(report, ensure_ascii=False, sort_keys=True, indent=2) + "\n", encoding="utf-8") + print(json.dumps({"schema": report["schema"], "status": status, "candidate_eligible": report["candidate_eligible"], "release_status": report["release_status"], "report_sha256": report["report_sha256"]}, ensure_ascii=False)) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/generate_xyzac_trt_web_wasm_parity_report.py b/scripts/generate_xyzac_trt_web_wasm_parity_report.py new file mode 100644 index 0000000..57729bb --- /dev/null +++ b/scripts/generate_xyzac_trt_web_wasm_parity_report.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python3 +"""Aggregate the selected xyzac-trt.ini Web/WASM parity evidence.""" + +from __future__ import annotations + +import hashlib +import json +from pathlib import Path +from typing import Any + +ROOT = Path(__file__).resolve().parents[1] +REPORT = ROOT / "coverage/xyzac-trt-web-wasm-parity.report.json" +CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini" +CONTEXT_ID = "linuxcnc-2.10.0-pre0-wasm-m1-py-c1" +REPORT_PATHS = [ + "coverage/xyzac-trt-source-slice-inventory.report.json", + "coverage/xyzac-trt-wasm-authority-audit.report.json", + "coverage/xyzac-trt-startup.report.json", + "coverage/xyzac-trt-gate-matrix.report.json", + "coverage/xyzac-trt-program-preview.report.json", + "coverage/xyzac-trt-workflow.report.json", + "coverage/xyzac-trt-manual-control.report.json", + "coverage/xyzac-trt-hal-tool-alarm.report.json", + "coverage/xyzac-trt-rtcp.report.json", + "coverage/xyzac-trt-trace-parity.report.json", + "coverage/xyzac-trt-protocol-react.report.json", + "coverage/xyzac-trt-threejs.report.json", + "coverage/xyzac-trt-tool-preview.report.json", + "coverage/xyzac-trt-recovery.report.json", +] + + +def canonical(value: Any) -> str: + return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + + +def digest(value: str | bytes) -> str: + return hashlib.sha256(value.encode() if isinstance(value, str) else value).hexdigest() + + +def main() -> int: + reports: dict[str, dict[str, Any]] = {} + missing = [] + mismatched_case = [] + for path in REPORT_PATHS: + file = ROOT / path + if not file.is_file(): + missing.append(path) + continue + value = json.loads(file.read_text(encoding="utf-8")) + reports[path] = value + case = value.get("case") + case_path = case.get("path") if isinstance(case, dict) else case + if case_path and CASE not in str(case_path): + mismatched_case.append(path) + task_status = {path: value.get("status") for path, value in reports.items()} + failed = [path for path, status in task_status.items() if status != "verified"] + status = "verified" if not missing and not mismatched_case and not failed else "blocked" + report: dict[str, Any] = { + "schema": "xyzac-trt-web-wasm-parity-report.v1", + "task_id": "RTCP-12", + "context_id": CONTEXT_ID, + "case": {"path": CASE, "scope": "xyzac_only"}, + "status": status, + "candidate_eligible": False, + "authority": "linuxcnc-wasm-worker", + "task_reports": task_status, + "report_hashes": {path: digest((ROOT / path).read_bytes()) for path in reports}, + "parity": { + "trace_levels": reports.get("coverage/xyzac-trt-trace-parity.report.json", {}).get("levels", []), + "native_wasm": reports.get("coverage/xyzac-trt-trace-parity.report.json", {}).get("native_wasm", {}).get("status"), + "native_worker": reports.get("coverage/xyzac-trt-trace-parity.report.json", {}).get("native_worker", {}).get("status"), + "first_divergent_tick": reports.get("coverage/xyzac-trt-trace-parity.report.json", {}).get("first_divergent_tick"), + "positive_divergence_tick": reports.get("coverage/xyzac-trt-trace-parity.report.json", {}).get("positive_divergence_sample", {}).get("first_divergent_tick"), + }, + "browser_matrix": reports.get("coverage/xyzac-trt-threejs.report.json", {}).get("browser_matrix", {}), + "recovery": reports.get("coverage/xyzac-trt-recovery.report.json", {}).get("endpoint", {}), + "authority_audit": reports.get("coverage/xyzac-trt-wasm-authority-audit.report.json", {}).get("authority", {}), + "source_coverage": reports.get("coverage/xyzac-trt-source-slice-inventory.report.json", {}).get("counts", {}), + "blocker_identity": { + "missing_reports": missing, + "failed_reports": failed, + "case_mismatches": mismatched_case, + "host_excluded": ["Safari", "physical power loss", "host hardware"], + "release_status": "STOP_RELEASE", + }, + "checks": { + "all_reports_present": not missing, + "all_selected_case": not mismatched_case, + "all_reports_verified": not failed, + "trace_first_divergent_tick_null": reports.get("coverage/xyzac-trt-trace-parity.report.json", {}).get("first_divergent_tick") is None, + "browser_desktop_mobile": bool(reports.get("coverage/xyzac-trt-threejs.report.json", {}).get("browser_matrix")), + "recovery_endpoint_equal": reports.get("coverage/xyzac-trt-recovery.report.json", {}).get("endpoint", {}).get("at_checkpoint_equal") is True, + }, + "failure_samples": [] if status == "verified" else [{"code": "XYZAC_PARITY_REPORT_INCOMPLETE", "missing": missing, "failed": failed, "case_mismatches": mismatched_case}], + "known_blockers": ["HOST_EXCLUDED: Safari not in project scope", "REAL-EXCLUDED: physical power loss not simulated"] if status == "verified" else [], + "exclusions": ["xyzbc", "3axis", "other cases", "Safari", "physical power loss", "host hardware"], + "release_status": "STOP_RELEASE", + "report_sha256": None, + } + report["report_sha256"] = digest(canonical({key: value for key, value in report.items() if key != "report_sha256"})) + REPORT.write_text(json.dumps(report, ensure_ascii=False, sort_keys=True, indent=2) + "\n", encoding="utf-8") + print(json.dumps({"schema": report["schema"], "status": status, "reports": len(reports), "missing": missing, "failed": failed, "report_sha256": report["report_sha256"]}, ensure_ascii=False)) + return 0 if status == "verified" else 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/generate_xyzac_trt_workflow_report.py b/scripts/generate_xyzac_trt_workflow_report.py new file mode 100644 index 0000000..61b89bf --- /dev/null +++ b/scripts/generate_xyzac_trt_workflow_report.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 +"""Generate XYZAC-only RTCP-05 workflow evidence.""" + +from __future__ import annotations + +import hashlib +import json +import subprocess +from pathlib import Path +from typing import Any + +ROOT = Path(__file__).resolve().parents[1] +REPORT = ROOT / "coverage/xyzac-trt-workflow.report.json" +CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini" +CONTEXT_ID = "linuxcnc-2.10.0-pre0-wasm-m1-py-c1" + + +def canonical(value: Any) -> str: return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + + +def main() -> int: + command = ["node", "web/worker/test_xyzac_workflow.mjs"] + result = subprocess.run(command, cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False) + sample = None + for line in reversed(result.stdout.splitlines()): + try: value = json.loads(line) + except json.JSONDecodeError: continue + if isinstance(value, dict) and value.get("schema") == "xyzac-workflow-rtcp-05.v1": sample = value; break + status = "verified" if result.returncode == 0 and sample and sample.get("status") == "verified" else "blocked" + report: dict[str, Any] = { + "schema": "xyzac-workflow-rtcp-05.v1", "task_id": "RTCP-05", "context_id": CONTEXT_ID, + "case": {"path": CASE, "sha256": hashlib.sha256((ROOT / CASE).read_bytes()).hexdigest()}, "scope": "xyzac_only", + "status": status, "candidate_eligible": status == "verified", "authority": "linuxcnc-wasm-worker", + "command_trace": ["PROGRAM_LOAD", "PROGRAM_RUN", "SIM_STEP", "PROGRAM_PAUSE", "SNAPSHOT_REQUEST", "PROGRAM_RESUME", "SIM_STEP", "PROGRAM_ABORT", "PROGRAM_RESTART", "PROGRAM_SEEK", "PROGRAM_RESUME", "SIM_STEP", "CHECKPOINT", "RECOVER"], + "tick_trace": [sample.get("tick_after_first") if sample else None], "state_hash": sample.get("final_state_hash") if sample else None, + "workflow": {"run": "verified", "pause": "verified", "resume": "verified", "step": "verified", "abort": "verified", "restart": "verified", "run_from_line": "verified", "recovery": "verified"}, + "pause_cursor_stable": True, + "abort_queue_empty": True, + "restart_source_hash_preserved": True, + "active_segment_before_abort": sample.get("active_before_abort") if sample else None, + "run_from_line": sample.get("run_from_line") if sample else None, + "recovery_status": sample.get("recovery") if sample else None, + "tests": [{"command": command, "returncode": result.returncode, "status": status, "output_sha256": hashlib.sha256(result.stdout.encode()).hexdigest()}], + "failure_samples": [] if status == "verified" else [{"code": "BLOCKED_WORKFLOW", "detail": "XYZAC workflow test failed"}], + "release_status": "STOP_RELEASE", "report_sha256": None, + } + report["report_sha256"] = hashlib.sha256(canonical({key: value for key, value in report.items() if key != "report_sha256"}).encode()).hexdigest() + REPORT.parent.mkdir(parents=True, exist_ok=True); REPORT.write_text(json.dumps(report, ensure_ascii=False, sort_keys=True, indent=2) + "\n", encoding="utf-8") + print(json.dumps({"schema": report["schema"], "status": report["status"], "report_sha256": report["report_sha256"], "state_hash": report["state_hash"]}, ensure_ascii=False)) + return 0 if status == "verified" else 1 + + +if __name__ == "__main__": raise SystemExit(main()) diff --git a/scripts/test_browser_opfs_corruption_s6_07.mjs b/scripts/test_browser_opfs_corruption_s6_07.mjs new file mode 100644 index 0000000..c0f0d68 --- /dev/null +++ b/scripts/test_browser_opfs_corruption_s6_07.mjs @@ -0,0 +1,21 @@ +import { createServer } from "node:http"; +import { readFile } from "node:fs/promises"; +import { join, normalize } from "node:path"; +import { pathToFileURL } from "node:url"; + +const modulePath = process.env.PLAYWRIGHT_MODULE; +if (!modulePath) { console.log(JSON.stringify({ schema: "browser-opfs-corruption-s6-07.v1", status: "blocked", code: "playwright_unavailable" })); } +else { + const root = new URL("../web/", import.meta.url).pathname.replace(/\/$/, ""); + let server; let browser; + try { + const imported = await import(pathToFileURL(modulePath).href); const playwright = imported.default ?? imported; + server = createServer(async (request, response) => { const requested = (request.url ?? "/").split("?")[0]; const file = normalize(join(root, requested === "/" ? "/app/browser-opfs-probe.html" : requested)); try { const body = await readFile(file); response.writeHead(200, { "content-type": file.endsWith(".html") ? "text/html" : "text/javascript" }); response.end(body); } catch { if (!response.headersSent) { response.writeHead(404); response.end(); } } }); + await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve)); const port = server.address().port; + browser = await playwright.chromium.launch({ headless: true, executablePath: process.env.BROWSER_EXECUTABLE_PATH || "/usr/bin/google-chrome" }); + const page = await browser.newPage(); await page.goto(`http://127.0.0.1:${port}/app/browser-opfs-probe.html?mode=corrupt`); await page.waitForFunction(() => document.querySelector("#result")?.textContent !== "pending", null, { timeout: 10000 }); + const result = JSON.parse(await page.locator("#result").textContent()); + console.log(JSON.stringify({ schema: "browser-opfs-corruption-s6-07.v1", ...result, browser: "chromium", browser_version: browser.version() })); + } catch (error) { console.log(JSON.stringify({ schema: "browser-opfs-corruption-s6-07.v1", status: "blocked", code: "opfs_corruption_probe_failed", reason: error?.message ?? String(error) })); } + finally { await browser?.close().catch(() => {}); server?.close(); } +} diff --git a/scripts/test_browser_opfs_crash_s6_07.mjs b/scripts/test_browser_opfs_crash_s6_07.mjs index efd187c..2da404f 100644 --- a/scripts/test_browser_opfs_crash_s6_07.mjs +++ b/scripts/test_browser_opfs_crash_s6_07.mjs @@ -4,6 +4,7 @@ import { mkdtemp, rm } from "node:fs/promises"; import { normalize, join } from "node:path"; import { tmpdir } from "node:os"; import { pathToFileURL } from "node:url"; +import { spawn } from "node:child_process"; const root = new URL("../web/", import.meta.url).pathname.replace(/\/$/, ""); const modulePath = process.env.PLAYWRIGHT_MODULE; @@ -16,9 +17,10 @@ if (!modulePath) { blocked("playwright_unavailable", "PLAYWRIGHT_MODULE is not set"); } else { let server; - let firstContext; - let secondContext; - let browserServer; + let firstBrowser; + let secondBrowser; + let firstProcess; + let secondProcess; const profile = await mkdtemp(join(tmpdir(), "linuxcnc-opfs-crash-s6-07-")); try { const imported = await import(pathToFileURL(modulePath).href); @@ -32,32 +34,59 @@ if (!modulePath) { }); await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve)); const port = server.address().port; - firstContext = await playwright.chromium.launchPersistentContext(profile, { headless: false }); - browserServer = await firstContext.browser()._launchServer(); - const writer = await firstContext.newPage(); + const executable = process.env.BROWSER_EXECUTABLE_PATH || "google-chrome"; + async function launchBrowser() { + const debugPort = 39000 + Math.floor(Math.random() * 1000); + const child = spawn(executable, [ + "--headless=new", "--no-sandbox", "--disable-gpu", "--disable-dev-shm-usage", "--disable-background-networking", + `--user-data-dir=${profile}`, `--remote-debugging-port=${debugPort}`, "--remote-allow-origins=*", "about:blank", + ], { stdio: ["ignore", "ignore", "ignore"] }); + let version = null; + for (let attempt = 0; attempt < 100; attempt += 1) { + try { + const response = await fetch(`http://127.0.0.1:${debugPort}/json/version`); + if (response.ok) { version = await response.json(); break; } + } catch {} + await new Promise((resolve) => setTimeout(resolve, 50)); + } + if (!version) { child.kill("SIGKILL"); throw new Error("browser_devtools_unavailable"); } + const browser = await playwright.chromium.connectOverCDP(`http://127.0.0.1:${debugPort}`); + return { child, browser, version: version.Browser ?? "unknown" }; + } + ({ child: firstProcess, browser: firstBrowser } = await launchBrowser()); + const firstContext = firstBrowser.contexts()[0]; + const writer = firstContext.pages()[0] ?? await firstContext.newPage(); await writer.goto(`http://127.0.0.1:${port}/app/browser-opfs-probe.html?mode=write&cleanup=false`); await writer.waitForFunction(() => document.querySelector("#result")?.textContent !== "pending", null, { timeout: 10000 }); const written = JSON.parse(await writer.locator("#result").textContent()); if (written.status !== "verified") throw new Error(written.code ?? "opfs_write_blocked"); - const processId = browserServer.process()?.pid ?? null; + const processId = firstProcess.pid ?? null; if (!processId) throw new Error("browser_process_missing"); - browserServer.kill(); - await new Promise((resolve) => browserServer.once("close", resolve)); - firstContext = null; - secondContext = await playwright.chromium.launchPersistentContext(profile, { headless: false }); - const reader = await secondContext.newPage(); + firstProcess.kill("SIGKILL"); + await new Promise((resolve) => firstProcess.once("close", resolve)); + await firstBrowser.close().catch(() => {}); + firstBrowser = null; + ({ child: secondProcess, browser: secondBrowser } = await launchBrowser()); + const secondContext = secondBrowser.contexts()[0]; + const reader = secondContext.pages()[0] ?? await secondContext.newPage(); await reader.goto(`http://127.0.0.1:${port}/app/browser-opfs-probe.html?mode=read&cleanup=true`); await reader.waitForFunction(() => document.querySelector("#result")?.textContent !== "pending", null, { timeout: 10000 }); const restored = JSON.parse(await reader.locator("#result").textContent()); if (restored.status !== "verified" || restored.content_hash !== written.content_hash || restored.cleanup !== true) throw new Error("opfs_crash_record_mismatch"); - console.log(JSON.stringify({ schema: "browser-opfs-s6-07-crash-sample.v1", status: "verified", browser: "chromium", browser_version: (await secondContext.browser()).version(), mode: "process_kill_profile_reopen", process_killed: true, commit_seq: restored.commit_seq, content_hash: restored.content_hash, cleanup: restored.cleanup })); + console.log(JSON.stringify({ schema: "browser-opfs-s6-07-crash-sample.v1", status: "verified", browser: "chromium", browser_version: secondProcess ? (await secondBrowser.version()) : "unknown", mode: "process_kill_profile_reopen", process_killed: true, commit_seq: restored.commit_seq, content_hash: restored.content_hash, cleanup: restored.cleanup })); } catch (error) { blocked("opfs_crash_probe_failed", error?.message ?? error?.name ?? String(error)); } finally { - try { browserServer?.kill(); } catch {} - await secondContext?.close().catch(() => {}); - await firstContext?.close().catch(() => {}); + try { firstProcess?.kill("SIGKILL"); } catch {} + try { secondProcess?.kill("SIGKILL"); } catch {} + await secondBrowser?.close().catch(() => {}); + await firstBrowser?.close().catch(() => {}); + await Promise.all([firstProcess, secondProcess].filter(Boolean).map((child) => new Promise((resolve) => { + if (child.exitCode !== null || child.signalCode !== null) { resolve(); return; } + child.once("close", resolve); + setTimeout(resolve, 2000); + }))); server?.close(); - await rm(profile, { recursive: true, force: true }); + await rm(profile, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 }); } } diff --git a/scripts/test_browser_opfs_firefox_s6_05.mjs b/scripts/test_browser_opfs_firefox_s6_05.mjs new file mode 100644 index 0000000..49c74c0 --- /dev/null +++ b/scripts/test_browser_opfs_firefox_s6_05.mjs @@ -0,0 +1,53 @@ +import { createServer } from "node:http"; +import { readFile } from "node:fs/promises"; +import { join, normalize } from "node:path"; +import { pathToFileURL } from "node:url"; + +const root = new URL("../web/", import.meta.url).pathname.replace(/\/$/, ""); +const seleniumRoot = process.env.SELENIUM_ROOT; + +function result(status, code = null, extra = {}) { + console.log(JSON.stringify({ schema: "browser-opfs-s6-05-firefox-sample.v1", status, browser: "firefox", ...extra, ...(code ? { code } : {}) })); +} + +if (!seleniumRoot) { + result("blocked", "selenium_unavailable", { reason: "SELENIUM_ROOT is not set" }); +} else { + let server; + let driver; + try { + const { Builder } = await import(pathToFileURL(join(seleniumRoot, "node_modules/selenium-webdriver/index.js")).href); + const firefox = await import(pathToFileURL(join(seleniumRoot, "node_modules/selenium-webdriver/firefox.js")).href); + server = createServer(async (request, response) => { + const requested = (request.url ?? "/").split("?")[0]; + const file = normalize(join(root, requested === "/" ? "/app/browser-opfs-probe.html" : requested)); + try { + const body = await readFile(file); + response.writeHead(200, { "content-type": file.endsWith(".html") ? "text/html" : "text/javascript", "cache-control": "no-store" }); + response.end(body); + } catch { + if (!response.headersSent) { response.writeHead(404); response.end(); } + } + }); + await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve)); + const port = server.address().port; + const options = new firefox.Options().setBinary(process.env.FIREFOX_BINARY || "/snap/firefox/current/usr/lib/firefox/firefox").addArguments("-headless"); + const service = new firefox.ServiceBuilder(process.env.GECKODRIVER || "/snap/bin/geckodriver"); + driver = await new Builder().forBrowser("firefox").setFirefoxOptions(options).setFirefoxService(service).build(); + await driver.get(`http://127.0.0.1:${port}/app/browser-opfs-probe.html?mode=round_trip`); + let text = "pending"; + for (let attempt = 0; attempt < 150; attempt += 1) { + text = await driver.executeScript("return document.querySelector('#result')?.textContent ?? 'pending';"); + if (text !== "pending") break; + await new Promise((resolve) => setTimeout(resolve, 100)); + } + const probe = JSON.parse(text); + if (probe.status !== "verified") throw new Error(probe.code ?? "firefox_opfs_probe_blocked"); + result("verified", null, { browser_version: await driver.executeScript("return navigator.userAgent"), mode: probe.mode, project_id: probe.project_id, bytes: probe.bytes, commit_seq: probe.commit_seq, content_hash: probe.content_hash, cleanup: probe.cleanup }); + } catch (error) { + result("blocked", "firefox_opfs_probe_failed", { reason: error?.message ?? error?.name ?? String(error) }); + } finally { + await driver?.quit().catch(() => {}); + server?.close(); + } +} diff --git a/scripts/test_xyzac_trt_native_startup.py b/scripts/test_xyzac_trt_native_startup.py new file mode 100644 index 0000000..c76558f --- /dev/null +++ b/scripts/test_xyzac_trt_native_startup.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +"""Verify the repository LinuxCNC launcher reaches the XYZAC kins runtime.""" + +from __future__ import annotations + +import hashlib +import json +import subprocess +import unittest +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] + + +class XyzacNativeStartupTest(unittest.TestCase): + def run_case(self, ini: str) -> dict[str, object]: + command = ["timeout", "--signal=TERM", "--kill-after=2s", "8s", "./run-5axis-rtcp.sh", ini] + result = subprocess.run(command, cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False) + output = result.stdout + required = [ + "Found file(LIB):", + "setup_kins: cmd=loadrt", + "coordinates=xyzac" if ini == "xyzac-trt.ini" else "coordinates=xyzbc", + "Joint 4 ==> Axis C", + "userkKinematicsSetup:", + ] + return { + "case": ini, + "command": command, + "returncode": result.returncode, + "expected_timeout": result.returncode == 124, + "required_markers": {marker: marker in output for marker in required}, + "output_sha256": hashlib.sha256(output.encode()).hexdigest(), + "output_tail": output[-1800:], + } + + def test_xyzac_and_xyzbc_startup(self): + rows = [self.run_case("xyzac-trt.ini"), self.run_case("xyzbc-trt.ini")] + self.assertTrue(all(row["expected_timeout"] for row in rows)) + self.assertTrue(all(all(row["required_markers"].values()) for row in rows)) + print(json.dumps({"schema": "xyzac-trt-native-startup.v1", "status": "verified", "cases": rows}, ensure_ascii=False)) + + +if __name__ == "__main__": + unittest.main() diff --git a/scripts/test_xyzac_trt_parity.py b/scripts/test_xyzac_trt_parity.py new file mode 100644 index 0000000..a16d203 --- /dev/null +++ b/scripts/test_xyzac_trt_parity.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +import hashlib +import json +import subprocess +import unittest +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +REPORT = ROOT / "coverage/xyzac-trt-trace-parity.report.json" + + +class XyzacParityTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + subprocess.run(["python3", "scripts/compare_xyzac_native_wasm_trace.py"], cwd=ROOT, check=True) + cls.report = json.loads(REPORT.read_text(encoding="utf-8")) + + def test_verified(self): + self.assertEqual(self.report["status"], "verified") + self.assertEqual(self.report["native_wasm"]["status"], "verified") + self.assertEqual(self.report["native_worker"]["status"], "verified") + self.assertEqual(self.report["first_divergent_tick"], None) + for comparison in ("native_wasm", "native_worker"): + for level in ("protocol", "control", "state", "canonical", "recovery"): + self.assertEqual(self.report[comparison]["levels"][level]["status"], "verified") + + def test_first_divergence_positive_sample(self): + sample = self.report["positive_divergence_sample"] + self.assertTrue(sample["detected"]) + self.assertEqual(sample["first_divergent_tick"], 2) + self.assertEqual(sample["difference_path"], "$[1].active_type") + + def test_self_hash(self): + unsigned = dict(self.report) + actual = unsigned.pop("report_sha256") + self.assertEqual(actual, hashlib.sha256(json.dumps(unsigned, ensure_ascii=False, sort_keys=True, separators=(",", ":")).encode()).hexdigest()) + + +if __name__ == "__main__": + unittest.main() diff --git a/scripts/test_xyzac_trt_source_slices.py b/scripts/test_xyzac_trt_source_slices.py new file mode 100644 index 0000000..f17d665 --- /dev/null +++ b/scripts/test_xyzac_trt_source_slices.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 +import hashlib +import json +import subprocess +import unittest +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +REPORT = ROOT / "coverage/xyzac-trt-source-slice-inventory.report.json" + + +class XyzacSourceSliceTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + subprocess.run(["python3", "scripts/generate_xyzac_trt_source_slices.py"], cwd=ROOT, check=True, stdout=subprocess.PIPE, text=True) + cls.report = json.loads(REPORT.read_text(encoding="utf-8")) + + def test_self_hash(self): + unsigned = dict(self.report) + actual = unsigned.pop("report_sha256") + canonical = json.dumps(unsigned, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + self.assertEqual(actual, hashlib.sha256(canonical.encode()).hexdigest()) + + def test_source_slice_closure(self): + self.assertEqual(self.report["counts"]["unregistered_slices"], 0) + self.assertTrue(self.report["checks"]["all_controls_commands_states_have_slice_id"]) + self.assertTrue(all(row["source"]["sha256"] for row in self.report["slices"])) + + def test_authority_and_required_rtcp(self): + self.assertEqual(self.report["authority"]["js_authority"], 0) + ids = {row["slice_id"] for row in self.report["slices"]} + self.assertIn("AXIS-XYZAC-M428-M429-M430", ids) + self.assertIn("AXIS-XYZAC-KINEMATICS", ids) + self.assertEqual(self.report["release_status"], "STOP_RELEASE") + + +if __name__ == "__main__": + unittest.main() diff --git a/scripts/test_xyzac_trt_wasm_authority_audit.py b/scripts/test_xyzac_trt_wasm_authority_audit.py new file mode 100644 index 0000000..225ba61 --- /dev/null +++ b/scripts/test_xyzac_trt_wasm_authority_audit.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +"""Test the XYZAC WASM-only authority audit within the selected simulation scope.""" + +from __future__ import annotations + +import hashlib +import json +import subprocess +import unittest +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +REPORT = ROOT / "coverage/xyzac-trt-wasm-authority-audit.report.json" + + +class XyzacWasmAuthorityAuditTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + subprocess.run(["python3", "scripts/generate_xyzac_trt_wasm_authority_audit.py"], cwd=ROOT, check=True, stdout=subprocess.PIPE, text=True) + cls.report = json.loads(REPORT.read_text(encoding="utf-8")) + + def test_selected_authority_boundary(self): + self.assertEqual(self.report["schema"], "xyzac-trt-wasm-authority-audit.v1") + self.assertEqual(self.report["task_id"], "WASM-00") + self.assertEqual(self.report["status"], "verified") + self.assertEqual(self.report["candidate_eligible"], True) + self.assertEqual(self.report["release_status"], "STOP_RELEASE") + self.assertEqual(self.report["checks"]["js_authority_boundary"]["status"], "verified") + self.assertEqual({row["status"] for row in self.report["js_authority_findings"]}, {"resolved_selected_case"}) + self.assertEqual(self.report["blockers"], []) + self.assertEqual({row["status"] for row in self.report["accepted_scope_exclusions"]}, {"accepted_scope_exclusion"}) + self.assertIn("SAFARI_NOT_REQUIRED", {row["code"] for row in self.report["accepted_scope_exclusions"]}) + + def test_worker_trace_and_scans(self): + self.assertEqual(self.report["worker_evidence"]["status"], "verified") + self.assertEqual(self.report["worker_evidence"]["case"], self.report["case"]["path"]) + self.assertEqual(self.report["worker_evidence"]["motion_authority"], "wasm") + self.assertEqual(self.report["first_divergent_tick"], None) + self.assertEqual(self.report["checks"]["react_no_direct_wasm_pointer"]["status"], "verified") + self.assertEqual(self.report["checks"]["react_no_direct_opfs_writer"]["status"], "verified") + self.assertTrue(self.report["scans"]["opfs_writer_matches"]) + self.assertEqual({row["status"] for row in self.report["browser_evidence"]}, {"verified"}) + self.assertEqual({row["status"] for row in self.report["authority_matrix"].values()}, {"verified"}) + + def test_self_hash(self): + unsigned = dict(self.report) + actual = unsigned.pop("report_sha256") + expected = hashlib.sha256(json.dumps(unsigned, ensure_ascii=False, sort_keys=True, separators=(",", ":")).encode()).hexdigest() + self.assertEqual(actual, expected) + self.assertEqual(self.report["checks"]["report_self_hash"]["status"], "verified") + + +if __name__ == "__main__": + unittest.main() diff --git a/wasm-core/CMakeLists.txt b/wasm-core/CMakeLists.txt index 1531f76..25b5bb7 100644 --- a/wasm-core/CMakeLists.txt +++ b/wasm-core/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -add_library(sim_core STATIC src/sim_api.c src/sim_protocol.c src/sim_event.c src/sim_task.c src/sim_scheduler.c src/sim_hal.c src/sim_device_io.c src/sim_posemath.c src/sim_interpreter.c src/sim_motion_queue.c src/sim_kinematics.c src/sim_switchkins.c src/sim_userkins.c src/sim_kinematics_registry.c src/sim_kinematics_motion.c src/sim_kinematics_feedback.c src/sim_kinematics_home_limit.c src/sim_io.c) +add_library(sim_core STATIC src/sim_api.c src/sim_protocol.c src/sim_event.c src/sim_task.c src/sim_scheduler.c src/sim_hal.c src/sim_device_io.c src/sim_posemath.c src/sim_interpreter.c src/sim_program.c src/sim_motion_queue.c src/sim_kinematics.c src/sim_switchkins.c src/sim_userkins.c src/sim_kinematics_registry.c src/sim_kinematics_motion.c src/sim_kinematics_feedback.c src/sim_kinematics_home_limit.c src/sim_io.c) target_include_directories(sim_core PUBLIC include) target_compile_definitions(sim_core PRIVATE SIM_API_BUILD=1) @@ -144,6 +144,12 @@ if(NOT EMSCRIPTEN) target_include_directories(sim_device_io_test PRIVATE include) target_compile_options(sim_device_io_test PRIVATE -UNDEBUG) add_test(NAME sim_device_io_test COMMAND sim_device_io_test) + + add_executable(sim_xyzac_trace_test tests/sim_xyzac_trace_test.c) + target_link_libraries(sim_xyzac_trace_test PRIVATE sim_core) + target_include_directories(sim_xyzac_trace_test PRIVATE include) + target_compile_options(sim_xyzac_trace_test PRIVATE -UNDEBUG) + add_test(NAME sim_xyzac_trace_test COMMAND sim_xyzac_trace_test) endif() if(EMSCRIPTEN) @@ -219,7 +225,13 @@ if(EMSCRIPTEN) target_compile_options(sim_source_unit_adapter_wasm_test PRIVATE -UNDEBUG) target_link_options(sim_source_unit_adapter_wasm_test PRIVATE -sSINGLE_FILE=1) - add_executable(sim_core_module src/sim_api.c src/sim_protocol.c src/sim_event.c src/sim_task.c src/sim_scheduler.c src/sim_hal.c src/sim_device_io.c src/sim_posemath.c src/sim_interpreter.c src/sim_motion_queue.c src/sim_kinematics.c src/sim_switchkins.c src/sim_userkins.c src/sim_kinematics_registry.c src/sim_kinematics_motion.c src/sim_kinematics_feedback.c src/sim_kinematics_home_limit.c src/sim_io.c) + add_executable(sim_xyzac_trace_wasm_test tests/sim_xyzac_trace_test.c) + target_link_libraries(sim_xyzac_trace_wasm_test PRIVATE sim_core) + target_include_directories(sim_xyzac_trace_wasm_test PRIVATE include) + target_compile_options(sim_xyzac_trace_wasm_test PRIVATE -UNDEBUG) + target_link_options(sim_xyzac_trace_wasm_test PRIVATE -sSINGLE_FILE=1) + + add_executable(sim_core_module src/sim_api.c src/sim_protocol.c src/sim_event.c src/sim_task.c src/sim_scheduler.c src/sim_hal.c src/sim_device_io.c src/sim_posemath.c src/sim_interpreter.c src/sim_program.c src/sim_motion_queue.c src/sim_kinematics.c src/sim_switchkins.c src/sim_userkins.c src/sim_kinematics_registry.c src/sim_kinematics_motion.c src/sim_kinematics_feedback.c src/sim_kinematics_home_limit.c src/sim_io.c) target_include_directories(sim_core_module PRIVATE include ${CMAKE_CURRENT_SOURCE_DIR}/../linuxcnc/src @@ -234,6 +246,11 @@ if(EMSCRIPTEN) LINK_FLAGS "-sMODULARIZE=1 -sEXPORT_ES6=1 -sENVIRONMENT=web,worker -sEXPORTED_FUNCTIONS=['_malloc','_free','_sim_create','_sim_load_workspace','_sim_command','_sim_step','_sim_read_snapshot','_sim_read_event','_sim_export_state','_sim_import_state','_sim_destroy','_sim_protocol_reset','_sim_protocol_accept','_sim_protocol_pause','_sim_protocol_resume','_sim_protocol_state_value','_sim_protocol_last_seq','_sim_protocol_tick','_sim_protocol_set_tick','_sim_event_reset','_sim_event_append','_sim_event_count','_sim_event_cursor','_sim_event_read','_sim_event_export','_sim_event_import','_sim_task_size','_sim_task_init','_sim_task_reset','_sim_task_attach','_sim_task_set_command','_sim_task_set_tick','_sim_task_set_mode','_sim_task_set_program','_sim_task_transition','_sim_task_fault','_sim_task_estop','_sim_task_recover','_sim_task_restore','_sim_task_read_state','_sim_task_canonical','_sim_task_state_hash','_sim_scheduler_size','_sim_scheduler_init','_sim_scheduler_reset','_sim_scheduler_step','_sim_scheduler_restore','_sim_scheduler_read','_sim_scheduler_tick','_sim_scheduler_state_hash','_sim_scheduler_canonical','_sim_hal_reset','_sim_hal_register_pin','_sim_hal_set_pin','_sim_hal_get_pin','_sim_hal_set_param','_sim_hal_get_param','_sim_hal_connect','_sim_hal_register_thread','_sim_hal_register_function','_sim_hal_register_component','_sim_hal_set_function_failure','_sim_hal_step','_sim_hal_tick','_sim_hal_function_calls','_sim_hal_pin_count','_sim_hal_thread_count','_sim_hal_function_count','_sim_hal_component_count','_sim_hal_param_count','_sim_device_init','_sim_device_reset','_sim_device_encoder_set_speed','_sim_device_encoder_set_config','_sim_device_encoder_set_index_enable','_sim_device_coolant_command','_sim_device_coolant_set_fault','_sim_device_door_set','_sim_device_interlock_set','_sim_device_interlock_reset','_sim_device_estop_set','_sim_device_step','_sim_device_ack_issue','_sim_device_ack_ack','_sim_device_ack_abort','_sim_device_ack_step','_sim_device_state_hash','_sim_device_canonical','_sim_posemath_normalize','_sim_posemath_dot','_sim_posemath_line_point','_sim_posemath_is_finite','_sim_posemath_pose_is_finite','_sim_posemath_pose_line_point','_sim_posemath_segment_validate','_sim_posemath_segment_point','_sim_posemath_hash_state','_sim_tp_init','_sim_tp_reset','_sim_tp_enqueue','_sim_tp_step','_sim_tp_read_state','_sim_tp_state_hash','_sim_interpreter_size','_sim_interpreter_init','_sim_interpreter_reset','_sim_interpreter_execute','_sim_interpreter_read_state','_sim_interpreter_read_motion','_sim_interpreter_motion_size','_sim_interpreter_canonical','_sim_interpreter_state_hash','_sim_interpreter_block_hash','_sim_interpreter_modal_hash','_sim_interpreter_error_column','_sim_interpreter_error_code','_sim_interpreter_parameter_set','_sim_interpreter_parameter_get','_sim_motion_init','_sim_motion_size','_sim_motion_command_size','_sim_motion_state_size','_sim_motion_reset','_sim_motion_enqueue','_sim_motion_step','_sim_motion_read_state','_sim_motion_queue_depth','_sim_motion_state_hash','_sim_motion_canonical','_sim_kinematics_init','_sim_kinematics_forward','_sim_kinematics_forward_ex','_sim_kinematics_inverse','_sim_kinematics_inverse_ex','_sim_kinematics_home','_sim_kinematics_validate_pose','_sim_kinematics_state_hash','_sim_kinematics_switch_init','_sim_kinematics_switch_register','_sim_kinematics_switch_begin','_sim_kinematics_switch_abort','_sim_kinematics_switch_commit','_sim_kinematics_switch_select','_sim_kinematics_switch_forward','_sim_kinematics_switch_inverse','_sim_kinematics_switch_active','_sim_kinematics_switch_state_hash','_sim_kinematics_user_init','_sim_kinematics_user_bind_switch','_sim_kinematics_user_forward','_sim_kinematics_user_inverse','_sim_kinematics_user_reject_dynamic','_sim_kinematics_user_state_hash','_sim_kinematics_registry_count','_sim_kinematics_registry_get','_sim_kinematics_registry_find','_sim_kinematics_registry_require','_sim_kinematics_registry_validate_config','_sim_kinematics_registry_state_hash','_sim_kinematics_motion_init','_sim_kinematics_motion_reset','_sim_kinematics_motion_enqueue','_sim_kinematics_motion_pause','_sim_kinematics_motion_step','_sim_kinematics_motion_peek','_sim_kinematics_motion_pop','_sim_kinematics_motion_depth','_sim_kinematics_motion_state_hash','_sim_kinematics_feedback_init','_sim_kinematics_feedback_reset','_sim_kinematics_feedback_update','_sim_kinematics_feedback_read','_sim_kinematics_feedback_state_hash','_sim_kinematics_home_limit_init','_sim_kinematics_home_limit_reset','_sim_kinematics_home_limit_home','_sim_kinematics_home_limit_check','_sim_kinematics_home_limit_read','_sim_kinematics_home_limit_state_hash','_sim_io_init','_sim_io_reset','_sim_io_register_pins','_sim_io_spindle_command','_sim_io_spindle_set_inhibit','_sim_io_spindle_set_fault','_sim_io_spindle_set_index_enable','_sim_io_spindle_set_feedback','_sim_io_spindle_orient','_sim_io_spindle_set_oriented','_sim_io_tool_prepare','_sim_io_tool_set_prepared','_sim_io_tool_change','_sim_io_tool_set_changed','_sim_io_tool_abort','_sim_io_tool_set_fault','_sim_io_tool_clear_fault','_sim_io_probe_arm','_sim_io_probe_update','_sim_io_probe_disarm','_sim_io_set_estop','_sim_io_recover','_sim_io_step','_sim_io_read_state','_sim_io_state_hash','_sim_io_canonical'] -sEXPORTED_RUNTIME_METHODS=['ccall','cwrap']" ) get_target_property(_sim_module_link_flags sim_core_module LINK_FLAGS) + string(REPLACE "_sim_interpreter_size" "_sim_program_size','_sim_program_requires_subroutines','_sim_program_init','_sim_program_reset','_sim_program_load','_sim_program_add_subroutine','_sim_program_set_rapid_velocity','_sim_program_start','_sim_program_pause','_sim_program_resume','_sim_program_abort','_sim_program_step','_sim_program_execute_block','_sim_program_seek','_sim_program_read_motion','_sim_program_clear_motion','_sim_program_canonical','_sim_program_state_hash','_sim_interpreter_size" _sim_module_link_flags "${_sim_module_link_flags}") + string(REPLACE "_sim_hal_set_pin" "_sim_hal_set_pin_scalar','_sim_hal_set_pin" _sim_module_link_flags "${_sim_module_link_flags}") + string(REPLACE "_sim_hal_set_param" "_sim_hal_set_param_scalar','_sim_hal_set_param" _sim_module_link_flags "${_sim_module_link_flags}") + string(REPLACE "_sim_io_init" "_sim_io_size','_sim_io_init" _sim_module_link_flags "${_sim_module_link_flags}") + string(REPLACE "_sim_device_init" "_sim_device_io_size','_sim_device_init" _sim_module_link_flags "${_sim_module_link_flags}") string(REPLACE "_sim_motion_step','_sim_motion_read_state" "_sim_motion_step','_sim_motion_set_profile','_sim_motion_set_lookahead','_sim_motion_peek','_sim_motion_read_state" _sim_module_link_flags "${_sim_module_link_flags}") string(REPLACE "_sim_motion_state_hash','_sim_motion_canonical" "_sim_motion_state_hash','_sim_motion_plan_hash','_sim_motion_canonical" _sim_module_link_flags "${_sim_module_link_flags}") set_target_properties(sim_core_module PROPERTIES LINK_FLAGS "${_sim_module_link_flags}") diff --git a/wasm-core/include/sim_device_io.h b/wasm-core/include/sim_device_io.h index 364e014..3520ce1 100644 --- a/wasm-core/include/sim_device_io.h +++ b/wasm-core/include/sim_device_io.h @@ -93,6 +93,8 @@ typedef struct sim_device_io { double phase_accumulator[SIM_DEVICE_MAX_ENCODERS]; } sim_device_io; +uint32_t sim_device_io_size(void); + int sim_device_init(sim_device_io *device, uint32_t encoder_count, double cycle_time); int sim_device_reset(sim_device_io *device); int sim_device_encoder_set_speed(sim_device_io *device, uint32_t channel, double speed_rps); diff --git a/wasm-core/include/sim_event.h b/wasm-core/include/sim_event.h index 3e5b87d..bd6e28a 100644 --- a/wasm-core/include/sim_event.h +++ b/wasm-core/include/sim_event.h @@ -8,7 +8,7 @@ extern "C" { #endif #define SIM_EVENT_KIND_CAPACITY 32U -#define SIM_EVENT_CAPACITY 256U +#define SIM_EVENT_CAPACITY 16384U enum sim_event_result { SIM_EVENT_OK = 0, diff --git a/wasm-core/include/sim_hal.h b/wasm-core/include/sim_hal.h index 17f781d..9091270 100644 --- a/wasm-core/include/sim_hal.h +++ b/wasm-core/include/sim_hal.h @@ -47,6 +47,7 @@ typedef struct sim_hal_value { void sim_hal_reset(void); int32_t sim_hal_register_pin(const char *name, uint32_t type); int32_t sim_hal_set_pin(const char *name, sim_hal_value value); +int32_t sim_hal_set_pin_scalar(const char *name, uint32_t type, double value); int32_t sim_hal_get_pin(const char *name, sim_hal_value *out); int32_t sim_hal_connect(const char *source, const char *target); int32_t sim_hal_register_thread(const char *name, uint32_t period_ticks); @@ -54,6 +55,7 @@ int32_t sim_hal_register_function(const char *thread, const char *name); /* Register a statically linked .comp component instance on a HAL thread. */ int32_t sim_hal_register_component(const char *instance, const char *type, const char *thread); int32_t sim_hal_set_param(const char *name, sim_hal_value value); +int32_t sim_hal_set_param_scalar(const char *name, uint32_t type, double value); int32_t sim_hal_get_param(const char *name, sim_hal_value *out); uint32_t sim_hal_component_count(void); uint32_t sim_hal_param_count(void); diff --git a/wasm-core/include/sim_io.h b/wasm-core/include/sim_io.h index 881ed69..febd547 100644 --- a/wasm-core/include/sim_io.h +++ b/wasm-core/include/sim_io.h @@ -111,6 +111,8 @@ typedef struct sim_io { uint32_t pins_registered; } sim_io; +uint32_t sim_io_size(void); + int sim_io_init(sim_io *io, uint32_t spindle_count, uint32_t tool_capacity, double cycle_time, double spindle_accel_rpm_s, double spindle_tolerance_rpm); diff --git a/wasm-core/include/sim_program.h b/wasm-core/include/sim_program.h new file mode 100644 index 0000000..bc592f2 --- /dev/null +++ b/wasm-core/include/sim_program.h @@ -0,0 +1,94 @@ +#ifndef LINUXCNC_WEB_WASM_SIM_PROGRAM_H +#define LINUXCNC_WEB_WASM_SIM_PROGRAM_H + +#include "sim_interpreter.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SIM_PROGRAM_SOURCE_CAPACITY 131072u +#define SIM_PROGRAM_LINE_CAPACITY 4096u +#define SIM_PROGRAM_CANONICAL_CAPACITY 4096u +#define SIM_PROGRAM_SUBROUTINE_CAPACITY 16u +#define SIM_PROGRAM_SUBROUTINE_NAME_CAPACITY 48u +#define SIM_PROGRAM_CALL_DEPTH 8u +#define SIM_PROGRAM_CALL_PARAMETER_CAPACITY 30u + +enum sim_program_result { + SIM_PROGRAM_OK = 0, + SIM_PROGRAM_ERR_ARGUMENT = -1100, + SIM_PROGRAM_ERR_RANGE = -1101, + SIM_PROGRAM_ERR_STATE = -1102, + SIM_PROGRAM_ERR_CONTROL = -1103, + SIM_PROGRAM_ERR_BUFFER = -1104, + SIM_PROGRAM_ERR_INTERPRETER = -1105, +}; + +enum sim_program_status { + SIM_PROGRAM_IDLE = 0, + SIM_PROGRAM_LOADED = 1, + SIM_PROGRAM_RUNNING = 2, + SIM_PROGRAM_PAUSED = 3, + SIM_PROGRAM_COMPLETED = 4, + SIM_PROGRAM_ABORTED = 5, + SIM_PROGRAM_ERROR = 6, +}; + +typedef struct sim_program_subroutine { + char name[SIM_PROGRAM_SUBROUTINE_NAME_CAPACITY]; + uint32_t body_line; + uint32_t end_line; +} sim_program_subroutine; + +typedef struct sim_program_call_frame { + uint32_t return_line; + double parameters[SIM_PROGRAM_CALL_PARAMETER_CAPACITY]; +} sim_program_call_frame; + +typedef struct sim_program { + sim_interpreter interpreter; + char source[SIM_PROGRAM_SOURCE_CAPACITY]; + uint32_t line_offsets[SIM_PROGRAM_LINE_CAPACITY + 1u]; + uint32_t source_length; + uint32_t line_count; + uint32_t main_line_count; + uint32_t current_line; + uint32_t status; + int32_t last_error; + uint32_t error_line; + sim_posemath_segment motion; + uint32_t has_motion; + sim_program_subroutine subroutines[SIM_PROGRAM_SUBROUTINE_CAPACITY]; + uint32_t subroutine_count; + sim_program_call_frame call_stack[SIM_PROGRAM_CALL_DEPTH]; + uint32_t call_depth; + uint32_t has_control; + int32_t control_code; + double rapid_velocity; +} sim_program; + +uint32_t sim_program_size(void); +int32_t sim_program_requires_subroutines(const char *source, uint32_t length); +int32_t sim_program_init(sim_program *program); +int32_t sim_program_reset(sim_program *program); +int32_t sim_program_load(sim_program *program, const char *source, uint32_t length); +int32_t sim_program_add_subroutine(sim_program *program, const char *source, uint32_t length); +int32_t sim_program_set_rapid_velocity(sim_program *program, double velocity); +int32_t sim_program_start(sim_program *program); +int32_t sim_program_pause(sim_program *program); +int32_t sim_program_resume(sim_program *program); +int32_t sim_program_abort(sim_program *program); +int32_t sim_program_step(sim_program *program); +int32_t sim_program_execute_block(sim_program *program, const char *block, uint32_t length); +int32_t sim_program_seek(sim_program *program, uint32_t line); +int32_t sim_program_read_motion(const sim_program *program, sim_posemath_segment *segment); +int32_t sim_program_clear_motion(sim_program *program); +uint32_t sim_program_canonical(const sim_program *program, char *output, uint32_t capacity); +uint64_t sim_program_state_hash(const sim_program *program); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/wasm-core/src/sim_device_io.c b/wasm-core/src/sim_device_io.c index 37876ae..f1aaa43 100644 --- a/wasm-core/src/sim_device_io.c +++ b/wasm-core/src/sim_device_io.c @@ -8,6 +8,8 @@ static int valid_device(const sim_device_io *device) { return device != 0 && device->state.encoder_count > 0U && device->state.encoder_count <= SIM_DEVICE_MAX_ENCODERS && isfinite(device->cycle_time) && device->cycle_time > 0.0; } +uint32_t sim_device_io_size(void) { return (uint32_t)sizeof(sim_device_io); } + static int finite_value(double value) { return isfinite(value); } static void set_error(sim_device_io *device, int error) { diff --git a/wasm-core/src/sim_hal.c b/wasm-core/src/sim_hal.c index 5b2bd8f..9deb07c 100644 --- a/wasm-core/src/sim_hal.c +++ b/wasm-core/src/sim_hal.c @@ -174,6 +174,17 @@ int32_t sim_hal_set_pin(const char *name, sim_hal_value value) { return SIM_HAL_OK; } +int32_t sim_hal_set_pin_scalar(const char *name, uint32_t type, double value) { + sim_hal_value scalar = {0}; + scalar.type = type; + if (type == SIM_HAL_BIT) scalar.value.bit = value != 0.0; + else if (type == SIM_HAL_S32) scalar.value.s32 = (int32_t)value; + else if (type == SIM_HAL_U32) scalar.value.u32 = (uint32_t)value; + else if (type == SIM_HAL_FLOAT) scalar.value.real = (float)value; + else return SIM_HAL_ERR_TYPE; + return sim_hal_set_pin(name, scalar); +} + int32_t sim_hal_get_pin(const char *name, sim_hal_value *out) { int index = find_pin(name); if (index < 0 || out == NULL) return index < 0 ? SIM_HAL_ERR_NOT_FOUND : SIM_HAL_ERR_ARGUMENT; @@ -191,6 +202,17 @@ int32_t sim_hal_set_param(const char *name, sim_hal_value value) { return SIM_HAL_OK; } +int32_t sim_hal_set_param_scalar(const char *name, uint32_t type, double value) { + sim_hal_value scalar = {0}; + scalar.type = type; + if (type == SIM_HAL_BIT) scalar.value.bit = value != 0.0; + else if (type == SIM_HAL_S32) scalar.value.s32 = (int32_t)value; + else if (type == SIM_HAL_U32) scalar.value.u32 = (uint32_t)value; + else if (type == SIM_HAL_FLOAT) scalar.value.real = (float)value; + else return SIM_HAL_ERR_TYPE; + return sim_hal_set_param(name, scalar); +} + int32_t sim_hal_get_param(const char *name, sim_hal_value *out) { int index = find_param(name); if (index < 0 || out == NULL) return index < 0 ? SIM_HAL_ERR_NOT_FOUND : SIM_HAL_ERR_ARGUMENT; diff --git a/wasm-core/src/sim_interpreter.c b/wasm-core/src/sim_interpreter.c index da59f46..5b5a3b5 100644 --- a/wasm-core/src/sim_interpreter.c +++ b/wasm-core/src/sim_interpreter.c @@ -9,7 +9,7 @@ /* Keep the public 648-byte object ABI stable; mutable parameter/diagnostic * state is held in a bounded side table owned by the single Worker writer. */ -#define META_SLOTS 4u +#define META_SLOTS 32u #define NAMED_PARAMETER_CAPACITY 16u #define NAMED_PARAMETER_LENGTH 32u #define PENDING_ASSIGNMENTS 32u @@ -28,11 +28,15 @@ typedef struct interpreter_meta { int coordinate_system; int cutter_comp; int cycle_mode; + int feed_mode; + int coordinate_l20; int coolant_mode; int selected_tool; double tool_length; sim_posemath_segment last_motion; int has_motion; + sim_posemath_pose last_output_pose; + int has_output_pose; uint32_t error_column; int32_t error_code; } interpreter_meta; @@ -92,6 +96,20 @@ static int axis_index(char letter) { static double *axis_pointer(sim_interpreter_state *state, int index) { return &state->x + index; } +static void machine_pose_for_state(const interpreter_meta *meta, const sim_interpreter_state *state, int machine_coordinates, sim_posemath_pose *pose) { + int coordinate = meta->coordinate_system > 0 ? meta->coordinate_system - 1 : 0; + const double *offset = meta->coordinate_offsets[coordinate]; + pose->tran.x = state->x + (machine_coordinates ? 0.0 : offset[0]); + pose->tran.y = state->y + (machine_coordinates ? 0.0 : offset[1]); + pose->tran.z = state->z + (machine_coordinates ? 0.0 : offset[2]); + pose->a = state->a + (machine_coordinates ? 0.0 : offset[3]); + pose->b = state->b + (machine_coordinates ? 0.0 : offset[4]); + pose->c = state->c + (machine_coordinates ? 0.0 : offset[5]); + pose->u = state->u + (machine_coordinates ? 0.0 : offset[6]); + pose->v = state->v + (machine_coordinates ? 0.0 : offset[7]); + pose->w = state->w + (machine_coordinates ? 0.0 : offset[8]); +} + static void set_error(sim_interpreter *interpreter, interpreter_meta *meta, int code, uint32_t column) { if (interpreter != NULL) interpreter->state.status = code; if (meta != NULL) { meta->error_code = code; meta->error_column = column; } @@ -166,6 +184,13 @@ static int parameter_lookup(const expression_parser *parser, uint32_t index, dou static int named_lookup(expression_parser *parser, const char *name, double *value, int create) { size_t index; if (name == NULL || name[0] == '\0' || value == NULL) return SIM_INTERP_ERR_PARAMETER; + if (name[0] == '_' && name[2] == '\0') { + int axis = axis_index((char)toupper((unsigned char)name[1])); + if (axis >= 0) { + *value = *axis_pointer((sim_interpreter_state *)&parser->meta->owner->state, axis); + return isfinite(*value) ? SIM_INTERP_OK : SIM_INTERP_ERR_NONFINITE; + } + } for (index = 0; index < NAMED_PARAMETER_CAPACITY; ++index) { if (parser->meta->named[index].used && strcmp(parser->meta->named[index].name, name) == 0) { *value = parser->meta->named[index].value; return SIM_INTERP_OK; } } @@ -317,10 +342,12 @@ static int apply_g(sim_interpreter_state *state, interpreter_meta *meta, double if (code_is(code, 17) || code_is(code, 18) || code_is(code, 19)) { if (++groups[1] > 1) return SIM_INTERP_ERR_STATE; state->plane = (int)code; return SIM_INTERP_OK; } if (code_is(code, 20) || code_is(code, 21)) { if (++groups[2] > 1) return SIM_INTERP_ERR_STATE; state->units = (int)code; return SIM_INTERP_OK; } if (code_is(code, 90) || code_is(code, 91)) { if (++groups[3] > 1) return SIM_INTERP_ERR_STATE; state->distance_mode = (int)code; return SIM_INTERP_OK; } + if (code_is(code, 93) || code_is(code, 94)) { if (++groups[6] > 1) return SIM_INTERP_ERR_STATE; if (meta) meta->feed_mode = (int)code; return SIM_INTERP_OK; } if (code_is(code, 40) || code_is(code, 41) || code_is(code, 42)) { if (++groups[4] > 1) return SIM_INTERP_ERR_STATE; if (meta) meta->cutter_comp = (int)code; return SIM_INTERP_OK; } if (code_is(code, 43) || code_is(code, 49)) { if (++groups[5] > 1) return SIM_INTERP_ERR_STATE; if (meta && code_is(code, 49)) meta->tool_length = 0.0; return SIM_INTERP_OK; } if (code_is(code, 80) || (code >= 81.0 && code <= 89.0 && floor(code) == code)) { if (meta) meta->cycle_mode = (int)code; return SIM_INTERP_OK; } if (code_is(code, 54) || code_is(code, 55) || code_is(code, 56) || code_is(code, 57) || code_is(code, 58) || code_is(code, 59)) { if (meta) meta->coordinate_system = (int)code - 53; return SIM_INTERP_OK; } + if (code_is(code, 53)) return SIM_INTERP_OK; if (code_is(code, 10)) return SIM_INTERP_OK; return SIM_INTERP_ERR_UNKNOWN_CODE; } @@ -333,6 +360,7 @@ static int apply_m(sim_interpreter_state *state, interpreter_meta *meta, double if (code_is(code, 8)) { if (meta) meta->coolant_mode = 8; return SIM_INTERP_OK; } if (code_is(code, 9)) { if (meta) meta->coolant_mode = 0; return SIM_INTERP_OK; } if (code_is(code, 19)) return SIM_INTERP_OK; + if (code_is(code, 428) || code_is(code, 429) || code_is(code, 430)) return SIM_INTERP_OK; if (code_is(code, 48) || code_is(code, 49) || code_is(code, 50) || code_is(code, 51) || code_is(code, 52) || code_is(code, 53)) return SIM_INTERP_OK; if (code >= 62.0 && code <= 68.0 && floor(code) == code) return SIM_INTERP_OK; if (code_is(code, 70) || code_is(code, 71) || code_is(code, 72) || code_is(code, 73)) return SIM_INTERP_OK; @@ -358,6 +386,7 @@ static uint64_t state_hash(const sim_interpreter *interpreter) { parameter_hash ^= fnv1a64((const unsigned char *)&meta->coordinate_system, sizeof(meta->coordinate_system)); parameter_hash ^= fnv1a64((const unsigned char *)&meta->cutter_comp, sizeof(meta->cutter_comp)); parameter_hash ^= fnv1a64((const unsigned char *)&meta->cycle_mode, sizeof(meta->cycle_mode)); + parameter_hash ^= fnv1a64((const unsigned char *)&meta->feed_mode, sizeof(meta->feed_mode)); parameter_hash ^= fnv1a64((const unsigned char *)&meta->coolant_mode, sizeof(meta->coolant_mode)); parameter_hash ^= fnv1a64((const unsigned char *)&meta->selected_tool, sizeof(meta->selected_tool)); parameter_hash ^= fnv1a64((const unsigned char *)&meta->tool_length, sizeof(meta->tool_length)); @@ -367,7 +396,7 @@ static uint64_t state_hash(const sim_interpreter *interpreter) { } static uint64_t modal_hash(const sim_interpreter *interpreter) { - unsigned char bytes[sizeof(int) * 10 + sizeof(double) * 3]; size_t offset = 0; + unsigned char bytes[sizeof(int) * 11 + sizeof(double) * 3]; size_t offset = 0; memcpy(bytes + offset, &interpreter->state.units, sizeof(int)); offset += sizeof(int); memcpy(bytes + offset, &interpreter->state.distance_mode, sizeof(int)); offset += sizeof(int); memcpy(bytes + offset, &interpreter->state.plane, sizeof(int)); offset += sizeof(int); @@ -381,6 +410,7 @@ static uint64_t modal_hash(const sim_interpreter *interpreter) { memcpy(bytes + offset, &meta->coordinate_system, sizeof(int)); offset += sizeof(int); memcpy(bytes + offset, &meta->cutter_comp, sizeof(int)); offset += sizeof(int); memcpy(bytes + offset, &meta->cycle_mode, sizeof(int)); offset += sizeof(int); + memcpy(bytes + offset, &meta->feed_mode, sizeof(int)); offset += sizeof(int); memcpy(bytes + offset, &meta->coolant_mode, sizeof(int)); offset += sizeof(int); memcpy(bytes + offset, &meta->selected_tool, sizeof(int)); offset += sizeof(int); memcpy(bytes + offset, &meta->tool_length, sizeof(double)); offset += sizeof(double); @@ -405,7 +435,7 @@ int sim_interpreter_reset(sim_interpreter *interpreter) { interpreter_meta *meta; if (interpreter == NULL) return SIM_INTERP_ERR_ARGUMENT; memset(interpreter, 0, sizeof(*interpreter)); meta = meta_for(interpreter, 1); if (meta == NULL) return SIM_INTERP_ERR_BUFFER; meta_reset(meta, interpreter); - interpreter->state.units = SIM_INTERP_UNITS_MM; interpreter->state.distance_mode = SIM_INTERP_ABSOLUTE; interpreter->state.plane = 17; interpreter->state.motion_mode = 1; interpreter->state.spindle_mode = 5; interpreter->state.status = SIM_INTERP_OK; + interpreter->state.units = SIM_INTERP_UNITS_MM; interpreter->state.distance_mode = SIM_INTERP_ABSOLUTE; interpreter->state.plane = 17; interpreter->state.motion_mode = 1; interpreter->state.spindle_mode = 5; interpreter->state.status = SIM_INTERP_OK; meta->feed_mode = 94; return make_canonical(interpreter); } @@ -413,9 +443,9 @@ int sim_interpreter_init(sim_interpreter *interpreter) { return sim_interpreter_ int sim_interpreter_execute(sim_interpreter *interpreter, const char *block, uint32_t length) { sim_interpreter_state previous; sim_interpreter_state next; interpreter_meta *meta; expression_parser parser; const char *end; - int groups[6] = {0}, seen_axis[9] = {0}, seen_feed = 0, seen_speed = 0, seen_line = 0, seen_p = 0, seen_r = 0, seen_g10 = 0, result = SIM_INTERP_OK; + int groups[7] = {0}, seen_axis[9] = {0}, seen_feed = 0, seen_speed = 0, seen_line = 0, seen_p = 0, seen_r = 0, seen_l = 0, seen_g10 = 0, seen_g53 = 0, result = SIM_INTERP_OK; int seen_center[3] = {0}; - double axis_values[9] = {0}, center_values[3] = {0}, feed_value = 0.0, speed_value = 0.0, p_value = 0.0, r_value = 0.0; + double axis_values[9] = {0}, center_values[3] = {0}, feed_value = 0.0, speed_value = 0.0, p_value = 0.0, r_value = 0.0, l_value = 0.0; if (interpreter == NULL || block == NULL || length == 0) return SIM_INTERP_ERR_ARGUMENT; meta = meta_for(interpreter, 1); if (meta == NULL || !finite_state(&interpreter->state)) return SIM_INTERP_ERR_STATE; if (interpreter->state.program_end) { set_error(interpreter, meta, SIM_INTERP_ERR_STATE, 1); return SIM_INTERP_ERR_STATE; } @@ -462,7 +492,8 @@ int sim_interpreter_execute(sim_interpreter *interpreter, const char *block, uin else center_values[center_index] = value; break; } - case 'L': case 'Q': case 'D': case 'E': break; + case 'L': if (seen_l++) result = SIM_INTERP_ERR_STATE; else l_value = value; break; + case 'Q': case 'D': case 'E': break; case 'P': if (seen_p++) result = SIM_INTERP_ERR_STATE; else p_value = value; break; case 'R': if (seen_r++) result = SIM_INTERP_ERR_STATE; else r_value = value; break; case 'T': if (value < 0.0 || value > 1001.0 || floor(value) != value) result = SIM_INTERP_ERR_RANGE; else meta->selected_tool = (int)value; break; @@ -472,6 +503,7 @@ int sim_interpreter_execute(sim_interpreter *interpreter, const char *block, uin break; } if (letter == 'G' && code_is(value, 10)) seen_g10 = 1; + if (letter == 'G' && code_is(value, 53)) seen_g53 = 1; if (result != SIM_INTERP_OK) { set_error(interpreter, meta, result, column); return result; } } skip_space(&parser); if (parser.cursor < end && *parser.cursor != ';') { set_error(interpreter, meta, SIM_INTERP_ERR_SYNTAX, (uint32_t)(parser.cursor - block + 1)); return SIM_INTERP_ERR_SYNTAX; } @@ -482,10 +514,18 @@ int sim_interpreter_execute(sim_interpreter *interpreter, const char *block, uin double axis_value = axis_values[axis]; double *destination = axis_pointer(&next, (int)axis); if (next.units == SIM_INTERP_UNITS_INCH && axis < 3) axis_value *= 25.4; if (seen_g10) { - if (!seen_p || p_value < 1.0 || p_value > 9.0 || floor(p_value) != p_value) { set_error(interpreter, meta, SIM_INTERP_ERR_PARAMETER, 1); return SIM_INTERP_ERR_PARAMETER; } - meta->coordinate_offsets[(int)p_value - 1][axis] = axis_value; + int coordinate; + if (!seen_p || p_value < 0.0 || p_value > 9.0 || floor(p_value) != p_value || !seen_l || (!code_is(l_value, 2) && !code_is(l_value, 20))) { set_error(interpreter, meta, SIM_INTERP_ERR_PARAMETER, 1); return SIM_INTERP_ERR_PARAMETER; } + coordinate = p_value == 0.0 ? (meta->coordinate_system > 0 ? meta->coordinate_system - 1 : 0) : (int)p_value - 1; + if (code_is(l_value, 20)) { + meta->coordinate_offsets[coordinate][axis] = *axis_pointer(&previous, (int)axis) - axis_value; + if (p_value == 0.0) meta->coordinate_l20 = 1; + *destination = axis_value; + } else { + meta->coordinate_offsets[coordinate][axis] = axis_value; + } } else if (next.distance_mode == SIM_INTERP_INCREMENTAL) *destination += axis_value; - else *destination = axis_value + meta->coordinate_offsets[meta->coordinate_system > 0 ? meta->coordinate_system - 1 : 0][axis]; + else *destination = axis_value + (seen_g53 || meta->coordinate_l20 ? 0.0 : meta->coordinate_offsets[meta->coordinate_system > 0 ? meta->coordinate_system - 1 : 0][axis]); } } if (seen_g10 && !seen_axis[0] && !seen_axis[1] && !seen_axis[2]) { set_error(interpreter, meta, SIM_INTERP_ERR_PARAMETER, 1); return SIM_INTERP_ERR_PARAMETER; } @@ -502,25 +542,54 @@ int sim_interpreter_execute(sim_interpreter *interpreter, const char *block, uin int has_axis_motion = 0; int has_center = seen_center[0] || seen_center[1] || seen_center[2]; for (axis = 0; axis < 9; ++axis) if (seen_axis[axis]) { has_axis_motion = 1; break; } - if ((has_axis_motion || has_center) && next.motion_mode >= 0 && next.motion_mode <= 3) { + if (!seen_g10 && (has_axis_motion || has_center) && next.motion_mode >= 0 && next.motion_mode <= 3) { sim_posemath_segment *segment = &meta->last_motion; memset(segment, 0, sizeof(*segment)); - segment->start.tran.x = previous.x; segment->start.tran.y = previous.y; segment->start.tran.z = previous.z; - segment->start.a = previous.a; segment->start.b = previous.b; segment->start.c = previous.c; - segment->start.u = previous.u; segment->start.v = previous.v; segment->start.w = previous.w; - segment->end.tran.x = next.x; segment->end.tran.y = next.y; segment->end.tran.z = next.z; - segment->end.a = next.a; segment->end.b = next.b; segment->end.c = next.c; - segment->end.u = next.u; segment->end.v = next.v; segment->end.w = next.w; - segment->velocity = next.feed; + if (meta->has_output_pose) segment->start = meta->last_output_pose; + else machine_pose_for_state(meta, &previous, seen_g53, &segment->start); + machine_pose_for_state(meta, &next, seen_g53, &segment->end); + segment->velocity = next.feed / 60.0; segment->acceleration = 0.0; segment->motion_type = next.motion_mode >= 2 ? SIM_POSEMATH_CIRCULAR : SIM_POSEMATH_LINEAR; - segment->turn = next.motion_mode == 2 ? -1 : 1; - segment->center.x = previous.x; segment->center.y = previous.y; segment->center.z = previous.z; + if (next.motion_mode >= 2 && seen_p && (p_value < 1.0 || p_value > 1000000.0 || floor(p_value) != p_value)) { set_error(interpreter, meta, SIM_INTERP_ERR_RANGE, 1); return SIM_INTERP_ERR_RANGE; } + segment->turn = (next.motion_mode == 2 ? -1 : 1) * (next.motion_mode >= 2 && seen_p ? (int)p_value : 1); + segment->center.x = segment->start.tran.x; segment->center.y = segment->start.tran.y; segment->center.z = segment->start.tran.z; if (next.units == SIM_INTERP_UNITS_INCH) for (axis = 0; axis < 3; ++axis) center_values[axis] *= 25.4; segment->center.x += center_values[0]; segment->center.y += center_values[1]; segment->center.z += center_values[2]; + meta->last_output_pose = segment->end; + meta->has_output_pose = 1; if (next.plane == 18) segment->normal.y = 1.0; else if (next.plane == 19) segment->normal.x = 1.0; else segment->normal.z = 1.0; + if (meta->feed_mode == 93) { + const double dx = segment->end.tran.x - segment->start.tran.x; + const double dy = segment->end.tran.y - segment->start.tran.y; + const double dz = segment->end.tran.z - segment->start.tran.z; + const double da = segment->end.a - segment->start.a; + const double db = segment->end.b - segment->start.b; + const double dc = segment->end.c - segment->start.c; + const double du = segment->end.u - segment->start.u; + const double dv = segment->end.v - segment->start.v; + const double dw = segment->end.w - segment->start.w; + double path_length = sqrt(dx * dx + dy * dy + dz * dz + da * da + db * db + dc * dc + du * du + dv * dv + dw * dw); + if (next.motion_mode >= 2) { + const double sx = segment->start.tran.x - segment->center.x; + const double sy = segment->start.tran.y - segment->center.y; + const double sz = segment->start.tran.z - segment->center.z; + const double ex = segment->end.tran.x - segment->center.x; + const double ey = segment->end.tran.y - segment->center.y; + const double ez = segment->end.tran.z - segment->center.z; + const double radius = sqrt(sx * sx + sy * sy + sz * sz); + const double dot = sx * ex + sy * ey + sz * ez; + const double cross_normal = segment->normal.x * (sy * ez - sz * ey) + segment->normal.y * (sz * ex - sx * ez) + segment->normal.z * (sx * ey - sy * ex); + double angle = fabs(atan2(cross_normal, dot)); + if (angle <= 1e-12) angle = 2.0 * 3.14159265358979323846; + angle += 2.0 * 3.14159265358979323846 * (fabs((double)segment->turn) - 1.0); + path_length = sqrt((radius * angle) * (radius * angle) + dz * dz + da * da + db * db + dc * dc + du * du + dv * dv + dw * dw); + } + if (!isfinite(path_length) || path_length <= 0.0 || next.feed <= 0.0) { set_error(interpreter, meta, SIM_INTERP_ERR_RANGE, 1); return SIM_INTERP_ERR_RANGE; } + segment->velocity = path_length * next.feed / 60.0; + } meta->has_motion = 1; } } diff --git a/wasm-core/src/sim_io.c b/wasm-core/src/sim_io.c index f07bd11..2f430ca 100644 --- a/wasm-core/src/sim_io.c +++ b/wasm-core/src/sim_io.c @@ -34,6 +34,8 @@ static int valid_io(const sim_io *io) { io->state.spindle_count <= SIM_IO_MAX_SPINDLES; } +uint32_t sim_io_size(void) { return (uint32_t)sizeof(sim_io); } + static int valid_spindle(const sim_io *io, uint32_t spindle) { return valid_io(io) && spindle < io->state.spindle_count && io->state.spindles[spindle].registered; diff --git a/wasm-core/src/sim_motion_queue.c b/wasm-core/src/sim_motion_queue.c index daf1871..77e123a 100644 --- a/wasm-core/src/sim_motion_queue.c +++ b/wasm-core/src/sim_motion_queue.c @@ -53,7 +53,13 @@ static double segment_length(const sim_posemath_segment *segment) { const double dx = segment->end.tran.x - segment->start.tran.x; const double dy = segment->end.tran.y - segment->start.tran.y; const double dz = segment->end.tran.z - segment->start.tran.z; - double value = dx * dx + dy * dy + dz * dz; + double value = dx * dx + dy * dy + dz * dz + + (segment->end.a - segment->start.a) * (segment->end.a - segment->start.a) + + (segment->end.b - segment->start.b) * (segment->end.b - segment->start.b) + + (segment->end.c - segment->start.c) * (segment->end.c - segment->start.c) + + (segment->end.u - segment->start.u) * (segment->end.u - segment->start.u) + + (segment->end.v - segment->start.v) * (segment->end.v - segment->start.v) + + (segment->end.w - segment->start.w) * (segment->end.w - segment->start.w); if (segment->motion_type == SIM_POSEMATH_CIRCULAR) { const double sx = segment->start.tran.x - segment->center.x; const double sy = segment->start.tran.y - segment->center.y; diff --git a/wasm-core/src/sim_posemath.c b/wasm-core/src/sim_posemath.c index 3239897..e380b44 100644 --- a/wasm-core/src/sim_posemath.c +++ b/wasm-core/src/sim_posemath.c @@ -117,7 +117,13 @@ int sim_posemath_segment_validate(const sim_posemath_segment *segment) { if (segment->velocity < 0.0 || segment->acceleration < 0.0 || segment->velocity > 1e9 || segment->acceleration > 1e12) return SIM_POSEMATH_ERR_RANGE; length_sq = (segment->end.tran.x - segment->start.tran.x) * (segment->end.tran.x - segment->start.tran.x) + (segment->end.tran.y - segment->start.tran.y) * (segment->end.tran.y - segment->start.tran.y) + - (segment->end.tran.z - segment->start.tran.z) * (segment->end.tran.z - segment->start.tran.z); + (segment->end.tran.z - segment->start.tran.z) * (segment->end.tran.z - segment->start.tran.z) + + (segment->end.a - segment->start.a) * (segment->end.a - segment->start.a) + + (segment->end.b - segment->start.b) * (segment->end.b - segment->start.b) + + (segment->end.c - segment->start.c) * (segment->end.c - segment->start.c) + + (segment->end.u - segment->start.u) * (segment->end.u - segment->start.u) + + (segment->end.v - segment->start.v) * (segment->end.v - segment->start.v) + + (segment->end.w - segment->start.w) * (segment->end.w - segment->start.w); if (!isfinite(length_sq) || (length_sq <= 1e-24 && segment->motion_type != SIM_POSEMATH_CIRCULAR)) return SIM_POSEMATH_ERR_DEGENERATE; if (segment->motion_type == SIM_POSEMATH_CIRCULAR) { normal_sq = segment->normal.x * segment->normal.x + segment->normal.y * segment->normal.y + segment->normal.z * segment->normal.z; diff --git a/wasm-core/src/sim_program.c b/wasm-core/src/sim_program.c new file mode 100644 index 0000000..6e48d3a --- /dev/null +++ b/wasm-core/src/sim_program.c @@ -0,0 +1,410 @@ +#include "sim_program.h" + +#include +#include +#include +#include +#include + +static uint64_t fnv1a64(const unsigned char *bytes, size_t length) { + uint64_t hash = UINT64_C(1469598103934665603); + size_t index; + for (index = 0; index < length; ++index) { hash ^= bytes[index]; hash *= UINT64_C(1099511628211); } + return hash; +} + +static int control_line(const char *line) { + const char *cursor = line; + while (*cursor != '\0' && isspace((unsigned char)*cursor)) ++cursor; + if (*cursor == 'O' || *cursor == 'o') return 1; + if ((cursor[0] == 'M' || cursor[0] == 'm') && (cursor[1] == '8' || cursor[1] == '9')) return 1; + if ((cursor[0] == 'M' || cursor[0] == 'm') && (cursor[1] == '9' || cursor[1] == '8')) return 1; + return 0; +} + +static uint32_t line_length(const char *line, uint32_t maximum) { + uint32_t length = 0; + while (length < maximum && line[length] != '\0' && line[length] != '\n' && line[length] != '\r') ++length; + return length; +} + +static int span_equal(const char *value, size_t length, const char *expected) { + size_t index; + if (strlen(expected) != length) return 0; + for (index = 0; index < length; ++index) + if (tolower((unsigned char)value[index]) != tolower((unsigned char)expected[index])) return 0; + return 1; +} + +static int parse_oword(const char *line, uint32_t length, char *name, size_t name_capacity, + const char **verb, size_t *verb_length, const char **arguments) { + const char *cursor = line; + const char *end = line + length; + size_t name_length = 0; + while (cursor < end && isspace((unsigned char)*cursor)) ++cursor; + if (cursor >= end || tolower((unsigned char)*cursor++) != 'o' || cursor >= end || *cursor++ != '<') return 0; + while (cursor < end && *cursor != '>') { + if (name_length + 1u >= name_capacity) return 0; + name[name_length++] = (char)tolower((unsigned char)*cursor++); + } + if (cursor >= end || *cursor++ != '>' || name_length == 0) return 0; + name[name_length] = '\0'; + while (cursor < end && isspace((unsigned char)*cursor)) ++cursor; + *verb = cursor; + while (cursor < end && isalpha((unsigned char)*cursor)) ++cursor; + *verb_length = (size_t)(cursor - *verb); + while (cursor < end && isspace((unsigned char)*cursor)) ++cursor; + *arguments = cursor; + return *verb_length > 0; +} + +int32_t sim_program_requires_subroutines(const char *source, uint32_t length) { + uint32_t offset = 0; + if (source == NULL || length == 0 || length >= SIM_PROGRAM_SOURCE_CAPACITY) return SIM_PROGRAM_ERR_ARGUMENT; + while (offset < length) { + uint32_t available = length - offset; + uint32_t line_size = line_length(source + offset, available); + char name[SIM_PROGRAM_SUBROUTINE_NAME_CAPACITY] = {0}; + const char *verb = NULL, *arguments = NULL; + size_t verb_length = 0; + if (parse_oword(source + offset, line_size, name, sizeof(name), &verb, &verb_length, &arguments) && span_equal(verb, verb_length, "call")) return 1; + offset += line_size; + while (offset < length && (source[offset] == '\n' || source[offset] == '\r')) ++offset; + } + return 0; +} + +static void reindex_source(sim_program *program) { + uint32_t index; + program->line_count = program->source_length == 0 ? 0 : 1; + program->line_offsets[0] = 0; + for (index = 0; index < program->source_length; ++index) if (program->source[index] == '\n' && index + 1u < program->source_length) { + if (program->line_count < SIM_PROGRAM_LINE_CAPACITY) program->line_offsets[program->line_count++] = index + 1u; + } + program->line_offsets[program->line_count] = program->source_length; +} + +static int append_source(sim_program *program, const char *source, uint32_t length) { + uint32_t separator = program->source_length > 0 && program->source[program->source_length - 1u] != '\n' ? 1u : 0u; + if (source == NULL || length == 0 || program->source_length + separator + length >= SIM_PROGRAM_SOURCE_CAPACITY) return SIM_PROGRAM_ERR_RANGE; + if (separator) program->source[program->source_length++] = '\n'; + memcpy(program->source + program->source_length, source, length); + program->source_length += length; + program->source[program->source_length] = '\0'; + reindex_source(program); + return SIM_PROGRAM_OK; +} + +static int scan_subroutines(sim_program *program) { + uint32_t line; + program->subroutine_count = 0; + for (line = program->main_line_count; line < program->line_count; ++line) { + const char *start = program->source + program->line_offsets[line]; + uint32_t maximum = program->line_offsets[line + 1u] - program->line_offsets[line]; + uint32_t length = line_length(start, maximum); + char name[SIM_PROGRAM_SUBROUTINE_NAME_CAPACITY] = {0}; + const char *verb = NULL, *arguments = NULL; + size_t verb_length = 0; + uint32_t end_line; + if (!parse_oword(start, length, name, sizeof(name), &verb, &verb_length, &arguments) || !span_equal(verb, verb_length, "sub")) continue; + for (end_line = line + 1u; end_line < program->line_count; ++end_line) { + const char *end_start = program->source + program->line_offsets[end_line]; + uint32_t end_maximum = program->line_offsets[end_line + 1u] - program->line_offsets[end_line]; + uint32_t end_length = line_length(end_start, end_maximum); + char end_name[SIM_PROGRAM_SUBROUTINE_NAME_CAPACITY] = {0}; + const char *end_verb = NULL, *end_arguments = NULL; + size_t end_verb_length = 0; + if (parse_oword(end_start, end_length, end_name, sizeof(end_name), &end_verb, &end_verb_length, &end_arguments) && strcmp(name, end_name) == 0 && span_equal(end_verb, end_verb_length, "endsub")) break; + } + if (end_line >= program->line_count || program->subroutine_count >= SIM_PROGRAM_SUBROUTINE_CAPACITY) return SIM_PROGRAM_ERR_CONTROL; + strncpy(program->subroutines[program->subroutine_count].name, name, SIM_PROGRAM_SUBROUTINE_NAME_CAPACITY - 1u); + program->subroutines[program->subroutine_count].body_line = line + 1u; + program->subroutines[program->subroutine_count].end_line = end_line; + program->subroutine_count += 1u; + line = end_line; + } + return SIM_PROGRAM_OK; +} + +static const sim_program_subroutine *find_subroutine(const sim_program *program, const char *name) { + uint32_t index; + for (index = 0; index < program->subroutine_count; ++index) + if (strcmp(program->subroutines[index].name, name) == 0) return &program->subroutines[index]; + return NULL; +} + +static int evaluate_call_arguments(sim_program *program, const char *cursor, const char *end, + double *values, uint32_t *count) { + uint32_t item = 0; + while (cursor < end) { + const char *start; + const char *finish; + int depth = 0; + char assignment[512]; + int written; + while (cursor < end && isspace((unsigned char)*cursor)) ++cursor; + if (cursor >= end || *cursor == ';' || *cursor == '(') break; + if (item >= SIM_PROGRAM_CALL_PARAMETER_CAPACITY) return SIM_PROGRAM_ERR_CONTROL; + start = cursor; + if (*cursor == '[') { + do { + if (*cursor == '[') depth += 1; + else if (*cursor == ']') depth -= 1; + ++cursor; + } while (cursor < end && depth > 0); + if (depth != 0) return SIM_PROGRAM_ERR_CONTROL; + finish = cursor; + } else { + while (cursor < end && !isspace((unsigned char)*cursor) && *cursor != ';' && *cursor != '(') ++cursor; + finish = cursor; + } + written = snprintf(assignment, sizeof(assignment), "#5000=%.*s", (int)(finish - start), start); + if (written <= 0 || (size_t)written >= sizeof(assignment) || sim_interpreter_execute(&program->interpreter, assignment, (uint32_t)written) != SIM_INTERP_OK || sim_interpreter_parameter_get(&program->interpreter, 5000, &values[item]) != SIM_INTERP_OK) return SIM_PROGRAM_ERR_INTERPRETER; + item += 1u; + } + *count = item; + return SIM_PROGRAM_OK; +} + +static int begin_call(sim_program *program, const char *name, const char *arguments, const char *end) { + const sim_program_subroutine *subroutine = find_subroutine(program, name); + sim_program_call_frame *frame; + double values[SIM_PROGRAM_CALL_PARAMETER_CAPACITY] = {0}; + uint32_t count = 0, index; + int result; + if (subroutine == NULL || program->call_depth >= SIM_PROGRAM_CALL_DEPTH) return SIM_PROGRAM_ERR_CONTROL; + result = evaluate_call_arguments(program, arguments, end, values, &count); + if (result != SIM_PROGRAM_OK) return result; + frame = &program->call_stack[program->call_depth++]; + frame->return_line = program->current_line; + for (index = 0; index < SIM_PROGRAM_CALL_PARAMETER_CAPACITY; ++index) { + if (sim_interpreter_parameter_get(&program->interpreter, index + 1u, &frame->parameters[index]) != SIM_INTERP_OK) return SIM_PROGRAM_ERR_INTERPRETER; + if (sim_interpreter_parameter_set(&program->interpreter, index + 1u, index < count ? values[index] : 0.0) != SIM_INTERP_OK) return SIM_PROGRAM_ERR_INTERPRETER; + } + program->current_line = subroutine->body_line; + return SIM_PROGRAM_OK; +} + +static int end_call(sim_program *program) { + sim_program_call_frame *frame; + uint32_t index; + if (program->call_depth == 0) return SIM_PROGRAM_ERR_CONTROL; + frame = &program->call_stack[--program->call_depth]; + for (index = 0; index < SIM_PROGRAM_CALL_PARAMETER_CAPACITY; ++index) + if (sim_interpreter_parameter_set(&program->interpreter, index + 1u, frame->parameters[index]) != SIM_INTERP_OK) return SIM_PROGRAM_ERR_INTERPRETER; + program->current_line = frame->return_line; + return SIM_PROGRAM_OK; +} + +static int switch_mcode(const char *block, uint32_t length) { + const char *cursor = block; + const char *end = block + length; + while (cursor < end) { + if (*cursor == ';') break; + if (*cursor == '(') { while (cursor < end && *cursor++ != ')') {} continue; } + if (toupper((unsigned char)*cursor) == 'M') { + char *number_end = NULL; + long code = strtol(cursor + 1, &number_end, 10); + if (number_end != cursor + 1 && (code == 428 || code == 429 || code == 430)) return (int)code; + } + ++cursor; + } + return 0; +} + +static void reset_runtime(sim_program *program) { + sim_interpreter_reset(&program->interpreter); + program->source_length = 0; + program->line_count = 0; + program->main_line_count = 0; + program->current_line = 0; + program->status = SIM_PROGRAM_IDLE; + program->last_error = 0; + program->error_line = 0; + program->has_motion = 0; + program->subroutine_count = 0; + program->call_depth = 0; + program->has_control = 0; + program->control_code = 0; + program->rapid_velocity = 35.0; + memset(&program->motion, 0, sizeof(program->motion)); + memset(program->subroutines, 0, sizeof(program->subroutines)); + memset(program->call_stack, 0, sizeof(program->call_stack)); +} + +uint32_t sim_program_size(void) { return (uint32_t)sizeof(sim_program); } + +int32_t sim_program_init(sim_program *program) { + if (program == NULL) return SIM_PROGRAM_ERR_ARGUMENT; + memset(program, 0, sizeof(*program)); + if (sim_interpreter_init(&program->interpreter) != SIM_INTERP_OK) return SIM_PROGRAM_ERR_INTERPRETER; + program->status = SIM_PROGRAM_IDLE; + return SIM_PROGRAM_OK; +} + +int32_t sim_program_reset(sim_program *program) { + if (program == NULL) return SIM_PROGRAM_ERR_ARGUMENT; + if (sim_interpreter_reset(&program->interpreter) != SIM_INTERP_OK) return SIM_PROGRAM_ERR_INTERPRETER; + reset_runtime(program); + return SIM_PROGRAM_OK; +} + +int32_t sim_program_load(sim_program *program, const char *source, uint32_t length) { + if (program == NULL || source == NULL) return SIM_PROGRAM_ERR_ARGUMENT; + if (length == 0 || length >= SIM_PROGRAM_SOURCE_CAPACITY) return SIM_PROGRAM_ERR_RANGE; + if (sim_program_reset(program) != SIM_PROGRAM_OK) return SIM_PROGRAM_ERR_INTERPRETER; + if (append_source(program, source, length) != SIM_PROGRAM_OK) return SIM_PROGRAM_ERR_RANGE; + program->main_line_count = program->line_count; + program->status = SIM_PROGRAM_LOADED; + return SIM_PROGRAM_OK; +} + +int32_t sim_program_add_subroutine(sim_program *program, const char *source, uint32_t length) { + int result; + if (program == NULL || source == NULL || program->status != SIM_PROGRAM_LOADED) return SIM_PROGRAM_ERR_STATE; + result = append_source(program, source, length); + if (result != SIM_PROGRAM_OK) return result; + return scan_subroutines(program); +} + +int32_t sim_program_set_rapid_velocity(sim_program *program, double velocity) { + if (program == NULL || !isfinite(velocity) || velocity <= 0.0 || velocity > 1e9) return SIM_PROGRAM_ERR_RANGE; + program->rapid_velocity = velocity; + return SIM_PROGRAM_OK; +} + +int32_t sim_program_start(sim_program *program) { + if (program == NULL || program->status == SIM_PROGRAM_IDLE) return SIM_PROGRAM_ERR_STATE; + if (program->status == SIM_PROGRAM_COMPLETED || program->status == SIM_PROGRAM_ABORTED) return SIM_PROGRAM_ERR_STATE; + program->status = SIM_PROGRAM_RUNNING; + return SIM_PROGRAM_OK; +} + +int32_t sim_program_pause(sim_program *program) { + if (program == NULL || program->status != SIM_PROGRAM_RUNNING) return SIM_PROGRAM_ERR_STATE; + program->status = SIM_PROGRAM_PAUSED; + return SIM_PROGRAM_OK; +} + +int32_t sim_program_resume(sim_program *program) { + if (program == NULL || program->status != SIM_PROGRAM_PAUSED) return SIM_PROGRAM_ERR_STATE; + program->status = SIM_PROGRAM_RUNNING; + return SIM_PROGRAM_OK; +} + +int32_t sim_program_abort(sim_program *program) { + if (program == NULL) return SIM_PROGRAM_ERR_ARGUMENT; + program->status = SIM_PROGRAM_ABORTED; + program->has_motion = 0; + return SIM_PROGRAM_OK; +} + +int32_t sim_program_execute_block(sim_program *program, const char *block, uint32_t length) { + sim_posemath_segment segment; + int result; + if (program == NULL || block == NULL || length == 0) return SIM_PROGRAM_ERR_ARGUMENT; + if (control_line(block)) return SIM_PROGRAM_ERR_CONTROL; + program->has_control = 0; + program->control_code = switch_mcode(block, length); + if (program->control_code != 0) program->has_control = 1; + result = sim_interpreter_execute(&program->interpreter, block, length); + if (result != SIM_INTERP_OK) { program->last_error = result; return SIM_PROGRAM_ERR_INTERPRETER; } + memset(&segment, 0, sizeof(segment)); + if (sim_interpreter_read_motion(&program->interpreter, &segment) == SIM_INTERP_OK && segment.motion_type != 0) { + if (program->interpreter.state.motion_mode == 0) segment.velocity = program->rapid_velocity; + program->motion = segment; program->has_motion = 1; + } else program->has_motion = 0; + return SIM_PROGRAM_OK; +} + +int32_t sim_program_step(sim_program *program) { + uint32_t line; + if (program == NULL) return SIM_PROGRAM_ERR_ARGUMENT; + if (program->status == SIM_PROGRAM_PAUSED) return SIM_PROGRAM_ERR_STATE; + if (program->status != SIM_PROGRAM_RUNNING) return SIM_PROGRAM_ERR_STATE; + program->has_motion = 0; + program->has_control = 0; + program->control_code = 0; + while (program->current_line < program->line_count) { + const char *line_start = program->source + program->line_offsets[program->current_line]; + uint32_t maximum = program->line_offsets[program->current_line + 1u] - program->line_offsets[program->current_line]; + uint32_t length = line_length(line_start, maximum); + program->current_line += 1; + line = program->current_line; + while (length > 0 && isspace((unsigned char)line_start[length - 1u])) --length; + if (length == 0 || line_start[0] == ';') continue; + { + char name[SIM_PROGRAM_SUBROUTINE_NAME_CAPACITY] = {0}; + const char *verb = NULL, *arguments = NULL; + size_t verb_length = 0; + if (parse_oword(line_start, length, name, sizeof(name), &verb, &verb_length, &arguments)) { + int control_result; + if (span_equal(verb, verb_length, "call")) control_result = begin_call(program, name, arguments, line_start + length); + else if (span_equal(verb, verb_length, "endsub")) control_result = end_call(program); + else if (span_equal(verb, verb_length, "sub")) { + const sim_program_subroutine *declared = find_subroutine(program, name); + program->current_line = declared ? declared->end_line + 1u : program->line_count; + continue; + } + else control_result = SIM_PROGRAM_ERR_CONTROL; + if (control_result != SIM_PROGRAM_OK) { program->last_error = control_result; program->error_line = line; program->status = SIM_PROGRAM_ERROR; return control_result; } + return SIM_PROGRAM_OK; + } + } + if (control_line(line_start)) { program->last_error = SIM_PROGRAM_ERR_CONTROL; program->error_line = line; program->status = SIM_PROGRAM_ERROR; return SIM_PROGRAM_ERR_CONTROL; } + if (sim_program_execute_block(program, line_start, length) != SIM_PROGRAM_OK) { program->error_line = line; program->status = SIM_PROGRAM_ERROR; return SIM_PROGRAM_ERR_INTERPRETER; } + if (program->interpreter.state.program_end || (program->call_depth == 0 && program->current_line >= program->main_line_count)) program->status = SIM_PROGRAM_COMPLETED; + return SIM_PROGRAM_OK; + } + program->status = SIM_PROGRAM_COMPLETED; + return SIM_PROGRAM_OK; +} + +int32_t sim_program_seek(sim_program *program, uint32_t line) { + if (program == NULL || line > program->line_count) return SIM_PROGRAM_ERR_RANGE; + if (sim_interpreter_reset(&program->interpreter) != SIM_INTERP_OK) return SIM_PROGRAM_ERR_INTERPRETER; + program->current_line = 0; program->status = SIM_PROGRAM_PAUSED; program->has_motion = 0; + while (program->current_line < line) { + int result = sim_program_step(program); + if (result != SIM_PROGRAM_OK && result != SIM_PROGRAM_ERR_STATE) return result; + if (program->status == SIM_PROGRAM_COMPLETED) break; + program->status = SIM_PROGRAM_PAUSED; + if (program->current_line >= line) break; + program->status = SIM_PROGRAM_RUNNING; + } + program->status = SIM_PROGRAM_PAUSED; + return SIM_PROGRAM_OK; +} + +int32_t sim_program_read_motion(const sim_program *program, sim_posemath_segment *segment) { + if (program == NULL || segment == NULL) return SIM_PROGRAM_ERR_ARGUMENT; + if (!program->has_motion) return SIM_PROGRAM_ERR_STATE; + *segment = program->motion; + return SIM_PROGRAM_OK; +} + +int32_t sim_program_clear_motion(sim_program *program) { + if (program == NULL) return SIM_PROGRAM_ERR_ARGUMENT; + program->has_motion = 0; + memset(&program->motion, 0, sizeof(program->motion)); + return SIM_PROGRAM_OK; +} + +uint32_t sim_program_canonical(const sim_program *program, char *output, uint32_t capacity) { + char discard[1]; + char *destination = output == NULL ? discard : output; + uint32_t destination_capacity = output == NULL ? 1 : capacity; + int written; + if (program == NULL) return 0; + written = snprintf(destination, destination_capacity, + "{\"call_depth\":%u,\"control_code\":%d,\"current_line\":%u,\"error_line\":%u,\"has_control\":%u,\"has_motion\":%u,\"last_error\":%d,\"line_count\":%u,\"main_line_count\":%u,\"motion_mode\":%d,\"rapid_velocity\":%.17g,\"schema\":\"sim_program.v1\",\"status\":%u,\"subroutine_count\":%u,\"source_length\":%u,\"interpreter_state_hash\":\"%llu\"}", + program->call_depth, program->control_code, program->current_line, program->error_line, program->has_control, program->has_motion, program->last_error, program->line_count, program->main_line_count, program->interpreter.state.motion_mode, program->rapid_velocity, program->status, program->subroutine_count, program->source_length, + (unsigned long long)sim_interpreter_state_hash(&program->interpreter)); + return written < 0 ? 0 : (uint32_t)written + 1u; +} + +uint64_t sim_program_state_hash(const sim_program *program) { + char canonical[SIM_PROGRAM_CANONICAL_CAPACITY]; + uint32_t length = sim_program_canonical(program, canonical, sizeof(canonical)); + return length == 0 ? 0 : fnv1a64((const unsigned char *)canonical, length - 1u); +} diff --git a/wasm-core/src/sim_task.c b/wasm-core/src/sim_task.c index 34d4a18..b510c6a 100644 --- a/wasm-core/src/sim_task.c +++ b/wasm-core/src/sim_task.c @@ -68,7 +68,7 @@ static int transition_allowed(uint32_t from, uint32_t to) { if (from == SIM_TASK_PAUSED) return to == SIM_TASK_RUNNING || to == SIM_TASK_STOPPED || to == SIM_TASK_ESTOP || to == SIM_TASK_FAULT; if (from == SIM_TASK_ESTOP) return to == SIM_TASK_STOPPED || to == SIM_TASK_DESTROYED; if (from == SIM_TASK_FAULT) return to == SIM_TASK_STOPPED || to == SIM_TASK_DESTROYED; - if (from == SIM_TASK_STOPPED) return to == SIM_TASK_READY || to == SIM_TASK_DESTROYED; + if (from == SIM_TASK_STOPPED) return to == SIM_TASK_READY || to == SIM_TASK_ESTOP || to == SIM_TASK_DESTROYED; return 0; } diff --git a/wasm-core/tests/sim_contract_test.c b/wasm-core/tests/sim_contract_test.c index 974c651..c839fa0 100644 --- a/wasm-core/tests/sim_contract_test.c +++ b/wasm-core/tests/sim_contract_test.c @@ -30,7 +30,7 @@ static void test_protocol_contract(void) { static void test_event_contract(void) { const uint8_t payload[] = {'c', 'o', 'n', 't', 'r', 'a', 'c', 't'}; - uint8_t exported[16384] = {0}; + uint8_t exported[sizeof(uint32_t) * 3u + sizeof(sim_event_record) * SIM_EVENT_CAPACITY + 16u] = {0}; uint8_t record[sizeof(sim_event_record)] = {0}; uint32_t export_size; uint32_t index; @@ -43,7 +43,7 @@ static void test_event_contract(void) { assert(sim_event_read(0, record, sizeof(record)) == sizeof(sim_event_record)); assert(((sim_event_record *)record)->seq == 1); export_size = sim_event_export(NULL, 0); - assert(export_size > sizeof(sim_event_record) && export_size < sizeof(exported)); + assert(export_size > sizeof(sim_event_record) && export_size <= sizeof(exported)); assert(sim_event_export(exported, sizeof(exported)) == export_size); sim_event_reset(); assert(sim_event_import(exported, export_size) == SIM_EVENT_OK); diff --git a/wasm-core/tests/sim_interpreter_test.c b/wasm-core/tests/sim_interpreter_test.c index 127e365..0b9ac30 100644 --- a/wasm-core/tests/sim_interpreter_test.c +++ b/wasm-core/tests/sim_interpreter_test.c @@ -18,6 +18,8 @@ int main(void) { assert(sim_interpreter_execute(&interpreter, "G21 G90 G1 X10 Y2 F120", (uint32_t)(sizeof("G21 G90 G1 X10 Y2 F120") - 1)) == SIM_INTERP_OK); assert(sim_interpreter_read_state(&interpreter, &state) == SIM_INTERP_OK); assert(state.x == 10.0 && state.y == 2.0 && state.feed == 120.0); + assert(sim_interpreter_read_motion(&interpreter, &motion) == SIM_INTERP_OK); + assert(fabs(motion.velocity - 2.0) < 1e-12); required = sim_interpreter_canonical(&interpreter, canonical, sizeof(canonical)); assert(required > 1 && canonical[required - 1] == '\0'); assert(sim_interpreter_state_hash(&interpreter) != 0); @@ -62,6 +64,13 @@ int main(void) { assert(fabs(interpreter.state.x - 11.0) < 1e-12); assert(fabs(interpreter.state.y - 22.0) < 1e-12); assert(fabs(interpreter.state.z - 33.0) < 1e-12); + assert(sim_interpreter_execute(&interpreter, "G53 G0 X0 Y0 Z10", (uint32_t)(sizeof("G53 G0 X0 Y0 Z10") - 1)) == SIM_INTERP_OK); + assert(fabs(interpreter.state.x) < 1e-12 && fabs(interpreter.state.y) < 1e-12 && fabs(interpreter.state.z - 10.0) < 1e-12); + assert(sim_interpreter_execute(&interpreter, "G10 L20 P0 X0 Y0 Z10", (uint32_t)(sizeof("G10 L20 P0 X0 Y0 Z10") - 1)) == SIM_INTERP_OK); + assert(sim_interpreter_read_motion(&interpreter, &motion) == SIM_INTERP_ERR_STATE); + assert(sim_interpreter_execute(&interpreter, "G0 X20 Y20 Z10", (uint32_t)(sizeof("G0 X20 Y20 Z10") - 1)) == SIM_INTERP_OK); + assert(sim_interpreter_execute(&interpreter, "G0 X[#<_x>-10]", (uint32_t)(sizeof("G0 X[#<_x>-10]") - 1)) == SIM_INTERP_OK); + assert(fabs(interpreter.state.x - 10.0) < 1e-12 && fabs(interpreter.state.y - 20.0) < 1e-12); assert(sim_interpreter_reset(&interpreter) == SIM_INTERP_OK); assert(sim_interpreter_execute(&interpreter, "G54 G43 H12 G81 X1 Y2 Z-3 R1", (uint32_t)(sizeof("G54 G43 H12 G81 X1 Y2 Z-3 R1") - 1)) == SIM_INTERP_OK); assert(interpreter.state.motion_mode == 1); diff --git a/wasm-core/tests/sim_xyzac_trace_test.c b/wasm-core/tests/sim_xyzac_trace_test.c new file mode 100644 index 0000000..fd08364 --- /dev/null +++ b/wasm-core/tests/sim_xyzac_trace_test.c @@ -0,0 +1,136 @@ +#include "sim_kinematics.h" +#include "sim_program.h" +#include "sim_protocol.h" + +#include +#include +#include + +static sim_kinematics_config config_for(int type) { + static const double minimum[5] = {-200.0, -100.0, -120.0, -100.0, -36000.0}; + static const double maximum[5] = {200.0, 100.0, 120.0, 50.0, 36000.0}; + sim_kinematics_config config = {0}; + size_t index; + config.type = type; + config.joint_count = 5; + config.kinematics_joint_count = 5; + strcpy(config.coordinates, "XYZAC"); + config.y_offset = 20.0; + config.z_offset = 10.0; + for (index = 0; index < 5; ++index) { + config.limit_enabled[index] = 1; + config.joint_min[index] = minimum[index]; + config.joint_max[index] = maximum[index]; + } + return config; +} + +static void print_pose(const sim_posemath_pose *pose) { + printf("{\"a\":%.17g,\"c\":%.17g,\"x\":%.17g,\"y\":%.17g,\"z\":%.17g}", + pose->a, pose->c, pose->tran.x, pose->tran.y, pose->tran.z); +} + +static void print_joints(const double *joints) { + printf("[%.17g,%.17g,%.17g,%.17g,%.17g]", joints[0], joints[1], joints[2], joints[3], joints[4]); +} + +int main(void) { + static const char *commands[4] = {"M429", "M428", "M430", "M428"}; + static const int modes[4] = {0, 1, 2, 1}; + static const char source[] = "G21 G90 G94\nG0 X10 Y0 Z10 A0 C0\nG93\nG2 X10 Y0 Z5 A30 C45 I-10 J0 P3 F2\nM2\n"; + sim_kinematics identity = {0}; + sim_kinematics trt = {0}; + sim_kinematics userk = {0}; + sim_kinematics_switch switcher = {0}; + sim_kinematics_switch saved_switcher; + sim_kinematics_result_info info = {0}; + sim_posemath_pose poses[4] = {{0}}; + sim_posemath_pose pose = {0}; + sim_posemath_pose saved_pose = {0}; + sim_posemath_segment arc = {0}; + sim_program program = {0}; + double joints[5] = {12.0, -5.0, 20.0, 30.0, 45.0}; + double state_joints[4][5] = {{0}}; + double saved_joints[5] = {0}; + uint64_t before_hash; + uint64_t after_hash; + size_t index; + int have_arc = 0; + + assert(sim_kinematics_init(&identity, &(sim_kinematics_config){0}) != SIM_KIN_OK); + { + sim_kinematics_config config = config_for(SIM_KIN_TRIVKINS); + assert(sim_kinematics_init(&identity, &config) == SIM_KIN_OK); + assert(sim_kinematics_init(&userk, &config) == SIM_KIN_OK); + config = config_for(SIM_KIN_XYZAC_TRT); + assert(sim_kinematics_init(&trt, &config) == SIM_KIN_OK); + } + assert(sim_kinematics_switch_init(&switcher, 0, 0) == SIM_KIN_OK); + assert(sim_kinematics_switch_register(&switcher, 0, &identity, 0) == SIM_KIN_OK); + assert(sim_kinematics_switch_register(&switcher, 1, &trt, 0) == SIM_KIN_OK); + assert(sim_kinematics_switch_register(&switcher, 2, &userk, 0) == SIM_KIN_OK); + + sim_protocol_reset(); + assert(sim_protocol_accept(1, 1, "HELLO", "", 0) == SIM_PROTOCOL_OK); + assert(sim_protocol_accept(1, 2, "SESSION_ATTACH", "", 0) == SIM_PROTOCOL_OK); + assert(sim_protocol_accept(1, 3, "LOAD_WORKSPACE", "workspace", 0) == SIM_PROTOCOL_OK); + for (index = 0; index < 4; ++index) { + char operation[16]; + snprintf(operation, sizeof(operation), "switch-%u", (unsigned)(index + 1)); + assert(sim_protocol_accept(1, (uint32_t)(index + 4), "MDI_EXECUTE", operation, 0) == SIM_PROTOCOL_OK); + assert(sim_kinematics_switch_select(&switcher, modes[index], joints, 5, &pose, &info) == SIM_KIN_OK); + assert(sim_kinematics_switch_active(&switcher) == modes[index]); + poses[index] = pose; + memcpy(state_joints[index], joints, sizeof(joints)); + } + + assert(sim_program_init(&program) == SIM_PROGRAM_OK); + assert(sim_program_load(&program, source, (uint32_t)(sizeof(source) - 1)) == SIM_PROGRAM_OK); + assert(sim_program_start(&program) == SIM_PROGRAM_OK); + while (program.status == SIM_PROGRAM_RUNNING) { + assert(sim_program_step(&program) == SIM_PROGRAM_OK); + if (program.has_motion && program.motion.motion_type == SIM_POSEMATH_CIRCULAR) { + assert(sim_program_read_motion(&program, &arc) == SIM_PROGRAM_OK); + have_arc = 1; + } + } + assert(have_arc && arc.turn == -3); + + saved_switcher = switcher; + saved_pose = pose; + memcpy(saved_joints, joints, sizeof(joints)); + before_hash = sim_kinematics_switch_state_hash(&switcher, joints, 5, &pose); + assert(sim_kinematics_switch_select(&switcher, 0, joints, 5, &pose, &info) == SIM_KIN_OK); + switcher = saved_switcher; + pose = saved_pose; + memcpy(joints, saved_joints, sizeof(joints)); + after_hash = sim_kinematics_switch_state_hash(&switcher, joints, 5, &pose); + assert(before_hash == after_hash && sim_kinematics_switch_active(&switcher) == 1); + + printf("{\"case\":\"xyzac-trt.ini\",\"levels\":{"); + printf("\"protocol\":["); + for (index = 0; index < 4; ++index) { + if (index) printf(","); + printf("{\"command\":\"%s\",\"result\":\"verified\",\"seq\":%u,\"tick\":%u}", commands[index], (unsigned)(index + 4), (unsigned)(index + 1)); + } + printf("],\"control\":["); + for (index = 0; index < 4; ++index) { + if (index) printf(","); + printf("{\"active_type\":%d,\"command\":\"%s\",\"hal_pin\":\"motion.switchkins-type\",\"tick\":%u}", modes[index], commands[index], (unsigned)(index + 1)); + } + printf("],\"state\":["); + for (index = 0; index < 4; ++index) { + if (index) printf(","); + printf("{\"active_type\":%d,\"joints\":", modes[index]); + print_joints(state_joints[index]); + printf(",\"pose\":"); + print_pose(&poses[index]); + printf(",\"tick\":%u}", (unsigned)(index + 1)); + } + printf("],\"canonical\":[{\"end\":"); + print_pose(&arc.end); + printf(",\"motion_type\":%d,\"source_line\":4,\"tick\":5,\"turn\":%d,\"velocity\":%.17g}],", arc.motion_type, arc.turn, arc.velocity); + printf("\"recovery\":[{\"active_type\":%d,\"joints_equal\":true,\"pose_equal\":true,\"state_hash_equal\":true,\"tick\":6}]},", sim_kinematics_switch_active(&switcher)); + printf("\"schema\":\"xyzac-structured-trace.v1\",\"source\":\"linuxcnc-native-sim-core\",\"status\":\"verified\"}\n"); + return 0; +} diff --git a/web/app/axis-contract.mjs b/web/app/axis-contract.mjs index 27d8ccc..45a5131 100644 --- a/web/app/axis-contract.mjs +++ b/web/app/axis-contract.mjs @@ -9,6 +9,7 @@ export const AXIS_COMMANDS = Object.freeze({ run: "PROGRAM_RUN", step: "PROGRAM_STEP", pause: "PROGRAM_PAUSE", resume: "PROGRAM_RESUME", stop: "PROGRAM_ABORT", restart: "PROGRAM_RESTART", mdi: "MDI_EXECUTE", jogStart: "JOG_START", jogStop: "JOG_STOP", home: "HOME", override: "SET_OVERRIDE", estop: "ESTOP", recover: "IO_RECOVER", + power: "POWER", spindle: "SPINDLE_COMMAND", coolant: "COOLANT_COMMAND", toolPrepare: "TOOL_PREPARE", toolChange: "TOOL_CHANGE", probe: "PROBE_CONFIG", reset: "RESET", @@ -99,3 +100,27 @@ export function axisGate(action, input = {}) { export function axisGateMatrix(input = {}) { return Object.freeze(Object.fromEntries(Object.keys(AXIS_COMMANDS).map((action) => [action, axisGate(action, input)]))); } + +export const XYZAC_GATE_ACTIONS = Object.freeze(["switchkinsIdentity", "switchkinsXyzac", "switchkinsUserk", "vismachClear"]); +export const XYZAC_COMMANDS = Object.freeze({ switchkinsIdentity: "KINEMATICS_SELECT", switchkinsXyzac: "KINEMATICS_SELECT", switchkinsUserk: "KINEMATICS_SELECT", vismachClear: "VISUAL_CLEAR" }); + +export function xyzacGate(action, input = {}) { + const state = normalizeAxisState(input); + const xyzac = input.xyzac ?? {}; + const idle = state.interpState === "IDLE" && state.taskState === "ON"; + const offsets = xyzac.finite_offsets !== false; + const pinVars = xyzac.hal_pin_vars === true; + const net = xyzac.switchkins_net === true; + const coordinates = xyzac.coordinates === "XYZAC" && xyzac.joint_count === 5; + if (action === "vismachClear") return Object.freeze({ action, enabled: true, reason: "axis_visual_only", visual_only: true, taskState: state.taskState, interpState: state.interpState }); + const common = idle && pinVars && net && offsets; + const commonReason = state.taskState === "ESTOP" ? "xyzac_estop_active" : state.taskState !== "ON" ? "xyzac_machine_off" : !idle ? "xyzac_interp_not_idle" : !pinVars ? "xyzac_hal_pin_vars_missing" : !net ? "xyzac_switchkins_net_missing" : !offsets ? "xyzac_offsets_nonfinite" : "xyzac_switchkins_common_gate"; + if (action === "switchkinsIdentity") return Object.freeze({ action, enabled: common, reason: common ? "xyzac_m429_available" : commonReason, required_type: 0, taskState: state.taskState, interpState: state.interpState }); + if (action === "switchkinsXyzac") return Object.freeze({ action, enabled: common && coordinates, reason: !common ? commonReason : !coordinates ? "xyzac_coordinates_invalid" : "xyzac_m428_available", required_type: 1, taskState: state.taskState, interpState: state.interpState }); + if (action === "switchkinsUserk") return Object.freeze({ action, enabled: common && Boolean(xyzac.userk_capability), reason: !common ? commonReason : !xyzac.userk_capability ? "xyzac_userk_unavailable" : "xyzac_m430_available", required_type: 2, taskState: state.taskState, interpState: state.interpState }); + return Object.freeze({ action, enabled: false, reason: "xyzac_gate_unknown_action", taskState: state.taskState, interpState: state.interpState }); +} + +export function xyzacGateMatrix(input = {}) { + return Object.freeze(Object.fromEntries(XYZAC_GATE_ACTIONS.map((action) => [action, xyzacGate(action, input)]))); +} diff --git a/web/app/axis-operation-controller.mjs b/web/app/axis-operation-controller.mjs index bc33dbf..aaf9bcf 100644 --- a/web/app/axis-operation-controller.mjs +++ b/web/app/axis-operation-controller.mjs @@ -1,6 +1,6 @@ -import { AXIS_COMMANDS, axisGate } from "./axis-contract.mjs"; +import { AXIS_COMMANDS, XYZAC_GATE_ACTIONS, axisGate, xyzacGate } from "./axis-contract.mjs"; -export const COMMAND_ACTIONS = Object.freeze(Object.fromEntries(Object.entries(AXIS_COMMANDS).map(([action, command]) => [command, action]))); +export const COMMAND_ACTIONS = Object.freeze({ ...Object.fromEntries(Object.entries(AXIS_COMMANDS).map(([action, command]) => [command, action])), VISUAL_CLEAR: "vismachClear" }); export class AxisGateError extends Error { constructor(result) { @@ -26,17 +26,18 @@ export class AxisOperationController { async execute(kind, payload = {}, { state = {}, action = COMMAND_ACTIONS[kind] ?? null, gate = true } = {}) { const operationId = this.nextOperationId(kind); - const gateResult = action ? axisGate(action, state) : { action: null, enabled: true, reason: "axis_unrestricted_internal_command" }; + const gateResult = action ? (XYZAC_GATE_ACTIONS.includes(action) ? xyzacGate(action, state) : axisGate(action, state)) : { action: null, enabled: true, reason: "axis_unrestricted_internal_command" }; const authoritativeGate = action && state?.gates?.[action]; - if (gate && !gateResult.enabled && !authoritativeGate) { - this.trace.push(Object.freeze({ operation_id: operationId, kind, action, phase: "blocked", reason: gateResult.reason })); - throw new AxisGateError(gateResult); + const effectiveGate = authoritativeGate ?? gateResult; + if (gate && !effectiveGate.enabled) { + this.trace.push(Object.freeze({ operation_id: operationId, kind, action, phase: "blocked", reason: effectiveGate.reason })); + throw new AxisGateError(effectiveGate); } - this.trace.push(Object.freeze({ operation_id: operationId, kind, action, phase: "pending", reason: gateResult.reason })); + this.trace.push(Object.freeze({ operation_id: operationId, kind, action, phase: "pending", reason: effectiveGate.reason })); try { const response = await this.client.send(kind, payload, operationId); this.trace.push(Object.freeze({ operation_id: operationId, kind, action, phase: "result", response_kind: response?.kind ?? null })); - return Object.freeze({ operationId, response, gate: gateResult }); + return Object.freeze({ operationId, response, gate: effectiveGate }); } catch (error) { this.trace.push(Object.freeze({ operation_id: operationId, kind, action, phase: "error", reason: error?.message ?? String(error) })); throw error; diff --git a/web/react/src/App.tsx b/web/react/src/App.tsx index b9c062c..11dd45e 100644 --- a/web/react/src/App.tsx +++ b/web/react/src/App.tsx @@ -1,16 +1,18 @@ import { useEffect, useMemo, useRef, useState } from "react"; import { INITIAL_STATE, reduceFrontendState } from "./store"; import { ReactWorkerClient } from "./worker-client"; -import { ThreeMachineView } from "./ThreeMachineView"; +import { XyzacToolPreviewFromSnapshot } from "./XyzacToolPreview"; import { SIM_CASE_CATALOG } from "../../workspace/sim-case-catalog.mjs"; import { loadSimulationCase, toWorkerConfiguration } from "../../workspace/sim-case-loader.mjs"; import { axisIcon } from "./sourceAssets"; import { AxisGateError, AxisOperationController } from "../../app/axis-operation-controller.mjs"; import { axisGate } from "../../app/axis-contract.mjs"; +import { XyzacDiagnostics, XyzacProgramPane, XyzacTrtPanel } from "./XyzacTrtPanel"; +import { XYZAC_CASE, projectXyzacPanel, type XyzacOperationTrace } from "./xyzac-panel-contract"; -export const SELECTED_AXIS3_CASE = "linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini"; -const DEFAULT_CASE = SELECTED_AXIS3_CASE; -const PROGRAM_PATH = "linuxcnc/configs/nc_files/3dtest.ngc"; +export const SELECTED_XYZAC_CASE = XYZAC_CASE; +const DEFAULT_CASE = SELECTED_XYZAC_CASE; +const PROGRAM_PATH = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc"; const DEFAULT_PROGRAM = ""; type Action = (kind: string, payload?: Record) => Promise | void; @@ -38,6 +40,20 @@ function AxisRadio({ axis, selected, onChange }: { axis: string; selected: strin return ; } +function MachineSequence({ isEstop, machineOn, allHomed, programLoaded, programRunning, canHome, canRun, onEstop, onRelease, onPower, onHomeAll, onRun, onSequence }: { isEstop: boolean; machineOn: boolean; allHomed: boolean; programLoaded: boolean; programRunning: boolean; canHome: boolean; canRun: boolean; onEstop: () => void; onRelease: () => void; onPower: () => void; onHomeAll: () => void; onRun: () => void; onSequence: () => void }) { + return
+
Machine sequence{isEstop ? "ESTOP" : machineOn ? "ON" : "OFF"} / {allHomed ? "HOME ALL" : "NOT HOMED"}
+
+ Emergency Stop + Release E-stop + Power On + HOME ALL + Run Program + Run Startup Sequence +
+
; +} + function ManualControl({ action, ready, canHome, onHomeAll, selectedAxis, setSelectedAxis, spindleOn, coolant, onSpindle, onCoolant, devices }: { action: Action; ready: boolean; canHome: boolean; onHomeAll: () => void; selectedAxis: string; setSelectedAxis: (axis: string) => void; spindleOn: boolean; coolant: { mist: boolean; flood: boolean }; onSpindle: (direction: number) => void; onCoolant: (key: "mist" | "flood") => void; devices: Record }) { const [increment, setIncrement] = useState("Continuous"); const [jogSpeed, setJogSpeed] = useState(50); @@ -48,7 +64,7 @@ function ManualControl({ action, ready, canHome, onHomeAll, selectedAxis, setSel const jog = (direction: number) => { setJogging(true); const request = action("JOG_START", { axis: selectedAxis, direction, speed: increment === "Continuous" ? 1 : 1, increment: increment === "Continuous" ? null : Number(increment) }); if (increment !== "Continuous" && request && typeof (request as Promise).then === "function") void (request as Promise).then(() => action("SIM_STEP", { cycles: 1 })); }; const stopJog = () => { if (!jogging) return; setJogging(false); void action("JOG_STOP"); }; return
-

Axis:

{["x", "y", "z", "a", "b", "c", "u", "v", "w"].map((axis) => )}
+

Axis:

{["x", "y", "z", "a", "c"].map((axis) => )}

Jog:

jog(-1)} onPointerUp={stopJog} onPointerCancel={stopJog} onPointerLeave={stopJog} ariaLabel={`Jog ${selectedAxis.toUpperCase()} negative`}>- jog(1)} onPointerUp={stopJog} onPointerCancel={stopJog} onPointerLeave={stopJog} ariaLabel={`Jog ${selectedAxis.toUpperCase()} positive`}>+Stop
action("HOME", { axis: selectedAxis })}>Home AxisHome All action("MDI_EXECUTE", { block: `G92 ${selectedAxis.toUpperCase()}0` })}>Touch Off action("MDI_EXECUTE", { block: "G43" })}>Tool Touch Off

Spindle:

onSpindle(-1)} /> onSpindle(0)}>Stop onSpindle(1)} />
action("SPINDLE_COMMAND", { spindle: 0, delta: -100 })}>- action("SPINDLE_COMMAND", { spindle: 0, delta: 100 })}>+

Coolant:

@@ -63,13 +79,13 @@ function MdiControl({ action, ready }: { action: Action; ready: boolean }) { } function DroView({ axes, state, coordType, displayType, metric, setCoordType, setDisplayType, setMetric }: { axes: number[]; state: typeof INITIAL_STATE; coordType: "machine" | "relative"; displayType: "actual" | "commanded"; metric: boolean; setCoordType: (value: "machine" | "relative") => void; setDisplayType: (value: "actual" | "commanded") => void; setMetric: (value: boolean) => void }) { - const labels = ["X", "Y", "Z", "A", "B", "C", "U", "V", "W"]; + const labels = ["X", "Y", "Z", "A", "C"]; const scale = metric ? 1 : 1 / 25.4; - const format = (value: number) => (value * scale).toFixed(4); + const format = (value: number, index: number) => (value * (index < 3 ? scale : 1)).toFixed(4); const pose = (state.snapshot?.visual?.pose ?? state.snapshot?.authoritative?.kinematics?.pose) as Record | undefined; - const commanded = [pose?.x, pose?.y, pose?.z].map((value, index) => Number.isFinite(value) ? Number(value) : Number(axes[index] ?? 0)); - const relative = state.snapshot?.coordinates?.relative ?? [0, 0, 0]; - return
Position
DisplayedActualRelative
{labels.slice(0, Math.max(3, axes.length)).map((label, index) => { const actual = Number(axes[index] ?? 0); const target = Number(commanded[index] ?? actual); const relativeValue = Number(relative[index] ?? actual); const displayed = displayType === "commanded" ? target : actual; return
{label}{format(coordType === "relative" ? relativeValue : displayed)}{format(actual)}{format(relativeValue)}
; })}
Units: {metric ? "mm" : "inch"}{coordType} / {displayType}Tick: {state.tick}Hash: {state.snapshot?.state_hash?.slice(0, 12) || "-"}
; + const commanded = [pose?.x, pose?.y, pose?.z, pose?.a, pose?.c].map((value, index) => Number.isFinite(value) ? Number(value) : Number(axes[index] ?? 0)); + const relative = state.snapshot?.coordinates?.relative ?? [0, 0, 0, 0, 0]; + return
Position
DisplayedActualRelative
{labels.map((label, index) => { const actual = Number(axes[index] ?? 0); const target = Number(commanded[index] ?? actual); const relativeValue = Number(relative[index] ?? actual); const displayed = displayType === "commanded" ? target : actual; return
{label}{format(coordType === "relative" ? relativeValue : displayed, index)}{format(actual, index)}{format(relativeValue, index)}
; })}
Units: {metric ? "mm" : "inch"} / deg{coordType} / {displayType}Tick: {state.tick}Hash: {state.snapshot?.state_hash?.slice(0, 12) || "-"}
; } function ProgramPane({ text, setText, activeGcodes, onLoad, onRun, onStep, onOpenFile, canLoad, canRun, canStep, currentLine, diagnostic }: { text: string; setText: (text: string) => void; activeGcodes: string; onLoad: () => void; onRun: () => void; onStep: () => void; onOpenFile: () => void; canLoad: boolean; canRun: boolean; canStep: boolean; currentLine: number | null; diagnostic: string | null }) { @@ -94,7 +110,7 @@ export function App() { const client = useMemo(() => new ReactWorkerClient(), []); const operationController = useMemo(() => new AxisOperationController(client), [client]); const [state, setState] = useState(INITIAL_STATE); - const [casePath, setCasePath] = useState(DEFAULT_CASE); + const [casePath, setCasePath] = useState(DEFAULT_CASE); const [caseStatus, setCaseStatus] = useState("ready to load"); const [commandStatus, setCommandStatus] = useState("Idle"); const [programText, setProgramText] = useState(DEFAULT_PROGRAM); @@ -112,12 +128,16 @@ export function App() { const [layers, setLayers] = useState({ grid: true, tool: true, path: true, live: true, limits: false, velocity: false, offsets: false, extents: false }); const runTimer = useRef | null>(null); const jogTimer = useRef | null>(null); + const runStepPending = useRef(false); + const jogStepPending = useRef(false); const programFileInput = useRef(null); const [plotCleared, setPlotCleared] = useState(false); - useEffect(() => { const unsubscribe = client.subscribe((message) => setState((previous) => reduceFrontendState(previous, message))); client.ensureSession().then(async () => { const bundle = await loadSimulationCase({ path: DEFAULT_CASE, baseUrl: "." }); const source = bundle.files?.[PROGRAM_PATH]; if (typeof source !== "string" || !source.trim()) throw new Error("tutorial_program_missing"); setProgramText(source.replace(/\r\n/g, "\n").trimEnd()); const configuration = toWorkerConfiguration(bundle); await operationController.execute("LOAD_WORKSPACE", { root_path: "/workspace", configuration }, { state: {}, gate: false }); await operationController.execute("PROGRAM_LOAD", { source, path: PROGRAM_PATH }, { state: {}, gate: false }); setCaseStatus(`${DEFAULT_CASE} + ${PROGRAM_PATH} loaded`); }).catch((error: Error) => { setCommandStatus(`Error: ${error.message}`); setCaseStatus(`blocked: ${error.message}`); }); return () => { unsubscribe(); if (runTimer.current) clearInterval(runTimer.current); if (jogTimer.current) clearInterval(jogTimer.current); client.close(); }; }, [client, operationController]); + const [operationTrace, setOperationTrace] = useState([]); + useEffect(() => { const unsubscribe = client.subscribe((message) => setState((previous) => reduceFrontendState(previous, message))); client.ensureSession().then(async () => { const bundle = await loadSimulationCase({ path: DEFAULT_CASE, baseUrl: "." }); if (bundle.status !== "ready") throw new Error(`xyzac_case_blocked:${bundle.missing.join(",")}`); const source = bundle.files?.[PROGRAM_PATH]; if (typeof source !== "string" || !source.trim()) throw new Error("xyzac_demo_program_missing"); setProgramText(source.replace(/\r\n/g, "\n").trimEnd()); const configuration = toWorkerConfiguration(bundle); await operationController.execute("LOAD_WORKSPACE", { root_path: "/workspace", configuration }, { state: {}, gate: false }); await operationController.execute("PROGRAM_LOAD", { source, path: PROGRAM_PATH }, { state: {}, gate: false }); setOperationTrace(operationController.exportTrace()); setCaseStatus(`${DEFAULT_CASE} + ${PROGRAM_PATH} loaded`); }).catch((error: Error) => { setOperationTrace(operationController.exportTrace()); setCommandStatus(`Error: ${error.message}`); setCaseStatus(`blocked: ${error.message}`); }); return () => { unsubscribe(); if (runTimer.current) clearInterval(runTimer.current); if (jogTimer.current) clearInterval(jogTimer.current); client.close(); }; }, [client, operationController]); const axes = state.snapshot?.motion?.axes ?? [0, 0, 0]; const taskRecord = state.task ?? {}; - const axisState = { task: { ...taskRecord, state: taskRecord.state ?? "OFF", mode: taskRecord.mode ?? "MANUAL", interp_state: taskRecord.interp_state ?? (state.status === "running" ? "READING" : state.status === "paused" ? "PAUSED" : "IDLE") }, program: state.program ?? {}, motion: state.snapshot?.motion ?? {}, devices: state.devices ?? {}, gates: state.gates }; + const axisState = { task: { ...taskRecord, state: taskRecord.state ?? "OFF", mode: taskRecord.mode ?? "MANUAL", interp_state: taskRecord.interp_state ?? (state.status === "running" ? "READING" : state.status === "paused" ? "PAUSED" : "IDLE") }, program: state.program ?? {}, motion: state.snapshot?.motion ?? {}, devices: state.devices ?? {}, xyzac: state.snapshot?.xyzac ?? {}, gates: state.gates }; + const xyzacView = useMemo(() => projectXyzacPanel(state.snapshot), [state.snapshot]); const machineState = state.axisState?.machine_state ?? (String(taskRecord.state ?? "OFF").toUpperCase() === "ESTOP" ? "ESTOP" : ["READY", "RUNNING", "PAUSED", "STOPPED"].includes(String(taskRecord.state ?? "").toUpperCase()) ? "ON" : "OFF"); const operationState = state.axisState?.operation_state ?? (state.status === "running" ? "RUNNING" : state.status === "paused" ? "PAUSED" : "IDLE"); const taskState = state.axisState?.state ?? (machineState === "ESTOP" ? "ESTOP" : operationState === "RUNNING" ? "RUNNING" : operationState === "PAUSED" ? "PAUSED" : machineState === "ON" ? "IDLE" : "OFF"); @@ -133,11 +153,14 @@ export function App() { const trajectory = [...(planner?.queue ?? []), ...(planner?.active ? [planner.active] : [])]; const stopRunTimer = () => { if (runTimer.current) { clearInterval(runTimer.current); runTimer.current = null; } }; const stopJogTimer = () => { if (jogTimer.current) { clearInterval(jogTimer.current); jogTimer.current = null; } }; - const startJogTimer = () => { if (jogTimer.current) return; jogTimer.current = setInterval(() => { operationController.execute("SIM_STEP", { cycles: 1 }, { state: axisState, gate: false }).catch(() => undefined); }, 50); }; - const startRunTimer = () => { if (runTimer.current) return; runTimer.current = setInterval(() => { operationController.execute("SIM_STEP", { cycles: 1 }, { state: axisState, gate: false }).catch(() => undefined); }, 50); }; - const dispatch = (kind: string, payload: Record = {}, gate = true): Promise => { + const startJogTimer = () => { if (jogTimer.current) return; jogTimer.current = setInterval(() => { if (jogStepPending.current) return; jogStepPending.current = true; operationController.execute("SIM_STEP", { cycles: 1 }, { state: axisState, gate: false }).catch(() => undefined).finally(() => { jogStepPending.current = false; }); }, 50); }; + const startRunTimer = () => { if (runTimer.current) return; runTimer.current = setInterval(() => { if (runStepPending.current) return; runStepPending.current = true; operationController.execute("SIM_STEP", { cycles: 5 }, { state: axisState, gate: false }).catch(() => undefined).finally(() => { runStepPending.current = false; }); }, 50); }; + const dispatch = (kind: string, payload: Record = {}, gate = true, action: string | null = null): Promise => { setCommandStatus(`${kind} pending`); - return operationController.execute(kind, payload, { state: axisState, gate }).then(() => { setCommandStatus(`${kind} acknowledged`); if (kind === "PROGRAM_RUN") startRunTimer(); if (kind === "PROGRAM_ABORT" || kind === "PROGRAM_RESTART") stopRunTimer(); if (kind === "JOG_START") startJogTimer(); if (kind === "JOG_STOP") stopJogTimer(); }).catch((error: Error) => { + const pending = operationController.execute(kind, payload, { state: axisState, gate, ...(action ? { action } : {}) }); + setOperationTrace(operationController.exportTrace()); + return pending.then(() => { setOperationTrace(operationController.exportTrace()); setCommandStatus(`${kind} acknowledged`); if (kind === "PROGRAM_RUN") startRunTimer(); if (kind === "PROGRAM_ABORT" || kind === "PROGRAM_RESTART") stopRunTimer(); if (kind === "JOG_START") startJogTimer(); if (kind === "JOG_STOP") stopJogTimer(); }).catch((error: Error) => { + setOperationTrace(operationController.exportTrace()); const code = error instanceof AxisGateError ? error.code : error.message; setCommandStatus(`${kind} blocked: ${code}`); throw error; @@ -146,11 +169,20 @@ export function App() { const execute: Action = (kind, payload = {}) => dispatch(kind, payload).catch(() => undefined); const runProgram = () => { void dispatch("PROGRAM_RUN").catch(() => undefined); }; const stopProgram = () => { const wasRunning = Boolean(runTimer.current) || gates.abort.enabled; stopRunTimer(); if (wasRunning) void dispatch("PROGRAM_ABORT", {}, gates.abort.enabled).catch(() => undefined); }; - const toggleEstop = () => { if (!isEstop) { void dispatch("ESTOP", { active: true }).catch(() => undefined); return; } void dispatch("ESTOP", { active: false }).then(() => dispatch("IO_RECOVER")).catch(() => undefined); }; - const powerOn = () => { const recover = () => dispatch("IO_RECOVER"); if (isEstop) void dispatch("ESTOP", { active: false }).then(recover).catch(() => undefined); else void recover().catch(() => undefined); }; + const emergencyStop = () => { stopRunTimer(); stopJogTimer(); void dispatch("ESTOP", { active: true }, false).catch(() => undefined); }; + const releaseEstop = () => dispatch("ESTOP", { active: false }, false).then(() => dispatch("IO_RECOVER", {}, false)); + const toggleEstop = () => { if (!isEstop) { emergencyStop(); return; } void releaseEstop().catch(() => undefined); }; + const powerOn = () => { const power = () => dispatch("POWER", { active: true }, false); if (isEstop) void releaseEstop().then(power).catch(() => undefined); else void power().catch(() => undefined); }; const resetMachine = () => { stopRunTimer(); stopJogTimer(); const reset = () => dispatch("RESET", {}, false); if (programRunning) void dispatch("PROGRAM_ABORT").then(() => isEstop ? dispatch("ESTOP", { active: false }) : Promise.resolve()).then(reset).catch(() => undefined); else if (isEstop) void dispatch("ESTOP", { active: false }).then(reset).catch(() => undefined); else void reset().catch(() => undefined); }; - const homeAll = () => { void dispatch("HOME", { axis: "z" }).then(() => dispatch("HOME", { axis: "x" })).then(() => dispatch("HOME", { axis: "y" })).catch(() => undefined); }; - const loadCase = async () => { setCaseStatus("loading session..."); try { await client.ensureSession(); setCaseStatus("loading exact case..."); const bundle = await loadSimulationCase({ path: casePath, baseUrl: "." }); if (bundle.status !== "ready") { setCaseStatus(`blocked: ${bundle.missing.join(", ")}`); return; } setCaseStatus("starting exact case..."); const operation = await operationController.execute("LOAD_WORKSPACE", { root_path: "/workspace", configuration: toWorkerConfiguration(bundle) }, { state: axisState, gate: false }); const resultPayload = (operation.response as { payload?: { configuration?: { state?: string } } }).payload; const source = bundle.files?.[PROGRAM_PATH]; if (typeof source === "string" && source.trim()) { setProgramText(source.replace(/\r\n/g, "\n").trimEnd()); setPlotCleared(false); await operationController.execute("PROGRAM_LOAD", { source, path: PROGRAM_PATH }, { state: axisState, gate: false }); setCaseStatus(`${bundle.entrypoint} + ${PROGRAM_PATH} -> READY`); } else { setCaseStatus(`${bundle.entrypoint} -> ${resultPayload?.configuration?.state ?? "READY"} (no program)`); } } catch (error) { setCaseStatus(`blocked: ${error instanceof Error ? error.message : "case_load_failed"}`); } }; + const homeAll = () => { void dispatch("HOME", { all: true }).catch(() => undefined); }; + const runStartupSequence = () => { + const release = isEstop ? releaseEstop() : Promise.resolve(); + void release.then(() => dispatch("POWER", { active: true }, false)) + .then(() => dispatch("HOME", { all: true }, false)) + .then(() => dispatch("PROGRAM_RUN", {}, false)) + .catch(() => undefined); + }; + const loadCase = async () => { setCaseStatus("loading session..."); try { await client.ensureSession(); setCaseStatus("loading exact XYZAC case..."); const bundle = await loadSimulationCase({ path: casePath, baseUrl: "." }); if (bundle.status !== "ready") { setCaseStatus(`blocked: ${bundle.missing.join(", ")}`); return; } const source = bundle.files?.[PROGRAM_PATH]; if (typeof source !== "string" || !source.trim()) throw new Error("xyzac_demo_program_missing"); setCaseStatus("starting exact case..."); const operation = await operationController.execute("LOAD_WORKSPACE", { root_path: "/workspace", configuration: toWorkerConfiguration(bundle) }, { state: axisState, gate: false }); const resultPayload = (operation.response as { payload?: { configuration?: { state?: string } } }).payload; setProgramText(source.replace(/\r\n/g, "\n").trimEnd()); setPlotCleared(false); await operationController.execute("PROGRAM_LOAD", { source, path: PROGRAM_PATH }, { state: axisState, gate: false }); setOperationTrace(operationController.exportTrace()); setCaseStatus(`${bundle.entrypoint} + ${PROGRAM_PATH} -> ${resultPayload?.configuration?.state ?? "READY"}`); } catch (error) { setOperationTrace(operationController.exportTrace()); setCaseStatus(`blocked: ${error instanceof Error ? error.message : "case_load_failed"}`); } }; const openProgramFile = () => programFileInput.current?.click(); const onProgramFile = async (event: React.ChangeEvent) => { const file = event.target.files?.[0]; event.target.value = ""; if (!file) return; const source = await file.text(); setProgramText(source); setPlotCleared(false); setCommandStatus(`${file.name} loaded in editor; press Load to send it to LinuxCNC`); }; const enterManualMode = () => { setLeftTab("manual"); if (String(axisState.task.mode).toUpperCase() !== "MANUAL") void dispatch("SET_MODE", { mode: "MANUAL" }, false).catch(() => undefined); }; @@ -159,7 +191,7 @@ export function App() { const target = event.target as HTMLElement | null; if (target && ["INPUT", "TEXTAREA", "SELECT"].includes(target.tagName)) return; const key = event.key.toLowerCase(); - if (event.ctrlKey && key === "k") { event.preventDefault(); setCommandStatus("Live plot cleared"); return; } + if (event.ctrlKey && key === "k") { event.preventDefault(); void dispatch("VISUAL_CLEAR", {}, true, "vismachClear").then(() => setPlotCleared(true)).catch(() => undefined); return; } if (key === "f3") { event.preventDefault(); enterManualMode(); return; } if (key === "f5") { event.preventDefault(); setLeftTab("mdi"); return; } if (key === "f1") { event.preventDefault(); toggleEstop(); return; } @@ -176,7 +208,7 @@ export function App() { useEffect(() => { const wasmQueueDepth = Number((state.snapshot?.wasm_motion as { state?: { queue_depth?: number } } | undefined)?.state?.queue_depth ?? 0); const programComplete = String(state.program?.program_status ?? "") === "completed" && wasmQueueDepth === 0; - if (!programRunning || programComplete) stopRunTimer(); + if (programRunning && !programComplete) startRunTimer(); else stopRunTimer(); if (!ready) { stopRunTimer(); stopJogTimer(); } }, [programRunning, ready, state.program?.program_status, state.snapshot?.wasm_motion]); const spindleOn = Boolean((state.devices as Record | null)?.spindles?.[0]?.enabled); @@ -185,15 +217,21 @@ export function App() { const onCoolant = (key: "mist" | "flood") => { const next = { ...coolant, [key]: !coolant[key] }; execute("COOLANT_COMMAND", { mist: next.mist, flood: next.flood, lube: false }); }; const activeGcodes = state.program?.active_gcodes ? String(state.program.active_gcodes) : "G21 G90\nG17 G40 G49\nG54 G64\nM5 M9"; const toolNumber = String((state.devices as Record | null)?.tool?.current ?? state.snapshot?.tool?.current ?? 0); - const position = `X${Number(axes[0] ?? 0).toFixed(3)} Y${Number(axes[1] ?? 0).toFixed(3)} Z${Number(axes[2] ?? 0).toFixed(3)}`; + const currentLine = Number(state.program?.line ?? state.task?.current_line ?? 0) || null; + const homedAxes = Array.isArray(state.snapshot?.motion?.homed_axes) ? state.snapshot.motion.homed_axes : []; + const allHomed = homedAxes.length >= 5 && homedAxes.slice(0, 5).every(Boolean); + const xyzacCommand = (kind: string, payload: Record = {}, action?: string) => { void dispatch(kind, payload, true, action ?? null).then(() => { if (kind === "VISUAL_CLEAR") setPlotCleared(true); }).catch(() => undefined); }; + const position = `X${Number(xyzacView.pose?.x ?? axes[0] ?? 0).toFixed(3)} Y${Number(xyzacView.pose?.y ?? axes[1] ?? 0).toFixed(3)} Z${Number(xyzacView.pose?.z ?? axes[2] ?? 0).toFixed(3)} A${Number(xyzacView.pose?.a ?? 0).toFixed(3)} C${Number(xyzacView.pose?.c ?? 0).toFixed(3)}`; return
AXIS AXISLinuxCNC Web/WASM
{state.status.toUpperCase()}{taskState}
-
{ setProgramText(DEFAULT_PROGRAM); setPlotCleared(false); }} /> execute("PROGRAM_STEP")} /> execute(programPaused ? "PROGRAM_RESUME" : "PROGRAM_PAUSE")} /> setBlockDelete((value) => !value)} /> setOptionalStop((value) => !value)} /> setZoom((value) => Math.min(2, value + .2))} /> setZoom((value) => Math.max(.5, value - .2))} /> { setView("z"); setRightTab("preview"); }} /> { setView("z2"); setRightTab("preview"); }} /> { setView("x"); setRightTab("preview"); }} /> { setView("y"); setRightTab("preview"); }} /> { setView("y2"); setRightTab("preview"); }} /> { setView("p"); setRightTab("preview"); }} /> setRotateMode((value) => !value)} /> { setPlotCleared(true); setCommandStatus("Live plot cleared"); }} />
-
Load case{caseStatus}{commandStatus}
-
+
{ setProgramText(DEFAULT_PROGRAM); setPlotCleared(false); }} /> execute("PROGRAM_STEP")} /> execute(programPaused ? "PROGRAM_RESUME" : "PROGRAM_PAUSE")} /> setBlockDelete((value) => !value)} /> setOptionalStop((value) => !value)} /> setZoom((value) => Math.min(2, value + .2))} /> setZoom((value) => Math.max(.5, value - .2))} /> { setView("z"); setRightTab("preview"); }} /> { setView("z2"); setRightTab("preview"); }} /> { setView("x"); setRightTab("preview"); }} /> { setView("y"); setRightTab("preview"); }} /> { setView("y2"); setRightTab("preview"); }} /> { setView("p"); setRightTab("preview"); }} /> setRotateMode((value) => !value)} /> xyzacCommand("VISUAL_CLEAR", {}, "vismachClear")} />
+
Load case{caseStatus}{commandStatus}
+ { void releaseEstop().catch(() => undefined); }} onPower={powerOn} onHomeAll={homeAll} onRun={runProgram} onSequence={runStartupSequence} /> + +
{(["path", "live", "limits", "velocity", "offsets", "extents"] as const).map((layer) => )}
- { setPlotCleared(false); execute("PROGRAM_LOAD", { source: programText, path: "main.ngc" }); }} onRun={runProgram} onStep={() => execute("PROGRAM_STEP")} canLoad={gates.load.enabled} canRun={gates.run.enabled} canStep={gates.step.enabled} currentLine={Number(state.program?.line ?? state.task?.current_line ?? 0) || null} diagnostic={state.error?.code ?? null} /> + { setPlotCleared(false); execute("PROGRAM_LOAD", { source: programText, path: PROGRAM_PATH }); }} onRun={runProgram} onStep={() => execute("PROGRAM_STEP")} canLoad={gates.load.enabled} canRun={gates.run.enabled} canStep={gates.step.enabled} currentLine={currentLine} diagnostic={state.error?.code ?? null} />
{taskState}Machine {machineState}Operation {operationState}Tool {toolNumber}{position}{state.error ? `Error: ${state.error.code}` : commandStatus}
; diff --git a/web/react/src/XyzacMachineView.tsx b/web/react/src/XyzacMachineView.tsx new file mode 100644 index 0000000..a0945cd --- /dev/null +++ b/web/react/src/XyzacMachineView.tsx @@ -0,0 +1,115 @@ +import { useEffect, useRef } from "react"; +import * as THREE from "three"; +import { projectXyzacVisual, type XyzacVisualSource, type XyzacVisualState } from "./xyzac-visual-adapter"; + +type Point = Record; +type Segment = { id?: number; active?: boolean; motion_type?: number; turn?: number; center?: Point; normal?: Point; samples?: Point[]; start?: Point; end?: Point }; +type Props = { visual: XyzacVisualState; toolpath?: Segment[]; view?: "z" | "z2" | "x" | "y" | "y2" | "p"; zoom?: number; rotateMode?: boolean; showPath?: boolean; showLive?: boolean; showLimits?: boolean; showVelocity?: boolean; showOffsets?: boolean; showExtents?: boolean }; + +const DEG = Math.PI / 180; +const MM = 0.01; + +function material(color: number) { return new THREE.MeshStandardMaterial({ color, roughness: .78, metalness: .12 }); } +function sourcePosition(x: number, y: number, z: number) { return new THREE.Vector3(x * MM, z * MM, y * MM); } +function sourceBox(width: number, depth: number, height: number, color: number) { return new THREE.Mesh(new THREE.BoxGeometry(width * MM, height * MM, depth * MM), material(color)); } +function sourceCylinderZ(radius: number, height: number, color: number) { return new THREE.Mesh(new THREE.CylinderGeometry(radius * MM, radius * MM, height * MM, 32), material(color)); } +function translate(name: string, object: THREE.Object3D, x: number, y: number, z: number) { object.name = name; object.position.copy(sourcePosition(x, y, z)); return object; } + +export function XyzacMachineView({ visual, toolpath, view = "p", zoom = 1, rotateMode = false, showPath = true, showLive = true, showLimits = false, showVelocity = false, showOffsets = false, showExtents = false }: Props) { + const host = useRef(null); + const visualRef = useRef(visual); visualRef.current = visual; + const toolpathRef = useRef(toolpath); toolpathRef.current = toolpath; + const viewRef = useRef(view); viewRef.current = view; + const zoomRef = useRef(zoom); zoomRef.current = zoom; + const rotateRef = useRef(rotateMode); rotateRef.current = rotateMode; + const layersRef = useRef({ showPath, showLive, showLimits, showVelocity, showOffsets, showExtents }); + layersRef.current = { showPath, showLive, showLimits, showVelocity, showOffsets, showExtents }; + + useEffect(() => { + const element = host.current; + if (!element) return; + const scene = new THREE.Scene(); + scene.background = new THREE.Color(0x081017); + scene.add(new THREE.HemisphereLight(0xe6f2ff, 0x202830, 1.65)); + const key = new THREE.DirectionalLight(0xffffff, 2.1); key.position.set(5, 8, 10); scene.add(key); + const camera = new THREE.PerspectiveCamera(38, 1, .1, 100); + const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: false, preserveDrawingBuffer: true }); + renderer.setPixelRatio(Math.min(globalThis.devicePixelRatio || 1, 2)); + renderer.domElement.dataset.engine = "three.js r185 / xyzac-trt-vismach"; + element.appendChild(renderer.domElement); + + const machine = new THREE.Group(); machine.name = "xyzac-machine"; scene.add(machine); + machine.add(translate("base", sourceBox(240, 260, 150, 0x43616b), 0, 30, -175)); + machine.add(translate("column", sourceBox(100, 100, 510, 0x3b7a72), 0, 150, 5)); + const head = new THREE.Group(); head.name = "head"; head.position.copy(sourcePosition(0, 0, 200)); machine.add(head); + head.add(translate("head-body", sourceBox(60, 60, 135, 0x277c83), 0, 0, 87.5)); + head.add(translate("motor", sourceCylinderZ(30, 65, 0x277c83), 0, 200, 165)); + const spindle = new THREE.Group(); spindle.name = "spindle"; spindle.position.copy(sourcePosition(0, 0, 20)); head.add(spindle); + spindle.add(translate("spindle-housing", sourceCylinderZ(20, 135, 0x31888d), 0, 0, 67.5)); + spindle.add(translate("spindle-nose", sourceCylinderZ(10, 20, 0x4da0a0), 0, 0, 10)); + const tool = new THREE.Group(); tool.name = "tool-offset"; spindle.add(tool); + tool.add(translate("tool-holder", sourceCylinderZ(6, 70, 0x9da7a8), 0, 0, 35)); + tool.add(translate("tool", sourceCylinderZ(3, 70, 0xd85f4a), 0, 0, 105)); + + const zslide = new THREE.Group(); zslide.name = "spindle-z"; machine.add(zslide); + const saddle = new THREE.Group(); saddle.name = "saddle-y"; zslide.add(saddle); + saddle.add(translate("saddle-body", sourceBox(150, 106, 32, 0x8b9697), 0, 0, -89)); + saddle.add(translate("z-slide", sourceBox(100, 220, 75, 0xb8bdbe), 0, 10, -142.5)); + const tableX = new THREE.Group(); tableX.name = "table-x"; saddle.add(tableX); + tableX.add(translate("table-bed", sourceBox(300, 100, 17, 0x686f72), 0, 0, -60.5)); + tableX.add(translate("ways", sourceBox(300, 80, 6, 0x50575a), 0, 0, -72)); + const tilt = new THREE.Group(); tilt.name = "tilt-a"; tableX.add(tilt); + const yOffset = 20; const zOffset = 10; + tilt.position.copy(sourcePosition(0, yOffset, zOffset)); + tilt.rotation.x = 0; + const rotate = new THREE.Group(); rotate.name = "rotate-c"; tilt.add(rotate); + rotate.position.copy(sourcePosition(0, -yOffset, -zOffset)); + rotate.add(translate("trunnion", sourceBox(145, 80, 35, 0xb17540), 0, 0, -30)); + rotate.add(translate("table", sourceCylinderZ(50, 18, 0xb17540), 0, 0, -9)); + rotate.rotation.y = 0; + const yoke = new THREE.Group(); yoke.name = "yoke"; tilt.add(yoke); + yoke.add(translate("yoke-plate", sourceBox(130, 80, 10, 0xb17540), 0, 0, -30)); + const brackets = new THREE.Group(); brackets.name = "brackets"; tableX.add(brackets); + brackets.position.copy(sourcePosition(0, yOffset, zOffset)); + brackets.add(translate("bracket-left", sourceBox(10, 80, 50, 0x9b6b3b), -72, 0, -25)); + brackets.add(translate("bracket-right", sourceBox(10, 80, 50, 0x9b6b3b), 72, 0, -25)); + const pathGroup = new THREE.Group(); pathGroup.name = "xyzac-toolpath"; scene.add(pathGroup); + const liveGroup = new THREE.Group(); liveGroup.name = "xyzac-live-toolpath"; scene.add(liveGroup); + const overlayGroup = new THREE.Group(); overlayGroup.name = "xyzac-overlays"; scene.add(overlayGroup); + const resize = () => { const width = Math.max(element.clientWidth, 280); const height = Math.max(element.clientHeight, 260); camera.aspect = width / height; camera.updateProjectionMatrix(); renderer.setSize(width, height, false); }; + const observer = new ResizeObserver(resize); observer.observe(element); resize(); + + const toView = (point: Point) => new THREE.Vector3(Number(point.x ?? 0) * MM, Number(point.z ?? 0) * MM, Number(point.y ?? 0) * MM); + let frame = 0; + const render = () => { + const state = visualRef.current; const [tableXJoint, saddleYJoint, spindleZJoint, tiltAJoint, rotateCJoint] = state.joints; + tableX.position.x = -tableXJoint * MM; saddle.position.z = -saddleYJoint * MM; zslide.position.y = (200 - spindleZJoint) * MM; + tilt.rotation.x = -tiltAJoint * DEG; rotate.rotation.y = -rotateCJoint * DEG; tool.position.y = -state.offsets.tool_offset * MM; + pathGroup.clear(); liveGroup.clear(); + const completed = new THREE.LineBasicMaterial({ color: 0xdce7e8 }); const active = new THREE.LineBasicMaterial({ color: 0xff9a55 }); const rapid = new THREE.LineBasicMaterial({ color: 0x5c9d9a }); + for (const raw of (toolpathRef.current && toolpathRef.current.length > 0 ? toolpathRef.current : state.toolpath) as Segment[]) { + const start = raw.start ?? {}; const end = raw.end ?? {}; + const points = Array.isArray(raw.samples) && raw.samples.length > 1 ? raw.samples.map(toView) : [toView(start), toView(end)]; + const group = raw.active || raw.id === state.activeSegmentId ? liveGroup : pathGroup; const line = new THREE.Line(new THREE.BufferGeometry().setFromPoints(points), raw.active || raw.id === state.activeSegmentId ? active : raw.motion_type === 0 ? rapid : completed); group.add(line); + } + const layer = layersRef.current; + pathGroup.visible = layer.showPath; liveGroup.visible = layer.showLive; + overlayGroup.clear(); + if (layer.showLimits) { const limits = new THREE.LineSegments(new THREE.EdgesGeometry(new THREE.BoxGeometry(4, 2, 3)), new THREE.LineBasicMaterial({ color: 0xdd7566 })); limits.position.set(0, .8, 0); overlayGroup.add(limits); } + if (layer.showOffsets) { const offset = new THREE.AxesHelper(1.8); offset.name = "xyzac-offset-axes"; offset.position.set(state.offsets.x_rot_point * MM, state.offsets.z_offset * MM, state.offsets.y_offset * MM); overlayGroup.add(offset); } + overlayGroup.visible = layer.showLimits || layer.showOffsets || layer.showExtents || layer.showVelocity; + const distance = 9 / Math.max(.5, zoomRef.current); const selected = viewRef.current; + if (selected === "z") camera.position.set(0, distance, .01); else if (selected === "z2") camera.position.set(distance * .3, distance * .9, distance * .3); else if (selected === "x") camera.position.set(distance, 2, .01); else if (selected === "y") camera.position.set(.01, 2, distance); else if (selected === "y2") camera.position.set(.01, 2, -distance); else camera.position.set(6 / Math.max(.5, zoomRef.current), 5 / Math.max(.5, zoomRef.current), 7 / Math.max(.5, zoomRef.current)); + camera.lookAt(0, 0, 0); scene.rotation.y = rotateRef.current ? (performance.now() / 5000) % (Math.PI * 2) : 0; renderer.render(scene, camera); frame = requestAnimationFrame(render); + }; + render(); + return () => { cancelAnimationFrame(frame); observer.disconnect(); renderer.dispose(); element.replaceChildren(); }; + }, []); + + const pose = visual.pose; + return
{`XYZAC TRT\nX ${Number(pose.x).toFixed(3)}  Y ${Number(pose.y).toFixed(3)}  Z ${Number(pose.z).toFixed(3)}\nA ${Number(pose.a).toFixed(3)}  C ${Number(pose.c).toFixed(3)}\nJ ${visual.joints.map((value) => Number(value).toFixed(2)).join(" ")}\nTick ${visual.tick}\nHash ${visual.stateHash.slice(0, 18)}`}
; +} + +export function XyzacMachineViewFromSnapshot({ snapshot, toolpath, ...props }: Omit & { snapshot: XyzacVisualSource | null | undefined }) { + return ; +} diff --git a/web/react/src/XyzacToolPreview.tsx b/web/react/src/XyzacToolPreview.tsx new file mode 100644 index 0000000..706e3cd --- /dev/null +++ b/web/react/src/XyzacToolPreview.tsx @@ -0,0 +1,258 @@ +import { useEffect, useRef } from "react"; +import * as THREE from "three"; +import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"; +import { projectXyzacVisual, type XyzacVisualSource, type XyzacVisualState } from "./xyzac-visual-adapter"; + +type Point = Record; +type Segment = { id?: number; active?: boolean; kind?: string; motion_type?: number; kinematics_mode?: number; turn?: number; center?: Point; normal?: Point; samples?: Point[]; start?: Point; end?: Point }; +type Props = { visual: XyzacVisualState; view?: "z" | "z2" | "x" | "y" | "y2" | "p"; zoom?: number; rotateMode?: boolean; showPath?: boolean; showLive?: boolean; showLimits?: boolean; showVelocity?: boolean; showOffsets?: boolean; showExtents?: boolean }; + +const DEG = Math.PI / 180; +const MM = 0.01; +const sourcePoint = (point: Point) => new THREE.Vector3(Number(point.x ?? 0) * MM, Number(point.z ?? 0) * MM, Number(point.y ?? 0) * MM); + +export function XyzacToolPreview({ visual, view = "p", zoom = 1, rotateMode = false, showPath = true, showLive = true, showLimits = false, showVelocity = false, showOffsets = false, showExtents = false }: Props) { + const host = useRef(null); + const hudRef = useRef(null); + const visualRef = useRef(visual); visualRef.current = visual; + const viewRef = useRef(view); viewRef.current = view; + const zoomRef = useRef(zoom); zoomRef.current = zoom; + const rotateRef = useRef(rotateMode); rotateRef.current = rotateMode; + const layersRef = useRef({ showPath, showLive, showLimits, showVelocity, showOffsets, showExtents }); + layersRef.current = { showPath, showLive, showLimits, showVelocity, showOffsets, showExtents }; + + useEffect(() => { + const element = host.current; + if (!element) return; + const scene = new THREE.Scene(); + scene.background = new THREE.Color(0x050a0e); + scene.add(new THREE.HemisphereLight(0xdcecff, 0x121820, 1.4)); + const camera = new THREE.PerspectiveCamera(40, 1, 0.01, 100); + const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: false, preserveDrawingBuffer: true }); + renderer.setPixelRatio(Math.min(globalThis.devicePixelRatio || 1, 2)); + renderer.domElement.dataset.engine = "three.js r185 / xyzac-tool-preview"; + element.appendChild(renderer.domElement); + const controls = new OrbitControls(camera, renderer.domElement); + controls.enableDamping = true; + controls.dampingFactor = .12; + controls.enableZoom = true; + controls.enablePan = true; + controls.enableRotate = true; + controls.screenSpacePanning = true; + controls.target.set(0, 0, 0); + const originGroup = new THREE.Group(); originGroup.name = "xyzac-origin-coordinate-system"; scene.add(originGroup); + const origin = new THREE.Mesh(new THREE.SphereGeometry(.035, 12, 8), new THREE.MeshBasicMaterial({ color: 0xffffff })); origin.name = "xyzac-origin"; originGroup.add(origin); + const originAxes = [ + { label: "X", direction: new THREE.Vector3(1, 0, 0), color: 0xe5534b, position: new THREE.Vector3(.72, 0, 0) }, + { label: "Y", direction: new THREE.Vector3(0, 0, 1), color: 0x55b86a, position: new THREE.Vector3(0, 0, .72) }, + { label: "Z", direction: new THREE.Vector3(0, 1, 0), color: 0x4d8fe8, position: new THREE.Vector3(0, .72, 0) }, + ]; + for (const axis of originAxes) { + const arrow = new THREE.ArrowHelper(axis.direction, new THREE.Vector3(), .62, axis.color, .1, .055); arrow.name = `xyzac-origin-axis-${axis.label.toLowerCase()}`; originGroup.add(arrow); + const labelCanvas = document.createElement("canvas"); labelCanvas.width = 96; labelCanvas.height = 48; + const labelContext = labelCanvas.getContext("2d"); + if (labelContext) { labelContext.clearRect(0, 0, labelCanvas.width, labelCanvas.height); labelContext.fillStyle = `#${axis.color.toString(16).padStart(6, "0")}`; labelContext.font = "bold 32px sans-serif"; labelContext.textAlign = "center"; labelContext.textBaseline = "middle"; labelContext.fillText(axis.label, 48, 24); } + const label = new THREE.Sprite(new THREE.SpriteMaterial({ map: new THREE.CanvasTexture(labelCanvas), transparent: true, depthTest: false })); label.name = `xyzac-origin-label-${axis.label.toLowerCase()}`; label.position.copy(axis.position); label.scale.set(.42, .21, 1); originGroup.add(label); + } + const grid = new THREE.GridHelper(2.5, 10, 0x304553, 0x18252d); grid.name = "xyzac-preview-grid"; scene.add(grid); + const pathGroup = new THREE.Group(); pathGroup.name = "xyzac-preview-toolpath"; scene.add(pathGroup); + const liveGroup = new THREE.Group(); liveGroup.name = "xyzac-preview-live-toolpath"; scene.add(liveGroup); + const toolGroup = new THREE.Group(); toolGroup.name = "xyzac-preview-tool"; scene.add(toolGroup); + const overlayGroup = new THREE.Group(); overlayGroup.name = "xyzac-preview-overlays"; scene.add(overlayGroup); + const offsetAxes = new THREE.AxesHelper(1.5); offsetAxes.name = "xyzac-preview-offset-axes"; overlayGroup.add(offsetAxes); + const limitGrid = new THREE.GridHelper(2.5, 10, 0x8b4d47, 0x4f2d2d); limitGrid.name = "xyzac-preview-limits"; overlayGroup.add(limitGrid); + const toolMaterial = new THREE.MeshStandardMaterial({ color: 0xb8bec4, roughness: .45, metalness: .35 }); + const tool = new THREE.Mesh(new THREE.CylinderGeometry(.04, .04, .58, 20), toolMaterial); tool.name = "xyzac-preview-tool-shaft"; toolGroup.add(tool); + const tipGeometry = new THREE.ConeGeometry(.09, .28, 24); tipGeometry.rotateZ(Math.PI); tipGeometry.translate(0, .14, 0); + const tip = new THREE.Mesh(tipGeometry, new THREE.MeshBasicMaterial({ color: 0xf2f2f2 })); tip.name = "xyzac-preview-tool-tip"; toolGroup.add(tip); + const resize = () => { const width = Math.max(element.clientWidth, 280); const height = Math.max(element.clientHeight, 260); camera.aspect = width / height; camera.updateProjectionMatrix(); renderer.setSize(width, height, false); }; + const observer = new ResizeObserver(resize); observer.observe(element); resize(); + const fit = (segments: Segment[]) => { + const points = segments.flatMap((segment) => (Array.isArray(segment.samples) && segment.samples.length > 1 ? segment.samples : [segment.start ?? {}, segment.end ?? {}]).map(sourcePoint)); + if (!points.length) return { center: new THREE.Vector3(), radius: .12 }; + const box = new THREE.Box3().setFromPoints(points); + return { center: box.getCenter(new THREE.Vector3()), radius: Math.max(box.getSize(new THREE.Vector3()).length() * .65, .12) }; + }; + const clearLines = (group: THREE.Group) => { + for (const child of group.children) { + const line = child as THREE.Line; + line.geometry?.dispose(); + } + group.clear(); + }; + const completed = new THREE.LineBasicMaterial({ color: 0xd8dfe3, depthTest: false }); + const rapid = new THREE.LineDashedMaterial({ color: 0xa85d5d, dashSize: .025, gapSize: .018, depthTest: false }); + const live = new THREE.LineBasicMaterial({ color: 0xffd166, depthTest: false }); + const liveHistory = new THREE.LineBasicMaterial({ color: 0xff6b4a, depthTest: false }); + let frame = 0; + let liveTick = -1; + let liveTrace: THREE.Vector3[] = []; + let pathKey = ""; + let liveKey = ""; + let bounds = { center: new THREE.Vector3(), radius: .12 }; + let playbackQueue: Array<{ tick: number; pose: Point; joints: number[]; activeSegmentId: number; activeProgress: number }> = []; + let playbackStart = 0; + let queuedLastTick = -1; + let renderedTick = -1; + let renderedPose: Point = { x: 0, y: 0, z: 0, a: 0, b: 0, c: 0, u: 0, v: 0, w: 0 }; + let renderedJoints: number[] = []; + let renderedActiveSegment = 0; + let renderedProgress = 0; + let lastPreset = ""; + const presetCamera = (selected: Props["view"], selectedZoom: number) => { + const distance = bounds.radius * 2.9 / Math.max(.5, selectedZoom); + controls.target.copy(bounds.center); + if (selected === "z") camera.position.copy(bounds.center).add(new THREE.Vector3(0, distance, .01)); + else if (selected === "z2") camera.position.copy(bounds.center).add(new THREE.Vector3(distance * .3, distance * .9, distance * .3)); + else if (selected === "x") camera.position.copy(bounds.center).add(new THREE.Vector3(distance, .02, .01)); + else if (selected === "y") camera.position.copy(bounds.center).add(new THREE.Vector3(.01, .02, distance)); + else if (selected === "y2") camera.position.copy(bounds.center).add(new THREE.Vector3(.01, .02, -distance)); + else camera.position.copy(bounds.center).add(new THREE.Vector3(distance * .85, distance * .7, distance)); + camera.lookAt(bounds.center); + controls.update(); + }; + const pan = (horizontal: number, vertical: number) => { + const amount = Math.max(.02, bounds.radius * .12); + const right = new THREE.Vector3().setFromMatrixColumn(camera.matrix, 0); + const up = new THREE.Vector3().setFromMatrixColumn(camera.matrix, 1); + const offset = right.multiplyScalar(horizontal * amount).add(up.multiplyScalar(vertical * amount)); + camera.position.add(offset); controls.target.add(offset); controls.update(); + }; + const zoomCamera = (factor: number) => { + const offset = new THREE.Vector3().subVectors(camera.position, controls.target); + offset.multiplyScalar(factor); + camera.position.copy(controls.target).add(offset); controls.update(); + }; + (element as typeof element & { xyzacController?: Record void> }).xyzacController = { + zoomIn: () => zoomCamera(.8), zoomOut: () => zoomCamera(1.25), panLeft: () => pan(-1, 0), panRight: () => pan(1, 0), panUp: () => pan(0, 1), panDown: () => pan(0, -1), reset: () => { lastPreset = ""; presetCamera(viewRef.current, zoomRef.current); }, + }; + const render = () => { + const state = visualRef.current; + const segments = state.toolpath as Segment[]; + const layer = layersRef.current; + const now = performance.now(); + if (state.tick < queuedLastTick) { + playbackQueue = []; + playbackStart = 0; + queuedLastTick = -1; + } + if (!state.motionTrace.length && state.tick > queuedLastTick) { + playbackQueue = []; + playbackStart = 0; + queuedLastTick = state.tick; + renderedTick = state.tick; + renderedPose = state.livePose; + renderedJoints = state.joints; + renderedActiveSegment = state.activeSegmentId ?? 0; + renderedProgress = state.activeProgress; + } + for (const sample of state.motionTrace) { + if (sample.tick > queuedLastTick) { + playbackQueue.push(sample); + queuedLastTick = sample.tick; + } + } + if (playbackQueue.length && playbackStart === 0) playbackStart = now; + if (playbackQueue.length) { + const index = Math.min(playbackQueue.length - 1, Math.max(0, Math.floor((now - playbackStart) / 10))); + const sample = playbackQueue[index]; + renderedTick = sample.tick; + renderedPose = sample.pose; + renderedJoints = sample.joints; + renderedActiveSegment = sample.activeSegmentId; + renderedProgress = sample.activeProgress; + if (index > 32) { + playbackQueue.splice(0, index); + playbackStart += index * 10; + } + } else { + renderedTick = state.tick; + renderedPose = state.livePose; + renderedJoints = state.joints; + renderedActiveSegment = state.activeSegmentId ?? 0; + renderedProgress = state.activeProgress; + } + // The planned path is immutable for a loaded program. Rebuilding all + // geometries on every animation frame starves worker snapshots and + // makes an otherwise continuous WASM trajectory appear to stutter. + const nextPathKey = segments.map((segment) => `${segment.id}:${segment.kind ?? ""}:${segment.samples?.length ?? 0}:${segment.start?.x ?? 0},${segment.start?.y ?? 0},${segment.start?.z ?? 0}:${segment.end?.x ?? 0},${segment.end?.y ?? 0},${segment.end?.z ?? 0}`).join("|"); + if (nextPathKey !== pathKey) { + clearLines(pathGroup); + bounds = fit(segments); + for (const segment of segments) { + const start = segment.start ?? {}; const end = segment.end ?? {}; + const points = Array.isArray(segment.samples) && segment.samples.length > 1 ? segment.samples.map(sourcePoint) : [sourcePoint(start), sourcePoint(end)]; + const line = new THREE.Line(new THREE.BufferGeometry().setFromPoints(points), segment.kind === "rapid" ? rapid : completed); + if (segment.kind === "rapid") line.computeLineDistances(); + line.renderOrder = 10; + pathGroup.add(line); + } + pathKey = nextPathKey; + liveKey = ""; + } + const presetKey = `${viewRef.current}:${zoomRef.current}:${bounds.radius}:${bounds.center.x}:${bounds.center.y}:${bounds.center.z}`; + if (presetKey !== lastPreset) { presetCamera(viewRef.current, zoomRef.current); lastPreset = presetKey; } + if (renderedTick < liveTick) liveTrace = []; + if (renderedTick !== liveTick) { + const current = sourcePoint(renderedPose); + const previous = liveTrace.at(-1); + if (!previous || previous.distanceTo(current) > 1e-9) liveTrace.push(current); + liveTick = renderedTick; + } + element.dataset.xyzacLiveTraceCount = String(liveTrace.length); + const nextLiveKey = `${renderedTick}:${renderedActiveSegment}:${renderedProgress}:${liveTrace.length}`; + if (nextLiveKey !== liveKey) { + clearLines(liveGroup); + if (liveTrace.length > 1) { + const historyLine = new THREE.Line(new THREE.BufferGeometry().setFromPoints(liveTrace), liveHistory); + historyLine.renderOrder = 19; + liveGroup.add(historyLine); + } + const activeSegment = segments.find((segment) => Boolean(segment.active || segment.id === renderedActiveSegment)); + if (activeSegment) { + const start = activeSegment.start ?? {}; const end = activeSegment.end ?? {}; + const points = Array.isArray(activeSegment.samples) && activeSegment.samples.length > 1 ? activeSegment.samples.map(sourcePoint) : [sourcePoint(start), sourcePoint(end)]; + if (points.length > 1) { + const progress = Math.max(0, Math.min(1, renderedProgress)); + const lastIndex = Math.max(1, Math.floor(progress * (points.length - 1)) + 1); + const travelled = points.slice(0, lastIndex); + const livePoint = sourcePoint(renderedPose); + const lastPoint = travelled.at(-1); + if (!lastPoint || lastPoint.distanceTo(livePoint) > 1e-9) travelled.push(livePoint); + if (travelled.length > 1) { + const liveLine = new THREE.Line(new THREE.BufferGeometry().setFromPoints(travelled), live); + liveLine.renderOrder = 20; + liveGroup.add(liveLine); + } + } + } + liveKey = nextLiveKey; + } + pathGroup.visible = layer.showPath; liveGroup.visible = layer.showLive; + grid.scale.setScalar(Math.max(.2, bounds.radius * 2.4)); + originGroup.scale.setScalar(Math.max(.35, bounds.radius * .55)); + const pose = sourcePoint(renderedPose); + toolGroup.position.copy(pose); + toolGroup.rotation.set(-Number(renderedPose.a ?? 0) * DEG, -Number(renderedPose.c ?? 0) * DEG, 0); + const toolScale = Math.min(1, Math.max(0.15, bounds.radius * 0.55)); + toolGroup.scale.setScalar(toolScale); + tool.position.set(0, .57, 0); tip.position.set(0, 0, 0); + grid.visible = true; limitGrid.visible = layer.showLimits; offsetAxes.visible = layer.showOffsets; + offsetAxes.position.copy(sourcePoint({ x: state.offsets.x_rot_point, y: state.offsets.y_offset, z: state.offsets.z_offset })); + if (hudRef.current) hudRef.current.textContent = `TOOL PREVIEW\nX ${Number(renderedPose.x).toFixed(3)} Y ${Number(renderedPose.y).toFixed(3)} Z ${Number(renderedPose.z).toFixed(3)}\nA ${Number(renderedPose.a).toFixed(3)} C ${Number(renderedPose.c).toFixed(3)}\nJ0 ${Number(renderedJoints[0] ?? 0).toFixed(3)} J1 ${Number(renderedJoints[1] ?? 0).toFixed(3)} J2 ${Number(renderedJoints[2] ?? 0).toFixed(3)}\nJ3 ${Number(renderedJoints[3] ?? 0).toFixed(3)} J4 ${Number(renderedJoints[4] ?? 0).toFixed(3)}\nHelix ${segments.filter((segment) => segment.kind === "helix").length} / Samples ${segments.reduce((count, segment) => count + (Array.isArray(segment.samples) ? segment.samples.length : 0), 0)}\nLive ${renderedActiveSegment || "-"} / ${renderedProgress.toFixed(3)}\nTick ${renderedTick}\nHash ${state.stateHash.slice(0, 18)}`; + controls.update(); scene.rotation.y = rotateRef.current ? (performance.now() / 5000) % (Math.PI * 2) : 0; renderer.render(scene, camera); frame = requestAnimationFrame(render); + }; + render(); + return () => { cancelAnimationFrame(frame); observer.disconnect(); clearLines(pathGroup); clearLines(liveGroup); completed.dispose(); rapid.dispose(); live.dispose(); liveHistory.dispose(); originGroup.traverse((child) => { const mesh = child as THREE.Mesh; mesh.geometry?.dispose?.(); const material = mesh.material as (THREE.Material & { map?: THREE.Texture }) | undefined; material?.map?.dispose?.(); material?.dispose?.(); }); controls.dispose(); delete (element as typeof element & { xyzacController?: unknown }).xyzacController; renderer.dispose(); element.replaceChildren(); }; + }, []); + + const pose = visual.pose; + const helixCount = visual.toolpath.filter((segment) => (segment as { kind?: string }).kind === "helix").length; + const sampleCount = visual.toolpath.reduce((count, segment) => count + (Array.isArray((segment as { samples?: unknown[] }).samples) ? (segment as { samples: unknown[] }).samples.length : 0), 0); + const controllerButton = (action: string, label: string, glyph: string) => ; + return
{controllerButton("zoomIn", "Zoom in", "+")}{controllerButton("zoomOut", "Zoom out", "-")}
{`TOOL PREVIEW\nX ${Number(pose.x).toFixed(3)}  Y ${Number(pose.y).toFixed(3)}  Z ${Number(pose.z).toFixed(3)}\nA ${Number(pose.a).toFixed(3)}  C ${Number(pose.c).toFixed(3)}\nJ0 ${Number(visual.joints[0]).toFixed(3)}  J1 ${Number(visual.joints[1]).toFixed(3)}  J2 ${Number(visual.joints[2]).toFixed(3)}\nJ3 ${Number(visual.joints[3]).toFixed(3)}  J4 ${Number(visual.joints[4]).toFixed(3)}\nHelix ${helixCount} / Samples ${sampleCount}\nLive ${visual.activeSegmentId ?? "-"} / ${visual.activeProgress.toFixed(3)}\nTick ${visual.tick}\nHash ${visual.stateHash.slice(0, 18)}`}
; +} + +export function XyzacToolPreviewFromSnapshot({ snapshot, ...props }: Omit & { snapshot: XyzacVisualSource | null | undefined }) { + return ; +} diff --git a/web/react/src/XyzacTrtPanel.tsx b/web/react/src/XyzacTrtPanel.tsx new file mode 100644 index 0000000..b47fbc8 --- /dev/null +++ b/web/react/src/XyzacTrtPanel.tsx @@ -0,0 +1,50 @@ +import type { ReactNode } from "react"; +import { XYZAC_KINEMATICS, type XyzacOperationTrace, type XyzacPanelView } from "./xyzac-panel-contract"; + +type Command = (kind: string, payload?: Record, action?: string) => void; + +export function XyzacKinematicsControl({ view, command }: { view: XyzacPanelView; command: Command }) { + const active = view.kinematics?.active_type; + return
+
Switchkins{view.kinematics?.native_type ?? "Unavailable"}
+
+ {XYZAC_KINEMATICS.map((item) => { + const gate = view.gates[item.action]; + const disabled = view.status !== "ready" || gate?.enabled === false; + return ; + })} +
+ +
; +} + +export function XyzacManualPanel({ view }: { view: XyzacPanelView }) { + const pose = view.pose; + const axes = ["x", "y", "z", "a", "c"] as const; + return
+
XYZAC authority{view.kinematics?.linear_units ?? "mm"} / {view.kinematics?.angular_units ?? "deg"}
+
+ {axes.map((axis, index) =>
{axis.toUpperCase()}{Number(pose?.[axis] ?? 0).toFixed(axis === "a" || axis === "c" ? 3 : 4)}J{index} {Number(view.joints[index] ?? 0).toFixed(4)}
)} +
+
Tool {Number(view.kinematics?.offsets.tool_offset ?? 0).toFixed(3)}Y offset {Number(view.kinematics?.offsets.y_offset ?? 0).toFixed(3)}Z offset {Number(view.kinematics?.offsets.z_offset ?? 0).toFixed(3)}
+
; +} + +export function XyzacProgramPane({ status, currentLine, sourceHash, children }: { status: string; currentLine: number | null; sourceHash?: string | null; children: ReactNode }) { + return
XYZAC Program{status}Line {currentLine ?? "-"}{sourceHash?.slice(0, 18) ?? "no source"}
{children}
; +} + +export function XyzacDiagnostics({ view, operations, alarms, error }: { view: XyzacPanelView; operations: XyzacOperationTrace[]; alarms: Array>; error: { code: string; message?: string } | null }) { + const disabled = Object.entries(view.gates).filter(([, gate]) => gate.enabled === false); + return
+
{view.status.toUpperCase()}Tick {view.tick}{view.stateHash || "no hash"}
+ {error &&
{error.code}{error.message}
} +

Operation trace

{operations.length ? operations.slice(-8).reverse().map((item, index) =>
{item.operation_id ?? "-"}{item.kind}{item.phase}{item.reason ?? item.response_kind}
) : No operations}
+

Alarms / recovery

{alarms.length ? alarms.slice(-5).map((alarm, index) =>
{String(alarm.code ?? "alarm")}{String(alarm.severity ?? "error")}
) : No alarms}
recovery{view.recovery ? JSON.stringify(view.recovery) : "idle"}
+

Gate reasons

{disabled.length ? disabled.slice(0, 10).map(([name, gate]) =>
{name}{gate.reason}
) : All XYZAC gates enabled}
+
; +} + +export function XyzacTrtPanel({ view, command }: { view: XyzacPanelView; command: Command }) { + return
; +} diff --git a/web/react/src/legacy.d.ts b/web/react/src/legacy.d.ts index 2a7a613..be22613 100644 --- a/web/react/src/legacy.d.ts +++ b/web/react/src/legacy.d.ts @@ -3,6 +3,7 @@ declare module "*.mjs" { export function loadSimulationCase(options: { path: string; baseUrl?: string }): Promise<{ status: string; entrypoint: string; files: Record; missing: string[]; fetched: string[]; state_hash: string; halManifest: unknown[] }>; export function toWorkerConfiguration(bundle: unknown): Record; export class SimSession { contextId: string; sessionId: string; constructor(core: unknown); accept(message: unknown): unknown; } + export class XyzacSession extends SimSession { authority(): Record; } export class AxisOperationController { constructor(client: { send(kind: string, payload?: unknown, operationId?: string): Promise }); execute(kind: string, payload?: Record, options?: { state?: unknown; action?: string | null; gate?: boolean }): Promise<{ operationId: string; response: unknown; gate: { enabled: boolean; reason: string } }>; diff --git a/web/react/src/protocol.ts b/web/react/src/protocol.ts index 0d4cb05..2443722 100644 --- a/web/react/src/protocol.ts +++ b/web/react/src/protocol.ts @@ -56,6 +56,37 @@ export type SimSnapshotV1 = { panel_snapshot?: PanelSnapshotV1; configuration?: Record | null; visual?: PanelSnapshotV1["visual"]; + kinematics?: XyzacKinematicsSnapshot; + xyzac?: XyzacCapabilitySnapshot; + gates?: Record; +}; + +export type XyzacKinematicsSnapshot = { + schema: "wasm-xyzac-kinematics.v1"; + status: "verified" | "error" | "blocked"; + active_type: 0 | 1 | 2; + native_type: string; + coordinates: "XYZAC"; + joint_count: 5; + linear_units: "mm"; + angular_units: "deg"; + pose: Record<"x" | "y" | "z" | "a" | "b" | "c" | "u" | "v" | "w", number>; + joints: [number, number, number, number, number]; + offsets: { x_rot_point: number; y_offset: number; z_offset: number; tool_offset: number }; + generation: number; + switch_count: number; + state_hash: string; + wasm_state_hash: string; +}; + +export type XyzacCapabilitySnapshot = { + coordinates: "XYZAC"; + joint_count: 5; + active_type: 0 | 1 | 2; + hal_pin_vars: boolean; + switchkins_net: boolean; + finite_offsets: boolean; + userk_capability: boolean; }; export type PanelSnapshotV1 = { @@ -81,13 +112,18 @@ export type PanelSnapshotV1 = { schema: "axis-visual.v1"; pose: Record; joints: number[]; - toolpath: Array>; + toolpath?: Array>; active_segment_id?: number | null; + active_progress?: number; + motion_trace?: Array<{ tick: number; pose: Record; joints: number[]; active_segment_id: number; active_progress: number }>; source: "wasm_canonical_motion"; }; authoritative: Record; motion_authority: string; task_authority: string; + kinematics?: XyzacKinematicsSnapshot; + xyzac?: XyzacCapabilitySnapshot; + io?: Record; }; export type Capabilities = { diff --git a/web/react/src/sim-worker-entry.ts b/web/react/src/sim-worker-entry.ts index a504308..0eb6eec 100644 --- a/web/react/src/sim-worker-entry.ts +++ b/web/react/src/sim-worker-entry.ts @@ -1,5 +1,5 @@ import createModule from "../../../build-wasm/linuxcnc-sim-core.js"; -import { SimSession } from "../../worker/sim-session.mjs"; +import { XyzacSession as SimSession } from "../../worker/xyzac-session.mjs"; // The boot event is a transport diagnostic; it carries no simulation state. self.postMessage({ schema_version: 1, kind: "WORKER_BOOT", context_id: "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", session_id: "boot", seq: 0, payload: { status: "booting", runtime: "react-vite-worker" } }); diff --git a/web/react/src/store.ts b/web/react/src/store.ts index 5ae5d0e..8c230ab 100644 --- a/web/react/src/store.ts +++ b/web/react/src/store.ts @@ -57,7 +57,7 @@ function payload(message: MessageEnvelope): T { function projection(result: Record, message: MessageEnvelope, previous: FrontendState) { const panel = result.panel_snapshot as PanelSnapshotV1 | undefined; if (panel?.schema === "axis-panel-snapshot.v1") { - const visualSegments = panel.visual.toolpath + const visualSegments = (Array.isArray(panel.visual.toolpath) ? panel.visual.toolpath : previous.toolpath) .filter((segment) => segment && typeof segment === "object" && Number.isSafeInteger((segment as { id?: unknown }).id ?? 0)) .map((segment, index) => { const value = segment as Record; @@ -68,13 +68,22 @@ function projection(result: Record, message: MessageEnvelope, p end: value.end as Record, ...(value.center ? { center: value.center as Record } : {}), ...(value.normal ? { normal: value.normal as Record } : {}), + ...(Array.isArray(value.samples) ? { samples: value.samples as Array> } : {}), + ...(typeof value.samples_source === "string" ? { samples_source: value.samples_source } : {}), + ...(typeof value.kind === "string" ? { kind: value.kind } : {}), + ...(typeof value.helix === "boolean" ? { helix: value.helix } : {}), + ...(typeof value.radius === "number" ? { radius: value.radius } : {}), + ...(typeof value.turns === "number" ? { turns: value.turns } : {}), + ...(typeof value.axial_delta === "number" ? { axial_delta: value.axial_delta } : {}), + ...(typeof value.canonical_motion_mode === "number" ? { canonical_motion_mode: value.canonical_motion_mode } : {}), + ...(typeof value.kinematics_mode === "number" ? { kinematics_mode: value.kinematics_mode } : {}), ...(typeof value.motion_type === "number" ? { motion_type: value.motion_type } : {}), ...(typeof value.turn === "number" ? { turn: value.turn } : {}), active: value.id === panel.visual.active_segment_id, }; }); const pose = panel.visual.pose; - const axes = [pose.x, pose.y, pose.z].map((value) => Number.isFinite(value) ? value : 0); + const axes = [pose.x, pose.y, pose.z, pose.a, pose.c].map((value) => Number.isFinite(value) ? value : 0); const snapshot = { schema: panel.schema, simulation_tick: panel.simulation_tick, @@ -85,17 +94,20 @@ function projection(result: Record, message: MessageEnvelope, p overrides: panel.overrides, wasm_motion: panel.wasm_motion, authoritative: panel.authoritative as SimSnapshotV1["authoritative"], - configuration: panel.configuration as SimSnapshotV1["configuration"], - visual: panel.visual, + configuration: (panel.configuration ?? previous.snapshot?.configuration ?? null) as SimSnapshotV1["configuration"], + visual: { ...panel.visual, toolpath: visualSegments }, + kinematics: panel.kinematics, + xyzac: panel.xyzac, + gates: panel.gates, } satisfies SimSnapshotV1; return { snapshot, toolpath: visualSegments, task: panel.task, program: panel.program, - devices: panel.devices, - deviceIo: panel.device_io, - hal: panel.hal, + devices: panel.devices ?? previous.devices, + deviceIo: panel.device_io ?? previous.deviceIo, + hal: panel.hal ?? previous.hal, axisState: panel.axis_state, gates: { ...panel.gates, jog: panel.gates.jogStart, load: panel.gates.load, run: panel.gates.run, step: panel.gates.step, pause: panel.gates.pause, resume: panel.gates.resume, abort: panel.gates.abort, mdi: panel.gates.mdi, home: panel.gates.home }, }; diff --git a/web/react/src/styles.css b/web/react/src/styles.css index 81976b5..0203add 100644 --- a/web/react/src/styles.css +++ b/web/react/src/styles.css @@ -16,7 +16,7 @@ } * { box-sizing: border-box; } -html, body, #root { min-height: 100%; margin: 0; } +html, body, #root { min-height: 100%; margin: 0; overflow-x: hidden; } body { min-width: 320px; background: #cfcfcf; color: var(--ink); } button, input, select, textarea { font: inherit; } button { color: inherit; } @@ -31,7 +31,7 @@ button { color: inherit; } .connection-state.ready, .connection-state.running { color: #185c1d; } .connection-state.error, .connection-state.blocked { color: #8b1010; background: #f3d2d2; } -.axis-menubar { display: flex; align-items: stretch; min-height: 27px; padding-left: 3px; border-bottom: 1px solid #888; background: #d3d3d3; } +.axis-menubar { display: flex; align-items: stretch; min-width: 0; min-height: 27px; padding-left: 3px; overflow-x: auto; border-bottom: 1px solid #888; background: #d3d3d3; } .axis-menu-item { position: relative; } .axis-menu-item summary { padding: 5px 10px; cursor: pointer; list-style: none; user-select: none; } .axis-menu-item summary::-webkit-details-marker { display: none; } @@ -41,7 +41,7 @@ button { color: inherit; } .axis-menu-popup button:hover, .axis-menu-popup button:focus-visible { outline: 1px solid var(--focus); background: #c8d7e8; } .axis-menu-popup kbd { margin-left: 22px; color: #555; font: 11px ui-monospace, monospace; } -.axis-toolbar { display: flex; align-items: center; min-height: 35px; padding: 3px 5px; overflow-x: auto; border-bottom: 1px solid #8a8a8a; background: #d9d9d9; } +.axis-toolbar { display: flex; align-items: center; width: 100%; min-width: 0; min-height: 35px; padding: 3px 5px; overflow-x: auto; border-bottom: 1px solid #8a8a8a; background: #d9d9d9; } .axis-tool-button { display: inline-grid; width: 29px; height: 29px; flex: 0 0 29px; place-items: center; padding: 2px; border: 1px solid transparent; border-radius: 2px; background: transparent; cursor: pointer; } .axis-tool-button img { width: 24px; height: 24px; object-fit: contain; pointer-events: none; } .axis-tool-button:hover, .axis-tool-button:focus-visible { border-color: #6a8db6; background: #c8d7e8; outline: none; } @@ -50,14 +50,60 @@ button { color: inherit; } .axis-tool-button:disabled { cursor: not-allowed; opacity: .48; } .axis-toolbar-separator { width: 1px; height: 26px; flex: 0 0 1px; margin: 0 5px; border-left: 1px solid #969696; border-right: 1px solid #eee; } -.axis-case-strip { display: flex; align-items: center; gap: 7px; min-height: 34px; padding: 4px 8px; border-bottom: 1px solid #999; background: #c7c7c7; } -.axis-case-strip label { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; } -.axis-case-strip select { max-width: min(420px, 46vw); min-height: 24px; border: 1px solid var(--border-dark); background: white; } +.axis-case-strip { display: flex; align-items: center; width: 100%; min-width: 0; gap: 7px; min-height: 34px; padding: 4px 8px; border-bottom: 1px solid #999; background: #c7c7c7; } +.axis-case-strip label { display: inline-flex; align-items: center; min-width: 0; flex: 0 0 auto; gap: 5px; font-size: 12px; } +.axis-case-strip select { width: min(420px, 46vw); max-width: 100%; min-height: 24px; border: 1px solid var(--border-dark); background: white; } +.axis-case-strip > .axis-text-button { min-width: 68px; white-space: nowrap; } .case-status, .command-status { overflow: hidden; color: #4d4d4d; font: 11px ui-monospace, monospace; text-overflow: ellipsis; white-space: nowrap; } +.case-status { min-width: 0; flex: 1 1 auto; } .command-status { margin-left: auto; } +.machine-sequence { display: flex; align-items: center; gap: 12px; min-width: 0; padding: 6px 9px; border-bottom: 1px solid #858585; background: #cfcfcf; } +.machine-sequence-heading { display: grid; gap: 2px; min-width: 148px; } +.machine-sequence-heading strong { font-size: 12px; } +.machine-sequence-heading span { color: #555; font: 10px ui-monospace, monospace; } +.machine-sequence-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; min-width: 0; } +.machine-sequence-actions .axis-text-button { min-height: 28px; } +.machine-sequence-actions .axis-text-button:first-child { border-color: #9b4a4a; } + +.xyzac-control-band { display: grid; grid-template-columns: minmax(330px, .8fr) minmax(470px, 1.5fr); gap: 12px; padding: 7px 10px; border-bottom: 1px solid #858585; background: #d5d5d5; } +.xyzac-kinematics, .xyzac-manual-summary { min-width: 0; } +.xyzac-section-title { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 5px; font-size: 11px; } +.xyzac-section-title strong { font-size: 12px; } +.xyzac-section-title span { overflow: hidden; color: #555; font: 10px ui-monospace, monospace; text-overflow: ellipsis; white-space: nowrap; } +.xyzac-segments { display: grid; grid-template-columns: repeat(3, minmax(86px, 1fr)); min-height: 38px; } +.xyzac-segments button { display: grid; place-content: center; min-width: 0; min-height: 38px; padding: 3px 7px; border: 1px solid #777; border-right-width: 0; border-radius: 0; background: #ededed; cursor: pointer; } +.xyzac-segments button:first-child { border-radius: 3px 0 0 3px; } +.xyzac-segments button:last-child { border-right-width: 1px; border-radius: 0 3px 3px 0; } +.xyzac-segments button.active { color: #fff; background: #315f8b; box-shadow: inset 0 0 0 1px #173b5e; } +.xyzac-segments button:disabled { color: #777; cursor: not-allowed; background: #c9c9c9; } +.xyzac-segments button span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +.xyzac-segments button small { font: 9px ui-monospace, monospace; } +.xyzac-clear { min-height: 24px; margin-top: 5px; padding: 2px 9px; border: 1px solid #858585; border-radius: 2px; background: #eee; cursor: pointer; } +.xyzac-position-grid { display: grid; grid-template-columns: repeat(5, minmax(74px, 1fr)); border: 1px solid #909090; background: #f4f4f4; } +.xyzac-position-grid > div { display: grid; grid-template-columns: 18px 1fr; align-items: baseline; min-width: 0; padding: 4px 6px; border-right: 1px solid #aaa; } +.xyzac-position-grid > div:last-child { border-right: 0; } +.xyzac-position-grid b { grid-row: span 2; font-size: 12px; } +.xyzac-position-grid output { overflow: hidden; font-size: 13px; text-overflow: ellipsis; } +.xyzac-position-grid small { overflow: hidden; color: #666; font: 9px ui-monospace, monospace; text-overflow: ellipsis; white-space: nowrap; } +.xyzac-offset-row { display: flex; gap: 12px; margin-top: 5px; color: #555; font: 10px ui-monospace, monospace; } +.xyzac-program { display: contents; } +.xyzac-program > header { display: flex; align-items: center; gap: 14px; min-height: 25px; margin: 0 5px; padding: 3px 8px; border: 1px solid #888; border-bottom: 0; background: #d4d4d4; font-size: 11px; } +.xyzac-program > header code { margin-left: auto; color: #4d4d4d; } +.xyzac-diagnostics { display: grid; gap: 8px; padding: 10px; border-top: 1px solid #aaa; background: #ededed; font-size: 11px; } +.xyzac-diagnostics h3 { margin: 0 0 3px; font-size: 11px; } +.xyzac-diagnostic-summary, .xyzac-diagnostic-row, .xyzac-error { display: flex; align-items: baseline; gap: 8px; min-width: 0; } +.xyzac-diagnostic-summary code, .xyzac-diagnostic-row span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +.xyzac-diagnostic-row code { min-width: 128px; } +.xyzac-error { padding: 5px; color: #7b1111; border: 1px solid #bd8585; background: #f7dddd; } + .axis-top-pane { display: grid; grid-template-columns: minmax(360px, .48fr) minmax(430px, 1fr); height: clamp(360px, calc(100vh - 415px), 680px); min-height: 360px; flex: 0 0 auto; padding: 5px; gap: 5px; } -.axis-notebook { min-width: 0; display: flex; flex-direction: column; border: 1px solid var(--border-dark); background: var(--face-light); } +.axis-notebook { min-width: 0; min-height: 0; display: flex; flex-direction: column; border: 1px solid var(--border-dark); background: var(--face-light); } +.axis-notebook > [role="tabpanel"] { min-width: 0; min-height: 0; flex: 1; overflow: auto; } +.axis-notebook > [role="tabpanel"] > .manual-control, +.axis-notebook > [role="tabpanel"] > .mdi-control, +.axis-notebook > [role="tabpanel"] > .dro-view, +.axis-notebook > [role="tabpanel"] > .axis-preview { height: 100%; min-height: 0; } .notebook-tabs { display: flex; align-items: end; min-height: 29px; padding: 3px 3px 0; border-bottom: 1px solid #777; background: #c5c5c5; } .notebook-tabs button { min-height: 26px; padding: 4px 12px; border: 1px solid transparent; border-bottom: 0; background: transparent; cursor: pointer; } .notebook-tabs button.active { margin-bottom: -1px; border-color: #777; background: var(--face-light); font-weight: 700; } @@ -104,6 +150,10 @@ output { font: 12px ui-monospace, monospace; text-align: right; } .three-viewer { position: relative; width: 100%; height: 100%; min-height: 0; flex: 1; overflow: hidden; border: 1px solid #303030; background: #000; } .three-viewer canvas { display: block; width: 100%; height: 100%; } .axis-preview-hud { position: absolute; z-index: 1; top: 11px; left: 34px; margin: 0; color: #f2f2f2; font: 12px/1.45 ui-monospace, monospace; white-space: pre; pointer-events: none; text-shadow: 0 1px #000; } +.xyzac-view-controller { position: absolute; z-index: 2; top: 8px; right: 8px; display: grid; grid-template-columns: repeat(2, 27px); gap: 3px; padding: 4px; border: 1px solid #68747c; background: rgba(12, 18, 22, .88); box-shadow: 0 1px 4px #0008; } +.xyzac-view-controller button { width: 27px; height: 25px; padding: 0; border: 1px solid #93a1a8; background: #e6ebed; color: #182126; font: 700 14px/1 ui-monospace, monospace; cursor: pointer; } +.xyzac-view-controller button:hover, .xyzac-view-controller button:focus-visible { background: #fff; outline: 2px solid #e7b84b; outline-offset: 1px; } +.xyzac-controller-divider { width: 100%; height: 1px; grid-column: 1 / -1; background: #68747c; } .dro-view { background: #ececec; } .dro-mode-row, .dro-column-headings, .dro-row { display: grid; grid-template-columns: 42px repeat(3, minmax(100px, 1fr)); align-items: center; gap: 9px; } .dro-mode-row { padding: 5px 6px; border-bottom: 1px solid #888; color: #555; font-size: 11px; } @@ -141,16 +191,17 @@ output { font: 12px ui-monospace, monospace; text-align: right; } .visually-hidden-file-input { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; } .axis-layer-controls { display: flex; flex-wrap: wrap; gap: 8px 12px; margin-top: 4px; color: #4d4d4d; font-size: 11px; } .axis-layer-controls input { margin: 0; } -.axis-info-bar { display: flex; align-items: stretch; min-height: 27px; margin-top: auto; border-top: 1px solid #777; background: #c4c4c4; } -.axis-info-bar > span { display: flex; align-items: center; min-height: 25px; padding: 2px 9px; border-right: 1px solid #999; font: 12px ui-monospace, monospace; } +.axis-info-bar { display: flex; align-items: stretch; width: 100%; min-width: 0; min-height: 27px; margin-top: auto; border-top: 1px solid #777; background: #c4c4c4; } +.axis-info-bar > span { display: flex; align-items: center; min-width: 0; min-height: 25px; padding: 2px 9px; overflow: hidden; border-right: 1px solid #999; font: 12px ui-monospace, monospace; text-overflow: ellipsis; white-space: nowrap; } .task-state { min-width: 92px; background: #ececec; font-weight: 700 !important; } .task-state.running { color: #145d1c; } .task-state.blocked, .task-state.error { color: #9b111e; background: #f2d6d6; } -.tool-state { flex: 1; } +.tool-state { min-width: 0; flex: 1; } .position-state { min-width: 230px; } .footer-status { min-width: 180px; color: #505050; } @media (max-width: 900px) { + .xyzac-control-band { grid-template-columns: 1fr; } .axis-top-pane { grid-template-columns: 1fr; height: auto; min-height: 0; flex: 0 0 auto; } .axis-notebook { min-height: 330px; } .axis-preview { min-height: 320px; } @@ -163,6 +214,15 @@ output { font: 12px ui-monospace, monospace; text-align: right; } .axis-case-strip { flex-wrap: wrap; } .axis-case-strip select { max-width: 62vw; } .command-status { margin-left: 0; width: 100%; } + .machine-sequence { align-items: flex-start; flex-direction: column; gap: 5px; } + .machine-sequence-heading { min-width: 0; } + .xyzac-control-band { padding: 6px; } + .xyzac-position-grid { grid-template-columns: repeat(5, minmax(54px, 1fr)); } + .xyzac-position-grid > div { grid-template-columns: 14px 1fr; padding: 3px; } + .xyzac-position-grid output { font-size: 10px; } + .xyzac-offset-row { flex-wrap: wrap; gap: 4px 9px; } + .xyzac-program > header { flex-wrap: wrap; gap: 4px 10px; } + .xyzac-program > header code { width: 100%; margin-left: 0; } .manual-grid, .manual-sliders, .axis-slider { grid-template-columns: 1fr; } .manual-axis-block, .manual-coolant-block { grid-row: auto; grid-column: auto; } .dro-mode-row, .dro-column-headings, .dro-row { grid-template-columns: 27px repeat(3, minmax(0, 1fr)); gap: 4px; } diff --git a/web/react/src/test_xyzac_threejs.mjs b/web/react/src/test_xyzac_threejs.mjs new file mode 100644 index 0000000..80a9569 --- /dev/null +++ b/web/react/src/test_xyzac_threejs.mjs @@ -0,0 +1,44 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import { projectXyzacVisual, XYZAC_MACHINE_GROUPS } from "./xyzac-visual-adapter.ts"; + +const source = await readFile(new URL("./XyzacMachineView.tsx", import.meta.url), "utf8"); +const adapter = await readFile(new URL("./xyzac-visual-adapter.ts", import.meta.url), "utf8"); +const snapshot = { + schema: "axis-panel-snapshot.v1", + simulation_tick: 42, + state_hash: "fnv1a64:xyzac-authoritative", + kinematics: { + schema: "wasm-xyzac-kinematics.v1", + status: "verified", + active_type: 1, + native_type: "xyzac-trt-kins", + coordinates: "XYZAC", + joint_count: 5, + linear_units: "mm", + angular_units: "deg", + pose: { x: 12, y: -5, z: 20, a: 30, b: 0, c: 45, u: 0, v: 0, w: 0 }, + joints: [12, -5, 20, 30, 45], + offsets: { x_rot_point: 0, y_offset: 20, z_offset: 10, tool_offset: 25 }, + generation: 2, + switch_count: 2, + state_hash: "fnv1a64:kinematics", + wasm_state_hash: "fnv1a64:wasm-kinematics", + }, + visual: { active_segment_id: 7, active_progress: 0.5, pose: { x: 12, y: -5, z: 20, a: 30, c: 45 }, joints: [12, -5, 20, 30, 45], toolpath: [{ id: 7, active: true, start: { x: 0, y: 0, z: 0 }, end: { x: 12, y: -5, z: 20 }, motion_type: 1 }] }, +}; +const visual = projectXyzacVisual(snapshot); +assert.equal(visual.schema, "xyzac-visual-state.v1"); +assert.equal(visual.tick, 42); +assert.equal(visual.stateHash, snapshot.state_hash); +assert.deepEqual(visual.joints, [12, -5, 20, 30, 45]); +assert.deepEqual(visual.pose, snapshot.kinematics.pose); +assert.deepEqual(visual.offsets, snapshot.kinematics.offsets); +assert.equal(visual.activeSegmentId, 7); +assert.equal(visual.activeProgress, 0.5); +assert.equal(visual.source, "linuxcnc-wasm-worker"); +assert.deepEqual(XYZAC_MACHINE_GROUPS, ["xyzac-machine", "table-x", "saddle-y", "spindle-z", "tilt-a", "rotate-c", "tool-offset", "xyzac-toolpath", "xyzac-live-toolpath"]); +for (const token of ["table-x", "saddle-y", "spindle-z", "tilt-a", "rotate-c", "tool-offset", "tableX.position.x = -tableXJoint * MM", "saddle.position.z = -saddleYJoint * MM", "zslide.position.y = (200 - spindleZJoint) * MM", "tilt.rotation.x = -tiltAJoint * DEG", "rotate.rotation.y = -rotateCJoint * DEG", "tool.position.y = -state.offsets.tool_offset * MM", "data-xyzac-tick", "data-xyzac-state-hash", "data-xyzac-active-segment", "data-xyzac-joints", "data-xyzac-offsets"]) assert.ok(source.includes(token), token); +for (const forbidden of [/accept\s*\(/, /postMessage\s*\(/, /_sim_/, /_malloc/, /navigator\.storage/, /HAL_SET/, /KINEMATICS_SELECT/]) assert.equal(forbidden.test(source), false, String(forbidden)); +assert.ok(adapter.includes("source: \"linuxcnc-wasm-worker\"")); +console.log(JSON.stringify({ schema: "xyzac-threejs-rtcp-10.v1", status: "verified", tick: visual.tick, state_hash: visual.stateHash, groups: XYZAC_MACHINE_GROUPS, active_segment: visual.activeSegmentId, direction: { table_x: -1, saddle_y: -1, spindle_z: -1, tilt_a: "x+", rotate_c: "z+", tool_offset: "z-" }, clear_visual_nonmutating: true, source: visual.source })); diff --git a/web/react/src/test_xyzac_tool_preview.mjs b/web/react/src/test_xyzac_tool_preview.mjs new file mode 100644 index 0000000..9560208 --- /dev/null +++ b/web/react/src/test_xyzac_tool_preview.mjs @@ -0,0 +1,22 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import { projectXyzacVisual } from "./xyzac-visual-adapter.ts"; + +const source = await readFile(new URL("./XyzacToolPreview.tsx", import.meta.url), "utf8"); +const visual = projectXyzacVisual({ + simulation_tick: 12, + state_hash: "fnv1a64:tool-preview", + kinematics: { schema: "wasm-xyzac-kinematics.v1", status: "verified", active_type: 1, native_type: "xyzac-trt-kins", coordinates: "XYZAC", joint_count: 5, linear_units: "mm", angular_units: "deg", pose: { x: 10, y: -5, z: 20, a: 30, b: 0, c: 45, u: 0, v: 0, w: 0 }, joints: [10, -5, 20, 30, 45], offsets: { x_rot_point: 0, y_offset: 20, z_offset: 10, tool_offset: 5 }, generation: 1, switch_count: 1, state_hash: "fnv1a64:k", wasm_state_hash: "fnv1a64:w" }, + visual: { active_segment_id: 3, active_progress: 0.375, pose: { x: 11, y: -4, z: 19, a: 31, c: 44 }, joints: [11, -4, 19, 31, 44], toolpath: [{ id: 3, active: true, motion_type: 1, start: { x: 0, y: 0, z: 0 }, end: { x: 10, y: -5, z: 20 } }] }, +}); +assert.equal(visual.tick, 12); +assert.equal(visual.stateHash, "fnv1a64:tool-preview"); +assert.deepEqual(visual.joints, [11, -4, 19, 31, 44]); +assert.deepEqual(visual.pose, { x: 11, y: -4, z: 19, a: 31, b: 0, c: 44, u: 0, v: 0, w: 0 }); +assert.deepEqual(visual.livePose, visual.pose); +assert.equal(visual.activeProgress, 0.375); +assert.equal(visual.activeSegmentId, 3); +for (const token of ["xyzac-tool-preview", "xyzac-preview-toolpath", "xyzac-preview-live-toolpath", "xyzac-preview-tool", "xyzac-preview-tool-shaft", "xyzac-preview-tool-tip", "xyzac-origin-coordinate-system", "xyzac-origin-axis-${axis.label.toLowerCase()}", "xyzac-origin-label-${axis.label.toLowerCase()}", "OrbitControls", "enablePan", "enableRotate", "zoomIn", "panRight", "data-xyzac-controller=\"orbit\"", "data-xyzac-origin=\"0,0,0\"", "sourcePoint", "toolGroup.position.copy(pose)", "toolGroup.rotation.set(-Number(renderedPose.a ?? 0) * DEG, -Number(renderedPose.c ?? 0) * DEG, 0)", "const segments = state.toolpath as Segment[]", "segment.samples.map(sourcePoint)", "state.activeProgress", "state.livePose", "motionTrace", "playbackQueue", "data-xyzac-preview=\"toolpath\"", "data-xyzac-helix-count", "data-xyzac-sample-count", "data-xyzac-samples-source", "data-xyzac-live-source", "data-xyzac-live-pose", "preserveDrawingBuffer: true", "authoritative tool preview"]) assert.ok(source.includes(token), token); +for (const forbidden of [/arcPoints/, /Math\.atan2/, /Quaternion/, /cross\(/]) assert.equal(forbidden.test(source), false, String(forbidden)); +for (const forbidden of [/xyzac-machine/, /table-x/, /saddle-y/, /spindle-z/, /accept\s*\(/, /postMessage\s*\(/, /_sim_/, /_malloc/, /navigator\.storage/]) assert.equal(forbidden.test(source), false, String(forbidden)); +console.log(JSON.stringify({ schema: "xyzac-tool-preview-rtcp-10b.v1", status: "verified", tick: visual.tick, state_hash: visual.stateHash, active_segment: visual.activeSegmentId, tool_pose: visual.pose, joints: visual.joints, machine_scene_nodes: 0, canonical_toolpath_segments: visual.toolpath.length, source: visual.source })); diff --git a/web/react/src/xyzac-panel-contract.ts b/web/react/src/xyzac-panel-contract.ts new file mode 100644 index 0000000..0f27454 --- /dev/null +++ b/web/react/src/xyzac-panel-contract.ts @@ -0,0 +1,59 @@ +import type { XyzacCapabilitySnapshot, XyzacKinematicsSnapshot } from "./protocol"; + +export const XYZAC_CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini" as const; +export const XYZAC_AXES = ["x", "y", "z", "a", "c"] as const; +export const XYZAC_COMMANDS = { + power: "POWER", + selectKinematics: "KINEMATICS_SELECT", + clearVisual: "VISUAL_CLEAR", +} as const; +export const XYZAC_KINEMATICS = [ + { type: 0, action: "switchkinsIdentity", label: "Identity", mcode: "M429" }, + { type: 1, action: "switchkinsXyzac", label: "TCP: XYZAC", mcode: "M428" }, + { type: 2, action: "switchkinsUserk", label: "User K", mcode: "M430" }, +] as const; + +export type XyzacGate = { action: string; enabled: boolean; reason: string; required_type?: number; visual_only?: boolean }; +export type XyzacOperationTrace = { operation_id?: string; kind?: string; action?: string | null; phase?: string; reason?: string; response_kind?: string }; +export type XyzacPanelView = { + status: "ready" | "unavailable"; + tick: number; + stateHash: string; + kinematics: XyzacKinematicsSnapshot | null; + capability: XyzacCapabilitySnapshot | null; + pose: XyzacKinematicsSnapshot["pose"] | null; + joints: number[]; + gates: Record; + recovery: Record | null; +}; + +type XyzacPanelSource = { + simulation_tick?: number; + state_hash?: string; + kinematics?: XyzacKinematicsSnapshot; + xyzac?: XyzacCapabilitySnapshot; + gates?: Record; + authoritative?: Record; + visual?: { pose?: Record; joints?: number[] }; +}; + +export function projectXyzacPanel(snapshot: XyzacPanelSource | null | undefined): XyzacPanelView { + const kinematics = snapshot?.kinematics?.coordinates === "XYZAC" && snapshot.kinematics.joint_count === 5 ? snapshot.kinematics : null; + const capability = snapshot?.xyzac?.coordinates === "XYZAC" && snapshot.xyzac.joint_count === 5 ? snapshot.xyzac : null; + const visualPose = snapshot?.visual?.pose; + const pose = visualPose && [visualPose.x, visualPose.y, visualPose.z, visualPose.a, visualPose.c].every((value) => Number.isFinite(value)) + ? { ...(kinematics?.pose ?? { x: 0, y: 0, z: 0, a: 0, b: 0, c: 0, u: 0, v: 0, w: 0 }), ...visualPose } + : kinematics?.pose ?? null; + const joints = snapshot?.visual?.joints?.length === 5 ? snapshot.visual.joints.slice(0, 5) : kinematics?.joints ? [...kinematics.joints] : []; + return { + status: kinematics && capability ? "ready" : "unavailable", + tick: snapshot?.simulation_tick ?? 0, + stateHash: snapshot?.state_hash ?? "", + kinematics, + capability, + pose, + joints, + gates: snapshot?.gates ?? {}, + recovery: (snapshot?.authoritative?.recovery as Record | undefined) ?? null, + }; +} diff --git a/web/react/src/xyzac-visual-adapter.ts b/web/react/src/xyzac-visual-adapter.ts new file mode 100644 index 0000000..5107924 --- /dev/null +++ b/web/react/src/xyzac-visual-adapter.ts @@ -0,0 +1,57 @@ +import type { XyzacKinematicsSnapshot } from "./protocol"; + +export type XyzacVisualState = { + schema: "xyzac-visual-state.v1"; + tick: number; + stateHash: string; + pose: XyzacKinematicsSnapshot["pose"]; + joints: [number, number, number, number, number]; + livePose: XyzacKinematicsSnapshot["pose"]; + activeProgress: number; + motionTrace: Array<{ tick: number; pose: XyzacKinematicsSnapshot["pose"]; joints: number[]; activeSegmentId: number; activeProgress: number }>; + offsets: XyzacKinematicsSnapshot["offsets"]; + activeSegmentId: number | null; + toolpath: Array>; + source: "linuxcnc-wasm-worker"; +}; + +const ZERO_POSE: XyzacKinematicsSnapshot["pose"] = { x: 0, y: 0, z: 0, a: 0, b: 0, c: 0, u: 0, v: 0, w: 0 }; +const ZERO_OFFSETS: XyzacKinematicsSnapshot["offsets"] = { x_rot_point: 0, y_offset: 0, z_offset: 0, tool_offset: 0 }; + +export type XyzacVisualSource = { + simulation_tick?: number; + state_hash?: string; + kinematics?: XyzacKinematicsSnapshot; + visual?: { active_segment_id?: number | null; active_progress?: number; motion_trace?: Array<{ tick: number; pose: Record; joints: number[]; active_segment_id: number; active_progress: number }>; pose?: Record; joints?: number[]; toolpath?: Array> }; +}; + +export function projectXyzacVisual(snapshot: XyzacVisualSource | null | undefined): XyzacVisualState { + const kinematics = snapshot?.kinematics; + const visualPose = snapshot?.visual?.pose; + const pose = visualPose && [visualPose.x, visualPose.y, visualPose.z, visualPose.a, visualPose.c].every((value) => Number.isFinite(value)) + ? { ...ZERO_POSE, ...visualPose } + : kinematics?.pose ?? ZERO_POSE; + const visualJoints = snapshot?.visual?.joints; + const joints: [number, number, number, number, number] = visualJoints?.length === 5 + ? visualJoints.slice(0, 5).map((value) => Number(value)) as [number, number, number, number, number] + : kinematics?.joints?.length === 5 ? [...kinematics.joints] as [number, number, number, number, number] : [0, 0, 0, 0, 0]; + const rawProgress = snapshot?.visual?.active_progress; + const activeProgress = Number.isFinite(rawProgress) ? Math.max(0, Math.min(1, Number(rawProgress))) : 0; + const motionTrace = (snapshot?.visual?.motion_trace ?? []).filter((sample) => sample && Number.isSafeInteger(sample.tick) && sample.pose && Array.isArray(sample.joints)).map((sample) => ({ tick: sample.tick, pose: { ...ZERO_POSE, ...sample.pose }, joints: sample.joints.slice(0, 5).map(Number), activeSegmentId: Number(sample.active_segment_id ?? 0), activeProgress: Math.max(0, Math.min(1, Number(sample.active_progress ?? 0))) })); + return { + schema: "xyzac-visual-state.v1", + tick: snapshot?.simulation_tick ?? 0, + stateHash: snapshot?.state_hash ?? "", + pose, + joints, + livePose: pose, + activeProgress, + motionTrace, + offsets: kinematics?.offsets ?? ZERO_OFFSETS, + activeSegmentId: snapshot?.visual?.active_segment_id ?? null, + toolpath: snapshot?.visual?.toolpath ?? [], + source: "linuxcnc-wasm-worker", + }; +} + +export const XYZAC_MACHINE_GROUPS = Object.freeze(["xyzac-machine", "table-x", "saddle-y", "spindle-z", "tilt-a", "rotate-c", "tool-offset", "xyzac-toolpath", "xyzac-live-toolpath"]); diff --git a/web/worker/sim-session.mjs b/web/worker/sim-session.mjs index db6159a..40d9889 100644 --- a/web/worker/sim-session.mjs +++ b/web/worker/sim-session.mjs @@ -1,7 +1,7 @@ import { ReplayTimeline, fnv1a64 } from "./replay.mjs"; import { capabilities, validateLimit } from "./capabilities.mjs"; import { mapCoreError } from "./error-map.mjs"; -import { createCheckpoint, recoverSimulation } from "../workspace/recovery.mjs"; +import { createCheckpoint, recoverSimulation, validateCheckpoint } from "../workspace/recovery.mjs"; import { preflightConfiguration } from "../workspace/configuration.mjs"; import { ConfigurationStartupStateMachine } from "../workspace/configuration.mjs"; import { preflightHalConfiguration } from "../workspace/hal-configuration.mjs"; @@ -23,7 +23,11 @@ import { AuthoritativeRuntime } from "./authoritative-runtime.mjs"; import { axisState } from "./axis-state.mjs"; import { WasmMotionQueue } from "./wasm-motion-queue.mjs"; import { WasmHomeLimit } from "./wasm-home-limit.mjs"; -import { axisGate } from "../app/axis-contract.mjs"; +import { WasmXyzacKinematics, XYZAC_MODES } from "./wasm-xyzac-kinematics.mjs"; +import { WasmXyzacIo } from "./wasm-xyzac-io.mjs"; +import { WasmXyzacDeviceIo } from "./wasm-xyzac-device-io.mjs"; +import { WasmProgramRuntime } from "./wasm-program-runtime.mjs"; +import { axisGate, xyzacGate, xyzacGateMatrix } from "../app/axis-contract.mjs"; const PROTOCOL_SCHEMA = 1; const CONTEXT_ID = "linuxcnc-2.10.0-pre0-wasm-m1-py-c1"; @@ -41,6 +45,7 @@ const OPERATION_KINDS = new Set([ "PYTHON_IMPORT", "PYTHON_CALL", "PYTHON_CAPABILITY", "PROGRAM_STEP", "PROGRAM_SEEK", "MDI_EXECUTE", "PLC_CONFIG", "PLC_SET", "PLC_TRIGGER", "FOLLOWING_ERROR", "IO_COMMAND", "IO_ACK", "IO_TIMEOUT", "REMAP_REGISTER", "REMAP_CALL", "VCP_REGISTER", "VCP_UPDATE", "FILTER_EXEC", + "POWER", "KINEMATICS_SELECT", "VISUAL_CLEAR", ]); const PANEL_GATE_ACTIONS = Object.freeze({ @@ -48,6 +53,7 @@ const PANEL_GATE_ACTIONS = Object.freeze({ PROGRAM_RESUME: "resume", PROGRAM_ABORT: "abort", PROGRAM_RESTART: "restart", JOG_START: "jogStart", JOG_STOP: "jogStop", HOME: "home", SET_OVERRIDE: "override", ESTOP: "estop", IO_RECOVER: "recover", + POWER: "power", }); function text(value) { @@ -102,21 +108,33 @@ export class SimSession { this.authoritative = new AuthoritativeRuntime(); this.wasmMotion = new WasmMotionQueue(core); this.wasmHomeLimit = new WasmHomeLimit(core); + this.xyzacKinematics = null; + this.xyzacIo = null; + this.xyzacDeviceIo = null; + this.xyzacProgram = null; + this.xyzacProgramKinematicsMode = XYZAC_MODES.identity; + this.xyzacRapidVelocity = 35; + this.pendingProgramControl = 0; this.motionAuthority = "js"; this.task = new SimTask(core, { contextId, sessionId: sessionId || null }); this.scheduler = new SimScheduler(core); this.configurationState = null; this.halState = null; this.previewState = null; + this.workspaceFiles = {}; call(core, "sim_protocol_reset"); if (typeof core.ccall === "function") core.ccall("sim_event_reset", null, [], []); } envelope(kind, input, payload, tick = this.tick) { const statePayload = payload && typeof payload === "object" ? payload : {}; - const program = statePayload.program ?? (this.program.loaded ? this.program.snapshot() : {}); + const program = statePayload.program ?? (this.xyzacProgram ? this.xyzacProgram.snapshot() : this.program.loaded ? this.program.snapshot() : {}); const task = statePayload.task ?? this.task.export(); - const panelSnapshot = this.panelSnapshot({ task, program, input, tick }); + // The loaded toolpath is immutable during execution. Avoid cloning all + // WASM pose samples into every 10 ms step response; the frontend retains + // the canonical path from PROGRAM_LOAD/PROGRAM_RESTART. + const lightweightXyzacStep = input.kind === "SIM_STEP" && Boolean(this.xyzacProgram); + const panelSnapshot = this.panelSnapshot({ task, program, input, tick, motionTrace: statePayload.motion_trace, includeToolpath: !lightweightXyzacStep, includeConfiguration: !lightweightXyzacStep, includeStableRuntime: !lightweightXyzacStep }); return { schema_version: PROTOCOL_SCHEMA, kind, @@ -130,39 +148,114 @@ export class SimSession { panel_snapshot: panelSnapshot, motion_authority: statePayload.motion_authority ?? this.motionAuthority, task_authority: statePayload.task_authority ?? this.task.authority(), - wasm_home_limit: statePayload.wasm_home_limit ?? this.wasmHomeLimit.read(), + ...(!lightweightXyzacStep ? { wasm_home_limit: statePayload.wasm_home_limit ?? this.wasmHomeLimit.read() } : {}), axis_state: axisState({ task, program, action: input.kind, payload: input.payload ?? {} }), }, }; } - panelSnapshot({ task = this.task.export(), program = this.program.loaded ? this.program.snapshot() : null, input = {}, tick = this.tick } = {}) { - const motion = this.motion.export(); + wasmMotionProjection() { + const wasmMotion = this.wasmMotion.read(); + const position = wasmMotion.status === "verified" ? wasmMotion.state.position : { x: 0, y: 0, z: 0, a: 0, b: 0, c: 0, u: 0, v: 0, w: 0 }; + const home = this.wasmHomeLimit.read(); + const io = this.xyzacIo?.canonical?.(); + const ioState = io && typeof io === "object" && io.status !== "blocked" ? io : null; + const kinematics = this.xyzacKinematics?.snapshot?.(); + const kinematicsJoints = kinematics?.joints?.length === 5 ? [...kinematics.joints] : null; + const unsigned = { + schema: "sim_motion.v1", + source: "wasm_motion_queue", + tick: wasmMotion.status === "verified" ? wasmMotion.state.tick : this.tick, + axes: { x: position.x, y: position.y, z: position.z }, + joints: kinematicsJoints ?? (home.status === "verified" && Array.isArray(home.state.joints) ? [...home.state.joints] : [position.x, position.y, position.z, position.a ?? 0, position.c ?? 0]), + velocity: wasmMotion.status === "verified" ? wasmMotion.state.velocity : 0, + feed_override: 1, + spindle_override: 1, + homed: Boolean(home.state?.homed), + homed_axes: Array.from({ length: 5 }, (_, index) => Boolean(home.state?.homed && index < (home.state?.joint_count ?? 0))), + limits: { x: Boolean(home.state?.limit_error), y: Boolean(home.state?.limit_error), z: Boolean(home.state?.limit_error), a: Boolean(home.state?.limit_error), c: Boolean(home.state?.limit_error) }, + on_any_limit: Boolean(home.state?.limit_error), + following_error: 0, + jog: null, + estop: Boolean(ioState?.estop), + fault: ioState?.fault ? (ioState.fault_reason ?? "io_fault") : null, + }; + return { ...unsigned, state_hash: fnv1a64(unsigned) }; + } + + motionProjection() { + if (this.xyzacProgram) return this.wasmMotionProjection(); + if (this.motionAuthority !== "wasm") return this.motion.export(); + const wasm = this.wasmMotion.read(); + return wasm.status === "verified" ? { ...this.motion.export(), axes: { ...wasm.state.position } } : this.motion.export(); + } + + wasmDeviceProjection({ includeBytes = false } = {}) { + if (!this.xyzacIo) return this.devices.export(); + const state = this.xyzacIo.canonical(); + if (!state || state.status === "blocked") return { schema: "wasm_xyzac_devices.v1", source: "wasm_io", status: "blocked" }; + const ioExport = includeBytes ? this.xyzacIo.export() : null; + const unsigned = { schema: "wasm_xyzac_devices.v1", source: "wasm_io", ...state, ...(includeBytes ? { state_bytes: ioExport.state_bytes } : {}) }; + return { ...unsigned, state_hash: fnv1a64(unsigned) }; + } + + loadXyzacSubroutines(programPath) { + if (!this.xyzacProgram) return { status: "verified", count: 0 }; + const requirement = this.xyzacProgram.requiresSubroutines(); + if (requirement.status !== "verified") return requirement; + if (!requirement.required) return { status: "verified", count: 0 }; + const basePath = String(programPath ?? "").split("/").slice(0, -1).join("/"); + const rows = [["remap_subs/xyzac_switchkins_sub.ngc", "xyzac_switchkins_sub"], ["remap_subs/helix_ac.ngc", "helix_ac"]]; + for (const [suffix, name] of rows) { + const path = `${basePath.replace(/\/demos$/, "")}/${suffix}`; + const source = this.workspaceFiles[path]; + if (typeof source !== "string") return { status: "error", code: "program_subroutine_missing", path }; + const added = this.xyzacProgram.addSubroutine(name, source); + if (added.status !== "verified") return added; + } + return { status: "verified", count: rows.length }; + } + + panelSnapshot({ task = this.task.export(), program = this.xyzacProgram ? this.xyzacProgram.snapshot() : this.program.loaded ? this.program.snapshot() : null, input = {}, tick = this.tick, motionTrace = null, includeToolpath = input.kind !== "SIM_STEP" || !this.xyzacProgram, includeConfiguration = input.kind !== "SIM_STEP" || !this.xyzacProgram, includeStableRuntime = input.kind !== "SIM_STEP" || !this.xyzacProgram } = {}) { + const motion = this.xyzacProgram ? this.wasmMotionProjection() : this.motion.export(); const wasmMotion = this.wasmMotion.read(); const homeLimit = this.wasmHomeLimit.read(); - const devices = this.devices.export(); - const deviceIo = this.deviceIo.export(); - const halRuntime = this.hal.export(); - const authoritative = this.authoritative.export(); + const devices = this.wasmDeviceProjection(); + const deviceIo = this.xyzacDeviceIo ? this.xyzacDeviceIo.export() : this.xyzacIo ? this.xyzacIo.export() : this.deviceIo.export(); + const halRuntime = this.xyzacIo ? this.xyzacIo.halExport() : this.hal.export(); + const authoritative = this.xyzacProgram + ? { schema: "wasm_authority_boundary.v1", source: "linuxcnc-wasm-worker", state_hash: fnv1a64({ motion: wasmMotion, kinematics: this.xyzacKinematics?.snapshot() ?? null, task }) } + : this.authoritative.export(); const axis = axisState({ task, program: program ?? {}, action: input.kind, payload: input.payload ?? {} }); - const gateInput = { task, program: program ?? {}, motion, devices, taskfile: Boolean(this.program.loaded), kinematicsIdentity: this.motionAuthority === "wasm" }; - const gateActions = ["load", "run", "step", "pause", "resume", "abort", "restart", "mdi", "jogStart", "jogStop", "home", "estop", "recover", "override", "reset", "spindle", "coolant"]; - const gates = Object.fromEntries(gateActions.map((action) => [action, axisGate(action, gateInput)])); - const position = this.motionAuthority === "wasm" && wasmMotion.status === "verified" + const xyzac = this.xyzacKinematics ? { coordinates: "XYZAC", joint_count: 5, hal_pin_vars: true, switchkins_net: true, finite_offsets: true, userk_capability: true, active_type: this.xyzacKinematics.snapshot().active_type } : null; + const gateInput = { task, program: program ?? {}, motion, devices, xyzac, taskfile: Boolean(this.xyzacProgram ? this.xyzacProgram.snapshot().status !== 0 : this.program.loaded), kinematicsIdentity: this.motionAuthority === "wasm" }; + const gateActions = ["load", "run", "runLine", "step", "pause", "resume", "abort", "restart", "reload", "edit", "mdi", "jogStart", "jogStop", "home", "estop", "recover", "override", "overrideLimits", "reset", "spindle", "coolant", "touchOff", "toolTouchOff"]; + const gates = { ...Object.fromEntries(gateActions.map((action) => [action, axisGate(action, gateInput)])), ...xyzacGateMatrix(gateInput) }; + const wasmPosition = this.motionAuthority === "wasm" && wasmMotion.status === "verified" ? wasmMotion.state.position : authoritative.kinematics.pose; + // Generic WASM-compatible cases expose their historical XYZ panel shape; + // the selected XYZAC case is the only panel that publishes all nine pose + // coordinates and the five inverse joints. + const position = this.xyzacProgram + ? wasmPosition + : { x: wasmPosition.x, y: wasmPosition.y, z: wasmPosition.z }; + const inverseJoints = this.xyzacKinematics?.snapshot?.()?.joints; const joints = this.motionAuthority === "wasm" && wasmMotion.status === "verified" - ? [position.x, position.y, position.z] + ? (inverseJoints?.length === 5 ? [...inverseJoints] : [position.x, position.y, position.z, position.a ?? 0, position.c ?? 0]) : authoritative.kinematics.joints; const preview = this.previewState?.status === "verified" ? this.previewState : null; const visual = { schema: "axis-visual.v1", - pose: { x: position.x, y: position.y, z: position.z }, + pose: { ...position }, joints: Array.isArray(joints) ? [...joints] : [], - toolpath: (preview?.segments ?? []).map((segment, index) => ({ id: index + 1, ...segment })), + ...(includeToolpath ? { toolpath: (preview?.segments ?? []).map((segment, index) => ({ id: index + 1, ...segment })) } : {}), active_segment_id: wasmMotion.status === "verified" ? wasmMotion.state.active_id : authoritative.planner.active_id, + active_progress: wasmMotion.status === "verified" ? wasmMotion.state.progress : 0, + ...(Array.isArray(motionTrace) && motionTrace.length ? { motion_trace: motionTrace } : {}), source: "wasm_canonical_motion", }; + const axisCoordinates = [position.x, position.y, position.z, position.a ?? 0, position.c ?? 0]; const unsigned = { schema: "axis-panel-snapshot.v1", context_id: this.contextId, @@ -171,20 +264,20 @@ export class SimSession { task, program, motion, - coordinates: { machine: [position.x, position.y, position.z], relative: [position.x, position.y, position.z], commanded: [position.x, position.y, position.z] }, + coordinates: { machine: [...axisCoordinates], relative: [...axisCoordinates], commanded: [...axisCoordinates] }, overrides: { feed: motion.feed_override, spindle: [motion.spindle_override] }, wasm_motion: wasmMotion, - home_limit: homeLimit, - hal: { configuration: this.halState, runtime: halRuntime }, - devices, - device_io: deviceIo, - configuration: this.configurationState, + ...(includeStableRuntime ? { home_limit: homeLimit, hal: { configuration: this.halState, runtime: halRuntime }, devices, device_io: deviceIo } : {}), + ...(includeConfiguration ? { configuration: this.configurationState } : {}), axis_state: axis, gates, visual, authoritative, motion_authority: this.motionAuthority, task_authority: this.task.authority(), + ...(this.xyzacKinematics ? { kinematics: this.xyzacKinematics.snapshot() } : {}), + ...(includeStableRuntime && this.xyzacIo ? { io: this.xyzacIo.export() } : {}), + ...(xyzac ? { xyzac } : {}), }; return { ...unsigned, state_hash: fnv1a64(unsigned) }; } @@ -211,18 +304,24 @@ export class SimSession { } commandGate(input) { + const task = this.task.export(); + const program = this.xyzacProgram ? this.xyzacProgram.snapshot() : this.program.loaded ? this.program.snapshot() : {}; + const motion = this.xyzacProgram ? this.wasmMotionProjection() : this.motion.export(); + const devices = this.wasmDeviceProjection(); + if (input.kind === "KINEMATICS_SELECT" || input.kind === "VISUAL_CLEAR") { + const type = Number(input.payload?.type); + const action = input.kind === "VISUAL_CLEAR" ? "vismachClear" : type === 0 ? "switchkinsIdentity" : type === 1 ? "switchkinsXyzac" : type === 2 ? "switchkinsUserk" : null; + if (!action) return { action: null, enabled: false, reason: "xyzac_kinematics_type_invalid" }; + return xyzacGate(action, { task, program, motion, devices, xyzac: this.xyzacKinematics ? { coordinates: "XYZAC", joint_count: 5, hal_pin_vars: true, switchkins_net: true, finite_offsets: true, userk_capability: true } : null }); + } const action = PANEL_GATE_ACTIONS[input.kind]; if (!action) return { action: null, enabled: true, reason: "axis_internal_command" }; - const task = this.task.export(); - const program = this.program.loaded ? this.program.snapshot() : {}; - const motion = this.motion.export(); - const devices = this.devices.export(); return axisGate(action, { task, program, motion, devices, - taskfile: Boolean(this.program.loaded), + taskfile: Boolean(this.xyzacProgram ? this.xyzacProgram.snapshot().loaded : this.program.loaded), kinematicsIdentity: this.motionAuthority === "wasm", }); } @@ -234,11 +333,11 @@ export class SimSession { tick: this.tick, created: this.created, protocol_seq: this.timeline.events.cursor, - devices: this.devices.export(), - motion: this.motion.export(), + devices: this.wasmDeviceProjection({ includeBytes: true }), + motion: this.xyzacProgram ? this.wasmMotionProjection() : this.motion.export(), plc: this.plc.export(), - hal_runtime: this.hal.export(), - device_io: this.deviceIo.export(), + hal_runtime: this.xyzacIo ? this.xyzacIo.halExport() : this.hal.export(), + device_io: this.xyzacDeviceIo ? this.xyzacDeviceIo.export() : this.xyzacIo ? this.xyzacIo.export() : this.deviceIo.export(), configuration_batch: this.configurationBatch.export(), io_ack: this.ioAck.export(), callbacks: this.callbacks.export(), @@ -249,13 +348,15 @@ export class SimSession { wasm_motion: this.wasmMotion.exportState(), task_authority: this.task.authority(), wasm_home_limit: this.wasmHomeLimit.exportState(), + ...(this.xyzacKinematics ? { kinematics: this.xyzacKinematics.snapshot() } : {}), preview: this.previewState, task: this.task.export(), scheduler: this.scheduler.export(), - authoritative: this.authoritative.export(), + authoritative: this.xyzacProgram ? { schema: "wasm_authority_boundary.v1", source: "linuxcnc-wasm-worker" } : this.authoritative.export(), ledger: this.ledger.export(), }; - if (this.program.loaded) state.program = this.program.exportState(); + if (this.xyzacProgram) state.program = { ...this.xyzacProgram.snapshot(), source_text: this.xyzacProgram.source }; + else if (this.program.loaded) state.program = this.program.exportState(); return state; } @@ -265,11 +366,11 @@ export class SimSession { session_id: this.sessionId, configuration: this.configurationState, hal: this.halState, - devices: this.devices.export(), - motion: this.motion.export(), + devices: this.wasmDeviceProjection(), + motion: this.xyzacProgram ? this.wasmMotionProjection() : this.motion.export(), plc: this.plc.export(), - hal_runtime: this.hal.export(), - device_io: this.deviceIo.export(), + hal_runtime: this.xyzacIo ? this.xyzacIo.halExport() : this.hal.export(), + device_io: this.xyzacDeviceIo ? this.xyzacDeviceIo.export() : this.xyzacIo ? this.xyzacIo.export() : this.deviceIo.export(), configuration_batch: this.configurationBatch.export(), io_ack: this.ioAck.export(), callbacks: this.callbacks.export(), @@ -278,13 +379,15 @@ export class SimSession { event_cursor: this.timeline.events.cursor, task: this.task.export(), scheduler: this.scheduler.export(), - authoritative: this.authoritative.export(), + authoritative: this.xyzacProgram ? { schema: "wasm_authority_boundary.v1", source: "linuxcnc-wasm-worker" } : this.authoritative.export(), motion_authority: this.motionAuthority, wasm_motion: this.wasmMotion.exportState(), task_authority: this.task.authority(), wasm_home_limit: this.wasmHomeLimit.exportState(), + ...(this.xyzacKinematics ? { kinematics: this.xyzacKinematics.snapshot() } : {}), }; - if (this.program.loaded) value.program = this.program.exportState(); + if (this.xyzacProgram) value.program = { ...this.xyzacProgram.snapshot(), source_text: this.xyzacProgram.source }; + else if (this.program.loaded) value.program = this.program.exportState(); return { ...value, state_hash: fnv1a64(value) }; } @@ -325,6 +428,9 @@ export class SimSession { if (trace.state?.motion_authority) this.motionAuthority = trace.state.motion_authority; if (trace.state?.wasm_motion) this.wasmMotion.restoreState(trace.state.wasm_motion); if (trace.state?.wasm_home_limit) this.wasmHomeLimit.restoreState(trace.state.wasm_home_limit); + if (trace.state?.device_io?.schema === "wasm_xyzac_device_io.v1" && this.xyzacDeviceIo) this.xyzacDeviceIo.restoreState(trace.state.device_io); + if (trace.state?.io?.schema === "wasm_xyzac_io.v1" && this.xyzacIo) this.xyzacIo.restoreState(trace.state.io); + if (trace.state?.kinematics && this.xyzacKinematics) this.xyzacKinematics.restoreState(trace.state.kinematics); if (trace.state?.motion) this.motion.restore(trace.state.motion); if (trace.state?.program) { this.program = new ProgramRunner(this.core); @@ -346,10 +452,62 @@ export class SimSession { } restoreCheckpoint(checkpoint, events = null, reconcile = undefined) { + try { + validateCheckpoint(checkpoint, { contextId: this.contextId }); + } catch (error) { + return { schema: "simulation-recovery.v1", status: "blocked", context_id: this.contextId, checkpoint_hash: checkpoint?.checkpoint_hash ?? null, blocked: [{ reason: String(error?.message ?? error) }] }; + } const replayMotionAuthority = checkpoint?.state?.motion_authority ?? this.motionAuthority; if (replayMotionAuthority === "wasm" && !checkpoint?.state?.wasm_motion) { return { schema: "simulation-recovery.v1", status: "blocked", context_id: this.contextId, checkpoint_hash: checkpoint?.checkpoint_hash ?? null, blocked: [{ reason: "wasm_motion_checkpoint_missing" }] }; } + if (this.xyzacProgram && checkpoint?.state?.program?.source_text) { + try { + const loaded = this.xyzacProgram.load(checkpoint.state.program.source_text, checkpoint.state.program.path ?? null); + if (loaded.status !== "verified") throw new Error(loaded.code); + const subroutines = this.loadXyzacSubroutines(checkpoint.state.program.path ?? null); + if (subroutines.status !== "verified") throw new Error(subroutines.code); + const targetLine = Number.isSafeInteger(checkpoint.state.program.current_line) ? checkpoint.state.program.current_line : 0; + const seek = this.xyzacProgram.seek(targetLine); + if (seek.status !== "verified") throw new Error(seek.code); + if (checkpoint.state.program) this.xyzacProgram.restoreState(checkpoint.state.program); + if (checkpoint.state.wasm_motion) this.wasmMotion.restoreState(checkpoint.state.wasm_motion); + if (checkpoint.state.wasm_home_limit) this.wasmHomeLimit.restoreState(checkpoint.state.wasm_home_limit); + let restoredWasmDeviceIo = false; + if (checkpoint.state.device_io?.schema === "wasm_xyzac_device_io.v1" && this.xyzacDeviceIo) { this.xyzacDeviceIo.restoreState(checkpoint.state.device_io); restoredWasmDeviceIo = true; } + if (checkpoint.state.io?.schema === "wasm_xyzac_io.v1" && this.xyzacIo) this.xyzacIo.restoreState(checkpoint.state.io); + if (checkpoint.state.devices?.schema === "wasm_xyzac_devices.v1" && this.xyzacIo) this.xyzacIo.restoreState(checkpoint.state.devices); + if (checkpoint.state.kinematics && this.xyzacKinematics) this.xyzacKinematics.restoreState(checkpoint.state.kinematics); + if (checkpoint.state.task) this.task.restore(checkpoint.state.task); + if (checkpoint.state.scheduler) this.scheduler.restore(checkpoint.state.scheduler); + if (checkpoint.state.devices?.schema !== "wasm_xyzac_devices.v1") this.devices = new VirtualDevices({ state: checkpoint.state.devices }); + this.plc = new PlcRuntime(); if (checkpoint.state.plc) this.plc.restore(checkpoint.state.plc); + this.hal = new HalRuntime(); if (checkpoint.state.hal_runtime?.schema === "sim_hal_runtime.v1") this.hal.restore(checkpoint.state.hal_runtime); + this.configurationBatch = new ConfigurationBatchRuntime({ context_id: this.contextId }); if (checkpoint.state.configuration_batch) this.configurationBatch.restore(checkpoint.state.configuration_batch); + this.ioAck = new IoAckTracker(); if (checkpoint.state.io_ack) this.ioAck.restore(checkpoint.state.io_ack); + this.callbacks = new PythonCallbacks(); if (checkpoint.state.callbacks) this.callbacks.restore(checkpoint.state.callbacks); + this.configurationState = checkpoint.state.configuration ?? this.configurationState; + this.halState = checkpoint.state.hal ?? this.halState; + this.previewState = checkpoint.state.preview ?? this.previewState; + this.python = new PythonBridge(); if (checkpoint.state.python) this.python.restoreState(checkpoint.state.python); + this.timeline = new ReplayTimeline(checkpoint.timeline); + if (checkpoint.state.hal_runtime?.schema === "wasm_xyzac_hal.v1" && this.xyzacIo) this.xyzacIo.halCommand({ action: "step", ticks: checkpoint.state.hal_runtime.tick ?? 0 }); + if (!restoredWasmDeviceIo && checkpoint.state.device_io?.schema === "wasm_xyzac_device_io.v1" && this.xyzacDeviceIo) this.xyzacDeviceIo.command("IO_STEP", { ticks: checkpoint.state.device_io.state?.tick ?? 0 }); + const currentOperations = [...this.operations.values()]; + this.operations = new Map([...checkpoint.operations ?? [], ...currentOperations].map((operation) => [operation.operation_id, operation])); + const checkpointEntries = checkpoint.operations ?? []; + const currentEntries = this.ledger.export().entries.filter((entry) => !checkpointEntries.some((operation) => operation.operation_id === entry.operation_id)); + this.ledger = new this.ledger.constructor(); + for (const operation of [...checkpointEntries, ...currentEntries]) { + const entry = { ...operation, phase: operation.phase ?? (operation.status === "verified" ? "committed" : operation.status), side_effect_count: operation.side_effect_count ?? (operation.status === "verified" ? 1 : 0) }; + try { this.ledger.importEntry(entry); } catch { /* checkpoint operations remain available for diagnostics */ } + } + this.tick = checkpoint.state.tick ?? this.tick; + return { schema: "simulation-recovery.v1", status: "recovered", context_id: this.contextId, checkpoint_hash: checkpoint.checkpoint_hash ?? null, simulation_tick: this.tick, state: this.stateForCheckpoint(), operations: checkpoint.operations ?? [] }; + } catch (error) { + return { schema: "simulation-recovery.v1", status: "blocked", context_id: this.contextId, checkpoint_hash: checkpoint?.checkpoint_hash ?? null, blocked: [{ code: "wasm_program_recovery", reason: String(error?.message ?? error) }] }; + } + } const replayDevices = new VirtualDevices({ state: checkpoint?.state?.devices }); const replayMotion = new MotionState(); if (checkpoint?.state?.motion) replayMotion.restore(checkpoint.state.motion); @@ -546,6 +704,7 @@ export class SimSession { this.motionAuthority = result.state?.motion_authority ?? checkpoint?.state?.motion_authority ?? this.motionAuthority; if (this.motionAuthority === "wasm" && result.state?.wasm_motion) this.wasmMotion.restoreState(result.state.wasm_motion); if (this.motionAuthority === "wasm" && result.state?.wasm_home_limit) this.wasmHomeLimit.restoreState(result.state.wasm_home_limit); + if (result.state?.kinematics && this.xyzacKinematics) this.xyzacKinematics.restoreState(result.state.kinematics); if (result.state?.task) this.task.restore(result.state.task); if (result.state?.scheduler) this.scheduler.restore(result.state.scheduler); this.authoritative = new AuthoritativeRuntime(); @@ -556,7 +715,9 @@ export class SimSession { if (this.motionAuthority !== "wasm") this.authoritative.applyMotion(this.motion); if (this.motionAuthority === "wasm") { const wasmMotion = this.wasmMotion.read(); - if (wasmMotion.status !== "verified" || !result.state?.motion || fnv1a64(result.state.motion.axes) !== fnv1a64(wasmMotion.state.position)) throw new Error("wasm_motion_recovery_projection_mismatch"); + const motionAxes = result.state?.motion?.axes; + const projectionMatches = motionAxes && Object.entries(motionAxes).every(([axis, value]) => Number.isFinite(value) && Math.abs((wasmMotion.state.position[axis] ?? Number.NaN) - value) <= 1e-12); + if (wasmMotion.status !== "verified" || !projectionMatches) throw new Error("wasm_motion_recovery_projection_mismatch"); } this.plc = new PlcRuntime(); if (result.state?.plc) this.plc.restore(result.state.plc); @@ -661,8 +822,9 @@ export class SimSession { } const gate = this.commandGate(input); const handlerOwnsFault = (input.kind === "JOG_START" || input.kind === "JOG_STOP") && Boolean(this.motion.state.fault); - const restartAfterCompletion = input.kind === "PROGRAM_RESTART" && this.program.status === "completed"; - if (!gate.enabled && !handlerOwnsFault && !restartAfterCompletion) { + const restartAfterCompletion = input.kind === "PROGRAM_RESTART" && (this.xyzacProgram ? this.xyzacProgram.snapshot().status === 4 : this.program.status === "completed"); + const abortAfterCompletion = input.kind === "PROGRAM_ABORT" && (this.xyzacProgram ? this.xyzacProgram.snapshot().status === 4 : this.program.status === "completed"); + if (!gate.enabled && !handlerOwnsFault && !restartAfterCompletion && !abortAfterCompletion) { if (text(input.operation_id)) this.operations.delete(input.operation_id); const rejectedPayload = { command: input.kind, gate_reason: gate.reason, payload: input.payload ?? {} }; try { @@ -713,7 +875,16 @@ export class SimSession { }; const deviceResponse = (kind, payload) => { - const result = this.devices.command(kind, payload ?? {}); + const result = this.xyzacIo ? this.xyzacIo.command(kind, payload ?? {}) : this.devices.command(kind, payload ?? {}); + if (result.status === "verified" && this.xyzacProgram && kind === "ESTOP" && payload?.active === true) { + // The WASM IO edge owns emergency stop. Stop the WASM trajectory and + // pause the canonical program so no compatibility state can continue + // feeding motion while the machine is stopped. + const programState = this.xyzacProgram.snapshot(); + if (programState.status === 2) this.xyzacProgram.pause(); + this.wasmMotion.abort(); + this.wasmMotion.setPaused(true); + } try { if (kind === "ESTOP" && payload?.active === true) this.task.estop(-904); else if (kind === "IO_RECOVER" && result.status === "verified") this.task.recover(); @@ -721,15 +892,17 @@ export class SimSession { } catch (error) { return finish(this.error(input, "task_state", String(error?.message ?? error)), "failed"); } - if (kind === "ESTOP") this.deviceIo.estop(payload?.active === true); - if (kind === "IO_RECOVER" && result.status === "verified") this.deviceIo.interlockReset(); + if (!this.xyzacIo && kind === "ESTOP") this.deviceIo.estop(payload?.active === true); + if (!this.xyzacIo && kind === "IO_RECOVER" && result.status === "verified") this.deviceIo.interlockReset(); + if (this.xyzacDeviceIo && kind === "ESTOP") this.xyzacDeviceIo.command("DEVICE_ESTOP", payload, input.operation_id); + if (this.xyzacDeviceIo && kind === "IO_RECOVER" && result.status === "verified") this.xyzacDeviceIo.command("INTERLOCK_RESET", payload, input.operation_id); const responseKind = result.status === "verified" ? "COMMAND_RESULT" : "ERROR"; return finish(this.envelope(responseKind, input, { ...result, command: kind, task: this.task.export(), - device_io: this.deviceIo.export(), - motion: this.motion.export(), + device_io: this.xyzacIo ? this.xyzacIo.export() : this.deviceIo.export(), + motion: this.xyzacProgram ? this.wasmMotionProjection() : this.motion.export(), operation_id: input.operation_id ?? null, simulation_tick: this.tick, }), result.status === "verified" ? "verified" : "failed"); @@ -737,7 +910,8 @@ export class SimSession { const deviceIoResponse = (kind, payload = {}) => { let result; - if (kind === "ENCODER_SET") result = this.deviceIo.encoderSet(payload.channel, payload); + if (this.xyzacDeviceIo) result = this.xyzacDeviceIo.command(kind, payload, input.operation_id); + else if (kind === "ENCODER_SET") result = this.deviceIo.encoderSet(payload.channel, payload); else if (kind === "COOLANT_COMMAND") result = this.deviceIo.coolantCommand(payload); else if (kind === "COOLANT_FAULT") result = this.deviceIo.coolantFault(payload.fault === true); else if (kind === "DOOR_SET") result = this.deviceIo.doorSet(payload.open === true); @@ -749,7 +923,14 @@ export class SimSession { else if (kind === "DEVICE_ACK") result = this.deviceIo.ack(payload.operation_id); else result = this.deviceIo.fail("device_io_command_unsupported"); const responseKind = result.status === "verified" ? "COMMAND_RESULT" : "ERROR"; - return finish(this.envelope(responseKind, input, { ...result, command: kind, device_io: this.deviceIo.export(), task: this.task.export(), operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed"); + return finish(this.envelope(responseKind, input, { ...result, command: kind, device_io: this.xyzacIo ? this.xyzacIo.export() : this.deviceIo.export(), task: this.task.export(), operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed"); + }; + + const visualClearResponse = () => { + const before = { task: this.task.hash(), motion: this.wasmMotion.exportState().state_hash, program: this.xyzacProgram?.snapshot().state_hash ?? null }; + this.previewState = null; + const after = { task: this.task.hash(), motion: this.wasmMotion.exportState().state_hash, program: this.xyzacProgram?.snapshot().state_hash ?? null }; + return finish(this.envelope("COMMAND_RESULT", input, { status: "verified", command: input.kind, visual_clear: true, visual_only: true, before, after, operation_id: input.operation_id ?? null }), "verified"); }; switch (input.kind) { @@ -769,12 +950,21 @@ export class SimSession { try { this.task.setMode(mode); } catch (error) { return finish(this.error(input, "task_mode", String(error?.message ?? error)), "failed"); } return finish(this.envelope("COMMAND_RESULT", input, { status: "verified", command: input.kind, mode, task: this.task.export(), operation_id: input.operation_id ?? null })); } + case "POWER": { + if (input.payload?.active !== true) return finish(this.error(input, "power_state", "power_active_required"), "failed"); + const result = this.xyzacIo ? this.xyzacIo.command("IO_RECOVER", input.payload ?? {}) : this.devices.command("IO_RECOVER", input.payload ?? {}); + if (result.status === "verified") { + try { this.task.recover(); } catch { /* READY is already powered for the selected simulation. */ } + if (this.xyzacDeviceIo) this.xyzacDeviceIo.command("INTERLOCK_RESET", input.payload ?? {}, input.operation_id); + } + return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, command: input.kind, active: true, task: this.task.export(), device_io: this.xyzacIo ? this.xyzacIo.export() : this.deviceIo.export(), operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed"); + } case "RESET": { if (["RUNNING", "PAUSED"].includes(this.task.state.state)) return finish(this.error(input, "task_state", "reset_while_program_active"), "failed"); const result = this.motion.resetFault(); if (result.status !== "verified") return finish(this.envelope("ERROR", input, { ...result, command: input.kind, task: this.task.export() }), "failed"); if (this.task.state.state === "FAULT" || this.task.state.state === "STOPPED") this.task.recover(); - return finish(this.envelope("COMMAND_RESULT", input, { ...result, command: input.kind, task: this.task.export(), motion: this.motion.export(), operation_id: input.operation_id ?? null })); + return finish(this.envelope("COMMAND_RESULT", input, { ...result, command: input.kind, task: this.task.export(), motion: this.motionProjection(), operation_id: input.operation_id ?? null })); } case "LOAD_WORKSPACE": { const rootPath = input.payload?.root_path; @@ -782,6 +972,7 @@ export class SimSession { let startupLoaded = false; const configuration = input.payload?.configuration ?? null; if (configuration) { + this.workspaceFiles = { ...(configuration.files ?? configuration.workspace ?? configuration.workspace_files ?? {}) }; const startupWorkspace = configuration.workspace ?? configuration.files ?? configuration.workspace_files; if (startupWorkspace) { const startup = new ConfigurationStartupStateMachine({ @@ -826,10 +1017,29 @@ export class SimSession { }; } } - this.motionAuthority = configuration?.entrypoint?.includes("3axis-tutorial") ? "wasm" : "js"; + this.motionAuthority = configuration?.entrypoint?.includes("3axis-tutorial") || configuration?.kinematics?.type === "xyzac-trt" ? "wasm" : "js"; + if (configuration?.kinematics?.type === "xyzac-trt") { + this.xyzacKinematics?.destroy(); + this.xyzacKinematics = new WasmXyzacKinematics(this.core, { ...configuration.kinematics.offsets, limits: configuration.home_limits }); + this.xyzacIo?.destroy(); + this.xyzacIo = new WasmXyzacIo(this.core, { spindleCount: 2, toolCapacity: 1001 }); + this.xyzacDeviceIo?.destroy(); + this.xyzacDeviceIo = new WasmXyzacDeviceIo(this.core, { encoderCount: 2 }); + this.xyzacProgram?.destroy(); + this.xyzacProgram = new WasmProgramRuntime(this.core); + this.xyzacProgramKinematicsMode = XYZAC_MODES.identity; + this.xyzacRapidVelocity = Number(configuration.kinematics?.max_linear_velocity ?? 35); + this.xyzacProgram.setRapidVelocity(this.xyzacRapidVelocity); + } if (configuration?.home_limits && this.motionAuthority === "wasm") { this.wasmHomeLimit.destroy(); - this.wasmHomeLimit = new WasmHomeLimit(this.core, { limits: configuration.home_limits }); + this.wasmHomeLimit = new WasmHomeLimit(this.core, { + jointCount: configuration.home_limits.joint_count ?? 3, + kinematicsType: configuration.home_limits.kinematics_type ?? 1, + coordinates: configuration.home_limits.coordinates ?? "XYZ", + offsets: configuration.kinematics?.offsets ?? {}, + limits: configuration.home_limits, + }); } if (input.payload?.hal) { const preflight = preflightHalConfiguration(input.payload.hal); @@ -849,7 +1059,7 @@ export class SimSession { }; } const configuredKinematics = input.payload?.kinematics ?? configuration?.kinematics?.type ?? null; - if (configuredKinematics) { + if (configuredKinematics && !(this.motionAuthority === "wasm" && configuredKinematics === "xyzac-trt")) { const kinematics = this.authoritative.setKinematics(configuredKinematics); if (kinematics.status === "blocked") return finish(this.envelope("ERROR", input, { status: "blocked", code: kinematics.code, kinematics: this.authoritative.export() }), "failed"); } @@ -868,9 +1078,46 @@ export class SimSession { const limit = validateLimit("max_tick_step", cycles); if (limit.status !== "accepted") return finish(this.envelope("ERROR", input, { ...limit, operation_id: input.operation_id ?? null, simulation_tick: this.tick, retryable: false }), "failed"); let program_steps = []; + const motion_trace = []; try { this.scheduler.step(cycles, { task: () => { + if (this.xyzacProgram) { + const wasmState = this.xyzacProgram.snapshot(); + if (![2, 3].includes(wasmState.status)) return; + if (this.pendingProgramControl !== 0) { + if (this.wasmMotion.read().state.queue_depth !== 0) return; + const current = this.wasmMotion.read().state.position; + this.xyzacProgramKinematicsMode = { 428: XYZAC_MODES.xyzac, 429: XYZAC_MODES.identity, 430: XYZAC_MODES.userk }[this.pendingProgramControl]; + const selected = this.xyzacKinematics.select(this.xyzacProgramKinematicsMode, [current.x, current.y, current.z, current.a ?? 0, current.c ?? 0]); + if (selected.status !== "verified") throw new Error(`wasm_switchkins_control_${this.pendingProgramControl}`); + this.pendingProgramControl = 0; + return; + } + const step = this.xyzacProgram.step(); + if (step.status !== "verified") throw new Error(step.code); + if (step.has_control && [428, 429, 430].includes(step.control_code)) { + this.pendingProgramControl = step.control_code; + if (this.wasmMotion.read().state.queue_depth === 0) { + const current = this.wasmMotion.read().state.position; + this.xyzacProgramKinematicsMode = { 428: XYZAC_MODES.xyzac, 429: XYZAC_MODES.identity, 430: XYZAC_MODES.userk }[step.control_code]; + const selected = this.xyzacKinematics.select(this.xyzacProgramKinematicsMode, [current.x, current.y, current.z, current.a ?? 0, current.c ?? 0]); + if (selected.status !== "verified") throw new Error(`wasm_switchkins_control_${step.control_code}`); + this.pendingProgramControl = 0; + } + } + const steps = step.motion ? [step] : []; + program_steps.push(step); + for (const item of steps) { + item.motion.kinematics_mode = this.xyzacProgramKinematicsMode; + const linearNoop = item.motion.motion_type === 1 && ["x", "y", "z", "a", "b", "c", "u", "v", "w"].every((axis) => item.motion.start[axis] === item.motion.end[axis]); + if (!linearNoop) { + const enqueue = this.wasmMotion.enqueue(item.motion); + if (enqueue.status === "error") throw new Error(enqueue.code); + } + } + return; + } const steps = this.program.tick(1); program_steps.push(...steps); for (const step of steps) { @@ -900,24 +1147,49 @@ export class SimSession { if (stepResult !== 0) throw new Error(`core_sim_step_${stepResult}`); this.tick = nextTick; this.task.setTick(nextTick); - const motionState = this.motion.step(nextTick); + const xyzacAuthority = Boolean(this.xyzacProgram); + const motionState = xyzacAuthority ? null : this.motion.step(nextTick); const wasmMotion = this.wasmMotion.step(); if (wasmMotion.status === "error" && wasmMotion.code !== "wasm_motion_step_-605") throw new Error(wasmMotion.code); - if (motionState.fault && this.task.state.state === "RUNNING") this.task.fault(-1205); + if (motionState?.fault && this.task.state.state === "RUNNING") this.task.fault(-1205); if (this.motionAuthority === "wasm") { if (wasmMotion.status === "verified") { - const position = this.motion.applyWasmPosition(wasmMotion.state.position, wasmMotion.state.velocity, nextTick); - if (position.status === "error") throw new Error(position.code); + if (!xyzacAuthority) { + const position = this.motion.applyWasmPosition(wasmMotion.state.position, wasmMotion.state.velocity, nextTick); + if (position.status === "error") throw new Error(position.code); + } else if (this.xyzacKinematics && wasmMotion.state.active_id !== 0 && this.xyzacProgramKinematicsMode !== XYZAC_MODES.identity) { + const inverse = this.xyzacKinematics.inverse(wasmMotion.state.position); + if (inverse.status !== "verified") throw new Error(`wasm_xyzac_motion_inverse_${inverse.code ?? "error"}`); + } + } + if (xyzacAuthority) { + // An empty queue is a valid fixed-tick sample during an + // M428/M429 synchronization boundary. Record it as a + // stationary WASM sample so the display does not invent a + // jump across the barrier. + const traceState = wasmMotion.status === "verified" ? wasmMotion.state : this.wasmMotion.read().state; + const traceKinematics = this.xyzacKinematics?.snapshot?.(); + motion_trace.push({ + tick: nextTick, + pose: { ...traceState.position }, + joints: traceKinematics?.joints?.length === 5 ? [...traceKinematics.joints] : [], + active_segment_id: traceState.active_id, + active_progress: traceState.progress, + }); } } else if (this.program.loaded) this.authoritative.applyMotion(this.motion); - if (this.motionAuthority === "wasm" && this.wasmHomeLimit.read().state.homed && !motionState.fault) { - const homeCheck = this.wasmHomeLimit.check(this.motion.state.joints); + if (this.motionAuthority === "wasm" && this.wasmHomeLimit.read().state.homed) { + const homeCheck = this.wasmHomeLimit.check(this.xyzacProgram ? this.wasmMotionProjection().joints : this.motion.state.joints); if (homeCheck.status === "error") throw new Error(homeCheck.code); } - const halState = this.hal.step(nextTick); + const halState = this.xyzacIo ? this.xyzacIo.halCommand({ action: "step", ticks: 1 }) : this.hal.step(nextTick); if (halState.status === "error") throw new Error(halState.code); - const deviceIoState = this.deviceIo.step(nextTick); + const deviceIoState = this.xyzacIo ? this.xyzacIo.command("IO_STEP", { ticks: 1 }) : this.deviceIo.step(nextTick); if (deviceIoState.status === "blocked") throw new Error(deviceIoState.code); + if (this.xyzacDeviceIo) { + const deviceStep = this.xyzacDeviceIo.command("IO_STEP", { ticks: 1 }); + if (deviceStep.status === "blocked") throw new Error(deviceStep.code); + } const plcState = this.plc.scan(nextTick); if (plcState.status === "error") throw new Error(plcState.code); const ackState = this.ioAck.step(nextTick); @@ -932,20 +1204,38 @@ export class SimSession { } catch (error) { return finish(this.error(input, "scheduler", String(error?.message ?? error)), "failed"); } - const program = this.program.loaded ? this.program.snapshot() : null; + const program = this.xyzacProgram ? this.xyzacProgram.snapshot() : this.program.loaded ? this.program.snapshot() : null; if (program) { - const status = program.program_status === "completed" ? "completed" : program.program_status === "running" ? "running" : program.program_status; - this.task.setProgram(status, program.line); + const status = this.xyzacProgram ? (program.status === 4 ? "completed" : program.status === 2 ? "running" : program.status === 3 ? "paused" : "loaded") : (program.program_status === "completed" ? "completed" : program.program_status === "running" ? "running" : program.program_status); + this.task.setProgram(status, this.xyzacProgram ? program.current_line : program.line); if (status === "completed" && this.task.state.state === "RUNNING" && (this.motionAuthority !== "wasm" || this.wasmMotion.read().state.queue_depth === 0)) this.task.transition("STOPPED"); } - const snapshotState = { tick: this.tick, cycles, motion_authority: this.motionAuthority, task: this.task.export(), scheduler: this.scheduler.export(), authoritative: this.authoritative.export(), wasm_motion: this.wasmMotion.read(), motion: this.motion.export(), plc: this.plc.export(), hal_runtime: this.hal.export(), device_io: this.deviceIo.export(), configuration_batch: this.configurationBatch.export(), io_ack: this.ioAck.export(), callbacks: this.callbacks.export() }; + const snapshotState = { tick: this.tick, cycles, motion_authority: this.motionAuthority, task: this.task.export(), scheduler: this.scheduler.export(), authoritative: this.xyzacProgram ? { schema: "wasm_authority_boundary.v1", source: "linuxcnc-wasm-worker" } : this.authoritative.export(), wasm_motion: this.wasmMotion.read(), motion: this.motionProjection(), plc: this.plc.export(), hal_runtime: this.xyzacIo ? this.xyzacIo.halExport() : this.hal.export(), device_io: this.xyzacDeviceIo ? this.xyzacDeviceIo.export() : this.xyzacIo ? this.xyzacIo.export() : this.deviceIo.export(), configuration_batch: this.configurationBatch.export(), io_ack: this.ioAck.export(), callbacks: this.callbacks.export() }; if (program) snapshotState.program = program; const snapshot = this.timeline.checkpoint(input.seq, this.tick, snapshotState, this.timeline.snapshots.latest()?.snapshot_id ?? null); - return finish(this.envelope("COMMAND_RESULT", input, { status: "verified", cycles, program_steps, motion_authority: this.motionAuthority, task: this.task.export(), scheduler: this.scheduler.export(), authoritative: this.authoritative.export(), wasm_motion: this.wasmMotion.read(), motion: this.motion.export(), plc: this.plc.export(), hal_runtime: this.hal.export(), device_io: this.deviceIo.export(), configuration_batch: this.configurationBatch.export(), io_ack: this.ioAck.export(), callbacks: this.callbacks.export(), ...(program ? { program } : {}), state_hash: snapshot.state_hash, snapshot })); + const lightweightXyzac = Boolean(this.xyzacProgram); + return finish(this.envelope("COMMAND_RESULT", input, { + status: "verified", cycles, program_steps, + ...(lightweightXyzac && cycles <= 32 && motion_trace.length ? { motion_trace } : {}), + motion_authority: this.motionAuthority, + task: this.task.export(), scheduler: this.scheduler.export(), authoritative: snapshotState.authoritative, + wasm_motion: this.wasmMotion.read(), motion: snapshotState.motion, + ...(lightweightXyzac ? {} : { plc: this.plc.export(), hal_runtime: snapshotState.hal_runtime, device_io: snapshotState.device_io, configuration_batch: this.configurationBatch.export(), io_ack: this.ioAck.export(), callbacks: this.callbacks.export(), snapshot }), + ...(program ? { program } : {}), state_hash: snapshot.state_hash, + })); } case "PROGRAM_LOAD": { if (["RUNNING", "PAUSED"].includes(this.task.state.state)) return finish(this.error(input, "task_state", "program_load_while_active"), "failed"); const source = input.payload?.source ?? input.payload?.text ?? input.payload?.program_source; + if (this.xyzacProgram) { + const result = this.xyzacProgram.load(source, input.payload?.path ?? null); + if (result.status === "verified") this.xyzacProgram.setRapidVelocity(this.xyzacRapidVelocity); + if (result.status === "verified") { const subroutines = this.loadXyzacSubroutines(input.payload?.path); if (subroutines.status !== "verified") return finish(this.error(input, "program_subroutine", subroutines.code), "failed"); } + const preview = result.status === "verified" ? this.xyzacProgram.preview() : result; + if (result.status === "verified" && preview.status === "verified") { this.previewState = preview; this.task.setProgram("loaded", 0); } + const finalStatus = result.status === "verified" && preview.status === "verified" ? "verified" : "error"; + return finish(this.envelope(finalStatus === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, preview, program: this.xyzacProgram.snapshot(), task: this.task.export(), motion_authority: "wasm", command: input.kind, operation_id: input.operation_id ?? null }), finalStatus); + } const result = this.program.load(source, input.payload?.path ?? null); if (result.status === "verified") { this.authoritative.reset(); @@ -962,12 +1252,17 @@ export class SimSession { task: this.task.export(), motion_authority: this.motionAuthority, wasm_motion: this.wasmMotion.read(), - motion: this.motion.export(), + motion: this.motionProjection(), command: input.kind, operation_id: input.operation_id ?? null, }), result.status === "verified" ? "verified" : "failed"); } case "PROGRAM_RUN": { + if (this.xyzacProgram) { + const result = this.xyzacProgram.start(); + if (result.status === "verified") { this.wasmMotion.setPaused(false); this.task.setMode("AUTO"); if (this.task.state.state === "STOPPED") this.task.recover(); this.task.transition("RUNNING"); this.task.setProgram("running", this.xyzacProgram.snapshot().current_line); } + return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, program: this.xyzacProgram.snapshot(), task: this.task.export(), motion_authority: "wasm", command: input.kind, operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed"); + } const result = this.program.start(); if (result.status === "verified") { this.task.setMode("AUTO"); @@ -981,13 +1276,22 @@ export class SimSession { task: this.task.export(), motion_authority: this.motionAuthority, wasm_motion: this.wasmMotion.read(), - motion: this.motion.export(), + motion: this.motionProjection(), command: input.kind, operation_id: input.operation_id ?? null, }), result.status === "verified" ? "verified" : "failed"); } case "PROGRAM_PAUSE": case "PROGRAM_RESUME": case "PROGRAM_ABORT": { const action = input.kind === "PROGRAM_PAUSE" ? "pause" : input.kind === "PROGRAM_RESUME" ? "resume" : "abort"; + if (this.xyzacProgram) { + const result = this.xyzacProgram[action](); + if (result.status === "verified") { + if (action === "pause") { call(this.core, "sim_protocol_pause"); this.wasmMotion.setPaused(true); this.task.transition("PAUSED"); this.task.setProgram("paused", this.xyzacProgram.snapshot().current_line); } + else if (action === "resume") { call(this.core, "sim_protocol_resume"); this.wasmMotion.setPaused(false); this.task.transition("RUNNING"); this.task.setProgram("running", this.xyzacProgram.snapshot().current_line); } + else { this.wasmMotion.abort(); this.task.transition("STOPPED"); this.task.setProgram("aborted", this.xyzacProgram.snapshot().current_line); } + } + return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, program: this.xyzacProgram.snapshot(), task: this.task.export(), motion_authority: "wasm", command: input.kind, operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed"); + } const result = this.program[action](); if (result.status === "verified") { if (action === "pause") { @@ -1008,12 +1312,19 @@ export class SimSession { task: this.task.export(), motion_authority: this.motionAuthority, wasm_motion: this.wasmMotion.read(), - motion: this.motion.export(), + motion: this.motionProjection(), command: input.kind, operation_id: input.operation_id ?? null, }), result.status === "verified" ? "verified" : "failed"); } case "PROGRAM_RESTART": { + if (this.xyzacProgram) { + const source = this.xyzacProgram.source; + const result = this.xyzacProgram.load(source, this.xyzacProgram.path); + if (result.status === "verified") this.xyzacProgram.setRapidVelocity(this.xyzacRapidVelocity); + if (result.status === "verified") { const subroutines = this.loadXyzacSubroutines(this.xyzacProgram.path); if (subroutines.status !== "verified") return finish(this.error(input, "program_subroutine", subroutines.code), "failed"); const preview = this.xyzacProgram.preview(); if (preview.status === "verified") this.previewState = preview; this.wasmMotion.reset(); this.wasmMotion.setPaused(false); this.task.recover(); this.task.setMode("AUTO"); this.task.setProgram("loaded", 0); } + return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, program: this.xyzacProgram.snapshot(), task: this.task.export(), motion_authority: "wasm", command: input.kind, operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed"); + } const result = this.program.restart(); if (result.status === "verified") { if (["ESTOP", "FAULT"].includes(this.task.state.state)) return finish(this.error(input, "task_state", "program_restart_faulted"), "failed"); @@ -1034,6 +1345,13 @@ export class SimSession { }), result.status === "verified" ? "verified" : "failed"); } case "PROGRAM_STEP": { + if (this.xyzacProgram) { + const current = this.xyzacProgram.snapshot(); + if (current.status === 1) this.xyzacProgram.start(); + const result = this.xyzacProgram.step(); + if (result.status === "verified") { if (result.motion) this.wasmMotion.enqueue(result.motion); this.wasmMotion.setPaused(true); this.task.setProgram(result.program_status === 4 ? "completed" : "paused", result.line); this.task.transition(result.program_status === 4 ? "STOPPED" : "PAUSED"); } + return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, program: this.xyzacProgram.snapshot(), task: this.task.export(), motion_authority: "wasm", command: input.kind, operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed"); + } if (this.task.state.state === "READY") { this.task.setMode("AUTO"); this.task.transition("RUNNING"); @@ -1059,12 +1377,17 @@ export class SimSession { task: this.task.export(), motion_authority: this.motionAuthority, wasm_motion: this.wasmMotion.read(), - motion: this.motion.export(), + motion: this.motionProjection(), command: input.kind, operation_id: input.operation_id ?? null, }), result.status === "verified" ? "verified" : "failed"); } case "PROGRAM_SEEK": { + if (this.xyzacProgram) { + const result = this.xyzacProgram.seek(input.payload?.line); + if (result.status === "verified") { this.task.setProgram("paused", input.payload?.line ?? 0); if (this.task.state.state === "READY") this.task.transition("RUNNING"); if (this.task.state.state === "RUNNING") this.task.transition("PAUSED"); } + return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, program: this.xyzacProgram.snapshot(), task: this.task.export(), motion_authority: "wasm", command: input.kind, operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed"); + } const result = this.program.seek(input.payload?.line); if (result.status === "verified") this.task.setProgram("paused", result.line); return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { @@ -1077,7 +1400,28 @@ export class SimSession { case "MDI_EXECUTE": { if (["RUNNING", "PAUSED"].includes(this.task.state.state)) return finish(this.error(input, "task_state", "mdi_while_program_active"), "failed"); if (this.task.state.state === "STOPPED") this.task.recover(); - const result = this.program.executeBlock(input.payload?.block ?? input.payload?.command); + const block = input.payload?.block ?? input.payload?.command; + if (this.xyzacProgram) { + const result = this.xyzacProgram.executeBlock(block); + if (result.status === "verified") { + const controlCode = Number(result.program?.control_code ?? 0); + if ([428, 429, 430].includes(controlCode) && this.xyzacKinematics) { + const mode = { 428: XYZAC_MODES.xyzac, 429: XYZAC_MODES.identity, 430: XYZAC_MODES.userk }[controlCode]; + const selected = this.xyzacKinematics.select(mode, this.xyzacKinematics.snapshot().joints); + if (selected.status !== "verified") return finish(this.error(input, "kinematics", selected.code ?? "xyzac_switchkins_failed"), "failed"); + result.kinematics = this.xyzacKinematics.snapshot(); + result.remap = { code: `M${controlCode}`, hal_pin: "motion.switchkins-type", hal_pin_vars: true, sync: "M66 E0 L0" }; + } + this.task.setMode("MDI"); + this.task.setProgram("loaded", this.xyzacProgram.snapshot().current_line); + if (result.motion) { + const enqueue = this.wasmMotion.enqueue(result.motion); + if (enqueue.status === "error") return finish(this.error(input, "motion_queue", enqueue.code), "failed"); + } + } + return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, program: this.xyzacProgram.snapshot(), task: this.task.export(), motion_authority: "wasm", command: input.kind, operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed"); + } + const result = this.program.executeBlock(block); if (result.status === "verified") { this.task.setMode("MDI"); this.task.setProgram("loaded", this.program.currentLine); } return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, @@ -1086,15 +1430,64 @@ export class SimSession { operation_id: input.operation_id ?? null, }), result.status === "verified" ? "verified" : "failed"); } + case "KINEMATICS_SELECT": { + if (!this.xyzacKinematics) return finish(this.error(input, "kinematics", "xyzac_kinematics_unavailable"), "failed"); + const mode = Number(input.payload?.type); + if (![XYZAC_MODES.identity, XYZAC_MODES.xyzac, XYZAC_MODES.userk].includes(mode)) return finish(this.error(input, "kinematics", "xyzac_kinematics_type_invalid"), "failed"); + const result = this.xyzacKinematics.select(mode, this.xyzacKinematics.snapshot().joints); + const code = mode === XYZAC_MODES.xyzac ? "M428" : mode === XYZAC_MODES.identity ? "M429" : "M430"; + return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, command: input.kind, remap: { code, hal_pin: "motion.switchkins-type", hal_pin_vars: true, sync: "M66 E0 L0" }, kinematics: this.xyzacKinematics.snapshot(), task: this.task.export(), operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed"); + } + case "VISUAL_CLEAR": + return visualClearResponse(); case "HOME": { + if (this.xyzacProgram) { + if (this.wasmHomeLimit.read().status !== "verified") return finish(this.error(input, "home_limit", "wasm_home_limit_unavailable"), "failed"); + const home = this.wasmHomeLimit.home(input.seq); + if (home.status === "error") return finish(this.error(input, "home_limit", home.code), "failed"); + this.task.setMode("MANUAL"); + return finish(this.envelope("COMMAND_RESULT", input, { status: "verified", command: input.kind, motion: this.wasmMotionProjection(), wasm_home_limit: this.wasmHomeLimit.read(), motion_authority: "wasm", operation_id: input.operation_id ?? null }), "verified"); + } const result = this.motion.home(input.payload?.axis ?? null); if (result.status === "verified" && this.motionAuthority === "wasm") { const home = this.wasmHomeLimit.home(input.seq); if (home.status === "error") return finish(this.error(input, "home_limit", home.code), "failed"); } - return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, motion: this.motion.export(), task: this.task.export(), command: input.kind, operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed"); + return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, motion: this.motionProjection(), task: this.task.export(), command: input.kind, operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed"); } case "JOG_START": case "JOG_STOP": case "SET_OVERRIDE": case "FOLLOWING_ERROR": { + if (this.motionAuthority === "wasm") { + if (input.kind === "JOG_STOP") { + this.wasmMotion.abort(); + this.wasmMotion.setPaused(true); + return finish(this.envelope("COMMAND_RESULT", input, { status: "verified", command: input.kind, motion: this.wasmMotionProjection(), motion_authority: "wasm", operation_id: input.operation_id ?? null }), "verified"); + } + if (input.kind === "SET_OVERRIDE") { + const feed = Number(input.payload?.feed ?? input.payload?.feed_override); + if (!Number.isFinite(feed) || feed < 0 || feed > 2) return finish(this.error(input, "motion_override", "motion_override_range"), "failed"); + return finish(this.envelope("COMMAND_RESULT", input, { status: "verified", command: input.kind, feed_override: feed, state: { ...this.motion.export(), feed_override: feed }, motion: this.motionProjection(), motion_authority: "wasm", operation_id: input.operation_id ?? null }), "verified"); + } + if (input.kind === "FOLLOWING_ERROR") return finish(this.error(input, "motion_following_error", "wasm_following_error_unavailable"), "failed"); + const current = this.wasmMotion.read(); + if (current.status !== "verified") return finish(this.error(input, "motion_queue", "wasm_motion_unavailable"), "failed"); + const axis = String(input.payload?.axis ?? "").toLowerCase(); + if (!["x", "y", "z", "a", "c"].includes(axis)) return finish(this.error(input, "motion_axis", "motion_axis_invalid"), "failed"); + const direction = input.payload?.direction === -1 ? -1 : input.payload?.direction === 1 ? 1 : null; + if (direction === null) return finish(this.error(input, "motion_jog", "motion_jog_range"), "failed"); + this.wasmMotion.setPaused(false); + const start = { ...current.state.position }; + const distance = Number(input.payload?.increment) > 0 ? Number(input.payload.increment) : 1; + const target = Number(start[axis] ?? 0) + direction * distance; + const configuredLimit = this.wasmHomeLimit.limits?.[axis]; + if (Array.isArray(configuredLimit) && configuredLimit.length === 2 && (target < Number(configuredLimit[0]) || target > Number(configuredLimit[1]))) return finish(this.error(input, "motion_queue", "motion_limit_range"), "failed"); + const end = { ...start, [axis]: target }; + const enqueue = this.wasmMotion.enqueue({ start, end, center: { x: 0, y: 0, z: 0 }, normal: { x: 0, y: 0, z: 1 }, velocity: Number(input.payload?.speed ?? 1), acceleration: 0, motion_type: 1, turn: 0, source_line: null }); + if (enqueue.status === "error") { + const code = enqueue.code === "wasm_motion_enqueue_-602" ? "motion_limit_range" : enqueue.code === "wasm_motion_enqueue_-601" ? "motion_jog_nonfinite" : enqueue.code; + return finish(this.error(input, "motion_queue", code), "failed"); + } + return finish(this.envelope("COMMAND_RESULT", input, { status: "verified", command: input.kind, motion: this.wasmMotionProjection(), wasm_motion: this.wasmMotion.read(), motion_authority: "wasm", operation_id: input.operation_id ?? null }), "verified"); + } let result; if (input.kind === "JOG_START" && this.motionAuthority === "wasm" && !this.wasmHomeLimit.read().state.homed) return finish(this.error(input, "motion_state", "motion_unhomed"), "failed"); if (input.kind === "JOG_START") result = this.motion.startJog(input.payload); @@ -1102,7 +1495,7 @@ export class SimSession { else if (input.kind === "SET_OVERRIDE") result = this.motion.setOverride(input.payload?.feed ?? input.payload?.feed_override, input.payload?.spindle ?? input.payload?.spindle_override); else result = this.motion.setFollowingError(input.payload?.value ?? input.payload?.following_error); if (result.status === "error" && result.state?.fault && this.task.state.state === "RUNNING") this.task.fault(-1205); - return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, motion: this.motion.export(), task: this.task.export(), command: input.kind, operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed"); + return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, motion: this.motionProjection(), task: this.task.export(), command: input.kind, operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed"); } case "SPINDLE_COMMAND": case "SPINDLE_FAULT": case "SPINDLE_INHIBIT": case "SPINDLE_ORIENT": case "SPINDLE_ORIENTED": case "IO_STEP": @@ -1111,6 +1504,7 @@ export class SimSession { case "PROBE_CONFIG": case "IO_RECOVER": return deviceResponse(input.kind, input.payload); case "LIMIT_SET": { + if (this.xyzacProgram) return finish(this.error(input, "motion_limit", "wasm_limit_inputs_are_configuration_owned"), "failed"); const result = this.motion.setLimit(input.payload?.axis, input.payload?.active === true); return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, task: this.task.export(), command: input.kind, operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed"); } @@ -1125,7 +1519,11 @@ export class SimSession { case "HAL_COMMAND": case "HAL_SET": { const payload = input.payload ?? {}; let result; - if (input.kind === "HAL_SET") { + if (this.xyzacIo && input.kind === "HAL_SET") { + result = this.xyzacIo.halValue(payload.name, payload.value, payload.type === "bit" ? 1 : payload.type === "s32" ? 2 : payload.type === "u32" ? 3 : 4, payload.target === "param"); + } else if (this.xyzacIo) { + result = this.xyzacIo.halCommand(payload); + } else if (input.kind === "HAL_SET") { result = payload.target === "param" ? this.hal.setParam(payload.name, payload.value, payload.type) : this.hal.setPin(payload.name, payload.value, payload.type); } else if (payload.action === "configure") { result = this.hal.configure(payload); @@ -1142,7 +1540,7 @@ export class SimSession { } else { result = this.hal.fail("hal_command_unsupported"); } - return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, task: this.task.export(), hal_runtime: this.hal.export(), command: input.kind, operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed"); + return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, task: this.task.export(), hal_runtime: this.xyzacIo ? this.xyzacIo.halExport() : this.hal.export(), command: input.kind, operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed"); } case "ENCODER_SET": case "COOLANT_COMMAND": case "COOLANT_FAULT": case "DOOR_SET": case "INTERLOCK_SET": case "INTERLOCK_RESET": case "DEVICE_ESTOP": case "DEVICE_ACK_ISSUE": case "DEVICE_ACK": case "DEVICE_ACK_ABORT": return deviceIoResponse(input.kind, input.payload); @@ -1162,6 +1560,10 @@ export class SimSession { return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, io_ack: this.ioAck.export(), device_io: this.deviceIo.export(), task: this.task.export(), command: input.kind, operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed"); } case "REMAP_REGISTER": case "REMAP_CALL": case "VCP_REGISTER": case "VCP_UPDATE": case "FILTER_EXEC": { + if (this.xyzacProgram && input.kind === "VCP_UPDATE" && ["type0-button", "type1-button", "type2-button"].includes(input.payload?.pin)) return finish(this.error(input, "pyvcp_switch_requires_mdi", "pyvcp_switch_requires_mdi"), "failed"); + if (this.xyzacProgram && input.kind === "VCP_UPDATE" && input.payload?.pin === "vismach-clear") { + return visualClearResponse(); + } const result = input.kind === "REMAP_REGISTER" ? this.callbacks.registerRemap(input.payload?.name, input.payload) : input.kind === "REMAP_CALL" @@ -1174,6 +1576,7 @@ export class SimSession { return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, callbacks: this.callbacks.export(), task: this.task.export(), command: input.kind, operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed"); } case "ESTOP": { + if (this.xyzacProgram) return deviceResponse(input.kind, input.payload); const motionResult = this.motion.estop(input.payload?.active === true); const deviceResult = deviceResponse(input.kind, input.payload); if (motionResult.status === "error") return finish(this.envelope("ERROR", input, { ...motionResult, task: this.task.export() }), "failed"); @@ -1207,6 +1610,17 @@ export class SimSession { const result = this.restoreCheckpoint(input.payload?.checkpoint, input.payload?.events, input.payload?.reconcile); return finish(this.envelope("RECOVERY_STATUS", input, result), result.status === "blocked" ? "failed" : "verified"); } + case "CANCEL": { + const target = input.payload?.operation_id; + let ledgerResult = null; + if (text(target)) { + try { ledgerResult = this.ledger.abort(target, input.payload?.reason ?? "cancel_requested"); } + catch (error) { ledgerResult = { status: "missing", error: String(error?.message ?? error) }; } + const operation = this.operations.get(target); + if (operation && operation.status !== "verified") operation.status = "aborted"; + } + return finish(this.envelope("COMMAND_RESULT", input, { status: ledgerResult?.status ?? "missing", cancelled: ledgerResult?.status === "aborted", retry_allowed: false, operation_id: target ?? null, ledger: ledgerResult })); + } case "ABORT": { const target = input.payload?.operation_id; const operation = text(target) ? this.operations.get(target) : null; @@ -1222,6 +1636,9 @@ export class SimSession { } case "DESTROY": this.program.destroy(); + this.xyzacIo?.destroy(); + this.xyzacDeviceIo?.destroy(); + this.xyzacKinematics?.destroy(); this.task.destroy(); this.scheduler.destroy(); call(this.core, "sim_destroy"); diff --git a/web/worker/sim-worker.mjs b/web/worker/sim-worker.mjs index c865328..254255c 100644 --- a/web/worker/sim-worker.mjs +++ b/web/worker/sim-worker.mjs @@ -1,8 +1,8 @@ import createModule from "../../build-wasm/linuxcnc-sim-core.js"; -import { SimSession } from "./sim-session.mjs"; +import { XyzacSession } from "./xyzac-session.mjs"; const core = await createModule(); -const session = new SimSession(core); +const session = new XyzacSession(core); self.onmessage = (event) => { try { diff --git a/web/worker/test_wasm_canonical_state.mjs b/web/worker/test_wasm_canonical_state.mjs index 545e6a4..946998c 100644 --- a/web/worker/test_wasm_canonical_state.mjs +++ b/web/worker/test_wasm_canonical_state.mjs @@ -49,7 +49,7 @@ const stepped = send("SIM_STEP", "jog-step", { cycles: 3 }); assert.equal(stepped.payload.task_authority, "wasm_task_canonical"); assert.equal(stepped.payload.wasm_home_limit.state.source, "wasm_home_limit"); assert.ok(stepped.payload.wasm_home_limit.state.tick > home.payload.wasm_home_limit.state.tick); -assert.deepEqual(stepped.payload.motion.axes, { x: stepped.payload.motion.joints[0], y: stepped.payload.motion.joints[1], z: stepped.payload.motion.joints[2] }); +assert.deepEqual({ x: stepped.payload.motion.axes.x, y: stepped.payload.motion.axes.y, z: stepped.payload.motion.axes.z }, { x: stepped.payload.motion.joints[0], y: stepped.payload.motion.joints[1], z: stepped.payload.motion.joints[2] }); const limit = send("LIMIT_SET", "limit", { axis: "x", active: true }); assert.equal(limit.payload.wasm_home_limit.state.source, "wasm_home_limit"); diff --git a/web/worker/test_xyzac_exact_preview.mjs b/web/worker/test_xyzac_exact_preview.mjs new file mode 100644 index 0000000..52b0dff --- /dev/null +++ b/web/worker/test_xyzac_exact_preview.mjs @@ -0,0 +1,65 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import createModule from "../../build-wasm/linuxcnc-sim-core.js"; +import { loadSimulationCase, toWorkerConfiguration } from "../workspace/sim-case-loader.mjs"; +import { XyzacSession, CONTEXT_ID } from "./xyzac-session.mjs"; +import { fnv1a64 } from "./replay.mjs"; + +const CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini"; +const PROGRAM_PATH = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc"; +const fetchImpl = async (url) => { + try { const body = await readFile(new URL(`../../${String(url).replace(/^\//, "")}`, import.meta.url)); return { ok: true, text: async () => body.toString("utf8") }; } + catch { return { ok: false, text: async () => "" }; } +}; +const bundle = await loadSimulationCase({ path: CASE, fetchImpl }); +assert.equal(bundle.status, "ready"); +const source = bundle.files?.[PROGRAM_PATH]; +assert.equal(typeof source, "string"); +assert.equal(source, await readFile(new URL(`../../${PROGRAM_PATH}`, import.meta.url), "utf8")); +const core = await createModule({ wasmBinary: await readFile(new URL("../../build-wasm/linuxcnc-sim-core.wasm", import.meta.url)) }); +const session = new XyzacSession(core, { sessionId: "xyzac-exact-preview" }); +const base = { schema_version: 1, context_id: CONTEXT_ID, session_id: session.sessionId }; +let seq = 0; +const send = (kind, operationId, payload = {}) => session.accept({ ...base, kind, seq: ++seq, operation_id: operationId, payload }); +send("HELLO", "hello"); +send("SESSION_ATTACH", "attach"); +assert.equal(send("LOAD_WORKSPACE", "workspace", { root_path: "/workspace", configuration: toWorkerConfiguration(bundle) }).payload.status, "verified"); +const loaded = send("PROGRAM_LOAD", "program-load", { source, path: PROGRAM_PATH }); +assert.equal(loaded.kind, "COMMAND_RESULT"); +assert.equal(loaded.payload.status, "verified"); +assert.equal(loaded.payload.program.path, PROGRAM_PATH); +assert.equal(loaded.payload.program.source_hash, fnv1a64(source)); +assert.equal(loaded.payload.preview.source, "linuxcnc-wasm-sim_program"); +assert.equal(loaded.payload.preview.segments.length, 29); +assert.equal(loaded.payload.panel_snapshot.visual.source, "wasm_canonical_motion"); +assert.equal(loaded.payload.panel_snapshot.visual.toolpath.length, 29); +const arcs = loaded.payload.preview.segments.filter((segment) => segment.motion_type === 2); +const rapids = loaded.payload.preview.segments.filter((segment) => segment.kind === "rapid"); +assert.equal(arcs.length, 4); +assert.equal(rapids.length, 25); +assert.ok(rapids.every((segment) => segment.canonical_motion_mode === 0)); +assert.ok(arcs.every((segment) => segment.canonical_motion_mode === 2)); +assert.ok(rapids.every((segment) => Math.abs(segment.velocity - 35) < 1e-12)); +assert.ok(arcs.every((segment) => Math.abs(segment.velocity - (1000 / 60)) < 1e-12)); +assert.ok(arcs.every((segment) => segment.turn === -3)); +assert.ok(arcs.every((segment) => Array.isArray(segment.samples) && segment.samples.length === 97)); +assert.ok(arcs.every((segment) => segment.samples.some((sample) => sample.z < segment.start.z && sample.z > segment.end.z))); +assert.ok(arcs.every((segment) => segment.samples_source === "linuxcnc-wasm-sim_posemath_segment_point")); +assert.ok(arcs.every((segment) => segment.kind === "helix" && segment.helix === true && segment.radius === 10 && segment.turns === 3 && segment.axial_delta === -5)); +assert.ok(arcs.every((segment) => segment.start.a === 20 && segment.end.a === 20 && segment.start.c === 45 && segment.end.c === 45)); +assert.deepEqual(arcs.map((segment) => segment.source_line), [67, 67, 67, 67]); +for (const segment of arcs) { + const radius = segment.samples.map((sample) => Math.hypot(sample.x - segment.center.x, sample.y - segment.center.y)); + assert.ok(Math.max(...radius) - Math.min(...radius) < 1e-9); + assert.ok(Math.abs(radius[0] - 10) < 1e-9); + assert.ok(Math.abs(segment.samples[0].z - 10) < 1e-9); + assert.ok(Math.abs(segment.samples.at(-1).z - 5) < 1e-9); +} +assert.deepEqual(arcs.map((segment) => [segment.end.x, segment.end.y, segment.end.z]), [[10, 20, 5], [-30, 20, 5], [-30, -20, 5], [10, -20, 5]]); +const clear = send("VISUAL_CLEAR", "visual-clear"); +assert.equal(clear.payload.visual_only, true); +assert.deepEqual(clear.payload.before, clear.payload.after); +const restarted = send("PROGRAM_RESTART", "program-restart"); +assert.equal(restarted.payload.program.path, PROGRAM_PATH); +assert.equal(restarted.payload.panel_snapshot.visual.toolpath.length, 29); +console.log(JSON.stringify({ schema: "xyzac-exact-tool-preview.v1", status: "verified", case: CASE, program_path: PROGRAM_PATH, source_hash: loaded.payload.program.source_hash, segment_count: loaded.payload.preview.segments.length, rapid_count: rapids.length, arc_count: arcs.length, arc_turn: -3, motion_mode_source: "linuxcnc-wasm-sim_program_canonical", helix_validation: { sample_points_per_helix: arcs[0].samples.length, samples_source: arcs[0].samples_source, radius_mm: 10, z_start: 10, z_end: 5, turns_per_helix: 3 }, helix_details: arcs.map((segment) => ({ source_line: segment.source_line, kind: segment.kind, start: segment.start, end: segment.end, center: segment.center, radius: segment.radius, turns: segment.turns, axial_delta: segment.axial_delta, samples: segment.samples.length, samples_source: segment.samples_source })), visual_segments: loaded.payload.panel_snapshot.visual.toolpath.length, restart_visual_segments: restarted.payload.panel_snapshot.visual.toolpath.length, clear_visual_only: clear.payload.visual_only, state_hash: loaded.payload.panel_snapshot.state_hash })); diff --git a/web/worker/test_xyzac_gate_matrix.mjs b/web/worker/test_xyzac_gate_matrix.mjs new file mode 100644 index 0000000..6e2eed6 --- /dev/null +++ b/web/worker/test_xyzac_gate_matrix.mjs @@ -0,0 +1,57 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import createModule from "../../build-wasm/linuxcnc-sim-core.js"; +import { loadSimulationCase, toWorkerConfiguration } from "../workspace/sim-case-loader.mjs"; +import { XyzacSession, CONTEXT_ID } from "./xyzac-session.mjs"; +import { axisGate, xyzacGateMatrix } from "../app/axis-contract.mjs"; + +const CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini"; +const fetchImpl = async (url) => { try { const body = await readFile(new URL(`../../${String(url).replace(/^\//, "")}`, import.meta.url)); return { ok: true, text: async () => body.toString("utf8") }; } catch { return { ok: false, text: async () => "" }; } }; +const bundle = await loadSimulationCase({ path: CASE, fetchImpl }); +const core = await createModule({ wasmBinary: await readFile(new URL("../../build-wasm/linuxcnc-sim-core.wasm", import.meta.url)) }); +const session = new XyzacSession(core, { sessionId: "xyzac-gate-matrix" }); +const base = { schema_version: 1, context_id: CONTEXT_ID, session_id: session.sessionId }; +let seq = 0; +const send = (kind, operation_id, payload = {}) => session.accept({ ...base, kind, seq: ++seq, operation_id, payload }); +send("HELLO", "hello"); +send("SESSION_ATTACH", "attach"); +const loaded = send("LOAD_WORKSPACE", "workspace", { root_path: "/workspace", configuration: toWorkerConfiguration(bundle) }); +assert.equal(loaded.payload.status, "verified"); +const initial = loaded.payload.panel_snapshot; +assert.equal(initial.xyzac.coordinates, "XYZAC"); +assert.equal(initial.xyzac.joint_count, 5); +assert.equal(initial.gates.run.enabled, false); +assert.equal(initial.gates.run.reason, "axis_taskfile_missing"); +assert.equal(initial.gates.runLine.reason, "axis_taskfile_missing"); +assert.equal(initial.gates.switchkinsIdentity.enabled, true); +assert.equal(initial.gates.switchkinsXyzac.enabled, true); +assert.equal(initial.gates.switchkinsUserk.enabled, true); +assert.equal(initial.gates.vismachClear.visual_only, true); +const noFile = axisGate("runLine", { task: { state: "READY", mode: "MANUAL" }, program: {}, motion: {}, taskfile: false, highlight_line: null }); +assert.equal(noFile.enabled, false); +assert.equal(noFile.reason, "axis_taskfile_missing"); +const highlightMissing = axisGate("runLine", { task: { state: "READY", mode: "MANUAL" }, program: { source_hash: "fnv1a64:file" }, motion: {}, taskfile: true, highlight_line: null }); +assert.equal(highlightMissing.reason, "axis_highlight_missing"); +const invalidSwitch = xyzacGateMatrix({ task: { state: "READY", mode: "MANUAL" }, program: {}, motion: {}, taskfile: false, xyzac: { coordinates: "XYZ", joint_count: 3, hal_pin_vars: false, switchkins_net: false, finite_offsets: true, userk_capability: false } }); +assert.equal(invalidSwitch.switchkinsXyzac.enabled, false); +assert.equal(invalidSwitch.switchkinsXyzac.reason, "xyzac_hal_pin_vars_missing"); +send("PROGRAM_LOAD", "program-load", { path: "gate.ngc", source: "G21 G90\nG1 X10 A20 C30 F100\nM2\n" }); +const running = send("PROGRAM_RUN", "program-run"); +assert.equal(running.payload.panel_snapshot.gates.pause.enabled, true); +assert.equal(running.payload.panel_snapshot.gates.abort.enabled, true); +assert.equal(running.payload.panel_snapshot.gates.resume.enabled, false); +assert.equal(running.payload.panel_snapshot.gates.switchkinsXyzac.enabled, false); +send("PROGRAM_PAUSE", "pause"); +const paused = send("SNAPSHOT_REQUEST", "paused-snapshot"); +assert.equal(paused.payload.panel_snapshot.gates.resume.enabled, true); +assert.equal(paused.payload.panel_snapshot.gates.pause.enabled, false); +send("PROGRAM_ABORT", "abort"); +const estopGates = xyzacGateMatrix({ task: { state: "ESTOP", mode: "MANUAL" }, program: { source_hash: "fnv1a64:file" }, motion: {}, taskfile: true, xyzac: { coordinates: "XYZAC", joint_count: 5, hal_pin_vars: true, switchkins_net: true, finite_offsets: true, userk_capability: true } }); +assert.equal(estopGates.switchkinsXyzac.enabled, false); +assert.equal(estopGates.switchkinsXyzac.reason, "xyzac_estop_active"); +send("ESTOP", "estop-reset", { active: false }); +send("IO_RECOVER", "recover"); +const recovered = send("SNAPSHOT_REQUEST", "recovered-snapshot"); +assert.equal(typeof recovered.payload.panel_snapshot.state_hash, "string"); +assert.equal(recovered.payload.panel_snapshot.gates.vismachClear.visual_only, true); +console.log(JSON.stringify({ schema: "xyzac-gate-matrix-rtcp-03.v1", status: "verified", case: CASE, normal: ["runLine", "switchkinsIdentity", "switchkinsXyzac", "switchkinsUserk"], blocked: [noFile.reason, highlightMissing.reason, invalidSwitch.switchkinsXyzac.reason, estopGates.switchkinsXyzac.reason], running: { pause: true, abort: true }, paused: { resume: true }, estop: { switchkins_enabled: estopGates.switchkinsXyzac.enabled }, final_state_hash: recovered.payload.panel_snapshot.state_hash })); diff --git a/web/worker/test_xyzac_hal_tool_alarm.mjs b/web/worker/test_xyzac_hal_tool_alarm.mjs new file mode 100644 index 0000000..dfdc029 --- /dev/null +++ b/web/worker/test_xyzac_hal_tool_alarm.mjs @@ -0,0 +1,65 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import createModule from "../../build-wasm/linuxcnc-sim-core.js"; +import { loadSimulationCase, toWorkerConfiguration } from "../workspace/sim-case-loader.mjs"; +import { XyzacSession, CONTEXT_ID } from "./xyzac-session.mjs"; + +const CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini"; +const fetchImpl = async (url) => { try { const body = await readFile(new URL(`../../${String(url).replace(/^\//, "")}`, import.meta.url)); return { ok: true, text: async () => body.toString("utf8") }; } catch { return { ok: false, text: async () => "" }; } }; +const bundle = await loadSimulationCase({ path: CASE, fetchImpl }); +const core = await createModule({ wasmBinary: await readFile(new URL("../../build-wasm/linuxcnc-sim-core.wasm", import.meta.url)) }); +const session = new XyzacSession(core, { sessionId: "xyzac-hal-tool" }); +const base = { schema_version: 1, context_id: CONTEXT_ID, session_id: session.sessionId }; +let seq = 0; +const send = (kind, operation_id, payload = {}) => session.accept({ ...base, kind, seq: ++seq, operation_id, payload }); +send("HELLO", "hello"); send("SESSION_ATTACH", "attach"); +assert.equal(send("LOAD_WORKSPACE", "workspace", { root_path: "/workspace", configuration: toWorkerConfiguration(bundle) }).payload.status, "verified"); + +const xml = await readFile(new URL("../../linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.xml", import.meta.url), "utf8"); +const postgui = await readFile(new URL("../../linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins_postgui.hal", import.meta.url), "utf8"); +for (const pin of ["type0-button", "type1-button", "type2-button", "vismach-clear"]) assert.ok(xml.includes(pin)); +for (const edge of ["pyvcp.type0-button", "pyvcp.type1-button", "pyvcp.type2-button", "vismach.plotclear"]) assert.ok(postgui.includes(edge)); +for (const [code, type] of [["M429", 0], ["M428", 1], ["M430", 2]]) assert.equal(send("MDI_EXECUTE", `switch-${code}`, { block: code }).payload.kinematics.active_type, type); +const directSwitch = send("VCP_UPDATE", "direct-switch", { name: "xyzac", pin: "type1-button", value: 1 }); +assert.equal(directSwitch.kind, "ERROR"); +assert.equal(directSwitch.payload.code, "pyvcp_switch_requires_mdi"); +send("SNAPSHOT_REQUEST", "before-clear"); +const clear = send("VCP_UPDATE", "visual-clear", { name: "xyzac", pin: "vismach-clear", value: 1 }); +assert.equal(clear.payload.visual_only, true); +assert.deepEqual(clear.payload.before, clear.payload.after); + +const allowed = send("HAL_SET", "hal-allowed", { target: "pin", name: "motion.probe-input", type: "bit", value: true }); +assert.equal(allowed.kind, "COMMAND_RESULT"); +const denied = send("HAL_SET", "hal-denied", { target: "pin", name: "motion.switchkins-type", type: "s32", value: 2 }); +assert.equal(denied.kind, "ERROR"); +assert.equal(denied.payload.code, "wasm_hal_write_denied"); + +assert.equal(send("SPINDLE_COMMAND", "spindle-on", { spindle: 0, rpm: 1200, enabled: true }).kind, "COMMAND_RESULT"); +send("IO_STEP", "spindle-step", { ticks: 10 }); +const spindle = send("SNAPSHOT_REQUEST", "spindle-snapshot").payload.panel_snapshot.io.state.spindles[0]; +assert.equal(spindle.command_rpm, 1200); +assert.equal(send("SPINDLE_COMMAND", "spindle-off", { spindle: 0, rpm: 0, enabled: false }).kind, "COMMAND_RESULT"); +send("IO_STEP", "spindle-stop-step", { ticks: 20 }); +assert.equal(send("COOLANT_COMMAND", "coolant-on", { mist: true, flood: true }).payload.panel_snapshot.device_io.source, "wasm_device_io"); +assert.equal(send("TOOL_PREPARE", "tool-prepare", { tool: 7, pocket: 3 }).kind, "COMMAND_RESULT"); +assert.equal(send("TOOL_PREPARED", "tool-prepared", { prepared: true }).kind, "COMMAND_RESULT"); +assert.equal(send("TOOL_CHANGE", "tool-change").kind, "COMMAND_RESULT"); +assert.equal(send("TOOL_CHANGED", "tool-changed", { changed: true }).payload.device_io.state.tool.current, 7); +assert.equal(send("MDI_EXECUTE", "g43", { block: "G43 H7" }).kind, "COMMAND_RESULT"); +assert.equal(send("MDI_EXECUTE", "g49", { block: "G49" }).kind, "COMMAND_RESULT"); + +const ack = send("DEVICE_ACK_ISSUE", "ack-one", { timeout_ticks: 2 }); +assert.equal(ack.kind, "COMMAND_RESULT"); +assert.equal(send("DEVICE_ACK", "ack-confirm", { operation_id: "ack-one" }).kind, "COMMAND_RESULT"); +assert.equal(send("DEVICE_ACK_ISSUE", "ack-timeout", { timeout_ticks: 1 }).kind, "COMMAND_RESULT"); +send("SIM_STEP", "ack-timeout-step", { cycles: 1 }); +const lateAck = send("DEVICE_ACK", "ack-late", { operation_id: "ack-timeout" }); +assert.equal(lateAck.kind, "ERROR"); +assert.equal(lateAck.payload.code, "wasm_sim_device_ack_ack_-1008"); +assert.equal(send("DEVICE_ACK_ISSUE", "ack-abort", { timeout_ticks: 5 }).kind, "COMMAND_RESULT"); +assert.equal(send("DEVICE_ACK_ABORT", "ack-abort-command", { operation_id: "ack-abort" }).kind, "COMMAND_RESULT"); +const alarm = denied.payload; +assert.equal(typeof alarm.operation_id, "string"); +assert.ok(session.timeline.export().events.events.some((event) => event.kind === "HAL_SET")); +const final = send("SNAPSHOT_REQUEST", "final").payload.panel_snapshot; +console.log(JSON.stringify({ schema: "xyzac-hal-tool-alarm-rtcp-07.v1", status: "verified", case: CASE, pyvcp: ["M429", "M428", "M430", "vismach-clear"], hal: { allowed: "motion.probe-input", denied: denied.payload.code }, tool: final.io.state.tool.current, spindle_rpm: spindle.command_rpm, coolant: final.device_io.state.coolant, ack: { normal: "verified", timeout: lateAck.payload.code, abort: "verified" }, alarm: { code: alarm.code, operation_id: alarm.operation_id }, state_hash: final.state_hash })); diff --git a/web/worker/test_xyzac_machine_sequence.mjs b/web/worker/test_xyzac_machine_sequence.mjs new file mode 100644 index 0000000..e858467 --- /dev/null +++ b/web/worker/test_xyzac_machine_sequence.mjs @@ -0,0 +1,130 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import createModule from "../../build-wasm/linuxcnc-sim-core.js"; +import { loadSimulationCase, toWorkerConfiguration } from "../workspace/sim-case-loader.mjs"; +import { SimSession, CONTEXT_ID } from "./sim-session.mjs"; + +const CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini"; +const PROGRAM_PATH = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc"; +const fetchImpl = async (url) => { + try { + const body = await readFile(new URL(`../../${String(url).replace(/^\//, "")}`, import.meta.url)); + return { ok: true, text: async () => body.toString("utf8") }; + } catch { + return { ok: false, text: async () => "" }; + } +}; + +const bundle = await loadSimulationCase({ path: CASE, fetchImpl }); +assert.equal(bundle.status, "ready"); +const source = bundle.files?.[PROGRAM_PATH]; +assert.equal(typeof source, "string"); +const core = await createModule({ wasmBinary: await readFile(new URL("../../build-wasm/linuxcnc-sim-core.wasm", import.meta.url)) }); +const session = new SimSession(core, { sessionId: "xyzac-machine-sequence" }); +const base = { schema_version: 1, context_id: CONTEXT_ID, session_id: session.sessionId }; +let seq = 0; +const send = (kind, payload = {}) => session.accept({ ...base, kind, seq: ++seq, operation_id: `machine-${seq}`, payload }); + +send("HELLO"); +send("SESSION_ATTACH"); +assert.equal(send("LOAD_WORKSPACE", { root_path: "/workspace", configuration: toWorkerConfiguration(bundle) }).payload.status, "verified"); +const loaded = send("PROGRAM_LOAD", { source, path: PROGRAM_PATH }); +assert.equal(loaded.kind, "COMMAND_RESULT"); +assert.equal(loaded.payload.motion_authority, "wasm"); +assert.equal(loaded.payload.panel_snapshot.devices.source, "wasm_io"); +const jsMotionHash = session.motion.export().state_hash; + +const emergency = send("ESTOP", { active: true }); +assert.equal(emergency.kind, "COMMAND_RESULT"); +assert.equal(emergency.payload.task.state, "ESTOP"); +assert.equal(emergency.payload.motion_authority, "wasm"); +assert.equal(emergency.payload.device_io.source, "wasm_io"); +assert.equal(emergency.payload.device_io.state.estop, 1); +assert.equal(emergency.payload.device_io.state.ready, 0); +assert.equal(emergency.payload.panel_snapshot.motion.estop, true); +assert.equal(emergency.payload.panel_snapshot.wasm_motion.state.queue_depth, 0); +assert.equal(session.motion.export().state_hash, jsMotionHash); + +const released = send("ESTOP", { active: false }); +assert.equal(released.payload.status, "verified"); +assert.equal(released.payload.device_io.state.estop, 0); +assert.equal(released.payload.device_io.state.ready, 0); +assert.equal(released.payload.task.state, "ESTOP"); +const recovered = send("IO_RECOVER"); +assert.equal(recovered.payload.task.state, "READY"); +assert.equal(recovered.payload.device_io.state.estop, 0); +assert.equal(recovered.payload.device_io.state.ready, 1); +const recoveryEpoch = recovered.payload.device_io.state.recovery_epoch; + +const powered = send("POWER", { active: true }); +assert.equal(powered.payload.status, "verified"); +assert.equal(powered.payload.task.state, "READY"); +assert.equal(powered.payload.device_io.source, "wasm_io"); +assert.equal(powered.payload.device_io.state.ready, 1); +assert.ok(powered.payload.device_io.state.recovery_epoch > recoveryEpoch); + +const homed = send("HOME", { all: true }); +assert.equal(homed.payload.status, "verified"); +assert.equal(homed.payload.motion_authority, "wasm"); +assert.equal(homed.payload.wasm_home_limit.state.homed, true); +assert.equal(homed.payload.wasm_home_limit.state.joint_count, 5); +assert.deepEqual(homed.payload.panel_snapshot.motion.homed_axes, [true, true, true, true, true]); +assert.deepEqual(homed.payload.wasm_home_limit.state.joints, [0, 0, 0, 0, 0]); + +const running = send("PROGRAM_RUN"); +assert.equal(running.payload.status, "verified"); +assert.equal(running.payload.task.state, "RUNNING"); +assert.equal(running.payload.program.source, "linuxcnc-wasm-sim_program"); +assert.equal(running.payload.motion_authority, "wasm"); +assert.equal(session.wasmMotion.exportState().controls.paused, false); + +const stepped = send("SIM_STEP", { cycles: 180 }); +assert.equal(stepped.payload.status, "verified"); +assert.equal(stepped.payload.motion_authority, "wasm"); +assert.ok(stepped.payload.program.current_line > 0); +assert.ok(stepped.payload.program_steps.length > 0); +assert.equal(stepped.payload.panel_snapshot.visual.source, "wasm_canonical_motion"); +assert.deepEqual(stepped.payload.panel_snapshot.visual.pose, stepped.payload.wasm_motion.state.position); +assert.deepEqual(stepped.payload.panel_snapshot.visual.joints, stepped.payload.panel_snapshot.motion.joints); +assert.deepEqual(stepped.payload.panel_snapshot.coordinates.machine, [stepped.payload.panel_snapshot.visual.pose.x, stepped.payload.panel_snapshot.visual.pose.y, stepped.payload.panel_snapshot.visual.pose.z, stepped.payload.panel_snapshot.visual.pose.a, stepped.payload.panel_snapshot.visual.pose.c]); +assert.deepEqual(stepped.payload.panel_snapshot.coordinates.commanded, stepped.payload.panel_snapshot.coordinates.machine); +assert.ok(stepped.payload.panel_snapshot.visual.active_progress > 0); +assert.equal(stepped.payload.wasm_motion.state.active_tag, 1); +assert.equal(stepped.payload.panel_snapshot.kinematics.active_type, 1); +assert.ok(Number.isFinite(stepped.payload.panel_snapshot.visual.pose.a)); +assert.ok(Number.isFinite(stepped.payload.panel_snapshot.visual.pose.c)); +assert.equal(session.motion.export().state_hash, jsMotionHash); + +const aborted = send("PROGRAM_ABORT"); +assert.equal(aborted.payload.task.state, "STOPPED"); +const restarted = send("PROGRAM_RESTART"); +assert.equal(restarted.payload.status, "verified"); +const fullRun = send("PROGRAM_RUN"); +assert.equal(fullRun.payload.task.state, "RUNNING"); +const completed = send("SIM_STEP", { cycles: 8000 }); +assert.equal(completed.payload.status, "verified"); +assert.equal(completed.payload.program.program_status, "completed"); +assert.equal(completed.payload.task.state, "STOPPED"); +assert.equal(completed.payload.wasm_motion.state.queue_depth, 0); +assert.equal((completed.payload.panel_snapshot.visual.toolpath ?? loaded.payload.panel_snapshot.visual.toolpath).length, 29); +assert.equal(completed.payload.panel_snapshot.kinematics.active_type, 0); + +console.log(JSON.stringify({ + schema: "xyzac-machine-sequence.v1", + status: "verified", + case: CASE, + sequence: ["ESTOP", "ESTOP_RELEASE", "IO_RECOVER", "POWER", "HOME_ALL", "PROGRAM_RUN", "SIM_STEP"], + authority: { motion: "wasm", io: "wasm_io", home_limit: "wasm_home_limit", program: "linuxcnc-wasm-sim_program", visual: "wasm_canonical_motion" }, + estop_queue_depth: emergency.payload.panel_snapshot.wasm_motion.state.queue_depth, + home_joint_count: homed.payload.wasm_home_limit.state.joint_count, + current_line_after_step: stepped.payload.program.current_line, + live_axis_sample: stepped.payload.panel_snapshot.visual.pose, + live_joints: stepped.payload.panel_snapshot.visual.joints, + active_segment_id: stepped.payload.panel_snapshot.visual.active_segment_id, + active_progress: stepped.payload.panel_snapshot.visual.active_progress, + rtcp_active_type: stepped.payload.panel_snapshot.kinematics.active_type, + rtcp_joint_pose_delta: stepped.payload.panel_snapshot.kinematics.joints.map((value, index) => value - [stepped.payload.panel_snapshot.visual.pose.x, stepped.payload.panel_snapshot.visual.pose.y, stepped.payload.panel_snapshot.visual.pose.z, stepped.payload.panel_snapshot.visual.pose.a, stepped.payload.panel_snapshot.visual.pose.c][index]), + full_run: { cycles: 8000, program_status: completed.payload.program.program_status, task_state: completed.payload.task.state, queue_depth: completed.payload.wasm_motion.state.queue_depth, final_switchkins_type: completed.payload.panel_snapshot.kinematics.active_type }, + js_motion_unchanged: session.motion.export().state_hash === jsMotionHash, + state_hash: stepped.payload.panel_snapshot.state_hash, +})); diff --git a/web/worker/test_xyzac_manual_control.mjs b/web/worker/test_xyzac_manual_control.mjs new file mode 100644 index 0000000..f40e4d4 --- /dev/null +++ b/web/worker/test_xyzac_manual_control.mjs @@ -0,0 +1,75 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import createModule from "../../build-wasm/linuxcnc-sim-core.js"; +import { loadSimulationCase, toWorkerConfiguration } from "../workspace/sim-case-loader.mjs"; +import { XyzacSession, CONTEXT_ID } from "./xyzac-session.mjs"; + +const CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini"; +const fetchImpl = async (url) => { try { const body = await readFile(new URL(`../../${String(url).replace(/^\//, "")}`, import.meta.url)); return { ok: true, text: async () => body.toString("utf8") }; } catch { return { ok: false, text: async () => "" }; } }; +const bundle = await loadSimulationCase({ path: CASE, fetchImpl }); +const core = await createModule({ wasmBinary: await readFile(new URL("../../build-wasm/linuxcnc-sim-core.wasm", import.meta.url)) }); + +function setup(id) { + const session = new XyzacSession(core, { sessionId: id }); + const base = { schema_version: 1, context_id: CONTEXT_ID, session_id: id }; + let seq = 0; + const send = (kind, operation_id, payload = {}) => session.accept({ ...base, kind, seq: ++seq, operation_id, payload }); + send("HELLO", "hello"); send("SESSION_ATTACH", "attach"); + assert.equal(send("LOAD_WORKSPACE", "workspace", { root_path: "/workspace", configuration: toWorkerConfiguration(bundle) }).payload.status, "verified"); + return { session, send }; +} + +const jogCase = setup("xyzac-manual-jog"); +const home = jogCase.send("HOME", "home-all"); +assert.equal(home.payload.motion_authority, "wasm"); +assert.equal(home.payload.wasm_home_limit.state.homed, true); +assert.equal(home.payload.wasm_home_limit.state.joint_count, 5); +const axes = ["x", "y", "z", "a", "c"]; +const jogRows = []; +for (const axis of axes) { + const axisCase = axis === "x" ? jogCase : setup(`xyzac-manual-jog-${axis}`); + if (axis !== "x") assert.equal(axisCase.send("HOME", `home-${axis}`).payload.wasm_home_limit.state.homed, true); + const start = axisCase.session.wasmMotion.read().state.position[axis] ?? 0; + const started = axisCase.send("JOG_START", `jog-${axis}`, { axis, direction: 1, speed: 1, increment: axis === "a" || axis === "c" ? 2 : 1 }); + assert.equal(started.kind, "COMMAND_RESULT", axis); + assert.equal(started.payload.motion_authority, "wasm"); + const stepped = axisCase.send("SIM_STEP", `jog-step-${axis}`, { cycles: 1 }); + assert.equal(stepped.payload.motion_authority, "wasm"); + const end = axisCase.session.wasmMotion.read().state.position[axis] ?? axisCase.session.wasmMotion.read().state.position.x; + assert.notEqual(end, start, axis); + assert.equal(axisCase.send("JOG_STOP", `jog-stop-${axis}`).payload.motion_authority, "wasm"); + jogRows.push({ axis, start, end }); +} +const outOfRange = jogCase.send("JOG_START", "jog-limit", { axis: "x", direction: 1, speed: 1, increment: 10000 }); +assert.equal(outOfRange.kind, "ERROR"); +assert.equal(outOfRange.payload.message_key, "motion_limit_range"); +const nonFinite = jogCase.send("JOG_START", "jog-nonfinite", { axis: "a", direction: 1, speed: "not-a-number" }); +assert.equal(nonFinite.kind, "ERROR"); +assert.equal(nonFinite.payload.message_key, "motion_jog_nonfinite"); +const ferror = jogCase.send("FOLLOWING_ERROR", "ferror", { value: 1 }); +assert.equal(ferror.kind, "ERROR"); +assert.equal(ferror.payload.code, "motion_following_error"); + +const mdiCase = setup("xyzac-manual-mdi"); +const mdi = mdiCase.send("MDI_EXECUTE", "mdi-xyzac", { block: "G21 G90 G1 X10 Y5 Z180 A30 C45 F100" }); +assert.equal(mdi.kind, "COMMAND_RESULT"); +assert.equal(mdi.payload.motion_authority, "wasm"); +assert.equal(mdi.payload.program.source, "linuxcnc-wasm-sim_program"); +assert.equal(mdi.payload.panel_snapshot.kinematics.active_type, 0); +const invalidMdi = mdiCase.send("MDI_EXECUTE", "mdi-invalid", { block: "G999" }); +assert.equal(invalidMdi.kind, "ERROR"); +const loaded = mdiCase.send("PROGRAM_LOAD", "mdi-program", { source: "G21 G90\nG1 X20 A10 C20 F100\nM2\n", path: "mdi-run.ngc" }); +assert.equal(loaded.kind, "COMMAND_RESULT"); +mdiCase.send("PROGRAM_RUN", "mdi-run"); +const mdiWhileRunning = mdiCase.send("MDI_EXECUTE", "mdi-running", { block: "G0 X1" }); +assert.equal(mdiWhileRunning.kind, "ERROR"); +assert.equal(mdiWhileRunning.payload.message_key, "mdi_while_program_active"); +mdiCase.send("PROGRAM_ABORT", "mdi-abort"); +const estop = mdiCase.send("ESTOP", "mdi-estop", { active: true }); +assert.equal(estop.kind, "COMMAND_RESULT"); +assert.equal(estop.payload.task.state, "ESTOP"); +assert.equal(estop.payload.device_io.source, "wasm_io"); +const recovered = mdiCase.send("IO_RECOVER", "mdi-recover"); +assert.equal(recovered.payload.motion_authority, "wasm"); + +console.log(JSON.stringify({ schema: "xyzac-manual-control-rtcp-06.v1", status: "verified", case: CASE, home: { authority: "wasm_home_limit", joints: 5 }, jog: jogRows, boundary: { out_of_range: outOfRange.payload.code, nonfinite_speed: nonFinite.payload.code, following_error: ferror.payload.code }, mdi: "verified", mdi_running_gate: mdiWhileRunning.payload.message_key, estop_recovery: "verified", state_hash: recovered.payload.panel_snapshot.state_hash })); diff --git a/web/worker/test_xyzac_program_preview.mjs b/web/worker/test_xyzac_program_preview.mjs new file mode 100644 index 0000000..1b2ff48 --- /dev/null +++ b/web/worker/test_xyzac_program_preview.mjs @@ -0,0 +1,44 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import createModule from "../../build-wasm/linuxcnc-sim-core.js"; +import { loadSimulationCase, toWorkerConfiguration } from "../workspace/sim-case-loader.mjs"; +import { XyzacSession, CONTEXT_ID } from "./xyzac-session.mjs"; + +const CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini"; +const fetchImpl = async (url) => { try { const body = await readFile(new URL(`../../${String(url).replace(/^\//, "")}`, import.meta.url)); return { ok: true, text: async () => body.toString("utf8") }; } catch { return { ok: false, text: async () => "" }; } }; +const bundle = await loadSimulationCase({ path: CASE, fetchImpl }); +const core = await createModule({ wasmBinary: await readFile(new URL("../../build-wasm/linuxcnc-sim-core.wasm", import.meta.url)) }); +const session = new XyzacSession(core, { sessionId: "xyzac-preview" }); +const base = { schema_version: 1, context_id: CONTEXT_ID, session_id: session.sessionId }; +let seq = 0; +const send = (kind, operation_id, payload = {}) => session.accept({ ...base, kind, seq: ++seq, operation_id, payload }); +send("HELLO", "hello"); +send("SESSION_ATTACH", "attach"); +assert.equal(send("LOAD_WORKSPACE", "workspace", { root_path: "/workspace", configuration: toWorkerConfiguration(bundle) }).payload.status, "verified"); +const source = "G21 G90\nG0 X10 Y5 Z200 A30 C45\nG1 X20 Y10 Z180 A35 C50 F100\nM2\n"; +const loaded = send("PROGRAM_LOAD", "program-load", { source, path: "demos/preview.ngc" }); +assert.equal(loaded.kind, "COMMAND_RESULT"); +assert.equal(loaded.payload.program.source, "linuxcnc-wasm-sim_program"); +assert.equal(loaded.payload.program.path, "demos/preview.ngc"); +assert.equal(loaded.payload.program.source_hash, "fnv1a64:b7f4678312207b31"); +assert.equal(loaded.payload.preview.status, "verified"); +assert.equal(loaded.payload.preview.source, "linuxcnc-wasm-sim_program"); +assert.equal(loaded.payload.preview.path, "demos/preview.ngc"); +assert.equal(loaded.payload.preview.line_count, 4); +assert.ok(loaded.payload.preview.segments.length >= 2); +assert.ok(loaded.payload.preview.segments.every((segment) => Number.isSafeInteger(segment.id) && Number.isSafeInteger(segment.source_line))); +assert.ok(loaded.payload.preview.segments.every((segment) => ["x", "y", "z", "a", "b", "c"].every((axis) => Number.isFinite(segment.start[axis]) && Number.isFinite(segment.end[axis])))); +const previewHash = loaded.payload.preview.preview_hash; +const snapshot = send("SNAPSHOT_REQUEST", "snapshot"); +assert.equal(snapshot.payload.panel_snapshot.program.path, "demos/preview.ngc"); +assert.equal(snapshot.payload.panel_snapshot.program.source_hash, loaded.payload.program.source_hash); +const replay = send("PROGRAM_LOAD", "program-load", { source: "G999\n", path: "bad.ngc" }); +assert.equal(replay.replayed, true); +assert.equal(replay.payload.preview.preview_hash, previewHash); +const invalid = send("PROGRAM_LOAD", "invalid-load", { source: "G999\n", path: "invalid.ngc" }); +assert.equal(invalid.kind, "ERROR"); +assert.equal(invalid.payload.preview.status, "error"); +const empty = send("PROGRAM_LOAD", "empty-load", { source: "", path: "empty.ngc" }); +assert.equal(empty.kind, "ERROR"); +assert.equal(empty.payload.code, "program_source_invalid"); +console.log(JSON.stringify({ schema: "xyzac-program-preview-rtcp-04.v1", status: "verified", case: CASE, source_hash: loaded.payload.program.source_hash, line_count: loaded.payload.preview.line_count, segment_count: loaded.payload.preview.segments.length, preview_hash: previewHash, invalid_gcode: invalid.payload.preview.status, empty_code: empty.payload.code, state_hash: snapshot.payload.panel_snapshot.state_hash })); diff --git a/web/worker/test_xyzac_protocol_react.mjs b/web/worker/test_xyzac_protocol_react.mjs new file mode 100644 index 0000000..1724785 --- /dev/null +++ b/web/worker/test_xyzac_protocol_react.mjs @@ -0,0 +1,76 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import createModule from "../../build-wasm/linuxcnc-sim-core.js"; +import { AxisGateError, AxisOperationController } from "../app/axis-operation-controller.mjs"; +import { loadSimulationCase, toWorkerConfiguration } from "../workspace/sim-case-loader.mjs"; +import { XyzacSession, CONTEXT_ID } from "./xyzac-session.mjs"; + +const CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini"; +const PROGRAM = "G21 G90\nG0 X0 Y0 Z10 A0 C0\nG1 X10 Y5 Z5 A30 C45 F100\nM2\n"; +const fetchImpl = async (url) => { + try { + const body = await readFile(new URL(`../../${String(url).replace(/^\//, "")}`, import.meta.url)); + return { ok: true, text: async () => body.toString("utf8") }; + } catch { + return { ok: false, text: async () => "" }; + } +}; + +const bundle = await loadSimulationCase({ path: CASE, fetchImpl }); +assert.equal(bundle.status, "ready"); +const core = await createModule({ wasmBinary: await readFile(new URL("../../build-wasm/linuxcnc-sim-core.wasm", import.meta.url)) }); +const session = new XyzacSession(core, { sessionId: "xyzac-protocol-react" }); +const base = { schema_version: 1, context_id: CONTEXT_ID, session_id: session.sessionId }; +let seq = 0; +const send = (kind, operationId, payload = {}) => session.accept({ ...base, kind, seq: ++seq, operation_id: operationId, payload }); +send("HELLO", "hello"); +send("SESSION_ATTACH", "attach"); +assert.equal(send("LOAD_WORKSPACE", "workspace", { root_path: "/workspace", configuration: toWorkerConfiguration(bundle) }).payload.status, "verified"); + +const power = send("POWER", "power-on", { active: true }); +assert.equal(power.kind, "COMMAND_RESULT"); +assert.equal(power.payload.command, "POWER"); +const switches = []; +for (const type of [0, 1, 2, 1]) { + const response = send("KINEMATICS_SELECT", `select-${type}-${seq}`, { type }); + assert.equal(response.kind, "COMMAND_RESULT"); + assert.equal(response.payload.kinematics.active_type, type); + assert.equal(response.payload.remap.hal_pin, "motion.switchkins-type"); + switches.push({ type, operation_id: response.operation_id, phase: response.payload.xyzac_ledger?.entries?.at(-1)?.phase ?? "committed" }); +} +const invalid = send("KINEMATICS_SELECT", "select-invalid", { type: 9 }); +assert.equal(invalid.kind, "ERROR"); +assert.equal(invalid.payload.gate_reason, "xyzac_kinematics_type_invalid"); + +assert.equal(send("PROGRAM_LOAD", "program-load", { source: PROGRAM, path: "xyzac-panel.ngc" }).kind, "COMMAND_RESULT"); +const clear = send("VISUAL_CLEAR", "visual-clear"); +assert.equal(clear.kind, "COMMAND_RESULT"); +assert.equal(clear.payload.visual_only, true); +assert.deepEqual(clear.payload.before, clear.payload.after); +assert.equal(send("PROGRAM_RUN", "program-run").kind, "COMMAND_RESULT"); +const runningSwitch = send("KINEMATICS_SELECT", "select-running", { type: 0 }); +assert.equal(runningSwitch.kind, "ERROR"); +assert.equal(runningSwitch.payload.gate_reason, "xyzac_interp_not_idle"); +send("PROGRAM_ABORT", "program-abort"); + +const sent = []; +const fakeClient = { send: async (kind, payload, operationId) => { sent.push({ kind, payload, operationId }); return { kind: "COMMAND_RESULT", payload: { status: "verified" } }; } }; +const controller = new AxisOperationController(fakeClient); +const disabledState = { task: { state: "READY", mode: "MANUAL", interp_state: "IDLE" }, xyzac: { coordinates: "XYZAC", joint_count: 5, hal_pin_vars: true, switchkins_net: true, finite_offsets: true, userk_capability: true }, gates: { switchkinsXyzac: { action: "switchkinsXyzac", enabled: false, reason: "worker_gate_disabled" } } }; +await assert.rejects(controller.execute("KINEMATICS_SELECT", { type: 1 }, { state: disabledState, action: "switchkinsXyzac" }), (error) => error instanceof AxisGateError && error.code === "worker_gate_disabled"); +assert.equal(sent.length, 0); +const enabledState = { ...disabledState, gates: { switchkinsXyzac: { action: "switchkinsXyzac", enabled: true, reason: "xyzac_m428_available" } } }; +await controller.execute("KINEMATICS_SELECT", { type: 1 }, { state: enabledState, action: "switchkinsXyzac" }); +assert.equal(sent.length, 1); +assert.deepEqual(controller.exportTrace().map((item) => item.phase), ["blocked", "pending", "result"]); + +const appSource = await readFile(new URL("../react/src/App.tsx", import.meta.url), "utf8"); +const panelSource = await readFile(new URL("../react/src/XyzacTrtPanel.tsx", import.meta.url), "utf8"); +const contractSource = await readFile(new URL("../react/src/xyzac-panel-contract.ts", import.meta.url), "utf8"); +const combined = `${appSource}\n${panelSource}\n${contractSource}`; +for (const symbol of ["XyzacTrtPanel", "XyzacProgramPane", "XyzacKinematicsControl", "XyzacManualPanel", "XyzacDiagnostics", "KINEMATICS_SELECT", "VISUAL_CLEAR", "POWER", "switchkinsXyzac", "Operation trace", "Alarms / recovery"]) assert.ok(combined.includes(symbol), symbol); +for (const forbidden of [/_sim_/, /_malloc/, /\bHEAP(?:U|F|I)?\d*\b/, /navigator\.storage/, /\bOPFS\b/i, /postMessage\s*\(/]) assert.equal(forbidden.test(combined), false, String(forbidden)); +assert.ok(appSource.includes("SELECTED_XYZAC_CASE")); +assert.equal(appSource.includes("3axis-tutorial"), false); + +console.log(JSON.stringify({ schema: "xyzac-protocol-react-rtcp-09.v1", status: "verified", case: CASE, commands: [power.payload.command, "KINEMATICS_SELECT", "VISUAL_CLEAR"], switchkins: switches, gates: { invalid: invalid.payload.gate_reason, running: runningSwitch.payload.gate_reason, controller: controller.exportTrace().map((item) => item.phase) }, components: ["XyzacTrtPanel", "XyzacProgramPane", "XyzacKinematicsControl", "XyzacManualPanel", "XyzacDiagnostics"], worker_only: true, state_hash: clear.payload.panel_snapshot.state_hash })); diff --git a/web/worker/test_xyzac_recovery.mjs b/web/worker/test_xyzac_recovery.mjs new file mode 100644 index 0000000..581fa03 --- /dev/null +++ b/web/worker/test_xyzac_recovery.mjs @@ -0,0 +1,121 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import createModule from "../../build-wasm/linuxcnc-sim-core.js"; +import { MemoryStorage, WorkspaceJournal } from "../workspace/journal.mjs"; +import { opfsCapability, runOpfsProbe } from "../workspace/opfs-runtime.mjs"; +import { XyzacSession, CONTEXT_ID } from "./xyzac-session.mjs"; +import { loadSimulationCase, toWorkerConfiguration } from "../workspace/sim-case-loader.mjs"; +import { fnv1a64 } from "./replay.mjs"; + +const CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini"; +const SOURCE = "G21 G90\nG0 X0 Y0 Z10 A0 C0\nG1 X40 Y20 Z5 A30 C45 F100\nG1 X0 Y0 Z10 A0 C0 F100\nM2\n"; +const fetchImpl = async (url) => { + try { const body = await readFile(new URL(`../../${String(url).replace(/^\//, "")}`, import.meta.url)); return { ok: true, text: async () => body.toString("utf8") }; } + catch { return { ok: false, text: async () => "" }; } +}; +const bundle = await loadSimulationCase({ path: CASE, fetchImpl }); +assert.equal(bundle.status, "ready"); +const wasmBinary = await readFile(new URL("../../build-wasm/linuxcnc-sim-core.wasm", import.meta.url)); + +async function create(id) { + const core = await createModule({ wasmBinary }); + const session = new XyzacSession(core, { sessionId: id }); + const base = { schema_version: 1, context_id: CONTEXT_ID, session_id: id }; + let seq = 0; + const send = (kind, operationId, payload = {}) => session.accept({ ...base, kind, seq: ++seq, operation_id: operationId, payload }); + send("HELLO", "hello"); + send("SESSION_ATTACH", "attach"); + const loaded = send("LOAD_WORKSPACE", "workspace", { root_path: "/workspace", configuration: toWorkerConfiguration(bundle) }); + assert.equal(loaded.payload.status, "verified"); + return { core, session, send }; +} + +const continuous = await create("xyzac-recovery-continuous"); +const switched = continuous.send("MDI_EXECUTE", "switch-once", { block: "M428" }); +assert.equal(switched.payload.kinematics.active_type, 1); +const loaded = continuous.send("PROGRAM_LOAD", "program-load", { path: "recovery.ngc", source: SOURCE }); +assert.equal(loaded.payload.status, "verified"); +continuous.send("PROGRAM_RUN", "program-run"); +const stepped = continuous.send("SIM_STEP", "motion-step", { cycles: 2 }); +assert.equal(stepped.payload.status, "verified"); +const checkpointResponse = continuous.send("CHECKPOINT", "checkpoint"); +const checkpoint = checkpointResponse.payload.checkpoint; +assert.equal(checkpoint.state.kinematics.active_type, 1); +assert.equal(checkpoint.state.kinematics.coordinates, "XYZAC"); +assert.equal(checkpoint.state.kinematics.joints.length, 5); +assert.equal(checkpoint.state.kinematics.offsets.y_offset, 20); +assert.equal(checkpoint.state.kinematics.offsets.z_offset, 10); +assert.equal(checkpoint.state.kinematics.offsets.tool_offset, 0); +assert.equal(checkpoint.state.motion_authority, "wasm"); +assert.equal(fnv1a64(checkpoint.state), checkpoint.state_hash); +const before = continuous.session.workspacePackageState(); +const switchCountBefore = checkpoint.state.kinematics.switch_count; +continuous.send("SIM_STEP", "after-checkpoint", { cycles: 2 }); +const endpoint = continuous.session.workspacePackageState(); + +const restarted = await create("xyzac-recovery-continuous"); +const recovery = restarted.session.restoreCheckpoint(checkpoint, continuous.session.timeline.export(), (operation) => operation); +if (recovery.status !== "recovered") console.error(JSON.stringify(recovery)); +assert.equal(recovery.status, "recovered"); +const restored = restarted.session.workspacePackageState(); +assert.equal(restored.kinematics.active_type, 1); +assert.deepEqual(restored.kinematics.joints, before.kinematics.joints); +assert.deepEqual(restored.kinematics.pose, before.kinematics.pose); +assert.equal(restored.kinematics.state_hash, before.kinematics.state_hash); +assert.equal(restored.kinematics.switch_count, switchCountBefore); +assert.equal(restored.program.source_hash, before.program.source_hash); +assert.equal(restored.motion_authority, "wasm"); +if (fnv1a64(before) !== fnv1a64(restored)) console.error(JSON.stringify({ differing: Object.fromEntries(Object.keys(before).filter((key) => fnv1a64(before[key]) !== fnv1a64(restored[key])).map((key) => [key, { before: before[key], restored: restored[key] }])) })); + +const replay = restarted.session.ledger.reconcile("switch-once"); +assert.equal(replay.status, "committed"); +assert.equal(restarted.session.xyzacKinematics.snapshot().switch_count, switchCountBefore); + +const corruptedState = structuredClone(checkpoint); +corruptedState.state.kinematics.pose.x += 1; +corruptedState.state_hash = fnv1a64(corruptedState.state); +const corrupted = restarted.session.restoreCheckpoint(corruptedState, null, (operation) => operation); +assert.equal(corrupted.status, "blocked"); +assert.equal(corrupted.blocked[0].reason, "checkpoint_hash_mismatch"); +const schemaMismatch = { ...checkpoint, schema: "simulation-checkpoint.v9" }; +const schemaBlocked = restarted.session.restoreCheckpoint(schemaMismatch, null, (operation) => operation); +assert.equal(schemaBlocked.status, "blocked"); + +const storage = new MemoryStorage(); +const journal = new WorkspaceJournal(storage, { projectId: "xyzac-recovery" }); +const prepare = journal.prepare("xyzac-journal-op", [{ path: "programs/recovery.ngc", data: SOURCE }]); +const commit = journal.commit("xyzac-journal-op"); +const journalRecovered = journal.recover(); +assert.equal(journalRecovered.status, "recovered"); +assert.equal(journalRecovered.files["programs/recovery.ngc"], SOURCE); +const journalCorrupt = new MemoryStorage(Object.fromEntries(storage.entries().map(([key, value]) => { + const record = JSON.parse(String(value)); + if (record.kind === "prepare") record.changes[0].data = `${record.changes[0].data}X`; + return [key, JSON.stringify(record)]; +}))); +assert.equal(new WorkspaceJournal(journalCorrupt, { projectId: "xyzac-recovery" }).recover().status, "blocked"); +const journalSchemaMismatch = new WorkspaceJournal(new MemoryStorage({ bad: JSON.stringify({ schema: "other.v1", schema_version: 9, project_id: "xyzac-recovery" }) }), { projectId: "xyzac-recovery" }).recover(); +assert.equal(journalSchemaMismatch.status, "blocked"); +assert.ok(prepare.content_hash && commit.prepare_hash); + +const opfsUnavailable = opfsCapability({ navigator: { storage: null } }); +assert.equal(opfsUnavailable.status, "blocked"); +const opfsProbe = await runOpfsProbe({ storage: null, projectId: "xyzac-recovery" }); +assert.equal(opfsProbe.status, "blocked"); + +console.log(JSON.stringify({ + schema: "xyzac-recovery-rtcp-11.v1", + status: "verified", + case: CASE, + checkpoint: { required_fields: ["context_id", "simulation_tick", "event_cursor", "state_hash", "task", "program", "kinematics", "motion", "wasm_motion", "ledger"], active_type: checkpoint.state.kinematics.active_type, state_hash: checkpoint.state.kinematics.state_hash }, + continuous_endpoint_hash: fnv1a64(endpoint), + restored_endpoint_hash: fnv1a64(restored), + endpoint_at_checkpoint_equal: fnv1a64(before) === fnv1a64(restored), + no_duplicate_m428: restarted.session.xyzacKinematics.snapshot().switch_count === switchCountBefore, + replayed_operation: replay.status === "committed", + corrupt_checkpoint: corrupted.status, + schema_mismatch: schemaBlocked.status, + journal: { status: journalRecovered.status, corrupt_status: "blocked", schema_status: journalSchemaMismatch.status }, + opfs: { unavailable_status: opfsUnavailable.status, probe_status: opfsProbe.status, physical_crash: "REAL-EXCLUDED" }, + first_divergent_tick: null, +})); diff --git a/web/worker/test_xyzac_rtcp.mjs b/web/worker/test_xyzac_rtcp.mjs new file mode 100644 index 0000000..48ae805 --- /dev/null +++ b/web/worker/test_xyzac_rtcp.mjs @@ -0,0 +1,168 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import createModule from "../../build-wasm/linuxcnc-sim-core.js"; +import { loadSimulationCase, toWorkerConfiguration } from "../workspace/sim-case-loader.mjs"; +import { WasmXyzacKinematics, XYZAC_MODES } from "./wasm-xyzac-kinematics.mjs"; +import { XyzacSession, CONTEXT_ID } from "./xyzac-session.mjs"; + +const CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini"; +const fetchImpl = async (url) => { + try { + const body = await readFile(new URL(`../../${String(url).replace(/^\//, "")}`, import.meta.url)); + return { ok: true, text: async () => body.toString("utf8") }; + } catch { + return { ok: false, text: async () => "" }; + } +}; +const close = (actual, expected, tolerance = 1e-9) => assert.ok(Math.abs(actual - expected) <= tolerance, `${actual} != ${expected}`); +const closeArray = (actual, expected) => actual.forEach((value, index) => close(value, expected[index])); + +const bundle = await loadSimulationCase({ path: CASE, fetchImpl }); +assert.equal(bundle.status, "ready"); +const core = await createModule({ wasmBinary: await readFile(new URL("../../build-wasm/linuxcnc-sim-core.wasm", import.meta.url)) }); +const limits = toWorkerConfiguration(bundle).home_limits; + +const kinematics = new WasmXyzacKinematics(core, { x_rot_point: 0, y_offset: 20, z_offset: 10, tool_offset: 0, limits }); +const initial = kinematics.snapshot(); +assert.equal(initial.active_type, XYZAC_MODES.identity); +assert.equal(initial.coordinates, "XYZAC"); +assert.equal(initial.linear_units, "mm"); +assert.equal(initial.angular_units, "deg"); +assert.deepEqual(initial.limits, { x: [-200, 200], y: [-100, 100], z: [-120, 120], a: [-100, 50], c: [-36000, 36000] }); + +const identityJoints = [12, -5, 20, 30, 45]; +const identityForward = kinematics.forward(identityJoints); +assert.equal(identityForward.status, "verified"); +assert.deepEqual(identityForward.pose, { x: 12, y: -5, z: 20, a: 30, b: 0, c: 45, u: 0, v: 0, w: 0 }); +const identityInverse = kinematics.inverse(identityForward.pose); +assert.equal(identityInverse.status, "verified"); +closeArray(identityInverse.joints, identityJoints); + +const rangeError = kinematics.forward([0, 0, 121, 0, 0]); +assert.equal(rangeError.code, "wasm_xyzac_forward_-702"); +const nonfiniteJoints = kinematics.forward([0, 0, Number.NaN, 0, 0]); +assert.equal(nonfiniteJoints.code, "wasm_xyzac_forward_-701"); +const nonfinitePose = kinematics.inverse({ ...identityForward.pose, x: Number.NaN }); +assert.equal(nonfinitePose.code, "wasm_xyzac_inverse_-701"); + +const selectedTrt = kinematics.select(XYZAC_MODES.xyzac, identityJoints); +assert.equal(selectedTrt.status, "verified"); +assert.equal(selectedTrt.active_type, XYZAC_MODES.xyzac); +close(selectedTrt.pose.x, identityForward.pose.x); +close(selectedTrt.pose.y, identityForward.pose.y); +close(selectedTrt.pose.z, identityForward.pose.z); +const trtJoints = [50, 10, 30, 30, 45]; +const trtForward = kinematics.forward(trtJoints); +assert.equal(trtForward.status, "verified"); +const trtInverse = kinematics.inverse(trtForward.pose); +assert.equal(trtInverse.status, "verified"); +closeArray(trtInverse.joints, trtJoints); + +const pivotBoundary = kinematics.forward([20, 5, 30, -90, 45]); +assert.equal(pivotBoundary.status, "verified"); +const pivotRoundtrip = kinematics.inverse(pivotBoundary.pose); +assert.equal(pivotRoundtrip.status, "verified"); +closeArray(pivotRoundtrip.joints, [20, 5, 30, -90, 45]); + +const tool0 = new WasmXyzacKinematics(core, { y_offset: 20, z_offset: 10, tool_offset: 0, limits }); +const tool25 = new WasmXyzacKinematics(core, { x_rot_point: 5, y_offset: 20, z_offset: 10, tool_offset: 25, limits }); +tool0.select(XYZAC_MODES.xyzac); +tool25.select(XYZAC_MODES.xyzac); +const offset0 = tool0.forward(trtJoints); +const offset25 = tool25.forward(trtJoints); +assert.equal(offset0.status, "verified"); +assert.equal(offset25.status, "verified"); +assert.notDeepEqual(offset25.pose, offset0.pose); +assert.deepEqual(offset25.offsets, { x_rot_point: 5, y_offset: 20, z_offset: 10, tool_offset: 25 }); + +const userPose = kinematics.forward(trtJoints).pose; +const userk = kinematics.select(XYZAC_MODES.userk, trtJoints); +assert.equal(userk.status, "verified"); +assert.equal(userk.native_type, "userk-identity-template"); +close(userk.pose.x, userPose.x); +close(userk.pose.y, userPose.y); +close(userk.pose.z, userPose.z); +const path = new TextEncoder().encode("/tmp/dynamic-userk.so\0"); +const pathPointer = core._malloc(path.length); +core.HEAPU8.set(path, pathPointer); +assert.equal(core._sim_kinematics_user_reject_dynamic(pathPointer), -712); +core._free(pathPointer); + +const session = new XyzacSession(core, { sessionId: "xyzac-rtcp" }); +const base = { schema_version: 1, context_id: CONTEXT_ID, session_id: session.sessionId }; +let seq = 0; +const send = (kind, operationId, payload = {}) => session.accept({ ...base, kind, seq: ++seq, operation_id: operationId, payload }); +send("HELLO", "hello"); +send("SESSION_ATTACH", "attach"); +assert.equal(send("LOAD_WORKSPACE", "workspace", { root_path: "/workspace", configuration: toWorkerConfiguration(bundle) }).payload.status, "verified"); + +const switchRows = []; +for (const [code, expected] of [["M429", 0], ["M428", 1], ["M430", 2], ["M428", 1]]) { + const switched = send("MDI_EXECUTE", `switch-${code}-${seq}`, { block: code }); + assert.equal(switched.kind, "COMMAND_RESULT"); + assert.equal(switched.payload.kinematics.active_type, expected); + assert.equal(switched.payload.remap.hal_pin, "motion.switchkins-type"); + assert.equal(switched.payload.remap.sync, "M66 E0 L0"); + switchRows.push({ code, active_type: expected, state_hash: switched.payload.kinematics.state_hash }); +} + +const helixSource = "G21 G90 G94\nG0 X10 Y0 Z10 A0 C0\nG93\nG2 X10 Y0 Z5 A30 C45 I-10 J0 P3 F2\nM2\n"; +const helixLoad = send("PROGRAM_LOAD", "helix-load", { source: helixSource, path: "remap_subs/helix_ac-rtcp.ngc" }); +assert.equal(helixLoad.kind, "COMMAND_RESULT"); +const helix = helixLoad.payload.preview.segments.find((segment) => segment.motion_type === 2); +assert.ok(helix); +assert.equal(helix.turn, -3); +assert.equal(helix.end.a, 30); +assert.equal(helix.end.c, 45); +assert.equal(helix.end.z, 5); +assert.ok(Number.isFinite(helix.velocity) && helix.velocity > 0); + +const recoveryPose = session.xyzacKinematics.forward([20, 5, 30, -90, 45]); +assert.equal(recoveryPose.status, "verified"); +const run = send("PROGRAM_RUN", "helix-run"); +assert.equal(run.payload.panel_snapshot.kinematics.active_type, 1); +send("SIM_STEP", "helix-step", { cycles: 1 }); +const paused = send("PROGRAM_PAUSE", "helix-pause"); +assert.equal(paused.payload.panel_snapshot.kinematics.active_type, 1); +const resumed = send("PROGRAM_RESUME", "helix-resume"); +assert.equal(resumed.payload.panel_snapshot.kinematics.active_type, 1); +send("SIM_STEP", "helix-step-2", { cycles: 1 }); +const aborted = send("PROGRAM_ABORT", "helix-abort"); +assert.equal(aborted.payload.panel_snapshot.kinematics.active_type, 1); +const restarted = send("PROGRAM_RESTART", "helix-restart"); +assert.equal(restarted.payload.panel_snapshot.kinematics.active_type, 1); + +const beforeCheckpoint = session.xyzacKinematics.snapshot(); +const checkpoint = send("CHECKPOINT", "rtcp-checkpoint"); +assert.equal(checkpoint.kind, "CHECKPOINT_READY"); +assert.equal(checkpoint.payload.checkpoint.state.kinematics.state_hash, beforeCheckpoint.state_hash); +const changed = send("MDI_EXECUTE", "switch-after-checkpoint", { block: "M429" }); +assert.equal(changed.payload.kinematics.active_type, 0); +close(changed.payload.kinematics.pose.x, beforeCheckpoint.pose.x); +close(changed.payload.kinematics.pose.y, beforeCheckpoint.pose.y); +close(changed.payload.kinematics.pose.z, beforeCheckpoint.pose.z); +const recovered = send("RECOVER", "rtcp-recover", { checkpoint: checkpoint.payload.checkpoint }); +assert.equal(recovered.payload.status, "recovered"); +assert.equal(recovered.payload.state.kinematics.active_type, 1); +assert.deepEqual(recovered.payload.state.kinematics.pose, beforeCheckpoint.pose); +assert.deepEqual(recovered.payload.state.kinematics.joints, beforeCheckpoint.joints); +assert.equal(recovered.payload.state.kinematics.state_hash, beforeCheckpoint.state_hash); + +console.log(JSON.stringify({ + schema: "xyzac-rtcp-08.v1", + status: "verified", + case: CASE, + mapping: { coordinates: initial.coordinates, linear_units: initial.linear_units, angular_units: initial.angular_units, limits: initial.limits }, + identity: { pose: identityForward.pose, state_hash: identityInverse.state_hash }, + trt: { pose: trtForward.pose, joints: trtInverse.joints, pivot_boundary: pivotBoundary.pose, state_hash: trtInverse.state_hash }, + offsets: { base: offset0.pose, changed: offset25.pose, configured: offset25.offsets }, + userk: { native_type: userk.native_type, dynamic_module_error: -712 }, + switchkins: switchRows, + helix: { turn: helix.turn, end: helix.end, velocity: helix.velocity, motion_type: helix.motion_type }, + boundaries: { range: rangeError.code, nonfinite_joints: nonfiniteJoints.code, nonfinite_pose: nonfinitePose.code, xyzac_singularity: "closed_form_no_singular_branch" }, + lifecycle: { pause: paused.payload.task.state, resume: resumed.payload.task.state, abort: aborted.payload.task.state, restart: restarted.payload.task.program_status, recovery: recovered.payload.status }, + recovery: { active_type: recovered.payload.state.kinematics.active_type, state_hash: recovered.payload.state.kinematics.state_hash }, + first_divergent_tick: null, +})); + +for (const value of [kinematics, tool0, tool25]) value.destroy(); diff --git a/web/worker/test_xyzac_session.mjs b/web/worker/test_xyzac_session.mjs new file mode 100644 index 0000000..a4c2258 --- /dev/null +++ b/web/worker/test_xyzac_session.mjs @@ -0,0 +1,71 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import createModule from "../../build-wasm/linuxcnc-sim-core.js"; +import { XyzacSession, CONTEXT_ID } from "./xyzac-session.mjs"; +import { XyzacCommandLedger } from "./xyzac-command-ledger.mjs"; +import { XYZAC_SCHEDULER_PHASES } from "./xyzac-scheduler.mjs"; +import { loadSimulationCase, toWorkerConfiguration } from "../workspace/sim-case-loader.mjs"; + +const CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini"; +const fetchImpl = async (url) => { + try { const body = await readFile(new URL(`../../${String(url).replace(/^\//, "")}`, import.meta.url)); return { ok: true, text: async () => body.toString("utf8") }; } + catch { return { ok: false, text: async () => "" }; } +}; +const bundle = await loadSimulationCase({ path: CASE, fetchImpl }); +assert.equal(bundle.status, "ready"); +const core = await createModule({ wasmBinary: await readFile(new URL("../../build-wasm/linuxcnc-sim-core.wasm", import.meta.url)) }); +const session = new XyzacSession(core, { sessionId: "xyzac-rtcp-01" }); +const base = { schema_version: 1, context_id: CONTEXT_ID, session_id: session.sessionId }; +let seq = 0; +const send = (kind, operation_id, payload = {}) => session.accept({ ...base, kind, seq: ++seq, operation_id, payload }); + +const hello = send("HELLO", "hello"); +assert.equal(hello.kind, "CAPABILITIES"); +assert.equal(hello.payload.xyzac_session.scope, "selected_xyzac_simulation"); +assert.equal(hello.payload.xyzac_session.machine.joint_count, 5); +assert.deepEqual(hello.payload.xyzac_scheduler.phase_trace, XYZAC_SCHEDULER_PHASES); +assert.equal(hello.payload.xyzac_ledger.pending_count, 0); + +const attached = send("SESSION_ATTACH", "attach"); +assert.equal(attached.kind, "SESSION_READY"); +const loaded = send("LOAD_WORKSPACE", "workspace", { root_path: "/workspace", configuration: toWorkerConfiguration(bundle) }); +assert.equal(loaded.payload.status, "verified"); +assert.equal(loaded.payload.xyzac_session.authority, "linuxcnc-wasm-worker"); + +const step = send("SIM_STEP", "step-1", { cycles: 3 }); +assert.equal(step.payload.status, "verified"); +assert.equal(step.payload.xyzac_scheduler.tick, 3); +assert.equal(step.payload.xyzac_scheduler.clock, "logical_tick"); +assert.equal(session.ledger.reconcile("step-1").status, "committed"); +const replay = session.accept({ ...base, kind: "SIM_STEP", seq: ++seq, operation_id: "step-1", payload: { cycles: 99 } }); +assert.equal(replay.replayed, true); +assert.equal(session.scheduler.tick, 3); +const cancelCommitted = send("CANCEL", "cancel-step", { operation_id: "step-1", reason: "late_cancel" }); +assert.equal(cancelCommitted.payload.retry_allowed, false); +assert.equal(cancelCommitted.payload.ledger.status, "too_late"); + +const gap = session.accept({ ...base, kind: "SNAPSHOT_REQUEST", seq: ++seq + 1, payload: {} }); +assert.equal(gap.kind, "ERROR"); +assert.equal(gap.payload.code, "protocol_sequence"); + +const ledger = new XyzacCommandLedger(); +ledger.prepare({ schema_version: 1, context_id: CONTEXT_ID, session_id: "ledger", kind: "PROGRAM_RUN", seq: 1, operation_id: "pending-run", payload: {} }); +ledger.execute("pending-run"); +assert.equal(ledger.pending().length, 1); +assert.equal(ledger.reconcileAll()[0].status, "executing"); +assert.equal(ledger.timeoutReconcile("pending-run").retry_allowed, false); +assert.equal(ledger.abort("pending-run").status, "aborted"); +assert.equal(ledger.pending().length, 0); +assert.equal(ledger.audit().scope, "selected_xyzac_simulation"); + +console.log(JSON.stringify({ + schema: "xyzac-session-rtcp-01.v1", + status: "verified", + case: CASE, + authority: session.authority(), + tick: session.scheduler.tick, + replayed: replay.replayed === true, + committed: session.ledger.reconcile("step-1").status, + pending_after_abort: ledger.pending().length, + state_hash: step.payload.xyzac_scheduler.state_hash, +})); diff --git a/web/worker/test_xyzac_startup.mjs b/web/worker/test_xyzac_startup.mjs new file mode 100644 index 0000000..1876488 --- /dev/null +++ b/web/worker/test_xyzac_startup.mjs @@ -0,0 +1,34 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import createModule from "../../build-wasm/linuxcnc-sim-core.js"; +import { loadXyzacTrtCase, XYZAC_TRT_CASE, XYZAC_TRT_STARTUP_STATES } from "../workspace/xyzac-trt-case-loader.mjs"; +import { XyzacSession, CONTEXT_ID } from "./xyzac-session.mjs"; + +const fetchImpl = async (url) => { + try { const body = await readFile(new URL(`../../${String(url).replace(/^\//, "")}`, import.meta.url)); return { ok: true, text: async () => body.toString("utf8") }; } + catch { return { ok: false, text: async () => "" }; } +}; +const core = await createModule({ wasmBinary: await readFile(new URL("../../build-wasm/linuxcnc-sim-core.wasm", import.meta.url)) }); +const loaded = await loadXyzacTrtCase({ fetchImpl, core }); +assert.equal(loaded.status, "ready"); +assert.equal(loaded.case, XYZAC_TRT_CASE); +assert.equal(loaded.startup.status, "ready"); +assert.equal(loaded.startup.state, "TASK_READY"); +assert.deepEqual(loaded.startup.transitions.map((row) => row.to), XYZAC_TRT_STARTUP_STATES); +assert.deepEqual(loaded.required_sections, { DISPLAY: true, TASK: true, HAL: true, RS274NGC: true, KINS: true, TRAJ: true, EMCIO: true }); +assert.equal(loaded.machine.coordinates, "XYZAC"); +assert.equal(loaded.machine.joint_count, 5); +assert.equal(loaded.machine.rotary_units, "degrees"); +assert.equal(loaded.machine.kinematics, "xyzac-trt"); +const roles = new Map(loaded.exact_resources.map((row) => [row.role, row])); +for (const role of ["case_entrypoint", "pyvcp", "postgui_hal", "tool_table", "parameter_file", "open_file", "remap_m428", "remap_m429", "remap_m430", "ngcgui_subfile", "rtcp_subroutine", "vismach_source", "hal_library", "intro_graphic"]) assert.equal(roles.get(role)?.status, "resolved", role); +assert.ok(loaded.exact_resources.every((row) => row.data_hash)); +assert.ok(loaded.startup.hal.record_count > 0); +const missing = await loadXyzacTrtCase({ fetchImpl: async (url) => String(url).endsWith("xyzac-trt.xml") ? { ok: false, text: async () => "" } : fetchImpl(url), core }); +assert.equal(missing.status, "blocked"); +assert.ok(missing.missing.includes("linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.xml")); +const session = new XyzacSession(core, { sessionId: "startup-session" }); +const base = { schema_version: 1, context_id: CONTEXT_ID, session_id: session.sessionId }; +const attach = session.accept({ ...base, kind: "HELLO", seq: 1, operation_id: "hello", payload: {} }); +assert.equal(attach.payload.xyzac_session.machine.coordinates, "XYZAC"); +console.log(JSON.stringify({ schema: "xyzac-trt-startup-rtcp-02.v1", status: "verified", case: XYZAC_TRT_CASE, startup: loaded.startup, exact_resource_count: loaded.exact_resources.length, fetched_count: loaded.fetched.length, missing_case_status: missing.status, state_hash: loaded.state_hash })); diff --git a/web/worker/test_xyzac_trace_parity.mjs b/web/worker/test_xyzac_trace_parity.mjs new file mode 100644 index 0000000..fcd6415 --- /dev/null +++ b/web/worker/test_xyzac_trace_parity.mjs @@ -0,0 +1,62 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import createModule from "../../build-wasm/linuxcnc-sim-core.js"; +import { loadSimulationCase, toWorkerConfiguration } from "../workspace/sim-case-loader.mjs"; +import { XyzacSession, CONTEXT_ID } from "./xyzac-session.mjs"; + +const CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini"; +const COMMANDS = [["M429", 0], ["M428", 1], ["M430", 2], ["M428", 1]]; +const HELIX = "G21 G90 G94\nG0 X10 Y0 Z10 A0 C0\nG93\nG2 X10 Y0 Z5 A30 C45 I-10 J0 P3 F2\nM2\n"; +const fetchImpl = async (url) => { + try { + const body = await readFile(new URL(`../../${String(url).replace(/^\//, "")}`, import.meta.url)); + return { ok: true, text: async () => body.toString("utf8") }; + } catch { + return { ok: false, text: async () => "" }; + } +}; +const selectedPose = (value) => ({ a: value.a, c: value.c, x: value.x, y: value.y, z: value.z }); + +const bundle = await loadSimulationCase({ path: CASE, fetchImpl }); +assert.equal(bundle.status, "ready"); +const core = await createModule({ wasmBinary: await readFile(new URL("../../build-wasm/linuxcnc-sim-core.wasm", import.meta.url)) }); +const session = new XyzacSession(core, { sessionId: "xyzac-trace-parity" }); +const base = { schema_version: 1, context_id: CONTEXT_ID, session_id: session.sessionId }; +let seq = 0; +const send = (kind, operationId, payload = {}) => session.accept({ ...base, kind, seq: ++seq, operation_id: operationId, payload }); + +assert.equal(send("HELLO", "hello").kind, "CAPABILITIES"); +assert.equal(send("SESSION_ATTACH", "attach").kind, "SESSION_READY"); +assert.equal(send("LOAD_WORKSPACE", "workspace", { root_path: "/workspace", configuration: toWorkerConfiguration(bundle) }).payload.status, "verified"); +assert.equal(session.xyzacKinematics.forward([12, -5, 20, 30, 45]).status, "verified"); + +const levels = { protocol: [], control: [], state: [], canonical: [], recovery: [] }; +for (const [index, [command, activeType]] of COMMANDS.entries()) { + const result = send("MDI_EXECUTE", `switch-${index + 1}`, { block: command }); + const kinematics = result.payload.kinematics; + const tick = index + 1; + assert.equal(result.kind, "COMMAND_RESULT"); + assert.equal(result.payload.status, "verified"); + assert.equal(kinematics.active_type, activeType); + levels.protocol.push({ command, result: "verified", seq: result.seq, tick }); + levels.control.push({ active_type: activeType, command, hal_pin: result.payload.remap.hal_pin, tick }); + levels.state.push({ active_type: activeType, joints: kinematics.joints, pose: selectedPose(kinematics.pose), tick }); +} + +const loaded = send("PROGRAM_LOAD", "helix-load", { source: HELIX, path: "remap_subs/helix_ac-parity.ngc" }); +assert.equal(loaded.kind, "COMMAND_RESULT"); +const arc = loaded.payload.preview.segments.find((segment) => segment.motion_type === 2); +assert.ok(arc); +levels.canonical.push({ end: selectedPose(arc.end), motion_type: arc.motion_type, source_line: arc.source_line, tick: 5, turn: arc.turn, velocity: arc.velocity }); + +const before = session.xyzacKinematics.snapshot(); +const checkpoint = send("CHECKPOINT", "parity-checkpoint").payload.checkpoint; +assert.equal(checkpoint.state.kinematics.state_hash, before.state_hash); +assert.equal(send("MDI_EXECUTE", "parity-change", { block: "M429" }).payload.kinematics.active_type, 0); +const recovered = send("RECOVER", "parity-recover", { checkpoint }); +assert.equal(recovered.payload.status, "recovered"); +const after = recovered.payload.state.kinematics; +levels.recovery.push({ active_type: after.active_type, joints_equal: JSON.stringify(after.joints) === JSON.stringify(before.joints), pose_equal: JSON.stringify(after.pose) === JSON.stringify(before.pose), state_hash_equal: after.state_hash === before.state_hash, tick: 6 }); +assert.deepEqual(levels.recovery[0], { active_type: 1, joints_equal: true, pose_equal: true, state_hash_equal: true, tick: 6 }); + +console.log(JSON.stringify({ case: "xyzac-trt.ini", levels, schema: "xyzac-structured-trace.v1", source: "linuxcnc-wasm-worker", status: "verified" })); diff --git a/web/worker/test_xyzac_trt_case.mjs b/web/worker/test_xyzac_trt_case.mjs new file mode 100644 index 0000000..704c995 --- /dev/null +++ b/web/worker/test_xyzac_trt_case.mjs @@ -0,0 +1,75 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import createModule from "../../build-wasm/linuxcnc-sim-core.js"; +import { loadSimulationCase, toWorkerConfiguration } from "../workspace/sim-case-loader.mjs"; +import { XYZAC_TRT_SOURCE_SLICES } from "../workspace/xyzac-trt-source-slices.mjs"; +import { SimSession, CONTEXT_ID } from "./sim-session.mjs"; + +const CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini"; +const fetchImpl = async (url) => { + try { + const body = await readFile(new URL(`../../${String(url).replace(/^\//, "")}`, import.meta.url)); + return { ok: true, text: async () => body.toString("utf8") }; + } catch { + return { ok: false, text: async () => "" }; + } +}; + +const bundle = await loadSimulationCase({ path: CASE, fetchImpl }); +assert.equal(bundle.status, "ready"); +assert.deepEqual(bundle.missing, []); +assert.ok(bundle.runtime_fixtures.some((fixture) => fixture.generated_hal?.endsWith("xyzac-trt-headless_cmds.hal"))); + +const core = await createModule({ wasmBinary: await readFile(new URL("../../build-wasm/linuxcnc-sim-core.wasm", import.meta.url)) }); +const session = new SimSession(core, { sessionId: "xyzac-trt-case" }); +const base = { schema_version: 1, context_id: CONTEXT_ID, session_id: session.sessionId }; +let seq = 0; +const send = (kind, operationId, payload = {}) => session.accept({ ...base, kind, seq: ++seq, operation_id: operationId, payload }); + +send("HELLO", "hello"); +send("SESSION_ATTACH", "attach"); +const loaded = send("LOAD_WORKSPACE", "workspace", { root_path: "/workspace", configuration: toWorkerConfiguration(bundle) }); +assert.equal(loaded.kind, "COMMAND_RESULT"); +assert.equal(loaded.payload.status, "verified"); +assert.equal(loaded.payload.motion_authority, "wasm"); +assert.equal(loaded.payload.configuration.state, "TASK_READY"); +assert.equal(loaded.payload.panel_snapshot.kinematics.joint_count, 5); + +const switchRows = []; +for (const [code, expected] of [["M429", 0], ["M428", 1], ["M430", 2]]) { + const result = send("MDI_EXECUTE", `mdi-${code}`, { block: code }); + assert.equal(result.kind, "COMMAND_RESULT"); + assert.equal(result.payload.status, "verified"); + assert.equal(result.payload.kinematics.active_type, expected); + assert.equal(result.payload.remap.hal_pin, "motion.switchkins-type"); + assert.equal(result.payload.remap.sync, "M66 E0 L0"); + switchRows.push({ code, tick: result.simulation_tick, active_type: expected, state_hash: result.payload.panel_snapshot.state_hash }); +} + +const pose = session.xyzacKinematics.forward([100, 50, 100, 30, 45]); +assert.equal(pose.status, "verified"); +assert.equal(pose.joint_count, 5); +assert.ok(Number.isFinite(pose.pose.x) && Number.isFinite(pose.pose.y) && Number.isFinite(pose.pose.z)); + +const sourceSliceIds = new Set(XYZAC_TRT_SOURCE_SLICES.slices.map((slice) => slice.slice_id)); +const controls = [ + ...XYZAC_TRT_SOURCE_SLICES.axis_controls.menus, + ...XYZAC_TRT_SOURCE_SLICES.axis_controls.toolbar, + ...XYZAC_TRT_SOURCE_SLICES.axis_controls.keyboard_bindings, +]; +assert.ok(controls.length >= 110); +assert.ok(controls.every((control) => sourceSliceIds.has(control.slice_id))); + +console.log(JSON.stringify({ + schema: "xyzac-trt-wasm-worker-trace.v1", + status: "verified", + case: CASE, + configuration: loaded.payload.configuration.state, + motion_authority: loaded.payload.motion_authority, + control_count: controls.length, + switchkins: switchRows, + pose: pose.pose, + wasm_state_hash: pose.wasm_state_hash, + state_hash: pose.state_hash, + first_divergent_tick: null, +})); diff --git a/web/worker/test_xyzac_trt_io_authority.mjs b/web/worker/test_xyzac_trt_io_authority.mjs new file mode 100644 index 0000000..a5fd2cd --- /dev/null +++ b/web/worker/test_xyzac_trt_io_authority.mjs @@ -0,0 +1,53 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import createModule from "../../build-wasm/linuxcnc-sim-core.js"; +import { loadSimulationCase, toWorkerConfiguration } from "../workspace/sim-case-loader.mjs"; +import { SimSession, CONTEXT_ID } from "./sim-session.mjs"; + +const CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini"; +const fetchImpl = async (url) => { + try { const body = await readFile(new URL(`../../${String(url).replace(/^\//, "")}`, import.meta.url)); return { ok: true, text: async () => body.toString("utf8") }; } + catch { return { ok: false, text: async () => "" }; } +}; +const bundle = await loadSimulationCase({ path: CASE, fetchImpl }); +assert.equal(bundle.status, "ready"); +const core = await createModule({ wasmBinary: await readFile(new URL("../../build-wasm/linuxcnc-sim-core.wasm", import.meta.url)) }); +const session = new SimSession(core, { sessionId: "xyzac-io-authority" }); +const base = { schema_version: 1, context_id: CONTEXT_ID, session_id: session.sessionId }; +let seq = 0; +const send = (kind, operation_id, payload = {}) => session.accept({ ...base, kind, seq: ++seq, operation_id, payload }); +send("HELLO", "hello"); +send("SESSION_ATTACH", "attach"); +const loaded = send("LOAD_WORKSPACE", "workspace", { root_path: "/workspace", configuration: toWorkerConfiguration(bundle) }); +assert.equal(loaded.payload.status, "verified"); +assert.equal(loaded.payload.panel_snapshot.io.source, "wasm_io"); +assert.equal(loaded.payload.panel_snapshot.device_io.source, "wasm_device_io"); +assert.equal(loaded.payload.panel_snapshot.hal.runtime.source, "wasm_hal"); + +const spindle = send("SPINDLE_COMMAND", "spindle-on", { spindle: 0, rpm: 1200, enabled: true }); +assert.equal(spindle.kind, "COMMAND_RESULT"); +assert.equal(spindle.payload.device_io.source, "wasm_io"); +assert.equal(spindle.payload.device_io.state.spindles[0].command_rpm, 1200); +const prepared = send("TOOL_PREPARE", "tool-prepare", { tool: 7, pocket: 3 }); +assert.equal(prepared.payload.device_io.source, "wasm_io"); +assert.equal(send("TOOL_PREPARED", "tool-prepared", { prepared: true }).payload.status, "verified"); +assert.equal(send("SPINDLE_COMMAND", "spindle-off", { spindle: 0, rpm: 0, enabled: false }).payload.status, "verified"); +assert.equal(send("TOOL_CHANGE", "tool-change").payload.status, "verified"); +assert.equal(send("TOOL_CHANGED", "tool-changed", { changed: true }).payload.status, "verified"); +assert.equal(send("PROBE_CONFIG", "probe-arm", { probe_type: 0 }).payload.status, "verified"); +const probe = session.xyzacIo.probeUpdate({ x: 10, y: 20, z: 30, a: 30, c: 45 }, 1); +assert.equal(probe.status, "verified"); +const hal = send("HAL_SET", "hal-probe", { target: "pin", name: "motion.probe-input", type: "bit", value: true }); +assert.equal(hal.kind, "COMMAND_RESULT"); +assert.equal(hal.payload.hal_runtime.source, "wasm_hal"); +assert.equal((send("SIM_STEP", "io-step", { cycles: 1 }).payload.panel_snapshot.io ?? loaded.payload.panel_snapshot.io).source, "wasm_io"); +assert.equal(send("SNAPSHOT_REQUEST", "device-snapshot").payload.panel_snapshot.device_io.source, "wasm_device_io"); +const estop = send("ESTOP", "io-estop", { active: true }); +assert.equal(estop.payload.device_io.source, "wasm_io"); +const blocked = send("SPINDLE_COMMAND", "spindle-blocked", { spindle: 0, rpm: 500, enabled: true }); +assert.equal(blocked.kind, "ERROR"); +assert.equal(send("IO_RECOVER", "io-recover").payload.device_io.source, "wasm_io"); +const firstHash = send("SNAPSHOT_REQUEST", "snapshot-a").payload.panel_snapshot.device_io.projection_hash; +const secondHash = send("SNAPSHOT_REQUEST", "snapshot-b").payload.panel_snapshot.device_io.projection_hash; +assert.equal(firstHash, secondHash); +console.log(JSON.stringify({ schema: "xyzac-trt-wasm-io-authority.v1", status: "verified", case: CASE, sources: ["wasm_io", "wasm_hal"], tool: 7, probe: true, estop_gate: "verified", state_hash: firstHash })); diff --git a/web/worker/test_xyzac_trt_wasm_program_authority.mjs b/web/worker/test_xyzac_trt_wasm_program_authority.mjs new file mode 100644 index 0000000..be94946 --- /dev/null +++ b/web/worker/test_xyzac_trt_wasm_program_authority.mjs @@ -0,0 +1,52 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import createModule from "../../build-wasm/linuxcnc-sim-core.js"; +import { loadSimulationCase, toWorkerConfiguration } from "../workspace/sim-case-loader.mjs"; +import { SimSession, CONTEXT_ID } from "./sim-session.mjs"; + +const CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini"; +const fetchImpl = async (url) => { try { const body = await readFile(new URL(`../../${String(url).replace(/^\//, "")}`, import.meta.url)); return { ok: true, text: async () => body.toString("utf8") }; } catch { return { ok: false, text: async () => "" }; } }; +const bundle = await loadSimulationCase({ path: CASE, fetchImpl }); +const core = await createModule({ wasmBinary: await readFile(new URL("../../build-wasm/linuxcnc-sim-core.wasm", import.meta.url)) }); +const session = new SimSession(core, { sessionId: "xyzac-program-authority" }); +const base = { schema_version: 1, context_id: CONTEXT_ID, session_id: session.sessionId }; +let seq = 0; +const send = (kind, operation_id, payload = {}) => session.accept({ ...base, kind, seq: ++seq, operation_id, payload }); +send("HELLO", "hello"); +send("SESSION_ATTACH", "attach"); +assert.equal(send("LOAD_WORKSPACE", "workspace", { root_path: "/workspace", configuration: toWorkerConfiguration(bundle) }).payload.status, "verified"); +const home = send("HOME", "home"); +assert.equal(home.payload.motion_authority, "wasm"); +assert.equal(home.payload.wasm_home_limit.state.homed, true); +const jog = send("JOG_START", "jog", { axis: "x", direction: 1, speed: 1, increment: 2 }); +assert.equal(jog.payload.motion_authority, "wasm"); +assert.equal(send("SIM_STEP", "jog-step", { cycles: 1 }).payload.motion_authority, "wasm"); +assert.equal(send("JOG_STOP", "jog-stop").payload.motion_authority, "wasm"); +const source = "G21 G90\nG1 X10 Y5 Z-2 A30 C45 F100\nM2\n"; +const loaded = send("PROGRAM_LOAD", "program-load", { source, path: "authority.ngc" }); +assert.equal(loaded.kind, "COMMAND_RESULT"); +assert.equal(loaded.payload.motion_authority, "wasm"); +assert.equal(loaded.payload.program.source, "linuxcnc-wasm-sim_program"); +const run = send("PROGRAM_RUN", "program-run"); +assert.equal(run.payload.program.source, "linuxcnc-wasm-sim_program"); +assert.equal(run.payload.task_authority, "wasm_task_canonical"); +const step = send("SIM_STEP", "program-step", { cycles: 1 }); +assert.equal(step.payload.motion_authority, "wasm"); +assert.ok(step.payload.program_steps.length >= 1); +const wasmSegment = step.payload.wasm_motion; +assert.equal(wasmSegment.status, "verified"); +assert.ok(wasmSegment.state.queue_depth >= 0); +const blocked = send("PROGRAM_PAUSE", "pause"); +assert.equal(blocked.payload.program.source, "linuxcnc-wasm-sim_program"); +const resumed = send("PROGRAM_RESUME", "resume"); +assert.equal(resumed.payload.program.source, "linuxcnc-wasm-sim_program"); +const aborted = send("PROGRAM_ABORT", "abort"); +assert.equal(aborted.payload.program.source, "linuxcnc-wasm-sim_program"); +assert.equal(session.xyzacProgram.source, source); +const checkpoint = send("CHECKPOINT", "checkpoint"); +assert.equal(checkpoint.kind, "CHECKPOINT_READY"); +const recovered = send("RECOVER", "recover", { checkpoint: checkpoint.payload.checkpoint }); +assert.equal(recovered.kind, "RECOVERY_STATUS"); +assert.equal(recovered.payload.status, "recovered"); +assert.equal(session.xyzacProgram.source, source); +console.log(JSON.stringify({ schema: "xyzac-trt-wasm-program-authority.v1", status: "verified", case: CASE, program_source: "linuxcnc-wasm-sim_program", task_authority: "wasm_task_canonical", motion_authority: "wasm", state_hash: aborted.payload.panel_snapshot.state_hash })); diff --git a/web/worker/test_xyzac_workflow.mjs b/web/worker/test_xyzac_workflow.mjs new file mode 100644 index 0000000..4c646ed --- /dev/null +++ b/web/worker/test_xyzac_workflow.mjs @@ -0,0 +1,57 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import createModule from "../../build-wasm/linuxcnc-sim-core.js"; +import { loadSimulationCase, toWorkerConfiguration } from "../workspace/sim-case-loader.mjs"; +import { XyzacSession, CONTEXT_ID } from "./xyzac-session.mjs"; + +const CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini"; +const fetchImpl = async (url) => { try { const body = await readFile(new URL(`../../${String(url).replace(/^\//, "")}`, import.meta.url)); return { ok: true, text: async () => body.toString("utf8") }; } catch { return { ok: false, text: async () => "" }; } }; +const bundle = await loadSimulationCase({ path: CASE, fetchImpl }); +const core = await createModule({ wasmBinary: await readFile(new URL("../../build-wasm/linuxcnc-sim-core.wasm", import.meta.url)) }); +const session = new XyzacSession(core, { sessionId: "xyzac-workflow" }); +const base = { schema_version: 1, context_id: CONTEXT_ID, session_id: session.sessionId }; +let seq = 0; +const send = (kind, operation_id, payload = {}) => session.accept({ ...base, kind, seq: ++seq, operation_id, payload }); +send("HELLO", "hello"); send("SESSION_ATTACH", "attach"); +assert.equal(send("LOAD_WORKSPACE", "workspace", { root_path: "/workspace", configuration: toWorkerConfiguration(bundle) }).payload.status, "verified"); +const source = "G21 G90\nG0 X10 Y5 Z200 A30 C45\nG1 X20 Y10 Z180 A35 C50 F100\nG1 X30 Y15 Z160 A40 C55 F100\nM2\n"; +const loaded = send("PROGRAM_LOAD", "program-load", { source, path: "workflow.ngc" }); +assert.equal(loaded.kind, "COMMAND_RESULT"); +const runWithout = send("PROGRAM_RUN", "run"); +assert.equal(runWithout.payload.task.state, "RUNNING"); +const first = send("SIM_STEP", "step-1", { cycles: 1 }); +assert.equal(first.payload.motion_authority, "wasm"); +const tickAfterFirst = first.simulation_tick; +const paused = send("PROGRAM_PAUSE", "pause"); +assert.equal(paused.payload.task.state, "PAUSED"); +const cursorPaused = paused.payload.program.current_line; +const pausedSnapshot = send("SNAPSHOT_REQUEST", "paused-snapshot"); +assert.equal(pausedSnapshot.payload.task.state, "PAUSED"); +assert.equal(pausedSnapshot.payload.panel_snapshot.program.current_line, cursorPaused); +const resumed = send("PROGRAM_RESUME", "resume"); +assert.equal(resumed.payload.task.state, "RUNNING"); +const second = send("SIM_STEP", "step-2", { cycles: 1 }); +assert.ok(second.simulation_tick > tickAfterFirst); +const activeBeforeAbort = second.payload.wasm_motion.state.active_id; +const aborted = send("PROGRAM_ABORT", "abort"); +assert.equal(aborted.payload.task.state, "STOPPED"); +assert.equal(aborted.payload.panel_snapshot.wasm_motion.state.queue_depth, 0); +assert.equal(aborted.payload.panel_snapshot.wasm_motion.state.active_id, 0); +const restart = send("PROGRAM_RESTART", "restart"); +assert.equal(restart.payload.task.program_status, "loaded"); +assert.equal(restart.payload.program.path, "workflow.ngc"); +assert.equal(restart.payload.program.source_hash, loaded.payload.program.source_hash); +const seek = send("PROGRAM_SEEK", "seek-line", { line: 3 }); +assert.equal(seek.payload.task.program_status, "paused"); +assert.equal(seek.payload.program.current_line, 3); +const runLine = send("PROGRAM_RESUME", "run-from-line"); +assert.equal(runLine.payload.task.state, "RUNNING"); +const lineStep = send("SIM_STEP", "run-line-step", { cycles: 1 }); +assert.equal(lineStep.payload.motion_authority, "wasm"); +const checkpoint = send("CHECKPOINT", "checkpoint"); +assert.equal(checkpoint.kind, "CHECKPOINT_READY"); +const recovered = send("RECOVER", "recover", { checkpoint: checkpoint.payload.checkpoint }); +assert.equal(recovered.payload.status, "recovered"); +assert.equal(recovered.payload.state.program.source_text, source); +assert.equal(session.ledger.reconcile("step-1").status, "committed"); +console.log(JSON.stringify({ schema: "xyzac-workflow-rtcp-05.v1", status: "verified", case: CASE, tick_after_first: tickAfterFirst, active_before_abort: activeBeforeAbort, pause_cursor: cursorPaused, restart_source_hash: restart.payload.program.source_hash, run_from_line: lineStep.payload.program.current_line, recovery: recovered.payload.status, final_state_hash: lineStep.payload.panel_snapshot.state_hash })); diff --git a/web/worker/wasm-home-limit.mjs b/web/worker/wasm-home-limit.mjs index b160e7c..9addf7d 100644 --- a/web/worker/wasm-home-limit.mjs +++ b/web/worker/wasm-home-limit.mjs @@ -2,12 +2,13 @@ import { fnv1a64 } from "./replay.mjs"; const HOME_LIMIT_SCHEMA = "sim_home_limit_state.v1"; const KIN_TYPE_TRIVKINS = 1; +const KIN_TYPE_XYZAC_TRT = 2; const KIN_CONFIG_SIZE = 1608; const KIN_SIZE = 1760; const HOME_LIMIT_SIZE = 184; const HOME_STATE_SIZE = 176; const HOME_STATE_OFFSET = 8; -const CONFIG_OFFSETS = Object.freeze({ type: 0, mode: 4, joint_count: 8, kinematics_joint_count: 12, extra_joint_count: 16, coordinates: 20, limit_enabled: 1448, joint_min: 1464, joint_max: 1536 }); +const CONFIG_OFFSETS = Object.freeze({ type: 0, mode: 4, joint_count: 8, kinematics_joint_count: 12, extra_joint_count: 16, coordinates: 20, x_rot_point: 40, y_offset: 72, z_offset: 80, tool_offset: 88, limit_enabled: 1448, joint_min: 1464, joint_max: 1536 }); const HOME_STATE_OFFSETS = Object.freeze({ pose: 0, joints: 72, joint_count: 144, homed: 148, home_sequence: 152, tick: 156, last_error: 160, limit_error: 164, kinematics_error: 168 }); function call(core, name, returnType, argTypes, args) { @@ -40,10 +41,13 @@ function finitePose(value) { } export class WasmHomeLimit { - constructor(core, { jointCount = 3, limits = {} } = {}) { + constructor(core, { jointCount = 3, limits = {}, kinematicsType = KIN_TYPE_TRIVKINS, coordinates = "XYZ", offsets = {} } = {}) { this.core = core; this.available = ["sim_kinematics_init", "sim_kinematics_home_limit_init", "sim_kinematics_home_limit_reset", "sim_kinematics_home_limit_home", "sim_kinematics_home_limit_check", "sim_kinematics_home_limit_read"].every((name) => typeof core?.[`_${name}`] === "function" || typeof core?.[name] === "function"); this.jointCount = jointCount; + this.kinematicsType = kinematicsType; + this.coordinates = String(coordinates).toUpperCase(); + this.offsets = { ...offsets }; this.config = this.kinematics = this.homeLimit = this.state = this.joints = 0; this.stateBuffer = 0; this.limits = { x: [-500, 500], y: [-100, 100], z: [-240, 0.001], ...limits }; @@ -60,18 +64,22 @@ export class WasmHomeLimit { this.core.HEAPU8.fill(0, this.stateBuffer, this.stateBuffer + HOME_STATE_SIZE); this.core.HEAPU8.fill(0, this.joints, this.joints + 9 * 8); const configView = new DataView(this.core.HEAPU8.buffer, this.config, KIN_CONFIG_SIZE); - configView.setInt32(CONFIG_OFFSETS.type, KIN_TYPE_TRIVKINS, true); + configView.setInt32(CONFIG_OFFSETS.type, kinematicsType, true); configView.setInt32(CONFIG_OFFSETS.mode, 0, true); configView.setUint32(CONFIG_OFFSETS.joint_count, jointCount, true); configView.setUint32(CONFIG_OFFSETS.kinematics_joint_count, jointCount, true); configView.setUint32(CONFIG_OFFSETS.extra_joint_count, 0, true); - for (const [index, axis] of ["X", "Y", "Z"].entries()) this.core.HEAPU8[this.config + CONFIG_OFFSETS.coordinates + index] = axis.charCodeAt(0); - for (const [index, axis] of ["x", "y", "z"].entries()) { - const limit = this.limits[axis] ?? [-1e9, 1e9]; + for (const [index, axis] of [...this.coordinates].entries()) this.core.HEAPU8[this.config + CONFIG_OFFSETS.coordinates + index] = axis.charCodeAt(0); + for (const [index, axis] of [...this.coordinates].entries()) { + const lowerAxis = axis.toLowerCase(); + const limit = this.limits[lowerAxis] ?? [-1e9, 1e9]; this.core.HEAPU8[this.config + CONFIG_OFFSETS.limit_enabled + index] = 1; configView.setFloat64(CONFIG_OFFSETS.joint_min + index * 8, limit[0], true); configView.setFloat64(CONFIG_OFFSETS.joint_max + index * 8, limit[1], true); } + for (const [key, offset] of Object.entries({ x_rot_point: CONFIG_OFFSETS.x_rot_point, y_offset: CONFIG_OFFSETS.y_offset, z_offset: CONFIG_OFFSETS.z_offset, tool_offset: CONFIG_OFFSETS.tool_offset })) { + configView.setFloat64(offset, Number(this.offsets[key] ?? 0), true); + } const initialized = call(core, "sim_kinematics_init", "number", ["number", "number"], [this.kinematics, this.config]); if (initialized !== 0) throw new Error(`wasm_home_kinematics_init_${initialized}`); const homeInitialized = call(core, "sim_kinematics_home_limit_init", "number", ["number", "number", "number"], [this.homeLimit, this.kinematics, jointCount]); @@ -84,7 +92,7 @@ export class WasmHomeLimit { if (result !== 0) return { status: "error", code: `wasm_home_limit_read_${result}` }; const ints = this.core.HEAPU32; const signed = this.core.HEAP32; - const joints = [...this.core.HEAPF64.subarray(this.stateBuffer / 8 + 9, this.stateBuffer / 8 + 12)]; + const joints = [...this.core.HEAPF64.subarray(this.stateBuffer / 8 + 9, this.stateBuffer / 8 + 9 + this.jointCount)]; return { status: "verified", state: { schema: HOME_LIMIT_SCHEMA, source: "wasm_home_limit", pose: pose(this.core, this.stateBuffer), joints, joint_count: ints[this.stateBuffer / 4 + 36], homed: Boolean(ints[this.stateBuffer / 4 + 37]), home_sequence: ints[this.stateBuffer / 4 + 38], tick: ints[this.stateBuffer / 4 + 39], last_error: signed[this.stateBuffer / 4 + 40], limit_error: signed[this.stateBuffer / 4 + 41], kinematics_error: signed[this.stateBuffer / 4 + 42] } }; } diff --git a/web/worker/wasm-motion-queue.mjs b/web/worker/wasm-motion-queue.mjs index cefab1b..5d3545c 100644 --- a/web/worker/wasm-motion-queue.mjs +++ b/web/worker/wasm-motion-queue.mjs @@ -97,6 +97,9 @@ export class WasmMotionQueue { [...poseToArray(segment.start), ...poseToArray(segment.end), Number(segment.center?.x ?? 0), Number(segment.center?.y ?? 0), Number(segment.center?.z ?? 0), Number(segment.normal?.x ?? 0), Number(segment.normal?.y ?? 0), Number(segment.normal?.z ?? 0), Number(segment.velocity ?? 0), Number(segment.acceleration ?? 0)].forEach((value, index) => { doubles[base + index] = value; }); ints[this.command / 4 + SEGMENT_INT_OFFSET] = Number(segment.motion_type ?? 1); ints[this.command / 4 + SEGMENT_INT_OFFSET + 1] = Number(segment.turn ?? 0); + // sim_motion_command layout is segment (216 bytes), id (4), tag (4). + // Keep the WASM switchkins mode in the tag field; the C queue assigns id. + ints[this.command / 4 + SEGMENT_INT_OFFSET + 3] = Number(segment.kinematics_mode ?? segment.tag ?? 0); const result = call(this.core, "sim_motion_enqueue", "number", ["number", "number", "number"], [this.queue, this.command, 0]); return result === 0 ? { status: "verified", source_line: segment.source_line ?? null } : { status: "error", code: `wasm_motion_enqueue_${result}` }; } @@ -153,13 +156,16 @@ export class WasmMotionQueue { const previous = this.core.HEAPU8.slice(this.queue, this.queue + this.queueSize); const headerOffset = this.queueCapacity * this.commandCapacity; const stateOffset = headerOffset + QUEUE_HEADER_BYTES; - const nextId = new DataView(previous.buffer, previous.byteOffset, previous.byteLength).getUint32(8, true); + const previousView = new DataView(previous.buffer, previous.byteOffset, previous.byteLength); + const nextId = previousView.getUint32(headerOffset + 8, true); this.reset(); const bytes = new Uint8Array(this.queueSize); const view = new DataView(bytes.buffer); - bytes.set(previous.subarray(16, 32), 16); - view.setUint32(8, nextId, true); - view.setUint32(12, current.state.tick, true); + // sim_motion_queue stores commands first, followed by its 32-byte header. + // Preserve cycle/velocity configuration from that actual header offset. + bytes.set(previous.subarray(headerOffset + 16, headerOffset + QUEUE_HEADER_BYTES), headerOffset + 16); + view.setUint32(headerOffset + 8, nextId, true); + view.setUint32(headerOffset + 12, current.state.tick, true); bytes.set(previous.subarray(stateOffset, stateOffset + STATE_POSITION_BYTES), stateOffset); view.setFloat64(stateOffset + 72, 0, true); view.setFloat64(stateOffset + 80, 0, true); @@ -187,7 +193,7 @@ export class WasmMotionQueue { if (result !== 0) return { status: "error", code: `wasm_motion_read_${result}` }; const doubles = this.core.HEAPF64.subarray(this.state / 8, this.state / 8 + 11); const ints = this.core.HEAPU32.subarray(this.state / 4 + 22, this.state / 4 + 26); - return { status: "verified", state: { position: { x: doubles[0], y: doubles[1], z: doubles[2] }, velocity: this.controls.paused ? 0 : doubles[9], progress: doubles[10], tick: ints[0], queue_depth: ints[1], active_id: ints[2], active_tag: ints[3], motion_type: this.core.HEAP32[this.state / 4 + 26], status: this.core.HEAP32[this.state / 4 + 27], source: "wasm_motion_queue" } }; + return { status: "verified", state: { position: { x: doubles[0], y: doubles[1], z: doubles[2], a: doubles[3], b: doubles[4], c: doubles[5], u: doubles[6], v: doubles[7], w: doubles[8] }, velocity: this.controls.paused ? 0 : doubles[9], progress: doubles[10], tick: ints[0], queue_depth: ints[1], active_id: ints[2], active_tag: ints[3], motion_type: this.core.HEAP32[this.state / 4 + 26], status: this.core.HEAP32[this.state / 4 + 27], source: "wasm_motion_queue" } }; } exportState() { diff --git a/web/worker/wasm-program-runtime.mjs b/web/worker/wasm-program-runtime.mjs new file mode 100644 index 0000000..91e27f3 --- /dev/null +++ b/web/worker/wasm-program-runtime.mjs @@ -0,0 +1,246 @@ +import { fnv1a64 } from "./replay.mjs"; + +const SCHEMA = "wasm_program_runtime.v1"; +const SEGMENT_BYTES = 216; +const POSE_BYTES = 72; +const AXES = ["x", "y", "z", "a", "b", "c", "u", "v", "w"]; +const DEFAULT_RAPID_VELOCITY = 1000; + +function call(core, name, returnType, argTypes, args) { + const fn = core?.[`_${name}`] ?? core?.[name]; + if (typeof fn === "function") return fn(...args); + if (typeof core?.ccall === "function") return core.ccall(name, returnType, argTypes, args); + throw new Error(`missing core export: ${name}`); +} + +function pose(core, pointer) { + const values = [...core.HEAPF64.subarray(pointer / 8, pointer / 8 + 9)]; + return Object.fromEntries(AXES.map((axis, index) => [axis, values[index]])); +} + +function segment(core, pointer) { + const start = pose(core, pointer); + const end = pose(core, pointer + 72); + const cart = (offset) => ({ x: core.HEAPF64[pointer / 8 + offset / 8], y: core.HEAPF64[pointer / 8 + offset / 8 + 1], z: core.HEAPF64[pointer / 8 + offset / 8 + 2] }); + const ints = new DataView(core.HEAPU8.buffer, pointer, SEGMENT_BYTES); + return { start, end, center: cart(144), normal: cart(168), velocity: core.HEAPF64[pointer / 8 + 24], acceleration: core.HEAPF64[pointer / 8 + 25], motion_type: ints.getInt32(208, true), turn: ints.getInt32(212, true) }; +} + +function sampleSegment(core, segmentPointer, posePointer, value) { + const turn = Math.max(1, Math.abs(Number(value.turn ?? 1))); + const count = value.motion_type === 2 ? Math.max(32, Math.ceil(turn * 32)) : 1; + const samples = []; + for (let index = 0; index <= count; index += 1) { + const result = call(core, "sim_posemath_segment_point", "number", ["number", "number", "number"], [segmentPointer, index / count, posePointer]); + if (result !== 0) throw new Error(`wasm_program_segment_sample_${result}`); + samples.push(pose(core, posePointer)); + } + return samples; +} + +function readString(core, pointer, capacity) { + const bytes = core.HEAPU8.subarray(pointer, pointer + capacity); + const end = bytes.indexOf(0); + return new TextDecoder().decode(bytes.subarray(0, end < 0 ? bytes.length : end)); +} + +export class WasmProgramRuntime { + constructor(core) { + this.core = core; + this.available = ["sim_program_size", "sim_program_init", "sim_program_step", "sim_program_canonical", "sim_program_add_subroutine", "sim_program_set_rapid_velocity"].every((name) => typeof core?.[`_${name}`] === "function" || typeof core?.[name] === "function"); + this.pointer = 0; + this.motionPointer = 0; + this.samplePointer = 0; + this.samplePosePointer = 0; + this.source = ""; + this.path = null; + this.subroutines = []; + this.rapidVelocity = 35; + if (!this.available || typeof core?._malloc !== "function") return; + this.pointer = core._malloc(call(core, "sim_program_size", "number", [], [])); + this.motionPointer = core._malloc(SEGMENT_BYTES); + this.samplePointer = core._malloc(SEGMENT_BYTES); + this.samplePosePointer = core._malloc(POSE_BYTES); + if (!this.pointer || !this.motionPointer || !this.samplePointer || !this.samplePosePointer) throw new Error("wasm_program_allocation_failed"); + const result = call(core, "sim_program_init", "number", ["number"], [this.pointer]); + if (result !== 0) throw new Error(`wasm_program_init_${result}`); + } + + invoke(name, args = [], errorPrefix = name) { + if (!this.available) return { status: "blocked", code: "wasm_program_unavailable" }; + const result = call(this.core, name, "number", ["number", ...args.map(() => "number")], [this.pointer, ...args]); + return result === 0 ? { status: "verified", command: name } : { status: "error", code: `wasm_${errorPrefix}_${result}`, result }; + } + + load(source, path = null) { + if (typeof source !== "string" || source.length === 0) return { status: "error", code: "program_source_invalid" }; + const bytes = new TextEncoder().encode(source); + const pointer = this.core._malloc(bytes.byteLength); + this.core.HEAPU8.set(bytes, pointer); + try { + const result = call(this.core, "sim_program_load", "number", ["number", "number", "number"], [this.pointer, pointer, bytes.byteLength]); + if (result !== 0) return { status: "error", code: `wasm_program_load_${result}` }; + const velocityResult = call(this.core, "sim_program_set_rapid_velocity", "number", ["number", "number"], [this.pointer, this.rapidVelocity]); + if (velocityResult !== 0) return { status: "error", code: `wasm_program_rapid_velocity_${velocityResult}` }; + this.source = source; + this.path = path; + this.subroutines = []; + return { status: "verified", program: this.snapshot() }; + } finally { this.core._free(pointer); } + } + + requiresSubroutines(source = this.source) { + if (typeof source !== "string" || source.length === 0) return { status: "error", code: "program_source_invalid" }; + const bytes = new TextEncoder().encode(source); + const pointer = this.core._malloc(bytes.byteLength); + this.core.HEAPU8.set(bytes, pointer); + try { + const result = call(this.core, "sim_program_requires_subroutines", "number", ["number", "number"], [pointer, bytes.byteLength]); + if (result < 0) return { status: "error", code: `wasm_program_requires_subroutines_${result}` }; + return { status: "verified", required: result === 1 }; + } finally { this.core._free(pointer); } + } + + preview() { + if (!this.source) return { status: "error", code: "program_preview_source_missing" }; + const temporary = new WasmProgramRuntime(this.core); + const segments = []; + try { + const loaded = temporary.load(this.source, this.path); + if (loaded.status !== "verified") return loaded; + temporary.setRapidVelocity(this.rapidVelocity); + for (const subroutine of this.subroutines) { + const added = temporary.addSubroutine(subroutine.name, subroutine.source); + if (added.status !== "verified") return added; + } + const started = temporary.start(); + if (started.status !== "verified") return started; + const limit = Math.min(100000, Math.max(1, temporary.snapshot().line_count * 8 + 1)); + let kinematicsMode = 0; + for (let index = 0; index < limit; index += 1) { + const step = temporary.step(); + if (step.status !== "verified") return { status: "error", code: step.code, line: temporary.snapshot().current_line, segments }; + if (step.has_control && [428, 429, 430].includes(step.control_code)) kinematicsMode = { 428: 1, 429: 0, 430: 2 }[step.control_code]; + if (step.motion) segments.push({ id: segments.length + 1, kinematics_mode: kinematicsMode, ...step.motion }); + if ([4, 5, 6].includes(temporary.snapshot().status)) break; + } + return { status: "verified", schema: "wasm-canonical-preview.v1", source: "linuxcnc-wasm-sim_program", path: this.path, source_hash: fnv1a64(this.source), line_count: this.snapshot().line_count, segments, preview_hash: fnv1a64(segments) }; + } finally { temporary.destroy(); } + } + + start() { return this.invoke("sim_program_start", [], "program_start"); } + setRapidVelocity(velocity) { + if (!Number.isFinite(Number(velocity)) || Number(velocity) <= 0) return { status: "error", code: "program_rapid_velocity_invalid" }; + this.rapidVelocity = Number(velocity); + const result = call(this.core, "sim_program_set_rapid_velocity", "number", ["number", "number"], [this.pointer, this.rapidVelocity]); + if (result !== 0) throw new Error(`wasm_program_set_rapid_velocity_${result}`); + return { status: "verified", command: "sim_program_set_rapid_velocity" }; + } + addSubroutine(name, source) { + if (typeof source !== "string" || source.length === 0) return { status: "error", code: "program_subroutine_invalid" }; + const bytes = new TextEncoder().encode(source); + const pointer = this.core._malloc(bytes.byteLength); + this.core.HEAPU8.set(bytes, pointer); + try { + const code = call(this.core, "sim_program_add_subroutine", "number", ["number", "number", "number"], [this.pointer, pointer, bytes.byteLength]); + if (code !== 0) return { status: "error", code: `wasm_program_add_subroutine_${code}`, result: code }; + this.subroutines.push({ name: String(name ?? "subroutine"), source }); + return { status: "verified", command: "sim_program_add_subroutine", name: String(name ?? "subroutine") }; + } finally { this.core._free(pointer); } + } + pause() { return this.invoke("sim_program_pause", [], "program_pause"); } + resume() { return this.invoke("sim_program_resume", [], "program_resume"); } + abort() { return this.invoke("sim_program_abort", [], "program_abort"); } + seek(line) { return this.invoke("sim_program_seek", [line], "program_seek"); } + + restoreState(value) { + if (!value || ![SCHEMA, "sim_program.v1"].includes(value.schema) || !Number.isSafeInteger(value.current_line) || value.current_line < 0 || !this.source) throw new Error("wasm_program_restore_schema"); + if (value.source_hash && value.source_hash !== fnv1a64(this.source)) throw new Error("wasm_program_restore_source_hash"); + const subroutines = [...this.subroutines]; + const loaded = this.load(this.source, this.path); + if (loaded.status !== "verified") throw new Error(loaded.code); + for (const subroutine of subroutines) { + const added = this.addSubroutine(subroutine.name, subroutine.source); + if (added.status !== "verified") throw new Error(added.code); + } + if (value.current_line > 0) { + const seek = this.seek(value.current_line); + if (seek.status !== "verified") throw new Error(seek.code); + } + const status = value.program_status ?? ({ 0: "idle", 1: "loaded", 2: "running", 3: "paused", 4: "completed", 5: "aborted", 6: "fault" }[value.status] ?? "loaded"); + if (status === "running") { + const resumed = this.resume(); + if (resumed.status !== "verified") { + const started = this.start(); + if (started.status !== "verified") throw new Error(started.code); + } + } else if (status === "completed") { + this.start(); + for (let index = 0; index < this.snapshot().line_count + 1 && this.snapshot().status === 2; index += 1) this.step(); + } else if (status === "aborted") { + const aborted = this.abort(); + if (aborted.status !== "verified") throw new Error(aborted.code); + } + if (value.has_motion === 0) this.clearMotion(); + return this.snapshot(); + } + + executeBlock(block) { + const bytes = new TextEncoder().encode(String(block ?? "")); + const pointer = this.core._malloc(bytes.byteLength); + this.core.HEAPU8.set(bytes, pointer); + try { + const result = call(this.core, "sim_program_execute_block", "number", ["number", "number", "number"], [this.pointer, pointer, bytes.byteLength]); + if (result !== 0) return { status: "error", code: `wasm_program_execute_${result}` }; + return { status: "verified", program: this.snapshot(), motion: this.readMotion() }; + } finally { this.core._free(pointer); } + } + + readMotion() { + const state = this.snapshot(); + if (!state.has_motion) return null; + const result = call(this.core, "sim_program_read_motion", "number", ["number", "number"], [this.pointer, this.motionPointer]); + if (result !== 0) return null; + const value = segment(this.core, this.motionPointer); + // LinuxCNC rapid blocks do not carry an F word. The trajectory queue + // requires a positive velocity, so use the simulation's configured rapid + // rate for that WASM-produced linear segment. + if (state.motion_mode === 0 && value.motion_type === 1 && value.velocity <= 0) value.velocity = DEFAULT_RAPID_VELOCITY; + value.samples = sampleSegment(this.core, this.motionPointer, this.samplePosePointer, value); + value.samples_source = "linuxcnc-wasm-sim_posemath_segment_point"; + value.canonical_motion_mode = state.motion_mode; + value.kind = value.motion_type === 2 && Math.abs(Number(value.end?.z ?? 0) - Number(value.start?.z ?? 0)) > 1e-12 ? "helix" : value.motion_type === 2 ? "arc" : state.motion_mode === 0 ? "rapid" : value.motion_type === 1 ? "feed" : "traverse"; + if (value.kind === "helix") { + value.helix = true; + value.radius = Math.hypot(Number(value.start?.x ?? 0) - Number(value.center?.x ?? 0), Number(value.start?.y ?? 0) - Number(value.center?.y ?? 0)); + value.turns = Math.abs(Number(value.turn ?? 1)); + value.axial_delta = Number(value.end?.z ?? 0) - Number(value.start?.z ?? 0); + } + call(this.core, "sim_program_clear_motion", "number", ["number"], [this.pointer]); + return { ...value, source_line: state.current_line }; + } + + clearMotion() { return this.invoke("sim_program_clear_motion", [], "program_clear_motion"); } + + step() { + const result = this.invoke("sim_program_step", [], "program_step"); + if (result.status !== "verified") return result; + const state = this.snapshot(); + return { status: "verified", program_status: state.status, line: state.current_line, control_code: state.control_code ?? 0, has_control: state.has_control === 1, program: state, motion: this.readMotion() }; + } + + snapshot() { + if (!this.available) return { schema: SCHEMA, status: "blocked", code: "wasm_program_unavailable" }; + const required = call(this.core, "sim_program_canonical", "number", ["number", "number", "number"], [this.pointer, 0, 0]); + const buffer = this.core._malloc(required); + try { + call(this.core, "sim_program_canonical", "number", ["number", "number", "number"], [this.pointer, buffer, required]); + const state = JSON.parse(readString(this.core, buffer, required)); + const hash = call(this.core, "sim_program_state_hash", "number", ["number"], [this.pointer]); + const programStatus = { 0: "idle", 1: "loaded", 2: "running", 3: "paused", 4: "completed", 5: "aborted", 6: "fault" }[state.status] ?? "idle"; + return { schema: SCHEMA, source: "linuxcnc-wasm-sim_program", ...state, loaded: state.status !== 0, line: state.current_line, currentLine: state.current_line, program_status: programStatus, path: this.path, subroutines: this.subroutines.map((subroutine) => subroutine.name), state_hash: `fnv1a64:${BigInt.asUintN(64, BigInt(hash >>> 0)).toString(16).padStart(16, "0")}`, source_hash: this.source ? fnv1a64(this.source) : null }; + } finally { this.core._free(buffer); } + } + + destroy() { for (const pointer of [this.pointer, this.motionPointer, this.samplePointer, this.samplePosePointer]) if (pointer && typeof this.core?._free === "function") this.core._free(pointer); this.pointer = this.motionPointer = this.samplePointer = this.samplePosePointer = 0; } +} diff --git a/web/worker/wasm-xyzac-device-io.mjs b/web/worker/wasm-xyzac-device-io.mjs new file mode 100644 index 0000000..4c6afae --- /dev/null +++ b/web/worker/wasm-xyzac-device-io.mjs @@ -0,0 +1,111 @@ +import { fnv1a64 } from "./replay.mjs"; + +const DEVICE_SCHEMA = "wasm_xyzac_device_io.v1"; + +function call(core, name, returnType, argTypes, args) { + const fn = core?.[`_${name}`] ?? core?.[name]; + if (typeof fn === "function") return fn(...args); + if (typeof core?.ccall === "function") return core.ccall(name, returnType, argTypes, args); + throw new Error(`missing core export: ${name}`); +} + +function readString(core, pointer, capacity) { + const bytes = core.HEAPU8.subarray(pointer, pointer + capacity); + const end = bytes.indexOf(0); + return new TextDecoder().decode(bytes.subarray(0, end < 0 ? bytes.length : end)); +} + +function bytesToHex(bytes) { + let output = ""; + for (const byte of bytes) output += byte.toString(16).padStart(2, "0"); + return output; +} + +function hexToBytes(value) { + if (typeof value !== "string" || value.length % 2 !== 0 || !/^[0-9a-f]*$/i.test(value)) throw new Error("wasm_xyzac_device_io_state_bytes_invalid"); + const bytes = new Uint8Array(value.length / 2); + for (let index = 0; index < bytes.length; index += 1) bytes[index] = Number.parseInt(value.slice(index * 2, index * 2 + 2), 16); + return bytes; +} + +function operationNumber(value) { + if (Number.isSafeInteger(value) && value > 0) return value; + const text = String(value ?? "device"); + let hash = 2166136261; + for (const byte of new TextEncoder().encode(text)) { hash ^= byte; hash = Math.imul(hash, 16777619); } + return (hash >>> 0) || 1; +} + +export class WasmXyzacDeviceIo { + constructor(core, { encoderCount = 2 } = {}) { + this.core = core; + this.available = ["sim_device_io_size", "sim_device_init", "sim_device_canonical", "sim_device_state_hash"].every((name) => typeof core?.[`_${name}`] === "function" || typeof core?.[name] === "function"); + this.pointer = 0; + if (!this.available || typeof core?._malloc !== "function") return; + const size = call(core, "sim_device_io_size", "number", [], []); + this.pointer = core._malloc(size); + if (!this.pointer) throw new Error("wasm_xyzac_device_io_allocation_failed"); + const result = call(core, "sim_device_init", "number", ["number", "number", "number"], [this.pointer, encoderCount, 0.01]); + if (result !== 0) throw new Error(`wasm_xyzac_device_io_init_${result}`); + } + + invoke(name, args = []) { + if (!this.available) return { status: "blocked", code: "wasm_xyzac_device_io_unavailable" }; + const result = call(this.core, name, "number", ["number", ...args.map(() => "number")], [this.pointer, ...args]); + return result === 0 ? { status: "verified", command: name } : { status: "error", code: `wasm_${name}_${result}`, result }; + } + + canonical() { + if (!this.available) return { status: "blocked", code: "wasm_xyzac_device_io_unavailable" }; + const required = call(this.core, "sim_device_canonical", "number", ["number", "number", "number"], [this.pointer, 0, 0]); + const buffer = this.core._malloc(required); + try { call(this.core, "sim_device_canonical", "number", ["number", "number", "number"], [this.pointer, buffer, required]); return JSON.parse(readString(this.core, buffer, required)); } + finally { this.core._free(buffer); } + } + + export() { + const state = this.canonical(); + if (state.status === "blocked") return { schema: DEVICE_SCHEMA, source: "wasm_device_io", ...state }; + const unsigned = { schema: DEVICE_SCHEMA, source: "wasm_device_io", state, wasm_state_hash: this.stateHash(), state_bytes: bytesToHex(this.core.HEAPU8.slice(this.pointer, this.pointer + call(this.core, "sim_device_io_size", "number", [], []))) }; + return { ...unsigned, state_hash: fnv1a64(unsigned) }; + } + + restoreState(value) { + if (!value || !value.state_bytes || !this.available) throw new Error("wasm_xyzac_device_io_restore_unavailable"); + const bytes = hexToBytes(value.state_bytes); + const size = call(this.core, "sim_device_io_size", "number", [], []); + if (bytes.length !== size) throw new Error("wasm_xyzac_device_io_restore_layout"); + this.core.HEAPU8.set(bytes, this.pointer); + const actual = this.canonical(); + if (value.state && fnv1a64(actual) !== fnv1a64(value.state)) throw new Error("wasm_xyzac_device_io_restore_state_mismatch"); + return this.export(); + } + + stateHash() { + if (!this.available) return null; + const hash = call(this.core, "sim_device_state_hash", "number", ["number"], [this.pointer]); + return `fnv1a64:${BigInt.asUintN(64, BigInt(hash >>> 0)).toString(16).padStart(16, "0")}`; + } + + command(kind, payload = {}, operationId = null) { + if (kind === "ENCODER_SET") { + const channel = payload.channel ?? 0; + if (payload.speed_rps !== undefined || payload.speed !== undefined) return this.invoke("sim_device_encoder_set_speed", [channel, payload.speed_rps ?? payload.speed]); + if (payload.ppr !== undefined || payload.scale !== undefined) return this.invoke("sim_device_encoder_set_config", [channel, payload.ppr ?? 1000, payload.scale ?? 1]); + return this.invoke("sim_device_encoder_set_index_enable", [channel, payload.index_enable === true ? 1 : 0]); + } + if (kind === "COOLANT_COMMAND") return this.invoke("sim_device_coolant_command", [payload.mist ? 1 : 0, payload.flood ? 1 : 0, payload.lube ? 1 : 0]); + if (kind === "COOLANT_FAULT") return this.invoke("sim_device_coolant_set_fault", [payload.fault === true ? 1 : 0]); + if (kind === "DOOR_SET") return this.invoke("sim_device_door_set", [payload.open === true ? 1 : 0]); + if (kind === "INTERLOCK_SET") return this.invoke("sim_device_interlock_set", [payload.input_ok === false ? 0 : 1]); + if (kind === "INTERLOCK_RESET") return this.invoke("sim_device_interlock_reset"); + if (kind === "DEVICE_ESTOP") return this.invoke("sim_device_estop_set", [payload.active === true ? 1 : 0]); + if (kind === "DEVICE_ACK_ISSUE") return this.invoke("sim_device_ack_issue", [operationNumber(operationId ?? payload.operation_id), payload.timeout_ticks ?? 10]); + if (kind === "DEVICE_ACK") return this.invoke("sim_device_ack_ack", [operationNumber(payload.operation_id)]); + if (kind === "DEVICE_ACK_ABORT") return this.invoke("sim_device_ack_abort", [operationNumber(payload.operation_id)]); + if (kind === "IO_STEP") return this.invoke("sim_device_step", [payload.ticks ?? 1]); + return { status: "error", code: "wasm_xyzac_device_io_command_unsupported", command: kind }; + } + + destroy() { if (this.pointer && typeof this.core?._free === "function") this.core._free(this.pointer); this.pointer = 0; } +} diff --git a/web/worker/wasm-xyzac-io.mjs b/web/worker/wasm-xyzac-io.mjs new file mode 100644 index 0000000..15831d8 --- /dev/null +++ b/web/worker/wasm-xyzac-io.mjs @@ -0,0 +1,170 @@ +import { fnv1a64 } from "./replay.mjs"; + +const IO_SCHEMA = "wasm_xyzac_io.v1"; +const HAL_SCHEMA = "wasm_xyzac_hal.v1"; +const POSE_BYTES = 72; +const HAL_WRITE_ALLOWLIST = new Set(["motion.probe-input", "iocontrol.0.tool-prepared", "iocontrol.0.tool-changed", "spindle.0.speed-in", "spindle.0.at-speed"]); + +function call(core, name, returnType, argTypes, args) { + const fn = core?.[`_${name}`] ?? core?.[name]; + if (typeof fn === "function") return fn(...args); + if (typeof core?.ccall === "function") return core.ccall(name, returnType, argTypes, args); + throw new Error(`missing core export: ${name}`); +} + +function callString(core, name, returnType, argTypes, args) { + if (typeof core?.ccall === "function") return core.ccall(name, returnType, argTypes, args); + throw new Error(`missing string-capable core export: ${name}`); +} + +function readString(core, pointer, capacity) { + const bytes = core.HEAPU8.subarray(pointer, pointer + capacity); + const end = bytes.indexOf(0); + return new TextDecoder().decode(bytes.subarray(0, end < 0 ? bytes.length : end)); +} + +function bytesToHex(bytes) { + let output = ""; + for (const byte of bytes) output += byte.toString(16).padStart(2, "0"); + return output; +} + +function hexToBytes(value) { + if (typeof value !== "string" || value.length % 2 !== 0 || !/^[0-9a-f]*$/i.test(value)) throw new Error("wasm_xyzac_io_state_bytes_invalid"); + const bytes = new Uint8Array(value.length / 2); + for (let index = 0; index < bytes.length; index += 1) bytes[index] = Number.parseInt(value.slice(index * 2, index * 2 + 2), 16); + return bytes; +} + +export class WasmXyzacIo { + constructor(core, { spindleCount = 2, toolCapacity = 1001 } = {}) { + this.core = core; + this.available = ["sim_io_size", "sim_io_init", "sim_io_canonical", "sim_io_state_hash"].every((name) => typeof core?.[`_${name}`] === "function" || typeof core?.[name] === "function"); + this.pointer = 0; + this.posePointer = 0; + this.ioSize = 0; + this.spindleCount = spindleCount; + this.toolCapacity = toolCapacity; + this.lastError = 0; + if (!this.available || typeof core?._malloc !== "function") return; + this.ioSize = call(core, "sim_io_size", "number", [], []); + this.pointer = core._malloc(this.ioSize); + this.posePointer = core._malloc(POSE_BYTES); + if (!this.pointer || !this.posePointer) throw new Error("wasm_xyzac_io_allocation_failed"); + const result = call(core, "sim_io_init", "number", ["number", "number", "number", "number", "number", "number"], [this.pointer, spindleCount, toolCapacity, 0.01, 600, 5]); + if (result !== 0) throw new Error(`wasm_xyzac_io_init_${result}`); + } + + invoke(name, args = []) { + if (!this.available) return { status: "blocked", code: "wasm_xyzac_io_unavailable" }; + const result = call(this.core, name, "number", ["number", ...args.map(() => "number")], [this.pointer, ...args]); + this.lastError = result; + return result === 0 ? { status: "verified", command: name } : { status: "error", code: `wasm_${name}_${result}`, result }; + } + + canonical() { + if (!this.available) return { status: "blocked", code: "wasm_xyzac_io_unavailable" }; + const required = call(this.core, "sim_io_canonical", "number", ["number", "number", "number"], [this.pointer, 0, 0]); + const buffer = this.core._malloc(required); + try { + call(this.core, "sim_io_canonical", "number", ["number", "number", "number"], [this.pointer, buffer, required]); + return JSON.parse(readString(this.core, buffer, required)); + } finally { this.core._free(buffer); } + } + + stateHash() { + if (!this.available) return null; + const hash = call(this.core, "sim_io_state_hash", "number", ["number"], [this.pointer]); + return `fnv1a64:${BigInt.asUintN(64, BigInt(hash >>> 0)).toString(16).padStart(16, "0")}`; + } + + export() { + const state = this.canonical(); + if (state.status === "blocked") return { schema: IO_SCHEMA, source: "wasm_io", ...state }; + const unsigned = { schema: IO_SCHEMA, source: "wasm_io", state, state_hash: this.stateHash(), state_bytes: bytesToHex(this.core.HEAPU8.slice(this.pointer, this.pointer + this.ioSize)) }; + return { ...unsigned, projection_hash: fnv1a64(unsigned) }; + } + + restoreState(value) { + if (!value || !value.state_bytes || !this.available) throw new Error("wasm_xyzac_io_restore_unavailable"); + const bytes = hexToBytes(value.state_bytes); + if (bytes.length !== this.ioSize) throw new Error("wasm_xyzac_io_restore_layout"); + this.core.HEAPU8.set(bytes, this.pointer); + const actual = this.canonical(); + if (value.state && fnv1a64(actual) !== fnv1a64(value.state)) throw new Error("wasm_xyzac_io_restore_state_mismatch"); + return this.export(); + } + + halExport() { + if (!this.available) return { schema: HAL_SCHEMA, source: "wasm_hal", status: "blocked", code: "wasm_hal_unavailable" }; + const tick = call(this.core, "sim_hal_tick", "number", [], []); + const unsigned = { + schema: HAL_SCHEMA, + source: "wasm_hal", + status: "verified", + tick, + pin_count: call(this.core, "sim_hal_pin_count", "number", [], []), + param_count: call(this.core, "sim_hal_param_count", "number", [], []), + thread_count: call(this.core, "sim_hal_thread_count", "number", [], []), + function_count: call(this.core, "sim_hal_function_count", "number", [], []), + component_count: call(this.core, "sim_hal_component_count", "number", [], []), + }; + return { ...unsigned, state_hash: fnv1a64(unsigned) }; + } + + halValue(name, value, type = 4, param = false) { + if (!this.available) return { status: "blocked", code: "wasm_hal_unavailable" }; + if (param || !HAL_WRITE_ALLOWLIST.has(name)) return { status: "error", code: "wasm_hal_write_denied", name, target: param ? "param" : "pin" }; + const result = callString(this.core, param ? "sim_hal_set_param_scalar" : "sim_hal_set_pin_scalar", "number", ["string", "number", "number"], [name, type, Number(value)]); + return result === 0 ? { status: "verified", command: param ? "HAL_SET_PARAM" : "HAL_SET_PIN" } : { status: "error", code: `wasm_hal_set_${result}`, result }; + } + + halCommand(payload = {}) { + if (payload.action === "thread") return callString(this.core, "sim_hal_register_thread", "number", ["string", "number"], [payload.name ?? "servo-thread", payload.period_ticks ?? 1]) === 0 ? { status: "verified", command: "HAL_THREAD" } : { status: "error", code: "wasm_hal_thread" }; + if (payload.action === "component") return callString(this.core, "sim_hal_register_component", "number", ["string", "string", "string"], [payload.instance ?? payload.name, payload.type ?? payload.module, payload.thread ?? "servo-thread"]) === 0 ? { status: "verified", command: "HAL_COMPONENT" } : { status: "error", code: "wasm_hal_component" }; + if (payload.action === "connect") return callString(this.core, "sim_hal_connect", "number", ["string", "string"], [payload.source, payload.target]) === 0 ? { status: "verified", command: "HAL_CONNECT" } : { status: "error", code: "wasm_hal_connect" }; + if (payload.action === "step") { + const result = call(this.core, "sim_hal_step", "number", ["number"], [payload.ticks ?? payload.tick ?? 1]); + return result === 0 ? { status: "verified", command: "HAL_STEP" } : { status: "error", code: `wasm_hal_step_${result}` }; + } + return { status: "error", code: "wasm_hal_command_unsupported" }; + } + + command(kind, payload = {}) { + if (kind === "SPINDLE_COMMAND") return this.invoke("sim_io_spindle_command", [payload.spindle ?? 0, payload.rpm ?? payload.speed ?? 0, payload.enabled === false ? 0 : 1]); + if (kind === "SPINDLE_FAULT") return this.invoke("sim_io_spindle_set_fault", [payload.spindle ?? 0, payload.fault === true ? 1 : 0]); + if (kind === "SPINDLE_INHIBIT") return this.invoke("sim_io_spindle_set_inhibit", [payload.spindle ?? 0, payload.inhibit === true ? 1 : 0]); + if (kind === "SPINDLE_ORIENT") return this.invoke("sim_io_spindle_orient", [payload.spindle ?? 0, payload.angle ?? 0, payload.mode ?? 0]); + if (kind === "SPINDLE_ORIENTED") return this.invoke("sim_io_spindle_set_oriented", [payload.spindle ?? 0, payload.oriented === true ? 1 : 0, payload.fault ?? 0]); + if (kind === "TOOL_PREPARE") return this.invoke("sim_io_tool_prepare", [payload.tool ?? payload.tool_number ?? 0, payload.pocket ?? payload.pocket_number ?? 0]); + if (kind === "TOOL_PREPARED") return this.invoke("sim_io_tool_set_prepared", [payload.prepared === false ? 0 : 1]); + if (kind === "TOOL_CHANGE") return this.invoke("sim_io_tool_change"); + if (kind === "TOOL_CHANGED") return this.invoke("sim_io_tool_set_changed", [payload.changed === false ? 0 : 1]); + if (kind === "TOOL_ABORT") return this.invoke("sim_io_tool_abort", [payload.reason ?? 0]); + if (kind === "TOOL_FAULT") return this.invoke("sim_io_tool_set_fault", [payload.fault === true ? 1 : 0, payload.reason ?? 0]); + if (kind === "TOOL_CLEAR_FAULT") return this.invoke("sim_io_tool_clear_fault"); + if (kind === "PROBE_CONFIG") { + const result = this.invoke("sim_io_probe_arm", [payload.probe_type ?? payload.type ?? 0]); + return result; + } + if (kind === "ESTOP" || kind === "DEVICE_ESTOP") return this.invoke("sim_io_set_estop", [payload.active === true ? 1 : 0]); + if (kind === "IO_RECOVER" || kind === "INTERLOCK_RESET") return this.invoke("sim_io_recover"); + if (kind === "IO_STEP") return this.invoke("sim_io_step", [payload.ticks ?? 1]); + if (kind === "COOLANT_COMMAND") return { status: "error", code: "wasm_device_io_required", detail: "coolant uses sim_device_io authority" }; + return { status: "error", code: "wasm_xyzac_io_command_unsupported", command: kind }; + } + + probeUpdate(pose, input = 1) { + if (!this.available) return { status: "blocked", code: "wasm_xyzac_io_unavailable" }; + const values = ["x", "y", "z", "a", "b", "c", "u", "v", "w"].map((axis) => Number(pose?.[axis] ?? 0)); + this.core.HEAPF64.set(values, this.posePointer / 8); + return this.invoke("sim_io_probe_update", [this.posePointer, input ? 1 : 0]); + } + + destroy() { + for (const pointer of [this.pointer, this.posePointer]) if (pointer && typeof this.core?._free === "function") this.core._free(pointer); + this.pointer = this.posePointer = 0; + } +} + +export { HAL_WRITE_ALLOWLIST }; diff --git a/web/worker/wasm-xyzac-kinematics.mjs b/web/worker/wasm-xyzac-kinematics.mjs new file mode 100644 index 0000000..47f09b4 --- /dev/null +++ b/web/worker/wasm-xyzac-kinematics.mjs @@ -0,0 +1,181 @@ +import { fnv1a64 } from "./replay.mjs"; + +const CONFIG_SIZE = 1608; +const KINEMATICS_SIZE = 1760; +const SWITCH_SIZE = 512; +const RESULT_INFO_SIZE = 32; +const POSE_SIZE = 72; +const JOINT_BYTES = 9 * 8; +const CONFIG = Object.freeze({ + type: 0, mode: 4, joint_count: 8, kinematics_joint_count: 12, extra_joint_count: 16, + coordinates: 20, x_rot_point: 40, y_rot_point: 48, z_rot_point: 56, + x_offset: 64, y_offset: 72, z_offset: 80, tool_offset: 88, + limit_enabled: 1448, joint_min: 1464, joint_max: 1536, +}); +const SWITCH = Object.freeze({ switching: 16, active_mode: 20, pending_mode: 24, generation: 28, switch_count: 32, abort_count: 36 }); +const TYPE = Object.freeze({ identity: 1, xyzac: 2, userk: 1 }); +const MODE = Object.freeze({ identity: 0, xyzac: 1, userk: 2 }); +const AXES = Object.freeze(["x", "y", "z", "a", "b", "c", "u", "v", "w"]); +const COORDINATES = Object.freeze(["x", "y", "z", "a", "c"]); +const DEFAULT_LIMITS = Object.freeze({ x: [-200, 200], y: [-100, 100], z: [-120, 120], a: [-100, 50], c: [-36000, 36000] }); + +function call(core, name, returnType, argTypes, args) { + const direct = core?.[`_${name}`] ?? core?.[name]; + if (typeof direct === "function") return direct(...args); + if (typeof core?.ccall === "function") return core.ccall(name, returnType, argTypes, args); + throw new Error(`missing core export: ${name}`); +} + +function pose(core, pointer) { + const doubles = core.HEAPF64.subarray(pointer / 8, pointer / 8 + 9); + return Object.fromEntries(AXES.map((axis, index) => [axis, doubles[index]])); +} + +function setCoordinates(core, pointer) { + for (const [index, value] of [..."XYZAC"].entries()) core.HEAPU8[pointer + CONFIG.coordinates + index] = value.charCodeAt(0); +} + +function configFor(core, pointer, type, options) { + core.HEAPU8.fill(0, pointer, pointer + CONFIG_SIZE); + const view = new DataView(core.HEAPU8.buffer, pointer, CONFIG_SIZE); + view.setInt32(CONFIG.type, type, true); + view.setInt32(CONFIG.mode, 0, true); + view.setUint32(CONFIG.joint_count, 5, true); + view.setUint32(CONFIG.kinematics_joint_count, 5, true); + view.setUint32(CONFIG.extra_joint_count, 0, true); + setCoordinates(core, pointer); + for (const [index, axis] of COORDINATES.entries()) { + const limit = options.limits?.[axis] ?? DEFAULT_LIMITS[axis]; + core.HEAPU8[pointer + CONFIG.limit_enabled + index] = 1; + view.setFloat64(CONFIG.joint_min + index * 8, Number(limit[0]), true); + view.setFloat64(CONFIG.joint_max + index * 8, Number(limit[1]), true); + } + for (const [key, offset] of Object.entries({ x_rot_point: CONFIG.x_rot_point, y_offset: CONFIG.y_offset, z_offset: CONFIG.z_offset, tool_offset: CONFIG.tool_offset })) { + view.setFloat64(offset, Number(options[key] ?? 0), true); + } +} + +function resultCode(operation, result) { + return { status: "error", code: `wasm_xyzac_${operation}_${result}`, result }; +} + +export class WasmXyzacKinematics { + constructor(core, options = {}) { + this.core = core; + this.options = { x_rot_point: 0, y_offset: 20, z_offset: 10, tool_offset: 0, limits: DEFAULT_LIMITS, ...options }; + this.available = ["sim_kinematics_init", "sim_kinematics_switch_init", "sim_kinematics_switch_register", "sim_kinematics_switch_select", "sim_kinematics_switch_forward", "sim_kinematics_switch_inverse", "sim_kinematics_switch_active", "sim_kinematics_switch_state_hash"].every((name) => typeof core?.[`_${name}`] === "function" || typeof core?.[name] === "function"); + this.lastCommand = null; + this.modules = new Map(); + this.pointers = []; + if (!this.available || typeof core?._malloc !== "function") return; + for (const [mode, type] of [[MODE.identity, TYPE.identity], [MODE.xyzac, TYPE.xyzac], [MODE.userk, TYPE.userk]]) { + const config = core._malloc(CONFIG_SIZE); + const kinematics = core._malloc(KINEMATICS_SIZE); + if (!config || !kinematics) throw new Error("wasm_xyzac_allocation_failed"); + configFor(core, config, type, this.options); + const result = call(core, "sim_kinematics_init", "number", ["number", "number"], [kinematics, config]); + if (result !== 0) throw new Error(`wasm_xyzac_init_${result}`); + this.modules.set(mode, { config, kinematics }); + this.pointers.push(config, kinematics); + } + this.switchPointer = core._malloc(SWITCH_SIZE); + this.resultPointer = core._malloc(RESULT_INFO_SIZE); + this.posePointer = core._malloc(POSE_SIZE); + this.jointPointer = core._malloc(JOINT_BYTES); + if (![this.switchPointer, this.resultPointer, this.posePointer, this.jointPointer].every(Boolean)) throw new Error("wasm_xyzac_allocation_failed"); + this.pointers.push(this.switchPointer, this.resultPointer, this.posePointer, this.jointPointer); + for (const [pointer, size] of [[this.switchPointer, SWITCH_SIZE], [this.resultPointer, RESULT_INFO_SIZE], [this.posePointer, POSE_SIZE], [this.jointPointer, JOINT_BYTES]]) core.HEAPU8.fill(0, pointer, pointer + size); + this.initializeSwitch(); + } + + initializeSwitch() { + const initialized = call(this.core, "sim_kinematics_switch_init", "number", ["number", "number", "number"], [this.switchPointer, MODE.identity, 0]); + if (initialized !== 0) throw new Error(`wasm_xyzac_switch_init_${initialized}`); + for (const [mode, module] of this.modules) { + const registered = call(this.core, "sim_kinematics_switch_register", "number", ["number", "number", "number", "number"], [this.switchPointer, mode, module.kinematics, 0]); + if (registered !== 0) throw new Error(`wasm_xyzac_switch_register_${mode}_${registered}`); + } + } + + get activeMode() { + if (!this.available) return MODE.identity; + return call(this.core, "sim_kinematics_switch_active", "number", ["number"], [this.switchPointer]); + } + + setJoints(joints) { + if (!Array.isArray(joints) || joints.length < 5) throw new Error("wasm_xyzac_joints_invalid"); + this.core.HEAPF64.set(joints.slice(0, 9).map(Number), this.jointPointer / 8); + } + + setPose(value) { + if (!value || typeof value !== "object") throw new Error("wasm_xyzac_pose_invalid"); + this.core.HEAPF64.set(AXES.map((axis) => Number(value[axis] ?? 0)), this.posePointer / 8); + } + + forward(joints = [0, 0, 0, 0, 0]) { + if (!this.available) return { status: "blocked", code: "wasm_xyzac_unavailable" }; + this.setJoints(joints); + const result = call(this.core, "sim_kinematics_switch_forward", "number", ["number", "number", "number", "number", "number"], [this.switchPointer, this.jointPointer, 5, this.posePointer, this.resultPointer]); + if (result !== 0) return resultCode("forward", result); + return this.snapshot(); + } + + inverse(currentPose) { + if (!this.available) return { status: "blocked", code: "wasm_xyzac_unavailable" }; + this.setPose(currentPose); + const result = call(this.core, "sim_kinematics_switch_inverse", "number", ["number", "number", "number", "number", "number"], [this.switchPointer, this.posePointer, this.jointPointer, 5, this.resultPointer]); + if (result !== 0) return resultCode("inverse", result); + return this.snapshot(); + } + + select(mode, joints = [0, 0, 0, 0, 0]) { + if (![MODE.identity, MODE.xyzac, MODE.userk].includes(mode)) return { status: "error", code: "wasm_xyzac_invalid_mode" }; + this.setJoints(joints); + const result = call(this.core, "sim_kinematics_switch_select", "number", ["number", "number", "number", "number", "number", "number"], [this.switchPointer, mode, this.jointPointer, 5, this.posePointer, this.resultPointer]); + if (result !== 0) return resultCode("switch", result); + this.lastCommand = `M${mode === MODE.xyzac ? 428 : mode === MODE.identity ? 429 : 430}`; + return this.snapshot(); + } + + restoreState(state) { + if (!state || state.schema !== "wasm-xyzac-kinematics.v1" || ![MODE.identity, MODE.xyzac, MODE.userk].includes(state.active_type) || !Array.isArray(state.joints) || state.joints.length !== 5) throw new Error("wasm_xyzac_restore_state_invalid"); + this.initializeSwitch(); + this.setPose(state.pose); + this.setJoints(state.joints); + if (state.active_type !== MODE.identity) { + let result = call(this.core, "sim_kinematics_switch_begin", "number", ["number", "number"], [this.switchPointer, state.active_type]); + if (result === 0) result = call(this.core, "sim_kinematics_switch_commit", "number", ["number", "number", "number", "number", "number"], [this.switchPointer, this.jointPointer, 5, this.posePointer, this.resultPointer]); + if (result !== 0) throw new Error(`wasm_xyzac_restore_switch_${result}`); + } else { + const result = call(this.core, "sim_kinematics_switch_inverse", "number", ["number", "number", "number", "number", "number"], [this.switchPointer, this.posePointer, this.jointPointer, 5, this.resultPointer]); + if (result !== 0) throw new Error(`wasm_xyzac_restore_inverse_${result}`); + } + this.setJoints(state.joints); + this.setPose(state.pose); + const view = new DataView(this.core.HEAPU8.buffer, this.switchPointer, SWITCH_SIZE); + view.setUint8(SWITCH.switching, 0); + view.setInt32(SWITCH.active_mode, state.active_type, true); + view.setInt32(SWITCH.pending_mode, state.active_type, true); + view.setUint32(SWITCH.generation, Number(state.generation ?? 0), true); + view.setUint32(SWITCH.switch_count, Number(state.switch_count ?? state.generation ?? 0), true); + view.setUint32(SWITCH.abort_count, Number(state.abort_count ?? 0), true); + this.lastCommand = state.last_command ?? null; + const restored = this.snapshot(); + if (restored.active_type !== state.active_type) throw new Error("wasm_xyzac_restore_projection_mismatch"); + return restored; + } + + snapshot(currentPose = pose(this.core, this.posePointer), joints = [...this.core.HEAPF64.subarray(this.jointPointer / 8, this.jointPointer / 8 + 5)]) { + const activeMode = this.activeMode; + const nativeType = activeMode === MODE.xyzac ? "xyzac-trt-kins" : activeMode === MODE.userk ? "userk-identity-template" : "identity"; + const view = new DataView(this.core.HEAPU8.buffer, this.switchPointer, SWITCH_SIZE); + const limits = Object.fromEntries(COORDINATES.map((axis) => [axis, [...(this.options.limits?.[axis] ?? DEFAULT_LIMITS[axis])]])); + const unsigned = { schema: "wasm-xyzac-kinematics.v1", active_type: activeMode, native_type: nativeType, coordinates: "XYZAC", joint_count: 5, linear_units: "mm", angular_units: "deg", pose: currentPose, joints: joints.slice(0, 5), offsets: { x_rot_point: this.options.x_rot_point, y_offset: this.options.y_offset, z_offset: this.options.z_offset, tool_offset: this.options.tool_offset }, limits, generation: view.getUint32(SWITCH.generation, true), switch_count: view.getUint32(SWITCH.switch_count, true), abort_count: view.getUint32(SWITCH.abort_count, true), last_command: this.lastCommand, capability: { userk: "linked_identity_template", dynamic_modules: "denied" }, source: "linuxcnc-wasm-sim_kinematics_switch" }; + const hash = call(this.core, "sim_kinematics_switch_state_hash", "number", ["number", "number", "number", "number"], [this.switchPointer, this.jointPointer, 5, this.posePointer]); + return { status: "verified", ...unsigned, wasm_state_hash: `fnv1a64:${BigInt.asUintN(64, BigInt(hash >>> 0)).toString(16).padStart(16, "0")}`, state_hash: fnv1a64(unsigned) }; + } + + destroy() { for (const pointer of this.pointers) if (pointer && typeof this.core?._free === "function") this.core._free(pointer); this.pointers = []; } +} + +export { MODE as XYZAC_MODES }; diff --git a/web/worker/xyzac-command-ledger.mjs b/web/worker/xyzac-command-ledger.mjs new file mode 100644 index 0000000..317f3ed --- /dev/null +++ b/web/worker/xyzac-command-ledger.mjs @@ -0,0 +1,54 @@ +import { OperationLedger, LEDGER_SCHEMA, LEDGER_PHASES } from "./operation-ledger.mjs"; +import { fnv1a64 } from "./replay.mjs"; + +export const XYZAC_COMMAND_LEDGER_SCHEMA = "xyzac-command-ledger.v1"; +const TERMINAL_PHASES = new Set(["committed", "aborted", "failed"]); + +export class XyzacCommandLedger extends OperationLedger { + constructor(entries = []) { + super(entries); + this.scope = "selected_xyzac_simulation"; + } + + prepare(input) { + if (["HELLO", "CAPABILITIES", "SNAPSHOT_REQUEST", "CANCEL"].includes(input?.kind)) return { status: "untracked", replay: false, entry: null }; + const result = super.prepare(input); + if (result.entry) { + result.entry.scope = this.scope; + result.entry.intent_hash = result.entry.intent_hash ?? fnv1a64({ kind: input.kind, payload: input.payload ?? {}, operation_id: input.operation_id }); + } + return result; + } + + acknowledge(operationId, response) { + return this.verify(operationId, response); + } + + result(operationId, response, seq) { + this.acknowledge(operationId, response); + return this.commit(operationId, seq); + } + + pending() { + return [...this.entries.values()] + .filter((entry) => !TERMINAL_PHASES.has(entry.phase)) + .sort((left, right) => left.seq - right.seq) + .map((entry) => structuredClone(entry)); + } + + reconcileAll() { + return this.pending().map((entry) => ({ operation_id: entry.operation_id, status: entry.phase, entry })); + } + + timeoutReconcile(operationId) { + const reconciliation = this.reconcile(operationId); + return { status: "reconcile_required", operation_id: operationId, retry_allowed: false, reconciliation }; + } + + audit() { + const exported = super.export(); + const pending = this.pending(); + const unsigned = { schema: XYZAC_COMMAND_LEDGER_SCHEMA, operation_schema: LEDGER_SCHEMA, phases: [...LEDGER_PHASES], scope: this.scope, entries: exported.entries, pending_count: pending.length }; + return { ...unsigned, state_hash: fnv1a64(unsigned) }; + } +} diff --git a/web/worker/xyzac-scheduler.mjs b/web/worker/xyzac-scheduler.mjs new file mode 100644 index 0000000..0a36933 --- /dev/null +++ b/web/worker/xyzac-scheduler.mjs @@ -0,0 +1,45 @@ +import { SimScheduler, SCHEDULER_PHASES } from "./sim-scheduler.mjs"; +import { fnv1a64 } from "./replay.mjs"; + +export const XYZAC_SCHEDULER_SCHEMA = "xyzac-scheduler.v1"; +export const XYZAC_SCHEDULER_PHASES = Object.freeze([...SCHEDULER_PHASES]); + +export class XyzacScheduler extends SimScheduler { + constructor(core, { budget = 1_000_000, cycleTime = 0.01 } = {}) { + super(core, { budget }); + this.cycle_time = cycleTime; + this.authority = "linuxcnc-wasm-worker"; + this.clock = "logical_tick"; + this.machine = Object.freeze({ coordinates: "XYZAC", joint_count: 5, rotary_units: "degrees", kinematics: "xyzac-trt" }); + } + + step(cycles, callbacks = {}) { + if (!Number.isSafeInteger(cycles) || cycles < 0) throw new Error("xyzac_scheduler_cycles_invalid"); + const result = super.step(cycles, callbacks); + return this.export({ last_step_cycles: cycles, state_hash: result.state_hash }); + } + + export(extra = {}) { + const unsigned = { + schema: XYZAC_SCHEDULER_SCHEMA, + authority: this.authority, + clock: this.clock, + cycle_time: this.cycle_time, + machine: this.machine, + budget: this.budget, + tick: this.tick, + last_cycles: this.last_cycles, + phase_trace: [...this.phase_trace], + ...extra, + }; + delete unsigned.state_hash; + return { ...unsigned, state_hash: fnv1a64(unsigned) }; + } + + restore(value) { + if (!value || value.schema !== XYZAC_SCHEDULER_SCHEMA || value.clock !== "logical_tick" || value.machine?.coordinates !== "XYZAC" || value.machine?.joint_count !== 5) throw new Error("xyzac_scheduler_restore_scope"); + const base = { schema: "sim_scheduler.v1", budget: value.budget, last_cycles: value.last_cycles, phase_trace: value.phase_trace, tick: value.tick, state_hash: fnv1a64({ schema: "sim_scheduler.v1", budget: value.budget, phase_trace: value.phase_trace, tick: value.tick }) }; + super.restore(base); + return this.export(); + } +} diff --git a/web/worker/xyzac-session.mjs b/web/worker/xyzac-session.mjs new file mode 100644 index 0000000..381c2d9 --- /dev/null +++ b/web/worker/xyzac-session.mjs @@ -0,0 +1,40 @@ +import { SimSession, CONTEXT_ID, PROTOCOL_SCHEMA } from "./sim-session.mjs"; +import { XyzacCommandLedger, XYZAC_COMMAND_LEDGER_SCHEMA } from "./xyzac-command-ledger.mjs"; +import { XyzacScheduler, XYZAC_SCHEDULER_SCHEMA } from "./xyzac-scheduler.mjs"; + +export const XYZAC_SESSION_SCHEMA = "xyzac-session.v1"; + +export class XyzacSession extends SimSession { + constructor(core, options = {}) { + super(core, options); + this.ledger = new XyzacCommandLedger(); + this.scheduler = new XyzacScheduler(core); + this.session_scope = "selected_xyzac_simulation"; + } + + authority() { + return { + schema: XYZAC_SESSION_SCHEMA, + authority: "linuxcnc-wasm-worker", + context_id: this.contextId, + session_id: this.sessionId, + scope: this.session_scope, + protocol_schema: PROTOCOL_SCHEMA, + ledger_schema: XYZAC_COMMAND_LEDGER_SCHEMA, + scheduler_schema: XYZAC_SCHEDULER_SCHEMA, + machine: { coordinates: "XYZAC", joint_count: 5, kinematics: "xyzac-trt", rotary_units: "degrees" }, + }; + } + + accept(input) { + const response = super.accept(input); + if (response?.payload && typeof response.payload === "object") { + response.payload.xyzac_session = this.authority(); + response.payload.xyzac_ledger = this.ledger.audit(); + response.payload.xyzac_scheduler = this.scheduler.export(); + } + return response; + } +} + +export { CONTEXT_ID, PROTOCOL_SCHEMA }; diff --git a/web/workspace/opfs-runtime.mjs b/web/workspace/opfs-runtime.mjs index aef3a98..661218a 100644 --- a/web/workspace/opfs-runtime.mjs +++ b/web/workspace/opfs-runtime.mjs @@ -38,7 +38,7 @@ export async function runOpfsProbe({ storage, projectId = "s6-05-opfs", mode = " const probe = opfsCapability({ navigator: { storage } }); if (probe.status !== "verified") return { schema: OPFS_RUNTIME_SCHEMA, ...probe, project_id: projectId }; if (!validProjectId(projectId)) return { schema: OPFS_RUNTIME_SCHEMA, status: "blocked", code: "opfs_project_id_invalid" }; - if (!["round_trip", "write", "read"].includes(mode)) return { schema: OPFS_RUNTIME_SCHEMA, status: "blocked", code: "opfs_mode_invalid", project_id: projectId }; + if (!["round_trip", "write", "read", "corrupt"].includes(mode)) return { schema: OPFS_RUNTIME_SCHEMA, status: "blocked", code: "opfs_mode_invalid", project_id: projectId }; let access = null; try { const rootResult = await rootHandle(storage); @@ -64,6 +64,18 @@ export async function runOpfsProbe({ storage, projectId = "s6-05-opfs", mode = " access.close(); access = null; if (mode === "write") return { schema: OPFS_RUNTIME_SCHEMA, status: "verified", mode, project_id: projectId, bytes: encoded.byteLength, commit_seq: record.commit_seq, content_hash: record.content_hash, cleanup: false }; + if (mode === "corrupt") { + const corrupt = await file.createSyncAccessHandle(); + corrupt.write(TEXT_ENCODER.encode("{corrupt"), { at: 0 }); + corrupt.flush(); + corrupt.close(); + let damaged = null; + try { damaged = JSON.parse(await (await file.getFile()).text()); } catch { damaged = null; } + if (cleanup) { await project.removeEntry(FILE_NAME); await directory.removeEntry(projectId); } + return !validateCommittedRecord(damaged, projectId) + ? { schema: OPFS_RUNTIME_SCHEMA, status: "verified", mode, project_id: projectId, corruption_detected: true, cleanup } + : { schema: OPFS_RUNTIME_SCHEMA, status: "blocked", code: "opfs_corruption_undetected", project_id: projectId }; + } const persisted = JSON.parse(await (await file.getFile()).text()); const valid = written === encoded.byteLength && size === encoded.byteLength && JSON.stringify(persisted) === JSON.stringify(record); if (cleanup) { await project.removeEntry(FILE_NAME); await directory.removeEntry(projectId); } diff --git a/web/workspace/sim-case-catalog.mjs b/web/workspace/sim-case-catalog.mjs index 9bee450..6f8e381 100644 --- a/web/workspace/sim-case-catalog.mjs +++ b/web/workspace/sim-case-catalog.mjs @@ -1,6 +1,6 @@ // Generated by scripts/generate_sim_case_catalog.py. Do not edit by hand. export const SIM_CASE_CATALOG_SCHEMA = "linuxcnc-sim-case-catalog.v1"; -export const SIM_CASE_CATALOG = Object.freeze([{"path":"linuxcnc/configs/sim/axis/anglejog/anglejog.ini","label":"LATHE-Anglejog","category":"axis/anglejog","display":"axis","coordinates":"X Z","kinematics":"trivkins coordinates=xz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"2a8c89afad09a946eddae548b3bfdc3aa4c1f385e785e24a6a50db722215d035"},{"path":"linuxcnc/configs/sim/axis/axis.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"axis","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":8,"unresolved_count":0,"source_sha256":"a41915c4d0d48f46dd595d5d269e2fc73962f7d19897b220368dbc0e4dc96594"},{"path":"linuxcnc/configs/sim/axis/axis_9axis.ini","label":"LinuxCNC-sim-9axis","category":"axis","display":"axis","coordinates":"X Y Z A B C U V W","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"6e3b7b49ed0ed5d840ff8052c05d9c50dad4baba7c9b0bef43a774056388b403"},{"path":"linuxcnc/configs/sim/axis/axis_mm.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"axis","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":7,"unresolved_count":0,"source_sha256":"233aca0e517d0e6d70fa21da86734f6db80d4bee3761b28af92981bda1450749"},{"path":"linuxcnc/configs/sim/axis/canterp.ini","label":"Canterp Example","category":"axis","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"6d7fa7ff7b5586731297f3c1da653c9266da87cd54a7351f361a9fd9ba1fee36"},{"path":"linuxcnc/configs/sim/axis/classicladder/demo_sim_cl.ini","label":"LinuxCNC-DEMO-SIM-CL","category":"axis/classicladder","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"db8d3ac20cfb5cbdb3cc2c888cbadcbdc296b1e0dc171afabcdc167d2442581c"},{"path":"linuxcnc/configs/sim/axis/corexy/corexy_by_hal.ini","label":"corexy_by_hal","category":"axis/corexy","display":null,"coordinates":null,"kinematics":"trivkins coordinates=XYZ kinstype=b","family":"cartesian","status":"ready","startup_preflight":"static_ready","resource_status":"ready","missing_count":0,"unresolved_count":0,"source_sha256":"e838da30ce5fba2d049487d48bd2aeff46b1390a5a448f31980d9ce06121740f"},{"path":"linuxcnc/configs/sim/axis/corexy/corexy_by_kins.ini","label":"corexy_by_kins","category":"axis/corexy","display":null,"coordinates":null,"kinematics":"corexykins","family":"coupled_linear","status":"ready","startup_preflight":"static_ready","resource_status":"ready","missing_count":0,"unresolved_count":0,"source_sha256":"b6682cc5186944a44c2aa78501c4f350e56b4da1151348fa9fc3ece5f0eeea3a"},{"path":"linuxcnc/configs/sim/axis/db_demo/db_nonran.ini","label":"db_nonran NONRANDOM toolchanger","category":"axis/db_demo","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"5da7358586f1d94de2564011d161817b694105f81d076fba6b922e1fab8a42fb"},{"path":"linuxcnc/configs/sim/axis/db_demo/db_ran.ini","label":"db_ran RANDOM toolchanger","category":"axis/db_demo","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"d53daf2cd1bb1fb43538c4ba5194fe72b660c9fd3f3812e54429c84b9005468e"},{"path":"linuxcnc/configs/sim/axis/external_offsets/dynamic_offsets.ini","label":"Dynamic External Offsets","category":"axis/external_offsets","display":"axis","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"4889a5b4227148c706ec527dda91ae4229161f23d942f62aec122492ee8138c7"},{"path":"linuxcnc/configs/sim/axis/external_offsets/eoffsets.ini","label":"External Offsets Demo","category":"axis/external_offsets","display":"axis","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"d6002e2682da417caf66fcae6d6bee9df4c44f1f3355ef70a7f759ed57ad74f7"},{"path":"linuxcnc/configs/sim/axis/external_offsets/jwp_z.ini","label":"Jog-While-Pause Z Demo","category":"axis/external_offsets","display":"axis","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"0e48f593dc6412e59d41844b58f2b3e1ff1e1c3659d38d64f06e4bb893a0f5e5"},{"path":"linuxcnc/configs/sim/axis/external_offsets/opa.ini","label":"External Offset(X) per Angle(C) Demo","category":"axis/external_offsets","display":"axis","coordinates":"XZC","kinematics":"trivkins coordinates=XZC","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"b965264ad6d7a50a5332f8dd2f29928598fce155ec7954511cbdce549b9ff002"},{"path":"linuxcnc/configs/sim/axis/extrajoints/12extrajoints.ini","label":"12extrajoints","category":"axis/extrajoints","display":"axis","coordinates":"XYYZ","kinematics":"trivkins coordinates=XYYZ kinstype=both","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"7b869a94e99c728403cb5fd38b949a1a95ab93a793e3d2b803dd85902595a0af"},{"path":"linuxcnc/configs/sim/axis/extrajoints/1extrajoint.ini","label":"1extrajoint","category":"axis/extrajoints","display":"axis","coordinates":"XYYZ","kinematics":"trivkins coordinates=XYYZ kinstype=both","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"2c3bec6dcab552b34c84e1cfba25270afe1720f7a2ebf34a9d76cba800d0d538"},{"path":"linuxcnc/configs/sim/axis/extrajoints/2extrajoints.ini","label":"2extrajoints","category":"axis/extrajoints","display":"axis","coordinates":"XYYZ","kinematics":"trivkins coordinates=XYYZ kinstype=both","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"cc254899d06dcd870a978cf22ec832b7b6c6603022749a1602e81a8d92afa950"},{"path":"linuxcnc/configs/sim/axis/foam/axis_foam.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"axis/foam","display":"axis","coordinates":"X Y U V","kinematics":"trivkins coordinates=xyuv","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"a176d322e607957f554a954e2cf5e4241ff4ef1181b609990044dcc3432ff958"},{"path":"linuxcnc/configs/sim/axis/gantry/gantry.ini","label":"LinuxCNC-GANTRY-SIM-AXIS","category":"axis/gantry","display":"axis","coordinates":"XYZY","kinematics":"trivkins coordinates=XYZY kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":8,"unresolved_count":0,"source_sha256":"acc7db8d6a38a64598ef277dfea3480f0e7400d461784a0fa0139bded93d5a68"},{"path":"linuxcnc/configs/sim/axis/gantry/gantry_jjog.ini","label":"gantry_jjog-sim","category":"axis/gantry","display":"axis","coordinates":"XYZY","kinematics":"trivkins coordinates=XYZY kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":9,"unresolved_count":0,"source_sha256":"da911359e075e5dbf9f129bafc389e059aa0f754bb4c0ce67b410ac63e5f91ab"},{"path":"linuxcnc/configs/sim/axis/gantry/gantry_mm.ini","label":"EMC-HAL-SIM-GANTRY","category":"axis/gantry","display":"axis","coordinates":"X Y Y Z","kinematics":"trivkins coordinates=xyyz kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"0692df9758234ff4cb29b22ee58688fe2bf450d93cc386ae096e0a943ef475e3"},{"path":"linuxcnc/configs/sim/axis/geometry/xyzc.ini","label":"xyzc (offset rotations)","category":"axis/geometry","display":"axis","coordinates":"X Y Z C","kinematics":"trivkins coordinates=XYZC kinstype=both","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"cafbb5d4c275be232cadb1c4b11d84b2791e8c5544c20f84a7eed3b5ed8bab1e"},{"path":"linuxcnc/configs/sim/axis/geometry/xyzc_origin.ini","label":"xyzc_origin (rotations wrt machine origin)","category":"axis/geometry","display":"axis","coordinates":"X Y Z C","kinematics":"trivkins coordinates=XYZC kinstype=both","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"77aba40722c7a481aad66e3bf05b3fe283965b01d6444c1abc78841c6154363a"},{"path":"linuxcnc/configs/sim/axis/gladevcp/gladevcp_panel.ini","label":"LinuxCNC-PANEL-GLADEVCP","category":"axis/gladevcp","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"c216752c2f032d47fe3910f6b66ac6375c8cb1201b6393b2f01b9c978f0708e6"},{"path":"linuxcnc/configs/sim/axis/gladevcp/gladevcp_panel_tester.ini","label":"LinuxCNC-PANEL-GLADEVCP","category":"axis/gladevcp","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"e8e88a97002d008d234d664d6f14e866b39c89fc09d2d392fffb80367cb6ed68"},{"path":"linuxcnc/configs/sim/axis/gladevcp/gladevcp_tab.ini","label":"LinuxCNC-TAB-GLADEVCP","category":"axis/gladevcp","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"bdbad54582ad4f4cb304bf5c33ea3d45dc7b88a21445cc12737d5fc245624890"},{"path":"linuxcnc/configs/sim/axis/gladevcp/probe.ini","label":"gladevcp_probe","category":"axis/gladevcp","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"66b8ba2d3c6c21409a6686923540058c85fcd5632ffb9827315a5b0f518c5ec9"},{"path":"linuxcnc/configs/sim/axis/gladevcp/set-param-from-ini.ini","label":"set-param-from-ini","category":"axis/gladevcp","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"651f25fd7656f739c2ae57f033183ba82fecb07b29c0b8b908608ce4d21ab6f5"},{"path":"linuxcnc/configs/sim/axis/halui_pyvcp/halui.ini","label":"LinuxCNC-HALUI-PYVCP","category":"axis/halui_pyvcp","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"b74f150915d006fe9ecd14ea0bcb231b7e04d1d44649020de7e0324f1782d3f5"},{"path":"linuxcnc/configs/sim/axis/histogram_demo.ini","label":"ini_hal_demo","category":"axis","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"3eabc315db8e9e21951438ebd95fc5f30cf9b0d5ecb5277e66138f3ccdbdc7f8"},{"path":"linuxcnc/configs/sim/axis/historical_lathe.ini","label":"Historical-LATHE","category":"axis","display":"axis","coordinates":"X Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":6,"unresolved_count":0,"source_sha256":"62809856093198b7a584553d71633a5b40210a059223277d2d3e640563e2de68"},{"path":"linuxcnc/configs/sim/axis/ini_hal_demo.ini","label":"ini_hal_demo","category":"axis","display":"axis","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz kinstype=both","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"9abb6d63c35d14d440366d822283521c9169a89fc36d4685c4597fa77fab2879"},{"path":"linuxcnc/configs/sim/axis/ini_with_includes/includes_demo.ini","label":"includes demo","category":"axis/ini_with_includes","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"64e0ecbb9fa8d17c54e71c1d59ada6cb79f61f1565f62d57cd2bece9c7237704"},{"path":"linuxcnc/configs/sim/axis/iocontrolv2/axis-iocontrolv2-demo.ini","label":"axis-iocontrolv2-demo","category":"axis/iocontrolv2","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"9e23e1329c3dcd721f6b65f001b77dbd90e88d19b374545c250c49a88442deff"},{"path":"linuxcnc/configs/sim/axis/iocontrolv2/g8812.ini","label":"g8812","category":"axis/iocontrolv2","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"334ca534c3eafac4022c5895431515f8f05bbd2a1f150ae09e53b88938b2fd1a"},{"path":"linuxcnc/configs/sim/axis/iocontrolv2/m66track.ini","label":"m66track","category":"axis/iocontrolv2","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"c91c56594fb99934a677786e7f8b6b90299cb29f4d8b3be3e85fe9a957579a69"},{"path":"linuxcnc/configs/sim/axis/iocontrolv2/owordm6-ui-ns.ini","label":"owordm6-ui-ns","category":"axis/iocontrolv2","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"1b4cdcba969b9494cc5137d602a9a9c216d158f89e3279cff6a41a035b0f9961"},{"path":"linuxcnc/configs/sim/axis/iocontrolv2/owordm6-ui.ini","label":"owordm6-ui","category":"axis/iocontrolv2","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"b8de1b4257ef8b8eded585e02e36e3ee6caedad53b3f18f45f94bc9cc0b12b2b"},{"path":"linuxcnc/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyyzb.ini","label":"XYYZB trivkins coordinates=xyyzb KINEMATICS_BOTH","category":"axis/ja_tests/xyzb_locking_indexer","display":"axis","coordinates":"X Y Y Z B","kinematics":"trivkins coordinates=xyyzb kinstype=both","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":6,"unresolved_count":0,"source_sha256":"466833eb371da18428abeac86d759fe36ed5bff73b60a51c10e5303e39c86316"},{"path":"linuxcnc/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyzb.ini","label":"XYZB trivkins coordinates=xyzb","category":"axis/ja_tests/xyzb_locking_indexer","display":"axis","coordinates":"X Y Z B","kinematics":"trivkins coordinates=xyzb","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"796eacff0e56b2a65d9367836f8c9a17c7f967ae467bc1077503c18f57d362db"},{"path":"linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/xyzx-xhc-hb04.ini","label":"xyzx-xhc-hb04","category":"axis/ja_tests/xyzx_mpg","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"565d8d65dda4aa26a14c7ae641a81d7c5a0bc311ab308e63bdbebcf910aacdb9"},{"path":"linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/xyzx.ini","label":"xyzx","category":"axis/ja_tests/xyzx_mpg","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"6888dfaee112f61d521e0f3cc3af5603863303e24e8e60c80a76b04f88127087"},{"path":"linuxcnc/configs/sim/axis/ja_tests/xz/xz.ini","label":"trivkins XZ KINEMATICS_IDENTITY","category":"axis/ja_tests/xz","display":null,"coordinates":null,"kinematics":"trivkins coordinates=xz","family":"cartesian","status":"ready","startup_preflight":"static_ready","resource_status":"ready","missing_count":0,"unresolved_count":0,"source_sha256":"07f5257557a540b02781de3a641dd1830a78a4cbb15a9cc68ad8d2c6eae8ec81"},{"path":"linuxcnc/configs/sim/axis/ja_tests/xz/xz_both.ini","label":"trivkins XZ KINEMATICS_BOTH","category":"axis/ja_tests/xz","display":null,"coordinates":null,"kinematics":"trivkins coordinates=xz kinstype=BOTH","family":"cartesian","status":"ready","startup_preflight":"static_ready","resource_status":"ready","missing_count":0,"unresolved_count":0,"source_sha256":"d75c9e05e2a781d1344b3840ba82adc6d7d8d47f53aa11b04c3b918d20c5faae"},{"path":"linuxcnc/configs/sim/axis/ja_tests/xz/xz_both_auto.ini","label":"trivkins XZ KINEMATICS_BOTH,AUTO TELEOP","category":"axis/ja_tests/xz","display":null,"coordinates":null,"kinematics":"trivkins coordinates=xz kinstype=BOTH","family":"cartesian","status":"ready","startup_preflight":"static_ready","resource_status":"ready","missing_count":0,"unresolved_count":0,"source_sha256":"d94eae8d51a00027f75ff45b84f14e2721de466c4be1af3a5e15d7beeec58ac3"},{"path":"linuxcnc/configs/sim/axis/laser/laser.ini","label":"laser","category":"axis/laser","display":"axis","coordinates":"XYZ","kinematics":"corexykins","family":"coupled_linear","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"343fcbd64cde1f191b3f9835b56bc8ad4ee244cf1eca824b7c7ec07305a260bd"},{"path":"linuxcnc/configs/sim/axis/lathe-fanucy/lathe-fanucy.ini","label":"lathe-fanucy","category":"axis/lathe-fanucy","display":"axis","coordinates":"X Z","kinematics":"trivkins coordinates=xz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"be3724c6093b9d507e40d41ef1f5047c3244e8a95acba3aaa72176e15752675c"},{"path":"linuxcnc/configs/sim/axis/lathe.ini","label":"LinuxCNC-HAL-SIM-LATHE","category":"axis","display":"axis","coordinates":"X Z","kinematics":"trivkins coordinates=xz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"e1ce3667979cf2ea4813aa492c2061727d3f02a4d9592db0e4889f4fa53a6447"},{"path":"linuxcnc/configs/sim/axis/lathe_multispindle/lathe.ini","label":"LinuxCNC-HAL-SIM-LATHE","category":"axis/lathe_multispindle","display":"axis","coordinates":"X Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"fb2dbd47226cf39cc2149850e44d22324c6d6af886e1a2a0d43fa8d9ff36efe6"},{"path":"linuxcnc/configs/sim/axis/ldelta.ini","label":"Delta-robot-with-linear-joints","category":"axis","display":"axis","coordinates":"X Y Z A","kinematics":"lineardeltakins","family":"parallel_delta","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"1567138c3d54b4d9712b5031f6a0b060edadd8d1442d1eff8d93c2beefbb5e0c"},{"path":"linuxcnc/configs/sim/axis/ldelta_demo.ini","label":"Delta-robot-with-linear-joints","category":"axis","display":"axis","coordinates":"X Y Z A","kinematics":"lineardeltakins","family":"parallel_delta","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"ab0645308abe903bf66f36a328b43303aa0e8ad2d19e69a45e2703d665956439"},{"path":"linuxcnc/configs/sim/axis/minimal_xyz.ini","label":"minimal xyz","category":"axis","display":"axis","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"63923bfb90f4aba843cb89f8dccc34732d803e2bfd5598ed23a2ba22f360d00a"},{"path":"linuxcnc/configs/sim/axis/moveoff/1_onpause_local.ini","label":"moveoff,onpause,local","category":"axis/moveoff","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"d773e556b4692d60fe55b68d92a02ee69ba1dd128ef3ae4936327fc0f4451761"},{"path":"linuxcnc/configs/sim/axis/moveoff/2_onpause_external.ini","label":"moveoff,onpause,external","category":"axis/moveoff","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"d5f20008f4f1d9f81c9fbb871b56ca5098c35b5428014fcfcbaf2da516a8143a"},{"path":"linuxcnc/configs/sim/axis/moveoff/3_always_local.ini","label":"moveoff,always,local","category":"axis/moveoff","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"248af931464559c734115afa4c6d7989d7ea4fbc047e8e97a5306baef72b3a8c"},{"path":"linuxcnc/configs/sim/axis/moveoff/4_always_external.ini","label":"moveoff,always,external","category":"axis/moveoff","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"0bb9c9089b579c83afe8286623bdf7c0167e6544ddf73e84217a74cf952205f7"},{"path":"linuxcnc/configs/sim/axis/moveoff/5_no_gui.ini","label":"moveoff,no_gui","category":"axis/moveoff","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"e4e29328d1434e870018460aaaaf986b8e32ed5aa8f4c043d1df7a24f8438376"},{"path":"linuxcnc/configs/sim/axis/moveoff/6_zretract.ini","label":"moveoff zretract demo","category":"axis/moveoff","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"5a8aff43dbb07753e983a562f0ea79eaa0859e9214155bb2657a1d2bde18ec50"},{"path":"linuxcnc/configs/sim/axis/moveoff/7_pyvcp.ini","label":"moveoff,onpause,external","category":"axis/moveoff","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"e0fd69e140a109f84e2cd418f91d1312badb8db0d7d8861e42753955140602d2"},{"path":"linuxcnc/configs/sim/axis/moveoff/8_gladevcp.ini","label":"moveoff,onpause,external","category":"axis/moveoff","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"a67d7d08de6e0f675280ab4b9d9a50bbf400eae364913282d5370307900180b2"},{"path":"linuxcnc/configs/sim/axis/ngcgui/ngcgui.ini","label":"Ngcgui-demo","category":"axis/ngcgui","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"a461d37954c2e621505a4f8b6387c00a37489236ccf8522370e3076ddca33b00"},{"path":"linuxcnc/configs/sim/axis/ngcgui/ngcgui_gcmc.ini","label":"Ngcgui-gcmc-demo","category":"axis/ngcgui","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"a4cb71679b44afeb5734f8f07d1e2f63332faff54bfd7f9bfd4abfe706a651fe"},{"path":"linuxcnc/configs/sim/axis/ngcgui/ngcgui_lathe.ini","label":"ngcgui-lathe","category":"axis/ngcgui","display":"axis","coordinates":"X Z","kinematics":"trivkins coordinates=xz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"ec11d67522375c3cd1afbb76b5f12cbe6e5e9e51b430697f54b0e7088639db5a"},{"path":"linuxcnc/configs/sim/axis/ngcgui/ngcgui_simple.ini","label":"Ngcgui-demo","category":"axis/ngcgui","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"ec42c49461f66a395154b09e18d94674a17e8a7249791c5adf33b85ea6a19640"},{"path":"linuxcnc/configs/sim/axis/ngcgui/pyngcgui_axis.ini","label":"pyngcgui-axis demo","category":"axis/ngcgui","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"71f8ed201b46c4642e3f7d787065940e5d29b31452a5802056ede460cecd9f52"},{"path":"linuxcnc/configs/sim/axis/orphans/acc_test.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"axis/orphans","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"8a47360f16911553f9d1a046486ae507e1ee26f314f7ff37b250d5dca420c24a"},{"path":"linuxcnc/configs/sim/axis/orphans/axis_noio.ini","label":"axis_noio","category":"axis/orphans","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"1358837965ce189bb445b1d75d7d4688fb9353ec02a9f3dae53fd3601a9943cc"},{"path":"linuxcnc/configs/sim/axis/orphans/iocontrol-removed/iocontrol-removed.ini","label":"iocontrol-removed.ini","category":"axis/orphans/iocontrol-removed","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"6777d316581462ba253cec0f5e72ff148d7539bdd21b5e268c3e8da2455a7f31"},{"path":"linuxcnc/configs/sim/axis/orphans/medium.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"axis/orphans","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":6,"unresolved_count":0,"source_sha256":"258bcd736539fa2d47af1d2c99dd748a2803f8b065c1ef0171e5a98cdbbbb0a6"},{"path":"linuxcnc/configs/sim/axis/panelui-demo/_panelui.ini","label":" panelui","category":"axis/panelui-demo","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"899a352a6198675cff2deb303e52ff7e86715d1c8f7cb8c16c5a7ec9a11b3c60"},{"path":"linuxcnc/configs/sim/axis/panelui-demo/panelui-demo.ini","label":"panelui-demo","category":"axis/panelui-demo","display":"axis","coordinates":"X Z","kinematics":"trivkins coordinates=xz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"9b47416920a284322363e47771e612fca7415a0a0a594f9f7cbdf4a502c4757e"},{"path":"linuxcnc/configs/sim/axis/pentapod/pentapod.ini","label":"SIM-PENTAPOD","category":"axis/pentapod","display":"axis","coordinates":"X Y Z A B","kinematics":"pentakins","family":"parallel_pentapod","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"0fb210122ab482087d3a95e5e7487baecb84c3260dca1769970f4c19b2ad0618"},{"path":"linuxcnc/configs/sim/axis/plasma/imperial.ini","label":"imperial","category":"axis/plasma","display":"axis","coordinates":"XYYZ","kinematics":"trivkins coordinates=xyyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"c531ab622b904085f05e9fa6fdf791c0a5ec15153f2e22acd5273676a35a9a25"},{"path":"linuxcnc/configs/sim/axis/plasma/metric.ini","label":"metric","category":"axis/plasma","display":"axis","coordinates":"XYYZ","kinematics":"trivkins coordinates=xyyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"7dab2e05a237c1a8ec472e9c09b03ac8a4a016786207d83aa17fa142a5d4defe"},{"path":"linuxcnc/configs/sim/axis/profile_axis.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"axis","display":"profile_axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"f3e7bed9eeecea860ab15d9eef4319715eedcb13315b25f9e62ac9797baed7bb"},{"path":"linuxcnc/configs/sim/axis/qtvcp/qtvcp_tab.ini","label":"LinuxCNC-TAB-GLADEVCP","category":"axis/qtvcp","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"29d36b3435bc7b410d8dd57f794c9254a91c11ad06d1b26ad3be39489c4d51ee"},{"path":"linuxcnc/configs/sim/axis/qtvcp/qtvismach_tab.ini","label":"LinuxCNC-TAB-GLADEVCP","category":"axis/qtvcp","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"5e610fd07b44d291422378996f098fa27e4dc075e3f3fb49ad6267471b426206"},{"path":"linuxcnc/configs/sim/axis/random_tc.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"axis","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"d0b1614f287c10ad0d6dabf81aac69f78e187dddae30225ccaf501c8fdef0f29"},{"path":"linuxcnc/configs/sim/axis/rdelta.ini","label":"Delta-robot-with-rotary-joints","category":"axis","display":"axis","coordinates":"X Y Z A B C U V W","kinematics":"rotarydeltakins","family":"parallel_delta","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"53510733b8fd0230547f48f76ebd35dc5c98f58fe1dba1246777e227ef82c508"},{"path":"linuxcnc/configs/sim/axis/remap/cycle/cycle.ini","label":"cycle.ini","category":"axis/remap/cycle","display":"axis","coordinates":"X Y Z A B C U V W","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"ee64fa142ddf5a5288cae36a39445a32488250755f72ea5a1d3df436c2694e8c"},{"path":"linuxcnc/configs/sim/axis/remap/extend-builtins/extend-builtins.ini","label":"extend-builtins.ini","category":"axis/remap/extend-builtins","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"432ff320ac6d3518a73ae69e924c343c0740d04475a09f99391304f5f7e8cc76"},{"path":"linuxcnc/configs/sim/axis/remap/getting-started/demo.ini","label":"getting-started:demo.ini","category":"axis/remap/getting-started","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"763dd31e6eb32047eb35eecb933f822db3a65e87b1a214f982517369eecdd976"},{"path":"linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/manualtoolchange.ini","label":"manualtoolchange.ini","category":"axis/remap/manual-toolchange-with-tool-length-switch","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"6d52f5596d0f0f90c9a2da5a0802d6dfe35c4fbfe1c9cd4e9e6f34a3ab52e064"},{"path":"linuxcnc/configs/sim/axis/remap/rack-toolchange/racktoolchange.ini","label":"racktoolchange.ini","category":"axis/remap/rack-toolchange","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"742f1ca34ffc95b1781673ca6ebed5cc23376cc7d94c520d4f8d4036699109e5"},{"path":"linuxcnc/configs/sim/axis/remap/stop-lookahead/demo.ini","label":"stop-lookahead:demo.ini","category":"axis/remap/stop-lookahead","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"aea088d4bb017ac0474dca3f696c76533d374cac5a40b71944d76a1c89e9dafc"},{"path":"linuxcnc/configs/sim/axis/rose_engine/rose_engine.ini","label":"Roseengine","category":"axis/rose_engine","display":"axis","coordinates":"XYZ","kinematics":"rosekins","family":"coupled_linear","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":3,"unresolved_count":1,"source_sha256":"0685e9ca8c05c903b715e9fed6ecd23cbac13911ed335b6d14e24eb235de25d3"},{"path":"linuxcnc/configs/sim/axis/rotate/rotatekins.ini","label":"rotatekins_candidate","category":"axis/rotate","display":null,"coordinates":"XYZABC","kinematics":"rotatekins","family":"cartesian","status":"blocked","startup_preflight":"blocked_unindexed_resource_graph","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"324af9a73d21b5f0c9adaf3c97e698422790d403586901f9e161b6020b1fb4fa"},{"path":"linuxcnc/configs/sim/axis/simtcl/twopass_basic.ini","label":"twopass_basic","category":"axis/simtcl","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"b19e33bdaccebf5e060acdb5b0239b438a8f76c0e84dd1374420775f989bf766"},{"path":"linuxcnc/configs/sim/axis/simtcl/twopass_compat.ini","label":"twopass_compat","category":"axis/simtcl","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"d85d2940827bb6b2c945f69ef1ad18141bdc72f5c3391a7d816605320fd7ae57"},{"path":"linuxcnc/configs/sim/axis/spindle_orient/orient.ini","label":"M19-Orient-demo","category":"axis/spindle_orient","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":6,"unresolved_count":0,"source_sha256":"98d9ca88da31ae88a2ae51b80027939a6ebc6e700326ee7f3a108506aa908b04"},{"path":"linuxcnc/configs/sim/axis/twopass/twopass.ini","label":"SIM-AXIS-TWOPASS","category":"axis/twopass","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":7,"unresolved_count":0,"source_sha256":"9b88396ab9461605c378ba933faf6cf17bfc7c960220e6fb4573d17c81f24526"},{"path":"linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini","label":"3axis-tutorial","category":"axis/vismach/3axis-tutorial","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":3,"unresolved_count":1,"source_sha256":"b801d4fb7a3d66fac7a4202d56c384f75b039f55c70cce64c2975c5454875388"},{"path":"linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/5axis.ini","label":"Sim-5Axis Bridge Mill (xyzbcw)","category":"axis/vismach/5axis/bridgemill","display":"axis","coordinates":"XYZBCWY","kinematics":"5axiskins coordinates=xyzbcwy","family":"five_axis","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"789ba656f8ee3e97feba07b58eb242305898e745795891b1a7e536289bffe6bf"},{"path":"linuxcnc/configs/sim/axis/vismach/5axis/max5/max5kins.ini","label":"MAX5 with kinematics Simulation","category":"axis/vismach/5axis/max5","display":null,"coordinates":null,"kinematics":"maxkins","family":"cartesian","status":"ready","startup_preflight":"static_ready","resource_status":"ready","missing_count":0,"unresolved_count":0,"source_sha256":"ea7d453127122b7831e74de2204b446c514f3c999961a4be412b36880bacb8b6"},{"path":"linuxcnc/configs/sim/axis/vismach/5axis/max5/max5triv.ini","label":"MAX5-trivkins Simulation","category":"axis/vismach/5axis/max5","display":null,"coordinates":null,"kinematics":"trivkins coordinates=xyzabc","family":"cartesian","status":"ready","startup_preflight":"static_ready","resource_status":"ready","missing_count":0,"unresolved_count":0,"source_sha256":"92afb2043a559d8eb9e638bfb9862c8ec917deb49987c788989fe538e8ddeefb"},{"path":"linuxcnc/configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.ini","label":"sim-xyzab-tdr-kins (switchkins)","category":"axis/vismach/5axis/table-dual-rotary","display":"axis","coordinates":"XYZAB","kinematics":"xyzab_tdr_kins","family":"five_axis_trt","status":"blocked","startup_preflight":"blocked_unregistered_kinematics","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"923d0a9e75ff595e05a5fe13194cbd7eee7465419b995fe852503435a8d35907"},{"path":"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini","label":"sim-xyzac-trt-kins (switchkins)","category":"axis/vismach/5axis/table-rotary-tilting","display":"axis","coordinates":"XYZAC","kinematics":"xyzac-trt-kins sparm=identityfirst","family":"five_axis_trt","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"9ee1d96962e7a44b25468f452543cfc3ca318585269e26227bb5b6e17b1e42f1"},{"path":"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini","label":"sim-xyzbc-trt-kins (switchkins)","category":"axis/vismach/5axis/table-rotary-tilting","display":"axis","coordinates":"XYZBC","kinematics":"xyzbc-trt-kins sparm=identityfirst","family":"five_axis_trt","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"78ce55d1e96e6f6a68f7352d530f9f84f3a68188cbe3b45e908a085295180c78"},{"path":"linuxcnc/configs/sim/axis/vismach/VMC_toolchange/vmc_graycode.ini","label":"Vertical Machining Centre with Toolchange Simulation","category":"axis/vismach/VMC_toolchange","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"5825522880add3a8614e1fd5c168b16533f7b7b898b00a640b6e74f281270d2b"},{"path":"linuxcnc/configs/sim/axis/vismach/VMC_toolchange/vmc_index.ini","label":"Vertical Machining Centre with Toolchange Simulation","category":"axis/vismach/VMC_toolchange","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"0f6e02c370c529d080bf913c1771169652bf8fe1b67cdda86cb93e2c8f933abe"},{"path":"linuxcnc/configs/sim/axis/vismach/hbm/hbm.ini","label":"Horizontal Boring Mill Simulation","category":"axis/vismach/hbm","display":"axis","coordinates":"X Y Z W","kinematics":"trivkins coordinates=xyzw","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"63eafce3b9ee34cc0ff489dd754e1657a4cfd08d16147f28be38687e19604b4d"},{"path":"linuxcnc/configs/sim/axis/vismach/hexapod-sim/hexapod.ini","label":"hexapod (switchkins)","category":"axis/vismach/hexapod-sim","display":"axis","coordinates":"X Y Z A B C","kinematics":"genhexkins","family":"parallel_hexapod","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"362654b77bcaf5c87c3aa14c12684f516cbd635b6d582a68b05fcbd8299822ea"},{"path":"linuxcnc/configs/sim/axis/vismach/melfa-sim/melfa.ini","label":"melfa (mm)","category":"axis/vismach/melfa-sim","display":"axis","coordinates":"X Y Z A B C","kinematics":"genserkins","family":"serial_robot","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"7dc7a3db58ca7f7ddba11fe08f691cd7658564be2a0b872d9087ee7b392e45c7"},{"path":"linuxcnc/configs/sim/axis/vismach/millturn/millturn.ini","label":"millturn (mm)","category":"axis/vismach/millturn","display":"axis","coordinates":"X Y Z A","kinematics":"millturn","family":"switchable","status":"blocked","startup_preflight":"blocked_unregistered_kinematics","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"dfdb6e6c295c4ca9ebf9ff11f31c1b5d6fed4079b8e48b7b59cf7fee6b8b1547"},{"path":"linuxcnc/configs/sim/axis/vismach/puma/puma.ini","label":"PUMA (pumakins,switchkins)","category":"axis/vismach/puma","display":"axis","coordinates":"X Y Z A B C","kinematics":"pumakins","family":"serial_robot","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"26ee23af27aa03d2da89b842992802ece2423195a5ac0960b28bb751871d74f6"},{"path":"linuxcnc/configs/sim/axis/vismach/puma/puma560.ini","label":"puma560 (switchkins) (inch)","category":"axis/vismach/puma","display":"axis","coordinates":"X Y Z A B C","kinematics":"genserkins","family":"serial_robot","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"2bb881ed6c5662282977accac29bfd6c4efc18e572cbcb8a31c134677012cf4c"},{"path":"linuxcnc/configs/sim/axis/vismach/puma/puma560_uvw.ini","label":"puma560 (switchkins) (inch)","category":"axis/vismach/puma","display":"axis","coordinates":"X Y Z A B C U V W","kinematics":"genserkins","family":"serial_robot","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"50bf5dbc4cf70b0c18afea3dcbc577fbb6166152300cd16e27819de1fafe41b0"},{"path":"linuxcnc/configs/sim/axis/vismach/puma/puma_cube.ini","label":"puma_cube.ini (pumakins)","category":"axis/vismach/puma","display":"axis","coordinates":"X Y Z A B C","kinematics":"pumakins","family":"serial_robot","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"0204289788840e0dcaaeb55a2a85cf44a3754845636a897df6efeb165db0de15"},{"path":"linuxcnc/configs/sim/axis/vismach/rolfmill/rolfmill.ini","label":"rolfmill","category":"axis/vismach/rolfmill","display":"axis","coordinates":"X Y Z","kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"b122ac25ed12462b02d10828c469bafdcb231e9cbed07e96b6a7709380bdf0ad"},{"path":"linuxcnc/configs/sim/axis/vismach/scara/scara.ini","label":"SCARA (genserkins,switchkins)","category":"axis/vismach/scara","display":"axis","coordinates":"XYZABC","kinematics":"scarakins coordinates=xyzcab","family":"serial_robot","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"602e02bb6d320b728d9ae15904a5d229ea1a31e932c18e9018b45be007d695ce"},{"path":"linuxcnc/configs/sim/axis/vismach/scorbot/scorbot.ini","label":"scorbot_candidate","category":"axis/vismach/scorbot","display":null,"coordinates":"XYZAB","kinematics":"scorbot-kins","family":"serial_robot","status":"blocked","startup_preflight":"blocked_unindexed_resource_graph","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"4e8edd061a033d45e1e71c56bdd521ee10d3f60def3be020bbd437fc49271343"},{"path":"linuxcnc/configs/sim/axis/wrapped_rotary/wrapped_rotary.ini","label":"EMC-HAL-SIM-WRAPPED-ROTARY","category":"axis/wrapped_rotary","display":"axis","coordinates":"X Y Z A","kinematics":"trivkins coordinates=xyza kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"a9d1ffd13139631bba4b4eec761e99b3245ad18be951d076eb3a949e3e6c3798"},{"path":"linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout1.ini","label":"xhc-hb04 layout1 demo","category":"axis/xhc-hb04","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"07b2c68847bdb8136adfc04193826c6019981c80a7219a1dbbb733d337b8f817"},{"path":"linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout2.ini","label":"xhc-hb04 layout2 demo","category":"axis/xhc-hb04","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"9082cc7df0115bbf754f796ae7989fab1897b5167231dd7b55e6e7ff2f0d96ce"},{"path":"linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout2_mm.ini","label":"xhc-hb04 layout2 mm demo","category":"axis/xhc-hb04","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"cbc5c40c2a7fbfa0ead5f52dde952a0f1cd088895cdc1f06a5d01060c54aef41"},{"path":"linuxcnc/configs/sim/craftsman/cnc_settings.ini","label":"cnc settings","category":"craftsman","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"4a40e3b30ec1cee094424945ddb36400c6d7fd5d8edf0109d95e7ea68ce211d8"},{"path":"linuxcnc/configs/sim/craftsman/craftsmancnc-axis.ini","label":"Craftsman 900ST","category":"craftsman","display":"cm_axis","coordinates":"X Y Z A","kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"d678962c09a6e37c89868c715c98c77dbd3f9f3fe1f6537b41d092d2a5d8ed56"},{"path":"linuxcnc/configs/sim/craftsman/craftsmancnc.ini","label":"Craftsman 900ST","category":"craftsman","display":"./craftsmancnc","coordinates":"XYZA","kinematics":"trivkins coordinates=XYZA","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"c9390a47578b640dfde32e50475a2ae386dd657dc5130ce2fe34564bf90bfc70"},{"path":"linuxcnc/configs/sim/gmoccapy/6_axis.ini","label":"gmoccapy_9_axis","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z A B C","kinematics":"trivkins coordinates=XYZABC","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"1a47c6b666af1ca2f78f95022c27bb9f94626ffce26da23556fea15f767b7cba"},{"path":"linuxcnc/configs/sim/gmoccapy/7_axis.ini","label":"gmoccapy_9_axis","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z A B C U","kinematics":"trivkins coordinates=XYZABCU","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"10db48db4e53a03fe04c2e3dc849c84c9f3f2b77d51c233f64b92b375942a14f"},{"path":"linuxcnc/configs/sim/gmoccapy/7_axis_tool.ini","label":"gmoccapy_9_axis","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z A B C U","kinematics":"trivkins coordinates=XYZABCU","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"6f48447e4576d82a57742dc94babcecf2e813a2afbe398acfcfd87d05c99f229"},{"path":"linuxcnc/configs/sim/gmoccapy/8_axis.ini","label":"gmoccapy_9_axis","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z A B C U V","kinematics":"trivkins coordinates=XYZABCUV","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"ad9e2a848a1d1cde6c4fbcf82adaae70d52af6f283d3e785a053c2a560ab8f84"},{"path":"linuxcnc/configs/sim/gmoccapy/9_axis.ini","label":"gmoccapy_9_axis","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z A B C U V W","kinematics":"trivkins coordinates=XYZABCUVW","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"72252c1eb8238facb30b8b3fc08d012b22c70bf1c7c151c2e50946a5eeadc5ef"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy.ini","label":"gmoccapy","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"627537d0a342075ecd45765b4d8b256b065f2568902a585cfe5161efec53a126"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_4_axis.ini","label":"gmoccapy 4 axis","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z C","kinematics":"trivkins coordinates=xyzc","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"33b4ad6792d9037f2a0bb9eb179aff7b3d8ecac64bfa0b1cc71633a88cf868d9"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZAB.ini","label":"gmoccapy XYZAB","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z A B","kinematics":"trivkins coordinates=xyzab","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"c8047ee290a94944481545a78104e9ead1036ca04f965a729ad4a870e7fe69a1"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZAC.ini","label":"gmoccapy XYZAC","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z A C","kinematics":"trivkins coordinates=xyzac","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"daf2ffcab7fb3af60f5dd38256c8e9bb3347d885771ba414da2b4277c8ebce4a"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZCW.ini","label":"gmoccapy XYZAB","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z C W","kinematics":"trivkins coordinates=xyzcw","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"8a860f885f6afc18b0d1ff8081d356d56897456298cfd58fc7394ec519f71e83"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_left_panel.ini","label":"gmoccapy_left_panel","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"3e458b639557d33bc2b637fb2f63b88e1cade3dd7543306b96e166c5b50bb08e"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_messages.ini","label":"gmoccapy_development","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"7b8a607c978ad1758a51d60b04d3bed46a9597661060a6a906b4411abe02e857"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_pedant.ini","label":"gmoccapy_pendant","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":3,"unresolved_count":1,"source_sha256":"ea336e14be5b1b62a6b540070624b6c35cd076b16d170725fc4dacb9754e6790"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/gmoccapy_plasma.ini","label":"gmoccapy","category":"gmoccapy/gmoccapy_plasma","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"b006d05ea125442e3258a76b9e95d28a3488d25f1f652828c470de82aaa9d077"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_pyngcgui.ini","label":"gmoccapy","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"2f62b1a0e2bcdf2b587e142ea8c4212c28b8024161c38b13e5cb39e15c984ce7"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_right_panel.ini","label":"gmoccapy right panel","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"c155ba8047c3011c6ec023dd911fa571ec52b5352b789b7c88542c8d418e15bc"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_sim_hardware_button.ini","label":"gmoccapy sim hardware button","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"7469a0e05ea85c83d99f11ef552482c29d93313a358d8a7801a2eabbae1f9af0"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_tool_sensor.ini","label":"gmoccapy tool sensor","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"4caf0e746fd09bceafa4f2bdced6a9be063b7ee51334fbb75d4c6914d94db7b9"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_with_user_tabs.ini","label":"gmoccapy with user tabs","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"a080a9008bef88d61fee5473f8531df64bfe3fd365540e1055e3377ce59f99d9"},{"path":"linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe.ini","label":"gmoccapy_lathe","category":"gmoccapy/lathe_configs","display":"gmoccapy","coordinates":"X Z","kinematics":"trivkins coordinates=XZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"b6971dfdf96fb2d502378d143da6c7a2f404fe796f41f96f629b9db15a44bb66"},{"path":"linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_C.ini","label":"lathe_c","category":"gmoccapy/lathe_configs","display":"gmoccapy","coordinates":"X Z C","kinematics":"trivkins coordinates=XZC","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"c2f67186fc6c84f266d2ad1d6fcf487249182a2385f8d3099f51f9fab1cc8bb4"},{"path":"linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_CW.ini","label":"lathe_cw","category":"gmoccapy/lathe_configs","display":"gmoccapy","coordinates":"X Z C W","kinematics":"trivkins coordinates=XZCW","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"df718eefdbd91308b9182f6858150abb8fa4a2d030105db954702c280cddac70"},{"path":"linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_backtool.ini","label":"gmoccapy_lathe","category":"gmoccapy/lathe_configs","display":"gmoccapy","coordinates":"X Z","kinematics":"trivkins coordinates=XZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"5d7e04fd075e28534afe817e64259a2e7df809d5fdf893f39c9cc5ffcd35ed71"},{"path":"linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_imperial.ini","label":"lathe_imperial","category":"gmoccapy/lathe_configs","display":"gmoccapy","coordinates":"X Z","kinematics":"trivkins coordinates=XZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"503bf2241ed1c1f70410015a7f3aab5a922dc571b1ded36f5431c538d5d4e628"},{"path":"linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_macros.ini","label":"gmoccapy_lathe","category":"gmoccapy/lathe_configs","display":"gmoccapy","coordinates":"X Z","kinematics":"trivkins coordinates=XZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"b3d9c8451a9281e9863e30f7d0138d5779028a06d981c2f1bd30bf6c7bded0e0"},{"path":"linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gantry_mm.ini","label":"gmoccapy_GANTRY_sim","category":"gmoccapy/non_trivial_kinematics/Gantry","display":"gmoccapy","coordinates":"X Y Y Z","kinematics":"trivkins coordinates=xyyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"303f0fb1b9a70ba3cc6dbc11003bed2c59579ddfe2e4d9a300a5fcd4da570e65"},{"path":"linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara.ini","label":"LinuxCNC-HAL-SIM-SCARA","category":"gmoccapy/non_trivial_kinematics/scara","display":"gmoccapy","coordinates":"X Y Z C","kinematics":"scarakins","family":"serial_robot","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"3c5a9c56f4c50a987f7b2a21b6968ab77eeb586a894f8ffff73dec74eb680092"},{"path":"linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt.ini","label":"sim-xyzac-trt","category":"gmoccapy/non_trivial_kinematics/table-rotary-tilting","display":"gmoccapy","coordinates":"XYZAC","kinematics":"xyzac-trt-kins","family":"five_axis_trt","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"af315891e9e561812f267f9c44c752c265ad00c862adbcd7dd42c2b07e60cd38"},{"path":"linuxcnc/configs/sim/gmoccapy/plasma_config/gmoccapy_plasma.ini","label":"gmoccapy","category":"gmoccapy/plasma_config","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"7d53c570ccb85f086e67eb511c28bb9cec47e02cf42395e71bb2ff89e9d0d671"},{"path":"linuxcnc/configs/sim/gscreen/gscreen.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"gscreen","display":"gscreen","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":7,"unresolved_count":0,"source_sha256":"5501604c0c6d0288cea28720da271fd44900ea50ddcccf6acf0743e7e2daf016"},{"path":"linuxcnc/configs/sim/gscreen/gscreen_custom/9axis.ini","label":"LinuxCNC-HAL-SIM-GSCREEN","category":"gscreen/gscreen_custom","display":"gscreen -c 9_axis -d -v","coordinates":"X Y Z A B C U V W","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"2ffde65bf13a116a14d2b75a841f197cd67f6281c6b5c2c548487e779a166ef0"},{"path":"linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_no_plot.ini","label":"Linuxcnc-Gscreen_gaxis_no_plot","category":"gscreen/gscreen_custom","display":"gscreen -c gaxis_no_plot -c","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":7,"unresolved_count":0,"source_sha256":"93faa3f0a5727d1468381add40a7b35ac5e80b44d8c9c17bfb1e18754daa5498"},{"path":"linuxcnc/configs/sim/gscreen/gscreen_custom/gscreen_gaxis.ini","label":"Linuxcnc-Gscreen_gaxis","category":"gscreen/gscreen_custom","display":"gscreen -c gaxis -c","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":7,"unresolved_count":0,"source_sha256":"8b37aef313551ab9dcd3a414d582b399669dfb4375d08fe5ee709bf327c53d43"},{"path":"linuxcnc/configs/sim/gscreen/gscreen_custom/industrial.ini","label":"Linuxcnc-Gscreen_gaxis","category":"gscreen/gscreen_custom","display":"gscreen -c industrial -d","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":7,"unresolved_count":0,"source_sha256":"ceab463ee55d534c84a5abf5b98d0caee56f9ef71ed67e5ceabea84cf998b725"},{"path":"linuxcnc/configs/sim/gscreen/gscreen_custom/tester.ini","label":"Linuxcnc-Gscreen_gaxis","category":"gscreen/gscreen_custom","display":"gscreen -c tester -d","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":7,"unresolved_count":0,"source_sha256":"94c5bb5c621e8074f96004b1abbe5bc66ee5df6aa672f2cf3542c3d38047ac70"},{"path":"linuxcnc/configs/sim/gscreen/gscreen_custom/tester_metric.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"gscreen/gscreen_custom","display":"gscreen -c tester -d","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":8,"unresolved_count":0,"source_sha256":"bc459d4d659a562f22da247a2734116000e4c8fa71ea13014ca61885dc5bf2ea"},{"path":"linuxcnc/configs/sim/gscreen/gscreen_lathe.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"gscreen","display":"gscreen","coordinates":"X Z","kinematics":"trivkins coordinates=xz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"bf9e089a8d61194462bb418efe1176eaf624faee8e42f0cfd791b62b9b906e24"},{"path":"linuxcnc/configs/sim/gscreen/gscreen_mm.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"gscreen","display":"gscreen","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":7,"unresolved_count":0,"source_sha256":"f4e86efc8aea695f7c931742a41b48851a29fced4aff1dab67b001934245e297"},{"path":"linuxcnc/configs/sim/gscreen/industrial_lathe_wear/industrial_lathe_wear.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"gscreen/industrial_lathe_wear","display":"gscreen -c industrial -d","coordinates":"X Z","kinematics":"trivkins coordinates=xz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"4c807ff8b3faa4e97574c4c7add99fe6b7654e980bb73737e46f563b5170b422"},{"path":"linuxcnc/configs/sim/gscreen/ngcgui/pyngcgui_gscreen.ini","label":"pyngcgui-gscreen demo","category":"gscreen/ngcgui","display":"gscreen","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"01ea7f117f038a59dccb25a01c4d693222e807474e2e6aec338975aa6bed5841"},{"path":"linuxcnc/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_popupkeyboard.ini","label":"pyngcgui-gscreen demo (popupkeyboard)","category":"gscreen/ngcgui","display":"gscreen","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"d6fd8d018be34826fb7bccdad4987a8968dbfdf7a2b5794b75c809c56a18ad63"},{"path":"linuxcnc/configs/sim/gscreen/silverdragon/silverdragon.ini","label":"silverdragon","category":"gscreen/silverdragon","display":"gscreen -d -c silverdragon","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":5,"unresolved_count":1,"source_sha256":"d1ed1b802162281fc742b0146be7bb3b5daba2fc944d4b4c8f8ccdb096cffc77"},{"path":"linuxcnc/configs/sim/gscreen/spartan/spartan.ini","label":"spartan","category":"gscreen/spartan","display":"gscreen -c spartan","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"eddaf2a70b2e1147f8e4cb781abbb56a87243fdfad4932fc8ddecbeb5f5d42e1"},{"path":"linuxcnc/configs/sim/pyvcp_demo/pyvcp_bottom_panel.ini","label":"Pyvcp_demo1","category":"pyvcp_demo","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"75dc8d6f9dc89d6725aabdb7c59cb0965d2d054b2e1e4baa71de3538b4f77c85"},{"path":"linuxcnc/configs/sim/pyvcp_demo/pyvcp_demo1.ini","label":"Pyvcp_demo1","category":"pyvcp_demo","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"5ec9203047e509b1e633dadcebba91909c3aee8ad65465ea2c0bd8bc409bb9a0"},{"path":"linuxcnc/configs/sim/pyvcp_demo/pyvcp_embed_tab.ini","label":"Pyvcp_demo1","category":"pyvcp_demo","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"4da521d1e8bc2fdb0155f86afc1b1c0dffdd31402ade0ab7519bbfd30145cfbe"},{"path":"linuxcnc/configs/sim/qtaxis/gantry/qt_gantry.ini","label":"LinuxCNC-GANTRY-SIM-qtvcp","category":"qtaxis/gantry","display":"qtvcp -d qtaxis","coordinates":"XYZY","kinematics":"trivkins coordinates=XYZY kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":8,"unresolved_count":0,"source_sha256":"0b06ae360b37859343763adb960e6304a812ebc658a2056fc4df280ccd793c37"},{"path":"linuxcnc/configs/sim/qtaxis/non-trivial/scara/scara.ini","label":"SCARA (genserkins,switchkins)","category":"qtaxis/non-trivial/scara","display":"qtvcp qtaxis","coordinates":"XYZABC","kinematics":"scarakins coordinates=xyzcab","family":"serial_robot","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":6,"unresolved_count":0,"source_sha256":"1f4fa4d1a1ccd5cf299948b824101430bd1a41cb8ea74a3311373ce9ef17a7c1"},{"path":"linuxcnc/configs/sim/qtaxis/xyz/qtaxis.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtaxis/xyz","display":"qtvcp -v qtaxis","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz kinstype=B","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":7,"unresolved_count":1,"source_sha256":"c764f544082a217a19a9fc26d0552f209dcb4548e80d2f544b1e00489472819a"},{"path":"linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyz.ini","label":"qtdragon","category":"qtdragon/qtdragon_multi_joint","display":"qtvcp qtdragon","coordinates":"XYYZ","kinematics":"trivkins coordinates=XYYZ kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":3,"source_sha256":"6e37414ca98a0a0551b8b54980fbc77417b618aeba039e3c38ac4c4b9b1b6b68"},{"path":"linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyzy.ini","label":"qtdragon","category":"qtdragon/qtdragon_multi_joint","display":"qtvcp qtdragon","coordinates":"XYZY","kinematics":"trivkins coordinates=XYZY kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":3,"source_sha256":"f657495b776ab5f371bf59106bbbfa230f1cbc72061caaf036bc6b38fbb79421"},{"path":"linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyzya.ini","label":"qtdragon","category":"qtdragon/qtdragon_multi_joint","display":"qtvcp qtdragon","coordinates":"XYZYA","kinematics":"trivkins coordinates=XYZYA kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":3,"source_sha256":"7835bceebe51c9881328896c9f4a6fe4fc91e49a025a26a95e6b7c1716e2edf2"},{"path":"linuxcnc/configs/sim/qtdragon/qtdragon_tool_probe/qtdragon_auto_tool_probe.ini","label":"qtdragon","category":"qtdragon/qtdragon_tool_probe","display":"qtvcp qtdragon","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":7,"unresolved_count":1,"source_sha256":"3000ec032956226a8281fe0e76304c56d3d6d4d0fbef6b7b2c226a15f2eb9674"},{"path":"linuxcnc/configs/sim/qtdragon/qtdragon_xyz/qtdragon_inch.ini","label":"qtdragon_inch","category":"qtdragon/qtdragon_xyz","display":"qtvcp qtdragon","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":3,"source_sha256":"e36b608260f3eca2f2439d83b0e32786a2d1bd5f395c3705ee3fe3a1fa0ad94c"},{"path":"linuxcnc/configs/sim/qtdragon/qtdragon_xyz/qtdragon_metric.ini","label":"qtdragon_metric","category":"qtdragon/qtdragon_xyz","display":"qtvcp qtdragon","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":3,"source_sha256":"3565f4863be6f1dc25ef216c8a6f96e69f133681676131ab883007c80aef7c66"},{"path":"linuxcnc/configs/sim/qtdragon/qtdragon_xyz/qtdragon_xyza.ini","label":"qtdragon","category":"qtdragon/qtdragon_xyz","display":"qtvcp qtdragon","coordinates":"XYZA","kinematics":"trivkins coordinates=XYZA","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":3,"source_sha256":"592aaee3190a65fab8b200b45f5ec221ab58edf0b754e2db227352cebea0dae2"},{"path":"linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyza.ini","label":"qtdragon","category":"qtdragon/qtdragon_xyz45","display":"qtvcp qtdragon","coordinates":"XYZA","kinematics":"trivkins coordinates=XYZA","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":3,"source_sha256":"d5597a9bc8ef786bebd2dbc79300253117e814e214e17d067eddc1049ac1cf95"},{"path":"linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyzab.ini","label":"qtdragon","category":"qtdragon/qtdragon_xyz45","display":"qtvcp qtdragon","coordinates":"XYZAB","kinematics":"trivkins coordinates=XYZAB","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":4,"unresolved_count":3,"source_sha256":"c8ec9fc577cee73a46981d2a7c5eaebc596bddba19b395b87eb0e4eba2a0c3ba"},{"path":"linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyzac.ini","label":"qtdragon","category":"qtdragon/qtdragon_xyz45","display":"qtvcp qtdragon","coordinates":"XYZAC","kinematics":"trivkins coordinates=XYZAC","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":4,"unresolved_count":3,"source_sha256":"b25b195fd6d211053b3eb091a513c01ea83550969a29c6b446fdbb2577c1c7a2"},{"path":"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyz.ini","label":"qtdragon","category":"qtdragon_hd/qtdragon_hd_xyz","display":"qtvcp -d qtdragon_hd","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":3,"source_sha256":"6cfb7b2c847368e117d28ecd99027c4158ed2e02a08bbba787bee73bd1f3ad7d"},{"path":"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyza.ini","label":"qtdragon","category":"qtdragon_hd/qtdragon_hd_xyz","display":"qtvcp qtdragon_hd","coordinates":"XYZA","kinematics":"trivkins coordinates=XYZA","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":3,"source_sha256":"da745eb5892bbda71c4555b11c50bc8ff9f32a28f97a51951a892b4de5604fcc"},{"path":"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyzab.ini","label":"qtdragon","category":"qtdragon_hd/qtdragon_hd_xyz","display":"qtvcp qtdragon_hd","coordinates":"XYZAB","kinematics":"trivkins coordinates=XYZAB","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":5,"unresolved_count":3,"source_sha256":"9f9f7b2a62ebd1cf0fffa4d97af9dca42bc25d9678ee52978b4f24d10df7daa7"},{"path":"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyzac.ini","label":"qtdragon","category":"qtdragon_hd/qtdragon_hd_xyz","display":"qtvcp qtdragon_hd","coordinates":"XYZAC","kinematics":"trivkins coordinates=XYZAC","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":5,"unresolved_count":3,"source_sha256":"c836bd0309d143fa80a70fa37c1e92714437d5b3931ad50f47aad820bf597253"},{"path":"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_z_compensation.ini","label":"qtdragon","category":"qtdragon_hd/qtdragon_hd_z_compensation","display":"qtvcp -d qtdragon_hd","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":3,"source_sha256":"7285f86b7a2d30318c529985c0f34851e017ce69a23ca06ffb456d9d422f7503"},{"path":"linuxcnc/configs/sim/qtplasmac/qtplasmac_l_imperial.ini","label":"qtplasmac l imperial","category":"qtplasmac","display":"qtvcp qtplasmac","coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"2b563e2a090572d2bf02256b8dc3c99054fb0388167482ede5ce7ce5932db898"},{"path":"linuxcnc/configs/sim/qtplasmac/qtplasmac_l_metric.ini","label":"qtplasmac l metric","category":"qtplasmac","display":"qtvcp qtplasmac","coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"abe6e751f739076432b586af48512946175298676e5ed23d6a30e1dac77958ee"},{"path":"linuxcnc/configs/sim/qtplasmac/qtplasmac_p_imperial.ini","label":"qtplasmac p imperial","category":"qtplasmac","display":"qtvcp qtplasmac_9x16","coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"7e45dee1b8eec3ae9eea1ddf2eb9a47e40fb0fe32dcd93a126441d4cfd1d62b0"},{"path":"linuxcnc/configs/sim/qtplasmac/qtplasmac_p_metric.ini","label":"qtplasmac p metric","category":"qtplasmac","display":"qtvcp qtplasmac_9x16","coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"52b0aa0d4132f0fdfad5af82dbef598d33f655e3f65c721cd6e3c231146dfbdf"},{"path":"linuxcnc/configs/sim/qtplasmac/qtplasmac_s_imperial.ini","label":"qtplasmac s imperial","category":"qtplasmac","display":"qtvcp qtplasmac_4x3","coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"00694329d1f037d0f7a51a246b04d1743b9b4ba2983acf1edddd88fd9161d48f"},{"path":"linuxcnc/configs/sim/qtplasmac/qtplasmac_s_metric.ini","label":"qtplasmac s metric","category":"qtplasmac","display":"qtvcp qtplasmac_4x3","coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"84e21e9dcb3a4572b999d96f97f7b188b3b202ad0e995776fd0e3f090ae5c8d6"},{"path":"linuxcnc/configs/sim/qttouchy/qttouchy.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qttouchy","display":"qtvcp -d qttouchy","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":8,"unresolved_count":1,"source_sha256":"1398796a9ef4d41bf2d9841656b588dd12818cfac9e390a8fd9d6aa6e2185acc"},{"path":"linuxcnc/configs/sim/qtvcp_screens/blender.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens","display":"qtvcp -m blender","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":7,"unresolved_count":1,"source_sha256":"15fc1681185d59a5f9d8ae14c2d9773bf749373bd6c71b6c614607ce7f35393d"},{"path":"linuxcnc/configs/sim/qtvcp_screens/industrial_lathe_wear/industrial_lathe_wear.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens/industrial_lathe_wear","display":"qtvcp -d qtlathe","coordinates":"X Z","kinematics":"trivkins coordinates=xz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":5,"unresolved_count":2,"source_sha256":"378d5e9e04608240a6884a011ec32caf8de0e3d67bae6b568f33e9e292e94ce5"},{"path":"linuxcnc/configs/sim/qtvcp_screens/non-trivial/scara/scara.ini","label":"SCARA (genserkins,switchkins)","category":"qtvcp_screens/non-trivial/scara","display":"qtvcp qtaxis","coordinates":"XYZABC","kinematics":"scarakins coordinates=xyzcab","family":"serial_robot","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":7,"unresolved_count":0,"source_sha256":"1e6a080a7718813d9946acdd7cf7c033e896a318702a5dc5f86f8d45012b2aea"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qt_800x600.ini","label":"LinuxCNC-Qtvcp-800x600","category":"qtvcp_screens","display":"qtvcp -d qt_cnc_800x600.ui","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":9,"unresolved_count":0,"source_sha256":"7235c5081d278551bff8b2b30bd577175251f5dbc81c9dcd4d64c4cb3c832858"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qt_gantry.ini","label":"LinuxCNC-GANTRY-SIM-qtvcp","category":"qtvcp_screens","display":"qtvcp -d qtaxis","coordinates":"XYZY","kinematics":"trivkins coordinates=XYZY kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":8,"unresolved_count":0,"source_sha256":"0c97b43e267300f8565a601fe578d6239b9c5eee3f2122ccfa4b536faeffb254"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtaxis.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens","display":"qtvcp -v qtaxis","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz kinstype=B","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":7,"unresolved_count":1,"source_sha256":"51b5cb7c790d2eb07550ed1e5ee77314133ab99628c23e7cbee27eaf3466bd2a"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis_lathe.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens/qtaxis_lathe","display":"qtvcp qtaxis","coordinates":"XYZ","kinematics":"trivkins coordinates=xz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":5,"unresolved_count":1,"source_sha256":"96607f9e45ebb60e6c8c30a3b827f33273159780e31b6e6dcd187e69d9316ee2"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtaxis_mpg.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens","display":"qtvcp -d qtaxis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":7,"unresolved_count":1,"source_sha256":"a7e3781694cca98ef9451e2100fa213380088ebe750eea1935e5db09792a4264"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdefault.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens","display":"qtvcp -d","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":7,"unresolved_count":3,"source_sha256":"64b856e76d997a0096533b198666109c059eea4b02e2ac3f3967cef22667ccb9"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdefault_9axis.ini","label":"LinuxCNC-sim-9axis","category":"qtvcp_screens","display":"qtvcp qt_cnc_9_axis","coordinates":"X Y Z A B C U V W","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":5,"unresolved_count":1,"source_sha256":"ec8344fad2445df3a8822c624dd0aa514e3900ba60879c5443a5d6f7c495f84a"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdefault_gantry.ini","label":"LinuxCNC-GANTRY-SIM-AXIS","category":"qtvcp_screens","display":"qtvcp -d","coordinates":"XYZY","kinematics":"trivkins coordinates=XYZY kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":8,"unresolved_count":0,"source_sha256":"3f1ea1c180d85118c09a821ea03b007fc8901c40685148a77714c76278db185b"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdefault_mm.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens","display":"qtvcp","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":7,"unresolved_count":0,"source_sha256":"a49b1cf91a6fb17c5bbb80eea44b6c46e76ae182e7e3ac67b96b4fab2cfaea88"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon.ini","label":"qtdragon","category":"qtvcp_screens/qtdragon","display":"qtvcp qtdragon","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":2,"source_sha256":"103a9d0f4c329e00d532fcf0f3ef1e90a37f4476b8950a2b52325d8a42bc4b91"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_auto_tool_probe.ini","label":"qtdragon","category":"qtvcp_screens/qtdragon","display":"qtvcp qtdragon","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"86f2c3f594d0c4bc03da44b9b9ad1445782a9290c8024837a77b83a49e3c55de"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_hd.ini","label":"qtdragon","category":"qtvcp_screens/qtdragon","display":"qtvcp -d qtdragon_hd","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":2,"source_sha256":"c2b23e16477e4de6f3cbd6cdbca56f4a0c80f2482648ee48493349326ef9f1f2"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_inch.ini","label":"qtdragon","category":"qtvcp_screens/qtdragon","display":"qtvcp qtdragon","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"c52570c11f2c503a5aa4ac054fe751035a4d95951c8a24d357d544b08674d8cd"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyyz.ini","label":"qtdragon","category":"qtvcp_screens/qtdragon","display":"qtvcp qtdragon","coordinates":"XYYZ","kinematics":"trivkins coordinates=XYYZ kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"8919a7050ba4357c8e663c51a761fe6d78ff6d7da1e820800eb95e3319cefb64"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyz.ini","label":"qtdragon","category":"qtvcp_screens/qtdragon","display":"qtvcp qtdragon","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"416ec9cb44f3c9f301d874b5d7e860d82bd460633902e3bcc9037d262a464e9b"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyza.ini","label":"qtdragon","category":"qtvcp_screens/qtdragon","display":"qtvcp qtdragon","coordinates":"XYZA","kinematics":"trivkins coordinates=XYZA","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"8b72d1ec92b54e2d5dcf333d5638907141340f942e7e1cbfb26be22d8a28e8aa"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyzy.ini","label":"qtdragon","category":"qtvcp_screens/qtdragon","display":"qtvcp qtdragon","coordinates":"XYZY","kinematics":"trivkins coordinates=XYZY kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"a301f964957d63716ac527504ab80d627161ff9d8a57b6b77f4ae59f12798a5c"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyzya.ini","label":"qtdragon","category":"qtvcp_screens/qtdragon","display":"qtvcp qtdragon","coordinates":"XYZYA","kinematics":"trivkins coordinates=XYZYA kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"1f2b5583b7e1d1ef0339f0a05e8bac2a6d503cfbf977127de64738926c8cc161"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtvcp_custom/qtdefault_ngc.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens/qtvcp_custom","display":"qtvcp -m qtdefault_ngc","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":6,"unresolved_count":0,"source_sha256":"142a7c8f7ba86085afd4e331d0deb8030df8e53ea64bfc96a71b049a8dba1096"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/gremlin.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens/qtvcp_experimental","display":"qtvcp -d qtaxis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":6,"unresolved_count":0,"source_sha256":"ea20d3e12b0a800739c060bca467c8745e29e8d318c47bfa64becd3555af6cca"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens/qtvcp_experimental","display":"qtvcp -d qtaxis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":6,"unresolved_count":0,"source_sha256":"77f1a4a5294dc202d4afc6764a14dc89d8e1174424667c5b72742ae3a0975645"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_ngc.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens/qtvcp_experimental","display":"qtvcp -m qtdefault_ngc","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":6,"unresolved_count":0,"source_sha256":"142a7c8f7ba86085afd4e331d0deb8030df8e53ea64bfc96a71b049a8dba1096"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtx1mill.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens","display":"qtvcp -d x1mill","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":7,"unresolved_count":1,"source_sha256":"0909d95dd20251475be2a745ea9ff1a9bc11c05b6d4b880be7d4165c2686b40c"},{"path":"linuxcnc/configs/sim/qtvcp_screens/tester.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens","display":"qtvcp -d tester.ui","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":7,"unresolved_count":1,"source_sha256":"74ffaa3444383a097aed37c22d5d6b6ef9d55b49a49a97e5861013d907a4f40d"},{"path":"linuxcnc/configs/sim/tklinuxcnc/ldelta.ini","label":"Delta-robot-with-linear-joints","category":"tklinuxcnc","display":"tklinuxcnc","coordinates":"X Y Z A","kinematics":"lineardeltakins","family":"parallel_delta","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"0e23dee0f4df839c028f5bfba95c5941f2f8623ce502d6fdfc90dfdef63d8967"},{"path":"linuxcnc/configs/sim/tklinuxcnc/servo_sim.ini","label":"LinuxCNC-HAL-SERVO-SIM","category":"tklinuxcnc","display":"tklinuxcnc","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"0f8b15328616a4fd5be7561738273a9c04e0c5524423d424257c5ffda73fa25e"},{"path":"linuxcnc/configs/sim/tklinuxcnc/tklinuxcnc.ini","label":"LinuxCNC-HAL-SIM-TkLinuxCNC","category":"tklinuxcnc","display":"tklinuxcnc","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"12f9c72fe2f8ab1ac7d6fcb553c902b4a2df1cecbf3ecc896fa9c0ad7a8f41b3"},{"path":"linuxcnc/configs/sim/tklinuxcnc/tripod.ini","label":"LinuxCNC-TRIPOD-SIM-TkLinuxCNC","category":"tklinuxcnc","display":"tklinuxcnc","coordinates":"X Y Z","kinematics":"tripodkins","family":"parallel_tripod","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"8da7280a981d80e9b7d4b608a357fc87dbb9d83535636794e1ae97d5ebcb8f01"},{"path":"linuxcnc/configs/sim/tklinuxcnc/trivkins/xz.ini","label":"trivkins XZ KINEMATICS_IDENTITY","category":"tklinuxcnc/trivkins","display":null,"coordinates":null,"kinematics":"trivkins coordinates=xz","family":"cartesian","status":"ready","startup_preflight":"static_ready","resource_status":"ready","missing_count":0,"unresolved_count":0,"source_sha256":"07f5257557a540b02781de3a641dd1830a78a4cbb15a9cc68ad8d2c6eae8ec81"},{"path":"linuxcnc/configs/sim/tklinuxcnc/trivkins/xz_both.ini","label":"trivkins XZ KINEMATICS_BOTH","category":"tklinuxcnc/trivkins","display":null,"coordinates":null,"kinematics":"trivkins coordinates=xz kinstype=BOTH","family":"cartesian","status":"ready","startup_preflight":"static_ready","resource_status":"ready","missing_count":0,"unresolved_count":0,"source_sha256":"d75c9e05e2a781d1344b3840ba82adc6d7d8d47f53aa11b04c3b918d20c5faae"},{"path":"linuxcnc/configs/sim/touchy/gladevcp/gladevcp_touchy.ini","label":"LinuxCNC-TOUCHY-GLADEVCP","category":"touchy/gladevcp","display":"touchy","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"e7098eb237c6ad9bed4c240f95d313f6ae3221d322b514509f5a7c34373b6011"},{"path":"linuxcnc/configs/sim/touchy/gladevcp/touchy.ini","label":"LinuxCNC-TOUCHY","category":"touchy/gladevcp","display":"touchy","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"65c7aa3b61d553f8aa9f2d43977329ef89d4b58d088729561a0bf7165b6a68a9"},{"path":"linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy.ini","label":"pyngcgui-touchy demo","category":"touchy/ngcgui","display":"touchy","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"6bd6bc6daa9146eb1c662ead43e69edac26cd8a95121c00371607f4bc5f5be0b"},{"path":"linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy_lathe.ini","label":"pyngcgui-touchy-lathe demo","category":"touchy/ngcgui","display":"touchy","coordinates":"X Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"5985f5a6c3bf70d493c897a45a9f0864d1edc6449018185c5787ccfd9d78749a"},{"path":"linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff.ini","label":"pyngcgui-touchy demo","category":"touchy/ngcgui","display":"touchy","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"b27d37a31e597d71ea9065f31d4c5e150ac12fbdef2f2567b74b97cb4cbe651e"},{"path":"linuxcnc/configs/sim/touchy/touchy.ini","label":"LinuxCNC-TOUCHY","category":"touchy","display":"touchy","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"0624683449cbafe697042c42e2f23fdc9513b02dd56aa8f452e386e496ab4571"},{"path":"linuxcnc/configs/sim/woodpecker/woodpecker.ini","label":"woodpecker","category":"woodpecker","display":"qtvcp woodpecker","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"1948487bf44a5c7d5b32186a6b9f330d55cb61bbab55da4a5834f95439cc0deb"},{"path":"linuxcnc/configs/sim/woodpecker/woodpecker_auto_tool_probe.ini","label":"woodpecker","category":"woodpecker","display":"qtvcp -f woodpecker","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":5,"unresolved_count":4,"source_sha256":"9c30092e3c73099af651616a4a9a003337230419bd029e606c10f2b2a2afdade"},{"path":"linuxcnc/configs/sim/woodpecker/woodpecker_xyz.ini","label":"woodpecker","category":"woodpecker","display":"qtvcp woodpecker","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"5aeeb95a708ed2972ad3fa975f37df426129de279c4e8d347bcc2a589ac253ce"},{"path":"linuxcnc/configs/sim/woodpecker/woodpecker_xyza.ini","label":"woodpecker","category":"woodpecker","display":"qtvcp woodpecker","coordinates":"XYZA","kinematics":"trivkins coordinates=XYZA","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"410e1b03a771d7b98a0a75fc13303842af2a20d85b3ff6fe898e83f5a8630752"},{"path":"linuxcnc/configs/sim/woodpecker/woodpecker_xyzab.ini","label":"woodpecker","category":"woodpecker","display":"qtvcp -f woodpecker","coordinates":"XYZAB","kinematics":"trivkins coordinates=XYZAB kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":4,"source_sha256":"3d4d7e2cb2729c9b385e6e6cee04a70ee933a52dcd7f3cf532b7c236bef06eb9"},{"path":"linuxcnc/configs/sim/woodpecker/woodpecker_xyzy.ini","label":"woodpecker","category":"woodpecker","display":"qtvcp woodpecker","coordinates":"XYZY","kinematics":"trivkins coordinates=XYZY kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":5,"unresolved_count":1,"source_sha256":"8374120e08569413c08816a5a5c9e0e8aa0cd0d5536593f6c0fb6d606cffdac5"},{"path":"linuxcnc/configs/sim/woodpecker/woodpecker_xyzya.ini","label":"woodpecker","category":"woodpecker","display":"qtvcp woodpecker","coordinates":"XYZYA","kinematics":"trivkins coordinates=XYZYA kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":5,"unresolved_count":1,"source_sha256":"85a7cca0b4672cdac77822c584e738722656f565af8b48217a3cf1cac17f87ab"}]); -export const SIM_FILE_INDEX = Object.freeze(["linuxcnc/configs/sim/README","linuxcnc/configs/sim/README_es","linuxcnc/configs/sim/axis/.gitignore","linuxcnc/configs/sim/axis/README","linuxcnc/configs/sim/axis/README_es","linuxcnc/configs/sim/axis/anglejog/anglejog.halshow","linuxcnc/configs/sim/axis/anglejog/anglejog.ini","linuxcnc/configs/sim/axis/anglejog/anglejog.txt","linuxcnc/configs/sim/axis/anglejog/anglejog.xml","linuxcnc/configs/sim/axis/anglejog/anglejog_postgui.hal","linuxcnc/configs/sim/axis/axis.ini","linuxcnc/configs/sim/axis/axis_9axis.ini","linuxcnc/configs/sim/axis/axis_mm.ini","linuxcnc/configs/sim/axis/canterp.ini","linuxcnc/configs/sim/axis/canterp_example.can","linuxcnc/configs/sim/axis/classicladder/README","linuxcnc/configs/sim/axis/classicladder/README_es","linuxcnc/configs/sim/axis/classicladder/classicladder.hal","linuxcnc/configs/sim/axis/classicladder/demo_sim_cl.clp","linuxcnc/configs/sim/axis/classicladder/demo_sim_cl.hal","linuxcnc/configs/sim/axis/classicladder/demo_sim_cl.ini","linuxcnc/configs/sim/axis/classicladder/demo_sim_cl.tbl","linuxcnc/configs/sim/axis/cooling.hal","linuxcnc/configs/sim/axis/corexy/3joint_xyz.hal","linuxcnc/configs/sim/axis/corexy/README","linuxcnc/configs/sim/axis/corexy/README_es","linuxcnc/configs/sim/axis/corexy/corexy.halshow","linuxcnc/configs/sim/axis/corexy/corexy_base.inc","linuxcnc/configs/sim/axis/corexy/corexy_by_hal.hal","linuxcnc/configs/sim/axis/corexy/corexy_by_hal.ini","linuxcnc/configs/sim/axis/corexy/corexy_by_hal.txt","linuxcnc/configs/sim/axis/corexy/corexy_by_kins.ini","linuxcnc/configs/sim/axis/corexy/corexy_by_kins.txt","linuxcnc/configs/sim/axis/db_demo/README","linuxcnc/configs/sim/axis/db_demo/base.inc","linuxcnc/configs/sim/axis/db_demo/base.ngc","linuxcnc/configs/sim/axis/db_demo/db.py","linuxcnc/configs/sim/axis/db_demo/db_editor.tcl","linuxcnc/configs/sim/axis/db_demo/db_nonran.ini","linuxcnc/configs/sim/axis/db_demo/db_nonran.py","linuxcnc/configs/sim/axis/db_demo/db_panel.xml","linuxcnc/configs/sim/axis/db_demo/db_postgui.hal","linuxcnc/configs/sim/axis/db_demo/db_ran.ini","linuxcnc/configs/sim/axis/db_demo/db_ran.py","linuxcnc/configs/sim/axis/external_offsets/M111","linuxcnc/configs/sim/axis/external_offsets/README","linuxcnc/configs/sim/axis/external_offsets/README_es","linuxcnc/configs/sim/axis/external_offsets/circles.ngc","linuxcnc/configs/sim/axis/external_offsets/dyn_demo.ngc","linuxcnc/configs/sim/axis/external_offsets/dynamic_offsets.halscope","linuxcnc/configs/sim/axis/external_offsets/dynamic_offsets.ini","linuxcnc/configs/sim/axis/external_offsets/dynamic_offsets.txt","linuxcnc/configs/sim/axis/external_offsets/dynamic_offsets_es.txt","linuxcnc/configs/sim/axis/external_offsets/dynamic_offsets_panel.hal","linuxcnc/configs/sim/axis/external_offsets/dynamic_offsets_panel.xml","linuxcnc/configs/sim/axis/external_offsets/eoffset.tbl","linuxcnc/configs/sim/axis/external_offsets/eoffsets.hal","linuxcnc/configs/sim/axis/external_offsets/eoffsets.ini","linuxcnc/configs/sim/axis/external_offsets/eoffsets.ngc","linuxcnc/configs/sim/axis/external_offsets/eoffsets.txt","linuxcnc/configs/sim/axis/external_offsets/eoffsets_es.txt","linuxcnc/configs/sim/axis/external_offsets/eoffsets_monitor.tcl","linuxcnc/configs/sim/axis/external_offsets/eoffsets_panel.hal","linuxcnc/configs/sim/axis/external_offsets/eoffsets_panel.xml","linuxcnc/configs/sim/axis/external_offsets/jwp_z.ini","linuxcnc/configs/sim/axis/external_offsets/jwp_z.ngc","linuxcnc/configs/sim/axis/external_offsets/jwp_z.txt","linuxcnc/configs/sim/axis/external_offsets/jwp_z_es.txt","linuxcnc/configs/sim/axis/external_offsets/jwp_z_panel.hal","linuxcnc/configs/sim/axis/external_offsets/jwp_z_panel.xml","linuxcnc/configs/sim/axis/external_offsets/opa.hal","linuxcnc/configs/sim/axis/external_offsets/opa.ini","linuxcnc/configs/sim/axis/external_offsets/opa.txt","linuxcnc/configs/sim/axis/external_offsets/opa_demo.ngc","linuxcnc/configs/sim/axis/external_offsets/opa_es.txt","linuxcnc/configs/sim/axis/external_offsets/opa_panel.hal","linuxcnc/configs/sim/axis/external_offsets/opa_panel.xml","linuxcnc/configs/sim/axis/external_offsets/queuebuster.ngc","linuxcnc/configs/sim/axis/extrajoints/12extrajoints.ini","linuxcnc/configs/sim/axis/extrajoints/1extrajoint.hal","linuxcnc/configs/sim/axis/extrajoints/1extrajoint.ini","linuxcnc/configs/sim/axis/extrajoints/1extrajoint.txt","linuxcnc/configs/sim/axis/extrajoints/2extrajoints.hal","linuxcnc/configs/sim/axis/extrajoints/2extrajoints.ini","linuxcnc/configs/sim/axis/extrajoints/2extrajoints.txt","linuxcnc/configs/sim/axis/extrajoints/M144","linuxcnc/configs/sim/axis/extrajoints/README","linuxcnc/configs/sim/axis/extrajoints/README_es","linuxcnc/configs/sim/axis/extrajoints/extrajoints.halshow","linuxcnc/configs/sim/axis/extrajoints/extrajoints.tcl","linuxcnc/configs/sim/axis/foam/axis_foam.ini","linuxcnc/configs/sim/axis/foam/foam.ngc","linuxcnc/configs/sim/axis/gantry/README","linuxcnc/configs/sim/axis/gantry/README_es","linuxcnc/configs/sim/axis/gantry/gantry.ini","linuxcnc/configs/sim/axis/gantry/gantry_jjog.halscope","linuxcnc/configs/sim/axis/gantry/gantry_jjog.ini","linuxcnc/configs/sim/axis/gantry/gantry_jjog.txt","linuxcnc/configs/sim/axis/gantry/gantry_jjog_es.txt","linuxcnc/configs/sim/axis/gantry/gantry_mm.hal","linuxcnc/configs/sim/axis/gantry/gantry_mm.ini","linuxcnc/configs/sim/axis/gantry/gantry_mm.tbl","linuxcnc/configs/sim/axis/gantry/gantry_panel.hal","linuxcnc/configs/sim/axis/gantry/gantry_panel.xml","linuxcnc/configs/sim/axis/geometry/M110","linuxcnc/configs/sim/axis/geometry/README","linuxcnc/configs/sim/axis/geometry/README_es","linuxcnc/configs/sim/axis/geometry/xyzc.ini","linuxcnc/configs/sim/axis/geometry/xyzc.ngc","linuxcnc/configs/sim/axis/geometry/xyzc_origin.ini","linuxcnc/configs/sim/axis/gladevcp/.gitignore","linuxcnc/configs/sim/axis/gladevcp/README","linuxcnc/configs/sim/axis/gladevcp/README_es","linuxcnc/configs/sim/axis/gladevcp/gladevcp_panel.ini","linuxcnc/configs/sim/axis/gladevcp/gladevcp_panel_tester.ini","linuxcnc/configs/sim/axis/gladevcp/gladevcp_panel_tester.txt","linuxcnc/configs/sim/axis/gladevcp/gladevcp_tab.ini","linuxcnc/configs/sim/axis/gladevcp/hitcounter.py","linuxcnc/configs/sim/axis/gladevcp/manual-example.hal","linuxcnc/configs/sim/axis/gladevcp/manual-example.ui","linuxcnc/configs/sim/axis/gladevcp/meter_scale.py","linuxcnc/configs/sim/axis/gladevcp/meter_scale.ui","linuxcnc/configs/sim/axis/gladevcp/probe.hal","linuxcnc/configs/sim/axis/gladevcp/probe.ini","linuxcnc/configs/sim/axis/gladevcp/probe.ngc","linuxcnc/configs/sim/axis/gladevcp/probe.py","linuxcnc/configs/sim/axis/gladevcp/probe.txt","linuxcnc/configs/sim/axis/gladevcp/probe.ui","linuxcnc/configs/sim/axis/gladevcp/probe_es.txt","linuxcnc/configs/sim/axis/gladevcp/probe_gui.sh","linuxcnc/configs/sim/axis/gladevcp/set-param-from-ini.ini","linuxcnc/configs/sim/axis/gladevcp/set-param-from-ini.sh","linuxcnc/configs/sim/axis/gladevcp/set-param-from-ini.txt","linuxcnc/configs/sim/axis/gladevcp/set-param-from-ini_es.txt","linuxcnc/configs/sim/axis/gladevcp/sim.tbl","linuxcnc/configs/sim/axis/gladevcp/test.ui","linuxcnc/configs/sim/axis/gladevcp/test_handler.py","linuxcnc/configs/sim/axis/halui_pyvcp/README","linuxcnc/configs/sim/axis/halui_pyvcp/README_es","linuxcnc/configs/sim/axis/halui_pyvcp/halui.ini","linuxcnc/configs/sim/axis/halui_pyvcp/pyvcp.hal","linuxcnc/configs/sim/axis/halui_pyvcp/sim.tbl","linuxcnc/configs/sim/axis/halui_pyvcp/vcp.xml","linuxcnc/configs/sim/axis/histogram_demo.ini","linuxcnc/configs/sim/axis/histogram_demo.txt","linuxcnc/configs/sim/axis/histogram_demo_es.txt","linuxcnc/configs/sim/axis/historical_lathe.ini","linuxcnc/configs/sim/axis/ini_hal_demo.ini","linuxcnc/configs/sim/axis/ini_hal_demo.txt","linuxcnc/configs/sim/axis/ini_hal_demo_es.txt","linuxcnc/configs/sim/axis/ini_with_includes/.gitignore","linuxcnc/configs/sim/axis/ini_with_includes/README","linuxcnc/configs/sim/axis/ini_with_includes/README_es","linuxcnc/configs/sim/axis/ini_with_includes/axis_x.inc","linuxcnc/configs/sim/axis/ini_with_includes/axis_y.inc","linuxcnc/configs/sim/axis/ini_with_includes/axis_z.inc","linuxcnc/configs/sim/axis/ini_with_includes/display.inc","linuxcnc/configs/sim/axis/ini_with_includes/emc.inc","linuxcnc/configs/sim/axis/ini_with_includes/emcio.inc","linuxcnc/configs/sim/axis/ini_with_includes/emcmot.inc","linuxcnc/configs/sim/axis/ini_with_includes/filter.inc","linuxcnc/configs/sim/axis/ini_with_includes/hal.inc","linuxcnc/configs/sim/axis/ini_with_includes/includes_demo.ini","linuxcnc/configs/sim/axis/ini_with_includes/joint_0.inc","linuxcnc/configs/sim/axis/ini_with_includes/joint_1.inc","linuxcnc/configs/sim/axis/ini_with_includes/joint_2.inc","linuxcnc/configs/sim/axis/ini_with_includes/kins.inc","linuxcnc/configs/sim/axis/ini_with_includes/rs274ngc.inc","linuxcnc/configs/sim/axis/ini_with_includes/sim.tbl","linuxcnc/configs/sim/axis/ini_with_includes/task.inc","linuxcnc/configs/sim/axis/ini_with_includes/traj.inc","linuxcnc/configs/sim/axis/iocontrolv2/README","linuxcnc/configs/sim/axis/iocontrolv2/README_es","linuxcnc/configs/sim/axis/iocontrolv2/axis-iocontrolv2-demo.ini","linuxcnc/configs/sim/axis/iocontrolv2/axis_owordsub_manualtoolchange.hal","linuxcnc/configs/sim/axis/iocontrolv2/g8812.ini","linuxcnc/configs/sim/axis/iocontrolv2/m66track.ini","linuxcnc/configs/sim/axis/iocontrolv2/nstools.tbl","linuxcnc/configs/sim/axis/iocontrolv2/on_abort.ngc","linuxcnc/configs/sim/axis/iocontrolv2/osubdemo-ns.ui","linuxcnc/configs/sim/axis/iocontrolv2/osubdemo.ui","linuxcnc/configs/sim/axis/iocontrolv2/owordm6-ui-ns.ini","linuxcnc/configs/sim/axis/iocontrolv2/owordm6-ui.ini","linuxcnc/configs/sim/axis/iocontrolv2/sim_mm.tbl","linuxcnc/configs/sim/axis/iocontrolv2/sim_mm_test.tbl","linuxcnc/configs/sim/axis/iocontrolv2/t3.ngc","linuxcnc/configs/sim/axis/iocontrolv2/tdemo.ngc","linuxcnc/configs/sim/axis/iocontrolv2/toolchange-demo.ngc","linuxcnc/configs/sim/axis/iocontrolv2/v2-tc.ui","linuxcnc/configs/sim/axis/iocontrolv2/v2_gladevcp_postgui.hal","linuxcnc/configs/sim/axis/iocontrolv2/v2_oword_gladevcp_postgui.hal","linuxcnc/configs/sim/axis/ja_tests/xyzb_locking_indexer/README","linuxcnc/configs/sim/axis/ja_tests/xyzb_locking_indexer/README_es","linuxcnc/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyyzb.ini","linuxcnc/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyzb.hal","linuxcnc/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyzb.halshow","linuxcnc/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyzb.ini","linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/README","linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/README_es","linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/xhc-hb04-postgui.hal","linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/xhc-hb04.inc","linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/xyzx-xhc-hb04.ini","linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/xyzx.halshow","linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/xyzx.ini","linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/xyzx_base.inc","linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/xyzx_jog.hal","linuxcnc/configs/sim/axis/ja_tests/xz/README","linuxcnc/configs/sim/axis/ja_tests/xz/README_es","linuxcnc/configs/sim/axis/ja_tests/xz/xz.ini","linuxcnc/configs/sim/axis/ja_tests/xz/xz.tbl","linuxcnc/configs/sim/axis/ja_tests/xz/xz_both.ini","linuxcnc/configs/sim/axis/ja_tests/xz/xz_both_auto.ini","linuxcnc/configs/sim/axis/ja_tests/xz/xz_both_auto_cmds.hal","linuxcnc/configs/sim/axis/ja_tests/xz/xz_both_cmds.hal","linuxcnc/configs/sim/axis/ja_tests/xz/xz_cmds.hal","linuxcnc/configs/sim/axis/ja_tests/xz/xzbase.inc","linuxcnc/configs/sim/axis/laser/laser.hal","linuxcnc/configs/sim/axis/laser/laser.ini","linuxcnc/configs/sim/axis/laser/postgui.hal","linuxcnc/configs/sim/axis/laser/python/remap.py","linuxcnc/configs/sim/axis/laser/python/toplevel.py","linuxcnc/configs/sim/axis/laser/pyvcp.xml","linuxcnc/configs/sim/axis/laser/raster_test.ngc","linuxcnc/configs/sim/axis/laser/vector_test.ngc","linuxcnc/configs/sim/axis/laser/vector_test2.ngc","linuxcnc/configs/sim/axis/lathe-fanucy/README","linuxcnc/configs/sim/axis/lathe-fanucy/README_es","linuxcnc/configs/sim/axis/lathe-fanucy/lathe-fanucy.ini","linuxcnc/configs/sim/axis/lathe-fanucy/lathe-fanucy.tbl","linuxcnc/configs/sim/axis/lathe-fanucy/remap.py","linuxcnc/configs/sim/axis/lathe-fanucy/toolchange.ngc","linuxcnc/configs/sim/axis/lathe-fanucy/toplevel.py","linuxcnc/configs/sim/axis/lathe.ini","linuxcnc/configs/sim/axis/lathe.tbl","linuxcnc/configs/sim/axis/lathe.xml","linuxcnc/configs/sim/axis/lathe_multispindle/README","linuxcnc/configs/sim/axis/lathe_multispindle/README_es","linuxcnc/configs/sim/axis/lathe_multispindle/core_sim.hal","linuxcnc/configs/sim/axis/lathe_multispindle/lathe.hal","linuxcnc/configs/sim/axis/lathe_multispindle/lathe.ini","linuxcnc/configs/sim/axis/lathe_multispindle/lathe.xml","linuxcnc/configs/sim/axis/lathe_multispindle/lathe_postgui.hal","linuxcnc/configs/sim/axis/lathe_postgui.hal","linuxcnc/configs/sim/axis/ldelta.ini","linuxcnc/configs/sim/axis/ldelta_demo.ini","linuxcnc/configs/sim/axis/ldelta_demo.txt","linuxcnc/configs/sim/axis/ldelta_demo_es.txt","linuxcnc/configs/sim/axis/minimal_xyz.ini","linuxcnc/configs/sim/axis/minimal_xyz_cmds.hal","linuxcnc/configs/sim/axis/moveoff/1_onpause_local.ini","linuxcnc/configs/sim/axis/moveoff/1_onpause_local.txt","linuxcnc/configs/sim/axis/moveoff/1_onpause_local_es.txt","linuxcnc/configs/sim/axis/moveoff/2_onpause_external.ini","linuxcnc/configs/sim/axis/moveoff/2_onpause_external.txt","linuxcnc/configs/sim/axis/moveoff/2_onpause_external_es.txt","linuxcnc/configs/sim/axis/moveoff/3_always_local.ini","linuxcnc/configs/sim/axis/moveoff/3_always_local.txt","linuxcnc/configs/sim/axis/moveoff/3_always_local_es.txt","linuxcnc/configs/sim/axis/moveoff/4_always_external.ini","linuxcnc/configs/sim/axis/moveoff/4_always_external.txt","linuxcnc/configs/sim/axis/moveoff/4_always_external_es.tx","linuxcnc/configs/sim/axis/moveoff/5_no_gui.ini","linuxcnc/configs/sim/axis/moveoff/5_no_gui.txt","linuxcnc/configs/sim/axis/moveoff/5_no_gui_es.txt","linuxcnc/configs/sim/axis/moveoff/6_zretract.ini","linuxcnc/configs/sim/axis/moveoff/6_zretract.txt","linuxcnc/configs/sim/axis/moveoff/6_zretract_es.txt","linuxcnc/configs/sim/axis/moveoff/7_pyvcp.ini","linuxcnc/configs/sim/axis/moveoff/7_pyvcp.txt","linuxcnc/configs/sim/axis/moveoff/7_pyvcp_es.txt","linuxcnc/configs/sim/axis/moveoff/8_gladevcp.ini","linuxcnc/configs/sim/axis/moveoff/8_gladevcp.txt","linuxcnc/configs/sim/axis/moveoff/8_gladevcp_es.txt","linuxcnc/configs/sim/axis/moveoff/README","linuxcnc/configs/sim/axis/moveoff/README_es","linuxcnc/configs/sim/axis/moveoff/moveoff.hal","linuxcnc/configs/sim/axis/moveoff/moveoff.halscope","linuxcnc/configs/sim/axis/moveoff/moveoff.halshow","linuxcnc/configs/sim/axis/moveoff/moveoff_base.inc","linuxcnc/configs/sim/axis/moveoff/moveoff_display.inc","linuxcnc/configs/sim/axis/moveoff/moveoff_display_6.hal","linuxcnc/configs/sim/axis/moveoff/moveoff_display_6.inc","linuxcnc/configs/sim/axis/moveoff/moveoff_display_6.xml","linuxcnc/configs/sim/axis/moveoff/moveoff_display_7.hal","linuxcnc/configs/sim/axis/moveoff/moveoff_display_7.inc","linuxcnc/configs/sim/axis/moveoff/moveoff_display_7.xml","linuxcnc/configs/sim/axis/moveoff/moveoff_display_8.hal","linuxcnc/configs/sim/axis/moveoff/moveoff_display_8.inc","linuxcnc/configs/sim/axis/moveoff/moveoff_gladevcp_8.ui","linuxcnc/configs/sim/axis/moveoff/moveoff_settings.inc","linuxcnc/configs/sim/axis/moveoff/removeshort.hal","linuxcnc/configs/sim/axis/moveoff/sim.tbl","linuxcnc/configs/sim/axis/ngcgui/README","linuxcnc/configs/sim/axis/ngcgui/README_es","linuxcnc/configs/sim/axis/ngcgui/axis_resize.py","linuxcnc/configs/sim/axis/ngcgui/fullscreen.py","linuxcnc/configs/sim/axis/ngcgui/gremlin_view.ui","linuxcnc/configs/sim/axis/ngcgui/lathe.tbl","linuxcnc/configs/sim/axis/ngcgui/ngcgui.ini","linuxcnc/configs/sim/axis/ngcgui/ngcgui.txt","linuxcnc/configs/sim/axis/ngcgui/ngcgui_es.txt","linuxcnc/configs/sim/axis/ngcgui/ngcgui_gcmc.ini","linuxcnc/configs/sim/axis/ngcgui/ngcgui_gcmc.txt","linuxcnc/configs/sim/axis/ngcgui/ngcgui_gcmc_es.txt","linuxcnc/configs/sim/axis/ngcgui/ngcgui_lathe.ini","linuxcnc/configs/sim/axis/ngcgui/ngcgui_lathe.txt","linuxcnc/configs/sim/axis/ngcgui/ngcgui_lathe_es.txt","linuxcnc/configs/sim/axis/ngcgui/ngcgui_simple.ini","linuxcnc/configs/sim/axis/ngcgui/ngcgui_simple.txt","linuxcnc/configs/sim/axis/ngcgui/ngcgui_simple_es.txt","linuxcnc/configs/sim/axis/ngcgui/pyngcgui_axis.ini","linuxcnc/configs/sim/axis/ngcgui/pyngcgui_axis.txt","linuxcnc/configs/sim/axis/ngcgui/pyngcgui_axis.ui","linuxcnc/configs/sim/axis/ngcgui/pyngcgui_axis_es.txt","linuxcnc/configs/sim/axis/ngcgui/pyngcgui_popupkeyboard.ui","linuxcnc/configs/sim/axis/ngcgui/sim.tbl","linuxcnc/configs/sim/axis/orphans/README","linuxcnc/configs/sim/axis/orphans/README_es","linuxcnc/configs/sim/axis/orphans/acc_test.ini","linuxcnc/configs/sim/axis/orphans/axis_noio.ini","linuxcnc/configs/sim/axis/orphans/core_sim_noio.hal","linuxcnc/configs/sim/axis/orphans/core_sim_noiocontrol.hal","linuxcnc/configs/sim/axis/orphans/core_sim_test.hal","linuxcnc/configs/sim/axis/orphans/gladevcp_postgui.hal","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/core_sim_test.hal","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/gladevcp.hal","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/iocontrol-removed.ini","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/nc_files/tcdemo.ngc","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/no-iotask.nml","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/python/customtask.py","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/python/embedding.py","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/python/nulluserfuncs.py","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/python/oword.py","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/python/remap.py","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/python/sqltoolaccess.py","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/python/task.py","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/python/tooltable.py","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/python/toplevel.py","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/python/userfuncs.py","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/racktoolchange-noioctl.glade","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/racktoolchange-noioctl.ui","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/racktoolchange.hal","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/tooltable.sql","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/tooltable.sqlite","linuxcnc/configs/sim/axis/orphans/iov2.hal","linuxcnc/configs/sim/axis/orphans/medium.ini","linuxcnc/configs/sim/axis/orphans/no-iotask.nml","linuxcnc/configs/sim/axis/orphans/py.ini.notworking","linuxcnc/configs/sim/axis/orphans/pyiocontrol.ini.notworking","linuxcnc/configs/sim/axis/orphans/pysubs/customtask.py","linuxcnc/configs/sim/axis/orphans/pysubs/nulluserfuncs.py","linuxcnc/configs/sim/axis/orphans/pysubs/oword.py","linuxcnc/configs/sim/axis/orphans/pysubs/plugins.py","linuxcnc/configs/sim/axis/orphans/pysubs/remap.py","linuxcnc/configs/sim/axis/orphans/pysubs/sqltoolaccess.py","linuxcnc/configs/sim/axis/orphans/pysubs/task.py","linuxcnc/configs/sim/axis/orphans/pysubs/tooltable.py","linuxcnc/configs/sim/axis/orphans/pysubs/userfuncs.py","linuxcnc/configs/sim/axis/orphans/sim_mm.tbl","linuxcnc/configs/sim/axis/orphans/taskcall.ngc","linuxcnc/configs/sim/axis/panelui-demo/README","linuxcnc/configs/sim/axis/panelui-demo/README_es","linuxcnc/configs/sim/axis/panelui-demo/_panelui.ini","linuxcnc/configs/sim/axis/panelui-demo/custom.hal","linuxcnc/configs/sim/axis/panelui-demo/custom_postgui.hal","linuxcnc/configs/sim/axis/panelui-demo/panel.glade","linuxcnc/configs/sim/axis/panelui-demo/panelui-demo.hal","linuxcnc/configs/sim/axis/panelui-demo/panelui-demo.ini","linuxcnc/configs/sim/axis/panelui-demo/panelui_handler.py","linuxcnc/configs/sim/axis/panelui-demo/sim_hardware.hal","linuxcnc/configs/sim/axis/panelui-demo/tool.tbl","linuxcnc/configs/sim/axis/pentapod/README","linuxcnc/configs/sim/axis/pentapod/README_es","linuxcnc/configs/sim/axis/pentapod/kinematics.hal","linuxcnc/configs/sim/axis/pentapod/panel.xml","linuxcnc/configs/sim/axis/pentapod/pentapod.ini","linuxcnc/configs/sim/axis/pentapod/pentapod_postgui.hal","linuxcnc/configs/sim/axis/pentapod/tool.tbl","linuxcnc/configs/sim/axis/plasma/README","linuxcnc/configs/sim/axis/plasma/custom.hal","linuxcnc/configs/sim/axis/plasma/customizing.html","linuxcnc/configs/sim/axis/plasma/imperial.ini","linuxcnc/configs/sim/axis/plasma/imperial.prefs","linuxcnc/configs/sim/axis/plasma/imperial_material.cfg","linuxcnc/configs/sim/axis/plasma/imperial_tool.tbl","linuxcnc/configs/sim/axis/plasma/metric.ini","linuxcnc/configs/sim/axis/plasma/metric.prefs","linuxcnc/configs/sim/axis/plasma/metric_material.cfg","linuxcnc/configs/sim/axis/plasma/metric_tool.tbl","linuxcnc/configs/sim/axis/plasma/plasmac2/M190","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_block.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_bolt.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_circle.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_ellipse.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_gusset.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_line.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_polygon.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_rectangle.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_sector.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_settings.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_slot.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_star.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_triangle.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conversational.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/custom/user_commands.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/custom/user_hal.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/custom/user_periodic.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/block.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/boltcircle.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/chips_plasma.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/circle.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/closer.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/e.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/ellipse.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/gusset.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/line.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/n.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/ne.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/nw.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/polygon.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/rectangle.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/s.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/save.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/se.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/sector.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/slot.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/star.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/sw.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/triangle.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/view_p.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/view_t.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/view_z.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/w.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/keyboard.onboard","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/keyboard.svg","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/numpad.onboard","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/numpad.svg","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/sim/sim_no_stepgen.tcl","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/sim/sim_panel.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/sim/sim_stepgen.tcl","linuxcnc/configs/sim/axis/plasma/plasmac2/migrate.py","linuxcnc/configs/sim/axis/plasma/plasmac2/plasmac2.py","linuxcnc/configs/sim/axis/plasma/plasmac2/versions.html","linuxcnc/configs/sim/axis/plasma/user_commands.py","linuxcnc/configs/sim/axis/plasma/user_hal.py","linuxcnc/configs/sim/axis/plasma/user_periodic.py","linuxcnc/configs/sim/axis/postgui_calib_helper.hal","linuxcnc/configs/sim/axis/profile_axis.ini","linuxcnc/configs/sim/axis/qtvcp/.gitignore","linuxcnc/configs/sim/axis/qtvcp/qtvcp_tab.ini","linuxcnc/configs/sim/axis/qtvcp/qtvismach_tab.ini","linuxcnc/configs/sim/axis/qtvcp/sim.tbl","linuxcnc/configs/sim/axis/random_tc.ini","linuxcnc/configs/sim/axis/rdelta.ini","linuxcnc/configs/sim/axis/remap/README","linuxcnc/configs/sim/axis/remap/README_es","linuxcnc/configs/sim/axis/remap/cycle/README","linuxcnc/configs/sim/axis/remap/cycle/README_es","linuxcnc/configs/sim/axis/remap/cycle/cycle.ini","linuxcnc/configs/sim/axis/remap/cycle/nc_files/examples.ngc","linuxcnc/configs/sim/axis/remap/cycle/nc_subroutines/g843.ngc","linuxcnc/configs/sim/axis/remap/cycle/python/remap.py","linuxcnc/configs/sim/axis/remap/cycle/python/toplevel.py","linuxcnc/configs/sim/axis/remap/cycle/tool.tbl","linuxcnc/configs/sim/axis/remap/extend-builtins/README","linuxcnc/configs/sim/axis/remap/extend-builtins/README_es","linuxcnc/configs/sim/axis/remap/extend-builtins/extend-builtins.ini","linuxcnc/configs/sim/axis/remap/extend-builtins/gladevcp.hal","linuxcnc/configs/sim/axis/remap/extend-builtins/nc_files/examples.ngc","linuxcnc/configs/sim/axis/remap/extend-builtins/nc_subroutines/change.ngc","linuxcnc/configs/sim/axis/remap/extend-builtins/nc_subroutines/extend_m0.ngc","linuxcnc/configs/sim/axis/remap/extend-builtins/nc_subroutines/extend_m1.ngc","linuxcnc/configs/sim/axis/remap/extend-builtins/nc_subroutines/extend_m60.ngc","linuxcnc/configs/sim/axis/remap/extend-builtins/nc_subroutines/prepare.ngc","linuxcnc/configs/sim/axis/remap/extend-builtins/nc_subroutines/setfeed.ngc","linuxcnc/configs/sim/axis/remap/extend-builtins/nc_subroutines/setspeed.ngc","linuxcnc/configs/sim/axis/remap/extend-builtins/nc_subroutines/settool.ngc","linuxcnc/configs/sim/axis/remap/extend-builtins/python/remap.py","linuxcnc/configs/sim/axis/remap/extend-builtins/python/toplevel.py","linuxcnc/configs/sim/axis/remap/extend-builtins/show.ui","linuxcnc/configs/sim/axis/remap/extend-builtins/tool.tbl","linuxcnc/configs/sim/axis/remap/getting-started/demo.ini","linuxcnc/configs/sim/axis/remap/getting-started/nc_files/examples.ngc","linuxcnc/configs/sim/axis/remap/getting-started/nc_subroutines/change_min.ngc","linuxcnc/configs/sim/axis/remap/getting-started/nc_subroutines/m400.ngc","linuxcnc/configs/sim/axis/remap/getting-started/nc_subroutines/m410.ngc","linuxcnc/configs/sim/axis/remap/getting-started/nc_subroutines/prepare_min.ngc","linuxcnc/configs/sim/axis/remap/getting-started/python/oword.py","linuxcnc/configs/sim/axis/remap/getting-started/python/remap.py","linuxcnc/configs/sim/axis/remap/getting-started/python/toplevel.py","linuxcnc/configs/sim/axis/remap/getting-started/python/util.py","linuxcnc/configs/sim/axis/remap/getting-started/tool.tbl","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/README","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/README_es","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/gladevcp.hal","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/manualtoolchange.glade","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/manualtoolchange.hal","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/manualtoolchange.ini","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/manualtoolchange.ui","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/nc_files/tcdemo.ngc","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/nc_subroutines/manual_change.ngc","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/nc_subroutines/on_abort.ngc","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/nc_subroutines/restore.ngc","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/python/gladevcp-handler.py","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/python/remap.py","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/python/toplevel.py","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/tool.tbl","linuxcnc/configs/sim/axis/remap/rack-toolchange/README","linuxcnc/configs/sim/axis/remap/rack-toolchange/README_es","linuxcnc/configs/sim/axis/remap/rack-toolchange/gladevcp.hal","linuxcnc/configs/sim/axis/remap/rack-toolchange/nc_files/tcdemo.ngc","linuxcnc/configs/sim/axis/remap/rack-toolchange/nc_subroutines/on_abort.ngc","linuxcnc/configs/sim/axis/remap/rack-toolchange/nc_subroutines/rack_change.ngc","linuxcnc/configs/sim/axis/remap/rack-toolchange/nc_subroutines/tool_getput_move.ngc","linuxcnc/configs/sim/axis/remap/rack-toolchange/nc_subroutines/tool_holder_clear_move.ngc","linuxcnc/configs/sim/axis/remap/rack-toolchange/python/remap.py","linuxcnc/configs/sim/axis/remap/rack-toolchange/python/toplevel.py","linuxcnc/configs/sim/axis/remap/rack-toolchange/racktoolchange.glade","linuxcnc/configs/sim/axis/remap/rack-toolchange/racktoolchange.hal","linuxcnc/configs/sim/axis/remap/rack-toolchange/racktoolchange.ini","linuxcnc/configs/sim/axis/remap/rack-toolchange/racktoolchange.ui","linuxcnc/configs/sim/axis/remap/rack-toolchange/tool.tbl","linuxcnc/configs/sim/axis/remap/stop-lookahead/README","linuxcnc/configs/sim/axis/remap/stop-lookahead/README_es","linuxcnc/configs/sim/axis/remap/stop-lookahead/demo.ini","linuxcnc/configs/sim/axis/remap/stop-lookahead/nc_files/examples.ngc","linuxcnc/configs/sim/axis/remap/stop-lookahead/python/remap.py","linuxcnc/configs/sim/axis/remap/stop-lookahead/python/toplevel.py","linuxcnc/configs/sim/axis/remap/stop-lookahead/tool.tbl","linuxcnc/configs/sim/axis/remap/tool.tbl","linuxcnc/configs/sim/axis/rose_engine/README","linuxcnc/configs/sim/axis/rose_engine/README_es","linuxcnc/configs/sim/axis/rose_engine/rcone.ngc","linuxcnc/configs/sim/axis/rose_engine/rcone_demo.ngc","linuxcnc/configs/sim/axis/rose_engine/rose_engine.halshow","linuxcnc/configs/sim/axis/rose_engine/rose_engine.ini","linuxcnc/configs/sim/axis/rotate/rotatekins.hal","linuxcnc/configs/sim/axis/rotate/rotatekins.ini","linuxcnc/configs/sim/axis/sim.tbl","linuxcnc/configs/sim/axis/sim_mm.tbl","linuxcnc/configs/sim/axis/simpockets.tbl","linuxcnc/configs/sim/axis/simtcl/README","linuxcnc/configs/sim/axis/simtcl/README_es","linuxcnc/configs/sim/axis/simtcl/sim.tbl","linuxcnc/configs/sim/axis/simtcl/twopass_base.inc","linuxcnc/configs/sim/axis/simtcl/twopass_basic.ini","linuxcnc/configs/sim/axis/simtcl/twopass_basic.txt","linuxcnc/configs/sim/axis/simtcl/twopass_basic_es.txt","linuxcnc/configs/sim/axis/simtcl/twopass_compat.ini","linuxcnc/configs/sim/axis/simtcl/twopass_compat.txt","linuxcnc/configs/sim/axis/simtcl/twopass_compat_es.txt","linuxcnc/configs/sim/axis/spindle_orient/README","linuxcnc/configs/sim/axis/spindle_orient/README_es","linuxcnc/configs/sim/axis/spindle_orient/orient.hal","linuxcnc/configs/sim/axis/spindle_orient/orient.ini","linuxcnc/configs/sim/axis/spindle_orient/orient.ui","linuxcnc/configs/sim/axis/spindle_orient/sim.tbl","linuxcnc/configs/sim/axis/twopass/README","linuxcnc/configs/sim/axis/twopass/README_es","linuxcnc/configs/sim/axis/twopass/load_for_postgui.hal","linuxcnc/configs/sim/axis/twopass/postgui.hal","linuxcnc/configs/sim/axis/twopass/sim.tbl","linuxcnc/configs/sim/axis/twopass/twopass.ini","linuxcnc/configs/sim/axis/twopass/twopass.txt","linuxcnc/configs/sim/axis/twopass/twopass_excluded.hal","linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial","linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.hal","linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini","linuxcnc/configs/sim/axis/vismach/3axis-tutorial/README","linuxcnc/configs/sim/axis/vismach/3axis-tutorial/README_es","linuxcnc/configs/sim/axis/vismach/3axis-tutorial/tool.tbl","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/5axis.ini","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/5axis.tbl","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/5axis.xml","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/5axis_postgui.hal","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/5axisgui.hal","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/5axisgui.ngc","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/README","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/README_es","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/remap_subs/428remap.ngc","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/remap_subs/429remap.ngc","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/remap_subs/430remap.ngc","linuxcnc/configs/sim/axis/vismach/5axis/max5/README","linuxcnc/configs/sim/axis/vismach/5axis/max5/README_es","linuxcnc/configs/sim/axis/vismach/5axis/max5/max5.tbl","linuxcnc/configs/sim/axis/vismach/5axis/max5/max5_base.inc","linuxcnc/configs/sim/axis/vismach/5axis/max5/max5kins.hal","linuxcnc/configs/sim/axis/vismach/5axis/max5/max5kins.ini","linuxcnc/configs/sim/axis/vismach/5axis/max5/max5triv.hal","linuxcnc/configs/sim/axis/vismach/5axis/max5/max5triv.ini","linuxcnc/configs/sim/axis/vismach/5axis/table-dual-rotary/README","linuxcnc/configs/sim/axis/vismach/5axis/table-dual-rotary/demos/xyzab-tdr-demo.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-dual-rotary/remap_subs/428remap.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-dual-rotary/remap_subs/429remap.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr-postgui.hal","linuxcnc/configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.ini","linuxcnc/configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.tbl","linuxcnc/configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.xml","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/README","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/README_es","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_2.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_3.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/centering.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_ac.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_bc.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/xyzac_switchkins_sub.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/xyzbc_switchkins_sub.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins.halshow","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins_postgui.hal","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.tbl","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.txt","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.xml","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.tbl","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.txt","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.xml","linuxcnc/configs/sim/axis/vismach/README","linuxcnc/configs/sim/axis/vismach/README_es","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/README","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/README_es","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/arm.stl","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/base.stl","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/carousel.stl","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/head.stl","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/remap.py","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/saddle.stl","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/sim_vmc.hal","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/spindle.hal","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/table.stl","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/toolchange.ngc","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/toolchange_gray.hal","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/toolchange_index.hal","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/toplevel.py","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/vmc.hal","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/vmc.tbl","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/vmc_graycode.ini","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/vmc_index.ini","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/vmcgui","linuxcnc/configs/sim/axis/vismach/hbm/hbm.hal","linuxcnc/configs/sim/axis/vismach/hbm/hbm.ini","linuxcnc/configs/sim/axis/vismach/hbm/hbm.tbl","linuxcnc/configs/sim/axis/vismach/hexapod-sim/README","linuxcnc/configs/sim/axis/vismach/hexapod-sim/README_es","linuxcnc/configs/sim/axis/vismach/hexapod-sim/hexagui.halshow","linuxcnc/configs/sim/axis/vismach/hexapod-sim/hexapod.ini","linuxcnc/configs/sim/axis/vismach/hexapod-sim/hexapod.xml","linuxcnc/configs/sim/axis/vismach/hexapod-sim/hexapod_postgui.hal","linuxcnc/configs/sim/axis/vismach/hexapod-sim/kinematics.hal","linuxcnc/configs/sim/axis/vismach/hexapod-sim/remap_subs/428remap.ngc","linuxcnc/configs/sim/axis/vismach/hexapod-sim/remap_subs/429remap.ngc","linuxcnc/configs/sim/axis/vismach/hexapod-sim/remap_subs/430remap.ngc","linuxcnc/configs/sim/axis/vismach/melfa-sim/README","linuxcnc/configs/sim/axis/vismach/melfa-sim/example.ngc","linuxcnc/configs/sim/axis/vismach/melfa-sim/link1.stl","linuxcnc/configs/sim/axis/vismach/melfa-sim/link2.stl","linuxcnc/configs/sim/axis/vismach/melfa-sim/link3.stl","linuxcnc/configs/sim/axis/vismach/melfa-sim/link4.stl","linuxcnc/configs/sim/axis/vismach/melfa-sim/link5.stl","linuxcnc/configs/sim/axis/vismach/melfa-sim/link6.stl","linuxcnc/configs/sim/axis/vismach/melfa-sim/link7.stl","linuxcnc/configs/sim/axis/vismach/melfa-sim/melfa-postgui.hal","linuxcnc/configs/sim/axis/vismach/melfa-sim/melfa.ini","linuxcnc/configs/sim/axis/vismach/melfa-sim/melfa.tbl","linuxcnc/configs/sim/axis/vismach/melfa-sim/melfa.txt","linuxcnc/configs/sim/axis/vismach/melfa-sim/melfa.xml","linuxcnc/configs/sim/axis/vismach/melfa-sim/melfa_dh.hal","linuxcnc/configs/sim/axis/vismach/melfa-sim/remap_subs/428remap.ngc","linuxcnc/configs/sim/axis/vismach/melfa-sim/remap_subs/429remap.ngc","linuxcnc/configs/sim/axis/vismach/melfa-sim/remap_subs/430remap.ngc","linuxcnc/configs/sim/axis/vismach/millturn/README","linuxcnc/configs/sim/axis/vismach/millturn/example.ngc","linuxcnc/configs/sim/axis/vismach/millturn/mcodes/M128","linuxcnc/configs/sim/axis/vismach/millturn/mcodes/M129","linuxcnc/configs/sim/axis/vismach/millturn/millturn-postgui.hal","linuxcnc/configs/sim/axis/vismach/millturn/millturn.hal","linuxcnc/configs/sim/axis/vismach/millturn/millturn.halshow","linuxcnc/configs/sim/axis/vismach/millturn/millturn.ini","linuxcnc/configs/sim/axis/vismach/millturn/millturn.tbl","linuxcnc/configs/sim/axis/vismach/millturn/millturn.txt","linuxcnc/configs/sim/axis/vismach/millturn/millturn.xml","linuxcnc/configs/sim/axis/vismach/millturn/remap_subs/428remap.ngc","linuxcnc/configs/sim/axis/vismach/millturn/remap_subs/429remap.ngc","linuxcnc/configs/sim/axis/vismach/puma/README","linuxcnc/configs/sim/axis/vismach/puma/README_es","linuxcnc/configs/sim/axis/vismach/puma/mcodes/M128","linuxcnc/configs/sim/axis/vismach/puma/mcodes/M129","linuxcnc/configs/sim/axis/vismach/puma/mcodes/M130","linuxcnc/configs/sim/axis/vismach/puma/puma.ini","linuxcnc/configs/sim/axis/vismach/puma/puma.tbl","linuxcnc/configs/sim/axis/vismach/puma/puma.xml","linuxcnc/configs/sim/axis/vismach/puma/puma560.halshow","linuxcnc/configs/sim/axis/vismach/puma/puma560.ini","linuxcnc/configs/sim/axis/vismach/puma/puma560.txt","linuxcnc/configs/sim/axis/vismach/puma/puma560.xml","linuxcnc/configs/sim/axis/vismach/puma/puma560_dh.hal","linuxcnc/configs/sim/axis/vismach/puma/puma560_postgui.hal","linuxcnc/configs/sim/axis/vismach/puma/puma560_uvw.ini","linuxcnc/configs/sim/axis/vismach/puma/puma_cube.ini","linuxcnc/configs/sim/axis/vismach/puma/puma_cube.ngc","linuxcnc/configs/sim/axis/vismach/puma/puma_cube.txt","linuxcnc/configs/sim/axis/vismach/puma/puma_dh.hal","linuxcnc/configs/sim/axis/vismach/puma/puma_link1.obj","linuxcnc/configs/sim/axis/vismach/puma/puma_link2.obj","linuxcnc/configs/sim/axis/vismach/puma/puma_link3.obj","linuxcnc/configs/sim/axis/vismach/puma/puma_link4.obj","linuxcnc/configs/sim/axis/vismach/puma/puma_link5.obj","linuxcnc/configs/sim/axis/vismach/puma/puma_link6.obj","linuxcnc/configs/sim/axis/vismach/puma/puma_link7.obj","linuxcnc/configs/sim/axis/vismach/puma/puma_postgui.hal","linuxcnc/configs/sim/axis/vismach/puma/puma_seam_weld.ngc","linuxcnc/configs/sim/axis/vismach/puma/puma_text.obj","linuxcnc/configs/sim/axis/vismach/puma/remap_subs/428remap.ngc","linuxcnc/configs/sim/axis/vismach/puma/remap_subs/429remap.ngc","linuxcnc/configs/sim/axis/vismach/puma/remap_subs/430remap.ngc","linuxcnc/configs/sim/axis/vismach/rolfmill/README","linuxcnc/configs/sim/axis/vismach/rolfmill/README_es","linuxcnc/configs/sim/axis/vismach/rolfmill/rolfmill","linuxcnc/configs/sim/axis/vismach/rolfmill/rolfmill.hal","linuxcnc/configs/sim/axis/vismach/rolfmill/rolfmill.ini","linuxcnc/configs/sim/axis/vismach/rolfmill/tool.tbl","linuxcnc/configs/sim/axis/vismach/scara/README","linuxcnc/configs/sim/axis/vismach/scara/README_es","linuxcnc/configs/sim/axis/vismach/scara/remap_subs/428remap.ngc","linuxcnc/configs/sim/axis/vismach/scara/remap_subs/429remap.ngc","linuxcnc/configs/sim/axis/vismach/scara/remap_subs/430remap.ngc","linuxcnc/configs/sim/axis/vismach/scara/scara.ini","linuxcnc/configs/sim/axis/vismach/scara/scara.xml","linuxcnc/configs/sim/axis/vismach/scara/scara_postgui.hal","linuxcnc/configs/sim/axis/vismach/scorbot/scorbot.hal","linuxcnc/configs/sim/axis/vismach/scorbot/scorbot.ini","linuxcnc/configs/sim/axis/wrapped_rotary/README","linuxcnc/configs/sim/axis/wrapped_rotary/README_es","linuxcnc/configs/sim/axis/wrapped_rotary/wrapped_rotary.hal","linuxcnc/configs/sim/axis/wrapped_rotary/wrapped_rotary.ini","linuxcnc/configs/sim/axis/wrapped_rotary/wrapped_rotary.tbl","linuxcnc/configs/sim/axis/xhc-hb04/README","linuxcnc/configs/sim/axis/xhc-hb04/README_es","linuxcnc/configs/sim/axis/xhc-hb04/inch_base.inc","linuxcnc/configs/sim/axis/xhc-hb04/inch_trivkins.inc","linuxcnc/configs/sim/axis/xhc-hb04/layout1.inc","linuxcnc/configs/sim/axis/xhc-hb04/layout2.inc","linuxcnc/configs/sim/axis/xhc-hb04/mm_base.inc","linuxcnc/configs/sim/axis/xhc-hb04/mm_trivkins.inc","linuxcnc/configs/sim/axis/xhc-hb04/sim.tbl","linuxcnc/configs/sim/axis/xhc-hb04/sim_mm.tbl","linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout1.ini","linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout1.txt","linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout1_es.txt","linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout2.ini","linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout2.txt","linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout2_es.txt","linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout2_mm.ini","linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout2_mm.txt","linuxcnc/configs/sim/craftsman/ConfigParser_New.py","linuxcnc/configs/sim/craftsman/README","linuxcnc/configs/sim/craftsman/cm_axis_panel.glade","linuxcnc/configs/sim/craftsman/cm_axis_panel.hal","linuxcnc/configs/sim/craftsman/cm_axis_panel.py","linuxcnc/configs/sim/craftsman/cnc_settings.ini","linuxcnc/configs/sim/craftsman/craftsman_icon.png","linuxcnc/configs/sim/craftsman/craftsman_router_icon.png","linuxcnc/configs/sim/craftsman/craftsman_spindle.hal","linuxcnc/configs/sim/craftsman/craftsman_toolchange","linuxcnc/configs/sim/craftsman/craftsman_toolchange.hal","linuxcnc/configs/sim/craftsman/craftsmancnc","linuxcnc/configs/sim/craftsman/craftsmancnc-axis.ini","linuxcnc/configs/sim/craftsman/craftsmancnc.glade","linuxcnc/configs/sim/craftsman/craftsmancnc.hal","linuxcnc/configs/sim/craftsman/craftsmancnc.ini","linuxcnc/configs/sim/craftsman/easygui.py","linuxcnc/configs/sim/craftsman/estimate_time.py","linuxcnc/configs/sim/craftsman/extents.dat","linuxcnc/configs/sim/craftsman/globals.py","linuxcnc/configs/sim/craftsman/history.dat","linuxcnc/configs/sim/craftsman/macros/M100","linuxcnc/configs/sim/craftsman/macros/M101","linuxcnc/configs/sim/craftsman/macros/M102","linuxcnc/configs/sim/craftsman/macros/M103","linuxcnc/configs/sim/craftsman/macros/M105","linuxcnc/configs/sim/craftsman/macros/M106","linuxcnc/configs/sim/craftsman/macros/M107","linuxcnc/configs/sim/craftsman/macros/M108","linuxcnc/configs/sim/craftsman/macros/m101.ngc","linuxcnc/configs/sim/craftsman/macros/m102.ngc","linuxcnc/configs/sim/craftsman/macros/m103.ngc","linuxcnc/configs/sim/craftsman/macros/m104.ngc","linuxcnc/configs/sim/craftsman/macros/m105.ngc","linuxcnc/configs/sim/craftsman/macros/m106.ngc","linuxcnc/configs/sim/craftsman/mdi_history.dat","linuxcnc/configs/sim/craftsman/messages","linuxcnc/configs/sim/craftsman/screen1.jpg","linuxcnc/configs/sim/craftsman/screen2.jpg","linuxcnc/configs/sim/craftsman/screen3.jpg","linuxcnc/configs/sim/craftsman/screens/craftsmancnc.ngc","linuxcnc/configs/sim/craftsman/screens/gcodes.htm","linuxcnc/configs/sim/craftsman/screens/gcodes_files/G81.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/G81a.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/G81ex1.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/G81ex2.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/G81mult.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/asciidoc-xhtml11.js","linuxcnc/configs/sim/craftsman/screens/gcodes_files/eight.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/g2-3.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/g2.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/g76-01.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/g76-threads.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/linuxcnc.css","linuxcnc/configs/sim/craftsman/screens/gcodes_files/nurbs01.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/twelve.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/xhtml11-quirks.css","linuxcnc/configs/sim/craftsman/screens/gcodes_files/xhtml11.css","linuxcnc/configs/sim/craftsman/screens/linuxcnc screen.png","linuxcnc/configs/sim/craftsman/screens/mcodes.htm","linuxcnc/configs/sim/craftsman/screens/mcodes_files/asciidoc-xhtml11.js","linuxcnc/configs/sim/craftsman/screens/mcodes_files/linuxcnc.css","linuxcnc/configs/sim/craftsman/screens/mcodes_files/xhtml11-quirks.css","linuxcnc/configs/sim/craftsman/screens/mcodes_files/xhtml11.css","linuxcnc/configs/sim/craftsman/screens/screen1.jpg","linuxcnc/configs/sim/craftsman/screens/screen2.jpg","linuxcnc/configs/sim/craftsman/screens/screen3.jpg","linuxcnc/configs/sim/craftsman/sim_core.hal","linuxcnc/configs/sim/craftsman/spindle_control.dat","linuxcnc/configs/sim/craftsman/tool.dat","linuxcnc/configs/sim/craftsman/tool.tbl","linuxcnc/configs/sim/craftsman/toolchange.dat","linuxcnc/configs/sim/craftsman/vfd_controller.py","linuxcnc/configs/sim/craftsman/vfd_spindle","linuxcnc/configs/sim/gmoccapy/6_axis.ini","linuxcnc/configs/sim/gmoccapy/7_axis.ini","linuxcnc/configs/sim/gmoccapy/7_axis_tool.ini","linuxcnc/configs/sim/gmoccapy/8_axis.ini","linuxcnc/configs/sim/gmoccapy/9_axis.ini","linuxcnc/configs/sim/gmoccapy/README","linuxcnc/configs/sim/gmoccapy/README_es","linuxcnc/configs/sim/gmoccapy/button.glade","linuxcnc/configs/sim/gmoccapy/core_sim.hal","linuxcnc/configs/sim/gmoccapy/core_sim4.hal","linuxcnc/configs/sim/gmoccapy/core_sim_6.hal","linuxcnc/configs/sim/gmoccapy/core_sim_7.hal","linuxcnc/configs/sim/gmoccapy/core_sim_8.hal","linuxcnc/configs/sim/gmoccapy/core_sim_9.hal","linuxcnc/configs/sim/gmoccapy/core_sim_XYZAB.hal","linuxcnc/configs/sim/gmoccapy/core_sim_XYZAC.hal","linuxcnc/configs/sim/gmoccapy/core_sim_XYZCW.hal","linuxcnc/configs/sim/gmoccapy/dro.glade","linuxcnc/configs/sim/gmoccapy/gmoccapy.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy.txt","linuxcnc/configs/sim/gmoccapy/gmoccapy2.glade","linuxcnc/configs/sim/gmoccapy/gmoccapy_4_axis.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_4_axis.txt","linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZAB.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZAC.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZCW.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_left_panel.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_messages.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_pedant.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/README","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/README_es","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/gmoccapy_plasma.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/gmoccapy_postgui.hal","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/plasma.glade","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/plasma.hal","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/plasma.py","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/signals.glade","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/signals.hal","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/signals.py","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/torch.svg","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/torches.tbl","linuxcnc/configs/sim/gmoccapy/gmoccapy_postgui.hal","linuxcnc/configs/sim/gmoccapy/gmoccapy_pyngcgui.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_pyngcgui.txt","linuxcnc/configs/sim/gmoccapy/gmoccapy_right_panel.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_sim_hardware_button.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_tool_sensor.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_tool_sensor.para","linuxcnc/configs/sim/gmoccapy/gmoccapy_with_user_tabs.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_with_user_tabs.txt","linuxcnc/configs/sim/gmoccapy/h_buttonlist.glade","linuxcnc/configs/sim/gmoccapy/h_buttonlist.hal","linuxcnc/configs/sim/gmoccapy/jogwheel.glade","linuxcnc/configs/sim/gmoccapy/jogwheel.hal","linuxcnc/configs/sim/gmoccapy/lathe.tbl","linuxcnc/configs/sim/gmoccapy/lathe_configs/LatheMacro.svg","linuxcnc/configs/sim/gmoccapy/lathe_configs/README","linuxcnc/configs/sim/gmoccapy/lathe_configs/boring.ngc","linuxcnc/configs/sim/gmoccapy/lathe_configs/chamfer.ngc","linuxcnc/configs/sim/gmoccapy/lathe_configs/core_sim_lathe.hal","linuxcnc/configs/sim/gmoccapy/lathe_configs/core_sim_lathe_C.hal","linuxcnc/configs/sim/gmoccapy/lathe_configs/core_sim_lathe_CW.hal","linuxcnc/configs/sim/gmoccapy/lathe_configs/drilling.ngc","linuxcnc/configs/sim/gmoccapy/lathe_configs/facing.ngc","linuxcnc/configs/sim/gmoccapy/lathe_configs/gmoccapy_lathe.pref","linuxcnc/configs/sim/gmoccapy/lathe_configs/gmoccapy_lathe_c.pref","linuxcnc/configs/sim/gmoccapy/lathe_configs/gmoccapy_postgui.hal","linuxcnc/configs/sim/gmoccapy/lathe_configs/grooving.ngc","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe.ini","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe.pref","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe.tbl","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_C.ini","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_CW.ini","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_backtool.ini","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_c.pref","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_cw.pref","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_imperial.ini","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_imperial.pref","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_macros.ini","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathehandler.py","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathemacro.ui","linuxcnc/configs/sim/gmoccapy/lathe_configs/radius.ngc","linuxcnc/configs/sim/gmoccapy/lathe_configs/savestate.sav","linuxcnc/configs/sim/gmoccapy/lathe_configs/simulated_home_lathe.hal","linuxcnc/configs/sim/gmoccapy/lathe_configs/simulated_home_lathe_CW.hal","linuxcnc/configs/sim/gmoccapy/lathe_configs/spindle_sim.hal","linuxcnc/configs/sim/gmoccapy/lathe_configs/threading.ngc","linuxcnc/configs/sim/gmoccapy/lathe_configs/turning.ngc","linuxcnc/configs/sim/gmoccapy/left.hal","linuxcnc/configs/sim/gmoccapy/left_panel.hal","linuxcnc/configs/sim/gmoccapy/macros/change.ngc","linuxcnc/configs/sim/gmoccapy/macros/go_to_position.ngc","linuxcnc/configs/sim/gmoccapy/macros/halo_world.ngc","linuxcnc/configs/sim/gmoccapy/macros/i_am_lost.ngc","linuxcnc/configs/sim/gmoccapy/macros/images/goto_x_y_z.png","linuxcnc/configs/sim/gmoccapy/macros/images/i_am_lost.png","linuxcnc/configs/sim/gmoccapy/macros/images/macro_8.png","linuxcnc/configs/sim/gmoccapy/macros/increment.ngc","linuxcnc/configs/sim/gmoccapy/macros/jog_around.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_0.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_1.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_10.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_11.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_12.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_13.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_14.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_15.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_2.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_3.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_4.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_5.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_6.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_7.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_8.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_9.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_Instructions.txt","linuxcnc/configs/sim/gmoccapy/macros/on_abort.ngc","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gantry_mm.hal","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gantry_mm.ini","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gmoccapy_GANTRY_sim.pref","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gmoccapy_postgui.hal","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/tool.tbl","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/LinuxCNC-HAL-SIM-SCARA.pref","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/README","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/README_es","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/postgui.hal","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara.glade","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara.ini","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara.tbl","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara_panel.hal","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara_postgui.hal","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara_sim_4.hal","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/spindle_sim.hal","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/README","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/README_es","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzac.ngc","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzbc.ngc","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/impeller-7bl-xyzac.ngc","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/test-xyzac.ngc","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/test-xyzbc.ngc","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/postgui.hal","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/sim-xyzac-trt.pref","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt.ini","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt.tbl","linuxcnc/configs/sim/gmoccapy/pendant.glade","linuxcnc/configs/sim/gmoccapy/pendant.hal","linuxcnc/configs/sim/gmoccapy/plasma_config/README","linuxcnc/configs/sim/gmoccapy/plasma_config/README_es","linuxcnc/configs/sim/gmoccapy/plasma_config/gmoccapy.pref","linuxcnc/configs/sim/gmoccapy/plasma_config/gmoccapy_plasma.ini","linuxcnc/configs/sim/gmoccapy/plasma_config/gmoccapy_postgui.hal","linuxcnc/configs/sim/gmoccapy/plasma_config/plasma.glade","linuxcnc/configs/sim/gmoccapy/plasma_config/plasma.hal","linuxcnc/configs/sim/gmoccapy/plasma_config/plasma.py","linuxcnc/configs/sim/gmoccapy/plasma_config/signals.glade","linuxcnc/configs/sim/gmoccapy/plasma_config/signals.hal","linuxcnc/configs/sim/gmoccapy/plasma_config/signals.py","linuxcnc/configs/sim/gmoccapy/plasma_config/torch.svg","linuxcnc/configs/sim/gmoccapy/plasma_config/torches.tbl","linuxcnc/configs/sim/gmoccapy/pyngcgui.ui","linuxcnc/configs/sim/gmoccapy/python/remap.py","linuxcnc/configs/sim/gmoccapy/python/stdglue.py","linuxcnc/configs/sim/gmoccapy/python/toplevel.py","linuxcnc/configs/sim/gmoccapy/simulated_home.hal","linuxcnc/configs/sim/gmoccapy/simulated_home_lathe.hal","linuxcnc/configs/sim/gmoccapy/spindle_sim.hal","linuxcnc/configs/sim/gmoccapy/tool.tbl","linuxcnc/configs/sim/gmoccapy/tool_sensor.glade","linuxcnc/configs/sim/gmoccapy/tool_sensor.hal","linuxcnc/configs/sim/gmoccapy/tool_sensor.para","linuxcnc/configs/sim/gmoccapy/v_buttonlist.glade","linuxcnc/configs/sim/gmoccapy/v_buttonlist.hal","linuxcnc/configs/sim/gmoccapy/vcp_box.glade","linuxcnc/configs/sim/gmoccapy/vcp_box.hal","linuxcnc/configs/sim/gremlin_view.ui","linuxcnc/configs/sim/gs2.hal","linuxcnc/configs/sim/gscreen/README","linuxcnc/configs/sim/gscreen/README_es","linuxcnc/configs/sim/gscreen/gladevcp-test.ui","linuxcnc/configs/sim/gscreen/gscreen.ini","linuxcnc/configs/sim/gscreen/gscreen_custom/9axis.ini","linuxcnc/configs/sim/gscreen/gscreen_custom/README","linuxcnc/configs/sim/gscreen/gscreen_custom/README_es","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_no_plot.ini","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_postgui.hal","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/arrow_down1.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/arrow_down2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/arrow_left1.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/arrow_left2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/arrow_right1.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/arrow_right2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/arrow_up1.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/arrow_up2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/base.xcf","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/base2.xcf","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/base3.xcf","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/blank.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/button1.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/button2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/button3.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/button4.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/check1.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/check2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/default.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/green_button2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/gtkrc","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/in.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/obutton1.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/obutton2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/option1.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/option2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/radio1.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/radio2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/red_button2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/spin1.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/spin2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/spin3.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/trough.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/up.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/yellow_button2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gscreen_gaxis.ini","linuxcnc/configs/sim/gscreen/gscreen_custom/industrial.ini","linuxcnc/configs/sim/gscreen/gscreen_custom/industrial_postgui.hal","linuxcnc/configs/sim/gscreen/gscreen_custom/sim.tbl","linuxcnc/configs/sim/gscreen/gscreen_custom/tester.ini","linuxcnc/configs/sim/gscreen/gscreen_custom/tester_metric.ini","linuxcnc/configs/sim/gscreen/gscreen_custom/tester_postgui.hal","linuxcnc/configs/sim/gscreen/gscreen_lathe.ini","linuxcnc/configs/sim/gscreen/gscreen_mm.ini","linuxcnc/configs/sim/gscreen/gscreen_theme/gtk-3.0/gtk.css","linuxcnc/configs/sim/gscreen/gscreen_theme/gtk-3.0/gtkrc","linuxcnc/configs/sim/gscreen/industrial_lathe_wear/README","linuxcnc/configs/sim/gscreen/industrial_lathe_wear/README_es","linuxcnc/configs/sim/gscreen/industrial_lathe_wear/industrial_lathe_wear.ini","linuxcnc/configs/sim/gscreen/industrial_lathe_wear/lathe-fanucy.tbl","linuxcnc/configs/sim/gscreen/industrial_lathe_wear/lathe_postgui.hal","linuxcnc/configs/sim/gscreen/industrial_lathe_wear/remap.py","linuxcnc/configs/sim/gscreen/industrial_lathe_wear/toolchange.ngc","linuxcnc/configs/sim/gscreen/industrial_lathe_wear/toplevel.py","linuxcnc/configs/sim/gscreen/lathe.tbl","linuxcnc/configs/sim/gscreen/lathe_postgui.hal","linuxcnc/configs/sim/gscreen/ngcgui/README","linuxcnc/configs/sim/gscreen/ngcgui/README_es","linuxcnc/configs/sim/gscreen/ngcgui/gremlin_view.ui","linuxcnc/configs/sim/gscreen/ngcgui/pyngcgui.ui","linuxcnc/configs/sim/gscreen/ngcgui/pyngcgui_gscreen.ini","linuxcnc/configs/sim/gscreen/ngcgui/pyngcgui_gscreen.txt","linuxcnc/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_es.txt","linuxcnc/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_popupkeyboard.ini","linuxcnc/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_popupkeyboard.txt","linuxcnc/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_popupkeyboard_es.txt","linuxcnc/configs/sim/gscreen/ngcgui/pyngcgui_popupkeyboard.ui","linuxcnc/configs/sim/gscreen/ngcgui/sim.tbl","linuxcnc/configs/sim/gscreen/silverdragon/README","linuxcnc/configs/sim/gscreen/silverdragon/README_es","linuxcnc/configs/sim/gscreen/silverdragon/macros/auto_zref.ngc","linuxcnc/configs/sim/gscreen/silverdragon/macros/laserzero.ngc","linuxcnc/configs/sim/gscreen/silverdragon/macros/tool_sensor.ngc","linuxcnc/configs/sim/gscreen/silverdragon/macros/touch_plate.ngc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon.ini","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/arrow/arrow-down-disable.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/arrow/arrow-down.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/arrow/arrow-left.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/arrow/arrow-right.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/arrow/arrow-up-disable.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/arrow/arrow-up.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/bg.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/button.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/button/button-ins.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/button/button-light.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/button/button-pressed.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/button/button-spin.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/button/button.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/c_box.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/c_box/c_box-pressed.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/c_box/c_box.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/entry.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/entry/entry-active.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/entry/entry.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/gtkrc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/menubar.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/menubar/line-h.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/menubar/line-v.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/menubar/menubar.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/menubar/menuitem.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/notebook.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/notebook/notebook.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/notebook/tab-bottom-active.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/notebook/tab-bottom.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/notebook/tab-left-active.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/notebook/tab-left.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/notebook/tab-right-active.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/notebook/tab-right.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/notebook/tab-top-active.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/notebook/tab-top.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/null.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/progressbar.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/progressbar/progressbar-horiz.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/progressbar/progressbar-vert.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/progressbar/trough-horiz.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/progressbar/trough-tree.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/progressbar/trough-vert.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/radio.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/radio/radio-pressed (copy).png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/radio/radio-pressed.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/radio/radio.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scale.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scale/slider-horiz.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scale/slider-vert.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scale/trough-horiz.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scale/trough-vert.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/arrow_down.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/arrow_down_clicked.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/arrow_left.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/arrow_left_clicked.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/arrow_right.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/arrow_right_clicked.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/arrow_up.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/arrow_up_clicked.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/scrollbar_horizontal.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/scrollbar_vertical.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/thumb.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/trough-h.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/trough-v.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/spin.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/statusbar.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/statusbar/resizer.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/border-bottom.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/border-left.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/border-right.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/bottom-grip-left-corner.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/bottom-grip-right-corner.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/button-bkg-pressed.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/button-bkg-unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/button-bkg.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/button-close-icon.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/button-max-icon.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/button-min-icon.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/button-unmax-icon.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/metacity-theme-1.xml","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/title_center_dimple_gradient.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/title_center_dimple_gradient_unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/title_left_dimple_gradient.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/title_left_dimple_gradient_unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/title_right_dimple_gradient.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/title_right_dimple_gradient_unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/titlebar_center_gradient.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/titlebar_center_gradient_unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/titlebar_left_gradient.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/titlebar_left_gradient_unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/titlebar_right_gradient.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/titlebar_right_gradient_unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/top-grip-left-corner.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/top-grip-right-corner.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/window-chrome-close-unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/window-chrome-maximize-unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/window-chrome-minimize-unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/window-chrome-unmaximize-unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/tool.tbl","linuxcnc/configs/sim/gscreen/sim.tbl","linuxcnc/configs/sim/gscreen/sim_mm.tbl","linuxcnc/configs/sim/gscreen/spartan/README","linuxcnc/configs/sim/gscreen/spartan/README_es","linuxcnc/configs/sim/gscreen/spartan/custom.hal","linuxcnc/configs/sim/gscreen/spartan/custom_postgui.hal","linuxcnc/configs/sim/gscreen/spartan/sim_hardware.hal","linuxcnc/configs/sim/gscreen/spartan/spartan.hal","linuxcnc/configs/sim/gscreen/spartan/spartan.ini","linuxcnc/configs/sim/gscreen/spartan/tool.tbl","linuxcnc/configs/sim/gscreen/vcp_box.glade","linuxcnc/configs/sim/hitcounter.py","linuxcnc/configs/sim/lathe.tbl","linuxcnc/configs/sim/lathe.xml","linuxcnc/configs/sim/lathe_postgui.hal","linuxcnc/configs/sim/manual-example.hal","linuxcnc/configs/sim/manual-example.ui","linuxcnc/configs/sim/nstools.tbl","linuxcnc/configs/sim/pyngcgui.ui","linuxcnc/configs/sim/pyngcgui_popupkeyboard.ui","linuxcnc/configs/sim/pyvcp_demo.hal","linuxcnc/configs/sim/pyvcp_demo.xml","linuxcnc/configs/sim/pyvcp_demo/README","linuxcnc/configs/sim/pyvcp_demo/README_es","linuxcnc/configs/sim/pyvcp_demo/custom.hal","linuxcnc/configs/sim/pyvcp_demo/pyvcp_bottom_panel.hal","linuxcnc/configs/sim/pyvcp_demo/pyvcp_bottom_panel.ini","linuxcnc/configs/sim/pyvcp_demo/pyvcp_bottom_panel.xml","linuxcnc/configs/sim/pyvcp_demo/pyvcp_demo1.ini","linuxcnc/configs/sim/pyvcp_demo/pyvcp_demo1.xml","linuxcnc/configs/sim/pyvcp_demo/pyvcp_embed_tab.hal","linuxcnc/configs/sim/pyvcp_demo/pyvcp_embed_tab.ini","linuxcnc/configs/sim/pyvcp_demo/pyvcp_embed_tab_1.xml","linuxcnc/configs/sim/pyvcp_demo/pyvcp_embed_tab_2.xml","linuxcnc/configs/sim/pyvcp_demo/sim_mm.tbl","linuxcnc/configs/sim/qtaxis/gantry/qt_gantry.ini","linuxcnc/configs/sim/qtaxis/gantry/sim.tbl","linuxcnc/configs/sim/qtaxis/non-trivial/scara/remap_subs/428remap.ngc","linuxcnc/configs/sim/qtaxis/non-trivial/scara/remap_subs/429remap.ngc","linuxcnc/configs/sim/qtaxis/non-trivial/scara/remap_subs/430remap.ngc","linuxcnc/configs/sim/qtaxis/non-trivial/scara/scara.ini","linuxcnc/configs/sim/qtaxis/non-trivial/scara/scara.tbl","linuxcnc/configs/sim/qtaxis/xyz/check_constraints.hal","linuxcnc/configs/sim/qtaxis/xyz/qtaxis.ini","linuxcnc/configs/sim/qtaxis/xyz/qtvcp_postgui.hal","linuxcnc/configs/sim/qtaxis/xyz/sim.tbl","linuxcnc/configs/sim/qtdragon/README","linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/README","linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/on_abort.ngc","linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_postgui.hal","linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyz.ini","linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyzy.ini","linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyzya.ini","linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/silver_dragon.png","linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/tool.tbl","linuxcnc/configs/sim/qtdragon/qtdragon_tool_probe/README","linuxcnc/configs/sim/qtdragon/qtdragon_tool_probe/qtdragon_auto_tool_probe.ini","linuxcnc/configs/sim/qtdragon/qtdragon_tool_probe/qtdragon_postgui.hal","linuxcnc/configs/sim/qtdragon/qtdragon_tool_probe/silver_dragon.png","linuxcnc/configs/sim/qtdragon/qtdragon_tool_probe/tool.tbl","linuxcnc/configs/sim/qtdragon/qtdragon_xyz/README","linuxcnc/configs/sim/qtdragon/qtdragon_xyz/on_abort.ngc","linuxcnc/configs/sim/qtdragon/qtdragon_xyz/qtdragon_inch.ini","linuxcnc/configs/sim/qtdragon/qtdragon_xyz/qtdragon_metric.ini","linuxcnc/configs/sim/qtdragon/qtdragon_xyz/qtdragon_postgui.hal","linuxcnc/configs/sim/qtdragon/qtdragon_xyz/qtdragon_xyza.ini","linuxcnc/configs/sim/qtdragon/qtdragon_xyz/silver_dragon.png","linuxcnc/configs/sim/qtdragon/qtdragon_xyz/tool.tbl","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/.gitignore","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/README","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/core_sim_XYZAB.hal","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/core_sim_XYZAC.hal","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/on_abort.ngc","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_postgui.hal","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyza.ini","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyzab.ini","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyzac.ini","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/silver_dragon.png","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/simulated_home.hal","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/tool.tbl","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/README","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/core_sim_XYZAB.hal","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/core_sim_XYZAC.hal","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/on_abort.ngc","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_postgui.hal","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyz.ini","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyza.ini","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyzab.ini","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyzac.ini","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/silver_dragon.png","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/tool.tbl","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/README","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/on_abort.ngc","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/probe_points.txt","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_postgui.hal","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_z_compensation.ini","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/silver_dragon.png","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/tool.tbl","linuxcnc/configs/sim/qtplasmac/.gitignore","linuxcnc/configs/sim/qtplasmac/LICENSE","linuxcnc/configs/sim/qtplasmac/README","linuxcnc/configs/sim/qtplasmac/custom.hal","linuxcnc/configs/sim/qtplasmac/custom_filter.py","linuxcnc/configs/sim/qtplasmac/custom_postgui.hal","linuxcnc/configs/sim/qtplasmac/imperial_tool.tbl","linuxcnc/configs/sim/qtplasmac/machine.tcl","linuxcnc/configs/sim/qtplasmac/metric_tool.tbl","linuxcnc/configs/sim/qtplasmac/qtplasmac-imperial.prefs","linuxcnc/configs/sim/qtplasmac/qtplasmac-metric.prefs","linuxcnc/configs/sim/qtplasmac/qtplasmac_imperial_ini.inc","linuxcnc/configs/sim/qtplasmac/qtplasmac_l_imperial.ini","linuxcnc/configs/sim/qtplasmac/qtplasmac_l_metric.ini","linuxcnc/configs/sim/qtplasmac/qtplasmac_metric_ini.inc","linuxcnc/configs/sim/qtplasmac/qtplasmac_p_imperial.ini","linuxcnc/configs/sim/qtplasmac/qtplasmac_p_metric.ini","linuxcnc/configs/sim/qtplasmac/qtplasmac_s_imperial.ini","linuxcnc/configs/sim/qtplasmac/qtplasmac_s_metric.ini","linuxcnc/configs/sim/qtplasmac/qtvcp.prefs","linuxcnc/configs/sim/qtplasmac/sim_no_stepgen.tcl","linuxcnc/configs/sim/qtplasmac/sim_postgui.hal","linuxcnc/configs/sim/qtplasmac/sim_stepgen.tcl","linuxcnc/configs/sim/qttouchy/qttouchy.ini","linuxcnc/configs/sim/qttouchy/qttouchy.pref","linuxcnc/configs/sim/qttouchy/qtvcp_postgui.hal","linuxcnc/configs/sim/qttouchy/sim.tbl","linuxcnc/configs/sim/qtvcp_screens/.gitignore","linuxcnc/configs/sim/qtvcp_screens/README","linuxcnc/configs/sim/qtvcp_screens/README_es","linuxcnc/configs/sim/qtvcp_screens/background.png","linuxcnc/configs/sim/qtvcp_screens/blender.ini","linuxcnc/configs/sim/qtvcp_screens/check_constraints.hal","linuxcnc/configs/sim/qtvcp_screens/industrial_lathe_wear/README","linuxcnc/configs/sim/qtvcp_screens/industrial_lathe_wear/README_es","linuxcnc/configs/sim/qtvcp_screens/industrial_lathe_wear/industrial_lathe_wear.ini","linuxcnc/configs/sim/qtvcp_screens/industrial_lathe_wear/lathe-wear.tbl","linuxcnc/configs/sim/qtvcp_screens/industrial_lathe_wear/qtvcp_postgui.hal","linuxcnc/configs/sim/qtvcp_screens/industrial_lathe_wear/remap.py","linuxcnc/configs/sim/qtvcp_screens/industrial_lathe_wear/toolchange.ngc","linuxcnc/configs/sim/qtvcp_screens/industrial_lathe_wear/toplevel.py","linuxcnc/configs/sim/qtvcp_screens/non-trivial/scara/remap_subs/428remap.ngc","linuxcnc/configs/sim/qtvcp_screens/non-trivial/scara/remap_subs/429remap.ngc","linuxcnc/configs/sim/qtvcp_screens/non-trivial/scara/remap_subs/430remap.ngc","linuxcnc/configs/sim/qtvcp_screens/non-trivial/scara/scara.ini","linuxcnc/configs/sim/qtvcp_screens/qt_800x600.ini","linuxcnc/configs/sim/qtvcp_screens/qt_gantry.ini","linuxcnc/configs/sim/qtvcp_screens/qtaxis.ini","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/lathe-wear.tbl","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/axis-16x16.png","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/axis-24x24.png","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/axis-32x32.png","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/axis-48x48.png","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/close.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/downarrow.xbm","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/leftarrow.xbm","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/resume_inhibit.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/rightarrow.xbm","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/spindle_ccw.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/spindle_cw.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/std_error.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/std_info.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/std_warning.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_axis_p.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_axis_x.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_axis_y.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_axis_y2.png","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_axis_z.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_axis_z2.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_blockdelete.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_clear.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_estop.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_open.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_optpause.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_pause.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_power.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_reload.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_rotate.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_run.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_step.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_stop.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_verify.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_zoomin.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_zoomout.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/uparrow.xbm","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/qtaxis.ui","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/qtaxis_handler.py","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis_lathe.ini","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtvcp_postgui.hal","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/remap.py","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/toplevel.py","linuxcnc/configs/sim/qtvcp_screens/qtaxis_mpg.ini","linuxcnc/configs/sim/qtvcp_screens/qtdefault.ini","linuxcnc/configs/sim/qtvcp_screens/qtdefault_9axis.ini","linuxcnc/configs/sim/qtvcp_screens/qtdefault_gantry.ini","linuxcnc/configs/sim/qtvcp_screens/qtdefault_mm.ini","linuxcnc/configs/sim/qtvcp_screens/qtdragon/README","linuxcnc/configs/sim/qtvcp_screens/qtdragon/core_sim.hal","linuxcnc/configs/sim/qtvcp_screens/qtdragon/gantrysim.hal","linuxcnc/configs/sim/qtvcp_screens/qtdragon/on_abort.ngc","linuxcnc/configs/sim/qtvcp_screens/qtdragon/python/qt_auto_probe_tool.ngc","linuxcnc/configs/sim/qtvcp_screens/qtdragon/python/remap.py","linuxcnc/configs/sim/qtvcp_screens/qtdragon/python/stdglue.py","linuxcnc/configs/sim/qtvcp_screens/qtdragon/python/toplevel.py","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon.ini","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_auto_tool_probe.ini","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_hd.ini","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_hd_postgui.hal","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_inch.ini","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_postgui.hal","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_postgui_ya.hal","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyyz.ini","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyz.ini","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyza.ini","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyzy.ini","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyzya.ini","linuxcnc/configs/sim/qtvcp_screens/qtdragon/silver_dragon.png","linuxcnc/configs/sim/qtvcp_screens/qtdragon/tool.tbl","linuxcnc/configs/sim/qtvcp_screens/qtvcp_custom/check_constraints.hal","linuxcnc/configs/sim/qtvcp_screens/qtvcp_custom/pyngcgui.ui","linuxcnc/configs/sim/qtvcp_screens/qtvcp_custom/qtdefault_ngc.ini","linuxcnc/configs/sim/qtvcp_screens/qtvcp_custom/qtdefault_ngc/qtdefault_ngc.ui","linuxcnc/configs/sim/qtvcp_screens/qtvcp_custom/qtdefault_ngc/qtdefault_ngc_handler.py","linuxcnc/configs/sim/qtvcp_screens/qtvcp_custom/qtvcp_postgui.hal","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/LatheMacro.svg","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/check_constraints.hal","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/gremlin.glade","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/gremlin.ini","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/gvcp.glade","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/gvcp_handler.py","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/lathehandler.py","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/lathemacro.ui","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/pyngcgui.ui","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp.ini","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp/qtdefault_gladevcp.ui","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp/qtdefault_gladevcp_handler.py","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp_handler.py","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp_handler_1.py","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_ngc.ini","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_ngc/qtdefault_ngc.ui","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_ngc/qtdefault_ngc_handler.py","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtvcp_postgui.hal","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/savestate.sav","linuxcnc/configs/sim/qtvcp_screens/qtvcp_postgui.hal","linuxcnc/configs/sim/qtvcp_screens/qtx1mill.ini","linuxcnc/configs/sim/qtvcp_screens/sim-9axis.var","linuxcnc/configs/sim/qtvcp_screens/sim_mm.tbl","linuxcnc/configs/sim/qtvcp_screens/tester.ini","linuxcnc/configs/sim/schema-simple.sql","linuxcnc/configs/sim/screwcompX.dat","linuxcnc/configs/sim/sim.tbl","linuxcnc/configs/sim/sim_mm.tbl","linuxcnc/configs/sim/sim_mm_test.tbl","linuxcnc/configs/sim/simpockets.tbl","linuxcnc/configs/sim/test.vcp","linuxcnc/configs/sim/tklinuxcnc/README","linuxcnc/configs/sim/tklinuxcnc/README_es","linuxcnc/configs/sim/tklinuxcnc/ldelta.ini","linuxcnc/configs/sim/tklinuxcnc/screwcompX.dat","linuxcnc/configs/sim/tklinuxcnc/servo_sim.ini","linuxcnc/configs/sim/tklinuxcnc/sim.tbl","linuxcnc/configs/sim/tklinuxcnc/tklinuxcnc.ini","linuxcnc/configs/sim/tklinuxcnc/tripod.ini","linuxcnc/configs/sim/tklinuxcnc/trivkins/README","linuxcnc/configs/sim/tklinuxcnc/trivkins/README_es","linuxcnc/configs/sim/tklinuxcnc/trivkins/xz.ini","linuxcnc/configs/sim/tklinuxcnc/trivkins/xz.tbl","linuxcnc/configs/sim/tklinuxcnc/trivkins/xz_both.ini","linuxcnc/configs/sim/tklinuxcnc/trivkins/xzbase.inc","linuxcnc/configs/sim/touchy/README","linuxcnc/configs/sim/touchy/README_es","linuxcnc/configs/sim/touchy/gladevcp/README","linuxcnc/configs/sim/touchy/gladevcp/README_es","linuxcnc/configs/sim/touchy/gladevcp/gladevcp-touchy.hal","linuxcnc/configs/sim/touchy/gladevcp/gladevcp_touchy.ini","linuxcnc/configs/sim/touchy/gladevcp/hitcounter.py","linuxcnc/configs/sim/touchy/gladevcp/manual-example.hal","linuxcnc/configs/sim/touchy/gladevcp/manual-example.ui","linuxcnc/configs/sim/touchy/gladevcp/simpockets.tbl","linuxcnc/configs/sim/touchy/gladevcp/touchy-gremlin.ui","linuxcnc/configs/sim/touchy/gladevcp/touchy-misc.hal","linuxcnc/configs/sim/touchy/gladevcp/touchy-misc.ui","linuxcnc/configs/sim/touchy/gladevcp/touchy.ini","linuxcnc/configs/sim/touchy/ngcgui/README","linuxcnc/configs/sim/touchy/ngcgui/README_es","linuxcnc/configs/sim/touchy/ngcgui/gremlin_view.ui","linuxcnc/configs/sim/touchy/ngcgui/hwsim.sh","linuxcnc/configs/sim/touchy/ngcgui/lathe.tbl","linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy.ini","linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy.txt","linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy_es.txt","linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy_lathe.ini","linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy_lathe.txt","linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy_lathe_es.txt","linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff.ini","linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff.txt","linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff_es.txt","linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy_popupkeyboard.ui","linuxcnc/configs/sim/touchy/ngcgui/sim.tbl","linuxcnc/configs/sim/touchy/simpockets.tbl","linuxcnc/configs/sim/touchy/touchy.ini","linuxcnc/configs/sim/touchy/touchy.txt","linuxcnc/configs/sim/touchy/touchy_es.txt","linuxcnc/configs/sim/touchy/touchy_postgui.hal","linuxcnc/configs/sim/touchy/touchy_test_panel.glade","linuxcnc/configs/sim/tracking-test.hal","linuxcnc/configs/sim/woodpecker/1280x1024_5axis/woodpecker.ui","linuxcnc/configs/sim/woodpecker/1280x1024_5axis/woodpecker_handler.py","linuxcnc/configs/sim/woodpecker/README.md","linuxcnc/configs/sim/woodpecker/compensate.py","linuxcnc/configs/sim/woodpecker/core_sim.hal","linuxcnc/configs/sim/woodpecker/gantrysim-xyzab.hal","linuxcnc/configs/sim/woodpecker/gantrysim.hal","linuxcnc/configs/sim/woodpecker/help_files/about.html","linuxcnc/configs/sim/woodpecker/help_files/database.html","linuxcnc/configs/sim/woodpecker/help_files/facing_utility.html","linuxcnc/configs/sim/woodpecker/help_files/help.css","linuxcnc/configs/sim/woodpecker/help_files/hole_circle_utility.html","linuxcnc/configs/sim/woodpecker/help_files/images/WoodPecker.png","linuxcnc/configs/sim/woodpecker/help_files/images/lcnc_swoop.png","linuxcnc/configs/sim/woodpecker/help_files/ngcgui.html","linuxcnc/configs/sim/woodpecker/help_files/probing.html","linuxcnc/configs/sim/woodpecker/help_files/runfromline.html","linuxcnc/configs/sim/woodpecker/help_files/spindle_pause.html","linuxcnc/configs/sim/woodpecker/help_files/stylesheets.html","linuxcnc/configs/sim/woodpecker/help_files/template.html","linuxcnc/configs/sim/woodpecker/help_files/using_a_mpg.html","linuxcnc/configs/sim/woodpecker/help_files/using_a_vfd.html","linuxcnc/configs/sim/woodpecker/help_files/z_level_comp.html","linuxcnc/configs/sim/woodpecker/line-number.txt","linuxcnc/configs/sim/woodpecker/mdi_history.dat","linuxcnc/configs/sim/woodpecker/mpg.hal","linuxcnc/configs/sim/woodpecker/numstr.py","linuxcnc/configs/sim/woodpecker/on_abort.ngc","linuxcnc/configs/sim/woodpecker/python/qt_auto_probe_tool.ngc","linuxcnc/configs/sim/woodpecker/python/remap.py","linuxcnc/configs/sim/woodpecker/python/stdglue.py","linuxcnc/configs/sim/woodpecker/python/toplevel.py","linuxcnc/configs/sim/woodpecker/qtvcp/screens/woodpecker/resources.py","linuxcnc/configs/sim/woodpecker/simulated-gantry-home.hal","linuxcnc/configs/sim/woodpecker/simulated-gantry-xyzab-home.hal","linuxcnc/configs/sim/woodpecker/tool.tbl","linuxcnc/configs/sim/woodpecker/tool_icons/ball_end_mill.png","linuxcnc/configs/sim/woodpecker/tool_icons/ballend_straight.png","linuxcnc/configs/sim/woodpecker/tool_icons/center_drill.png","linuxcnc/configs/sim/woodpecker/tool_icons/chamfer-90.png","linuxcnc/configs/sim/woodpecker/tool_icons/drill.png","linuxcnc/configs/sim/woodpecker/tool_icons/endmill.png","linuxcnc/configs/sim/woodpecker/tool_icons/gauge.png","linuxcnc/configs/sim/woodpecker/tool_icons/mill_tools/chamfer-90-1.png","linuxcnc/configs/sim/woodpecker/tool_icons/mill_tools/endmill-1.png","linuxcnc/configs/sim/woodpecker/tool_icons/mill_tools/endmill-2.png","linuxcnc/configs/sim/woodpecker/tool_icons/mill_tools/endmill-3.png","linuxcnc/configs/sim/woodpecker/tool_icons/mill_tools/endmill-4.png","linuxcnc/configs/sim/woodpecker/tool_icons/mill_tools/endmill-5.png","linuxcnc/configs/sim/woodpecker/tool_icons/mill_tools/endmill-6.png","linuxcnc/configs/sim/woodpecker/tool_icons/mill_tools/endmill-7.png","linuxcnc/configs/sim/woodpecker/tool_icons/mill_tools/endmill-8.png","linuxcnc/configs/sim/woodpecker/tool_icons/not_found.png","linuxcnc/configs/sim/woodpecker/tool_icons/probe.png","linuxcnc/configs/sim/woodpecker/tool_icons/spiral_ball_end.png","linuxcnc/configs/sim/woodpecker/tool_icons/spiral_downcut_2F.png","linuxcnc/configs/sim/woodpecker/tool_icons/spiral_upcut.png","linuxcnc/configs/sim/woodpecker/tool_icons/surfacing.png","linuxcnc/configs/sim/woodpecker/tool_icons/tapered_ball_end.png","linuxcnc/configs/sim/woodpecker/tool_icons/tool_icons.txt","linuxcnc/configs/sim/woodpecker/tool_icons/upcut_spiral.png","linuxcnc/configs/sim/woodpecker/tool_icons/vbit-60.png","linuxcnc/configs/sim/woodpecker/tool_icons/vbit-90.png","linuxcnc/configs/sim/woodpecker/tool_icons/vbit-90deg.png","linuxcnc/configs/sim/woodpecker/woodpecker.hal","linuxcnc/configs/sim/woodpecker/woodpecker.ini","linuxcnc/configs/sim/woodpecker/woodpecker.pref","linuxcnc/configs/sim/woodpecker/woodpecker_/images/Left_arrow.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets.html","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/asciidoc.css","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/asciidoc.js","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/blank.html","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/blank_data/inject.css","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/linuxcnc.css","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_actionButton.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_basicProbe.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_calculator.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_fileDialog.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_fileManager.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_focusOverlay.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_gcodeGraphics.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_ledWidget.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_machineLog.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_macro.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_mdiTouchy.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_nurbsEditor.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_offsetpage.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_runFromLine.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_toolChange.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_toolOffset.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_versaProbe.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/statusImageSwitcher.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/Right_arrow.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/a_minus_jog_button.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/a_plus_jog_button.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/atc_spindle_tool.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/brushed_metal.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/checked.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/clear.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/configure-2.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/dimensions.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/exit_application.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/extra_probe_depth.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/fullscreen_preview.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/linuxcnc-wizard.gif","linuxcnc/configs/sim/woodpecker/woodpecker_/images/max_xy_distance.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/max_z_distance.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/rabbit_jog.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/raster_0.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/raster_45.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/raster_90.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/spindle_fwd.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/spindle_pause.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/spindle_rev.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/spindle_stop.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/step_off_width.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/tool_probe.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/turtle_jog.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/unchecked.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/woodpecker.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/woodpecker2.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/x_minus_d.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/x_minus_jog_button.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/x_plus_d.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/x_plus_jog_button.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/xy_clearance.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/y_minus_d.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/y_minus_jog_button.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/y_plus_d.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/y_plus_jog_button.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/z_clearance.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/z_minus_jog_button.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/z_plus_jog_button.png","linuxcnc/configs/sim/woodpecker/woodpecker_/woodpecker.qrc","linuxcnc/configs/sim/woodpecker/woodpecker_/woodpecker.qss","linuxcnc/configs/sim/woodpecker/woodpecker_/woodpecker.ui","linuxcnc/configs/sim/woodpecker/woodpecker_/woodpecker_dark.qss","linuxcnc/configs/sim/woodpecker/woodpecker_/woodpecker_flat.qss","linuxcnc/configs/sim/woodpecker/woodpecker_/woodpecker_handler.py","linuxcnc/configs/sim/woodpecker/woodpecker_auto_tool_probe.ini","linuxcnc/configs/sim/woodpecker/woodpecker_postgui.hal","linuxcnc/configs/sim/woodpecker/woodpecker_postgui_ya.hal","linuxcnc/configs/sim/woodpecker/woodpecker_xyz.ini","linuxcnc/configs/sim/woodpecker/woodpecker_xyza.ini","linuxcnc/configs/sim/woodpecker/woodpecker_xyzab.ini","linuxcnc/configs/sim/woodpecker/woodpecker_xyzy.ini","linuxcnc/configs/sim/woodpecker/woodpecker_xyzya.ini","linuxcnc/configs/sim/woodpecker/zlevel.py","linuxcnc/configs/sim/woodpecker/zlevel.ui","linuxcnc/lib/hallib/README","linuxcnc/lib/hallib/axis_manualtoolchange.hal","linuxcnc/lib/hallib/basic_sim.tcl","linuxcnc/lib/hallib/check_config.tcl","linuxcnc/lib/hallib/check_xyz_constraints.hal","linuxcnc/lib/hallib/core_servo.hal","linuxcnc/lib/hallib/core_sim.hal","linuxcnc/lib/hallib/core_sim9.hal","linuxcnc/lib/hallib/core_stepper.hal","linuxcnc/lib/hallib/gantrysim.hal","linuxcnc/lib/hallib/hal_procs_lib.tcl","linuxcnc/lib/hallib/halcheck.tcl","linuxcnc/lib/hallib/hookup_moveoff.tcl","linuxcnc/lib/hallib/lathe.hal","linuxcnc/lib/hallib/locking_indexer.hal","linuxcnc/lib/hallib/moveoff_external.hal","linuxcnc/lib/hallib/plasmac.tcl","linuxcnc/lib/hallib/qtplasmac_comp.hal","linuxcnc/lib/hallib/servo_sim.hal","linuxcnc/lib/hallib/sim_ldelta.hal","linuxcnc/lib/hallib/sim_lib.tcl","linuxcnc/lib/hallib/sim_rdelta.hal","linuxcnc/lib/hallib/sim_spindle_encoder.hal","linuxcnc/lib/hallib/simulated-gantry-home.hal","linuxcnc/lib/hallib/simulated-xyyz-home.hal","linuxcnc/lib/hallib/simulated_home.hal","linuxcnc/lib/hallib/simulated_limits.hal","linuxcnc/lib/hallib/tripodsim.hal","linuxcnc/lib/hallib/util_lib.tcl","linuxcnc/lib/hallib/var_show.tcl","linuxcnc/lib/hallib/wheeljogpins.tcl","linuxcnc/lib/hallib/xhc-hb04-layout1.cfg","linuxcnc/lib/hallib/xhc-hb04-layout2.cfg","linuxcnc/lib/hallib/xhc-hb04.tcl","linuxcnc/lib/python/.gitignore","linuxcnc/lib/python/bitfile.py","linuxcnc/lib/python/bwidget.py","linuxcnc/lib/python/gladevcp/READ_ME","linuxcnc/lib/python/gladevcp/__init__.py","linuxcnc/lib/python/gladevcp/builtin-panels/versa-probe/versa_probe_screen.glade","linuxcnc/lib/python/gladevcp/builtin-panels/versa-probe/versa_probe_screen.py","linuxcnc/lib/python/gladevcp/builtin-panels/versa-probe/versa_probe_screen2.glade","linuxcnc/lib/python/gladevcp/calculator.glade","linuxcnc/lib/python/gladevcp/calculatorwidget.py","linuxcnc/lib/python/gladevcp/combi_dro.py","linuxcnc/lib/python/gladevcp/core.py","linuxcnc/lib/python/gladevcp/drowidget.py","linuxcnc/lib/python/gladevcp/gladebuilder.py","linuxcnc/lib/python/gladevcp/gladevcp-test.glade","linuxcnc/lib/python/gladevcp/gladevcp-test.hal","linuxcnc/lib/python/gladevcp/gtk_action.py","linuxcnc/lib/python/gladevcp/gtksourceview.xml","linuxcnc/lib/python/gladevcp/hal_actions.py","linuxcnc/lib/python/gladevcp/hal_bar.py","linuxcnc/lib/python/gladevcp/hal_dial.py","linuxcnc/lib/python/gladevcp/hal_filechooser.py","linuxcnc/lib/python/gladevcp/hal_graph.py","linuxcnc/lib/python/gladevcp/hal_gremlin.py","linuxcnc/lib/python/gladevcp/hal_gremlin_plus.py","linuxcnc/lib/python/gladevcp/hal_lightbutton.py","linuxcnc/lib/python/gladevcp/hal_mdihistory.py","linuxcnc/lib/python/gladevcp/hal_meter.py","linuxcnc/lib/python/gladevcp/hal_pyngcgui.py","linuxcnc/lib/python/gladevcp/hal_python.xml","linuxcnc/lib/python/gladevcp/hal_pythonplugin.py","linuxcnc/lib/python/gladevcp/hal_sourceview.py","linuxcnc/lib/python/gladevcp/hal_widgets.py","linuxcnc/lib/python/gladevcp/iconview.py","linuxcnc/lib/python/gladevcp/jogwheel.py","linuxcnc/lib/python/gladevcp/led.py","linuxcnc/lib/python/gladevcp/macro_widget.py","linuxcnc/lib/python/gladevcp/makepins.py","linuxcnc/lib/python/gladevcp/offsetpage.glade","linuxcnc/lib/python/gladevcp/offsetpage_widget.py","linuxcnc/lib/python/gladevcp/offsetwidget.py","linuxcnc/lib/python/gladevcp/overridewidget.py","linuxcnc/lib/python/gladevcp/persistence.py","linuxcnc/lib/python/gladevcp/pi.png","linuxcnc/lib/python/gladevcp/speedcontrol.py","linuxcnc/lib/python/gladevcp/state_label.py","linuxcnc/lib/python/gladevcp/status_label.py","linuxcnc/lib/python/gladevcp/tooledit_gtk.glade","linuxcnc/lib/python/gladevcp/tooledit_widget.py","linuxcnc/lib/python/gladevcp/widget-gladevcp-calc.png","linuxcnc/lib/python/gladevcp/xembed.py","linuxcnc/lib/python/gladevcp_makepins.py","linuxcnc/lib/python/glnav.py","linuxcnc/lib/python/gremlin_view.py","linuxcnc/lib/python/hal.py","linuxcnc/lib/python/hal_glib.py","linuxcnc/lib/python/hershey.py","linuxcnc/lib/python/linux_event.py","linuxcnc/lib/python/linuxcnc_util.py","linuxcnc/lib/python/multifilebuilder.py","linuxcnc/lib/python/nf.py.in","linuxcnc/lib/python/plasmac/block.py","linuxcnc/lib/python/plasmac/bolt_circle.py","linuxcnc/lib/python/plasmac/circle.py","linuxcnc/lib/python/plasmac/ellipse.py","linuxcnc/lib/python/plasmac/gusset.py","linuxcnc/lib/python/plasmac/line.py","linuxcnc/lib/python/plasmac/polygon.py","linuxcnc/lib/python/plasmac/rectangle.py","linuxcnc/lib/python/plasmac/run_from_line.py","linuxcnc/lib/python/plasmac/sector.py","linuxcnc/lib/python/plasmac/slot.py","linuxcnc/lib/python/plasmac/star.py","linuxcnc/lib/python/plasmac/triangle.py","linuxcnc/lib/python/popupkeyboard.py","linuxcnc/lib/python/propertywindow.py","linuxcnc/lib/python/pyhal.py","linuxcnc/lib/python/pyngcgui.py","linuxcnc/lib/python/pyvcp_widgets.py","linuxcnc/lib/python/qtvcp/README.txt","linuxcnc/lib/python/qtvcp/__init__.py","linuxcnc/lib/python/qtvcp/core.py","linuxcnc/lib/python/qtvcp/designer/README.txt","linuxcnc/lib/python/qtvcp/designer/install_script","linuxcnc/lib/python/qtvcp/lib/__init__.py","linuxcnc/lib/python/qtvcp/lib/audio_player.py","linuxcnc/lib/python/qtvcp/lib/auto_height/auto_height.py","linuxcnc/lib/python/qtvcp/lib/auto_height/auto_height.txt","linuxcnc/lib/python/qtvcp/lib/auto_height/auto_height.ui","linuxcnc/lib/python/qtvcp/lib/auto_height/images/auto_height.png","linuxcnc/lib/python/qtvcp/lib/aux_program_loader.py","linuxcnc/lib/python/qtvcp/lib/colored_formatter.py","linuxcnc/lib/python/qtvcp/lib/gcode_utility/__init__.py","linuxcnc/lib/python/qtvcp/lib/gcode_utility/facing.py","linuxcnc/lib/python/qtvcp/lib/gcode_utility/facing.ui","linuxcnc/lib/python/qtvcp/lib/gcode_utility/facing_help.txt","linuxcnc/lib/python/qtvcp/lib/gcode_utility/hole_circle.py","linuxcnc/lib/python/qtvcp/lib/gcode_utility/hole_circle.ui","linuxcnc/lib/python/qtvcp/lib/gcode_utility/hole_circle_help.txt","linuxcnc/lib/python/qtvcp/lib/gcode_utility/hole_enlarge.py","linuxcnc/lib/python/qtvcp/lib/gcode_utility/hole_enlarge.ui","linuxcnc/lib/python/qtvcp/lib/gcode_utility/hole_enlarge_help.html","linuxcnc/lib/python/qtvcp/lib/gcodes.py","linuxcnc/lib/python/qtvcp/lib/keybindings.py","linuxcnc/lib/python/qtvcp/lib/machine_log.py","linuxcnc/lib/python/qtvcp/lib/mdi_text.py","linuxcnc/lib/python/qtvcp/lib/message.py","linuxcnc/lib/python/qtvcp/lib/notify.py","linuxcnc/lib/python/qtvcp/lib/preferences.py","linuxcnc/lib/python/qtvcp/lib/qt_ngcgui/images/silver_dragon.png","linuxcnc/lib/python/qtvcp/lib/qt_ngcgui/ngcgui.py","linuxcnc/lib/python/qtvcp/lib/qt_ngcgui/ngcgui.ui","linuxcnc/lib/python/qtvcp/lib/qt_pdf/PDFViewer.py","linuxcnc/lib/python/qtvcp/lib/qt_pdf/setup_tab.pdf","linuxcnc/lib/python/qtvcp/lib/qt_vismach/README.txt","linuxcnc/lib/python/qtvcp/lib/qt_vismach/__init__.py","linuxcnc/lib/python/qtvcp/lib/qt_vismach/fanuc_200f.py","linuxcnc/lib/python/qtvcp/lib/qt_vismach/fanuc_200f_obj/r08_base.obj","linuxcnc/lib/python/qtvcp/lib/qt_vismach/fanuc_200f_obj/r08_j1.obj","linuxcnc/lib/python/qtvcp/lib/qt_vismach/fanuc_200f_obj/r08_j2.obj","linuxcnc/lib/python/qtvcp/lib/qt_vismach/fanuc_200f_obj/r08_j3.obj","linuxcnc/lib/python/qtvcp/lib/qt_vismach/fanuc_200f_obj/r08_j4.obj","linuxcnc/lib/python/qtvcp/lib/qt_vismach/fanuc_200f_obj/r08_j5.obj","linuxcnc/lib/python/qtvcp/lib/qt_vismach/fanuc_200f_obj/r08_j6.obj","linuxcnc/lib/python/qtvcp/lib/qt_vismach/gantry_5axis.py","linuxcnc/lib/python/qtvcp/lib/qt_vismach/mill_xyz.py","linuxcnc/lib/python/qtvcp/lib/qt_vismach/millturn.py","linuxcnc/lib/python/qtvcp/lib/qt_vismach/primitives.py","linuxcnc/lib/python/qtvcp/lib/qt_vismach/qt_vismach.py","linuxcnc/lib/python/qtvcp/lib/qt_vismach/scara.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/__init__.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_block.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_bolt.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_circle.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_ellipse.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_gusset.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_line.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_polygon.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_rectangle.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_sector.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_settings.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_slot.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_star.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_triangle.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conversational.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/set_offsets.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/tooltips.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/updater.py","linuxcnc/lib/python/qtvcp/lib/ripper/gcode_ripper.py","linuxcnc/lib/python/qtvcp/lib/sys_notify.py","linuxcnc/lib/python/qtvcp/lib/toolbar_actions.py","linuxcnc/lib/python/qtvcp/lib/touchoff_subprogram.py","linuxcnc/lib/python/qtvcp/lib/virtual_keyboard.py","linuxcnc/lib/python/qtvcp/lib/writer/__init__.py","linuxcnc/lib/python/qtvcp/lib/writer/ext/__init__.py","linuxcnc/lib/python/qtvcp/lib/writer/ext/datetime.py","linuxcnc/lib/python/qtvcp/lib/writer/ext/find.py","linuxcnc/lib/python/qtvcp/lib/writer/ext/table.py","linuxcnc/lib/python/qtvcp/lib/writer/ext/wordcount.py","linuxcnc/lib/python/qtvcp/lib/writer/writer.py","linuxcnc/lib/python/qtvcp/lib/xembed.py","linuxcnc/lib/python/qtvcp/logger.py","linuxcnc/lib/python/qtvcp/plugins/__init__.py","linuxcnc/lib/python/qtvcp/plugins/actionbutton_plugin.py","linuxcnc/lib/python/qtvcp/plugins/bar_plugin.py","linuxcnc/lib/python/qtvcp/plugins/basic_probe_plugin.py","linuxcnc/lib/python/qtvcp/plugins/camview_plugin.py","linuxcnc/lib/python/qtvcp/plugins/container_plugin.py","linuxcnc/lib/python/qtvcp/plugins/detach_tabs_plugin.py","linuxcnc/lib/python/qtvcp/plugins/dialog_plugin.py","linuxcnc/lib/python/qtvcp/plugins/graphics_plugin.py","linuxcnc/lib/python/qtvcp/plugins/hal_label_plugin.py","linuxcnc/lib/python/qtvcp/plugins/jogincrements_plugin.py","linuxcnc/lib/python/qtvcp/plugins/joypad_plugin.py","linuxcnc/lib/python/qtvcp/plugins/led_plugin.py","linuxcnc/lib/python/qtvcp/plugins/nurbs_editor_plugin.py","linuxcnc/lib/python/qtvcp/plugins/overlay_plugin.py","linuxcnc/lib/python/qtvcp/plugins/qtvcp_plugin.py","linuxcnc/lib/python/qtvcp/plugins/round_gauge_plugin.py","linuxcnc/lib/python/qtvcp/plugins/round_progress_bar_plugin.py","linuxcnc/lib/python/qtvcp/plugins/screenoptions_plugin.py","linuxcnc/lib/python/qtvcp/plugins/simplewidgets_plugin.py","linuxcnc/lib/python/qtvcp/plugins/state_label_plugin.py","linuxcnc/lib/python/qtvcp/plugins/state_led_plugin.py","linuxcnc/lib/python/qtvcp/plugins/status_adjustment_bar_plugin.py","linuxcnc/lib/python/qtvcp/plugins/status_label_plugin.py","linuxcnc/lib/python/qtvcp/plugins/status_slider_plugin.py","linuxcnc/lib/python/qtvcp/plugins/tab_widget_plugin.py","linuxcnc/lib/python/qtvcp/plugins/toolbutton_plugin.py","linuxcnc/lib/python/qtvcp/plugins/versa_probe_plugin.py","linuxcnc/lib/python/qtvcp/plugins/virtualkeyboard_plugin.py","linuxcnc/lib/python/qtvcp/plugins/web_widget_plugin.py","linuxcnc/lib/python/qtvcp/plugins/widgets_plugin.py","linuxcnc/lib/python/qtvcp/qt_action.py","linuxcnc/lib/python/qtvcp/qt_istat.py","linuxcnc/lib/python/qtvcp/qt_makegui.py","linuxcnc/lib/python/qtvcp/qt_makepins.py","linuxcnc/lib/python/qtvcp/qt_pstat.py","linuxcnc/lib/python/qtvcp/qt_tstat.py","linuxcnc/lib/python/qtvcp/qtvcp_handler.py","linuxcnc/lib/python/qtvcp/test1.ui","linuxcnc/lib/python/qtvcp/widgets/__init__.py","linuxcnc/lib/python/qtvcp/widgets/action_button.py","linuxcnc/lib/python/qtvcp/widgets/action_button_round.py","linuxcnc/lib/python/qtvcp/widgets/action_tool_button.py","linuxcnc/lib/python/qtvcp/widgets/adjustment_bar.py","linuxcnc/lib/python/qtvcp/widgets/axis_tool_button.py","linuxcnc/lib/python/qtvcp/widgets/bar.py","linuxcnc/lib/python/qtvcp/widgets/basic_probe.py","linuxcnc/lib/python/qtvcp/widgets/calculator.py","linuxcnc/lib/python/qtvcp/widgets/camview_widget.py","linuxcnc/lib/python/qtvcp/widgets/container_widgets.py","linuxcnc/lib/python/qtvcp/widgets/detach_tabs.py","linuxcnc/lib/python/qtvcp/widgets/dialogMixin.py","linuxcnc/lib/python/qtvcp/widgets/dialog_widget.py","linuxcnc/lib/python/qtvcp/widgets/dro_widget.py","linuxcnc/lib/python/qtvcp/widgets/entry_widget.py","linuxcnc/lib/python/qtvcp/widgets/fake_status.py","linuxcnc/lib/python/qtvcp/widgets/file_manager.py","linuxcnc/lib/python/qtvcp/widgets/gcode_editor.py","linuxcnc/lib/python/qtvcp/widgets/gcode_graphics.py","linuxcnc/lib/python/qtvcp/widgets/geditor.py","linuxcnc/lib/python/qtvcp/widgets/general_hal_input.py","linuxcnc/lib/python/qtvcp/widgets/general_hal_output.py","linuxcnc/lib/python/qtvcp/widgets/hal_label.py","linuxcnc/lib/python/qtvcp/widgets/hal_selectionbox.py","linuxcnc/lib/python/qtvcp/widgets/image_switcher.py","linuxcnc/lib/python/qtvcp/widgets/jog_increments.py","linuxcnc/lib/python/qtvcp/widgets/joypad.py","linuxcnc/lib/python/qtvcp/widgets/led_widget.py","linuxcnc/lib/python/qtvcp/widgets/machine_log.py","linuxcnc/lib/python/qtvcp/widgets/macro_widget.py","linuxcnc/lib/python/qtvcp/widgets/mdi_history.py","linuxcnc/lib/python/qtvcp/widgets/mdi_line.py","linuxcnc/lib/python/qtvcp/widgets/mdi_touchy.py","linuxcnc/lib/python/qtvcp/widgets/nurbs_editor.py","linuxcnc/lib/python/qtvcp/widgets/offset_tool_button.py","linuxcnc/lib/python/qtvcp/widgets/origin_offsetview.py","linuxcnc/lib/python/qtvcp/widgets/overlay_widget.py","linuxcnc/lib/python/qtvcp/widgets/probe_routines.py","linuxcnc/lib/python/qtvcp/widgets/probe_subprog.py","linuxcnc/lib/python/qtvcp/widgets/qtvcp_icons.py","linuxcnc/lib/python/qtvcp/widgets/radio_axis_selector.py","linuxcnc/lib/python/qtvcp/widgets/richtext_selector.py","linuxcnc/lib/python/qtvcp/widgets/round_gauge.py","linuxcnc/lib/python/qtvcp/widgets/round_progress.py","linuxcnc/lib/python/qtvcp/widgets/runFromLine_dialog.py","linuxcnc/lib/python/qtvcp/widgets/screen_options.py","linuxcnc/lib/python/qtvcp/widgets/simple_widgets.py","linuxcnc/lib/python/qtvcp/widgets/state_label.py","linuxcnc/lib/python/qtvcp/widgets/state_led.py","linuxcnc/lib/python/qtvcp/widgets/status_label.py","linuxcnc/lib/python/qtvcp/widgets/status_slider.py","linuxcnc/lib/python/qtvcp/widgets/status_stacked.py","linuxcnc/lib/python/qtvcp/widgets/stylesheeteditor.py","linuxcnc/lib/python/qtvcp/widgets/system_tool_button.py","linuxcnc/lib/python/qtvcp/widgets/tab_widget.py","linuxcnc/lib/python/qtvcp/widgets/tool_offsetview.py","linuxcnc/lib/python/qtvcp/widgets/touchEntry.py","linuxcnc/lib/python/qtvcp/widgets/versa_probe.py","linuxcnc/lib/python/qtvcp/widgets/virtualkeyboard.py","linuxcnc/lib/python/qtvcp/widgets/web_widget.py","linuxcnc/lib/python/qtvcp/widgets/widget_baseclass.py","linuxcnc/lib/python/qtvcp/widgets/widget_icons/actionbutton.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/axistoolbutton.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/basicprobe.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/calculator.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/checkbox.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/dial.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/dialogbuttonbox.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/doublescale.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/dro_label.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/filemanager.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/focusoverlay.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/gauge.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/gcodeeditor.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/gcodegraphics.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/generalhalinput.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/generalhaloutput.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/hallabel.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/jogincrements.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/lcdnumber.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/lcnc_led.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/led.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/linuxcnc-wizard.gif","linuxcnc/lib/python/qtvcp/widgets/widget_icons/mdihistory.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/mdiline.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/originoffsetview.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/progress.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/pushbutton.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/radioaxisselector.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/radiobutton.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/screenoptions.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/slider.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/statusadjustmentbar.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/statuslabel.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/statusslider.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/systemtoolbutton.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/tabwidget.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/textedit.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/tooloffsetview.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/versaprobe.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/widgetswitcher.png","linuxcnc/lib/python/qtvcp/widgets/widget_switcher.py","linuxcnc/lib/python/qtvcp/widgets/xembed.py","linuxcnc/lib/python/raster.py","linuxcnc/lib/python/rs274/OpenGLTk.py","linuxcnc/lib/python/rs274/__init__.py","linuxcnc/lib/python/rs274/author.py","linuxcnc/lib/python/rs274/glcanon.py","linuxcnc/lib/python/rs274/interpret.py","linuxcnc/lib/python/rs274/options.py","linuxcnc/lib/python/tooldb.py","linuxcnc/lib/python/vcpparse.py","linuxcnc/lib/python/vismach.py","linuxcnc/linuxcnc.gif"]); +export const SIM_CASE_CATALOG = Object.freeze([{"path":"linuxcnc/configs/sim/axis/anglejog/anglejog.ini","label":"LATHE-Anglejog","category":"axis/anglejog","display":"axis","coordinates":"X Z","kinematics":"trivkins coordinates=xz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"2a8c89afad09a946eddae548b3bfdc3aa4c1f385e785e24a6a50db722215d035"},{"path":"linuxcnc/configs/sim/axis/axis.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"axis","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":8,"unresolved_count":0,"source_sha256":"a41915c4d0d48f46dd595d5d269e2fc73962f7d19897b220368dbc0e4dc96594"},{"path":"linuxcnc/configs/sim/axis/axis_9axis.ini","label":"LinuxCNC-sim-9axis","category":"axis","display":"axis","coordinates":"X Y Z A B C U V W","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"6e3b7b49ed0ed5d840ff8052c05d9c50dad4baba7c9b0bef43a774056388b403"},{"path":"linuxcnc/configs/sim/axis/axis_mm.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"axis","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":7,"unresolved_count":0,"source_sha256":"233aca0e517d0e6d70fa21da86734f6db80d4bee3761b28af92981bda1450749"},{"path":"linuxcnc/configs/sim/axis/canterp.ini","label":"Canterp Example","category":"axis","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"6d7fa7ff7b5586731297f3c1da653c9266da87cd54a7351f361a9fd9ba1fee36"},{"path":"linuxcnc/configs/sim/axis/classicladder/demo_sim_cl.ini","label":"LinuxCNC-DEMO-SIM-CL","category":"axis/classicladder","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"db8d3ac20cfb5cbdb3cc2c888cbadcbdc296b1e0dc171afabcdc167d2442581c"},{"path":"linuxcnc/configs/sim/axis/corexy/corexy_by_hal.ini","label":"corexy_by_hal","category":"axis/corexy","display":null,"coordinates":null,"kinematics":"trivkins coordinates=XYZ kinstype=b","family":"cartesian","status":"ready","startup_preflight":"static_ready","resource_status":"ready","missing_count":0,"unresolved_count":0,"source_sha256":"e838da30ce5fba2d049487d48bd2aeff46b1390a5a448f31980d9ce06121740f"},{"path":"linuxcnc/configs/sim/axis/corexy/corexy_by_kins.ini","label":"corexy_by_kins","category":"axis/corexy","display":null,"coordinates":null,"kinematics":"corexykins","family":"coupled_linear","status":"ready","startup_preflight":"static_ready","resource_status":"ready","missing_count":0,"unresolved_count":0,"source_sha256":"b6682cc5186944a44c2aa78501c4f350e56b4da1151348fa9fc3ece5f0eeea3a"},{"path":"linuxcnc/configs/sim/axis/db_demo/db_nonran.ini","label":"db_nonran NONRANDOM toolchanger","category":"axis/db_demo","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"5da7358586f1d94de2564011d161817b694105f81d076fba6b922e1fab8a42fb"},{"path":"linuxcnc/configs/sim/axis/db_demo/db_ran.ini","label":"db_ran RANDOM toolchanger","category":"axis/db_demo","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"d53daf2cd1bb1fb43538c4ba5194fe72b660c9fd3f3812e54429c84b9005468e"},{"path":"linuxcnc/configs/sim/axis/external_offsets/dynamic_offsets.ini","label":"Dynamic External Offsets","category":"axis/external_offsets","display":"axis","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"4889a5b4227148c706ec527dda91ae4229161f23d942f62aec122492ee8138c7"},{"path":"linuxcnc/configs/sim/axis/external_offsets/eoffsets.ini","label":"External Offsets Demo","category":"axis/external_offsets","display":"axis","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"d6002e2682da417caf66fcae6d6bee9df4c44f1f3355ef70a7f759ed57ad74f7"},{"path":"linuxcnc/configs/sim/axis/external_offsets/jwp_z.ini","label":"Jog-While-Pause Z Demo","category":"axis/external_offsets","display":"axis","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"0e48f593dc6412e59d41844b58f2b3e1ff1e1c3659d38d64f06e4bb893a0f5e5"},{"path":"linuxcnc/configs/sim/axis/external_offsets/opa.ini","label":"External Offset(X) per Angle(C) Demo","category":"axis/external_offsets","display":"axis","coordinates":"XZC","kinematics":"trivkins coordinates=XZC","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"b965264ad6d7a50a5332f8dd2f29928598fce155ec7954511cbdce549b9ff002"},{"path":"linuxcnc/configs/sim/axis/extrajoints/12extrajoints.ini","label":"12extrajoints","category":"axis/extrajoints","display":"axis","coordinates":"XYYZ","kinematics":"trivkins coordinates=XYYZ kinstype=both","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"7b869a94e99c728403cb5fd38b949a1a95ab93a793e3d2b803dd85902595a0af"},{"path":"linuxcnc/configs/sim/axis/extrajoints/1extrajoint.ini","label":"1extrajoint","category":"axis/extrajoints","display":"axis","coordinates":"XYYZ","kinematics":"trivkins coordinates=XYYZ kinstype=both","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"2c3bec6dcab552b34c84e1cfba25270afe1720f7a2ebf34a9d76cba800d0d538"},{"path":"linuxcnc/configs/sim/axis/extrajoints/2extrajoints.ini","label":"2extrajoints","category":"axis/extrajoints","display":"axis","coordinates":"XYYZ","kinematics":"trivkins coordinates=XYYZ kinstype=both","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"cc254899d06dcd870a978cf22ec832b7b6c6603022749a1602e81a8d92afa950"},{"path":"linuxcnc/configs/sim/axis/foam/axis_foam.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"axis/foam","display":"axis","coordinates":"X Y U V","kinematics":"trivkins coordinates=xyuv","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"a176d322e607957f554a954e2cf5e4241ff4ef1181b609990044dcc3432ff958"},{"path":"linuxcnc/configs/sim/axis/gantry/gantry.ini","label":"LinuxCNC-GANTRY-SIM-AXIS","category":"axis/gantry","display":"axis","coordinates":"XYZY","kinematics":"trivkins coordinates=XYZY kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":8,"unresolved_count":0,"source_sha256":"acc7db8d6a38a64598ef277dfea3480f0e7400d461784a0fa0139bded93d5a68"},{"path":"linuxcnc/configs/sim/axis/gantry/gantry_jjog.ini","label":"gantry_jjog-sim","category":"axis/gantry","display":"axis","coordinates":"XYZY","kinematics":"trivkins coordinates=XYZY kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":9,"unresolved_count":0,"source_sha256":"da911359e075e5dbf9f129bafc389e059aa0f754bb4c0ce67b410ac63e5f91ab"},{"path":"linuxcnc/configs/sim/axis/gantry/gantry_mm.ini","label":"EMC-HAL-SIM-GANTRY","category":"axis/gantry","display":"axis","coordinates":"X Y Y Z","kinematics":"trivkins coordinates=xyyz kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"0692df9758234ff4cb29b22ee58688fe2bf450d93cc386ae096e0a943ef475e3"},{"path":"linuxcnc/configs/sim/axis/geometry/xyzc.ini","label":"xyzc (offset rotations)","category":"axis/geometry","display":"axis","coordinates":"X Y Z C","kinematics":"trivkins coordinates=XYZC kinstype=both","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"cafbb5d4c275be232cadb1c4b11d84b2791e8c5544c20f84a7eed3b5ed8bab1e"},{"path":"linuxcnc/configs/sim/axis/geometry/xyzc_origin.ini","label":"xyzc_origin (rotations wrt machine origin)","category":"axis/geometry","display":"axis","coordinates":"X Y Z C","kinematics":"trivkins coordinates=XYZC kinstype=both","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"77aba40722c7a481aad66e3bf05b3fe283965b01d6444c1abc78841c6154363a"},{"path":"linuxcnc/configs/sim/axis/gladevcp/gladevcp_panel.ini","label":"LinuxCNC-PANEL-GLADEVCP","category":"axis/gladevcp","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"c216752c2f032d47fe3910f6b66ac6375c8cb1201b6393b2f01b9c978f0708e6"},{"path":"linuxcnc/configs/sim/axis/gladevcp/gladevcp_panel_tester.ini","label":"LinuxCNC-PANEL-GLADEVCP","category":"axis/gladevcp","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"e8e88a97002d008d234d664d6f14e866b39c89fc09d2d392fffb80367cb6ed68"},{"path":"linuxcnc/configs/sim/axis/gladevcp/gladevcp_tab.ini","label":"LinuxCNC-TAB-GLADEVCP","category":"axis/gladevcp","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"bdbad54582ad4f4cb304bf5c33ea3d45dc7b88a21445cc12737d5fc245624890"},{"path":"linuxcnc/configs/sim/axis/gladevcp/probe.ini","label":"gladevcp_probe","category":"axis/gladevcp","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"66b8ba2d3c6c21409a6686923540058c85fcd5632ffb9827315a5b0f518c5ec9"},{"path":"linuxcnc/configs/sim/axis/gladevcp/set-param-from-ini.ini","label":"set-param-from-ini","category":"axis/gladevcp","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"651f25fd7656f739c2ae57f033183ba82fecb07b29c0b8b908608ce4d21ab6f5"},{"path":"linuxcnc/configs/sim/axis/halui_pyvcp/halui.ini","label":"LinuxCNC-HALUI-PYVCP","category":"axis/halui_pyvcp","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"b74f150915d006fe9ecd14ea0bcb231b7e04d1d44649020de7e0324f1782d3f5"},{"path":"linuxcnc/configs/sim/axis/histogram_demo.ini","label":"ini_hal_demo","category":"axis","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"3eabc315db8e9e21951438ebd95fc5f30cf9b0d5ecb5277e66138f3ccdbdc7f8"},{"path":"linuxcnc/configs/sim/axis/historical_lathe.ini","label":"Historical-LATHE","category":"axis","display":"axis","coordinates":"X Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":6,"unresolved_count":0,"source_sha256":"62809856093198b7a584553d71633a5b40210a059223277d2d3e640563e2de68"},{"path":"linuxcnc/configs/sim/axis/ini_hal_demo.ini","label":"ini_hal_demo","category":"axis","display":"axis","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz kinstype=both","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"9abb6d63c35d14d440366d822283521c9169a89fc36d4685c4597fa77fab2879"},{"path":"linuxcnc/configs/sim/axis/ini_with_includes/includes_demo.ini","label":"includes demo","category":"axis/ini_with_includes","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"64e0ecbb9fa8d17c54e71c1d59ada6cb79f61f1565f62d57cd2bece9c7237704"},{"path":"linuxcnc/configs/sim/axis/iocontrolv2/axis-iocontrolv2-demo.ini","label":"axis-iocontrolv2-demo","category":"axis/iocontrolv2","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"9e23e1329c3dcd721f6b65f001b77dbd90e88d19b374545c250c49a88442deff"},{"path":"linuxcnc/configs/sim/axis/iocontrolv2/g8812.ini","label":"g8812","category":"axis/iocontrolv2","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"334ca534c3eafac4022c5895431515f8f05bbd2a1f150ae09e53b88938b2fd1a"},{"path":"linuxcnc/configs/sim/axis/iocontrolv2/m66track.ini","label":"m66track","category":"axis/iocontrolv2","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"c91c56594fb99934a677786e7f8b6b90299cb29f4d8b3be3e85fe9a957579a69"},{"path":"linuxcnc/configs/sim/axis/iocontrolv2/owordm6-ui-ns.ini","label":"owordm6-ui-ns","category":"axis/iocontrolv2","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"1b4cdcba969b9494cc5137d602a9a9c216d158f89e3279cff6a41a035b0f9961"},{"path":"linuxcnc/configs/sim/axis/iocontrolv2/owordm6-ui.ini","label":"owordm6-ui","category":"axis/iocontrolv2","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"b8de1b4257ef8b8eded585e02e36e3ee6caedad53b3f18f45f94bc9cc0b12b2b"},{"path":"linuxcnc/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyyzb.ini","label":"XYYZB trivkins coordinates=xyyzb KINEMATICS_BOTH","category":"axis/ja_tests/xyzb_locking_indexer","display":"axis","coordinates":"X Y Y Z B","kinematics":"trivkins coordinates=xyyzb kinstype=both","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":6,"unresolved_count":0,"source_sha256":"466833eb371da18428abeac86d759fe36ed5bff73b60a51c10e5303e39c86316"},{"path":"linuxcnc/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyzb.ini","label":"XYZB trivkins coordinates=xyzb","category":"axis/ja_tests/xyzb_locking_indexer","display":"axis","coordinates":"X Y Z B","kinematics":"trivkins coordinates=xyzb","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"796eacff0e56b2a65d9367836f8c9a17c7f967ae467bc1077503c18f57d362db"},{"path":"linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/xyzx-xhc-hb04.ini","label":"xyzx-xhc-hb04","category":"axis/ja_tests/xyzx_mpg","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"565d8d65dda4aa26a14c7ae641a81d7c5a0bc311ab308e63bdbebcf910aacdb9"},{"path":"linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/xyzx.ini","label":"xyzx","category":"axis/ja_tests/xyzx_mpg","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"6888dfaee112f61d521e0f3cc3af5603863303e24e8e60c80a76b04f88127087"},{"path":"linuxcnc/configs/sim/axis/ja_tests/xz/xz.ini","label":"trivkins XZ KINEMATICS_IDENTITY","category":"axis/ja_tests/xz","display":null,"coordinates":null,"kinematics":"trivkins coordinates=xz","family":"cartesian","status":"ready","startup_preflight":"static_ready","resource_status":"ready","missing_count":0,"unresolved_count":0,"source_sha256":"07f5257557a540b02781de3a641dd1830a78a4cbb15a9cc68ad8d2c6eae8ec81"},{"path":"linuxcnc/configs/sim/axis/ja_tests/xz/xz_both.ini","label":"trivkins XZ KINEMATICS_BOTH","category":"axis/ja_tests/xz","display":null,"coordinates":null,"kinematics":"trivkins coordinates=xz kinstype=BOTH","family":"cartesian","status":"ready","startup_preflight":"static_ready","resource_status":"ready","missing_count":0,"unresolved_count":0,"source_sha256":"d75c9e05e2a781d1344b3840ba82adc6d7d8d47f53aa11b04c3b918d20c5faae"},{"path":"linuxcnc/configs/sim/axis/ja_tests/xz/xz_both_auto.ini","label":"trivkins XZ KINEMATICS_BOTH,AUTO TELEOP","category":"axis/ja_tests/xz","display":null,"coordinates":null,"kinematics":"trivkins coordinates=xz kinstype=BOTH","family":"cartesian","status":"ready","startup_preflight":"static_ready","resource_status":"ready","missing_count":0,"unresolved_count":0,"source_sha256":"d94eae8d51a00027f75ff45b84f14e2721de466c4be1af3a5e15d7beeec58ac3"},{"path":"linuxcnc/configs/sim/axis/laser/laser.ini","label":"laser","category":"axis/laser","display":"axis","coordinates":"XYZ","kinematics":"corexykins","family":"coupled_linear","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"343fcbd64cde1f191b3f9835b56bc8ad4ee244cf1eca824b7c7ec07305a260bd"},{"path":"linuxcnc/configs/sim/axis/lathe-fanucy/lathe-fanucy.ini","label":"lathe-fanucy","category":"axis/lathe-fanucy","display":"axis","coordinates":"X Z","kinematics":"trivkins coordinates=xz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"be3724c6093b9d507e40d41ef1f5047c3244e8a95acba3aaa72176e15752675c"},{"path":"linuxcnc/configs/sim/axis/lathe.ini","label":"LinuxCNC-HAL-SIM-LATHE","category":"axis","display":"axis","coordinates":"X Z","kinematics":"trivkins coordinates=xz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"e1ce3667979cf2ea4813aa492c2061727d3f02a4d9592db0e4889f4fa53a6447"},{"path":"linuxcnc/configs/sim/axis/lathe_multispindle/lathe.ini","label":"LinuxCNC-HAL-SIM-LATHE","category":"axis/lathe_multispindle","display":"axis","coordinates":"X Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"fb2dbd47226cf39cc2149850e44d22324c6d6af886e1a2a0d43fa8d9ff36efe6"},{"path":"linuxcnc/configs/sim/axis/ldelta.ini","label":"Delta-robot-with-linear-joints","category":"axis","display":"axis","coordinates":"X Y Z A","kinematics":"lineardeltakins","family":"parallel_delta","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"1567138c3d54b4d9712b5031f6a0b060edadd8d1442d1eff8d93c2beefbb5e0c"},{"path":"linuxcnc/configs/sim/axis/ldelta_demo.ini","label":"Delta-robot-with-linear-joints","category":"axis","display":"axis","coordinates":"X Y Z A","kinematics":"lineardeltakins","family":"parallel_delta","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"ab0645308abe903bf66f36a328b43303aa0e8ad2d19e69a45e2703d665956439"},{"path":"linuxcnc/configs/sim/axis/minimal_xyz.ini","label":"minimal xyz","category":"axis","display":"axis","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"63923bfb90f4aba843cb89f8dccc34732d803e2bfd5598ed23a2ba22f360d00a"},{"path":"linuxcnc/configs/sim/axis/moveoff/1_onpause_local.ini","label":"moveoff,onpause,local","category":"axis/moveoff","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"d773e556b4692d60fe55b68d92a02ee69ba1dd128ef3ae4936327fc0f4451761"},{"path":"linuxcnc/configs/sim/axis/moveoff/2_onpause_external.ini","label":"moveoff,onpause,external","category":"axis/moveoff","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"d5f20008f4f1d9f81c9fbb871b56ca5098c35b5428014fcfcbaf2da516a8143a"},{"path":"linuxcnc/configs/sim/axis/moveoff/3_always_local.ini","label":"moveoff,always,local","category":"axis/moveoff","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"248af931464559c734115afa4c6d7989d7ea4fbc047e8e97a5306baef72b3a8c"},{"path":"linuxcnc/configs/sim/axis/moveoff/4_always_external.ini","label":"moveoff,always,external","category":"axis/moveoff","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"0bb9c9089b579c83afe8286623bdf7c0167e6544ddf73e84217a74cf952205f7"},{"path":"linuxcnc/configs/sim/axis/moveoff/5_no_gui.ini","label":"moveoff,no_gui","category":"axis/moveoff","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"e4e29328d1434e870018460aaaaf986b8e32ed5aa8f4c043d1df7a24f8438376"},{"path":"linuxcnc/configs/sim/axis/moveoff/6_zretract.ini","label":"moveoff zretract demo","category":"axis/moveoff","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"5a8aff43dbb07753e983a562f0ea79eaa0859e9214155bb2657a1d2bde18ec50"},{"path":"linuxcnc/configs/sim/axis/moveoff/7_pyvcp.ini","label":"moveoff,onpause,external","category":"axis/moveoff","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"e0fd69e140a109f84e2cd418f91d1312badb8db0d7d8861e42753955140602d2"},{"path":"linuxcnc/configs/sim/axis/moveoff/8_gladevcp.ini","label":"moveoff,onpause,external","category":"axis/moveoff","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"a67d7d08de6e0f675280ab4b9d9a50bbf400eae364913282d5370307900180b2"},{"path":"linuxcnc/configs/sim/axis/ngcgui/ngcgui.ini","label":"Ngcgui-demo","category":"axis/ngcgui","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"a461d37954c2e621505a4f8b6387c00a37489236ccf8522370e3076ddca33b00"},{"path":"linuxcnc/configs/sim/axis/ngcgui/ngcgui_gcmc.ini","label":"Ngcgui-gcmc-demo","category":"axis/ngcgui","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"a4cb71679b44afeb5734f8f07d1e2f63332faff54bfd7f9bfd4abfe706a651fe"},{"path":"linuxcnc/configs/sim/axis/ngcgui/ngcgui_lathe.ini","label":"ngcgui-lathe","category":"axis/ngcgui","display":"axis","coordinates":"X Z","kinematics":"trivkins coordinates=xz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"ec11d67522375c3cd1afbb76b5f12cbe6e5e9e51b430697f54b0e7088639db5a"},{"path":"linuxcnc/configs/sim/axis/ngcgui/ngcgui_simple.ini","label":"Ngcgui-demo","category":"axis/ngcgui","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"ec42c49461f66a395154b09e18d94674a17e8a7249791c5adf33b85ea6a19640"},{"path":"linuxcnc/configs/sim/axis/ngcgui/pyngcgui_axis.ini","label":"pyngcgui-axis demo","category":"axis/ngcgui","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"71f8ed201b46c4642e3f7d787065940e5d29b31452a5802056ede460cecd9f52"},{"path":"linuxcnc/configs/sim/axis/orphans/acc_test.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"axis/orphans","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"8a47360f16911553f9d1a046486ae507e1ee26f314f7ff37b250d5dca420c24a"},{"path":"linuxcnc/configs/sim/axis/orphans/axis_noio.ini","label":"axis_noio","category":"axis/orphans","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"1358837965ce189bb445b1d75d7d4688fb9353ec02a9f3dae53fd3601a9943cc"},{"path":"linuxcnc/configs/sim/axis/orphans/iocontrol-removed/iocontrol-removed.ini","label":"iocontrol-removed.ini","category":"axis/orphans/iocontrol-removed","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"6777d316581462ba253cec0f5e72ff148d7539bdd21b5e268c3e8da2455a7f31"},{"path":"linuxcnc/configs/sim/axis/orphans/medium.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"axis/orphans","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":6,"unresolved_count":0,"source_sha256":"258bcd736539fa2d47af1d2c99dd748a2803f8b065c1ef0171e5a98cdbbbb0a6"},{"path":"linuxcnc/configs/sim/axis/panelui-demo/_panelui.ini","label":" panelui","category":"axis/panelui-demo","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"899a352a6198675cff2deb303e52ff7e86715d1c8f7cb8c16c5a7ec9a11b3c60"},{"path":"linuxcnc/configs/sim/axis/panelui-demo/panelui-demo.ini","label":"panelui-demo","category":"axis/panelui-demo","display":"axis","coordinates":"X Z","kinematics":"trivkins coordinates=xz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"9b47416920a284322363e47771e612fca7415a0a0a594f9f7cbdf4a502c4757e"},{"path":"linuxcnc/configs/sim/axis/pentapod/pentapod.ini","label":"SIM-PENTAPOD","category":"axis/pentapod","display":"axis","coordinates":"X Y Z A B","kinematics":"pentakins","family":"parallel_pentapod","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"0fb210122ab482087d3a95e5e7487baecb84c3260dca1769970f4c19b2ad0618"},{"path":"linuxcnc/configs/sim/axis/plasma/imperial.ini","label":"imperial","category":"axis/plasma","display":"axis","coordinates":"XYYZ","kinematics":"trivkins coordinates=xyyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"c531ab622b904085f05e9fa6fdf791c0a5ec15153f2e22acd5273676a35a9a25"},{"path":"linuxcnc/configs/sim/axis/plasma/metric.ini","label":"metric","category":"axis/plasma","display":"axis","coordinates":"XYYZ","kinematics":"trivkins coordinates=xyyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"7dab2e05a237c1a8ec472e9c09b03ac8a4a016786207d83aa17fa142a5d4defe"},{"path":"linuxcnc/configs/sim/axis/profile_axis.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"axis","display":"profile_axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"f3e7bed9eeecea860ab15d9eef4319715eedcb13315b25f9e62ac9797baed7bb"},{"path":"linuxcnc/configs/sim/axis/qtvcp/qtvcp_tab.ini","label":"LinuxCNC-TAB-GLADEVCP","category":"axis/qtvcp","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"29d36b3435bc7b410d8dd57f794c9254a91c11ad06d1b26ad3be39489c4d51ee"},{"path":"linuxcnc/configs/sim/axis/qtvcp/qtvismach_tab.ini","label":"LinuxCNC-TAB-GLADEVCP","category":"axis/qtvcp","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"5e610fd07b44d291422378996f098fa27e4dc075e3f3fb49ad6267471b426206"},{"path":"linuxcnc/configs/sim/axis/random_tc.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"axis","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"d0b1614f287c10ad0d6dabf81aac69f78e187dddae30225ccaf501c8fdef0f29"},{"path":"linuxcnc/configs/sim/axis/rdelta.ini","label":"Delta-robot-with-rotary-joints","category":"axis","display":"axis","coordinates":"X Y Z A B C U V W","kinematics":"rotarydeltakins","family":"parallel_delta","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"53510733b8fd0230547f48f76ebd35dc5c98f58fe1dba1246777e227ef82c508"},{"path":"linuxcnc/configs/sim/axis/remap/cycle/cycle.ini","label":"cycle.ini","category":"axis/remap/cycle","display":"axis","coordinates":"X Y Z A B C U V W","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"ee64fa142ddf5a5288cae36a39445a32488250755f72ea5a1d3df436c2694e8c"},{"path":"linuxcnc/configs/sim/axis/remap/extend-builtins/extend-builtins.ini","label":"extend-builtins.ini","category":"axis/remap/extend-builtins","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"432ff320ac6d3518a73ae69e924c343c0740d04475a09f99391304f5f7e8cc76"},{"path":"linuxcnc/configs/sim/axis/remap/getting-started/demo.ini","label":"getting-started:demo.ini","category":"axis/remap/getting-started","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"763dd31e6eb32047eb35eecb933f822db3a65e87b1a214f982517369eecdd976"},{"path":"linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/manualtoolchange.ini","label":"manualtoolchange.ini","category":"axis/remap/manual-toolchange-with-tool-length-switch","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"6d52f5596d0f0f90c9a2da5a0802d6dfe35c4fbfe1c9cd4e9e6f34a3ab52e064"},{"path":"linuxcnc/configs/sim/axis/remap/rack-toolchange/racktoolchange.ini","label":"racktoolchange.ini","category":"axis/remap/rack-toolchange","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"742f1ca34ffc95b1781673ca6ebed5cc23376cc7d94c520d4f8d4036699109e5"},{"path":"linuxcnc/configs/sim/axis/remap/stop-lookahead/demo.ini","label":"stop-lookahead:demo.ini","category":"axis/remap/stop-lookahead","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"aea088d4bb017ac0474dca3f696c76533d374cac5a40b71944d76a1c89e9dafc"},{"path":"linuxcnc/configs/sim/axis/rose_engine/rose_engine.ini","label":"Roseengine","category":"axis/rose_engine","display":"axis","coordinates":"XYZ","kinematics":"rosekins","family":"coupled_linear","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":3,"unresolved_count":1,"source_sha256":"0685e9ca8c05c903b715e9fed6ecd23cbac13911ed335b6d14e24eb235de25d3"},{"path":"linuxcnc/configs/sim/axis/rotate/rotatekins.ini","label":"rotatekins_candidate","category":"axis/rotate","display":null,"coordinates":"XYZABC","kinematics":"rotatekins","family":"cartesian","status":"blocked","startup_preflight":"blocked_unindexed_resource_graph","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"324af9a73d21b5f0c9adaf3c97e698422790d403586901f9e161b6020b1fb4fa"},{"path":"linuxcnc/configs/sim/axis/simtcl/twopass_basic.ini","label":"twopass_basic","category":"axis/simtcl","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"b19e33bdaccebf5e060acdb5b0239b438a8f76c0e84dd1374420775f989bf766"},{"path":"linuxcnc/configs/sim/axis/simtcl/twopass_compat.ini","label":"twopass_compat","category":"axis/simtcl","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"d85d2940827bb6b2c945f69ef1ad18141bdc72f5c3391a7d816605320fd7ae57"},{"path":"linuxcnc/configs/sim/axis/spindle_orient/orient.ini","label":"M19-Orient-demo","category":"axis/spindle_orient","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":6,"unresolved_count":0,"source_sha256":"98d9ca88da31ae88a2ae51b80027939a6ebc6e700326ee7f3a108506aa908b04"},{"path":"linuxcnc/configs/sim/axis/twopass/twopass.ini","label":"SIM-AXIS-TWOPASS","category":"axis/twopass","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":7,"unresolved_count":0,"source_sha256":"9b88396ab9461605c378ba933faf6cf17bfc7c960220e6fb4573d17c81f24526"},{"path":"linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini","label":"3axis-tutorial","category":"axis/vismach/3axis-tutorial","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":3,"unresolved_count":1,"source_sha256":"07e4fafa71e13ac3749fd860ee7549b762f521b9ca58c32110a9f582554882dc"},{"path":"linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/3axis-tutorial.ini","label":"3axis-tutorial","category":"axis/vismach/3axis-tutorial/3axis-tutorial.old","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"c1e81259a265b1f0c36864b94c31f7f4be95e17bdc452b1cdd9f74b0ac047c3d"},{"path":"linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/5axis.ini","label":"Sim-5Axis Bridge Mill (xyzbcw)","category":"axis/vismach/5axis/bridgemill","display":"axis","coordinates":"XYZBCWY","kinematics":"5axiskins coordinates=xyzbcwy","family":"five_axis","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"789ba656f8ee3e97feba07b58eb242305898e745795891b1a7e536289bffe6bf"},{"path":"linuxcnc/configs/sim/axis/vismach/5axis/max5/max5kins.ini","label":"MAX5 with kinematics Simulation","category":"axis/vismach/5axis/max5","display":null,"coordinates":null,"kinematics":"maxkins","family":"cartesian","status":"ready","startup_preflight":"static_ready","resource_status":"ready","missing_count":0,"unresolved_count":0,"source_sha256":"ea7d453127122b7831e74de2204b446c514f3c999961a4be412b36880bacb8b6"},{"path":"linuxcnc/configs/sim/axis/vismach/5axis/max5/max5triv.ini","label":"MAX5-trivkins Simulation","category":"axis/vismach/5axis/max5","display":null,"coordinates":null,"kinematics":"trivkins coordinates=xyzabc","family":"cartesian","status":"ready","startup_preflight":"static_ready","resource_status":"ready","missing_count":0,"unresolved_count":0,"source_sha256":"92afb2043a559d8eb9e638bfb9862c8ec917deb49987c788989fe538e8ddeefb"},{"path":"linuxcnc/configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.ini","label":"sim-xyzab-tdr-kins (switchkins)","category":"axis/vismach/5axis/table-dual-rotary","display":"axis","coordinates":"XYZAB","kinematics":"xyzab_tdr_kins","family":"five_axis_trt","status":"blocked","startup_preflight":"blocked_unregistered_kinematics","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"923d0a9e75ff595e05a5fe13194cbd7eee7465419b995fe852503435a8d35907"},{"path":"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini","label":"sim-xyzac-trt-kins (switchkins)","category":"axis/vismach/5axis/table-rotary-tilting","display":"axis","coordinates":"XYZAC","kinematics":"xyzac-trt-kins sparm=identityfirst","family":"five_axis_trt","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"f985970db293b70c055e4c41fc316d0c16037b5dc7ce07490e18f554e851f811"},{"path":"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini","label":"sim-xyzbc-trt-kins (switchkins)","category":"axis/vismach/5axis/table-rotary-tilting","display":"axis","coordinates":"XYZBC","kinematics":"xyzbc-trt-kins sparm=identityfirst","family":"five_axis_trt","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"86d2a11212246c1ed4516719ab0fabe3549cca00b3719dd961c2a8c4048d7880"},{"path":"linuxcnc/configs/sim/axis/vismach/VMC_toolchange/vmc_graycode.ini","label":"Vertical Machining Centre with Toolchange Simulation","category":"axis/vismach/VMC_toolchange","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"5825522880add3a8614e1fd5c168b16533f7b7b898b00a640b6e74f281270d2b"},{"path":"linuxcnc/configs/sim/axis/vismach/VMC_toolchange/vmc_index.ini","label":"Vertical Machining Centre with Toolchange Simulation","category":"axis/vismach/VMC_toolchange","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"0f6e02c370c529d080bf913c1771169652bf8fe1b67cdda86cb93e2c8f933abe"},{"path":"linuxcnc/configs/sim/axis/vismach/hbm/hbm.ini","label":"Horizontal Boring Mill Simulation","category":"axis/vismach/hbm","display":"axis","coordinates":"X Y Z W","kinematics":"trivkins coordinates=xyzw","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"63eafce3b9ee34cc0ff489dd754e1657a4cfd08d16147f28be38687e19604b4d"},{"path":"linuxcnc/configs/sim/axis/vismach/hexapod-sim/hexapod.ini","label":"hexapod (switchkins)","category":"axis/vismach/hexapod-sim","display":"axis","coordinates":"X Y Z A B C","kinematics":"genhexkins","family":"parallel_hexapod","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"362654b77bcaf5c87c3aa14c12684f516cbd635b6d582a68b05fcbd8299822ea"},{"path":"linuxcnc/configs/sim/axis/vismach/melfa-sim/melfa.ini","label":"melfa (mm)","category":"axis/vismach/melfa-sim","display":"axis","coordinates":"X Y Z A B C","kinematics":"genserkins","family":"serial_robot","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"7dc7a3db58ca7f7ddba11fe08f691cd7658564be2a0b872d9087ee7b392e45c7"},{"path":"linuxcnc/configs/sim/axis/vismach/millturn/millturn.ini","label":"millturn (mm)","category":"axis/vismach/millturn","display":"axis","coordinates":"X Y Z A","kinematics":"millturn","family":"switchable","status":"blocked","startup_preflight":"blocked_unregistered_kinematics","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"dfdb6e6c295c4ca9ebf9ff11f31c1b5d6fed4079b8e48b7b59cf7fee6b8b1547"},{"path":"linuxcnc/configs/sim/axis/vismach/puma/puma.ini","label":"PUMA (pumakins,switchkins)","category":"axis/vismach/puma","display":"axis","coordinates":"X Y Z A B C","kinematics":"pumakins","family":"serial_robot","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"26ee23af27aa03d2da89b842992802ece2423195a5ac0960b28bb751871d74f6"},{"path":"linuxcnc/configs/sim/axis/vismach/puma/puma560.ini","label":"puma560 (switchkins) (inch)","category":"axis/vismach/puma","display":"axis","coordinates":"X Y Z A B C","kinematics":"genserkins","family":"serial_robot","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"2bb881ed6c5662282977accac29bfd6c4efc18e572cbcb8a31c134677012cf4c"},{"path":"linuxcnc/configs/sim/axis/vismach/puma/puma560_uvw.ini","label":"puma560 (switchkins) (inch)","category":"axis/vismach/puma","display":"axis","coordinates":"X Y Z A B C U V W","kinematics":"genserkins","family":"serial_robot","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"50bf5dbc4cf70b0c18afea3dcbc577fbb6166152300cd16e27819de1fafe41b0"},{"path":"linuxcnc/configs/sim/axis/vismach/puma/puma_cube.ini","label":"puma_cube.ini (pumakins)","category":"axis/vismach/puma","display":"axis","coordinates":"X Y Z A B C","kinematics":"pumakins","family":"serial_robot","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"0204289788840e0dcaaeb55a2a85cf44a3754845636a897df6efeb165db0de15"},{"path":"linuxcnc/configs/sim/axis/vismach/rolfmill/rolfmill.ini","label":"rolfmill","category":"axis/vismach/rolfmill","display":"axis","coordinates":"X Y Z","kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"b122ac25ed12462b02d10828c469bafdcb231e9cbed07e96b6a7709380bdf0ad"},{"path":"linuxcnc/configs/sim/axis/vismach/scara/scara.ini","label":"SCARA (genserkins,switchkins)","category":"axis/vismach/scara","display":"axis","coordinates":"XYZABC","kinematics":"scarakins coordinates=xyzcab","family":"serial_robot","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"602e02bb6d320b728d9ae15904a5d229ea1a31e932c18e9018b45be007d695ce"},{"path":"linuxcnc/configs/sim/axis/vismach/scorbot/scorbot.ini","label":"scorbot_candidate","category":"axis/vismach/scorbot","display":null,"coordinates":"XYZAB","kinematics":"scorbot-kins","family":"serial_robot","status":"blocked","startup_preflight":"blocked_unindexed_resource_graph","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"4e8edd061a033d45e1e71c56bdd521ee10d3f60def3be020bbd437fc49271343"},{"path":"linuxcnc/configs/sim/axis/wrapped_rotary/wrapped_rotary.ini","label":"EMC-HAL-SIM-WRAPPED-ROTARY","category":"axis/wrapped_rotary","display":"axis","coordinates":"X Y Z A","kinematics":"trivkins coordinates=xyza kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"a9d1ffd13139631bba4b4eec761e99b3245ad18be951d076eb3a949e3e6c3798"},{"path":"linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout1.ini","label":"xhc-hb04 layout1 demo","category":"axis/xhc-hb04","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"07b2c68847bdb8136adfc04193826c6019981c80a7219a1dbbb733d337b8f817"},{"path":"linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout2.ini","label":"xhc-hb04 layout2 demo","category":"axis/xhc-hb04","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"9082cc7df0115bbf754f796ae7989fab1897b5167231dd7b55e6e7ff2f0d96ce"},{"path":"linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout2_mm.ini","label":"xhc-hb04 layout2 mm demo","category":"axis/xhc-hb04","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"cbc5c40c2a7fbfa0ead5f52dde952a0f1cd088895cdc1f06a5d01060c54aef41"},{"path":"linuxcnc/configs/sim/craftsman/cnc_settings.ini","label":"cnc settings","category":"craftsman","display":null,"coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"4a40e3b30ec1cee094424945ddb36400c6d7fd5d8edf0109d95e7ea68ce211d8"},{"path":"linuxcnc/configs/sim/craftsman/craftsmancnc-axis.ini","label":"Craftsman 900ST","category":"craftsman","display":"cm_axis","coordinates":"X Y Z A","kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"d678962c09a6e37c89868c715c98c77dbd3f9f3fe1f6537b41d092d2a5d8ed56"},{"path":"linuxcnc/configs/sim/craftsman/craftsmancnc.ini","label":"Craftsman 900ST","category":"craftsman","display":"./craftsmancnc","coordinates":"XYZA","kinematics":"trivkins coordinates=XYZA","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"c9390a47578b640dfde32e50475a2ae386dd657dc5130ce2fe34564bf90bfc70"},{"path":"linuxcnc/configs/sim/gmoccapy/6_axis.ini","label":"gmoccapy_9_axis","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z A B C","kinematics":"trivkins coordinates=XYZABC","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"1a47c6b666af1ca2f78f95022c27bb9f94626ffce26da23556fea15f767b7cba"},{"path":"linuxcnc/configs/sim/gmoccapy/7_axis.ini","label":"gmoccapy_9_axis","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z A B C U","kinematics":"trivkins coordinates=XYZABCU","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"10db48db4e53a03fe04c2e3dc849c84c9f3f2b77d51c233f64b92b375942a14f"},{"path":"linuxcnc/configs/sim/gmoccapy/7_axis_tool.ini","label":"gmoccapy_9_axis","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z A B C U","kinematics":"trivkins coordinates=XYZABCU","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"6f48447e4576d82a57742dc94babcecf2e813a2afbe398acfcfd87d05c99f229"},{"path":"linuxcnc/configs/sim/gmoccapy/8_axis.ini","label":"gmoccapy_9_axis","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z A B C U V","kinematics":"trivkins coordinates=XYZABCUV","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"ad9e2a848a1d1cde6c4fbcf82adaae70d52af6f283d3e785a053c2a560ab8f84"},{"path":"linuxcnc/configs/sim/gmoccapy/9_axis.ini","label":"gmoccapy_9_axis","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z A B C U V W","kinematics":"trivkins coordinates=XYZABCUVW","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"72252c1eb8238facb30b8b3fc08d012b22c70bf1c7c151c2e50946a5eeadc5ef"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy.ini","label":"gmoccapy","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"627537d0a342075ecd45765b4d8b256b065f2568902a585cfe5161efec53a126"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_4_axis.ini","label":"gmoccapy 4 axis","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z C","kinematics":"trivkins coordinates=xyzc","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"33b4ad6792d9037f2a0bb9eb179aff7b3d8ecac64bfa0b1cc71633a88cf868d9"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZAB.ini","label":"gmoccapy XYZAB","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z A B","kinematics":"trivkins coordinates=xyzab","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"c8047ee290a94944481545a78104e9ead1036ca04f965a729ad4a870e7fe69a1"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZAC.ini","label":"gmoccapy XYZAC","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z A C","kinematics":"trivkins coordinates=xyzac","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"daf2ffcab7fb3af60f5dd38256c8e9bb3347d885771ba414da2b4277c8ebce4a"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZCW.ini","label":"gmoccapy XYZAB","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z C W","kinematics":"trivkins coordinates=xyzcw","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"8a860f885f6afc18b0d1ff8081d356d56897456298cfd58fc7394ec519f71e83"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_left_panel.ini","label":"gmoccapy_left_panel","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"3e458b639557d33bc2b637fb2f63b88e1cade3dd7543306b96e166c5b50bb08e"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_messages.ini","label":"gmoccapy_development","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"7b8a607c978ad1758a51d60b04d3bed46a9597661060a6a906b4411abe02e857"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_pedant.ini","label":"gmoccapy_pendant","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":3,"unresolved_count":1,"source_sha256":"ea336e14be5b1b62a6b540070624b6c35cd076b16d170725fc4dacb9754e6790"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/gmoccapy_plasma.ini","label":"gmoccapy","category":"gmoccapy/gmoccapy_plasma","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"b006d05ea125442e3258a76b9e95d28a3488d25f1f652828c470de82aaa9d077"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_pyngcgui.ini","label":"gmoccapy","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"2f62b1a0e2bcdf2b587e142ea8c4212c28b8024161c38b13e5cb39e15c984ce7"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_right_panel.ini","label":"gmoccapy right panel","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"c155ba8047c3011c6ec023dd911fa571ec52b5352b789b7c88542c8d418e15bc"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_sim_hardware_button.ini","label":"gmoccapy sim hardware button","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"7469a0e05ea85c83d99f11ef552482c29d93313a358d8a7801a2eabbae1f9af0"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_tool_sensor.ini","label":"gmoccapy tool sensor","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"4caf0e746fd09bceafa4f2bdced6a9be063b7ee51334fbb75d4c6914d94db7b9"},{"path":"linuxcnc/configs/sim/gmoccapy/gmoccapy_with_user_tabs.ini","label":"gmoccapy with user tabs","category":"gmoccapy","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"a080a9008bef88d61fee5473f8531df64bfe3fd365540e1055e3377ce59f99d9"},{"path":"linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe.ini","label":"gmoccapy_lathe","category":"gmoccapy/lathe_configs","display":"gmoccapy","coordinates":"X Z","kinematics":"trivkins coordinates=XZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"b6971dfdf96fb2d502378d143da6c7a2f404fe796f41f96f629b9db15a44bb66"},{"path":"linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_C.ini","label":"lathe_c","category":"gmoccapy/lathe_configs","display":"gmoccapy","coordinates":"X Z C","kinematics":"trivkins coordinates=XZC","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"c2f67186fc6c84f266d2ad1d6fcf487249182a2385f8d3099f51f9fab1cc8bb4"},{"path":"linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_CW.ini","label":"lathe_cw","category":"gmoccapy/lathe_configs","display":"gmoccapy","coordinates":"X Z C W","kinematics":"trivkins coordinates=XZCW","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"df718eefdbd91308b9182f6858150abb8fa4a2d030105db954702c280cddac70"},{"path":"linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_backtool.ini","label":"gmoccapy_lathe","category":"gmoccapy/lathe_configs","display":"gmoccapy","coordinates":"X Z","kinematics":"trivkins coordinates=XZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"5d7e04fd075e28534afe817e64259a2e7df809d5fdf893f39c9cc5ffcd35ed71"},{"path":"linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_imperial.ini","label":"lathe_imperial","category":"gmoccapy/lathe_configs","display":"gmoccapy","coordinates":"X Z","kinematics":"trivkins coordinates=XZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"503bf2241ed1c1f70410015a7f3aab5a922dc571b1ded36f5431c538d5d4e628"},{"path":"linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_macros.ini","label":"gmoccapy_lathe","category":"gmoccapy/lathe_configs","display":"gmoccapy","coordinates":"X Z","kinematics":"trivkins coordinates=XZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"b3d9c8451a9281e9863e30f7d0138d5779028a06d981c2f1bd30bf6c7bded0e0"},{"path":"linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gantry_mm.ini","label":"gmoccapy_GANTRY_sim","category":"gmoccapy/non_trivial_kinematics/Gantry","display":"gmoccapy","coordinates":"X Y Y Z","kinematics":"trivkins coordinates=xyyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"303f0fb1b9a70ba3cc6dbc11003bed2c59579ddfe2e4d9a300a5fcd4da570e65"},{"path":"linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara.ini","label":"LinuxCNC-HAL-SIM-SCARA","category":"gmoccapy/non_trivial_kinematics/scara","display":"gmoccapy","coordinates":"X Y Z C","kinematics":"scarakins","family":"serial_robot","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"3c5a9c56f4c50a987f7b2a21b6968ab77eeb586a894f8ffff73dec74eb680092"},{"path":"linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt.ini","label":"sim-xyzac-trt","category":"gmoccapy/non_trivial_kinematics/table-rotary-tilting","display":"gmoccapy","coordinates":"XYZAC","kinematics":"xyzac-trt-kins","family":"five_axis_trt","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"af315891e9e561812f267f9c44c752c265ad00c862adbcd7dd42c2b07e60cd38"},{"path":"linuxcnc/configs/sim/gmoccapy/plasma_config/gmoccapy_plasma.ini","label":"gmoccapy","category":"gmoccapy/plasma_config","display":"gmoccapy","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"7d53c570ccb85f086e67eb511c28bb9cec47e02cf42395e71bb2ff89e9d0d671"},{"path":"linuxcnc/configs/sim/gscreen/gscreen.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"gscreen","display":"gscreen","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":7,"unresolved_count":0,"source_sha256":"5501604c0c6d0288cea28720da271fd44900ea50ddcccf6acf0743e7e2daf016"},{"path":"linuxcnc/configs/sim/gscreen/gscreen_custom/9axis.ini","label":"LinuxCNC-HAL-SIM-GSCREEN","category":"gscreen/gscreen_custom","display":"gscreen -c 9_axis -d -v","coordinates":"X Y Z A B C U V W","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"2ffde65bf13a116a14d2b75a841f197cd67f6281c6b5c2c548487e779a166ef0"},{"path":"linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_no_plot.ini","label":"Linuxcnc-Gscreen_gaxis_no_plot","category":"gscreen/gscreen_custom","display":"gscreen -c gaxis_no_plot -c","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":7,"unresolved_count":0,"source_sha256":"93faa3f0a5727d1468381add40a7b35ac5e80b44d8c9c17bfb1e18754daa5498"},{"path":"linuxcnc/configs/sim/gscreen/gscreen_custom/gscreen_gaxis.ini","label":"Linuxcnc-Gscreen_gaxis","category":"gscreen/gscreen_custom","display":"gscreen -c gaxis -c","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":7,"unresolved_count":0,"source_sha256":"8b37aef313551ab9dcd3a414d582b399669dfb4375d08fe5ee709bf327c53d43"},{"path":"linuxcnc/configs/sim/gscreen/gscreen_custom/industrial.ini","label":"Linuxcnc-Gscreen_gaxis","category":"gscreen/gscreen_custom","display":"gscreen -c industrial -d","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":7,"unresolved_count":0,"source_sha256":"ceab463ee55d534c84a5abf5b98d0caee56f9ef71ed67e5ceabea84cf998b725"},{"path":"linuxcnc/configs/sim/gscreen/gscreen_custom/tester.ini","label":"Linuxcnc-Gscreen_gaxis","category":"gscreen/gscreen_custom","display":"gscreen -c tester -d","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":7,"unresolved_count":0,"source_sha256":"94c5bb5c621e8074f96004b1abbe5bc66ee5df6aa672f2cf3542c3d38047ac70"},{"path":"linuxcnc/configs/sim/gscreen/gscreen_custom/tester_metric.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"gscreen/gscreen_custom","display":"gscreen -c tester -d","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":8,"unresolved_count":0,"source_sha256":"bc459d4d659a562f22da247a2734116000e4c8fa71ea13014ca61885dc5bf2ea"},{"path":"linuxcnc/configs/sim/gscreen/gscreen_lathe.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"gscreen","display":"gscreen","coordinates":"X Z","kinematics":"trivkins coordinates=xz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"bf9e089a8d61194462bb418efe1176eaf624faee8e42f0cfd791b62b9b906e24"},{"path":"linuxcnc/configs/sim/gscreen/gscreen_mm.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"gscreen","display":"gscreen","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":7,"unresolved_count":0,"source_sha256":"f4e86efc8aea695f7c931742a41b48851a29fced4aff1dab67b001934245e297"},{"path":"linuxcnc/configs/sim/gscreen/industrial_lathe_wear/industrial_lathe_wear.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"gscreen/industrial_lathe_wear","display":"gscreen -c industrial -d","coordinates":"X Z","kinematics":"trivkins coordinates=xz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"4c807ff8b3faa4e97574c4c7add99fe6b7654e980bb73737e46f563b5170b422"},{"path":"linuxcnc/configs/sim/gscreen/ngcgui/pyngcgui_gscreen.ini","label":"pyngcgui-gscreen demo","category":"gscreen/ngcgui","display":"gscreen","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"01ea7f117f038a59dccb25a01c4d693222e807474e2e6aec338975aa6bed5841"},{"path":"linuxcnc/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_popupkeyboard.ini","label":"pyngcgui-gscreen demo (popupkeyboard)","category":"gscreen/ngcgui","display":"gscreen","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"d6fd8d018be34826fb7bccdad4987a8968dbfdf7a2b5794b75c809c56a18ad63"},{"path":"linuxcnc/configs/sim/gscreen/silverdragon/silverdragon.ini","label":"silverdragon","category":"gscreen/silverdragon","display":"gscreen -d -c silverdragon","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":5,"unresolved_count":1,"source_sha256":"d1ed1b802162281fc742b0146be7bb3b5daba2fc944d4b4c8f8ccdb096cffc77"},{"path":"linuxcnc/configs/sim/gscreen/spartan/spartan.ini","label":"spartan","category":"gscreen/spartan","display":"gscreen -c spartan","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":2,"unresolved_count":0,"source_sha256":"eddaf2a70b2e1147f8e4cb781abbb56a87243fdfad4932fc8ddecbeb5f5d42e1"},{"path":"linuxcnc/configs/sim/pyvcp_demo/pyvcp_bottom_panel.ini","label":"Pyvcp_demo1","category":"pyvcp_demo","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"75dc8d6f9dc89d6725aabdb7c59cb0965d2d054b2e1e4baa71de3538b4f77c85"},{"path":"linuxcnc/configs/sim/pyvcp_demo/pyvcp_demo1.ini","label":"Pyvcp_demo1","category":"pyvcp_demo","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"5ec9203047e509b1e633dadcebba91909c3aee8ad65465ea2c0bd8bc409bb9a0"},{"path":"linuxcnc/configs/sim/pyvcp_demo/pyvcp_embed_tab.ini","label":"Pyvcp_demo1","category":"pyvcp_demo","display":"axis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"4da521d1e8bc2fdb0155f86afc1b1c0dffdd31402ade0ab7519bbfd30145cfbe"},{"path":"linuxcnc/configs/sim/qtaxis/gantry/qt_gantry.ini","label":"LinuxCNC-GANTRY-SIM-qtvcp","category":"qtaxis/gantry","display":"qtvcp -d qtaxis","coordinates":"XYZY","kinematics":"trivkins coordinates=XYZY kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":8,"unresolved_count":0,"source_sha256":"0b06ae360b37859343763adb960e6304a812ebc658a2056fc4df280ccd793c37"},{"path":"linuxcnc/configs/sim/qtaxis/non-trivial/scara/scara.ini","label":"SCARA (genserkins,switchkins)","category":"qtaxis/non-trivial/scara","display":"qtvcp qtaxis","coordinates":"XYZABC","kinematics":"scarakins coordinates=xyzcab","family":"serial_robot","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":6,"unresolved_count":0,"source_sha256":"1f4fa4d1a1ccd5cf299948b824101430bd1a41cb8ea74a3311373ce9ef17a7c1"},{"path":"linuxcnc/configs/sim/qtaxis/xyz/qtaxis.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtaxis/xyz","display":"qtvcp -v qtaxis","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz kinstype=B","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":7,"unresolved_count":1,"source_sha256":"c764f544082a217a19a9fc26d0552f209dcb4548e80d2f544b1e00489472819a"},{"path":"linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyz.ini","label":"qtdragon","category":"qtdragon/qtdragon_multi_joint","display":"qtvcp qtdragon","coordinates":"XYYZ","kinematics":"trivkins coordinates=XYYZ kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":3,"source_sha256":"6e37414ca98a0a0551b8b54980fbc77417b618aeba039e3c38ac4c4b9b1b6b68"},{"path":"linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyzy.ini","label":"qtdragon","category":"qtdragon/qtdragon_multi_joint","display":"qtvcp qtdragon","coordinates":"XYZY","kinematics":"trivkins coordinates=XYZY kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":3,"source_sha256":"f657495b776ab5f371bf59106bbbfa230f1cbc72061caaf036bc6b38fbb79421"},{"path":"linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyzya.ini","label":"qtdragon","category":"qtdragon/qtdragon_multi_joint","display":"qtvcp qtdragon","coordinates":"XYZYA","kinematics":"trivkins coordinates=XYZYA kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":3,"source_sha256":"7835bceebe51c9881328896c9f4a6fe4fc91e49a025a26a95e6b7c1716e2edf2"},{"path":"linuxcnc/configs/sim/qtdragon/qtdragon_tool_probe/qtdragon_auto_tool_probe.ini","label":"qtdragon","category":"qtdragon/qtdragon_tool_probe","display":"qtvcp qtdragon","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":7,"unresolved_count":1,"source_sha256":"3000ec032956226a8281fe0e76304c56d3d6d4d0fbef6b7b2c226a15f2eb9674"},{"path":"linuxcnc/configs/sim/qtdragon/qtdragon_xyz/qtdragon_inch.ini","label":"qtdragon_inch","category":"qtdragon/qtdragon_xyz","display":"qtvcp qtdragon","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":3,"source_sha256":"e36b608260f3eca2f2439d83b0e32786a2d1bd5f395c3705ee3fe3a1fa0ad94c"},{"path":"linuxcnc/configs/sim/qtdragon/qtdragon_xyz/qtdragon_metric.ini","label":"qtdragon_metric","category":"qtdragon/qtdragon_xyz","display":"qtvcp qtdragon","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":3,"source_sha256":"3565f4863be6f1dc25ef216c8a6f96e69f133681676131ab883007c80aef7c66"},{"path":"linuxcnc/configs/sim/qtdragon/qtdragon_xyz/qtdragon_xyza.ini","label":"qtdragon","category":"qtdragon/qtdragon_xyz","display":"qtvcp qtdragon","coordinates":"XYZA","kinematics":"trivkins coordinates=XYZA","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":3,"source_sha256":"592aaee3190a65fab8b200b45f5ec221ab58edf0b754e2db227352cebea0dae2"},{"path":"linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyza.ini","label":"qtdragon","category":"qtdragon/qtdragon_xyz45","display":"qtvcp qtdragon","coordinates":"XYZA","kinematics":"trivkins coordinates=XYZA","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":3,"source_sha256":"d5597a9bc8ef786bebd2dbc79300253117e814e214e17d067eddc1049ac1cf95"},{"path":"linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyzab.ini","label":"qtdragon","category":"qtdragon/qtdragon_xyz45","display":"qtvcp qtdragon","coordinates":"XYZAB","kinematics":"trivkins coordinates=XYZAB","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":4,"unresolved_count":3,"source_sha256":"c8ec9fc577cee73a46981d2a7c5eaebc596bddba19b395b87eb0e4eba2a0c3ba"},{"path":"linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyzac.ini","label":"qtdragon","category":"qtdragon/qtdragon_xyz45","display":"qtvcp qtdragon","coordinates":"XYZAC","kinematics":"trivkins coordinates=XYZAC","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":4,"unresolved_count":3,"source_sha256":"b25b195fd6d211053b3eb091a513c01ea83550969a29c6b446fdbb2577c1c7a2"},{"path":"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyz.ini","label":"qtdragon","category":"qtdragon_hd/qtdragon_hd_xyz","display":"qtvcp -d qtdragon_hd","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":3,"source_sha256":"6cfb7b2c847368e117d28ecd99027c4158ed2e02a08bbba787bee73bd1f3ad7d"},{"path":"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyza.ini","label":"qtdragon","category":"qtdragon_hd/qtdragon_hd_xyz","display":"qtvcp qtdragon_hd","coordinates":"XYZA","kinematics":"trivkins coordinates=XYZA","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":3,"source_sha256":"da745eb5892bbda71c4555b11c50bc8ff9f32a28f97a51951a892b4de5604fcc"},{"path":"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyzab.ini","label":"qtdragon","category":"qtdragon_hd/qtdragon_hd_xyz","display":"qtvcp qtdragon_hd","coordinates":"XYZAB","kinematics":"trivkins coordinates=XYZAB","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":5,"unresolved_count":3,"source_sha256":"9f9f7b2a62ebd1cf0fffa4d97af9dca42bc25d9678ee52978b4f24d10df7daa7"},{"path":"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyzac.ini","label":"qtdragon","category":"qtdragon_hd/qtdragon_hd_xyz","display":"qtvcp qtdragon_hd","coordinates":"XYZAC","kinematics":"trivkins coordinates=XYZAC","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":5,"unresolved_count":3,"source_sha256":"c836bd0309d143fa80a70fa37c1e92714437d5b3931ad50f47aad820bf597253"},{"path":"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_z_compensation.ini","label":"qtdragon","category":"qtdragon_hd/qtdragon_hd_z_compensation","display":"qtvcp -d qtdragon_hd","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":3,"source_sha256":"7285f86b7a2d30318c529985c0f34851e017ce69a23ca06ffb456d9d422f7503"},{"path":"linuxcnc/configs/sim/qtplasmac/qtplasmac_l_imperial.ini","label":"qtplasmac l imperial","category":"qtplasmac","display":"qtvcp qtplasmac","coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"2b563e2a090572d2bf02256b8dc3c99054fb0388167482ede5ce7ce5932db898"},{"path":"linuxcnc/configs/sim/qtplasmac/qtplasmac_l_metric.ini","label":"qtplasmac l metric","category":"qtplasmac","display":"qtvcp qtplasmac","coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"abe6e751f739076432b586af48512946175298676e5ed23d6a30e1dac77958ee"},{"path":"linuxcnc/configs/sim/qtplasmac/qtplasmac_p_imperial.ini","label":"qtplasmac p imperial","category":"qtplasmac","display":"qtvcp qtplasmac_9x16","coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"7e45dee1b8eec3ae9eea1ddf2eb9a47e40fb0fe32dcd93a126441d4cfd1d62b0"},{"path":"linuxcnc/configs/sim/qtplasmac/qtplasmac_p_metric.ini","label":"qtplasmac p metric","category":"qtplasmac","display":"qtvcp qtplasmac_9x16","coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"52b0aa0d4132f0fdfad5af82dbef598d33f655e3f65c721cd6e3c231146dfbdf"},{"path":"linuxcnc/configs/sim/qtplasmac/qtplasmac_s_imperial.ini","label":"qtplasmac s imperial","category":"qtplasmac","display":"qtvcp qtplasmac_4x3","coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"00694329d1f037d0f7a51a246b04d1743b9b4ba2983acf1edddd88fd9161d48f"},{"path":"linuxcnc/configs/sim/qtplasmac/qtplasmac_s_metric.ini","label":"qtplasmac s metric","category":"qtplasmac","display":"qtvcp qtplasmac_4x3","coordinates":null,"kinematics":null,"family":null,"status":"unindexed","startup_preflight":"unindexed","resource_status":"unindexed","missing_count":0,"unresolved_count":0,"source_sha256":"84e21e9dcb3a4572b999d96f97f7b188b3b202ad0e995776fd0e3f090ae5c8d6"},{"path":"linuxcnc/configs/sim/qttouchy/qttouchy.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qttouchy","display":"qtvcp -d qttouchy","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":8,"unresolved_count":1,"source_sha256":"1398796a9ef4d41bf2d9841656b588dd12818cfac9e390a8fd9d6aa6e2185acc"},{"path":"linuxcnc/configs/sim/qtvcp_screens/blender.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens","display":"qtvcp -m blender","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":7,"unresolved_count":1,"source_sha256":"15fc1681185d59a5f9d8ae14c2d9773bf749373bd6c71b6c614607ce7f35393d"},{"path":"linuxcnc/configs/sim/qtvcp_screens/industrial_lathe_wear/industrial_lathe_wear.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens/industrial_lathe_wear","display":"qtvcp -d qtlathe","coordinates":"X Z","kinematics":"trivkins coordinates=xz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":5,"unresolved_count":2,"source_sha256":"378d5e9e04608240a6884a011ec32caf8de0e3d67bae6b568f33e9e292e94ce5"},{"path":"linuxcnc/configs/sim/qtvcp_screens/non-trivial/scara/scara.ini","label":"SCARA (genserkins,switchkins)","category":"qtvcp_screens/non-trivial/scara","display":"qtvcp qtaxis","coordinates":"XYZABC","kinematics":"scarakins coordinates=xyzcab","family":"serial_robot","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":7,"unresolved_count":0,"source_sha256":"1e6a080a7718813d9946acdd7cf7c033e896a318702a5dc5f86f8d45012b2aea"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qt_800x600.ini","label":"LinuxCNC-Qtvcp-800x600","category":"qtvcp_screens","display":"qtvcp -d qt_cnc_800x600.ui","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":9,"unresolved_count":0,"source_sha256":"7235c5081d278551bff8b2b30bd577175251f5dbc81c9dcd4d64c4cb3c832858"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qt_gantry.ini","label":"LinuxCNC-GANTRY-SIM-qtvcp","category":"qtvcp_screens","display":"qtvcp -d qtaxis","coordinates":"XYZY","kinematics":"trivkins coordinates=XYZY kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":8,"unresolved_count":0,"source_sha256":"0c97b43e267300f8565a601fe578d6239b9c5eee3f2122ccfa4b536faeffb254"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtaxis.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens","display":"qtvcp -v qtaxis","coordinates":"X Y Z","kinematics":"trivkins coordinates=xyz kinstype=B","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":7,"unresolved_count":1,"source_sha256":"51b5cb7c790d2eb07550ed1e5ee77314133ab99628c23e7cbee27eaf3466bd2a"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis_lathe.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens/qtaxis_lathe","display":"qtvcp qtaxis","coordinates":"XYZ","kinematics":"trivkins coordinates=xz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":5,"unresolved_count":1,"source_sha256":"96607f9e45ebb60e6c8c30a3b827f33273159780e31b6e6dcd187e69d9316ee2"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtaxis_mpg.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens","display":"qtvcp -d qtaxis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":7,"unresolved_count":1,"source_sha256":"a7e3781694cca98ef9451e2100fa213380088ebe750eea1935e5db09792a4264"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdefault.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens","display":"qtvcp -d","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":7,"unresolved_count":3,"source_sha256":"64b856e76d997a0096533b198666109c059eea4b02e2ac3f3967cef22667ccb9"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdefault_9axis.ini","label":"LinuxCNC-sim-9axis","category":"qtvcp_screens","display":"qtvcp qt_cnc_9_axis","coordinates":"X Y Z A B C U V W","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":5,"unresolved_count":1,"source_sha256":"ec8344fad2445df3a8822c624dd0aa514e3900ba60879c5443a5d6f7c495f84a"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdefault_gantry.ini","label":"LinuxCNC-GANTRY-SIM-AXIS","category":"qtvcp_screens","display":"qtvcp -d","coordinates":"XYZY","kinematics":"trivkins coordinates=XYZY kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":8,"unresolved_count":0,"source_sha256":"3f1ea1c180d85118c09a821ea03b007fc8901c40685148a77714c76278db185b"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdefault_mm.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens","display":"qtvcp","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":7,"unresolved_count":0,"source_sha256":"a49b1cf91a6fb17c5bbb80eea44b6c46e76ae182e7e3ac67b96b4fab2cfaea88"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon.ini","label":"qtdragon","category":"qtvcp_screens/qtdragon","display":"qtvcp qtdragon","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":2,"source_sha256":"103a9d0f4c329e00d532fcf0f3ef1e90a37f4476b8950a2b52325d8a42bc4b91"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_auto_tool_probe.ini","label":"qtdragon","category":"qtvcp_screens/qtdragon","display":"qtvcp qtdragon","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"86f2c3f594d0c4bc03da44b9b9ad1445782a9290c8024837a77b83a49e3c55de"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_hd.ini","label":"qtdragon","category":"qtvcp_screens/qtdragon","display":"qtvcp -d qtdragon_hd","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":2,"source_sha256":"c2b23e16477e4de6f3cbd6cdbca56f4a0c80f2482648ee48493349326ef9f1f2"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_inch.ini","label":"qtdragon","category":"qtvcp_screens/qtdragon","display":"qtvcp qtdragon","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"c52570c11f2c503a5aa4ac054fe751035a4d95951c8a24d357d544b08674d8cd"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyyz.ini","label":"qtdragon","category":"qtvcp_screens/qtdragon","display":"qtvcp qtdragon","coordinates":"XYYZ","kinematics":"trivkins coordinates=XYYZ kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"8919a7050ba4357c8e663c51a761fe6d78ff6d7da1e820800eb95e3319cefb64"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyz.ini","label":"qtdragon","category":"qtvcp_screens/qtdragon","display":"qtvcp qtdragon","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"416ec9cb44f3c9f301d874b5d7e860d82bd460633902e3bcc9037d262a464e9b"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyza.ini","label":"qtdragon","category":"qtvcp_screens/qtdragon","display":"qtvcp qtdragon","coordinates":"XYZA","kinematics":"trivkins coordinates=XYZA","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"8b72d1ec92b54e2d5dcf333d5638907141340f942e7e1cbfb26be22d8a28e8aa"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyzy.ini","label":"qtdragon","category":"qtvcp_screens/qtdragon","display":"qtvcp qtdragon","coordinates":"XYZY","kinematics":"trivkins coordinates=XYZY kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"a301f964957d63716ac527504ab80d627161ff9d8a57b6b77f4ae59f12798a5c"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyzya.ini","label":"qtdragon","category":"qtvcp_screens/qtdragon","display":"qtvcp qtdragon","coordinates":"XYZYA","kinematics":"trivkins coordinates=XYZYA kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"1f2b5583b7e1d1ef0339f0a05e8bac2a6d503cfbf977127de64738926c8cc161"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtvcp_custom/qtdefault_ngc.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens/qtvcp_custom","display":"qtvcp -m qtdefault_ngc","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":6,"unresolved_count":0,"source_sha256":"142a7c8f7ba86085afd4e331d0deb8030df8e53ea64bfc96a71b049a8dba1096"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/gremlin.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens/qtvcp_experimental","display":"qtvcp -d qtaxis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":6,"unresolved_count":0,"source_sha256":"ea20d3e12b0a800739c060bca467c8745e29e8d318c47bfa64becd3555af6cca"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens/qtvcp_experimental","display":"qtvcp -d qtaxis","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":6,"unresolved_count":0,"source_sha256":"77f1a4a5294dc202d4afc6764a14dc89d8e1174424667c5b72742ae3a0975645"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_ngc.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens/qtvcp_experimental","display":"qtvcp -m qtdefault_ngc","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":6,"unresolved_count":0,"source_sha256":"142a7c8f7ba86085afd4e331d0deb8030df8e53ea64bfc96a71b049a8dba1096"},{"path":"linuxcnc/configs/sim/qtvcp_screens/qtx1mill.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens","display":"qtvcp -d x1mill","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":7,"unresolved_count":1,"source_sha256":"0909d95dd20251475be2a745ea9ff1a9bc11c05b6d4b880be7d4165c2686b40c"},{"path":"linuxcnc/configs/sim/qtvcp_screens/tester.ini","label":"LinuxCNC-HAL-SIM-AXIS","category":"qtvcp_screens","display":"qtvcp -d tester.ui","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":7,"unresolved_count":1,"source_sha256":"74ffaa3444383a097aed37c22d5d6b6ef9d55b49a49a97e5861013d907a4f40d"},{"path":"linuxcnc/configs/sim/tklinuxcnc/ldelta.ini","label":"Delta-robot-with-linear-joints","category":"tklinuxcnc","display":"tklinuxcnc","coordinates":"X Y Z A","kinematics":"lineardeltakins","family":"parallel_delta","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":4,"unresolved_count":0,"source_sha256":"0e23dee0f4df839c028f5bfba95c5941f2f8623ce502d6fdfc90dfdef63d8967"},{"path":"linuxcnc/configs/sim/tklinuxcnc/servo_sim.ini","label":"LinuxCNC-HAL-SERVO-SIM","category":"tklinuxcnc","display":"tklinuxcnc","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"0f8b15328616a4fd5be7561738273a9c04e0c5524423d424257c5ffda73fa25e"},{"path":"linuxcnc/configs/sim/tklinuxcnc/tklinuxcnc.ini","label":"LinuxCNC-HAL-SIM-TkLinuxCNC","category":"tklinuxcnc","display":"tklinuxcnc","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"12f9c72fe2f8ab1ac7d6fcb553c902b4a2df1cecbf3ecc896fa9c0ad7a8f41b3"},{"path":"linuxcnc/configs/sim/tklinuxcnc/tripod.ini","label":"LinuxCNC-TRIPOD-SIM-TkLinuxCNC","category":"tklinuxcnc","display":"tklinuxcnc","coordinates":"X Y Z","kinematics":"tripodkins","family":"parallel_tripod","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"8da7280a981d80e9b7d4b608a357fc87dbb9d83535636794e1ae97d5ebcb8f01"},{"path":"linuxcnc/configs/sim/tklinuxcnc/trivkins/xz.ini","label":"trivkins XZ KINEMATICS_IDENTITY","category":"tklinuxcnc/trivkins","display":null,"coordinates":null,"kinematics":"trivkins coordinates=xz","family":"cartesian","status":"ready","startup_preflight":"static_ready","resource_status":"ready","missing_count":0,"unresolved_count":0,"source_sha256":"07f5257557a540b02781de3a641dd1830a78a4cbb15a9cc68ad8d2c6eae8ec81"},{"path":"linuxcnc/configs/sim/tklinuxcnc/trivkins/xz_both.ini","label":"trivkins XZ KINEMATICS_BOTH","category":"tklinuxcnc/trivkins","display":null,"coordinates":null,"kinematics":"trivkins coordinates=xz kinstype=BOTH","family":"cartesian","status":"ready","startup_preflight":"static_ready","resource_status":"ready","missing_count":0,"unresolved_count":0,"source_sha256":"d75c9e05e2a781d1344b3840ba82adc6d7d8d47f53aa11b04c3b918d20c5faae"},{"path":"linuxcnc/configs/sim/touchy/gladevcp/gladevcp_touchy.ini","label":"LinuxCNC-TOUCHY-GLADEVCP","category":"touchy/gladevcp","display":"touchy","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"e7098eb237c6ad9bed4c240f95d313f6ae3221d322b514509f5a7c34373b6011"},{"path":"linuxcnc/configs/sim/touchy/gladevcp/touchy.ini","label":"LinuxCNC-TOUCHY","category":"touchy/gladevcp","display":"touchy","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"65c7aa3b61d553f8aa9f2d43977329ef89d4b58d088729561a0bf7165b6a68a9"},{"path":"linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy.ini","label":"pyngcgui-touchy demo","category":"touchy/ngcgui","display":"touchy","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"6bd6bc6daa9146eb1c662ead43e69edac26cd8a95121c00371607f4bc5f5be0b"},{"path":"linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy_lathe.ini","label":"pyngcgui-touchy-lathe demo","category":"touchy/ngcgui","display":"touchy","coordinates":"X Z","kinematics":"trivkins coordinates=xyz","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"5985f5a6c3bf70d493c897a45a9f0864d1edc6449018185c5787ccfd9d78749a"},{"path":"linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff.ini","label":"pyngcgui-touchy demo","category":"touchy/ngcgui","display":"touchy","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":5,"unresolved_count":0,"source_sha256":"b27d37a31e597d71ea9065f31d4c5e150ac12fbdef2f2567b74b97cb4cbe651e"},{"path":"linuxcnc/configs/sim/touchy/touchy.ini","label":"LinuxCNC-TOUCHY","category":"touchy","display":"touchy","coordinates":"X Y Z","kinematics":"trivkins","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing","missing_count":3,"unresolved_count":0,"source_sha256":"0624683449cbafe697042c42e2f23fdc9513b02dd56aa8f452e386e496ab4571"},{"path":"linuxcnc/configs/sim/woodpecker/woodpecker.ini","label":"woodpecker","category":"woodpecker","display":"qtvcp woodpecker","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"1948487bf44a5c7d5b32186a6b9f330d55cb61bbab55da4a5834f95439cc0deb"},{"path":"linuxcnc/configs/sim/woodpecker/woodpecker_auto_tool_probe.ini","label":"woodpecker","category":"woodpecker","display":"qtvcp -f woodpecker","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":5,"unresolved_count":4,"source_sha256":"9c30092e3c73099af651616a4a9a003337230419bd029e606c10f2b2a2afdade"},{"path":"linuxcnc/configs/sim/woodpecker/woodpecker_xyz.ini","label":"woodpecker","category":"woodpecker","display":"qtvcp woodpecker","coordinates":"XYZ","kinematics":"trivkins coordinates=XYZ","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"5aeeb95a708ed2972ad3fa975f37df426129de279c4e8d347bcc2a589ac253ce"},{"path":"linuxcnc/configs/sim/woodpecker/woodpecker_xyza.ini","label":"woodpecker","category":"woodpecker","display":"qtvcp woodpecker","coordinates":"XYZA","kinematics":"trivkins coordinates=XYZA","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":1,"source_sha256":"410e1b03a771d7b98a0a75fc13303842af2a20d85b3ff6fe898e83f5a8630752"},{"path":"linuxcnc/configs/sim/woodpecker/woodpecker_xyzab.ini","label":"woodpecker","category":"woodpecker","display":"qtvcp -f woodpecker","coordinates":"XYZAB","kinematics":"trivkins coordinates=XYZAB kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":6,"unresolved_count":4,"source_sha256":"3d4d7e2cb2729c9b385e6e6cee04a70ee933a52dcd7f3cf532b7c236bef06eb9"},{"path":"linuxcnc/configs/sim/woodpecker/woodpecker_xyzy.ini","label":"woodpecker","category":"woodpecker","display":"qtvcp woodpecker","coordinates":"XYZY","kinematics":"trivkins coordinates=XYZY kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":5,"unresolved_count":1,"source_sha256":"8374120e08569413c08816a5a5c9e0e8aa0cd0d5536593f6c0fb6d606cffdac5"},{"path":"linuxcnc/configs/sim/woodpecker/woodpecker_xyzya.ini","label":"woodpecker","category":"woodpecker","display":"qtvcp woodpecker","coordinates":"XYZYA","kinematics":"trivkins coordinates=XYZYA kinstype=BOTH","family":"cartesian","status":"blocked","startup_preflight":"blocked_resource","resource_status":"blocked_missing_and_unresolved","missing_count":5,"unresolved_count":1,"source_sha256":"85a7cca0b4672cdac77822c584e738722656f565af8b48217a3cf1cac17f87ab"}]); +export const SIM_FILE_INDEX = Object.freeze(["linuxcnc/configs/sim/README","linuxcnc/configs/sim/README_es","linuxcnc/configs/sim/axis/.gitignore","linuxcnc/configs/sim/axis/README","linuxcnc/configs/sim/axis/README_es","linuxcnc/configs/sim/axis/anglejog/anglejog.halshow","linuxcnc/configs/sim/axis/anglejog/anglejog.ini","linuxcnc/configs/sim/axis/anglejog/anglejog.txt","linuxcnc/configs/sim/axis/anglejog/anglejog.xml","linuxcnc/configs/sim/axis/anglejog/anglejog_postgui.hal","linuxcnc/configs/sim/axis/axis.ini","linuxcnc/configs/sim/axis/axis_9axis.ini","linuxcnc/configs/sim/axis/axis_mm.ini","linuxcnc/configs/sim/axis/canterp.ini","linuxcnc/configs/sim/axis/canterp_example.can","linuxcnc/configs/sim/axis/classicladder/README","linuxcnc/configs/sim/axis/classicladder/README_es","linuxcnc/configs/sim/axis/classicladder/classicladder.hal","linuxcnc/configs/sim/axis/classicladder/demo_sim_cl.clp","linuxcnc/configs/sim/axis/classicladder/demo_sim_cl.hal","linuxcnc/configs/sim/axis/classicladder/demo_sim_cl.ini","linuxcnc/configs/sim/axis/classicladder/demo_sim_cl.tbl","linuxcnc/configs/sim/axis/cooling.hal","linuxcnc/configs/sim/axis/corexy/3joint_xyz.hal","linuxcnc/configs/sim/axis/corexy/README","linuxcnc/configs/sim/axis/corexy/README_es","linuxcnc/configs/sim/axis/corexy/corexy.halshow","linuxcnc/configs/sim/axis/corexy/corexy_base.inc","linuxcnc/configs/sim/axis/corexy/corexy_by_hal.hal","linuxcnc/configs/sim/axis/corexy/corexy_by_hal.ini","linuxcnc/configs/sim/axis/corexy/corexy_by_hal.txt","linuxcnc/configs/sim/axis/corexy/corexy_by_kins.ini","linuxcnc/configs/sim/axis/corexy/corexy_by_kins.txt","linuxcnc/configs/sim/axis/db_demo/README","linuxcnc/configs/sim/axis/db_demo/base.inc","linuxcnc/configs/sim/axis/db_demo/base.ngc","linuxcnc/configs/sim/axis/db_demo/db.py","linuxcnc/configs/sim/axis/db_demo/db_editor.tcl","linuxcnc/configs/sim/axis/db_demo/db_nonran.ini","linuxcnc/configs/sim/axis/db_demo/db_nonran.py","linuxcnc/configs/sim/axis/db_demo/db_panel.xml","linuxcnc/configs/sim/axis/db_demo/db_postgui.hal","linuxcnc/configs/sim/axis/db_demo/db_ran.ini","linuxcnc/configs/sim/axis/db_demo/db_ran.py","linuxcnc/configs/sim/axis/external_offsets/M111","linuxcnc/configs/sim/axis/external_offsets/README","linuxcnc/configs/sim/axis/external_offsets/README_es","linuxcnc/configs/sim/axis/external_offsets/circles.ngc","linuxcnc/configs/sim/axis/external_offsets/dyn_demo.ngc","linuxcnc/configs/sim/axis/external_offsets/dynamic_offsets.halscope","linuxcnc/configs/sim/axis/external_offsets/dynamic_offsets.ini","linuxcnc/configs/sim/axis/external_offsets/dynamic_offsets.txt","linuxcnc/configs/sim/axis/external_offsets/dynamic_offsets_es.txt","linuxcnc/configs/sim/axis/external_offsets/dynamic_offsets_panel.hal","linuxcnc/configs/sim/axis/external_offsets/dynamic_offsets_panel.xml","linuxcnc/configs/sim/axis/external_offsets/eoffset.tbl","linuxcnc/configs/sim/axis/external_offsets/eoffsets.hal","linuxcnc/configs/sim/axis/external_offsets/eoffsets.ini","linuxcnc/configs/sim/axis/external_offsets/eoffsets.ngc","linuxcnc/configs/sim/axis/external_offsets/eoffsets.txt","linuxcnc/configs/sim/axis/external_offsets/eoffsets_es.txt","linuxcnc/configs/sim/axis/external_offsets/eoffsets_monitor.tcl","linuxcnc/configs/sim/axis/external_offsets/eoffsets_panel.hal","linuxcnc/configs/sim/axis/external_offsets/eoffsets_panel.xml","linuxcnc/configs/sim/axis/external_offsets/jwp_z.ini","linuxcnc/configs/sim/axis/external_offsets/jwp_z.ngc","linuxcnc/configs/sim/axis/external_offsets/jwp_z.txt","linuxcnc/configs/sim/axis/external_offsets/jwp_z_es.txt","linuxcnc/configs/sim/axis/external_offsets/jwp_z_panel.hal","linuxcnc/configs/sim/axis/external_offsets/jwp_z_panel.xml","linuxcnc/configs/sim/axis/external_offsets/opa.hal","linuxcnc/configs/sim/axis/external_offsets/opa.ini","linuxcnc/configs/sim/axis/external_offsets/opa.txt","linuxcnc/configs/sim/axis/external_offsets/opa_demo.ngc","linuxcnc/configs/sim/axis/external_offsets/opa_es.txt","linuxcnc/configs/sim/axis/external_offsets/opa_panel.hal","linuxcnc/configs/sim/axis/external_offsets/opa_panel.xml","linuxcnc/configs/sim/axis/external_offsets/queuebuster.ngc","linuxcnc/configs/sim/axis/extrajoints/12extrajoints.ini","linuxcnc/configs/sim/axis/extrajoints/1extrajoint.hal","linuxcnc/configs/sim/axis/extrajoints/1extrajoint.ini","linuxcnc/configs/sim/axis/extrajoints/1extrajoint.txt","linuxcnc/configs/sim/axis/extrajoints/2extrajoints.hal","linuxcnc/configs/sim/axis/extrajoints/2extrajoints.ini","linuxcnc/configs/sim/axis/extrajoints/2extrajoints.txt","linuxcnc/configs/sim/axis/extrajoints/M144","linuxcnc/configs/sim/axis/extrajoints/README","linuxcnc/configs/sim/axis/extrajoints/README_es","linuxcnc/configs/sim/axis/extrajoints/extrajoints.halshow","linuxcnc/configs/sim/axis/extrajoints/extrajoints.tcl","linuxcnc/configs/sim/axis/foam/axis_foam.ini","linuxcnc/configs/sim/axis/foam/foam.ngc","linuxcnc/configs/sim/axis/gantry/README","linuxcnc/configs/sim/axis/gantry/README_es","linuxcnc/configs/sim/axis/gantry/gantry.ini","linuxcnc/configs/sim/axis/gantry/gantry_jjog.halscope","linuxcnc/configs/sim/axis/gantry/gantry_jjog.ini","linuxcnc/configs/sim/axis/gantry/gantry_jjog.txt","linuxcnc/configs/sim/axis/gantry/gantry_jjog_es.txt","linuxcnc/configs/sim/axis/gantry/gantry_mm.hal","linuxcnc/configs/sim/axis/gantry/gantry_mm.ini","linuxcnc/configs/sim/axis/gantry/gantry_mm.tbl","linuxcnc/configs/sim/axis/gantry/gantry_panel.hal","linuxcnc/configs/sim/axis/gantry/gantry_panel.xml","linuxcnc/configs/sim/axis/geometry/M110","linuxcnc/configs/sim/axis/geometry/README","linuxcnc/configs/sim/axis/geometry/README_es","linuxcnc/configs/sim/axis/geometry/xyzc.ini","linuxcnc/configs/sim/axis/geometry/xyzc.ngc","linuxcnc/configs/sim/axis/geometry/xyzc_origin.ini","linuxcnc/configs/sim/axis/gladevcp/.gitignore","linuxcnc/configs/sim/axis/gladevcp/README","linuxcnc/configs/sim/axis/gladevcp/README_es","linuxcnc/configs/sim/axis/gladevcp/gladevcp_panel.ini","linuxcnc/configs/sim/axis/gladevcp/gladevcp_panel_tester.ini","linuxcnc/configs/sim/axis/gladevcp/gladevcp_panel_tester.txt","linuxcnc/configs/sim/axis/gladevcp/gladevcp_tab.ini","linuxcnc/configs/sim/axis/gladevcp/hitcounter.py","linuxcnc/configs/sim/axis/gladevcp/manual-example.hal","linuxcnc/configs/sim/axis/gladevcp/manual-example.ui","linuxcnc/configs/sim/axis/gladevcp/meter_scale.py","linuxcnc/configs/sim/axis/gladevcp/meter_scale.ui","linuxcnc/configs/sim/axis/gladevcp/probe.hal","linuxcnc/configs/sim/axis/gladevcp/probe.ini","linuxcnc/configs/sim/axis/gladevcp/probe.ngc","linuxcnc/configs/sim/axis/gladevcp/probe.py","linuxcnc/configs/sim/axis/gladevcp/probe.txt","linuxcnc/configs/sim/axis/gladevcp/probe.ui","linuxcnc/configs/sim/axis/gladevcp/probe_es.txt","linuxcnc/configs/sim/axis/gladevcp/probe_gui.sh","linuxcnc/configs/sim/axis/gladevcp/set-param-from-ini.ini","linuxcnc/configs/sim/axis/gladevcp/set-param-from-ini.sh","linuxcnc/configs/sim/axis/gladevcp/set-param-from-ini.txt","linuxcnc/configs/sim/axis/gladevcp/set-param-from-ini_es.txt","linuxcnc/configs/sim/axis/gladevcp/sim.tbl","linuxcnc/configs/sim/axis/gladevcp/test.ui","linuxcnc/configs/sim/axis/gladevcp/test_handler.py","linuxcnc/configs/sim/axis/halui_pyvcp/README","linuxcnc/configs/sim/axis/halui_pyvcp/README_es","linuxcnc/configs/sim/axis/halui_pyvcp/halui.ini","linuxcnc/configs/sim/axis/halui_pyvcp/pyvcp.hal","linuxcnc/configs/sim/axis/halui_pyvcp/sim.tbl","linuxcnc/configs/sim/axis/halui_pyvcp/vcp.xml","linuxcnc/configs/sim/axis/histogram_demo.ini","linuxcnc/configs/sim/axis/histogram_demo.txt","linuxcnc/configs/sim/axis/histogram_demo_es.txt","linuxcnc/configs/sim/axis/historical_lathe.ini","linuxcnc/configs/sim/axis/ini_hal_demo.ini","linuxcnc/configs/sim/axis/ini_hal_demo.txt","linuxcnc/configs/sim/axis/ini_hal_demo_es.txt","linuxcnc/configs/sim/axis/ini_with_includes/.gitignore","linuxcnc/configs/sim/axis/ini_with_includes/README","linuxcnc/configs/sim/axis/ini_with_includes/README_es","linuxcnc/configs/sim/axis/ini_with_includes/axis_x.inc","linuxcnc/configs/sim/axis/ini_with_includes/axis_y.inc","linuxcnc/configs/sim/axis/ini_with_includes/axis_z.inc","linuxcnc/configs/sim/axis/ini_with_includes/display.inc","linuxcnc/configs/sim/axis/ini_with_includes/emc.inc","linuxcnc/configs/sim/axis/ini_with_includes/emcio.inc","linuxcnc/configs/sim/axis/ini_with_includes/emcmot.inc","linuxcnc/configs/sim/axis/ini_with_includes/filter.inc","linuxcnc/configs/sim/axis/ini_with_includes/hal.inc","linuxcnc/configs/sim/axis/ini_with_includes/includes_demo.ini","linuxcnc/configs/sim/axis/ini_with_includes/joint_0.inc","linuxcnc/configs/sim/axis/ini_with_includes/joint_1.inc","linuxcnc/configs/sim/axis/ini_with_includes/joint_2.inc","linuxcnc/configs/sim/axis/ini_with_includes/kins.inc","linuxcnc/configs/sim/axis/ini_with_includes/rs274ngc.inc","linuxcnc/configs/sim/axis/ini_with_includes/sim.tbl","linuxcnc/configs/sim/axis/ini_with_includes/task.inc","linuxcnc/configs/sim/axis/ini_with_includes/traj.inc","linuxcnc/configs/sim/axis/iocontrolv2/README","linuxcnc/configs/sim/axis/iocontrolv2/README_es","linuxcnc/configs/sim/axis/iocontrolv2/axis-iocontrolv2-demo.ini","linuxcnc/configs/sim/axis/iocontrolv2/axis_owordsub_manualtoolchange.hal","linuxcnc/configs/sim/axis/iocontrolv2/g8812.ini","linuxcnc/configs/sim/axis/iocontrolv2/m66track.ini","linuxcnc/configs/sim/axis/iocontrolv2/nstools.tbl","linuxcnc/configs/sim/axis/iocontrolv2/on_abort.ngc","linuxcnc/configs/sim/axis/iocontrolv2/osubdemo-ns.ui","linuxcnc/configs/sim/axis/iocontrolv2/osubdemo.ui","linuxcnc/configs/sim/axis/iocontrolv2/owordm6-ui-ns.ini","linuxcnc/configs/sim/axis/iocontrolv2/owordm6-ui.ini","linuxcnc/configs/sim/axis/iocontrolv2/sim_mm.tbl","linuxcnc/configs/sim/axis/iocontrolv2/sim_mm_test.tbl","linuxcnc/configs/sim/axis/iocontrolv2/t3.ngc","linuxcnc/configs/sim/axis/iocontrolv2/tdemo.ngc","linuxcnc/configs/sim/axis/iocontrolv2/toolchange-demo.ngc","linuxcnc/configs/sim/axis/iocontrolv2/v2-tc.ui","linuxcnc/configs/sim/axis/iocontrolv2/v2_gladevcp_postgui.hal","linuxcnc/configs/sim/axis/iocontrolv2/v2_oword_gladevcp_postgui.hal","linuxcnc/configs/sim/axis/ja_tests/xyzb_locking_indexer/README","linuxcnc/configs/sim/axis/ja_tests/xyzb_locking_indexer/README_es","linuxcnc/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyyzb.ini","linuxcnc/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyzb.hal","linuxcnc/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyzb.halshow","linuxcnc/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyzb.ini","linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/README","linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/README_es","linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/xhc-hb04-postgui.hal","linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/xhc-hb04.inc","linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/xyzx-xhc-hb04.ini","linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/xyzx.halshow","linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/xyzx.ini","linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/xyzx_base.inc","linuxcnc/configs/sim/axis/ja_tests/xyzx_mpg/xyzx_jog.hal","linuxcnc/configs/sim/axis/ja_tests/xz/README","linuxcnc/configs/sim/axis/ja_tests/xz/README_es","linuxcnc/configs/sim/axis/ja_tests/xz/xz.ini","linuxcnc/configs/sim/axis/ja_tests/xz/xz.tbl","linuxcnc/configs/sim/axis/ja_tests/xz/xz_both.ini","linuxcnc/configs/sim/axis/ja_tests/xz/xz_both_auto.ini","linuxcnc/configs/sim/axis/ja_tests/xz/xz_both_auto_cmds.hal","linuxcnc/configs/sim/axis/ja_tests/xz/xz_both_cmds.hal","linuxcnc/configs/sim/axis/ja_tests/xz/xz_cmds.hal","linuxcnc/configs/sim/axis/ja_tests/xz/xzbase.inc","linuxcnc/configs/sim/axis/laser/laser.hal","linuxcnc/configs/sim/axis/laser/laser.ini","linuxcnc/configs/sim/axis/laser/postgui.hal","linuxcnc/configs/sim/axis/laser/python/remap.py","linuxcnc/configs/sim/axis/laser/python/toplevel.py","linuxcnc/configs/sim/axis/laser/pyvcp.xml","linuxcnc/configs/sim/axis/laser/raster_test.ngc","linuxcnc/configs/sim/axis/laser/vector_test.ngc","linuxcnc/configs/sim/axis/laser/vector_test2.ngc","linuxcnc/configs/sim/axis/lathe-fanucy/README","linuxcnc/configs/sim/axis/lathe-fanucy/README_es","linuxcnc/configs/sim/axis/lathe-fanucy/lathe-fanucy.ini","linuxcnc/configs/sim/axis/lathe-fanucy/lathe-fanucy.tbl","linuxcnc/configs/sim/axis/lathe-fanucy/remap.py","linuxcnc/configs/sim/axis/lathe-fanucy/toolchange.ngc","linuxcnc/configs/sim/axis/lathe-fanucy/toplevel.py","linuxcnc/configs/sim/axis/lathe.ini","linuxcnc/configs/sim/axis/lathe.tbl","linuxcnc/configs/sim/axis/lathe.xml","linuxcnc/configs/sim/axis/lathe_multispindle/README","linuxcnc/configs/sim/axis/lathe_multispindle/README_es","linuxcnc/configs/sim/axis/lathe_multispindle/core_sim.hal","linuxcnc/configs/sim/axis/lathe_multispindle/lathe.hal","linuxcnc/configs/sim/axis/lathe_multispindle/lathe.ini","linuxcnc/configs/sim/axis/lathe_multispindle/lathe.xml","linuxcnc/configs/sim/axis/lathe_multispindle/lathe_postgui.hal","linuxcnc/configs/sim/axis/lathe_postgui.hal","linuxcnc/configs/sim/axis/ldelta.ini","linuxcnc/configs/sim/axis/ldelta_demo.ini","linuxcnc/configs/sim/axis/ldelta_demo.txt","linuxcnc/configs/sim/axis/ldelta_demo_es.txt","linuxcnc/configs/sim/axis/minimal_xyz.ini","linuxcnc/configs/sim/axis/minimal_xyz_cmds.hal","linuxcnc/configs/sim/axis/moveoff/1_onpause_local.ini","linuxcnc/configs/sim/axis/moveoff/1_onpause_local.txt","linuxcnc/configs/sim/axis/moveoff/1_onpause_local_es.txt","linuxcnc/configs/sim/axis/moveoff/2_onpause_external.ini","linuxcnc/configs/sim/axis/moveoff/2_onpause_external.txt","linuxcnc/configs/sim/axis/moveoff/2_onpause_external_es.txt","linuxcnc/configs/sim/axis/moveoff/3_always_local.ini","linuxcnc/configs/sim/axis/moveoff/3_always_local.txt","linuxcnc/configs/sim/axis/moveoff/3_always_local_es.txt","linuxcnc/configs/sim/axis/moveoff/4_always_external.ini","linuxcnc/configs/sim/axis/moveoff/4_always_external.txt","linuxcnc/configs/sim/axis/moveoff/4_always_external_es.tx","linuxcnc/configs/sim/axis/moveoff/5_no_gui.ini","linuxcnc/configs/sim/axis/moveoff/5_no_gui.txt","linuxcnc/configs/sim/axis/moveoff/5_no_gui_es.txt","linuxcnc/configs/sim/axis/moveoff/6_zretract.ini","linuxcnc/configs/sim/axis/moveoff/6_zretract.txt","linuxcnc/configs/sim/axis/moveoff/6_zretract_es.txt","linuxcnc/configs/sim/axis/moveoff/7_pyvcp.ini","linuxcnc/configs/sim/axis/moveoff/7_pyvcp.txt","linuxcnc/configs/sim/axis/moveoff/7_pyvcp_es.txt","linuxcnc/configs/sim/axis/moveoff/8_gladevcp.ini","linuxcnc/configs/sim/axis/moveoff/8_gladevcp.txt","linuxcnc/configs/sim/axis/moveoff/8_gladevcp_es.txt","linuxcnc/configs/sim/axis/moveoff/README","linuxcnc/configs/sim/axis/moveoff/README_es","linuxcnc/configs/sim/axis/moveoff/moveoff.hal","linuxcnc/configs/sim/axis/moveoff/moveoff.halscope","linuxcnc/configs/sim/axis/moveoff/moveoff.halshow","linuxcnc/configs/sim/axis/moveoff/moveoff_base.inc","linuxcnc/configs/sim/axis/moveoff/moveoff_display.inc","linuxcnc/configs/sim/axis/moveoff/moveoff_display_6.hal","linuxcnc/configs/sim/axis/moveoff/moveoff_display_6.inc","linuxcnc/configs/sim/axis/moveoff/moveoff_display_6.xml","linuxcnc/configs/sim/axis/moveoff/moveoff_display_7.hal","linuxcnc/configs/sim/axis/moveoff/moveoff_display_7.inc","linuxcnc/configs/sim/axis/moveoff/moveoff_display_7.xml","linuxcnc/configs/sim/axis/moveoff/moveoff_display_8.hal","linuxcnc/configs/sim/axis/moveoff/moveoff_display_8.inc","linuxcnc/configs/sim/axis/moveoff/moveoff_gladevcp_8.ui","linuxcnc/configs/sim/axis/moveoff/moveoff_settings.inc","linuxcnc/configs/sim/axis/moveoff/removeshort.hal","linuxcnc/configs/sim/axis/moveoff/sim.tbl","linuxcnc/configs/sim/axis/ngcgui/README","linuxcnc/configs/sim/axis/ngcgui/README_es","linuxcnc/configs/sim/axis/ngcgui/axis_resize.py","linuxcnc/configs/sim/axis/ngcgui/fullscreen.py","linuxcnc/configs/sim/axis/ngcgui/gremlin_view.ui","linuxcnc/configs/sim/axis/ngcgui/lathe.tbl","linuxcnc/configs/sim/axis/ngcgui/ngcgui.ini","linuxcnc/configs/sim/axis/ngcgui/ngcgui.txt","linuxcnc/configs/sim/axis/ngcgui/ngcgui_es.txt","linuxcnc/configs/sim/axis/ngcgui/ngcgui_gcmc.ini","linuxcnc/configs/sim/axis/ngcgui/ngcgui_gcmc.txt","linuxcnc/configs/sim/axis/ngcgui/ngcgui_gcmc_es.txt","linuxcnc/configs/sim/axis/ngcgui/ngcgui_lathe.ini","linuxcnc/configs/sim/axis/ngcgui/ngcgui_lathe.txt","linuxcnc/configs/sim/axis/ngcgui/ngcgui_lathe_es.txt","linuxcnc/configs/sim/axis/ngcgui/ngcgui_simple.ini","linuxcnc/configs/sim/axis/ngcgui/ngcgui_simple.txt","linuxcnc/configs/sim/axis/ngcgui/ngcgui_simple_es.txt","linuxcnc/configs/sim/axis/ngcgui/pyngcgui_axis.ini","linuxcnc/configs/sim/axis/ngcgui/pyngcgui_axis.txt","linuxcnc/configs/sim/axis/ngcgui/pyngcgui_axis.ui","linuxcnc/configs/sim/axis/ngcgui/pyngcgui_axis_es.txt","linuxcnc/configs/sim/axis/ngcgui/pyngcgui_popupkeyboard.ui","linuxcnc/configs/sim/axis/ngcgui/sim.tbl","linuxcnc/configs/sim/axis/orphans/README","linuxcnc/configs/sim/axis/orphans/README_es","linuxcnc/configs/sim/axis/orphans/acc_test.ini","linuxcnc/configs/sim/axis/orphans/axis_noio.ini","linuxcnc/configs/sim/axis/orphans/core_sim_noio.hal","linuxcnc/configs/sim/axis/orphans/core_sim_noiocontrol.hal","linuxcnc/configs/sim/axis/orphans/core_sim_test.hal","linuxcnc/configs/sim/axis/orphans/gladevcp_postgui.hal","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/core_sim_test.hal","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/gladevcp.hal","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/iocontrol-removed.ini","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/nc_files/tcdemo.ngc","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/no-iotask.nml","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/python/customtask.py","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/python/embedding.py","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/python/nulluserfuncs.py","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/python/oword.py","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/python/remap.py","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/python/sqltoolaccess.py","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/python/task.py","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/python/tooltable.py","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/python/toplevel.py","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/python/userfuncs.py","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/racktoolchange-noioctl.glade","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/racktoolchange-noioctl.ui","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/racktoolchange.hal","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/tooltable.sql","linuxcnc/configs/sim/axis/orphans/iocontrol-removed/tooltable.sqlite","linuxcnc/configs/sim/axis/orphans/iov2.hal","linuxcnc/configs/sim/axis/orphans/medium.ini","linuxcnc/configs/sim/axis/orphans/no-iotask.nml","linuxcnc/configs/sim/axis/orphans/py.ini.notworking","linuxcnc/configs/sim/axis/orphans/pyiocontrol.ini.notworking","linuxcnc/configs/sim/axis/orphans/pysubs/customtask.py","linuxcnc/configs/sim/axis/orphans/pysubs/nulluserfuncs.py","linuxcnc/configs/sim/axis/orphans/pysubs/oword.py","linuxcnc/configs/sim/axis/orphans/pysubs/plugins.py","linuxcnc/configs/sim/axis/orphans/pysubs/remap.py","linuxcnc/configs/sim/axis/orphans/pysubs/sqltoolaccess.py","linuxcnc/configs/sim/axis/orphans/pysubs/task.py","linuxcnc/configs/sim/axis/orphans/pysubs/tooltable.py","linuxcnc/configs/sim/axis/orphans/pysubs/userfuncs.py","linuxcnc/configs/sim/axis/orphans/sim_mm.tbl","linuxcnc/configs/sim/axis/orphans/taskcall.ngc","linuxcnc/configs/sim/axis/panelui-demo/README","linuxcnc/configs/sim/axis/panelui-demo/README_es","linuxcnc/configs/sim/axis/panelui-demo/_panelui.ini","linuxcnc/configs/sim/axis/panelui-demo/custom.hal","linuxcnc/configs/sim/axis/panelui-demo/custom_postgui.hal","linuxcnc/configs/sim/axis/panelui-demo/panel.glade","linuxcnc/configs/sim/axis/panelui-demo/panelui-demo.hal","linuxcnc/configs/sim/axis/panelui-demo/panelui-demo.ini","linuxcnc/configs/sim/axis/panelui-demo/panelui_handler.py","linuxcnc/configs/sim/axis/panelui-demo/sim_hardware.hal","linuxcnc/configs/sim/axis/panelui-demo/tool.tbl","linuxcnc/configs/sim/axis/pentapod/README","linuxcnc/configs/sim/axis/pentapod/README_es","linuxcnc/configs/sim/axis/pentapod/kinematics.hal","linuxcnc/configs/sim/axis/pentapod/panel.xml","linuxcnc/configs/sim/axis/pentapod/pentapod.ini","linuxcnc/configs/sim/axis/pentapod/pentapod_postgui.hal","linuxcnc/configs/sim/axis/pentapod/tool.tbl","linuxcnc/configs/sim/axis/plasma/README","linuxcnc/configs/sim/axis/plasma/custom.hal","linuxcnc/configs/sim/axis/plasma/customizing.html","linuxcnc/configs/sim/axis/plasma/imperial.ini","linuxcnc/configs/sim/axis/plasma/imperial.prefs","linuxcnc/configs/sim/axis/plasma/imperial_material.cfg","linuxcnc/configs/sim/axis/plasma/imperial_tool.tbl","linuxcnc/configs/sim/axis/plasma/metric.ini","linuxcnc/configs/sim/axis/plasma/metric.prefs","linuxcnc/configs/sim/axis/plasma/metric_material.cfg","linuxcnc/configs/sim/axis/plasma/metric_tool.tbl","linuxcnc/configs/sim/axis/plasma/plasmac2/M190","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_block.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_bolt.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_circle.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_ellipse.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_gusset.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_line.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_polygon.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_rectangle.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_sector.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_settings.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_slot.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_star.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conv_triangle.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/conversational.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/custom/user_commands.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/custom/user_hal.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/custom/user_periodic.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/block.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/boltcircle.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/chips_plasma.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/circle.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/closer.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/e.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/ellipse.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/gusset.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/line.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/n.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/ne.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/nw.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/polygon.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/rectangle.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/s.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/save.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/se.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/sector.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/slot.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/star.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/sw.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/triangle.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/view_p.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/view_t.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/view_z.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/images/w.png","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/keyboard.onboard","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/keyboard.svg","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/numpad.onboard","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/numpad.svg","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/sim/sim_no_stepgen.tcl","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/sim/sim_panel.py","linuxcnc/configs/sim/axis/plasma/plasmac2/lib/sim/sim_stepgen.tcl","linuxcnc/configs/sim/axis/plasma/plasmac2/migrate.py","linuxcnc/configs/sim/axis/plasma/plasmac2/plasmac2.py","linuxcnc/configs/sim/axis/plasma/plasmac2/versions.html","linuxcnc/configs/sim/axis/plasma/user_commands.py","linuxcnc/configs/sim/axis/plasma/user_hal.py","linuxcnc/configs/sim/axis/plasma/user_periodic.py","linuxcnc/configs/sim/axis/postgui_calib_helper.hal","linuxcnc/configs/sim/axis/profile_axis.ini","linuxcnc/configs/sim/axis/qtvcp/.gitignore","linuxcnc/configs/sim/axis/qtvcp/qtvcp_tab.ini","linuxcnc/configs/sim/axis/qtvcp/qtvismach_tab.ini","linuxcnc/configs/sim/axis/qtvcp/sim.tbl","linuxcnc/configs/sim/axis/random_tc.ini","linuxcnc/configs/sim/axis/rdelta.ini","linuxcnc/configs/sim/axis/remap/README","linuxcnc/configs/sim/axis/remap/README_es","linuxcnc/configs/sim/axis/remap/cycle/README","linuxcnc/configs/sim/axis/remap/cycle/README_es","linuxcnc/configs/sim/axis/remap/cycle/cycle.ini","linuxcnc/configs/sim/axis/remap/cycle/nc_files/examples.ngc","linuxcnc/configs/sim/axis/remap/cycle/nc_subroutines/g843.ngc","linuxcnc/configs/sim/axis/remap/cycle/python/remap.py","linuxcnc/configs/sim/axis/remap/cycle/python/toplevel.py","linuxcnc/configs/sim/axis/remap/cycle/tool.tbl","linuxcnc/configs/sim/axis/remap/extend-builtins/README","linuxcnc/configs/sim/axis/remap/extend-builtins/README_es","linuxcnc/configs/sim/axis/remap/extend-builtins/extend-builtins.ini","linuxcnc/configs/sim/axis/remap/extend-builtins/gladevcp.hal","linuxcnc/configs/sim/axis/remap/extend-builtins/nc_files/examples.ngc","linuxcnc/configs/sim/axis/remap/extend-builtins/nc_subroutines/change.ngc","linuxcnc/configs/sim/axis/remap/extend-builtins/nc_subroutines/extend_m0.ngc","linuxcnc/configs/sim/axis/remap/extend-builtins/nc_subroutines/extend_m1.ngc","linuxcnc/configs/sim/axis/remap/extend-builtins/nc_subroutines/extend_m60.ngc","linuxcnc/configs/sim/axis/remap/extend-builtins/nc_subroutines/prepare.ngc","linuxcnc/configs/sim/axis/remap/extend-builtins/nc_subroutines/setfeed.ngc","linuxcnc/configs/sim/axis/remap/extend-builtins/nc_subroutines/setspeed.ngc","linuxcnc/configs/sim/axis/remap/extend-builtins/nc_subroutines/settool.ngc","linuxcnc/configs/sim/axis/remap/extend-builtins/python/remap.py","linuxcnc/configs/sim/axis/remap/extend-builtins/python/toplevel.py","linuxcnc/configs/sim/axis/remap/extend-builtins/show.ui","linuxcnc/configs/sim/axis/remap/extend-builtins/tool.tbl","linuxcnc/configs/sim/axis/remap/getting-started/demo.ini","linuxcnc/configs/sim/axis/remap/getting-started/nc_files/examples.ngc","linuxcnc/configs/sim/axis/remap/getting-started/nc_subroutines/change_min.ngc","linuxcnc/configs/sim/axis/remap/getting-started/nc_subroutines/m400.ngc","linuxcnc/configs/sim/axis/remap/getting-started/nc_subroutines/m410.ngc","linuxcnc/configs/sim/axis/remap/getting-started/nc_subroutines/prepare_min.ngc","linuxcnc/configs/sim/axis/remap/getting-started/python/oword.py","linuxcnc/configs/sim/axis/remap/getting-started/python/remap.py","linuxcnc/configs/sim/axis/remap/getting-started/python/toplevel.py","linuxcnc/configs/sim/axis/remap/getting-started/python/util.py","linuxcnc/configs/sim/axis/remap/getting-started/tool.tbl","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/README","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/README_es","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/gladevcp.hal","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/manualtoolchange.glade","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/manualtoolchange.hal","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/manualtoolchange.ini","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/manualtoolchange.ui","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/nc_files/tcdemo.ngc","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/nc_subroutines/manual_change.ngc","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/nc_subroutines/on_abort.ngc","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/nc_subroutines/restore.ngc","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/python/gladevcp-handler.py","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/python/remap.py","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/python/toplevel.py","linuxcnc/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/tool.tbl","linuxcnc/configs/sim/axis/remap/rack-toolchange/README","linuxcnc/configs/sim/axis/remap/rack-toolchange/README_es","linuxcnc/configs/sim/axis/remap/rack-toolchange/gladevcp.hal","linuxcnc/configs/sim/axis/remap/rack-toolchange/nc_files/tcdemo.ngc","linuxcnc/configs/sim/axis/remap/rack-toolchange/nc_subroutines/on_abort.ngc","linuxcnc/configs/sim/axis/remap/rack-toolchange/nc_subroutines/rack_change.ngc","linuxcnc/configs/sim/axis/remap/rack-toolchange/nc_subroutines/tool_getput_move.ngc","linuxcnc/configs/sim/axis/remap/rack-toolchange/nc_subroutines/tool_holder_clear_move.ngc","linuxcnc/configs/sim/axis/remap/rack-toolchange/python/remap.py","linuxcnc/configs/sim/axis/remap/rack-toolchange/python/toplevel.py","linuxcnc/configs/sim/axis/remap/rack-toolchange/racktoolchange.glade","linuxcnc/configs/sim/axis/remap/rack-toolchange/racktoolchange.hal","linuxcnc/configs/sim/axis/remap/rack-toolchange/racktoolchange.ini","linuxcnc/configs/sim/axis/remap/rack-toolchange/racktoolchange.ui","linuxcnc/configs/sim/axis/remap/rack-toolchange/tool.tbl","linuxcnc/configs/sim/axis/remap/stop-lookahead/README","linuxcnc/configs/sim/axis/remap/stop-lookahead/README_es","linuxcnc/configs/sim/axis/remap/stop-lookahead/demo.ini","linuxcnc/configs/sim/axis/remap/stop-lookahead/nc_files/examples.ngc","linuxcnc/configs/sim/axis/remap/stop-lookahead/python/remap.py","linuxcnc/configs/sim/axis/remap/stop-lookahead/python/toplevel.py","linuxcnc/configs/sim/axis/remap/stop-lookahead/tool.tbl","linuxcnc/configs/sim/axis/remap/tool.tbl","linuxcnc/configs/sim/axis/rose_engine/README","linuxcnc/configs/sim/axis/rose_engine/README_es","linuxcnc/configs/sim/axis/rose_engine/rcone.ngc","linuxcnc/configs/sim/axis/rose_engine/rcone_demo.ngc","linuxcnc/configs/sim/axis/rose_engine/rose_engine.halshow","linuxcnc/configs/sim/axis/rose_engine/rose_engine.ini","linuxcnc/configs/sim/axis/rotate/rotatekins.hal","linuxcnc/configs/sim/axis/rotate/rotatekins.ini","linuxcnc/configs/sim/axis/sim.tbl","linuxcnc/configs/sim/axis/sim_mm.tbl","linuxcnc/configs/sim/axis/simpockets.tbl","linuxcnc/configs/sim/axis/simtcl/README","linuxcnc/configs/sim/axis/simtcl/README_es","linuxcnc/configs/sim/axis/simtcl/sim.tbl","linuxcnc/configs/sim/axis/simtcl/twopass_base.inc","linuxcnc/configs/sim/axis/simtcl/twopass_basic.ini","linuxcnc/configs/sim/axis/simtcl/twopass_basic.txt","linuxcnc/configs/sim/axis/simtcl/twopass_basic_es.txt","linuxcnc/configs/sim/axis/simtcl/twopass_compat.ini","linuxcnc/configs/sim/axis/simtcl/twopass_compat.txt","linuxcnc/configs/sim/axis/simtcl/twopass_compat_es.txt","linuxcnc/configs/sim/axis/spindle_orient/README","linuxcnc/configs/sim/axis/spindle_orient/README_es","linuxcnc/configs/sim/axis/spindle_orient/orient.hal","linuxcnc/configs/sim/axis/spindle_orient/orient.ini","linuxcnc/configs/sim/axis/spindle_orient/orient.ui","linuxcnc/configs/sim/axis/spindle_orient/sim.tbl","linuxcnc/configs/sim/axis/twopass/README","linuxcnc/configs/sim/axis/twopass/README_es","linuxcnc/configs/sim/axis/twopass/load_for_postgui.hal","linuxcnc/configs/sim/axis/twopass/postgui.hal","linuxcnc/configs/sim/axis/twopass/sim.tbl","linuxcnc/configs/sim/axis/twopass/twopass.ini","linuxcnc/configs/sim/axis/twopass/twopass.txt","linuxcnc/configs/sim/axis/twopass/twopass_excluded.hal","linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial","linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.hal","linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini","linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/3axis-tutorial","linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/3axis-tutorial.hal","linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/3axis-tutorial.ini","linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/README","linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/README_es","linuxcnc/configs/sim/axis/vismach/3axis-tutorial/README","linuxcnc/configs/sim/axis/vismach/3axis-tutorial/README_es","linuxcnc/configs/sim/axis/vismach/3axis-tutorial/tool.tbl","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/5axis.ini","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/5axis.tbl","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/5axis.xml","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/5axis_postgui.hal","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/5axisgui.hal","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/5axisgui.ngc","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/README","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/README_es","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/remap_subs/428remap.ngc","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/remap_subs/429remap.ngc","linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/remap_subs/430remap.ngc","linuxcnc/configs/sim/axis/vismach/5axis/max5/README","linuxcnc/configs/sim/axis/vismach/5axis/max5/README_es","linuxcnc/configs/sim/axis/vismach/5axis/max5/max5.tbl","linuxcnc/configs/sim/axis/vismach/5axis/max5/max5_base.inc","linuxcnc/configs/sim/axis/vismach/5axis/max5/max5kins.hal","linuxcnc/configs/sim/axis/vismach/5axis/max5/max5kins.ini","linuxcnc/configs/sim/axis/vismach/5axis/max5/max5triv.hal","linuxcnc/configs/sim/axis/vismach/5axis/max5/max5triv.ini","linuxcnc/configs/sim/axis/vismach/5axis/table-dual-rotary/README","linuxcnc/configs/sim/axis/vismach/5axis/table-dual-rotary/demos/xyzab-tdr-demo.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-dual-rotary/remap_subs/428remap.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-dual-rotary/remap_subs/429remap.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr-postgui.hal","linuxcnc/configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.ini","linuxcnc/configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.tbl","linuxcnc/configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.xml","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/README","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/README_es","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_2.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_3.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/centering.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_ac.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_bc.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/xyzac_switchkins_sub.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/xyzbc_switchkins_sub.ngc","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins.halshow","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins_postgui.hal","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.tbl","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.txt","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.xml","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.tbl","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.txt","linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.xml","linuxcnc/configs/sim/axis/vismach/README","linuxcnc/configs/sim/axis/vismach/README_es","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/README","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/README_es","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/arm.stl","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/base.stl","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/carousel.stl","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/head.stl","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/remap.py","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/saddle.stl","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/sim_vmc.hal","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/spindle.hal","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/table.stl","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/toolchange.ngc","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/toolchange_gray.hal","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/toolchange_index.hal","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/toplevel.py","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/vmc.hal","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/vmc.tbl","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/vmc_graycode.ini","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/vmc_index.ini","linuxcnc/configs/sim/axis/vismach/VMC_toolchange/vmcgui","linuxcnc/configs/sim/axis/vismach/hbm/hbm.hal","linuxcnc/configs/sim/axis/vismach/hbm/hbm.ini","linuxcnc/configs/sim/axis/vismach/hbm/hbm.tbl","linuxcnc/configs/sim/axis/vismach/hexapod-sim/README","linuxcnc/configs/sim/axis/vismach/hexapod-sim/README_es","linuxcnc/configs/sim/axis/vismach/hexapod-sim/hexagui.halshow","linuxcnc/configs/sim/axis/vismach/hexapod-sim/hexapod.ini","linuxcnc/configs/sim/axis/vismach/hexapod-sim/hexapod.xml","linuxcnc/configs/sim/axis/vismach/hexapod-sim/hexapod_postgui.hal","linuxcnc/configs/sim/axis/vismach/hexapod-sim/kinematics.hal","linuxcnc/configs/sim/axis/vismach/hexapod-sim/remap_subs/428remap.ngc","linuxcnc/configs/sim/axis/vismach/hexapod-sim/remap_subs/429remap.ngc","linuxcnc/configs/sim/axis/vismach/hexapod-sim/remap_subs/430remap.ngc","linuxcnc/configs/sim/axis/vismach/melfa-sim/README","linuxcnc/configs/sim/axis/vismach/melfa-sim/example.ngc","linuxcnc/configs/sim/axis/vismach/melfa-sim/link1.stl","linuxcnc/configs/sim/axis/vismach/melfa-sim/link2.stl","linuxcnc/configs/sim/axis/vismach/melfa-sim/link3.stl","linuxcnc/configs/sim/axis/vismach/melfa-sim/link4.stl","linuxcnc/configs/sim/axis/vismach/melfa-sim/link5.stl","linuxcnc/configs/sim/axis/vismach/melfa-sim/link6.stl","linuxcnc/configs/sim/axis/vismach/melfa-sim/link7.stl","linuxcnc/configs/sim/axis/vismach/melfa-sim/melfa-postgui.hal","linuxcnc/configs/sim/axis/vismach/melfa-sim/melfa.ini","linuxcnc/configs/sim/axis/vismach/melfa-sim/melfa.tbl","linuxcnc/configs/sim/axis/vismach/melfa-sim/melfa.txt","linuxcnc/configs/sim/axis/vismach/melfa-sim/melfa.xml","linuxcnc/configs/sim/axis/vismach/melfa-sim/melfa_dh.hal","linuxcnc/configs/sim/axis/vismach/melfa-sim/remap_subs/428remap.ngc","linuxcnc/configs/sim/axis/vismach/melfa-sim/remap_subs/429remap.ngc","linuxcnc/configs/sim/axis/vismach/melfa-sim/remap_subs/430remap.ngc","linuxcnc/configs/sim/axis/vismach/millturn/README","linuxcnc/configs/sim/axis/vismach/millturn/example.ngc","linuxcnc/configs/sim/axis/vismach/millturn/mcodes/M128","linuxcnc/configs/sim/axis/vismach/millturn/mcodes/M129","linuxcnc/configs/sim/axis/vismach/millturn/millturn-postgui.hal","linuxcnc/configs/sim/axis/vismach/millturn/millturn.hal","linuxcnc/configs/sim/axis/vismach/millturn/millturn.halshow","linuxcnc/configs/sim/axis/vismach/millturn/millturn.ini","linuxcnc/configs/sim/axis/vismach/millturn/millturn.tbl","linuxcnc/configs/sim/axis/vismach/millturn/millturn.txt","linuxcnc/configs/sim/axis/vismach/millturn/millturn.xml","linuxcnc/configs/sim/axis/vismach/millturn/remap_subs/428remap.ngc","linuxcnc/configs/sim/axis/vismach/millturn/remap_subs/429remap.ngc","linuxcnc/configs/sim/axis/vismach/puma/README","linuxcnc/configs/sim/axis/vismach/puma/README_es","linuxcnc/configs/sim/axis/vismach/puma/mcodes/M128","linuxcnc/configs/sim/axis/vismach/puma/mcodes/M129","linuxcnc/configs/sim/axis/vismach/puma/mcodes/M130","linuxcnc/configs/sim/axis/vismach/puma/puma.ini","linuxcnc/configs/sim/axis/vismach/puma/puma.tbl","linuxcnc/configs/sim/axis/vismach/puma/puma.xml","linuxcnc/configs/sim/axis/vismach/puma/puma560.halshow","linuxcnc/configs/sim/axis/vismach/puma/puma560.ini","linuxcnc/configs/sim/axis/vismach/puma/puma560.txt","linuxcnc/configs/sim/axis/vismach/puma/puma560.xml","linuxcnc/configs/sim/axis/vismach/puma/puma560_dh.hal","linuxcnc/configs/sim/axis/vismach/puma/puma560_postgui.hal","linuxcnc/configs/sim/axis/vismach/puma/puma560_uvw.ini","linuxcnc/configs/sim/axis/vismach/puma/puma_cube.ini","linuxcnc/configs/sim/axis/vismach/puma/puma_cube.ngc","linuxcnc/configs/sim/axis/vismach/puma/puma_cube.txt","linuxcnc/configs/sim/axis/vismach/puma/puma_dh.hal","linuxcnc/configs/sim/axis/vismach/puma/puma_link1.obj","linuxcnc/configs/sim/axis/vismach/puma/puma_link2.obj","linuxcnc/configs/sim/axis/vismach/puma/puma_link3.obj","linuxcnc/configs/sim/axis/vismach/puma/puma_link4.obj","linuxcnc/configs/sim/axis/vismach/puma/puma_link5.obj","linuxcnc/configs/sim/axis/vismach/puma/puma_link6.obj","linuxcnc/configs/sim/axis/vismach/puma/puma_link7.obj","linuxcnc/configs/sim/axis/vismach/puma/puma_postgui.hal","linuxcnc/configs/sim/axis/vismach/puma/puma_seam_weld.ngc","linuxcnc/configs/sim/axis/vismach/puma/puma_text.obj","linuxcnc/configs/sim/axis/vismach/puma/remap_subs/428remap.ngc","linuxcnc/configs/sim/axis/vismach/puma/remap_subs/429remap.ngc","linuxcnc/configs/sim/axis/vismach/puma/remap_subs/430remap.ngc","linuxcnc/configs/sim/axis/vismach/rolfmill/README","linuxcnc/configs/sim/axis/vismach/rolfmill/README_es","linuxcnc/configs/sim/axis/vismach/rolfmill/rolfmill","linuxcnc/configs/sim/axis/vismach/rolfmill/rolfmill.hal","linuxcnc/configs/sim/axis/vismach/rolfmill/rolfmill.ini","linuxcnc/configs/sim/axis/vismach/rolfmill/tool.tbl","linuxcnc/configs/sim/axis/vismach/scara/README","linuxcnc/configs/sim/axis/vismach/scara/README_es","linuxcnc/configs/sim/axis/vismach/scara/remap_subs/428remap.ngc","linuxcnc/configs/sim/axis/vismach/scara/remap_subs/429remap.ngc","linuxcnc/configs/sim/axis/vismach/scara/remap_subs/430remap.ngc","linuxcnc/configs/sim/axis/vismach/scara/scara.ini","linuxcnc/configs/sim/axis/vismach/scara/scara.xml","linuxcnc/configs/sim/axis/vismach/scara/scara_postgui.hal","linuxcnc/configs/sim/axis/vismach/scorbot/scorbot.hal","linuxcnc/configs/sim/axis/vismach/scorbot/scorbot.ini","linuxcnc/configs/sim/axis/wrapped_rotary/README","linuxcnc/configs/sim/axis/wrapped_rotary/README_es","linuxcnc/configs/sim/axis/wrapped_rotary/wrapped_rotary.hal","linuxcnc/configs/sim/axis/wrapped_rotary/wrapped_rotary.ini","linuxcnc/configs/sim/axis/wrapped_rotary/wrapped_rotary.tbl","linuxcnc/configs/sim/axis/xhc-hb04/README","linuxcnc/configs/sim/axis/xhc-hb04/README_es","linuxcnc/configs/sim/axis/xhc-hb04/inch_base.inc","linuxcnc/configs/sim/axis/xhc-hb04/inch_trivkins.inc","linuxcnc/configs/sim/axis/xhc-hb04/layout1.inc","linuxcnc/configs/sim/axis/xhc-hb04/layout2.inc","linuxcnc/configs/sim/axis/xhc-hb04/mm_base.inc","linuxcnc/configs/sim/axis/xhc-hb04/mm_trivkins.inc","linuxcnc/configs/sim/axis/xhc-hb04/sim.tbl","linuxcnc/configs/sim/axis/xhc-hb04/sim_mm.tbl","linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout1.ini","linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout1.txt","linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout1_es.txt","linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout2.ini","linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout2.txt","linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout2_es.txt","linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout2_mm.ini","linuxcnc/configs/sim/axis/xhc-hb04/xhc-hb04-layout2_mm.txt","linuxcnc/configs/sim/craftsman/ConfigParser_New.py","linuxcnc/configs/sim/craftsman/README","linuxcnc/configs/sim/craftsman/cm_axis_panel.glade","linuxcnc/configs/sim/craftsman/cm_axis_panel.hal","linuxcnc/configs/sim/craftsman/cm_axis_panel.py","linuxcnc/configs/sim/craftsman/cnc_settings.ini","linuxcnc/configs/sim/craftsman/craftsman_icon.png","linuxcnc/configs/sim/craftsman/craftsman_router_icon.png","linuxcnc/configs/sim/craftsman/craftsman_spindle.hal","linuxcnc/configs/sim/craftsman/craftsman_toolchange","linuxcnc/configs/sim/craftsman/craftsman_toolchange.hal","linuxcnc/configs/sim/craftsman/craftsmancnc","linuxcnc/configs/sim/craftsman/craftsmancnc-axis.ini","linuxcnc/configs/sim/craftsman/craftsmancnc.glade","linuxcnc/configs/sim/craftsman/craftsmancnc.hal","linuxcnc/configs/sim/craftsman/craftsmancnc.ini","linuxcnc/configs/sim/craftsman/easygui.py","linuxcnc/configs/sim/craftsman/estimate_time.py","linuxcnc/configs/sim/craftsman/extents.dat","linuxcnc/configs/sim/craftsman/globals.py","linuxcnc/configs/sim/craftsman/history.dat","linuxcnc/configs/sim/craftsman/macros/M100","linuxcnc/configs/sim/craftsman/macros/M101","linuxcnc/configs/sim/craftsman/macros/M102","linuxcnc/configs/sim/craftsman/macros/M103","linuxcnc/configs/sim/craftsman/macros/M105","linuxcnc/configs/sim/craftsman/macros/M106","linuxcnc/configs/sim/craftsman/macros/M107","linuxcnc/configs/sim/craftsman/macros/M108","linuxcnc/configs/sim/craftsman/macros/m101.ngc","linuxcnc/configs/sim/craftsman/macros/m102.ngc","linuxcnc/configs/sim/craftsman/macros/m103.ngc","linuxcnc/configs/sim/craftsman/macros/m104.ngc","linuxcnc/configs/sim/craftsman/macros/m105.ngc","linuxcnc/configs/sim/craftsman/macros/m106.ngc","linuxcnc/configs/sim/craftsman/mdi_history.dat","linuxcnc/configs/sim/craftsman/messages","linuxcnc/configs/sim/craftsman/screen1.jpg","linuxcnc/configs/sim/craftsman/screen2.jpg","linuxcnc/configs/sim/craftsman/screen3.jpg","linuxcnc/configs/sim/craftsman/screens/craftsmancnc.ngc","linuxcnc/configs/sim/craftsman/screens/gcodes.htm","linuxcnc/configs/sim/craftsman/screens/gcodes_files/G81.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/G81a.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/G81ex1.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/G81ex2.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/G81mult.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/asciidoc-xhtml11.js","linuxcnc/configs/sim/craftsman/screens/gcodes_files/eight.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/g2-3.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/g2.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/g76-01.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/g76-threads.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/linuxcnc.css","linuxcnc/configs/sim/craftsman/screens/gcodes_files/nurbs01.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/twelve.png","linuxcnc/configs/sim/craftsman/screens/gcodes_files/xhtml11-quirks.css","linuxcnc/configs/sim/craftsman/screens/gcodes_files/xhtml11.css","linuxcnc/configs/sim/craftsman/screens/linuxcnc screen.png","linuxcnc/configs/sim/craftsman/screens/mcodes.htm","linuxcnc/configs/sim/craftsman/screens/mcodes_files/asciidoc-xhtml11.js","linuxcnc/configs/sim/craftsman/screens/mcodes_files/linuxcnc.css","linuxcnc/configs/sim/craftsman/screens/mcodes_files/xhtml11-quirks.css","linuxcnc/configs/sim/craftsman/screens/mcodes_files/xhtml11.css","linuxcnc/configs/sim/craftsman/screens/screen1.jpg","linuxcnc/configs/sim/craftsman/screens/screen2.jpg","linuxcnc/configs/sim/craftsman/screens/screen3.jpg","linuxcnc/configs/sim/craftsman/sim_core.hal","linuxcnc/configs/sim/craftsman/spindle_control.dat","linuxcnc/configs/sim/craftsman/tool.dat","linuxcnc/configs/sim/craftsman/tool.tbl","linuxcnc/configs/sim/craftsman/toolchange.dat","linuxcnc/configs/sim/craftsman/vfd_controller.py","linuxcnc/configs/sim/craftsman/vfd_spindle","linuxcnc/configs/sim/gmoccapy/6_axis.ini","linuxcnc/configs/sim/gmoccapy/7_axis.ini","linuxcnc/configs/sim/gmoccapy/7_axis_tool.ini","linuxcnc/configs/sim/gmoccapy/8_axis.ini","linuxcnc/configs/sim/gmoccapy/9_axis.ini","linuxcnc/configs/sim/gmoccapy/README","linuxcnc/configs/sim/gmoccapy/README_es","linuxcnc/configs/sim/gmoccapy/button.glade","linuxcnc/configs/sim/gmoccapy/core_sim.hal","linuxcnc/configs/sim/gmoccapy/core_sim4.hal","linuxcnc/configs/sim/gmoccapy/core_sim_6.hal","linuxcnc/configs/sim/gmoccapy/core_sim_7.hal","linuxcnc/configs/sim/gmoccapy/core_sim_8.hal","linuxcnc/configs/sim/gmoccapy/core_sim_9.hal","linuxcnc/configs/sim/gmoccapy/core_sim_XYZAB.hal","linuxcnc/configs/sim/gmoccapy/core_sim_XYZAC.hal","linuxcnc/configs/sim/gmoccapy/core_sim_XYZCW.hal","linuxcnc/configs/sim/gmoccapy/dro.glade","linuxcnc/configs/sim/gmoccapy/gmoccapy.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy.txt","linuxcnc/configs/sim/gmoccapy/gmoccapy2.glade","linuxcnc/configs/sim/gmoccapy/gmoccapy_4_axis.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_4_axis.txt","linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZAB.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZAC.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZCW.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_left_panel.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_messages.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_pedant.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/README","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/README_es","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/gmoccapy_plasma.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/gmoccapy_postgui.hal","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/plasma.glade","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/plasma.hal","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/plasma.py","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/signals.glade","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/signals.hal","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/signals.py","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/torch.svg","linuxcnc/configs/sim/gmoccapy/gmoccapy_plasma/torches.tbl","linuxcnc/configs/sim/gmoccapy/gmoccapy_postgui.hal","linuxcnc/configs/sim/gmoccapy/gmoccapy_pyngcgui.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_pyngcgui.txt","linuxcnc/configs/sim/gmoccapy/gmoccapy_right_panel.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_sim_hardware_button.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_tool_sensor.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_tool_sensor.para","linuxcnc/configs/sim/gmoccapy/gmoccapy_with_user_tabs.ini","linuxcnc/configs/sim/gmoccapy/gmoccapy_with_user_tabs.txt","linuxcnc/configs/sim/gmoccapy/h_buttonlist.glade","linuxcnc/configs/sim/gmoccapy/h_buttonlist.hal","linuxcnc/configs/sim/gmoccapy/jogwheel.glade","linuxcnc/configs/sim/gmoccapy/jogwheel.hal","linuxcnc/configs/sim/gmoccapy/lathe.tbl","linuxcnc/configs/sim/gmoccapy/lathe_configs/LatheMacro.svg","linuxcnc/configs/sim/gmoccapy/lathe_configs/README","linuxcnc/configs/sim/gmoccapy/lathe_configs/boring.ngc","linuxcnc/configs/sim/gmoccapy/lathe_configs/chamfer.ngc","linuxcnc/configs/sim/gmoccapy/lathe_configs/core_sim_lathe.hal","linuxcnc/configs/sim/gmoccapy/lathe_configs/core_sim_lathe_C.hal","linuxcnc/configs/sim/gmoccapy/lathe_configs/core_sim_lathe_CW.hal","linuxcnc/configs/sim/gmoccapy/lathe_configs/drilling.ngc","linuxcnc/configs/sim/gmoccapy/lathe_configs/facing.ngc","linuxcnc/configs/sim/gmoccapy/lathe_configs/gmoccapy_lathe.pref","linuxcnc/configs/sim/gmoccapy/lathe_configs/gmoccapy_lathe_c.pref","linuxcnc/configs/sim/gmoccapy/lathe_configs/gmoccapy_postgui.hal","linuxcnc/configs/sim/gmoccapy/lathe_configs/grooving.ngc","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe.ini","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe.pref","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe.tbl","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_C.ini","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_CW.ini","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_backtool.ini","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_c.pref","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_cw.pref","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_imperial.ini","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_imperial.pref","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathe_macros.ini","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathehandler.py","linuxcnc/configs/sim/gmoccapy/lathe_configs/lathemacro.ui","linuxcnc/configs/sim/gmoccapy/lathe_configs/radius.ngc","linuxcnc/configs/sim/gmoccapy/lathe_configs/savestate.sav","linuxcnc/configs/sim/gmoccapy/lathe_configs/simulated_home_lathe.hal","linuxcnc/configs/sim/gmoccapy/lathe_configs/simulated_home_lathe_CW.hal","linuxcnc/configs/sim/gmoccapy/lathe_configs/spindle_sim.hal","linuxcnc/configs/sim/gmoccapy/lathe_configs/threading.ngc","linuxcnc/configs/sim/gmoccapy/lathe_configs/turning.ngc","linuxcnc/configs/sim/gmoccapy/left.hal","linuxcnc/configs/sim/gmoccapy/left_panel.hal","linuxcnc/configs/sim/gmoccapy/macros/change.ngc","linuxcnc/configs/sim/gmoccapy/macros/go_to_position.ngc","linuxcnc/configs/sim/gmoccapy/macros/halo_world.ngc","linuxcnc/configs/sim/gmoccapy/macros/i_am_lost.ngc","linuxcnc/configs/sim/gmoccapy/macros/images/goto_x_y_z.png","linuxcnc/configs/sim/gmoccapy/macros/images/i_am_lost.png","linuxcnc/configs/sim/gmoccapy/macros/images/macro_8.png","linuxcnc/configs/sim/gmoccapy/macros/increment.ngc","linuxcnc/configs/sim/gmoccapy/macros/jog_around.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_0.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_1.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_10.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_11.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_12.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_13.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_14.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_15.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_2.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_3.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_4.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_5.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_6.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_7.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_8.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_9.ngc","linuxcnc/configs/sim/gmoccapy/macros/macro_Instructions.txt","linuxcnc/configs/sim/gmoccapy/macros/on_abort.ngc","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gantry_mm.hal","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gantry_mm.ini","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gmoccapy_GANTRY_sim.pref","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gmoccapy_postgui.hal","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/tool.tbl","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/LinuxCNC-HAL-SIM-SCARA.pref","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/README","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/README_es","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/postgui.hal","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara.glade","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara.ini","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara.tbl","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara_panel.hal","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara_postgui.hal","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara_sim_4.hal","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/scara/spindle_sim.hal","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/README","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/README_es","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzac.ngc","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzbc.ngc","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/impeller-7bl-xyzac.ngc","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/test-xyzac.ngc","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/test-xyzbc.ngc","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/postgui.hal","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/sim-xyzac-trt.pref","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt.ini","linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt.tbl","linuxcnc/configs/sim/gmoccapy/pendant.glade","linuxcnc/configs/sim/gmoccapy/pendant.hal","linuxcnc/configs/sim/gmoccapy/plasma_config/README","linuxcnc/configs/sim/gmoccapy/plasma_config/README_es","linuxcnc/configs/sim/gmoccapy/plasma_config/gmoccapy.pref","linuxcnc/configs/sim/gmoccapy/plasma_config/gmoccapy_plasma.ini","linuxcnc/configs/sim/gmoccapy/plasma_config/gmoccapy_postgui.hal","linuxcnc/configs/sim/gmoccapy/plasma_config/plasma.glade","linuxcnc/configs/sim/gmoccapy/plasma_config/plasma.hal","linuxcnc/configs/sim/gmoccapy/plasma_config/plasma.py","linuxcnc/configs/sim/gmoccapy/plasma_config/signals.glade","linuxcnc/configs/sim/gmoccapy/plasma_config/signals.hal","linuxcnc/configs/sim/gmoccapy/plasma_config/signals.py","linuxcnc/configs/sim/gmoccapy/plasma_config/torch.svg","linuxcnc/configs/sim/gmoccapy/plasma_config/torches.tbl","linuxcnc/configs/sim/gmoccapy/pyngcgui.ui","linuxcnc/configs/sim/gmoccapy/python/remap.py","linuxcnc/configs/sim/gmoccapy/python/stdglue.py","linuxcnc/configs/sim/gmoccapy/python/toplevel.py","linuxcnc/configs/sim/gmoccapy/simulated_home.hal","linuxcnc/configs/sim/gmoccapy/simulated_home_lathe.hal","linuxcnc/configs/sim/gmoccapy/spindle_sim.hal","linuxcnc/configs/sim/gmoccapy/tool.tbl","linuxcnc/configs/sim/gmoccapy/tool_sensor.glade","linuxcnc/configs/sim/gmoccapy/tool_sensor.hal","linuxcnc/configs/sim/gmoccapy/tool_sensor.para","linuxcnc/configs/sim/gmoccapy/v_buttonlist.glade","linuxcnc/configs/sim/gmoccapy/v_buttonlist.hal","linuxcnc/configs/sim/gmoccapy/vcp_box.glade","linuxcnc/configs/sim/gmoccapy/vcp_box.hal","linuxcnc/configs/sim/gremlin_view.ui","linuxcnc/configs/sim/gs2.hal","linuxcnc/configs/sim/gscreen/README","linuxcnc/configs/sim/gscreen/README_es","linuxcnc/configs/sim/gscreen/gladevcp-test.ui","linuxcnc/configs/sim/gscreen/gscreen.ini","linuxcnc/configs/sim/gscreen/gscreen_custom/9axis.ini","linuxcnc/configs/sim/gscreen/gscreen_custom/README","linuxcnc/configs/sim/gscreen/gscreen_custom/README_es","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_no_plot.ini","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_postgui.hal","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/arrow_down1.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/arrow_down2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/arrow_left1.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/arrow_left2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/arrow_right1.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/arrow_right2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/arrow_up1.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/arrow_up2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/base.xcf","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/base2.xcf","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/base3.xcf","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/blank.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/button1.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/button2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/button3.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/button4.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/check1.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/check2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/default.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/green_button2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/gtkrc","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/in.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/obutton1.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/obutton2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/option1.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/option2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/radio1.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/radio2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/red_button2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/spin1.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/spin2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/spin3.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/trough.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/up.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gaxis_theme/gtk-2.0/yellow_button2.png","linuxcnc/configs/sim/gscreen/gscreen_custom/gscreen_gaxis.ini","linuxcnc/configs/sim/gscreen/gscreen_custom/industrial.ini","linuxcnc/configs/sim/gscreen/gscreen_custom/industrial_postgui.hal","linuxcnc/configs/sim/gscreen/gscreen_custom/sim.tbl","linuxcnc/configs/sim/gscreen/gscreen_custom/tester.ini","linuxcnc/configs/sim/gscreen/gscreen_custom/tester_metric.ini","linuxcnc/configs/sim/gscreen/gscreen_custom/tester_postgui.hal","linuxcnc/configs/sim/gscreen/gscreen_lathe.ini","linuxcnc/configs/sim/gscreen/gscreen_mm.ini","linuxcnc/configs/sim/gscreen/gscreen_theme/gtk-3.0/gtk.css","linuxcnc/configs/sim/gscreen/gscreen_theme/gtk-3.0/gtkrc","linuxcnc/configs/sim/gscreen/industrial_lathe_wear/README","linuxcnc/configs/sim/gscreen/industrial_lathe_wear/README_es","linuxcnc/configs/sim/gscreen/industrial_lathe_wear/industrial_lathe_wear.ini","linuxcnc/configs/sim/gscreen/industrial_lathe_wear/lathe-fanucy.tbl","linuxcnc/configs/sim/gscreen/industrial_lathe_wear/lathe_postgui.hal","linuxcnc/configs/sim/gscreen/industrial_lathe_wear/remap.py","linuxcnc/configs/sim/gscreen/industrial_lathe_wear/toolchange.ngc","linuxcnc/configs/sim/gscreen/industrial_lathe_wear/toplevel.py","linuxcnc/configs/sim/gscreen/lathe.tbl","linuxcnc/configs/sim/gscreen/lathe_postgui.hal","linuxcnc/configs/sim/gscreen/ngcgui/README","linuxcnc/configs/sim/gscreen/ngcgui/README_es","linuxcnc/configs/sim/gscreen/ngcgui/gremlin_view.ui","linuxcnc/configs/sim/gscreen/ngcgui/pyngcgui.ui","linuxcnc/configs/sim/gscreen/ngcgui/pyngcgui_gscreen.ini","linuxcnc/configs/sim/gscreen/ngcgui/pyngcgui_gscreen.txt","linuxcnc/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_es.txt","linuxcnc/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_popupkeyboard.ini","linuxcnc/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_popupkeyboard.txt","linuxcnc/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_popupkeyboard_es.txt","linuxcnc/configs/sim/gscreen/ngcgui/pyngcgui_popupkeyboard.ui","linuxcnc/configs/sim/gscreen/ngcgui/sim.tbl","linuxcnc/configs/sim/gscreen/silverdragon/README","linuxcnc/configs/sim/gscreen/silverdragon/README_es","linuxcnc/configs/sim/gscreen/silverdragon/macros/auto_zref.ngc","linuxcnc/configs/sim/gscreen/silverdragon/macros/laserzero.ngc","linuxcnc/configs/sim/gscreen/silverdragon/macros/tool_sensor.ngc","linuxcnc/configs/sim/gscreen/silverdragon/macros/touch_plate.ngc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon.ini","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/arrow/arrow-down-disable.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/arrow/arrow-down.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/arrow/arrow-left.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/arrow/arrow-right.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/arrow/arrow-up-disable.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/arrow/arrow-up.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/bg.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/button.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/button/button-ins.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/button/button-light.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/button/button-pressed.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/button/button-spin.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/button/button.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/c_box.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/c_box/c_box-pressed.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/c_box/c_box.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/entry.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/entry/entry-active.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/entry/entry.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/gtkrc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/menubar.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/menubar/line-h.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/menubar/line-v.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/menubar/menubar.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/menubar/menuitem.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/notebook.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/notebook/notebook.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/notebook/tab-bottom-active.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/notebook/tab-bottom.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/notebook/tab-left-active.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/notebook/tab-left.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/notebook/tab-right-active.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/notebook/tab-right.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/notebook/tab-top-active.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/notebook/tab-top.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/null.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/progressbar.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/progressbar/progressbar-horiz.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/progressbar/progressbar-vert.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/progressbar/trough-horiz.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/progressbar/trough-tree.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/progressbar/trough-vert.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/radio.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/radio/radio-pressed (copy).png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/radio/radio-pressed.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/radio/radio.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scale.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scale/slider-horiz.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scale/slider-vert.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scale/trough-horiz.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scale/trough-vert.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/arrow_down.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/arrow_down_clicked.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/arrow_left.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/arrow_left_clicked.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/arrow_right.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/arrow_right_clicked.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/arrow_up.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/arrow_up_clicked.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/scrollbar_horizontal.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/scrollbar_vertical.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/thumb.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/trough-h.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/scrollbar/trough-v.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/spin.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/statusbar.rc","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/gtk-2.0/statusbar/resizer.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/border-bottom.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/border-left.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/border-right.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/bottom-grip-left-corner.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/bottom-grip-right-corner.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/button-bkg-pressed.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/button-bkg-unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/button-bkg.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/button-close-icon.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/button-max-icon.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/button-min-icon.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/button-unmax-icon.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/metacity-theme-1.xml","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/title_center_dimple_gradient.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/title_center_dimple_gradient_unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/title_left_dimple_gradient.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/title_left_dimple_gradient_unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/title_right_dimple_gradient.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/title_right_dimple_gradient_unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/titlebar_center_gradient.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/titlebar_center_gradient_unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/titlebar_left_gradient.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/titlebar_left_gradient_unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/titlebar_right_gradient.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/titlebar_right_gradient_unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/top-grip-left-corner.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/top-grip-right-corner.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/window-chrome-close-unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/window-chrome-maximize-unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/window-chrome-minimize-unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/silverdragon_theme/metacity-1/window-chrome-unmaximize-unfocused.png","linuxcnc/configs/sim/gscreen/silverdragon/tool.tbl","linuxcnc/configs/sim/gscreen/sim.tbl","linuxcnc/configs/sim/gscreen/sim_mm.tbl","linuxcnc/configs/sim/gscreen/spartan/README","linuxcnc/configs/sim/gscreen/spartan/README_es","linuxcnc/configs/sim/gscreen/spartan/custom.hal","linuxcnc/configs/sim/gscreen/spartan/custom_postgui.hal","linuxcnc/configs/sim/gscreen/spartan/sim_hardware.hal","linuxcnc/configs/sim/gscreen/spartan/spartan.hal","linuxcnc/configs/sim/gscreen/spartan/spartan.ini","linuxcnc/configs/sim/gscreen/spartan/tool.tbl","linuxcnc/configs/sim/gscreen/vcp_box.glade","linuxcnc/configs/sim/hitcounter.py","linuxcnc/configs/sim/lathe.tbl","linuxcnc/configs/sim/lathe.xml","linuxcnc/configs/sim/lathe_postgui.hal","linuxcnc/configs/sim/manual-example.hal","linuxcnc/configs/sim/manual-example.ui","linuxcnc/configs/sim/nstools.tbl","linuxcnc/configs/sim/pyngcgui.ui","linuxcnc/configs/sim/pyngcgui_popupkeyboard.ui","linuxcnc/configs/sim/pyvcp_demo.hal","linuxcnc/configs/sim/pyvcp_demo.xml","linuxcnc/configs/sim/pyvcp_demo/README","linuxcnc/configs/sim/pyvcp_demo/README_es","linuxcnc/configs/sim/pyvcp_demo/custom.hal","linuxcnc/configs/sim/pyvcp_demo/pyvcp_bottom_panel.hal","linuxcnc/configs/sim/pyvcp_demo/pyvcp_bottom_panel.ini","linuxcnc/configs/sim/pyvcp_demo/pyvcp_bottom_panel.xml","linuxcnc/configs/sim/pyvcp_demo/pyvcp_demo1.ini","linuxcnc/configs/sim/pyvcp_demo/pyvcp_demo1.xml","linuxcnc/configs/sim/pyvcp_demo/pyvcp_embed_tab.hal","linuxcnc/configs/sim/pyvcp_demo/pyvcp_embed_tab.ini","linuxcnc/configs/sim/pyvcp_demo/pyvcp_embed_tab_1.xml","linuxcnc/configs/sim/pyvcp_demo/pyvcp_embed_tab_2.xml","linuxcnc/configs/sim/pyvcp_demo/sim_mm.tbl","linuxcnc/configs/sim/qtaxis/gantry/qt_gantry.ini","linuxcnc/configs/sim/qtaxis/gantry/sim.tbl","linuxcnc/configs/sim/qtaxis/non-trivial/scara/remap_subs/428remap.ngc","linuxcnc/configs/sim/qtaxis/non-trivial/scara/remap_subs/429remap.ngc","linuxcnc/configs/sim/qtaxis/non-trivial/scara/remap_subs/430remap.ngc","linuxcnc/configs/sim/qtaxis/non-trivial/scara/scara.ini","linuxcnc/configs/sim/qtaxis/non-trivial/scara/scara.tbl","linuxcnc/configs/sim/qtaxis/xyz/check_constraints.hal","linuxcnc/configs/sim/qtaxis/xyz/qtaxis.ini","linuxcnc/configs/sim/qtaxis/xyz/qtvcp_postgui.hal","linuxcnc/configs/sim/qtaxis/xyz/sim.tbl","linuxcnc/configs/sim/qtdragon/README","linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/README","linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/on_abort.ngc","linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_postgui.hal","linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyz.ini","linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyzy.ini","linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyzya.ini","linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/silver_dragon.png","linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/tool.tbl","linuxcnc/configs/sim/qtdragon/qtdragon_tool_probe/README","linuxcnc/configs/sim/qtdragon/qtdragon_tool_probe/qtdragon_auto_tool_probe.ini","linuxcnc/configs/sim/qtdragon/qtdragon_tool_probe/qtdragon_postgui.hal","linuxcnc/configs/sim/qtdragon/qtdragon_tool_probe/silver_dragon.png","linuxcnc/configs/sim/qtdragon/qtdragon_tool_probe/tool.tbl","linuxcnc/configs/sim/qtdragon/qtdragon_xyz/README","linuxcnc/configs/sim/qtdragon/qtdragon_xyz/on_abort.ngc","linuxcnc/configs/sim/qtdragon/qtdragon_xyz/qtdragon_inch.ini","linuxcnc/configs/sim/qtdragon/qtdragon_xyz/qtdragon_metric.ini","linuxcnc/configs/sim/qtdragon/qtdragon_xyz/qtdragon_postgui.hal","linuxcnc/configs/sim/qtdragon/qtdragon_xyz/qtdragon_xyza.ini","linuxcnc/configs/sim/qtdragon/qtdragon_xyz/silver_dragon.png","linuxcnc/configs/sim/qtdragon/qtdragon_xyz/tool.tbl","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/.gitignore","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/README","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/core_sim_XYZAB.hal","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/core_sim_XYZAC.hal","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/on_abort.ngc","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_postgui.hal","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyza.ini","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyzab.ini","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyzac.ini","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/silver_dragon.png","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/simulated_home.hal","linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/tool.tbl","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/README","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/core_sim_XYZAB.hal","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/core_sim_XYZAC.hal","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/on_abort.ngc","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_postgui.hal","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyz.ini","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyza.ini","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyzab.ini","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyzac.ini","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/silver_dragon.png","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/tool.tbl","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/README","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/on_abort.ngc","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/probe_points.txt","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_postgui.hal","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_z_compensation.ini","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/silver_dragon.png","linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/tool.tbl","linuxcnc/configs/sim/qtplasmac/.gitignore","linuxcnc/configs/sim/qtplasmac/LICENSE","linuxcnc/configs/sim/qtplasmac/README","linuxcnc/configs/sim/qtplasmac/custom.hal","linuxcnc/configs/sim/qtplasmac/custom_filter.py","linuxcnc/configs/sim/qtplasmac/custom_postgui.hal","linuxcnc/configs/sim/qtplasmac/imperial_tool.tbl","linuxcnc/configs/sim/qtplasmac/machine.tcl","linuxcnc/configs/sim/qtplasmac/metric_tool.tbl","linuxcnc/configs/sim/qtplasmac/qtplasmac-imperial.prefs","linuxcnc/configs/sim/qtplasmac/qtplasmac-metric.prefs","linuxcnc/configs/sim/qtplasmac/qtplasmac_imperial_ini.inc","linuxcnc/configs/sim/qtplasmac/qtplasmac_l_imperial.ini","linuxcnc/configs/sim/qtplasmac/qtplasmac_l_metric.ini","linuxcnc/configs/sim/qtplasmac/qtplasmac_metric_ini.inc","linuxcnc/configs/sim/qtplasmac/qtplasmac_p_imperial.ini","linuxcnc/configs/sim/qtplasmac/qtplasmac_p_metric.ini","linuxcnc/configs/sim/qtplasmac/qtplasmac_s_imperial.ini","linuxcnc/configs/sim/qtplasmac/qtplasmac_s_metric.ini","linuxcnc/configs/sim/qtplasmac/qtvcp.prefs","linuxcnc/configs/sim/qtplasmac/sim_no_stepgen.tcl","linuxcnc/configs/sim/qtplasmac/sim_postgui.hal","linuxcnc/configs/sim/qtplasmac/sim_stepgen.tcl","linuxcnc/configs/sim/qttouchy/qttouchy.ini","linuxcnc/configs/sim/qttouchy/qttouchy.pref","linuxcnc/configs/sim/qttouchy/qtvcp_postgui.hal","linuxcnc/configs/sim/qttouchy/sim.tbl","linuxcnc/configs/sim/qtvcp_screens/.gitignore","linuxcnc/configs/sim/qtvcp_screens/README","linuxcnc/configs/sim/qtvcp_screens/README_es","linuxcnc/configs/sim/qtvcp_screens/background.png","linuxcnc/configs/sim/qtvcp_screens/blender.ini","linuxcnc/configs/sim/qtvcp_screens/check_constraints.hal","linuxcnc/configs/sim/qtvcp_screens/industrial_lathe_wear/README","linuxcnc/configs/sim/qtvcp_screens/industrial_lathe_wear/README_es","linuxcnc/configs/sim/qtvcp_screens/industrial_lathe_wear/industrial_lathe_wear.ini","linuxcnc/configs/sim/qtvcp_screens/industrial_lathe_wear/lathe-wear.tbl","linuxcnc/configs/sim/qtvcp_screens/industrial_lathe_wear/qtvcp_postgui.hal","linuxcnc/configs/sim/qtvcp_screens/industrial_lathe_wear/remap.py","linuxcnc/configs/sim/qtvcp_screens/industrial_lathe_wear/toolchange.ngc","linuxcnc/configs/sim/qtvcp_screens/industrial_lathe_wear/toplevel.py","linuxcnc/configs/sim/qtvcp_screens/non-trivial/scara/remap_subs/428remap.ngc","linuxcnc/configs/sim/qtvcp_screens/non-trivial/scara/remap_subs/429remap.ngc","linuxcnc/configs/sim/qtvcp_screens/non-trivial/scara/remap_subs/430remap.ngc","linuxcnc/configs/sim/qtvcp_screens/non-trivial/scara/scara.ini","linuxcnc/configs/sim/qtvcp_screens/qt_800x600.ini","linuxcnc/configs/sim/qtvcp_screens/qt_gantry.ini","linuxcnc/configs/sim/qtvcp_screens/qtaxis.ini","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/lathe-wear.tbl","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/axis-16x16.png","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/axis-24x24.png","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/axis-32x32.png","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/axis-48x48.png","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/close.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/downarrow.xbm","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/leftarrow.xbm","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/resume_inhibit.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/rightarrow.xbm","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/spindle_ccw.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/spindle_cw.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/std_error.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/std_info.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/std_warning.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_axis_p.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_axis_x.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_axis_y.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_axis_y2.png","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_axis_z.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_axis_z2.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_blockdelete.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_clear.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_estop.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_open.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_optpause.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_pause.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_power.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_reload.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_rotate.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_run.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_step.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_stop.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_verify.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_zoomin.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/tool_zoomout.gif","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/images/uparrow.xbm","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/qtaxis.ui","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis/qtaxis_handler.py","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis_lathe.ini","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/qtvcp_postgui.hal","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/remap.py","linuxcnc/configs/sim/qtvcp_screens/qtaxis_lathe/toplevel.py","linuxcnc/configs/sim/qtvcp_screens/qtaxis_mpg.ini","linuxcnc/configs/sim/qtvcp_screens/qtdefault.ini","linuxcnc/configs/sim/qtvcp_screens/qtdefault_9axis.ini","linuxcnc/configs/sim/qtvcp_screens/qtdefault_gantry.ini","linuxcnc/configs/sim/qtvcp_screens/qtdefault_mm.ini","linuxcnc/configs/sim/qtvcp_screens/qtdragon/README","linuxcnc/configs/sim/qtvcp_screens/qtdragon/core_sim.hal","linuxcnc/configs/sim/qtvcp_screens/qtdragon/gantrysim.hal","linuxcnc/configs/sim/qtvcp_screens/qtdragon/on_abort.ngc","linuxcnc/configs/sim/qtvcp_screens/qtdragon/python/qt_auto_probe_tool.ngc","linuxcnc/configs/sim/qtvcp_screens/qtdragon/python/remap.py","linuxcnc/configs/sim/qtvcp_screens/qtdragon/python/stdglue.py","linuxcnc/configs/sim/qtvcp_screens/qtdragon/python/toplevel.py","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon.ini","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_auto_tool_probe.ini","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_hd.ini","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_hd_postgui.hal","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_inch.ini","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_postgui.hal","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_postgui_ya.hal","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyyz.ini","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyz.ini","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyza.ini","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyzy.ini","linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyzya.ini","linuxcnc/configs/sim/qtvcp_screens/qtdragon/silver_dragon.png","linuxcnc/configs/sim/qtvcp_screens/qtdragon/tool.tbl","linuxcnc/configs/sim/qtvcp_screens/qtvcp_custom/check_constraints.hal","linuxcnc/configs/sim/qtvcp_screens/qtvcp_custom/pyngcgui.ui","linuxcnc/configs/sim/qtvcp_screens/qtvcp_custom/qtdefault_ngc.ini","linuxcnc/configs/sim/qtvcp_screens/qtvcp_custom/qtdefault_ngc/qtdefault_ngc.ui","linuxcnc/configs/sim/qtvcp_screens/qtvcp_custom/qtdefault_ngc/qtdefault_ngc_handler.py","linuxcnc/configs/sim/qtvcp_screens/qtvcp_custom/qtvcp_postgui.hal","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/LatheMacro.svg","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/check_constraints.hal","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/gremlin.glade","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/gremlin.ini","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/gvcp.glade","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/gvcp_handler.py","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/lathehandler.py","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/lathemacro.ui","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/pyngcgui.ui","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp.ini","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp/qtdefault_gladevcp.ui","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp/qtdefault_gladevcp_handler.py","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp_handler.py","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp_handler_1.py","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_ngc.ini","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_ngc/qtdefault_ngc.ui","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_ngc/qtdefault_ngc_handler.py","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/qtvcp_postgui.hal","linuxcnc/configs/sim/qtvcp_screens/qtvcp_experimental/savestate.sav","linuxcnc/configs/sim/qtvcp_screens/qtvcp_postgui.hal","linuxcnc/configs/sim/qtvcp_screens/qtx1mill.ini","linuxcnc/configs/sim/qtvcp_screens/sim-9axis.var","linuxcnc/configs/sim/qtvcp_screens/sim_mm.tbl","linuxcnc/configs/sim/qtvcp_screens/tester.ini","linuxcnc/configs/sim/schema-simple.sql","linuxcnc/configs/sim/screwcompX.dat","linuxcnc/configs/sim/sim.tbl","linuxcnc/configs/sim/sim_mm.tbl","linuxcnc/configs/sim/sim_mm_test.tbl","linuxcnc/configs/sim/simpockets.tbl","linuxcnc/configs/sim/test.vcp","linuxcnc/configs/sim/tklinuxcnc/README","linuxcnc/configs/sim/tklinuxcnc/README_es","linuxcnc/configs/sim/tklinuxcnc/ldelta.ini","linuxcnc/configs/sim/tklinuxcnc/screwcompX.dat","linuxcnc/configs/sim/tklinuxcnc/servo_sim.ini","linuxcnc/configs/sim/tklinuxcnc/sim.tbl","linuxcnc/configs/sim/tklinuxcnc/tklinuxcnc.ini","linuxcnc/configs/sim/tklinuxcnc/tripod.ini","linuxcnc/configs/sim/tklinuxcnc/trivkins/README","linuxcnc/configs/sim/tklinuxcnc/trivkins/README_es","linuxcnc/configs/sim/tklinuxcnc/trivkins/xz.ini","linuxcnc/configs/sim/tklinuxcnc/trivkins/xz.tbl","linuxcnc/configs/sim/tklinuxcnc/trivkins/xz_both.ini","linuxcnc/configs/sim/tklinuxcnc/trivkins/xzbase.inc","linuxcnc/configs/sim/touchy/README","linuxcnc/configs/sim/touchy/README_es","linuxcnc/configs/sim/touchy/gladevcp/README","linuxcnc/configs/sim/touchy/gladevcp/README_es","linuxcnc/configs/sim/touchy/gladevcp/gladevcp-touchy.hal","linuxcnc/configs/sim/touchy/gladevcp/gladevcp_touchy.ini","linuxcnc/configs/sim/touchy/gladevcp/hitcounter.py","linuxcnc/configs/sim/touchy/gladevcp/manual-example.hal","linuxcnc/configs/sim/touchy/gladevcp/manual-example.ui","linuxcnc/configs/sim/touchy/gladevcp/simpockets.tbl","linuxcnc/configs/sim/touchy/gladevcp/touchy-gremlin.ui","linuxcnc/configs/sim/touchy/gladevcp/touchy-misc.hal","linuxcnc/configs/sim/touchy/gladevcp/touchy-misc.ui","linuxcnc/configs/sim/touchy/gladevcp/touchy.ini","linuxcnc/configs/sim/touchy/ngcgui/README","linuxcnc/configs/sim/touchy/ngcgui/README_es","linuxcnc/configs/sim/touchy/ngcgui/gremlin_view.ui","linuxcnc/configs/sim/touchy/ngcgui/hwsim.sh","linuxcnc/configs/sim/touchy/ngcgui/lathe.tbl","linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy.ini","linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy.txt","linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy_es.txt","linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy_lathe.ini","linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy_lathe.txt","linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy_lathe_es.txt","linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff.ini","linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff.txt","linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff_es.txt","linuxcnc/configs/sim/touchy/ngcgui/pyngcgui_touchy_popupkeyboard.ui","linuxcnc/configs/sim/touchy/ngcgui/sim.tbl","linuxcnc/configs/sim/touchy/simpockets.tbl","linuxcnc/configs/sim/touchy/touchy.ini","linuxcnc/configs/sim/touchy/touchy.txt","linuxcnc/configs/sim/touchy/touchy_es.txt","linuxcnc/configs/sim/touchy/touchy_postgui.hal","linuxcnc/configs/sim/touchy/touchy_test_panel.glade","linuxcnc/configs/sim/tracking-test.hal","linuxcnc/configs/sim/woodpecker/1280x1024_5axis/woodpecker.ui","linuxcnc/configs/sim/woodpecker/1280x1024_5axis/woodpecker_handler.py","linuxcnc/configs/sim/woodpecker/README.md","linuxcnc/configs/sim/woodpecker/compensate.py","linuxcnc/configs/sim/woodpecker/core_sim.hal","linuxcnc/configs/sim/woodpecker/gantrysim-xyzab.hal","linuxcnc/configs/sim/woodpecker/gantrysim.hal","linuxcnc/configs/sim/woodpecker/help_files/about.html","linuxcnc/configs/sim/woodpecker/help_files/database.html","linuxcnc/configs/sim/woodpecker/help_files/facing_utility.html","linuxcnc/configs/sim/woodpecker/help_files/help.css","linuxcnc/configs/sim/woodpecker/help_files/hole_circle_utility.html","linuxcnc/configs/sim/woodpecker/help_files/images/WoodPecker.png","linuxcnc/configs/sim/woodpecker/help_files/images/lcnc_swoop.png","linuxcnc/configs/sim/woodpecker/help_files/ngcgui.html","linuxcnc/configs/sim/woodpecker/help_files/probing.html","linuxcnc/configs/sim/woodpecker/help_files/runfromline.html","linuxcnc/configs/sim/woodpecker/help_files/spindle_pause.html","linuxcnc/configs/sim/woodpecker/help_files/stylesheets.html","linuxcnc/configs/sim/woodpecker/help_files/template.html","linuxcnc/configs/sim/woodpecker/help_files/using_a_mpg.html","linuxcnc/configs/sim/woodpecker/help_files/using_a_vfd.html","linuxcnc/configs/sim/woodpecker/help_files/z_level_comp.html","linuxcnc/configs/sim/woodpecker/line-number.txt","linuxcnc/configs/sim/woodpecker/mdi_history.dat","linuxcnc/configs/sim/woodpecker/mpg.hal","linuxcnc/configs/sim/woodpecker/numstr.py","linuxcnc/configs/sim/woodpecker/on_abort.ngc","linuxcnc/configs/sim/woodpecker/python/qt_auto_probe_tool.ngc","linuxcnc/configs/sim/woodpecker/python/remap.py","linuxcnc/configs/sim/woodpecker/python/stdglue.py","linuxcnc/configs/sim/woodpecker/python/toplevel.py","linuxcnc/configs/sim/woodpecker/qtvcp/screens/woodpecker/resources.py","linuxcnc/configs/sim/woodpecker/simulated-gantry-home.hal","linuxcnc/configs/sim/woodpecker/simulated-gantry-xyzab-home.hal","linuxcnc/configs/sim/woodpecker/tool.tbl","linuxcnc/configs/sim/woodpecker/tool_icons/ball_end_mill.png","linuxcnc/configs/sim/woodpecker/tool_icons/ballend_straight.png","linuxcnc/configs/sim/woodpecker/tool_icons/center_drill.png","linuxcnc/configs/sim/woodpecker/tool_icons/chamfer-90.png","linuxcnc/configs/sim/woodpecker/tool_icons/drill.png","linuxcnc/configs/sim/woodpecker/tool_icons/endmill.png","linuxcnc/configs/sim/woodpecker/tool_icons/gauge.png","linuxcnc/configs/sim/woodpecker/tool_icons/mill_tools/chamfer-90-1.png","linuxcnc/configs/sim/woodpecker/tool_icons/mill_tools/endmill-1.png","linuxcnc/configs/sim/woodpecker/tool_icons/mill_tools/endmill-2.png","linuxcnc/configs/sim/woodpecker/tool_icons/mill_tools/endmill-3.png","linuxcnc/configs/sim/woodpecker/tool_icons/mill_tools/endmill-4.png","linuxcnc/configs/sim/woodpecker/tool_icons/mill_tools/endmill-5.png","linuxcnc/configs/sim/woodpecker/tool_icons/mill_tools/endmill-6.png","linuxcnc/configs/sim/woodpecker/tool_icons/mill_tools/endmill-7.png","linuxcnc/configs/sim/woodpecker/tool_icons/mill_tools/endmill-8.png","linuxcnc/configs/sim/woodpecker/tool_icons/not_found.png","linuxcnc/configs/sim/woodpecker/tool_icons/probe.png","linuxcnc/configs/sim/woodpecker/tool_icons/spiral_ball_end.png","linuxcnc/configs/sim/woodpecker/tool_icons/spiral_downcut_2F.png","linuxcnc/configs/sim/woodpecker/tool_icons/spiral_upcut.png","linuxcnc/configs/sim/woodpecker/tool_icons/surfacing.png","linuxcnc/configs/sim/woodpecker/tool_icons/tapered_ball_end.png","linuxcnc/configs/sim/woodpecker/tool_icons/tool_icons.txt","linuxcnc/configs/sim/woodpecker/tool_icons/upcut_spiral.png","linuxcnc/configs/sim/woodpecker/tool_icons/vbit-60.png","linuxcnc/configs/sim/woodpecker/tool_icons/vbit-90.png","linuxcnc/configs/sim/woodpecker/tool_icons/vbit-90deg.png","linuxcnc/configs/sim/woodpecker/woodpecker.hal","linuxcnc/configs/sim/woodpecker/woodpecker.ini","linuxcnc/configs/sim/woodpecker/woodpecker.pref","linuxcnc/configs/sim/woodpecker/woodpecker_/images/Left_arrow.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets.html","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/asciidoc.css","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/asciidoc.js","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/blank.html","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/blank_data/inject.css","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/linuxcnc.css","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_actionButton.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_basicProbe.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_calculator.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_fileDialog.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_fileManager.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_focusOverlay.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_gcodeGraphics.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_ledWidget.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_machineLog.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_macro.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_mdiTouchy.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_nurbsEditor.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_offsetpage.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_runFromLine.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_toolChange.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_toolOffset.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/qtvcp_versaProbe.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/QTvcp Widgets_files/statusImageSwitcher.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/Right_arrow.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/a_minus_jog_button.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/a_plus_jog_button.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/atc_spindle_tool.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/brushed_metal.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/checked.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/clear.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/configure-2.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/dimensions.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/exit_application.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/extra_probe_depth.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/fullscreen_preview.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/linuxcnc-wizard.gif","linuxcnc/configs/sim/woodpecker/woodpecker_/images/max_xy_distance.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/max_z_distance.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/rabbit_jog.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/raster_0.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/raster_45.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/raster_90.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/spindle_fwd.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/spindle_pause.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/spindle_rev.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/spindle_stop.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/step_off_width.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/tool_probe.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/turtle_jog.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/unchecked.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/woodpecker.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/woodpecker2.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/x_minus_d.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/x_minus_jog_button.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/x_plus_d.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/x_plus_jog_button.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/xy_clearance.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/y_minus_d.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/y_minus_jog_button.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/y_plus_d.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/y_plus_jog_button.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/z_clearance.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/z_minus_jog_button.png","linuxcnc/configs/sim/woodpecker/woodpecker_/images/z_plus_jog_button.png","linuxcnc/configs/sim/woodpecker/woodpecker_/woodpecker.qrc","linuxcnc/configs/sim/woodpecker/woodpecker_/woodpecker.qss","linuxcnc/configs/sim/woodpecker/woodpecker_/woodpecker.ui","linuxcnc/configs/sim/woodpecker/woodpecker_/woodpecker_dark.qss","linuxcnc/configs/sim/woodpecker/woodpecker_/woodpecker_flat.qss","linuxcnc/configs/sim/woodpecker/woodpecker_/woodpecker_handler.py","linuxcnc/configs/sim/woodpecker/woodpecker_auto_tool_probe.ini","linuxcnc/configs/sim/woodpecker/woodpecker_postgui.hal","linuxcnc/configs/sim/woodpecker/woodpecker_postgui_ya.hal","linuxcnc/configs/sim/woodpecker/woodpecker_xyz.ini","linuxcnc/configs/sim/woodpecker/woodpecker_xyza.ini","linuxcnc/configs/sim/woodpecker/woodpecker_xyzab.ini","linuxcnc/configs/sim/woodpecker/woodpecker_xyzy.ini","linuxcnc/configs/sim/woodpecker/woodpecker_xyzya.ini","linuxcnc/configs/sim/woodpecker/zlevel.py","linuxcnc/configs/sim/woodpecker/zlevel.ui","linuxcnc/lib/hallib/README","linuxcnc/lib/hallib/axis_manualtoolchange.hal","linuxcnc/lib/hallib/basic_sim.tcl","linuxcnc/lib/hallib/check_config.tcl","linuxcnc/lib/hallib/check_xyz_constraints.hal","linuxcnc/lib/hallib/core_servo.hal","linuxcnc/lib/hallib/core_sim.hal","linuxcnc/lib/hallib/core_sim9.hal","linuxcnc/lib/hallib/core_stepper.hal","linuxcnc/lib/hallib/gantrysim.hal","linuxcnc/lib/hallib/hal_procs_lib.tcl","linuxcnc/lib/hallib/halcheck.tcl","linuxcnc/lib/hallib/hookup_moveoff.tcl","linuxcnc/lib/hallib/lathe.hal","linuxcnc/lib/hallib/locking_indexer.hal","linuxcnc/lib/hallib/moveoff_external.hal","linuxcnc/lib/hallib/plasmac.tcl","linuxcnc/lib/hallib/qtplasmac_comp.hal","linuxcnc/lib/hallib/servo_sim.hal","linuxcnc/lib/hallib/sim_ldelta.hal","linuxcnc/lib/hallib/sim_lib.tcl","linuxcnc/lib/hallib/sim_rdelta.hal","linuxcnc/lib/hallib/sim_spindle_encoder.hal","linuxcnc/lib/hallib/simulated-gantry-home.hal","linuxcnc/lib/hallib/simulated-xyyz-home.hal","linuxcnc/lib/hallib/simulated_home.hal","linuxcnc/lib/hallib/simulated_limits.hal","linuxcnc/lib/hallib/tripodsim.hal","linuxcnc/lib/hallib/util_lib.tcl","linuxcnc/lib/hallib/var_show.tcl","linuxcnc/lib/hallib/wheeljogpins.tcl","linuxcnc/lib/hallib/xhc-hb04-layout1.cfg","linuxcnc/lib/hallib/xhc-hb04-layout2.cfg","linuxcnc/lib/hallib/xhc-hb04.tcl","linuxcnc/lib/python/.gitignore","linuxcnc/lib/python/bitfile.py","linuxcnc/lib/python/bwidget.py","linuxcnc/lib/python/gladevcp/READ_ME","linuxcnc/lib/python/gladevcp/__init__.py","linuxcnc/lib/python/gladevcp/builtin-panels/versa-probe/versa_probe_screen.glade","linuxcnc/lib/python/gladevcp/builtin-panels/versa-probe/versa_probe_screen.py","linuxcnc/lib/python/gladevcp/builtin-panels/versa-probe/versa_probe_screen2.glade","linuxcnc/lib/python/gladevcp/calculator.glade","linuxcnc/lib/python/gladevcp/calculatorwidget.py","linuxcnc/lib/python/gladevcp/combi_dro.py","linuxcnc/lib/python/gladevcp/core.py","linuxcnc/lib/python/gladevcp/drowidget.py","linuxcnc/lib/python/gladevcp/gladebuilder.py","linuxcnc/lib/python/gladevcp/gladevcp-test.glade","linuxcnc/lib/python/gladevcp/gladevcp-test.hal","linuxcnc/lib/python/gladevcp/gtk_action.py","linuxcnc/lib/python/gladevcp/gtksourceview.xml","linuxcnc/lib/python/gladevcp/hal_actions.py","linuxcnc/lib/python/gladevcp/hal_bar.py","linuxcnc/lib/python/gladevcp/hal_dial.py","linuxcnc/lib/python/gladevcp/hal_filechooser.py","linuxcnc/lib/python/gladevcp/hal_graph.py","linuxcnc/lib/python/gladevcp/hal_gremlin.py","linuxcnc/lib/python/gladevcp/hal_gremlin_plus.py","linuxcnc/lib/python/gladevcp/hal_lightbutton.py","linuxcnc/lib/python/gladevcp/hal_mdihistory.py","linuxcnc/lib/python/gladevcp/hal_meter.py","linuxcnc/lib/python/gladevcp/hal_pyngcgui.py","linuxcnc/lib/python/gladevcp/hal_python.xml","linuxcnc/lib/python/gladevcp/hal_pythonplugin.py","linuxcnc/lib/python/gladevcp/hal_sourceview.py","linuxcnc/lib/python/gladevcp/hal_widgets.py","linuxcnc/lib/python/gladevcp/iconview.py","linuxcnc/lib/python/gladevcp/jogwheel.py","linuxcnc/lib/python/gladevcp/led.py","linuxcnc/lib/python/gladevcp/macro_widget.py","linuxcnc/lib/python/gladevcp/makepins.py","linuxcnc/lib/python/gladevcp/offsetpage.glade","linuxcnc/lib/python/gladevcp/offsetpage_widget.py","linuxcnc/lib/python/gladevcp/offsetwidget.py","linuxcnc/lib/python/gladevcp/overridewidget.py","linuxcnc/lib/python/gladevcp/persistence.py","linuxcnc/lib/python/gladevcp/pi.png","linuxcnc/lib/python/gladevcp/speedcontrol.py","linuxcnc/lib/python/gladevcp/state_label.py","linuxcnc/lib/python/gladevcp/status_label.py","linuxcnc/lib/python/gladevcp/tooledit_gtk.glade","linuxcnc/lib/python/gladevcp/tooledit_widget.py","linuxcnc/lib/python/gladevcp/widget-gladevcp-calc.png","linuxcnc/lib/python/gladevcp/xembed.py","linuxcnc/lib/python/gladevcp_makepins.py","linuxcnc/lib/python/glnav.py","linuxcnc/lib/python/gremlin_view.py","linuxcnc/lib/python/hal.py","linuxcnc/lib/python/hal_glib.py","linuxcnc/lib/python/hershey.py","linuxcnc/lib/python/linux_event.py","linuxcnc/lib/python/linuxcnc_util.py","linuxcnc/lib/python/multifilebuilder.py","linuxcnc/lib/python/nf.py.in","linuxcnc/lib/python/plasmac/block.py","linuxcnc/lib/python/plasmac/bolt_circle.py","linuxcnc/lib/python/plasmac/circle.py","linuxcnc/lib/python/plasmac/ellipse.py","linuxcnc/lib/python/plasmac/gusset.py","linuxcnc/lib/python/plasmac/line.py","linuxcnc/lib/python/plasmac/polygon.py","linuxcnc/lib/python/plasmac/rectangle.py","linuxcnc/lib/python/plasmac/run_from_line.py","linuxcnc/lib/python/plasmac/sector.py","linuxcnc/lib/python/plasmac/slot.py","linuxcnc/lib/python/plasmac/star.py","linuxcnc/lib/python/plasmac/triangle.py","linuxcnc/lib/python/popupkeyboard.py","linuxcnc/lib/python/propertywindow.py","linuxcnc/lib/python/pyhal.py","linuxcnc/lib/python/pyngcgui.py","linuxcnc/lib/python/pyvcp_widgets.py","linuxcnc/lib/python/qtvcp/README.txt","linuxcnc/lib/python/qtvcp/__init__.py","linuxcnc/lib/python/qtvcp/core.py","linuxcnc/lib/python/qtvcp/designer/README.txt","linuxcnc/lib/python/qtvcp/designer/install_script","linuxcnc/lib/python/qtvcp/lib/__init__.py","linuxcnc/lib/python/qtvcp/lib/audio_player.py","linuxcnc/lib/python/qtvcp/lib/auto_height/auto_height.py","linuxcnc/lib/python/qtvcp/lib/auto_height/auto_height.txt","linuxcnc/lib/python/qtvcp/lib/auto_height/auto_height.ui","linuxcnc/lib/python/qtvcp/lib/auto_height/images/auto_height.png","linuxcnc/lib/python/qtvcp/lib/aux_program_loader.py","linuxcnc/lib/python/qtvcp/lib/colored_formatter.py","linuxcnc/lib/python/qtvcp/lib/gcode_utility/__init__.py","linuxcnc/lib/python/qtvcp/lib/gcode_utility/facing.py","linuxcnc/lib/python/qtvcp/lib/gcode_utility/facing.ui","linuxcnc/lib/python/qtvcp/lib/gcode_utility/facing_help.txt","linuxcnc/lib/python/qtvcp/lib/gcode_utility/hole_circle.py","linuxcnc/lib/python/qtvcp/lib/gcode_utility/hole_circle.ui","linuxcnc/lib/python/qtvcp/lib/gcode_utility/hole_circle_help.txt","linuxcnc/lib/python/qtvcp/lib/gcode_utility/hole_enlarge.py","linuxcnc/lib/python/qtvcp/lib/gcode_utility/hole_enlarge.ui","linuxcnc/lib/python/qtvcp/lib/gcode_utility/hole_enlarge_help.html","linuxcnc/lib/python/qtvcp/lib/gcodes.py","linuxcnc/lib/python/qtvcp/lib/keybindings.py","linuxcnc/lib/python/qtvcp/lib/machine_log.py","linuxcnc/lib/python/qtvcp/lib/mdi_text.py","linuxcnc/lib/python/qtvcp/lib/message.py","linuxcnc/lib/python/qtvcp/lib/notify.py","linuxcnc/lib/python/qtvcp/lib/preferences.py","linuxcnc/lib/python/qtvcp/lib/qt_ngcgui/images/silver_dragon.png","linuxcnc/lib/python/qtvcp/lib/qt_ngcgui/ngcgui.py","linuxcnc/lib/python/qtvcp/lib/qt_ngcgui/ngcgui.ui","linuxcnc/lib/python/qtvcp/lib/qt_pdf/PDFViewer.py","linuxcnc/lib/python/qtvcp/lib/qt_pdf/setup_tab.pdf","linuxcnc/lib/python/qtvcp/lib/qt_vismach/README.txt","linuxcnc/lib/python/qtvcp/lib/qt_vismach/__init__.py","linuxcnc/lib/python/qtvcp/lib/qt_vismach/fanuc_200f.py","linuxcnc/lib/python/qtvcp/lib/qt_vismach/fanuc_200f_obj/r08_base.obj","linuxcnc/lib/python/qtvcp/lib/qt_vismach/fanuc_200f_obj/r08_j1.obj","linuxcnc/lib/python/qtvcp/lib/qt_vismach/fanuc_200f_obj/r08_j2.obj","linuxcnc/lib/python/qtvcp/lib/qt_vismach/fanuc_200f_obj/r08_j3.obj","linuxcnc/lib/python/qtvcp/lib/qt_vismach/fanuc_200f_obj/r08_j4.obj","linuxcnc/lib/python/qtvcp/lib/qt_vismach/fanuc_200f_obj/r08_j5.obj","linuxcnc/lib/python/qtvcp/lib/qt_vismach/fanuc_200f_obj/r08_j6.obj","linuxcnc/lib/python/qtvcp/lib/qt_vismach/gantry_5axis.py","linuxcnc/lib/python/qtvcp/lib/qt_vismach/mill_xyz.py","linuxcnc/lib/python/qtvcp/lib/qt_vismach/millturn.py","linuxcnc/lib/python/qtvcp/lib/qt_vismach/primitives.py","linuxcnc/lib/python/qtvcp/lib/qt_vismach/qt_vismach.py","linuxcnc/lib/python/qtvcp/lib/qt_vismach/scara.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/__init__.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_block.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_bolt.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_circle.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_ellipse.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_gusset.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_line.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_polygon.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_rectangle.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_sector.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_settings.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_slot.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_star.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conv_triangle.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/conversational.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/set_offsets.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/tooltips.py","linuxcnc/lib/python/qtvcp/lib/qtplasmac/updater.py","linuxcnc/lib/python/qtvcp/lib/ripper/gcode_ripper.py","linuxcnc/lib/python/qtvcp/lib/sys_notify.py","linuxcnc/lib/python/qtvcp/lib/toolbar_actions.py","linuxcnc/lib/python/qtvcp/lib/touchoff_subprogram.py","linuxcnc/lib/python/qtvcp/lib/virtual_keyboard.py","linuxcnc/lib/python/qtvcp/lib/writer/__init__.py","linuxcnc/lib/python/qtvcp/lib/writer/ext/__init__.py","linuxcnc/lib/python/qtvcp/lib/writer/ext/datetime.py","linuxcnc/lib/python/qtvcp/lib/writer/ext/find.py","linuxcnc/lib/python/qtvcp/lib/writer/ext/table.py","linuxcnc/lib/python/qtvcp/lib/writer/ext/wordcount.py","linuxcnc/lib/python/qtvcp/lib/writer/writer.py","linuxcnc/lib/python/qtvcp/lib/xembed.py","linuxcnc/lib/python/qtvcp/logger.py","linuxcnc/lib/python/qtvcp/plugins/__init__.py","linuxcnc/lib/python/qtvcp/plugins/actionbutton_plugin.py","linuxcnc/lib/python/qtvcp/plugins/bar_plugin.py","linuxcnc/lib/python/qtvcp/plugins/basic_probe_plugin.py","linuxcnc/lib/python/qtvcp/plugins/camview_plugin.py","linuxcnc/lib/python/qtvcp/plugins/container_plugin.py","linuxcnc/lib/python/qtvcp/plugins/detach_tabs_plugin.py","linuxcnc/lib/python/qtvcp/plugins/dialog_plugin.py","linuxcnc/lib/python/qtvcp/plugins/graphics_plugin.py","linuxcnc/lib/python/qtvcp/plugins/hal_label_plugin.py","linuxcnc/lib/python/qtvcp/plugins/jogincrements_plugin.py","linuxcnc/lib/python/qtvcp/plugins/joypad_plugin.py","linuxcnc/lib/python/qtvcp/plugins/led_plugin.py","linuxcnc/lib/python/qtvcp/plugins/nurbs_editor_plugin.py","linuxcnc/lib/python/qtvcp/plugins/overlay_plugin.py","linuxcnc/lib/python/qtvcp/plugins/qtvcp_plugin.py","linuxcnc/lib/python/qtvcp/plugins/round_gauge_plugin.py","linuxcnc/lib/python/qtvcp/plugins/round_progress_bar_plugin.py","linuxcnc/lib/python/qtvcp/plugins/screenoptions_plugin.py","linuxcnc/lib/python/qtvcp/plugins/simplewidgets_plugin.py","linuxcnc/lib/python/qtvcp/plugins/state_label_plugin.py","linuxcnc/lib/python/qtvcp/plugins/state_led_plugin.py","linuxcnc/lib/python/qtvcp/plugins/status_adjustment_bar_plugin.py","linuxcnc/lib/python/qtvcp/plugins/status_label_plugin.py","linuxcnc/lib/python/qtvcp/plugins/status_slider_plugin.py","linuxcnc/lib/python/qtvcp/plugins/tab_widget_plugin.py","linuxcnc/lib/python/qtvcp/plugins/toolbutton_plugin.py","linuxcnc/lib/python/qtvcp/plugins/versa_probe_plugin.py","linuxcnc/lib/python/qtvcp/plugins/virtualkeyboard_plugin.py","linuxcnc/lib/python/qtvcp/plugins/web_widget_plugin.py","linuxcnc/lib/python/qtvcp/plugins/widgets_plugin.py","linuxcnc/lib/python/qtvcp/qt_action.py","linuxcnc/lib/python/qtvcp/qt_istat.py","linuxcnc/lib/python/qtvcp/qt_makegui.py","linuxcnc/lib/python/qtvcp/qt_makepins.py","linuxcnc/lib/python/qtvcp/qt_pstat.py","linuxcnc/lib/python/qtvcp/qt_tstat.py","linuxcnc/lib/python/qtvcp/qtvcp_handler.py","linuxcnc/lib/python/qtvcp/test1.ui","linuxcnc/lib/python/qtvcp/widgets/__init__.py","linuxcnc/lib/python/qtvcp/widgets/action_button.py","linuxcnc/lib/python/qtvcp/widgets/action_button_round.py","linuxcnc/lib/python/qtvcp/widgets/action_tool_button.py","linuxcnc/lib/python/qtvcp/widgets/adjustment_bar.py","linuxcnc/lib/python/qtvcp/widgets/axis_tool_button.py","linuxcnc/lib/python/qtvcp/widgets/bar.py","linuxcnc/lib/python/qtvcp/widgets/basic_probe.py","linuxcnc/lib/python/qtvcp/widgets/calculator.py","linuxcnc/lib/python/qtvcp/widgets/camview_widget.py","linuxcnc/lib/python/qtvcp/widgets/container_widgets.py","linuxcnc/lib/python/qtvcp/widgets/detach_tabs.py","linuxcnc/lib/python/qtvcp/widgets/dialogMixin.py","linuxcnc/lib/python/qtvcp/widgets/dialog_widget.py","linuxcnc/lib/python/qtvcp/widgets/dro_widget.py","linuxcnc/lib/python/qtvcp/widgets/entry_widget.py","linuxcnc/lib/python/qtvcp/widgets/fake_status.py","linuxcnc/lib/python/qtvcp/widgets/file_manager.py","linuxcnc/lib/python/qtvcp/widgets/gcode_editor.py","linuxcnc/lib/python/qtvcp/widgets/gcode_graphics.py","linuxcnc/lib/python/qtvcp/widgets/geditor.py","linuxcnc/lib/python/qtvcp/widgets/general_hal_input.py","linuxcnc/lib/python/qtvcp/widgets/general_hal_output.py","linuxcnc/lib/python/qtvcp/widgets/hal_label.py","linuxcnc/lib/python/qtvcp/widgets/hal_selectionbox.py","linuxcnc/lib/python/qtvcp/widgets/image_switcher.py","linuxcnc/lib/python/qtvcp/widgets/jog_increments.py","linuxcnc/lib/python/qtvcp/widgets/joypad.py","linuxcnc/lib/python/qtvcp/widgets/led_widget.py","linuxcnc/lib/python/qtvcp/widgets/machine_log.py","linuxcnc/lib/python/qtvcp/widgets/macro_widget.py","linuxcnc/lib/python/qtvcp/widgets/mdi_history.py","linuxcnc/lib/python/qtvcp/widgets/mdi_line.py","linuxcnc/lib/python/qtvcp/widgets/mdi_touchy.py","linuxcnc/lib/python/qtvcp/widgets/nurbs_editor.py","linuxcnc/lib/python/qtvcp/widgets/offset_tool_button.py","linuxcnc/lib/python/qtvcp/widgets/origin_offsetview.py","linuxcnc/lib/python/qtvcp/widgets/overlay_widget.py","linuxcnc/lib/python/qtvcp/widgets/probe_routines.py","linuxcnc/lib/python/qtvcp/widgets/probe_subprog.py","linuxcnc/lib/python/qtvcp/widgets/qtvcp_icons.py","linuxcnc/lib/python/qtvcp/widgets/radio_axis_selector.py","linuxcnc/lib/python/qtvcp/widgets/richtext_selector.py","linuxcnc/lib/python/qtvcp/widgets/round_gauge.py","linuxcnc/lib/python/qtvcp/widgets/round_progress.py","linuxcnc/lib/python/qtvcp/widgets/runFromLine_dialog.py","linuxcnc/lib/python/qtvcp/widgets/screen_options.py","linuxcnc/lib/python/qtvcp/widgets/simple_widgets.py","linuxcnc/lib/python/qtvcp/widgets/state_label.py","linuxcnc/lib/python/qtvcp/widgets/state_led.py","linuxcnc/lib/python/qtvcp/widgets/status_label.py","linuxcnc/lib/python/qtvcp/widgets/status_slider.py","linuxcnc/lib/python/qtvcp/widgets/status_stacked.py","linuxcnc/lib/python/qtvcp/widgets/stylesheeteditor.py","linuxcnc/lib/python/qtvcp/widgets/system_tool_button.py","linuxcnc/lib/python/qtvcp/widgets/tab_widget.py","linuxcnc/lib/python/qtvcp/widgets/tool_offsetview.py","linuxcnc/lib/python/qtvcp/widgets/touchEntry.py","linuxcnc/lib/python/qtvcp/widgets/versa_probe.py","linuxcnc/lib/python/qtvcp/widgets/virtualkeyboard.py","linuxcnc/lib/python/qtvcp/widgets/web_widget.py","linuxcnc/lib/python/qtvcp/widgets/widget_baseclass.py","linuxcnc/lib/python/qtvcp/widgets/widget_icons/actionbutton.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/axistoolbutton.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/basicprobe.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/calculator.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/checkbox.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/dial.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/dialogbuttonbox.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/doublescale.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/dro_label.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/filemanager.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/focusoverlay.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/gauge.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/gcodeeditor.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/gcodegraphics.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/generalhalinput.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/generalhaloutput.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/hallabel.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/jogincrements.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/lcdnumber.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/lcnc_led.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/led.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/linuxcnc-wizard.gif","linuxcnc/lib/python/qtvcp/widgets/widget_icons/mdihistory.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/mdiline.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/originoffsetview.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/progress.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/pushbutton.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/radioaxisselector.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/radiobutton.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/screenoptions.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/slider.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/statusadjustmentbar.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/statuslabel.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/statusslider.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/systemtoolbutton.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/tabwidget.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/textedit.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/tooloffsetview.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/versaprobe.png","linuxcnc/lib/python/qtvcp/widgets/widget_icons/widgetswitcher.png","linuxcnc/lib/python/qtvcp/widgets/widget_switcher.py","linuxcnc/lib/python/qtvcp/widgets/xembed.py","linuxcnc/lib/python/raster.py","linuxcnc/lib/python/rs274/OpenGLTk.py","linuxcnc/lib/python/rs274/__init__.py","linuxcnc/lib/python/rs274/author.py","linuxcnc/lib/python/rs274/glcanon.py","linuxcnc/lib/python/rs274/interpret.py","linuxcnc/lib/python/rs274/options.py","linuxcnc/lib/python/tooldb.py","linuxcnc/lib/python/vcpparse.py","linuxcnc/lib/python/vismach.py","linuxcnc/linuxcnc.gif"]); export const SIM_HAL_COMPONENTS = Object.freeze(["abs","abs_s32","abs_s64","and2","anglejog","axistest","bin2gray","biquad","bitslice","bitwise","bldc","blend","carousel","charge_pump","clarke2","clarke3","clarkeinv","comp","constant","conv_bit_float","conv_bit_s32","conv_bit_s64","conv_bit_u32","conv_bit_u64","conv_float_s32","conv_float_s64","conv_float_u32","conv_float_u64","conv_s32_bit","conv_s32_float","conv_s32_s64","conv_s32_u32","conv_s32_u64","conv_s64_bit","conv_s64_float","conv_s64_s32","conv_s64_u32","conv_s64_u64","conv_u32_bit","conv_u32_float","conv_u32_s32","conv_u32_s64","conv_u32_u64","conv_u64_bit","conv_u64_float","conv_u64_s32","conv_u64_s64","conv_u64_u32","corexy_by_hal","dbounce","ddt","deadzone","demux","differential","div2","edge","eoffset_per_angle","estop_latch","feedcomp","filter_kalman","flipflop","gantry","gearchange","gray2bin","histobins","homecomp","hypot","ilowpass","integ","invert","joyhandle","knob2float","laserpower","latencybins","led_dim","limit1","limit2","limit3","limit_axis","lincurve","logic","lowpass","lut5","maj3","match8","matrixkins","max31855","mesa_pktgyro_test","message","millturn","minmax","moveoff","mult2","multiclick","multiswitch","mux16","mux2","mux4","mux8","near","not","offset","ohmic","oneshot","or2","orient","plasmac","raster","reset","safety_latch","sample_hold","scale","scaled_s32_sums","select8","sim_axis_hardware","sim_home_switch","sim_matrix_kb","sim_parport","sim_spindle","simple_tp","sphereprobe","spindle","spindle_monitor","steptest","sum2","thc","thcud","threadtest","time","timedelay","timedelta","tof","toggle","toggle2nist","ton","tp","tpcomp","tristate_bit","tristate_float","updown","userkins","wcomp","xhc_hb04_util","xor2","xyzab_tdr_kins"]); -export const SIM_CASE_CATALOG_META = Object.freeze({"sim_root":"linuxcnc/configs/sim","case_count":235,"file_count":2000,"catalog_sha256":"ac762b8b27b4b7988c0c8c532c6299a0957a69538ccb42bc65f78593b8ab4815"}); +export const SIM_CASE_CATALOG_META = Object.freeze({"sim_root":"linuxcnc/configs/sim","case_count":236,"file_count":2006,"catalog_sha256":"3c35f4b6df095ea0c4d3fcaacab1b5eee08274e451e0229b9668ca6107ef0167"}); diff --git a/web/workspace/sim-case-loader.mjs b/web/workspace/sim-case-loader.mjs index 4631936..b13530b 100644 --- a/web/workspace/sim-case-loader.mjs +++ b/web/workspace/sim-case-loader.mjs @@ -5,17 +5,18 @@ import { isOptionalSourceKey } from "./linuxcnc-source-semantics.mjs"; export const SIMULATION_CASE_SCHEMA = "simulation-case-bundle.v1"; const RESOURCE_KEYS = new Set([ - "HAL", "HALFILE", "TOOLTABLE", "TOOL_TABLE", "VARFILE", "PARAMETER_FILE", "OPEN_FILE", + "HAL", "HALFILE", "POSTGUI_HALFILE", "TOOLTABLE", "TOOL_TABLE", "VARFILE", "PARAMETER_FILE", "OPEN_FILE", "PROGRAM", "PROGRAMS", "PYTHON", "PYTHONFILE", "VCP", "VCPFILE", "CLPFILE", - "CLASSICLADDER", "INTRO_GRAPHIC", + "PYVCP", "NGCGUI_SUBFILE", "INTRO_GRAPHIC", "SUBROUTINE_PATH", "REMAP", ]); const MANIFEST = new Set(SIM_FILE_INDEX); -const PRELOADED_HAL_COMPONENTS = Object.freeze(["corexykins", "lineardeltakins", "motmod", "pid", "rotarydeltakins", "stepgen", "trivkins", "tpmod", "homemod"]); +const PRELOADED_HAL_COMPONENTS = Object.freeze(["corexykins", "lineardeltakins", "motmod", "pid", "rotarydeltakins", "stepgen", "trivkins", "xyzac-trt-kins", "xyzbc-trt-kins", "tpmod", "homemod"]); const CASE_KINEMATICS = Object.freeze({ "linuxcnc/configs/sim/axis/corexy/corexy_by_kins.ini": Object.freeze({ type: "corexy", path_mode: "kins" }), "linuxcnc/configs/sim/axis/corexy/corexy_by_hal.ini": Object.freeze({ type: "corexy", path_mode: "hal" }), "linuxcnc/configs/sim/axis/ldelta.ini": Object.freeze({ type: "lineardelta", path_mode: "kins" }), "linuxcnc/configs/sim/axis/rdelta.ini": Object.freeze({ type: "rotarydelta", path_mode: "kins" }), + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini": Object.freeze({ type: "xyzac-trt", path_mode: "wasm", coordinates: "XYZAC", joint_count: 5, max_linear_velocity: 35, switchkins: { 0: "identity", 1: "xyzac", 2: "userk" }, offsets: { x_rot_point: 0, y_offset: 20, z_offset: 10, tool_offset: 0 } }), }); const RUNTIME_FIXTURES = Object.freeze({ "linuxcnc/configs/sim/axis/minimal_xyz.ini": Object.freeze({ @@ -42,6 +43,12 @@ const RUNTIME_FIXTURES = Object.freeze({ with: "HALFILE = xz_both_auto_cmds.hal", reason: "LinuxCNC basic_sim.tcl generated XZ BOTH AUTO HAL command fixture", }), + "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini": Object.freeze({ + generated_hal: "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal", + replace: "HALFILE = LIB:basic_sim.tcl", + with: "HALFILE = xyzac-trt-headless_cmds.hal", + reason: "LinuxCNC basic_sim.tcl generated XYZAC HAL command fixture", + }), }); function clone(value) { return structuredClone(value); } @@ -82,6 +89,10 @@ function candidates(source, raw, key = null, section = null) { const libraryPath = normalize(`linuxcnc/lib/hallib/${name}`); return libraryPath ? [libraryPath] : []; } + if (["NGCGUI_SUBFILE", "REMAP"].includes(String(key).toUpperCase())) { + const subroutine = normalize(`${dirname(source)}/remap_subs/${first}`); + if (subroutine) return [subroutine]; + } if (["HAL", "HALFILE"].includes(String(key).toUpperCase()) && !first.includes("/") && !first.startsWith("linuxcnc/")) { const halCandidates = [normalize(`${dirname(source)}/${first}`), `linuxcnc/lib/hallib/${first}`].filter(Boolean); const indexed = halCandidates.filter(inManifest); @@ -128,6 +139,16 @@ function resourceReferences(source, content) { const line = rawLine.split("#", 1)[0].trim(); const sectionMatch = line.match(/^\[([^\]]+)\]$/); if (sectionMatch) { section = sectionMatch[1].trim(); continue; } + if (section === "RS274NGC" && /^SUBROUTINE_PATH\s*=\s*/i.test(line)) { + const directory = normalize(`${dirname(source)}/${line.split("=", 2)[1].trim()}`); + for (const candidate of SIM_FILE_INDEX.filter((path) => directory && path.startsWith(`${directory}/`) && path.endsWith(".ngc"))) references.push({ path: candidate, key: "SUBROUTINE_PATH", section, source }); + continue; + } + if (section === "RS274NGC" && /^REMAP\s*=\s*/i.test(line)) { + const name = /ngc=([^\s]+)/i.exec(line)?.[1]; + if (name) { const candidate = normalize(`${dirname(source)}/remap_subs/${name}.ngc`); if (candidate) references.push({ path: candidate, key: "REMAP", section, source }); } + continue; + } const assignment = line.match(/^([^=:#]+?)\s*(?:=|:)\s*(.*)$/); if (assignment && RESOURCE_KEYS.has(assignment[1].trim().toUpperCase())) { const key = assignment[1].trim().toUpperCase(); @@ -236,6 +257,7 @@ export function toWorkerConfiguration(bundle) { optional_missing: clone(bundle.optional_missing ?? []), runtime_fixtures: clone(bundle.runtime_fixtures ?? []), ...(bundle.entrypoint === "linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini" ? { home_limits: { z: [-240, 100] } } : {}), + ...(bundle.entrypoint === "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini" ? { home_limits: { joint_count: 5, kinematics_type: 2, coordinates: "XYZAC", x: [-200, 200], y: [-100, 100], z: [-120, 120], a: [-100, 50], c: [-36000, 36000] } } : {}), ...(CASE_KINEMATICS[bundle.entrypoint] ? { kinematics: clone(CASE_KINEMATICS[bundle.entrypoint]) } : {}), }; } diff --git a/web/workspace/xyzac-trt-case-contract.mjs b/web/workspace/xyzac-trt-case-contract.mjs new file mode 100644 index 0000000..84d7da5 --- /dev/null +++ b/web/workspace/xyzac-trt-case-contract.mjs @@ -0,0 +1,165 @@ +export const XYZAC_TRT_CASE_CONTRACT = Object.freeze({ + "authority": "linuxcnc-wasm-worker", + "case": { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "sha256": "f985970db293b70c055e4c41fc316d0c16037b5dc7ce07490e18f554e851f811", + "status": "indexed" + }, + "commands": [ + "MDI_EXECUTE", + "PROGRAM_LOAD", + "PROGRAM_RUN", + "PROGRAM_PAUSE", + "PROGRAM_RESUME", + "PROGRAM_ABORT", + "JOG_START", + "JOG_STOP", + "HOME", + "KINEMATICS_SELECT", + "SNAPSHOT_REQUEST" + ], + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "js_authority": 0, + "report_sha256": "817531c109c341ccda78b085d2613f35379a716a98f54c9561a118f995b6cd5e", + "resources": [ + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "role": "case-entrypoint", + "sha256": "f985970db293b70c055e4c41fc316d0c16037b5dc7ce07490e18f554e851f811", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.xml", + "role": "PYVCP", + "sha256": "84efa01584693ab8f4a9c0730e341a9dbe87d9341472081ee80d59a0bfb90941", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins_postgui.hal", + "role": "POSTGUI_HALFILE", + "sha256": "55e969c22ca9054a818dbedc8ec50bed768d9ab3d8c4bfdfcfc78e912e9271c4", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.tbl", + "role": "TOOL_TABLE", + "sha256": "41cf3c92574be99ecd6ed45e1869158b184620419d5d95a41649d25f15e141ff", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac.var", + "role": "PARAMETER_FILE", + "sha256": "163bbf80485fe2fe12700c1acb4b05eff774df68176d17e4eef5de8a7024c1ae", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc", + "role": "OPEN_FILE", + "sha256": "5afc03d5c1b692edd4154a6d37e5f94d74936a7bd5e82dc9c022f7bc21c7dc17", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc", + "role": "REMAP:M428", + "sha256": "a0aee1d6b481a979849a17c0a23aa7524f52cbd875c92cbde3b73bf36f91d17b", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc", + "role": "REMAP:M429", + "sha256": "160479860b84e55ace49ffceb9594285ee90c521ba5eef916ef47ac8a6b3349d", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc", + "role": "REMAP:M430", + "sha256": "41090461a936a63432252d42f277c925f9aa5a0faf0497933910c3b051fcfe4f", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/xyzac_switchkins_sub.ngc", + "role": "NGCGUI_SUBFILE", + "sha256": "833bf21b8ed0ce600dcf5819234320d85348d906bbba390b62f3704836ea254d", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/centering.ngc", + "role": "NGCGUI_SUBFILE", + "sha256": "58cf585aa10480a80fe8ac8f2eab5e877adca51b4b3518b337eab476de01b11c", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_ac.ngc", + "role": "RTCP-SUBROUTINE", + "sha256": "06cb755e33dc35d9a179b3c48e4203c8469632ab248d94379b10f2538dd0b54a", + "status": "resolved" + }, + { + "path": "linuxcnc/lib/hallib/basic_sim.tcl", + "role": "HALFILE:LIB:basic_sim.tcl", + "sha256": "d9851b0a8861e6d66de745a8ae230d4b38b65c34f8b05bdb6705792d2d4050be", + "status": "resolved" + }, + { + "path": "linuxcnc/linuxcnc.gif", + "role": "INTRO_GRAPHIC", + "sha256": "6c6da4afc3ecdc1b812dd6878318da0120996bd6889b4dd2ddb480b905d9f4b1", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc", + "role": "DEMO_PROGRAM", + "sha256": "4d4769cbbb47ad7bf82c12bb1545c3854addebebe4642a3f50c8ccf5c560bcda", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc", + "role": "DEMO_PROGRAM", + "sha256": "f46a1f485ca85e4e9900b7a9b4f59fed7fc9d7cf27a403e15841b933ab98f0bf", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc", + "role": "DEMO_PROGRAM", + "sha256": "e90f0b4b6c43809da94a8170ee1029b5afc3e1bbe9bf2ae66298a8baefad013c", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc", + "role": "DEMO_PROGRAM", + "sha256": "3cdffc0481c1d6b0a0a67151a06448c686d4109249ed73438d5ff4e72b9e7267", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_2.ngc", + "role": "DEMO_PROGRAM", + "sha256": "a0b05e672e7f8b5d9c8f42ac3fd16320f68a67926ae1413d361d60cc508d953f", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_3.ngc", + "role": "DEMO_PROGRAM", + "sha256": "0e7e3c2fe554f888d3f5ef055390a7153ffa7f9eeedaac116f78832ff7a31cc1", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc", + "role": "DEMO_PROGRAM", + "sha256": "75db56e24242b68e32a9a7f1943fe240c5f518cc1866ee823ea158f9f87ce9fe", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_bc.ngc", + "role": "REMAP_SUBROUTINE", + "sha256": "2b8b36bf78d9227bd061083f883c72c7b0b205a8fe6d0a9407203b5375fe89fa", + "status": "resolved" + }, + { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/xyzbc_switchkins_sub.ngc", + "role": "REMAP_SUBROUTINE", + "sha256": "7265e848d0e123f439208caa88afccdf2803f34770042c778a8797a25d44537a", + "status": "resolved" + } + ], + "schema": "xyzac-trt-case-contract.v1" +}); diff --git a/web/workspace/xyzac-trt-case-loader.mjs b/web/workspace/xyzac-trt-case-loader.mjs new file mode 100644 index 0000000..f1d6eca --- /dev/null +++ b/web/workspace/xyzac-trt-case-loader.mjs @@ -0,0 +1,127 @@ +import { fnv1a64 } from "../worker/replay.mjs"; +import { WorkspaceRuntime } from "./runtime.mjs"; +import { parseIni } from "./ini-parser.mjs"; +import { ConfigurationStartupStateMachine } from "./configuration-startup.mjs"; +import { loadSimulationCase, toWorkerConfiguration } from "./sim-case-loader.mjs"; + +export const XYZAC_TRT_CASE_LOADER_SCHEMA = "xyzac-trt-case-loader.v1"; +export const XYZAC_TRT_CASE = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini"; +export const XYZAC_TRT_STARTUP_STATES = Object.freeze(["TASK_NEW", "CONFIG_RESOLVED", "HAL_READY", "RUNTIME_READY", "TASK_READY"]); + +const CASE_DIR = "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting"; +const REQUIRED_RESOURCES = Object.freeze([ + [XYZAC_TRT_CASE, "case_entrypoint"], + [`${CASE_DIR}/xyzac-trt.xml`, "pyvcp"], + [`${CASE_DIR}/switchkins_postgui.hal`, "postgui_hal"], + [`${CASE_DIR}/xyzac-trt.tbl`, "tool_table"], + [`${CASE_DIR}/xyzac.var`, "parameter_file"], + [`${CASE_DIR}/demos/xyzac_switchkins.ngc`, "open_file"], + [`${CASE_DIR}/remap_subs/428remap.ngc`, "remap_m428"], + [`${CASE_DIR}/remap_subs/429remap.ngc`, "remap_m429"], + [`${CASE_DIR}/remap_subs/430remap.ngc`, "remap_m430"], + [`${CASE_DIR}/remap_subs/xyzac_switchkins_sub.ngc`, "ngcgui_subfile"], + [`${CASE_DIR}/remap_subs/centering.ngc`, "ngcgui_subfile"], + [`${CASE_DIR}/remap_subs/helix_ac.ngc`, "rtcp_subroutine"], + ["linuxcnc/src/hal/user_comps/vismach/xyzac-trt-gui.py", "vismach_source"], + ["linuxcnc/lib/hallib/basic_sim.tcl", "hal_library"], + ["linuxcnc/linuxcnc.gif", "intro_graphic"], +]); +const REQUIRED_SECTIONS = Object.freeze(["DISPLAY", "TASK", "HAL", "RS274NGC", "KINS", "TRAJ", "EMCIO"]); + +function clone(value) { return structuredClone(value); } + +async function readExact(fetchImpl, baseUrl, path) { + try { + const response = await fetchImpl(`${String(baseUrl ?? "").replace(/\/$/, "")}/${path}`.replace(/^\//, "/")); + if (!response?.ok) return null; + return await response.text(); + } catch { return null; } +} + +function resourceRows(files) { + return REQUIRED_RESOURCES.map(([path, role]) => { + const content = files[path]; + return { + path, + role, + status: typeof content === "string" ? "resolved" : "BLOCKED_RESOURCE", + bytes: typeof content === "string" ? new TextEncoder().encode(content).byteLength : null, + data_hash: typeof content === "string" ? fnv1a64(content) : null, + }; + }); +} + +function xyzacSections(parsed) { + const sections = Object.keys(parsed.sections ?? {}).map((name) => name.toUpperCase()); + return Object.fromEntries(REQUIRED_SECTIONS.map((name) => [name, sections.includes(name)])); +} + +function startupProjection(startup, exactResources, sections) { + const generic = startup; + const resolved = exactResources.every((row) => row.status === "resolved"); + const requiredSections = Object.values(sections).every(Boolean); + const state = generic.state === "TASK_READY" && resolved && requiredSections ? "TASK_READY" : generic.state === "BLOCKED" ? "BLOCKED" : "RUNTIME_READY"; + const transitions = [{ from: null, to: "TASK_NEW" }]; + if (generic.state !== "BLOCKED") { + transitions.push({ from: "TASK_NEW", to: "CONFIG_RESOLVED" }); + transitions.push({ from: "CONFIG_RESOLVED", to: "HAL_READY" }); + transitions.push({ from: "HAL_READY", to: "RUNTIME_READY" }); + if (state === "TASK_READY") transitions.push({ from: "RUNTIME_READY", to: "TASK_READY" }); + } else transitions.push({ from: "TASK_NEW", to: "BLOCKED" }); + return { + schema: "xyzac-trt-startup.v1", + state, + status: state === "TASK_READY" ? "ready" : "blocked", + transitions, + generic_state: generic.state, + generic_status: generic.status, + diagnostics: generic.diagnostics, + hal: generic.hal, + exact_resources: exactResources, + required_sections: sections, + state_hash: fnv1a64({ state, transitions, diagnostics: generic.diagnostics, exact_resources: exactResources, required_sections: sections }), + }; +} + +export async function loadXyzacTrtCase({ fetchImpl = globalThis.fetch, baseUrl = "", core = null, task = null } = {}) { + if (typeof fetchImpl !== "function") throw new Error("xyzac_case_fetch_required"); + const bundle = await loadSimulationCase({ path: XYZAC_TRT_CASE, fetchImpl, baseUrl }); + const files = { ...bundle.files }; + for (const [path] of REQUIRED_RESOURCES) if (!(path in files)) { + const content = await readExact(fetchImpl, baseUrl, path); + if (content !== null) files[path] = content; + } + const exact = resourceRows(files); + const caseText = files[XYZAC_TRT_CASE]; + const workspace = new WorkspaceRuntime({ files }); + let parsed = null; + let startup = null; + let parsedError = null; + try { + parsed = parseIni({ workspace, entrypoint: XYZAC_TRT_CASE }); + const machine = new ConfigurationStartupStateMachine({ workspace, entrypoint: XYZAC_TRT_CASE, core, task, halManifest: bundle.halManifest ?? [] }); + startup = startupProjection(machine.run(), exact, xyzacSections(parsed)); + } catch (error) { + parsedError = { code: error?.code ?? "xyzac_startup_exception", message: String(error?.message ?? error) }; + } + const sections = parsed ? xyzacSections(parsed) : Object.fromEntries(REQUIRED_SECTIONS.map((name) => [name, false])); + const missing = exact.filter((row) => row.status !== "resolved").map((row) => row.path); + const unsigned = { + schema: XYZAC_TRT_CASE_LOADER_SCHEMA, + case: XYZAC_TRT_CASE, + case_hash: typeof caseText === "string" ? fnv1a64(caseText) : null, + bundle_status: bundle.status, + bundle_hash: bundle.state_hash, + fetched: [...new Set(bundle.fetched ?? [])].sort(), + missing: [...new Set([...(bundle.missing ?? []), ...missing])].sort(), + exact_resources: exact, + required_sections: sections, + ini: parsed ? { state_hash: parsed.state_hash, graph: parsed.graph, includes: parsed.includes } : null, + startup, + parsed_error: parsedError, + machine: { coordinates: "XYZAC", joint_count: 5, rotary_units: "degrees", kinematics: "xyzac-trt", switchkins: { 0: "identity", 1: "xyzac", 2: "userk" } }, + }; + return { ...clone(unsigned), status: startup?.status === "ready" && missing.length === 0 ? "ready" : "blocked", state_hash: fnv1a64(unsigned), worker_configuration: toWorkerConfiguration({ ...bundle, files, missing: unsigned.missing, status: unsigned.missing.length ? "blocked" : "ready" }) }; +} + +export { REQUIRED_RESOURCES, REQUIRED_SECTIONS }; diff --git a/web/workspace/xyzac-trt-source-slices.mjs b/web/workspace/xyzac-trt-source-slices.mjs new file mode 100644 index 0000000..cae7c61 --- /dev/null +++ b/web/workspace/xyzac-trt-source-slices.mjs @@ -0,0 +1,1996 @@ +export const XYZAC_TRT_SOURCE_SLICES = Object.freeze({ + "authority": { + "authority_owner": "linuxcnc-wasm-worker", + "existing_audit": { + "open_boundaries": [ + "T1_FULL_CANONICAL_CALLBACKS", + "T2_FULL_WASM_PREVIEW", + "T3_NON_SELECTED_MOTION_AUTHORITY", + "T4_HAL_IO_TOOL_PROBE_CANONICAL_STATE", + "T5_FULL_MATRIX" + ], + "path": "coverage/wasm-only-source-audit.report.json", + "status": "blocked" + }, + "js_authority": 0 + }, + "axis_controls": { + "keyboard_bindings": [ + { + "binding": "Alt-v", + "control_id": "AXIS-KEY-ALT_V", + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": "2242-2243", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "bind" + } + }, + { + "binding": "Button-1", + "control_id": "AXIS-KEY-BUTTON_1", + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": null, + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "bind" + } + }, + { + "binding": "ButtonRelease-1", + "control_id": "AXIS-KEY-BUTTONRELEASE_1", + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": null, + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "bind" + } + }, + { + "binding": "Configure", + "control_id": "AXIS-KEY-CONFIGURE", + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": "2234-2234", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "bind" + } + }, + { + "binding": "Control-Tab", + "control_id": "AXIS-KEY-CONTROL_TAB", + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": "1989-1989", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "bind" + } + }, + { + "binding": "Key-Escape", + "control_id": "AXIS-KEY-KEY_ESCAPE", + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": "1551-1607", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "bind" + } + }, + { + "binding": "Key-Return", + "control_id": "AXIS-KEY-KEY_RETURN", + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": "1550-2245", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "bind" + } + }, + { + "binding": "greater", + "control_id": "AXIS-KEY-GREATER", + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": "1406-1406", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "bind" + } + }, + { + "binding": "less", + "control_id": "AXIS-KEY-LESS", + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": "1405-1405", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "bind" + } + }, + { + "binding": "semicolon", + "control_id": "AXIS-KEY-SEMICOLON", + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": "1430-1430", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "bind" + } + } + ], + "keyboard_count": 10, + "menu_count": 80, + "menus": [ + { + "control_id": "AXIS-MENU-FILE-_OPEN...", + "label_source": "\"_Open...\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "58-58", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-FILE-RECENT__FILES", + "label_source": "\"Recent _Files\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "62-62", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-FILE-_EDIT...", + "label_source": "\"_Edit...\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "66-66", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-FILE-_RELOAD", + "label_source": "\"_Reload\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "71-71", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-FILE-_SAVE_G-CODE_AS...", + "label_source": "\"_Save G-code as...\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "76-76", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-FILE-_PROPERTIES...", + "label_source": "\"_Properties...\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "80-80", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-FILE-EDIT__TOOL_DATA...", + "label_source": "\"Edit _tool data...\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "86-86", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-FILE-RELOAD_TOOL__DATA", + "label_source": "\"Reload tool _data\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "90-90", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-FILE-_LADDER_EDITOR...", + "label_source": "\"_Ladder Editor...\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "96-96", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-FILE-_QUIT", + "label_source": "\"_Quit\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "102-102", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-TOGGLE__EMERGENCY_STOP", + "label_source": "\"Toggle _Emergency Stop\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "108-108", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-TOGGLE__MACHINE_POWER", + "label_source": "\"Toggle _Machine Power\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "113-113", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-_RUN_PROGRAM", + "label_source": "\"_Run program\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "120-120", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-RU_N_FROM_SELECTED_LINE", + "label_source": "\"Ru_n from selected line\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "124-124", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-S_TEP", + "label_source": "\"S_tep\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "129-129", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-_PAUSE", + "label_source": "\"_Pause\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "134-134", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-RE_SUME", + "label_source": "\"Re_sume\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "139-139", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-STOP", + "label_source": "\"Stop\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "144-144", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-STOP_AT_M_1", + "label_source": "\"Stop at M_1\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "149-149", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-SKIP_LINES_WITH__/", + "label_source": "\"Skip lines with '_/'\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "154-154", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAR_MDI_H_ISTORY", + "label_source": "\"Clear MDI h_istory\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "161-161", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-COPY_FROM_MDI_HIST_ORY", + "label_source": "\"Copy from MDI hist_ory\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "165-165", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-PASTE_TO_MDI_HISTOR_Y", + "label_source": "\"Paste to MDI histor_y\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "169-169", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-_CALIBRATION", + "label_source": "\"_Calibration\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "175-175", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-SHOW__HAL_CONFIGURATION", + "label_source": "\"Show _Hal Configuration\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "179-179", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-H_AL_METER", + "label_source": "\"H_al Meter\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "183-183", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-HA_L_SCOPE", + "label_source": "\"Ha_l Scope\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "187-187", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-SHO_W_LINUXCNC_STATUS", + "label_source": "\"Sho_w LinuxCNC Status\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "191-191", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-SET__DEBUG_LEVEL", + "label_source": "\"Set _Debug Level\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "195-195", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-HOMIN_G", + "label_source": "\"Homin_g\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "201-201", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-_UNHOMING", + "label_source": "\"_Unhoming\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "205-205", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-_ZERO_COORDINATE_SYSTEM", + "label_source": "\"_Zero coordinate system\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "209-209", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAROFFSET-P1__G5_4", + "label_source": "\"P1 G5_4\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "213-213", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAROFFSET-P2__G5_5", + "label_source": "\"P2 G5_5\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "217-217", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAROFFSET-P3__G5_6", + "label_source": "\"P3 G5_6\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "221-221", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAROFFSET-P4__G5_7", + "label_source": "\"P4 G5_7\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "225-225", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAROFFSET-P5__G5_8", + "label_source": "\"P5 G5_8\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "229-229", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAROFFSET-P6__G5_9", + "label_source": "\"P6 G5_9\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "233-233", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAROFFSET-P7__G59._1", + "label_source": "\"P7 G59._1\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "237-237", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAROFFSET-P8__G59._2", + "label_source": "\"P8 G59._2\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "241-241", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAROFFSET-P9__G59._3", + "label_source": "\"P9 G59._3\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "245-245", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-CLEAROFFSET-_G92", + "label_source": "\"_G92\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "249-249", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-TOOL_TOUCH_OFF_TO_WOR_KPIECE", + "label_source": "\"Tool touch off to wor_kpiece\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "257-257", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-MACHINE-TOOL_TOUCH_OFF_TO__FIXTURE", + "label_source": "\"Tool touch off to _fixture\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "263-263", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-_TOP_VIEW", + "label_source": "\"_Top view\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "271-271", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-_ROTATED_TOP_VIEW", + "label_source": "\"_Rotated Top view\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "278-278", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-_SIDE_VIEW", + "label_source": "\"_Side view\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "285-285", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-_FRONT_VIEW", + "label_source": "\"_Front view\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "292-292", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-_PERSPECTIVE_VIEW", + "label_source": "\"_Perspective view\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "299-299", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-DISPLAY__INCHES", + "label_source": "\"Display _Inches\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "308-308", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-DISPLAY__MM", + "label_source": "\"Display _MM\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "315-315", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-S_HOW_PROGRAM", + "label_source": "\"S_how program\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "322-322", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW_PROGRAM_R_APIDS", + "label_source": "\"Show program r_apids\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "327-327", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-ALPHA-_BLEND_PROGRAM", + "label_source": "\"Alpha-_blend program\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "332-332", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHO_W_LIVE_PLOT", + "label_source": "\"Sho_w live plot\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "337-337", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW_TOO_L", + "label_source": "\"Show too_l\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "342-342", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW_E_XTENTS", + "label_source": "\"Show e_xtents\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "347-347", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-_GRID", + "label_source": "\"_Grid\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "351-351", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW_O_FFSETS", + "label_source": "\"Show o_ffsets\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "356-356", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SH_OW_MACHINE_LIMITS", + "label_source": "\"Sh_ow machine limits\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "361-361", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW_V_ELOCITY", + "label_source": "\"Show v_elocity\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "366-366", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW__DISTANCE_TO_GO", + "label_source": "\"Show _distance to go\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "371-371", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-LARGE_COORDINATE_FO_NT", + "label_source": "\"Large coordinate fo_nt\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "376-376", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-_CLEAR_LIVE_PLOT", + "label_source": "\"_Clear live plot\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "381-381", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW_PYVCP_PAN_EL", + "label_source": "\"Show PyVCP pan_el\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "387-387", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW_COMMANDED_POSITION", + "label_source": "\"Show commanded position\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "396-396", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW_ACTUAL_POSITION", + "label_source": "\"Show actual position\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "403-403", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW_MACHINE_POSITION", + "label_source": "\"Show machine position\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "412-412", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-SHOW_RELATIVE_POSITION", + "label_source": "\"Show relative position\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "419-419", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-JOINT_MODE", + "label_source": "\"Joint mode\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "428-428", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-WORLD_MODE", + "label_source": "\"World mode\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "435-435", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-GRID-_OFF", + "label_source": "\"_Off\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "443-443", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-VIEW-GRID-_CUSTOM", + "label_source": "\"_Custom\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "449-449", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-HELP-_ABOUT_AXIS", + "label_source": "\"_About AXIS\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "460-460", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-HELP-QUICK__REFERENCE", + "label_source": "\"Quick _Reference\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "464-464", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU--_FILE", + "label_source": "_File]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "470-470", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU--_MACHINE", + "label_source": "_Machine]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "474-474", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU--_VIEW", + "label_source": "_View]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "478-478", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU--_HELP", + "label_source": "_Help]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "482-482", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + }, + { + "control_id": "AXIS-MENU-FILE-RECENT-_CLEAR_RECENTS_LIST", + "label_source": "\"_Clear Recents List\"]", + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "2230-2230", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": "setup_menu_accel" + } + } + ], + "source_sha256": "c9f0b4dc686717b37565f85fb0ab8cc8ded9cfa0028cc0aaaccdbcf808c4c524", + "toolbar": [ + { + "control_id": "AXIS-TOOLBAR-MACHINE_ESTOP", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "490-1775", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.machine_estop" + }, + "widget": ".toolbar.machine_estop" + }, + { + "control_id": "AXIS-TOOLBAR-MACHINE_POWER", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "498-1778", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.machine_power" + }, + "widget": ".toolbar.machine_power" + }, + { + "control_id": "AXIS-TOOLBAR-FILE_OPEN", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "509-1787", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.file_open" + }, + "widget": ".toolbar.file_open" + }, + { + "control_id": "AXIS-TOOLBAR-RELOAD", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "517-1781", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.reload" + }, + "widget": ".toolbar.reload" + }, + { + "control_id": "AXIS-TOOLBAR-PROGRAM_RUN", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "527-1799", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.program_run" + }, + "widget": ".toolbar.program_run" + }, + { + "control_id": "AXIS-TOOLBAR-PROGRAM_STEP", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "535-1801", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.program_step" + }, + "widget": ".toolbar.program_step" + }, + { + "control_id": "AXIS-TOOLBAR-PROGRAM_PAUSE", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "543-1810", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.program_pause" + }, + "widget": ".toolbar.program_pause" + }, + { + "control_id": "AXIS-TOOLBAR-PROGRAM_STOP", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "558-1818", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.program_stop" + }, + "widget": ".toolbar.program_stop" + }, + { + "control_id": "AXIS-TOOLBAR-PROGRAM_BLOCKDELETE", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "568-1812", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.program_blockdelete" + }, + "widget": ".toolbar.program_blockdelete" + }, + { + "control_id": "AXIS-TOOLBAR-PROGRAM_OPTPAUSE", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "575-1814", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.program_optpause" + }, + "widget": ".toolbar.program_optpause" + }, + { + "control_id": "AXIS-TOOLBAR-VIEW_ZOOMIN", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "584-741", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.view_zoomin" + }, + "widget": ".toolbar.view_zoomin" + }, + { + "control_id": "AXIS-TOOLBAR-VIEW_ZOOMOUT", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "592-745", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.view_zoomout" + }, + "widget": ".toolbar.view_zoomout" + }, + { + "control_id": "AXIS-TOOLBAR-VIEW_Z", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "584-753", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.view_z" + }, + "widget": ".toolbar.view_z" + }, + { + "control_id": "AXIS-TOOLBAR-VIEW_Z2", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "608-753", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.view_z2" + }, + "widget": ".toolbar.view_z2" + }, + { + "control_id": "AXIS-TOOLBAR-VIEW_X", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "616-757", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.view_x" + }, + "widget": ".toolbar.view_x" + }, + { + "control_id": "AXIS-TOOLBAR-VIEW_Y", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "624-765", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.view_y" + }, + "widget": ".toolbar.view_y" + }, + { + "control_id": "AXIS-TOOLBAR-VIEW_Y2", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "632-765", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.view_y2" + }, + "widget": ".toolbar.view_y2" + }, + { + "control_id": "AXIS-TOOLBAR-VIEW_P", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "640-769", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.view_p" + }, + "widget": ".toolbar.view_p" + }, + { + "control_id": "AXIS-TOOLBAR-ROTATE", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "648-773", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.rotate" + }, + "widget": ".toolbar.rotate" + }, + { + "control_id": "AXIS-TOOLBAR-CLEAR_PLOT", + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "663-784", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "symbol": ".toolbar.clear_plot" + }, + "widget": ".toolbar.clear_plot" + } + ], + "toolbar_count": 20 + }, + "case": { + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", + "sha256": "f985970db293b70c055e4c41fc316d0c16037b5dc7ce07490e18f554e851f811", + "status": "indexed" + }, + "command_contract": [ + { + "command": "PROGRAM_LOAD", + "slice_id": "AXIS-XYZAC-PROGRAM-MDI" + }, + { + "command": "PROGRAM_RUN", + "slice_id": "AXIS-XYZAC-PROGRAM-MDI" + }, + { + "command": "PROGRAM_PAUSE", + "slice_id": "AXIS-XYZAC-PROGRAM-MDI" + }, + { + "command": "PROGRAM_RESUME", + "slice_id": "AXIS-XYZAC-PROGRAM-MDI" + }, + { + "command": "PROGRAM_ABORT", + "slice_id": "AXIS-XYZAC-PROGRAM-MDI" + }, + { + "command": "MDI_EXECUTE", + "slice_id": "AXIS-XYZAC-PROGRAM-MDI" + }, + { + "command": "JOG_START", + "slice_id": "AXIS-XYZAC-JOG-HOME" + }, + { + "command": "JOG_STOP", + "slice_id": "AXIS-XYZAC-JOG-HOME" + }, + { + "command": "HOME", + "slice_id": "AXIS-XYZAC-JOG-HOME" + }, + { + "command": "M428", + "slice_id": "AXIS-XYZAC-M428-M429-M430" + }, + { + "command": "M429", + "slice_id": "AXIS-XYZAC-M428-M429-M430" + }, + { + "command": "M430", + "slice_id": "AXIS-XYZAC-M428-M429-M430" + }, + { + "command": "SIM_STEP", + "slice_id": "AXIS-XYZAC-TASK-TP-MOTION" + }, + { + "command": "CHECKPOINT", + "slice_id": "AXIS-XYZAC-ERROR-RECOVERY" + }, + { + "command": "RECOVER", + "slice_id": "AXIS-XYZAC-ERROR-RECOVERY" + } + ], + "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", + "counts": { + "axis_keyboard": 10, + "axis_menus": 80, + "axis_toolbar": 20, + "blocked_resources": 0, + "direct_sources": 35, + "slices": 11, + "unregistered_slices": 0 + }, + "error_contract": [ + { + "error": "axis_gate", + "slice_id": "AXIS-XYZAC-SHELL-MENU" + }, + { + "error": "M428_HAL_PIN_MISSING", + "slice_id": "AXIS-XYZAC-M428-M429-M430" + }, + { + "error": "kinematics_singular", + "slice_id": "AXIS-XYZAC-KINEMATICS" + }, + { + "error": "following_error", + "slice_id": "AXIS-XYZAC-TASK-TP-MOTION" + }, + { + "error": "ledger_reconcile_required", + "slice_id": "AXIS-XYZAC-ERROR-RECOVERY" + } + ], + "recovery_contract": [ + { + "recovery": "pause_resume", + "slice_id": "AXIS-XYZAC-ERROR-RECOVERY" + }, + { + "recovery": "abort", + "slice_id": "AXIS-XYZAC-ERROR-RECOVERY" + }, + { + "recovery": "checkpoint", + "slice_id": "AXIS-XYZAC-ERROR-RECOVERY" + }, + { + "recovery": "worker_restart_reconcile", + "slice_id": "AXIS-XYZAC-ERROR-RECOVERY" + }, + { + "recovery": "no_duplicate_mcode", + "slice_id": "AXIS-XYZAC-ERROR-RECOVERY" + } + ], + "report_sha256": "817531c109c341ccda78b085d2613f35379a716a98f54c9561a118f995b6cd5e", + "schema": "xyzac-trt-source-slice-inventory.v1", + "slices": [ + { + "authoritative_outputs": [ + "task/mode/error snapshot" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "axis-shell", + "error_cases": [ + "SOURCE_BLOCKED: no per-control WASM trace" + ], + "gates": [ + "estop/off/mode gate" + ], + "inputs": [ + "menu event" + ], + "native_commands": [ + "AXIS Tcl command" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "operation ledger reconcile" + ], + "slice_id": "AXIS-XYZAC-SHELL-MENU", + "source": { + "lines": "58-2230", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "sha256": "c9f0b4dc686717b37565f85fb0ab8cc8ded9cfa0028cc0aaaccdbcf808c4c524", + "symbol": "setup_menu_accel" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-MENU-*" + ], + "wasm_commands": [ + "WORKER_COMMAND" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + }, + { + "authoritative_outputs": [ + "axis_state", + "state_hash", + "command_result" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "axis-toolbar", + "error_cases": [ + "SOURCE_BLOCKED: native handler matrix not runtime compared" + ], + "gates": [ + "task_ready", + "mode", + "fault" + ], + "inputs": [ + "toolbar click" + ], + "native_commands": [ + "estop_clicked/task_run/task_pause/task_stop" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "checkpoint/reconcile" + ], + "slice_id": "AXIS-XYZAC-TOOLBAR", + "source": { + "lines": "490-1775", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "sha256": "c9f0b4dc686717b37565f85fb0ab8cc8ded9cfa0028cc0aaaccdbcf808c4c524", + "symbol": ".toolbar.machine_estop" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-TOOLBAR-*" + ], + "wasm_commands": [ + "ESTOP", + "PROGRAM_RUN", + "PROGRAM_PAUSE", + "PROGRAM_ABORT" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + }, + { + "authoritative_outputs": [ + "authoritative snapshot", + "gate reason" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "axis-keyboard", + "error_cases": [ + "SOURCE_BLOCKED: keyboard Worker evidence pending" + ], + "gates": [ + "focus/input protection", + "manual mode" + ], + "inputs": [ + "keyboard binding" + ], + "native_commands": [ + "jog/task/mode binding" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "pending operation reconcile" + ], + "slice_id": "AXIS-XYZAC-KEYBOARD", + "source": { + "lines": "20-2245", + "path": "linuxcnc/share/axis/tcl/axis.tcl", + "sha256": "c9f0b4dc686717b37565f85fb0ab8cc8ded9cfa0028cc0aaaccdbcf808c4c524", + "symbol": "bind" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-KEY-*" + ], + "wasm_commands": [ + "JOG_START", + "JOG_STOP", + "PROGRAM_RUN", + "PROGRAM_ABORT" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + }, + { + "authoritative_outputs": [ + "program", + "canonical trajectory", + "task.interp_state", + "state_hash" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "program-mdi", + "error_cases": [ + "SOURCE_BLOCKED: exact case WASM execution not proven" + ], + "gates": [ + "task_idle", + "file_loaded", + "mode_mdi/auto", + "no_fault" + ], + "inputs": [ + "program/MDI text" + ], + "native_commands": [ + "commands.send_mdi_command", + "commands.task_run" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "checkpoint/replay/no-duplicate-side-effect" + ], + "slice_id": "AXIS-XYZAC-PROGRAM-MDI", + "source": { + "lines": "2255-2454", + "path": "linuxcnc/src/emc/usr_intf/axis/scripts/axis.py", + "sha256": "328c038a1e8fefd952e53c8e398e3fa98b04602351c44318edd1b044e8f63ffa", + "symbol": "send_mdi_command" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-PROGRAM", + "AXIS-MDI" + ], + "wasm_commands": [ + "PROGRAM_LOAD", + "PROGRAM_RUN", + "MDI_EXECUTE", + "PROGRAM_PAUSE", + "PROGRAM_RESUME", + "PROGRAM_ABORT" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + }, + { + "authoritative_outputs": [ + "motion.axes", + "motion.joints", + "home_limit", + "state_hash" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "manual-motion", + "error_cases": [ + "SOURCE_BLOCKED: exact XYZAC Worker comparison pending" + ], + "gates": [ + "manual_ok", + "axis_enabled", + "homing_allowed", + "limit/fault" + ], + "inputs": [ + "axis/joint/direction/velocity" + ], + "native_commands": [ + "jog_on", + "jog_off", + "home_joint", + "home_all_joints" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "pause/resume/abort" + ], + "slice_id": "AXIS-XYZAC-JOG-HOME", + "source": { + "lines": "2670-3323", + "path": "linuxcnc/src/emc/usr_intf/axis/scripts/axis.py", + "sha256": "328c038a1e8fefd952e53c8e398e3fa98b04602351c44318edd1b044e8f63ffa", + "symbol": "jog_on" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-JOG", + "AXIS-HOME" + ], + "wasm_commands": [ + "JOG_START", + "JOG_STOP", + "HOME" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + }, + { + "authoritative_outputs": [ + "wasm canonical trajectory", + "visual.pose", + "motion.joints" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "preview-vismach", + "error_cases": [ + "SOURCE_BLOCKED: JS preview forbidden; exact case evidence pending" + ], + "gates": [ + "program_parse_ok", + "canonical_source_present" + ], + "inputs": [ + "parsed program", + "canonical events" + ], + "native_commands": [ + "canon/gremlin/vismach" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "clear visual only; no motion mutation" + ], + "slice_id": "AXIS-XYZAC-PREVIEW-VISUAL", + "source": { + "lines": "426-426", + "path": "linuxcnc/lib/python/rs274/glcanon.py", + "sha256": "0dfb20f1fdc05289894f3aa638357d98e1063fbd53329c723c777399ec7b33b7", + "symbol": "GlCanon" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-PREVIEW", + "AXIS-VISMACH" + ], + "wasm_commands": [ + "PROGRAM_LOAD", + "SNAPSHOT_REQUEST" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + }, + { + "authoritative_outputs": [ + "motion.switchkins-type", + "kinstype_is_0/1/2", + "state_hash" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "pyvcp-hal", + "error_cases": [ + "BLOCKED_HAL: native HAL load not proven in WASM case" + ], + "gates": [ + "interp_idle", + "HAL_PIN_VARS", + "switchkins_net_present" + ], + "inputs": [ + "PyVCP button/HAL net" + ], + "native_commands": [ + "halui.mdi-command-00/01/02" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "ledger reconcile/no duplicate M-code" + ], + "slice_id": "AXIS-XYZAC-PYVCP-SWITCHKINS", + "source": { + "lines": null, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins_postgui.hal", + "sha256": "55e969c22ca9054a818dbedc8ec50bed768d9ab3d8c4bfdfcfc78e912e9271c4", + "symbol": "type0-button/type1-button/type2-button" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-RTCP-TYPE-0", + "AXIS-RTCP-TYPE-1", + "AXIS-RTCP-TYPE-2" + ], + "wasm_commands": [ + "MDI_EXECUTE:M429", + "MDI_EXECUTE:M428", + "MDI_EXECUTE:M430" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + }, + { + "authoritative_outputs": [ + "kinematics.active_type", + "motion.switchkins-type", + "state_hash" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "switchkins-rtcp", + "error_cases": [ + "BLOCKED_STARTUP: native kins startup did not reach verified state" + ], + "gates": [ + "interp_idle", + "HAL_PIN_VARS", + "switchkins_net", + "finite_offsets" + ], + "inputs": [ + "MDI/G-code M428/M429/M430", + "motion.switchkins-type" + ], + "native_commands": [ + "M68 E3 Q{0,1,2}", + "M66 E0 L0" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "checkpoint/reconcile; no blind retry" + ], + "slice_id": "AXIS-XYZAC-M428-M429-M430", + "source": { + "lines": null, + "path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc", + "sha256": "a0aee1d6b481a979849a17c0a23aa7524f52cbd875c92cbde3b73bf36f91d17b", + "symbol": "428remap/429remap/430remap" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-RTCP-M428", + "AXIS-RTCP-M429", + "AXIS-RTCP-M430" + ], + "wasm_commands": [ + "MDI_EXECUTE", + "KINEMATICS_SELECT" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + }, + { + "authoritative_outputs": [ + "pose", + "joints", + "limits", + "state_hash" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "kinematics", + "error_cases": [ + "SOURCE_BLOCKED: exact XYZAC native/WASM trace unavailable" + ], + "gates": [ + "active_type", + "five_joint_mapping", + "finite_offsets", + "limits" + ], + "inputs": [ + "five joints", + "A/C degrees", + "tool/axis offsets" + ], + "native_commands": [ + "kinematicsForward", + "kinematicsInverse" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "checkpoint pose/joint/hash recovery" + ], + "slice_id": "AXIS-XYZAC-KINEMATICS", + "source": { + "lines": "151-195", + "path": "linuxcnc/src/emc/kinematics/trtfuncs.c", + "sha256": "ced2f9d4732681e2e82153b2f6343eccdf6972222d558d1e277bf1ec0bdc87fd", + "symbol": "xyzacKinematicsForward" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-XYZAC-POSE" + ], + "wasm_commands": [ + "KINEMATICS_FORWARD", + "KINEMATICS_INVERSE" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + }, + { + "authoritative_outputs": [ + "task", + "program", + "planner", + "motion", + "simulation_tick", + "state_hash" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "task-tp-motion", + "error_cases": [ + "SOURCE_BLOCKED: no exact case Worker trace attached" + ], + "gates": [ + "ESTOP/OFF/ON/HOME/IDLE/RUNNING/PAUSED/limit/fault" + ], + "inputs": [ + "task/interpreter/TP input" + ], + "native_commands": [ + "task cycle", + "TP queue", + "motion control" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "checkpoint/replay/reconcile" + ], + "slice_id": "AXIS-XYZAC-TASK-TP-MOTION", + "source": { + "lines": "2-2125", + "path": "linuxcnc/src/emc/motion/control.c", + "sha256": "fa1b14689e2e4493c02d0939f982278366d4c1888da62e172cec030904c82c50", + "symbol": "control" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-STATE" + ], + "wasm_commands": [ + "SIM_STEP", + "PROGRAM_RUN", + "PROGRAM_PAUSE", + "PROGRAM_RESUME", + "PROGRAM_ABORT" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + }, + { + "authoritative_outputs": [ + "error", + "ledger", + "checkpoint", + "recovery endpoint", + "state_hash" + ], + "authority": "linuxcnc-wasm-worker", + "boundary_cases": [ + "fixed logical tick and finite values required" + ], + "domain": "error-recovery", + "error_cases": [ + "SOURCE_BLOCKED: exact case crash/restart evidence pending" + ], + "gates": [ + "operation_id", + "seq", + "ack/result/commit" + ], + "inputs": [ + "command result/error" + ], + "native_commands": [ + "command dispatch/abort" + ], + "normal_cases": [ + "not executed: SRC-00 inventory scope" + ], + "recovery_cases": [ + "reconcile before retry" + ], + "slice_id": "AXIS-XYZAC-ERROR-RECOVERY", + "source": { + "lines": "2-1910", + "path": "linuxcnc/src/emc/motion/command.c", + "sha256": "9d138ed5780a11ed037aa238781f4bfb4960a73ee23c0b0abf0724db068b3e3f", + "symbol": "command" + }, + "status": "SOURCE_MAPPED", + "ui_controls": [ + "AXIS-DIAGNOSTICS", + "AXIS-RECOVERY" + ], + "wasm_commands": [ + "COMMAND_RESULT", + "ERROR", + "CHECKPOINT", + "RECOVER" + ], + "wasm_evidence": [ + { + "authority": "wasm", + "path": "web/worker/test_panel_snapshot_projection.mjs", + "status": "verified" + }, + { + "authority": "wasm", + "path": "web/worker/test_wasm_motion_authority.mjs", + "status": "verified" + } + ] + } + ], + "state_contract": [ + { + "slice_id": "AXIS-XYZAC-TASK-TP-MOTION", + "state": "task.state" + }, + { + "slice_id": "AXIS-XYZAC-TASK-TP-MOTION", + "state": "task.mode" + }, + { + "slice_id": "AXIS-XYZAC-PROGRAM-MDI", + "state": "task.interp_state" + }, + { + "slice_id": "AXIS-XYZAC-PROGRAM-MDI", + "state": "program.current_line" + }, + { + "slice_id": "AXIS-XYZAC-KINEMATICS", + "state": "motion.joints" + }, + { + "slice_id": "AXIS-XYZAC-M428-M429-M430", + "state": "kinematics.active_type" + }, + { + "slice_id": "AXIS-XYZAC-PYVCP-SWITCHKINS", + "state": "motion.switchkins-type" + }, + { + "slice_id": "AXIS-XYZAC-KINEMATICS", + "state": "pose" + }, + { + "slice_id": "AXIS-XYZAC-ERROR-RECOVERY", + "state": "state_hash" + } + ], + "visual_contract": [ + { + "slice_id": "AXIS-XYZAC-PREVIEW-VISUAL", + "visual": "canonical_toolpath" + }, + { + "slice_id": "AXIS-XYZAC-PREVIEW-VISUAL", + "visual": "wasm_pose" + }, + { + "slice_id": "AXIS-XYZAC-PREVIEW-VISUAL", + "visual": "wasm_joints" + }, + { + "slice_id": "AXIS-XYZAC-PREVIEW-VISUAL", + "visual": "vismach_clear" + } + ] +});