altium-toolkit 1.1.41 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +113 -19
- package/docs/api.md +224 -18
- package/docs/capabilities.md +65 -0
- package/docs/migration/legacy-001.md +309 -0
- package/docs/migration/legacy-002.md +309 -0
- package/docs/migration/legacy-003.md +309 -0
- package/docs/migration/legacy-004.md +309 -0
- package/docs/migration/legacy-005.md +111 -0
- package/docs/migration.md +20 -0
- package/docs/model-format.md +28 -3
- package/docs/release-notes-v1.2.0.md +147 -0
- package/docs/testing.md +43 -1
- package/examples/arduino-uno/PcbThreeSceneRenderer.mjs +1 -1
- package/examples/arduino-uno/example.mjs +1 -1
- package/examples/cli-utils.mjs +1 -1
- package/examples/corpus-smoke.mjs +1 -1
- package/examples/inspect-board.mjs +1 -1
- package/examples/library-catalog.mjs +1 -1
- package/examples/validate-library.mjs +1 -1
- package/package.json +20 -5
- package/spec/api-baseline-v1.1.41.json +1 -0
- package/spec/asset-baseline-v1.1.41.json +1 -0
- package/spec/feature-preservation.json +1 -0
- package/spec/library-scope.md +14 -4
- package/spec/native-source-manifest-v1.1.41.json +1 -0
- package/src/capabilities.mjs +4 -0
- package/src/convergence/AltiumCircuitJsonProjection.mjs +230 -0
- package/src/convergence/AltiumDocumentBuilder.mjs +167 -0
- package/src/convergence/AltiumExtensionResolver.mjs +98 -0
- package/src/convergence/AltiumProjectDocumentResolver.mjs +324 -0
- package/src/convergence/AltiumSchematicCoordinateProjection.mjs +130 -0
- package/src/convergence/AltiumWorkerClient.mjs +95 -0
- package/src/convergence/Parser.mjs +285 -0
- package/src/convergence/ParserInput.mjs +282 -0
- package/src/convergence/ProjectLoader.mjs +916 -0
- package/src/convergence/SchematicSvgRenderer.mjs +126 -0
- package/src/convergence/ToolkitCapabilities.mjs +49 -0
- package/src/core/circuit-json/CircuitJsonSchematicDocumentGraphicBuilder.mjs +785 -0
- package/src/core/circuit-json/CircuitJsonSchematicGraphicBuilder.mjs +909 -0
- package/src/core/circuit-json/CircuitJsonSchematicImageProjection.mjs +277 -0
- package/src/core/circuit-json/CircuitJsonSchematicStrokeStyle.mjs +47 -0
- package/src/extensions.mjs +11 -0
- package/src/index.mjs +20 -4
- package/src/interaction.mjs +7 -0
- package/src/legacy-netlist-query.mjs +11 -0
- package/src/legacy-parser.mjs +141 -0
- package/src/legacy-renderers.mjs +25 -0
- package/src/legacy-scene3d.mjs +10 -0
- package/src/manufacturing.mjs +4 -0
- package/src/parser.mjs +12 -138
- package/src/project.mjs +11 -0
- package/src/query.mjs +4 -0
- package/src/renderers.mjs +4 -22
- package/src/scene3d.mjs +5 -8
- package/src/simulation.mjs +4 -0
- package/src/styles/renderers.css +27 -0
- package/src/testing.mjs +8 -0
- package/src/workers/parser.worker.mjs +37 -0
package/spec/library-scope.md
CHANGED
|
@@ -6,13 +6,21 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
6
6
|
|
|
7
7
|
# Library Scope
|
|
8
8
|
|
|
9
|
-
Altium Toolkit provides reusable native Altium parsing
|
|
10
|
-
|
|
9
|
+
Altium Toolkit provides reusable native Altium parsing behind the common ECAD
|
|
10
|
+
toolkit API. Canonical results use CircuitJSON; source-only facts and all
|
|
11
|
+
historical 1.1.41 contracts remain explicit Altium extensions.
|
|
11
12
|
|
|
12
13
|
## In Scope
|
|
13
14
|
|
|
14
|
-
-
|
|
15
|
-
|
|
15
|
+
- Canonical `Parser`, `ProjectLoader`, error, progress, cancellation, and worker
|
|
16
|
+
contracts shared with CircuitJSON, Gerber, and KiCad
|
|
17
|
+
- Immutable CircuitJSON document envelopes, common project envelopes, and
|
|
18
|
+
reusable document contexts
|
|
19
|
+
- Shared CircuitJSON render, interaction, query, manufacturing, simulation,
|
|
20
|
+
and data-only 3D scene services
|
|
21
|
+
- Exact `/extensions` preservation of audited Altium 1.1.41 behavior
|
|
22
|
+
- `.SchDoc`, `.PcbDoc`, `.PCBDwf`, `.SchLib`, `.PcbLib`, `.PrjPcb`, `.PrjScr`,
|
|
23
|
+
and `.IntLib` parsing from `ArrayBuffer`
|
|
16
24
|
- OLE and binary stream helpers needed by parser recovery
|
|
17
25
|
- Schematic SVG rendering
|
|
18
26
|
- PCB SVG rendering
|
|
@@ -48,3 +56,5 @@ rendering primitives.
|
|
|
48
56
|
- Server, deployment, and app metadata endpoints
|
|
49
57
|
- Native document authoring, round-trip writing, GUI automation, and compiled
|
|
50
58
|
multi-sheet project netlist generation
|
|
59
|
+
- Pretending an Altium-only feature exists in another source toolkit when no
|
|
60
|
+
truthful CircuitJSON or native implementation is possible
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"schema":"altium-toolkit.source-manifest.v1","package":"altium-toolkit","packageVersion":"1.1.41","provenance":{"sourceCommit":"9fa22e1028d96e583275093279bf6e03e8619588","sourceTree":"1ddc290f5fc034454c5f33dac4de56b917070174","testTree":"00be0165c10e69611c8c571c9befef24b48273ae"},"files":[{"path":"src/core/altium/AltiumGeneratedLibraryRecordBuilder.mjs","sha256":"c6024166ad005c0f15a120b67ed0feb3ab7a43202065ae1aa2e983f4f7000d2e"},{"path":"src/core/altium/AltiumLayoutParser.mjs","sha256":"2ff28ea83903ef5cb95d569d6c1daae7340c8710a01d397faf5c8dbb045dad0f"},{"path":"src/core/altium/AltiumLibraryBatchExporter.mjs","sha256":"cc49aa0e106487f754d0a306cf82418bfaf1ba0eb199e9161c2b29aae89977be"},{"path":"src/core/altium/AltiumLibraryRecordBuilder.mjs","sha256":"3941b609c1536ff29e5cd4dccf8060c5524b075645fdf2c22ad153a60edfcc59"},{"path":"src/core/altium/AltiumParser.mjs","sha256":"bfae2e63ccde1a18dc50df9b661208c8d0c78ce447b0094a01187c41413b39eb"},{"path":"src/core/altium/AltiumPcbLibExporter.mjs","sha256":"384ae177fe5ceadef1a22f191e12fe7af5327dff1fee971972826a3def5b616a"},{"path":"src/core/altium/AltiumSchematicArcAngleNormalizer.mjs","sha256":"831be977a80e2a5ecb5a0987fa4587cb601afe5908344c62de3358b355af0206"},{"path":"src/core/altium/AltiumSchematicFreeGraphicStrokeNormalizer.mjs","sha256":"19b49250b16be521213d2bfa31e41436aa7c2d543d6e48c0029ffce9183900a4"},{"path":"src/core/altium/AltiumSchematicHiddenDesignatorResolver.mjs","sha256":"f49603ac7f35cc435ce5d9ff65a0ef59d1601d0445643372ceb4daf8ea05f751"},{"path":"src/core/altium/AltiumSchematicPackedImageResolver.mjs","sha256":"948fff19a9a7695687887bbc416bca182b6c717df66b3707bff45d447bc29d9c"},{"path":"src/core/altium/AltiumSchematicSheetBoundsNormalizer.mjs","sha256":"f11d853ecbfd03f83c7084e48c621234077d1d5e4f6e759070096cff3e8fde99"},{"path":"src/core/altium/AltiumSchLibExporter.mjs","sha256":"f1bc1c04e1de6b736987c4e3c036cdf8b0d21d745f2cd50b8c13bf9b62f5615c"},{"path":"src/core/altium/AltiumUnits.mjs","sha256":"e3ac28990bd40abae95d54c55852b229428d01323e694af1a8ba5ddb973b5e91"},{"path":"src/core/altium/AsciiRecordParser.mjs","sha256":"6b300d6b16e726bb7d61109b7afeec956e318e9cae531f1970f13b425fc4cac5"},{"path":"src/core/altium/CiArtifactBundleBuilder.mjs","sha256":"379efc7823bfab5902edf025cedf76b0c6147db7fa668c9560549401dcfdcbd6"},{"path":"src/core/altium/ContractGateReportBuilder.mjs","sha256":"11fdf71be9229e6a075a673065323be0fe472be2c99d6b2f6968b73852293313"},{"path":"src/core/altium/DraftsmanBoardViewMetadataBuilder.mjs","sha256":"b21c5cc9e8973aeed3d188af250ba455fc514fae7d0efec6e235c2e7dbaed367"},{"path":"src/core/altium/DraftsmanDigestParser.mjs","sha256":"d570b966a08c62c2d09e73ff7d227f5645f10961ad46aac1d706fbd15bb17a00"},{"path":"src/core/altium/DraftsmanImagePayloadManifestBuilder.mjs","sha256":"d79492cdcb886a5ae3b4a724423b71f6fd3f80bd8ef53135348b1265a4b4567c"},{"path":"src/core/altium/EmbeddedAssetReportBuilder.mjs","sha256":"e36b708738ea20a817849c88bec32de0415acc39194746a4b343890230a924b9"},{"path":"src/core/altium/EmbeddedFileInventoryBuilder.mjs","sha256":"5e86fff091cde0d493e4788b8ad85342c4fc0e54a063491e738bc58b2a95732b"},{"path":"src/core/altium/FixtureCoverageMatrixBuilder.mjs","sha256":"6dbda10369d0ec8cff69c8eb804b63405c7601525fa704b26c730664fcd27aff"},{"path":"src/core/altium/GeometryBoundsReportBuilder.mjs","sha256":"ac2e29de3266c7b9682284352c800d17ca7b2965e5a5c0169600799c64f2939c"},{"path":"src/core/altium/HostCapabilityDiagnosticsBuilder.mjs","sha256":"aa9aa1da9a608daf196e533853e9ad1d0e01b200732712547f1f5424343d4931"},{"path":"src/core/altium/IntLibModelParser.mjs","sha256":"3ea00a4ac85f4ac4994b059c02157428e211271dc2c5faecd5d5ac9c23a86d7c"},{"path":"src/core/altium/IntLibStreamExtractor.mjs","sha256":"e48a6b8b1c1efb790191175ab7f8b129c166350f8e1977b67b2d27b1f969268d"},{"path":"src/core/altium/LibraryCatalogArtifactBuilder.mjs","sha256":"bf067fa0e86d3b2b13ddfb6da2af9b1ddecc984bb25788af8b2fb45475112c70"},{"path":"src/core/altium/LibraryCompatibilityGeometry.mjs","sha256":"c6cab949fcbdad107524d60c5ddda7447ce452086f7d42a0a6a3f57df10993b4"},{"path":"src/core/altium/LibraryCompatibilityModelHintBuilder.mjs","sha256":"d365e07a481fca6330ff5362593acf5248be637d66d454c973d65bb460fece21"},{"path":"src/core/altium/LibraryCompatibilityReportBuilder.mjs","sha256":"8504e07e80900716e82ec4f3c503f9a70fd08a44fa2ae86e911858fd1c4718da"},{"path":"src/core/altium/LibraryDiffReportBuilder.mjs","sha256":"a15c8ab7b4fcc04108faad13fbd74a4df24a8ce7267b2bd2a2f14f58a4d5ad99"},{"path":"src/core/altium/LibraryInspectionReportBuilder.mjs","sha256":"464f867471a85c01d7fc906695bef10219eaddc4013a4afcf2fe4de46f32d0f1"},{"path":"src/core/altium/LibraryQaReportBuilder.mjs","sha256":"2c35077ef7140110979f35f93901aabdd1bb7b2d64879212cfd4abb5a6b3f8f3"},{"path":"src/core/altium/LibraryRenderManifestBuilder.mjs","sha256":"66b8383470d3452f4cdceffad6c8a09533bd0fb3a32a47484725ac3edd8c5fe7"},{"path":"src/core/altium/LibrarySearchIndex.mjs","sha256":"a97e0852b91e6abfc548b927e821dc950945baf85ee20f2fc4c52346ec338c8d"},{"path":"src/core/altium/NativeStreamInventoryBuilder.mjs","sha256":"2c9144c17b68e609bb27757d856887bda10a79dda0c69d8c4f789f1e7b0ccedb"},{"path":"src/core/altium/NaturalStringComparator.mjs","sha256":"d970b4c63472de2e870d08e97ea65624d161b08410a7fb4239725efc216b0722"},{"path":"src/core/altium/NormalizedModelSchema.mjs","sha256":"d12c8dad7c97adf152be00be51092307525e6bb77aaae7322c2b49e661c25564"},{"path":"src/core/altium/ParameterCollection.mjs","sha256":"61dd3309af3b1fce92223ba1223f7fefb1bb21a4d8c1d79aa4ca90d7ec654517"},{"path":"src/core/altium/ParameterRecordInventoryBuilder.mjs","sha256":"5cc461dcdbabfc9e5bdaa920dfc95b9e574ee8fdfd10014788109e42a755f754"},{"path":"src/core/altium/ParserCompatibilityFuzzer.mjs","sha256":"53c5379621bc5d03f3f222c6e9a5708c45e1037d0771a1eb293c6d78bc5b4bd1"},{"path":"src/core/altium/ParserDiagnosticNormalizer.mjs","sha256":"3528601140dccda335f1e5770888d4bbac19d732ea3b501211352ecd87d46f73"},{"path":"src/core/altium/ParserErrors.mjs","sha256":"194fdd0d5b570d981dcdd21e9041186652c8f5635d91a501f6d9e4ff8d2288a2"},{"path":"src/core/altium/ParserFieldCoverageReportBuilder.mjs","sha256":"e31a5951630a2956cc5b482e30e7b4a8c637947339cddb16619f356e369bdb9f"},{"path":"src/core/altium/ParserUtils.mjs","sha256":"0ccedb569986cf86a2cd618e6bd368b7313d0a9ad14f475de54c86f7da10c84b"},{"path":"src/core/altium/ParserValueVerificationReportBuilder.mjs","sha256":"5d5ce89942290e541b2acb79dbf67ee38fe9fae7e1af68016f093160780da2a0"},{"path":"src/core/altium/PcbArcPrimitiveParser.mjs","sha256":"3570d39234ebff7c07a1ef46b95f85a3a01ae2576b0fa5e1adf7a75098a20eca"},{"path":"src/core/altium/PcbBinaryPrimitiveParser.mjs","sha256":"b2de45c4d1fab5373f85a87673e068ead145db9092afc9703b595ae9fbd142d7"},{"path":"src/core/altium/PcbBoardRegionSemanticsParser.mjs","sha256":"792e2740142e2ddbadffee70a3af691dfd1b291d58aba0d1491d9fd47789741a"},{"path":"src/core/altium/PcbBomProfileBuilder.mjs","sha256":"18c1808428a54a515b0d0ca0dd71765b48dc174423c992180bffec8d6b54f114"},{"path":"src/core/altium/PcbClassReportBuilder.mjs","sha256":"e0522ff6603aac9747228bec70cc786cc8051e2233e5a5b241f9646954da13e0"},{"path":"src/core/altium/PcbComponentAnnotationNormalizer.mjs","sha256":"ce95d09cf256ba128b393a9ae248dff17215fc2c7861f828c32304e51d391977"},{"path":"src/core/altium/PcbComponentBodyPlacementNormalizer.mjs","sha256":"90ca987defaa709a1a994c2be65216db1d8fb2eda5ba2c8e445fac48d9737fdb"},{"path":"src/core/altium/PcbComponentKindPolicy.mjs","sha256":"c0cdf2eb55fa04acdba2b30ada85fa215cf4b22418c371fb8bbfe76d435ca98b"},{"path":"src/core/altium/PcbComponentPrimitiveIndexer.mjs","sha256":"8c6ec484f819b1faf3e55c8f5ab5be8c2079c0f16e24378298bf841ae225a733"},{"path":"src/core/altium/PcbCustomPadShapeParser.mjs","sha256":"1dd23d02e5eadbdc5b59210b31e61ea258addb923500edfb2c78f7ea5ce4bfbc"},{"path":"src/core/altium/PcbDefaultsParser.mjs","sha256":"b30b748a6e672482d9849e6ee6244d1999965256d7e9397131cc8818f77496f5"},{"path":"src/core/altium/PcbDimensionParser.mjs","sha256":"7f1676a27cfec1a9da7d8317b3f7a2191b5a41e4563b894ba357480dac360d79"},{"path":"src/core/altium/PcbDimensionReportBuilder.mjs","sha256":"b635274a67fcbec7f8dc80407b334c647bd7ee9b162bf0086a40bb82e6f89157"},{"path":"src/core/altium/PcbEmbeddedFontExtractor.mjs","sha256":"447cf031a6e36e6f8a0f6454d1d50df5617ed4590033d714df7d28bb88508b7c"},{"path":"src/core/altium/PcbEmbeddedModelExtractor.mjs","sha256":"253d297f4a402978a12fa28c060981365ab382a1d5b777e134bc1b72c8617c45"},{"path":"src/core/altium/PcbExtendedPrimitiveInformationParser.mjs","sha256":"4cc5bdccbe7f56793083fea870c39e4891786d96dc1b14ba70065f3b1eb52ad9"},{"path":"src/core/altium/PcbFabricationReadinessReportBuilder.mjs","sha256":"2d9168f0ee94feaa06500bd05f0932647855e4614639e70bd7fb39cd9cf87ad4"},{"path":"src/core/altium/PcbFillPrimitiveParser.mjs","sha256":"398c13534fdce0a66237afe522b98c8856241647f3e9adb707c29c346f0d8db7"},{"path":"src/core/altium/PcbFontMetricsParser.mjs","sha256":"18859fa2ba4fed7e1f03f7fd380201cce5963edb238ec4b6a52f93346455fbde"},{"path":"src/core/altium/PcbGeometryFlipper.mjs","sha256":"88f88696a5ef50539ab79e3fd7e155c0eeb7e54d9f6d7258278a53457e417a31"},{"path":"src/core/altium/PcbInspectionReportBuilder.mjs","sha256":"fc25424dcac7c847d5797ac987853beb8a84152cd43fa34c45f275f31bcd2fa1"},{"path":"src/core/altium/PcbLayerGroups.mjs","sha256":"09b70c09815cd3d8f91baaed24aed519f8571bfad971ae4a490f52203c8760b0"},{"path":"src/core/altium/PcbLayerIdCodec.mjs","sha256":"efa53c24a7a753bdb585398929bbe557759ceb0213410c43f6609eb365adee45"},{"path":"src/core/altium/PcbLayerStackCustomDataParser.mjs","sha256":"66995a16a42a9080279e4b8a785ab7fe85392810ca0313d8dd478c8e39dd6eb6"},{"path":"src/core/altium/PcbLayerStackFidelityReportBuilder.mjs","sha256":"5862c2b14d9ac4af13806e4608dbd2f0ae84900ce2bfbf75535bec3aca9196af"},{"path":"src/core/altium/PcbLayerStackInterchangeParser.mjs","sha256":"e75616e15db5cbd5bdb4d7dff18c8fb313100b1ce20a0f8636dbd366f52a5538"},{"path":"src/core/altium/PcbLayerStackQueryHelper.mjs","sha256":"979c64608beb3d932366955f090fbb3b8ad3e735be8d5969a59fd5e9aa8d1bd9"},{"path":"src/core/altium/PcbLayerStackReadModelBuilder.mjs","sha256":"11f6169e01742148bfc7adaf2e5319d6805fc43ec926f2f30da3ffd411ee1287"},{"path":"src/core/altium/PcbLayerStackSourceMetadataParser.mjs","sha256":"9d8ce7ee4572f4f9af11b6a50a3e34fedbf76a5ab19be0843a180abecc65a236"},{"path":"src/core/altium/PcbLibModelParser.mjs","sha256":"a0c9b2bdda831567180326174247113628598cfd4324e46908e6fe5f4a8ad241"},{"path":"src/core/altium/PcbLibParityReportBuilder.mjs","sha256":"2c54d52739ddd55eee80cd21344ba18b9db4db1f32f2de1a7805a8b6e5e4ffb6"},{"path":"src/core/altium/PcbLibStorageNameResolver.mjs","sha256":"90a6d6980400906a93c3ef8ae19575e9a11071dc647752b28a6b6576ffe4bf92"},{"path":"src/core/altium/PcbLibStreamExtractor.mjs","sha256":"ee3f2e43b63678d5187e960ae3e0ad7e124c7223bffdbbf83b3bca3e5ef754d1"},{"path":"src/core/altium/PcbMaskPasteResolver.mjs","sha256":"7f20dd398f8fdf6b90f2a71fbebc3c7f540832cfe53d60e777df0e1ffcf13e26"},{"path":"src/core/altium/PcbMechanicalLayerPairParser.mjs","sha256":"d52bb4910b4da59ce619e08cf094a04115c26732cfdde19cd909dd6cba1c2d09"},{"path":"src/core/altium/PcbModelParser.mjs","sha256":"526c021dcd5c881d4ef8497fc8bd7d0fc444481b24d455df21dc261918a6c27d"},{"path":"src/core/altium/PcbNetMembershipReportBuilder.mjs","sha256":"99eb577ed1ac1c427f18f7510b0799b16b2615ff459579b181bd4cfec2e1ac5f"},{"path":"src/core/altium/PcbOutlineRasterizer.mjs","sha256":"d6c3d258da0f6bc20984d866447610398607883efc0c1b059737db1bbcbc01a1"},{"path":"src/core/altium/PcbOutlineRecovery.mjs","sha256":"0489fa6ff8da5ade83b25b8d5593801a8624245abcc37d174d9f0a933853459b"},{"path":"src/core/altium/PcbOwnershipGraphBuilder.mjs","sha256":"72494fa6b6a226e8ae60ce6ab34b99d0a573180fd71f28a6be413b7ba2d57854"},{"path":"src/core/altium/PcbPadPrimitiveParser.mjs","sha256":"f0da55e9987e586f03d20ac900ed705fdb4b71b90eab6ecbcef6357dd7131409"},{"path":"src/core/altium/PcbPadShapeCodec.mjs","sha256":"32020d864cb2edc614fd276c205613c390ba1ab98fe6a159655dae787087f343"},{"path":"src/core/altium/PcbPadStackParser.mjs","sha256":"fd65280b9c8dab1f762f6f19a5d16bce2ac3861c096e1735cdcc4b8ba7d402ea"},{"path":"src/core/altium/PcbPickPlacePositionResolver.mjs","sha256":"05cd6ad01e0ab77bd44cb69fcf7ffe266eeb8880ac839c8e6b3c43b8763a6404"},{"path":"src/core/altium/PcbPlacedFootprintManifestBuilder.mjs","sha256":"20200b453341de5044ab4b24b21f3bf999764e23179bc153ca4da7ca74ab895e"},{"path":"src/core/altium/PcbPolygonRecordParser.mjs","sha256":"98b0e21d3acc213e60ff6aac9215864be4fbd584177581f00e78f54132efeb3c"},{"path":"src/core/altium/PcbPrimitiveFieldOffsetReportBuilder.mjs","sha256":"3e593152684685c33d978c8507201955343b22af5c9459762829215272191dc9"},{"path":"src/core/altium/PcbPrimitiveOwnershipIndexParser.mjs","sha256":"13209fe9de519e5c86682bfb7a62ca2b7804d68c17fc2d6ebef2e7523d384717"},{"path":"src/core/altium/PcbPrimitiveParameterParser.mjs","sha256":"472509419d8c208b50dc0e9d2f389bcbe7b9b5aaf11ad9f1ff759a06bdfde0a9"},{"path":"src/core/altium/PcbPrimitiveRecordSlicer.mjs","sha256":"f5f37ea1a29c8e652a3e11d47c7c3fbcd1339872a35daedf3b7393f009b83d25"},{"path":"src/core/altium/PcbRawRecordRegistry.mjs","sha256":"7267a6154ae42966e6610df11f887e793038956da496aeeadb8a4c664b3f11f6"},{"path":"src/core/altium/PcbRegionPrimitiveParser.mjs","sha256":"04f6822c60d2261af398f667a70d4aec4720aae93ed35599d8a4464b18b33876"},{"path":"src/core/altium/PcbReviewDrillMetadataBuilder.mjs","sha256":"807f67f133da728a0597d0c346648270fdd810384d3e351c21f1e7ba2822aa77"},{"path":"src/core/altium/PcbReviewMetadataBuilder.mjs","sha256":"d4f918c03ebfbda9f6cd4500be24eec45856f3c6128dcb55437a86e2bc445e28"},{"path":"src/core/altium/PcbReviewPolygonRealizationBuilder.mjs","sha256":"2dd8e2d97b1f9b35bb938f6714e1724606eebd26a7f7291ecbc1f8d5d9e5285d"},{"path":"src/core/altium/PcbReviewRouteHighlightProfileBuilder.mjs","sha256":"103d6b50f0fa41671b021702df67c40a95bfe318dc223d36e7f97bd15c155ebb"},{"path":"src/core/altium/PcbRigidFlexTopologyBuilder.mjs","sha256":"b3d71a4f8cea5b8bf90a588c0c1c6f9a9680b36a171441794f18cc34c80d9395"},{"path":"src/core/altium/PcbRouteAnalysisBuilder.mjs","sha256":"56f24354868bf82ddfd10d158accbf26677340273015c0ce424ddefd00929e3a"},{"path":"src/core/altium/PcbRuleImpactReportBuilder.mjs","sha256":"de4ed931eced6fbc2a5eda2ce87f65a745a6c78732615f1573f7b716db5f871e"},{"path":"src/core/altium/PcbRuleParser.mjs","sha256":"6dd28b296dc133de2da9fd1a9826ae1f2c3b00b0447ee05bd803d724bff3f5ff"},{"path":"src/core/altium/PcbShapeBasedBodyGeometryParser.mjs","sha256":"41f0866dffced76cb28b1db91c4d8a712b1441a3ba7e78e86836318cca7e075a"},{"path":"src/core/altium/PcbSidecarRecordParser.mjs","sha256":"69d750a911efbc29a400962e46b6accfc534f6674fcaec83226ccc5425ab4faa"},{"path":"src/core/altium/PcbSpecialStringResolver.mjs","sha256":"1cf33548eeca612f5a8ae05880e47024bcceff8b37b3c6379fa25439eafa7bbb"},{"path":"src/core/altium/PcbStatisticsBuilder.mjs","sha256":"abb489b06d5e51bc823a66f87a105f53907a0a3375ef010bcb9c6c123be973a7"},{"path":"src/core/altium/PcbStreamExtractor.mjs","sha256":"90d9a21f65db93fc7c8460e6f825d4c8a17f89d1e691840f5793c9fd21ebe29b"},{"path":"src/core/altium/PcbTextPrimitiveParser.mjs","sha256":"8769aa4a9b71d6629742f0227e9ea9eca5d76df177af1553ac2803284add0df2"},{"path":"src/core/altium/PcbTrackPrimitiveParser.mjs","sha256":"f16e311f27c579185e32828e7d58e03a9ef0d7e57ece1cf9394e3d24b4fa08a4"},{"path":"src/core/altium/PcbUnionParser.mjs","sha256":"561bc3edd615e7d0ef78926f3046dd5deb295fd14da4d7936a622bb3438676a6"},{"path":"src/core/altium/PcbViaPrimitiveParser.mjs","sha256":"c6e43d36082becbf930eade3dc06afc1e80532d6d370dcd137460bc534c5b585"},{"path":"src/core/altium/PcbViaStackParser.mjs","sha256":"f56aae32526af6e019f02e1accf2ccf606210ebce42191f2b3614cacf50dfc64"},{"path":"src/core/altium/PcbViaStructureParser.mjs","sha256":"1e5f0020689a0ad20428313b5f03b8b05cd8996373c3eeaa18416b84c2791af0"},{"path":"src/core/altium/PcbWideStringTableParser.mjs","sha256":"2b56f17232bea3b69c04f0e3b0c319649dd00210c67bfde2cff67ba54271c16a"},{"path":"src/core/altium/PrintableTextDecoder.mjs","sha256":"1a68d493221c87fd28cfe741a614b08a77428da0b689b7302399c212346880ff"},{"path":"src/core/altium/PrjPcbModelParser.mjs","sha256":"2ab110abe772a422571ced319a7e183f1c96080a1609458b069b2583a04b23fa"},{"path":"src/core/altium/PrjScrModelParser.mjs","sha256":"beb049fe0c2da57a69318870fafed491c74ee4db6aa343cae81d49ea3fbcce7e"},{"path":"src/core/altium/ProjectAnnotationParser.mjs","sha256":"263f818043abb386060e0e89cc86df166731a87e270fdddf7215ed54f55af412"},{"path":"src/core/altium/ProjectBomPnpReconciliationBuilder.mjs","sha256":"7456a9bf5c315fa69e5bf94d5570a62509f0516408478e9bffe685a895ec6ee4"},{"path":"src/core/altium/ProjectDesignBundleBuilder.mjs","sha256":"be4be530e2ce6bb241ed35a2c1d8baf714e4bdf34302a52295f66eb924957fb4"},{"path":"src/core/altium/ProjectDocumentGraphBuilder.mjs","sha256":"90f57388d12d6adb08d7c23f5505150f83ec76b8ebc67a7e01185ba6485fd6b7"},{"path":"src/core/altium/ProjectHierarchyReportBuilder.mjs","sha256":"4dffd614f1303d44b15cb935bb74114bff4494ffe2a8e435578c53efc041813b"},{"path":"src/core/altium/ProjectNetlistExporter.mjs","sha256":"d9f129172442ec6b75e6cce375f3dac71511435b9ebda3082c217e62233fa4c0"},{"path":"src/core/altium/ProjectOutJobDigestBuilder.mjs","sha256":"820a249b9358836e84a8acf23fbec493cc4ce656652d17394c2f43a554161b1c"},{"path":"src/core/altium/ProjectVariantViewBuilder.mjs","sha256":"221663cde2254f926e50bc9066d06a34c17ada90ebb33ccbc862ee1d0759d3d7"},{"path":"src/core/altium/RawDataPreservationReportBuilder.mjs","sha256":"58feb0fed1d49ca3cf7351fb9343d161a9e20dc6eb01d358a34a1bece8516abb"},{"path":"src/core/altium/SchematicAnnotationParser.mjs","sha256":"c47dda158ff5e923b41b44a900b08bdab3c7b4a11fa04e54222b00dc9f9fe636"},{"path":"src/core/altium/SchematicBindingProvenanceParser.mjs","sha256":"064ec613a13e9ce42ce58691b01618f7fcd283499112a954fee29bc87c2ea9cf"},{"path":"src/core/altium/SchematicBusEntryParser.mjs","sha256":"de0a7752a07c9b8e923917565a47f8e8c6da2d46708d11e896f4144be680969d"},{"path":"src/core/altium/SchematicCodeSymbolParser.mjs","sha256":"adbba28155e4acebd22f3784d3cc8b178bf8a33d33440e2ef0f2cceaf1f7f61e"},{"path":"src/core/altium/SchematicComponentOwnerTextResolver.mjs","sha256":"ce5dcd74a4c1e4100d20673d51547c08faffaff0dee7962627db9109997624cf"},{"path":"src/core/altium/SchematicComponentTextResolver.mjs","sha256":"c486d4c89df3713deb56e6590285917f55faf24fa9110bb39cfbb2926694ccaf"},{"path":"src/core/altium/SchematicConnectivityQaBuilder.mjs","sha256":"af1a54ed8911f5e43e08c405600f0e82c26707e6681538f067ec341122320a1b"},{"path":"src/core/altium/SchematicCrossSheetConnectorParser.mjs","sha256":"7b6f62989ec8ef6a181d676138d0db77583563c541d50a2db37f12ab703cde7d"},{"path":"src/core/altium/SchematicDirectiveParser.mjs","sha256":"f95a13b05d09cd49cb2735474564cb6739460cb6e29767071fecae1ebe815eb2"},{"path":"src/core/altium/SchematicDisplayModeCatalogParser.mjs","sha256":"0ecb3d723f09e2d53331f494c9269719783219c1f215d56ce5797133b2369767"},{"path":"src/core/altium/SchematicFieldCoverageReportBuilder.mjs","sha256":"ca0db10caf2b3968e6746acf4d501368fd9dd68dfd64e47f7b924ec74f9820ed"},{"path":"src/core/altium/SchematicHarnessParser.mjs","sha256":"3393fe30785fdc5d7b28834bc7becc8d37dcd81cd2962efc86644d4593123ceb"},{"path":"src/core/altium/SchematicHyperlinkParser.mjs","sha256":"0cf30dfd3cd1d1fecf6b8debba83d6b61bfcbe9db745f2a348f46fe3e579c696"},{"path":"src/core/altium/SchematicImageDiagnosticsBuilder.mjs","sha256":"3a0dee66b15cc8c111371596d02fb40e289ccd8ccc01d2069e98d7b3fee63704"},{"path":"src/core/altium/SchematicImageParser.mjs","sha256":"6ea901dbb70f1e6d24621ade7863a8427b6ce0db174fb7b0a6f96d90bd5da366"},{"path":"src/core/altium/SchematicImplementationParser.mjs","sha256":"1f745fa6177ce67d4a8fae881083872987a67d874333212bec24967fbb39273f"},{"path":"src/core/altium/SchematicJunctionParser.mjs","sha256":"1691240945c03286523f7be252b1462e4f6cbc16a3b951d362955c70e08aed07"},{"path":"src/core/altium/SchematicMultipartDesignatorNormalizer.mjs","sha256":"7156ed5fb9f12a26862c9017b10638ab08c8adbf7404f9a1dbf38c40ec5bb1bd"},{"path":"src/core/altium/SchematicMultipartOwnerMatcher.mjs","sha256":"49f3c937b6042555fdfdaf617ff65b7762a523dd8fe081227d70cd73f296cb20"},{"path":"src/core/altium/SchematicNetlistBuilder.mjs","sha256":"9e4bc310f86e7e981df05fb1756272702b0836616e63f117f8dd0c8fd4b9f004"},{"path":"src/core/altium/SchematicNoErcSymbolResolver.mjs","sha256":"0dd719bf87e8b2501b6cf40d32a107f2248e16c45a5ee6717bd16389651483e6"},{"path":"src/core/altium/SchematicOwnershipGraphParser.mjs","sha256":"2eecbf3803d7ffdaeec6745e62dc854a03b0648b93618fc36e27da38dcfb3f7e"},{"path":"src/core/altium/SchematicPinDesignatorInferer.mjs","sha256":"bffe94e837ca35fd8e109619cc87d620dc7a014d328aba3aec3d8f28dfa0e03c"},{"path":"src/core/altium/SchematicPinParser.mjs","sha256":"9fd88f5a143f6ed9614b4a25afc04b2aa1aca847508b2ab857703604c6bd713e"},{"path":"src/core/altium/SchematicPrimitiveParser.mjs","sha256":"28c927cef76650194cf4ac26d8034dcef65e50929714092ade601818db8fb60e"},{"path":"src/core/altium/SchematicProjectParameterResolver.mjs","sha256":"b56adcf3261bb9d2e364cc86083b8e0a37d14af26fde9cb6de18fc0a154a723d"},{"path":"src/core/altium/SchematicQaReportBuilder.mjs","sha256":"7c09f53ded67103efffd8e45f5bd3436b88b64fce03d31b7de173a1068bfb67f"},{"path":"src/core/altium/SchematicRecordStreamParser.mjs","sha256":"8e98ea0a8725d486a82c4b42f2f98e791078d17dd55c19d91845d4ed3bd9e68a"},{"path":"src/core/altium/SchematicRecordTypeRegistry.mjs","sha256":"1d9f29424d04a1655395bc40119aa10fcb037d42a5a63c822852c6278486469f"},{"path":"src/core/altium/SchematicRepeatedChannelParser.mjs","sha256":"1aba78fb0e6201ef66958648f5789c7c322bda4f62751f1dcd031be7edfecd11"},{"path":"src/core/altium/SchematicSheetParser.mjs","sha256":"1e281222e7a5a5f1ce5ebf7655c2f8f9fc4cc7be59f3f0cc319aec1b805a4122"},{"path":"src/core/altium/SchematicSheetStyleResolver.mjs","sha256":"284554aba014cfa593055d4890d731be979df6ea8abae3aa5fdd9b14d66fbda2"},{"path":"src/core/altium/SchematicStandaloneCalloutNormalizer.mjs","sha256":"c80c3317f606bee56e1b53d169cddfa2ecf7f4dc59c3c9f85058521d31dc3432"},{"path":"src/core/altium/SchematicStreamExtractor.mjs","sha256":"12113eddf53d7e75bcc87032547c242964ca4b262f4100b82fbddcd2d83fcaf0"},{"path":"src/core/altium/SchematicTemplateParser.mjs","sha256":"a5fcc74f0dd1f0f1ff65fbb33304b308c7507ee1c429d590e876f6fb4502c0e9"},{"path":"src/core/altium/SchematicTextOrientationResolver.mjs","sha256":"59c3c2c77912c913190fd49d01ba76b1165c745b5db3998ff3458b394e7a7d0e"},{"path":"src/core/altium/SchematicTextParser.mjs","sha256":"73af8b419fddfc51118a95f6d4869daa4d4e9b5aaae8cd54c5a702c2470fbc4e"},{"path":"src/core/altium/SchematicTextPostProcessor.mjs","sha256":"1e97cebf6e9593aecbb04bfe0daab277582f7dd07c0b52fd9e69f5c92afdead1"},{"path":"src/core/altium/SchematicTextRunParser.mjs","sha256":"23f57ddecfe8da72e5205d2f1755cadc12659323fa67a8bec08dc341438c3c81"},{"path":"src/core/altium/SchematicThumbnailParser.mjs","sha256":"c3f2e5597bc2a8875874a058d7ac5037a59f6e3fa973769f40ce846f9d119ef8"},{"path":"src/core/altium/SchematicTitleBlockParser.mjs","sha256":"ec4d359e24bd0cd3b31281305129771dcfb97dcb47177376ae2f748bab78eeab"},{"path":"src/core/altium/SchematicWireNormalizer.mjs","sha256":"fb9d9c4f177b2a9ebdc4cf2d817660779303c9472c21c99ceb788deeb971f093"},{"path":"src/core/altium/SchLibModelParser.mjs","sha256":"40dd14984651861b6c2c719bd5380e1259c13c9be6d46b8c034f93534a9546ce"},{"path":"src/core/altium/SchLibStreamExtractor.mjs","sha256":"70490aaa2a14777657659e60f1b48684ded19a1e050219708999e68fa968f23e"},{"path":"src/core/altium/SelectedPartAltiumExportAdapter.mjs","sha256":"79bb54584a271bf328140b6b7d58ef19835e768a91846e03f4a1a03ef39809c7"},{"path":"src/core/altium/SourceBundleExporter.mjs","sha256":"3c6edd0469cc5af513db42f8e181ab4a9823cc8502fe372aa2ec5d6f26db5046"},{"path":"src/core/altium/SourceComponentBundleNormalizer.mjs","sha256":"d593413f19ede5b8b174dd243cb4dcd2dc581516a7681c79d863b45d0054f464"},{"path":"src/core/altium/SourceComponentClient.mjs","sha256":"3a26ee1c07b4b4023af6d209215e1342387cd45bd52eba7f3b8a1f0608544023"},{"path":"src/core/altium/SvgModelCrossLinkValidator.mjs","sha256":"888f40c08aafbd7e712ba27d7cf3b359d51fdd4d92e80d5a9ce70768e81d77b2"},{"path":"src/core/altium/UnsupportedFeatureReportBuilder.mjs","sha256":"a9d6b4294a4e60ad4350b6a38de4ba906ba9fe11cc00b4ed055edba6b475b3e9"},{"path":"src/core/BinaryReader.mjs","sha256":"66fc8f8f4ae62b01eadb07af1a5270e75203b2366083103f6bbd169547433167"},{"path":"src/core/circuit-json/CircuitJsonModelAdapter.mjs","sha256":"48b96b324db706d64be136f1c0e2cef0ca361b23ec0c12af4b00331a4a30498a"},{"path":"src/core/circuit-json/CircuitJsonModelAdapterPcbElements.mjs","sha256":"e069491b5dc1c698dff3a3d68db1c2a5ebb69cec95caafdd92719aa54acd8265"},{"path":"src/core/circuit-json/CircuitJsonModelAdapterPrimitives.mjs","sha256":"29157012b29084ad74a1b75e397022a30eef9467fea2a3cd363b5b8309e93fba"},{"path":"src/core/circuit-json/CircuitJsonModelSchema.mjs","sha256":"7061b877cbfce909396908f278befe85c013582ffd33ecf61f4737a8fee27ff2"},{"path":"src/core/netlist-query/CircuitTraversal.mjs","sha256":"ac97c24c10f2cdf0f84fe080c7a1b76749a52f44b9d28461137fcd067b8fe116"},{"path":"src/core/netlist-query/ComponentGrouping.mjs","sha256":"54945b958a06b38632bec0ebe3a0947386f18acd1697a2b98d63cfaf6bf3a6b2"},{"path":"src/core/netlist-query/LoadedDesignNetlistService.mjs","sha256":"8d4c20f4f2454750459458f4896d76640777975198bdd0d1f84f16c4474118d7"},{"path":"src/core/netlist-query/QueryNetlistBuilder.mjs","sha256":"8f383d61bef2a012215e6e3ce596d26a1410ab890e56858a377dd5d66921b35a"},{"path":"src/core/netlist-query/RegexPattern.mjs","sha256":"1d40dc3362787a84e287cbe2ae99a8de46af94907009ee67432790469ae7129a"},{"path":"src/core/ole/OleCompoundDocument.mjs","sha256":"34d5771dfc5195e16d0eb167dafb3daec2ac60b214a1a57be5a7b9e78d5ca05e"},{"path":"src/core/ole/OleCompoundDocumentWriter.mjs","sha256":"387f511a4d4a6e03ca085ddf51ef9d9254910cd9cb3a140e4c9f67f90a89d7b4"},{"path":"src/core/ole/OleConstants.mjs","sha256":"dcef27b79d6d839eafcb62b51e7084f48a5567f5cf3bc09c1dd9255277ab5a6f"},{"path":"src/core/ole/OleDirectoryEntry.mjs","sha256":"dfdeba53530b63d4040582e55fc375cb708cf2c12032ca2619f171a32bcbd84e"},{"path":"src/ui/AltiumPcbBottomViewMirror.mjs","sha256":"892f549d381bc7c7b67254065f7c6ee1dd08c184ce4fccea9ac03391bde1be05"},{"path":"src/ui/AltiumScene3dAuthoredBodyAnchorAdapter.mjs","sha256":"5d9a7b036e323acdc620dcf2b8997c41606c287f75dab8f4516f07670ff6673e"},{"path":"src/ui/AltiumScene3dAuthoredConnectorYawPolicy.mjs","sha256":"f91fb4c98811a84dfc3511fb037cb9722f121344bd5056177756bf9c39fe38a2"},{"path":"src/ui/AltiumScene3dBottomPadRotationAdapter.mjs","sha256":"03fd6713891f2847b3b03808aeef00e77126b09bb372b9c112b626b83ee31f1d"},{"path":"src/ui/AltiumScene3dBottomSourceHalfTurnPolicy.mjs","sha256":"adcceb5d19085856a17b6772d2fb1520fc36d431bb4e4bdb1848e297d4ed90b7"},{"path":"src/ui/AltiumScene3dComponentBodyAdapter.mjs","sha256":"4aea27f91bad6deda2321f613eeb05bc4b6b3fcabf5b57b1515efce1b1a66ee1"},{"path":"src/ui/AltiumScene3dDisplayModuleYawPolicy.mjs","sha256":"293f0ff9c87cf560b57b14015611c24dc187514446beb03f62578aa3c2ca735a"},{"path":"src/ui/AltiumScene3dExternalPlacementAdapter.mjs","sha256":"f92410372e77df247594fd50339f19318d332da45b3d3bfdf80d23f61eb9a055"},{"path":"src/ui/AltiumScene3dIdentityTokens.mjs","sha256":"f4047d7cfb033d3f21f4a8b90bbba23f8aa408306f8ee7d44a42ccdaa178935d"},{"path":"src/ui/AltiumScene3dPlacementRotationPolicy.mjs","sha256":"32d272be4ed91616237cd8c74c7faa49f82138b7c03268490a28b2f2e2a9154a"},{"path":"src/ui/AltiumScene3dQfnFootprintDetector.mjs","sha256":"eb5ac1e634da650d0027d4b0f937ac0c4efd949c29b39bf4bd5fd03607d44518"},{"path":"src/ui/AltiumScene3dRepeatedFullFootprintBodyCollapse.mjs","sha256":"0536f4fe445d1bea5df85a6502de4ed8d1608390497eb1218da2fdbe5345573b"},{"path":"src/ui/AltiumScene3dRepeatedModelOwnerRepair.mjs","sha256":"a4b1ec5dd5abdcc17066bf66ea295eb44371af0f8a0bc47647e2f9163727424c"},{"path":"src/ui/AltiumScene3dShapeStackOwnerAdapter.mjs","sha256":"b18d55eea6a1a1837fa18e6e1d689f4fb2581e26e7a5aa7f95180b8901bf4e1d"},{"path":"src/ui/AltiumScene3dShapeStackOwnerConflictPolicy.mjs","sha256":"441c850eb6a50315ffcb0af6302473ca4f91827806c0ddb06aa051680697f605"},{"path":"src/ui/AltiumScene3dTwoRowFootprintDetector.mjs","sha256":"9a8a126ac7d1fd2e6045ec32102521a914142dc5f48cb26b94222a193e805f93"},{"path":"src/ui/BomTableRenderer.mjs","sha256":"0aa6a10bd109e50e92c6a6f67d44145f85664d37decf6d66c373a9602e7e55a8"},{"path":"src/ui/PcbArcUtils.mjs","sha256":"8ab6172352645dbf6dd6258ef5dec36cd549c5a96abcb287de5d2cd643fb4c75"},{"path":"src/ui/PcbBarcodeTextRenderer.mjs","sha256":"8d0b5ea8bf08bb91a2bced5c46e5ef8e0cae5989440e992218d8ac95413c0292"},{"path":"src/ui/PcbCopperPrimitiveSplitter.mjs","sha256":"759aa5f6d39511aac69f1f0ca3afe462b8595d4cad586c3b24d0a9064933971a"},{"path":"src/ui/PcbDimensionPrimitiveRenderer.mjs","sha256":"172f14b39b218d241fa6f2aa47cdee83ff587d9165b7c66b29a57ad4b23cf6ab"},{"path":"src/ui/PcbEdgeFacingGlyphNormalizer.mjs","sha256":"d1024e62e8cdf98f1677c1b881dc921a4533ec689d226a9fe89c9875b38875e2"},{"path":"src/ui/PcbEmbeddedFontFaceRenderer.mjs","sha256":"32e96fab5059009f199755e31bc963754073fc8a1deff400b7dc8e5951fb3a68"},{"path":"src/ui/PcbFootprintPadAxisNormalizer.mjs","sha256":"c6841ba836e6cd1aee75f8145797eac9be471b5f7d2e9f95a2a4a213d47015e2"},{"path":"src/ui/PcbFootprintPrimitiveSelector.mjs","sha256":"17264251298c1aa2265d68447829ebd78efd480307f58a9b7cda4ce1cc3a334a"},{"path":"src/ui/PcbInteractionGeometry.mjs","sha256":"fa884a3e117d3fe7618c504be5f1c79c5fc74cc78db200d617e046f7da8239f1"},{"path":"src/ui/PcbInteractionIndex.mjs","sha256":"2aad186bb1a915d8f87560fdd517687521afb3584347077051589f13feec722a"},{"path":"src/ui/PcbInteractionItemRegistry.mjs","sha256":"4acc5a0a2697bb70c107f02484e6fa24c3da1f163dad1e40436c3a84452a8cfe"},{"path":"src/ui/PcbInteractionLayerModel.mjs","sha256":"f0926044f604a4ec18107de516933208c1d63725e545522e229f280701a36cfe"},{"path":"src/ui/PcbNativeTextKnockoutDetector.mjs","sha256":"0ca6bcaab6586846c1838d457c7eb80f4458c977a210d1c263b92781edaba3ab"},{"path":"src/ui/PcbPadMaskApertureRenderer.mjs","sha256":"803a931a56a900d73bf9b49771131659b515526acf21f8ee864efdf0602e9be4"},{"path":"src/ui/PcbRegionPrimitiveRenderer.mjs","sha256":"80ffbdbaa8325959e8efa3ccc33fea9f022cbe92da997c35cd73e02a2c79ee5b"},{"path":"src/ui/PcbScene3dBoardOutlineRefiner.mjs","sha256":"aa82e2558869d071b7f482ceb292d243be16875952e454d264e17b8cd835c89d"},{"path":"src/ui/PcbScene3dBuilder.mjs","sha256":"54900524eab8486363758fceb8d3c6e4118545c3050040c54c95112527f84094"},{"path":"src/ui/PcbScene3dCopperRegionDetailBuilder.mjs","sha256":"efc6a5a93193a45d5d2502c97268e5f17935d346aadca802ee6a2d68ecbb7bac"},{"path":"src/ui/PcbScene3dDrillCutoutBuilder.mjs","sha256":"8b45e376f759f0701b367af8128854f2187143eb82d6f0e5ab0ce9d1154faaf8"},{"path":"src/ui/PcbScene3dModelRegistry.mjs","sha256":"b7ed18b37a044be3eb6772d5aa0fbce3911eb94e2efaa87e3b135ed3629cce85"},{"path":"src/ui/PcbScene3dPackageDimensionResolver.mjs","sha256":"2a7c44fa552bffecf56bc6f59a7e30b7040f489d8d2e2c66f5faf7defbe00a87"},{"path":"src/ui/PcbScene3dPackages.mjs","sha256":"44d27b169f233db741f0cb25d7a8206c7cdc079466c5efb06ca8aa4146b957f9"},{"path":"src/ui/PcbScene3dPadLocalSpanResolver.mjs","sha256":"f6ce117b38deb770a56a08ef2911319e17b688cf751867027d2d22f09c650caa"},{"path":"src/ui/PcbScene3dPadYawResolver.mjs","sha256":"ea04e8f95242437563aaa14c8a226ed53a056fe4e574249565d421d9048843dc"},{"path":"src/ui/PcbScene3dPlacementSideResolver.mjs","sha256":"ea1a40159125375c846dc82f61dbc9a2b112dacd5d0e5c4ecc589901866ed645"},{"path":"src/ui/PcbScene3dScenePreparator.mjs","sha256":"a5a12fe7b0b3e18d71268f263a221d63e47549bbf1699f9e248a1e1e8b95ac7a"},{"path":"src/ui/PcbScene3dStaticBodyOwnerPromotion.mjs","sha256":"af6c44f8b907073b71ad484c535a88a61284e7652d711fce9c2cd6bbcbe499bb"},{"path":"src/ui/PcbScene3dStaticBodyPadOwnerPromotion.mjs","sha256":"a905c4744c7df078596f8fa0b58a5e9dd2766f9535566737ea895af903a6c385"},{"path":"src/ui/PcbScene3dStaticBodyPlacementBuilder.mjs","sha256":"23bdd9151089f9a1afea5aede98c33fc7b1bf34f333df8feb91c129886e47cde"},{"path":"src/ui/PcbScene3dStaticBodyPrototypeRecovery.mjs","sha256":"48b12d3406c19a3b5727b701c9f7532a19f6bd637305fa51dfe0c24f6d9bc375"},{"path":"src/ui/PcbScene3dStaticBodyRecovery.mjs","sha256":"d868c313ab9ed8d45ef81ed1b1c1d383de148ae01c9b197bbe303d6dcdffa762"},{"path":"src/ui/PcbScene3dStaticBodySelectionKeyBuilder.mjs","sha256":"7d130e9ab1e1bfe357096241471c2a14fd904b86c612a81a4254cf9d26a985b8"},{"path":"src/ui/PcbScene3dStaticBodySymmetricOwnerPromotion.mjs","sha256":"0e3676f2f2a0466476d38314c40bba5edc11f201985da3025247a50615661f4c"},{"path":"src/ui/PcbScene3dStaticBodySymmetryRecovery.mjs","sha256":"ce20c07bd055825ed918505ab5eaa7fef5d91bd15473578835df54559569862b"},{"path":"src/ui/PcbScene3dSummaryRenderer.mjs","sha256":"3c4312018accda438d5482d3b7fb686687b328caa563c8b9806d4225b4f68acf"},{"path":"src/ui/PcbScene3dTextBoxLayoutResolver.mjs","sha256":"6e2f3083555a4cb5faedef7dbf2bf443fd94f577ea463783c3ec77eb80be6fbe"},{"path":"src/ui/PcbSideResolvedRenderModel.mjs","sha256":"62647b98263dc6cdc9a79ed6fc48705b054abc534ba6decd9582043606f25389"},{"path":"src/ui/PcbSvgRenderer.mjs","sha256":"32273a67574a2b803e80f52e178d0d8320f858bf6d9fb303b1fc28d538e982ca"},{"path":"src/ui/PcbTextPrimitiveRenderer.mjs","sha256":"d1eae1dfa71b5be8c166564595bf308990221a83328bd04a65ea89ba2b49ceed"},{"path":"src/ui/SchematicColorResolver.mjs","sha256":"ba03749bd50a9f3b5db57334ff4fc4f42b8f95a95fc30ab36b1d1199a66da731"},{"path":"src/ui/SchematicContentLayout.mjs","sha256":"bc8996084da679aa9fae0728b13117c0178363edc229f1f16b19d661cfea7486"},{"path":"src/ui/SchematicDirectiveRenderer.mjs","sha256":"c29ab1e779e8e374db3b441c6e35614ce482ddc1735a0b408f9edb8a13762066"},{"path":"src/ui/SchematicImageRenderer.mjs","sha256":"647858a10a6a5fc77af63e88fc7644c6511070ec330f7fdbfd7694f0a3377d93"},{"path":"src/ui/SchematicJunctionRenderer.mjs","sha256":"6584af8fa602aac987fe8376121d3cfe12738f67750e2830116c6cca28ae9c59"},{"path":"src/ui/SchematicLineColorResolver.mjs","sha256":"8c46bcd318e5a175ecb5ccf53477b07a1c185928695c29e45f0afe17c2fc7203"},{"path":"src/ui/SchematicNativeFooterPartitioner.mjs","sha256":"ebdee1fd03050c95180c4f301a5ecf38e7e47594b97aae65bac8f1f391183af5"},{"path":"src/ui/SchematicNoteRenderer.mjs","sha256":"85835827e14fb491a824b55b107470fb9528b5c6a642aaefe391845cbb72b901"},{"path":"src/ui/SchematicOwnerPinLabelLayout.mjs","sha256":"4379716eae1f6b35ce516aac05ca986c0c3580c0363b1b75380919b797fa0b8b"},{"path":"src/ui/SchematicOwnerPinMarkerLineThemer.mjs","sha256":"988eb199dfa2ee1a7f0f3536ec5a29b1a4872c5daa7cca2c36475823d88d472b"},{"path":"src/ui/SchematicPinSvgRenderer.mjs","sha256":"78dd0cd4b3a2ae2b4ff0b1924c76ad41cf035efe168d3e7c432b691020a4bb34"},{"path":"src/ui/SchematicPortRenderer.mjs","sha256":"ffe1c9103b3c6951e1387f0e16c8f2cf78ee3c119e798728ffcc866d966d8320"},{"path":"src/ui/SchematicPowerDiagramImageProcessor.mjs","sha256":"4cb4f144e7ab12556e66be77ee686501ffebc07696f1ca32c917faa355fc5b71"},{"path":"src/ui/SchematicPowerDiagramLineMasks.mjs","sha256":"61842c13729b9b61fb015010e281236dd8ec2295a41d93389db30b6271e61606"},{"path":"src/ui/SchematicPowerPortRenderer.mjs","sha256":"3247da347bd85729d3b3421be1395c18705fd08d85678498c521b3abb7cde0ed"},{"path":"src/ui/SchematicRegionRenderer.mjs","sha256":"b7ee4bda1feff5727db80e5b5218642a856b1d55abaedb06a4535be32e99e48e"},{"path":"src/ui/SchematicRenderOpsSidecarBuilder.mjs","sha256":"cc99e49c940b1dab0185e902b8f62eda9bbef56844421d15b6d1479e0ecdd62a"},{"path":"src/ui/SchematicShapeRenderer.mjs","sha256":"677b514a26b507308ade0c5eba137b0a958f80cd11bbc52b22a93f448951ad02"},{"path":"src/ui/SchematicSheetChromeRenderer.mjs","sha256":"53f7711cf24767e310272912178f3db31d44b55b1a5c9be6c01dfbc09306efab"},{"path":"src/ui/SchematicSheetSymbolRenderer.mjs","sha256":"a9bd87ac3e0950938276d6aaa060a060137bf3a414bb1f1b8e1ea4334c03e2c4"},{"path":"src/ui/SchematicSheetZoneRenderer.mjs","sha256":"1fe5934f7cc8c66a6215303ad4ef6f73baa9528724c3d9940aec10e04b1d3ae6"},{"path":"src/ui/SchematicSvgRenderer.mjs","sha256":"1be780c1ba094c4944db1e7ae535228a7dd54492494f2b9fc936c94adbc140f5"},{"path":"src/ui/SchematicSvgUtils.mjs","sha256":"7aabdf074d2ebbd741df6d686c794cd437c02c9e9d3c8297d52e56bdb5eac902"},{"path":"src/ui/SchematicTypography.mjs","sha256":"7910eca9a01d84eb5fec775469a9db581d35f7560ccde27a4ac818658097a65c"},{"path":"src/ui/TextGeometrySidecarBuilder.mjs","sha256":"3d00ee22ace17bec70d41c0f527779b0d7ea347b2bda1833e15910f24693e1cf"}],"artifactChecksum":"e3bfcbcdd0fdcda6de5f08c16a75949eb377749274d742a7a89ff16ad3a09c98"}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 André Fiedler
|
|
2
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
import { CircuitJsonModelAdapterPrimitives } from '../core/circuit-json/CircuitJsonModelAdapterPrimitives.mjs'
|
|
5
|
+
import { CircuitJsonSchematicGraphicBuilder } from '../core/circuit-json/CircuitJsonSchematicGraphicBuilder.mjs'
|
|
6
|
+
import { AltiumSchematicCoordinateProjection } from './AltiumSchematicCoordinateProjection.mjs'
|
|
7
|
+
|
|
8
|
+
const Primitives = CircuitJsonModelAdapterPrimitives
|
|
9
|
+
const LEGACY_SCHEMATIC_DRAWING_TYPES = new Set([
|
|
10
|
+
'schematic_line',
|
|
11
|
+
'schematic_net_label',
|
|
12
|
+
'schematic_text',
|
|
13
|
+
'schematic_trace'
|
|
14
|
+
])
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Enriches the frozen native adapter output at the common API boundary.
|
|
18
|
+
*/
|
|
19
|
+
export class AltiumCircuitJsonProjection {
|
|
20
|
+
/**
|
|
21
|
+
* Replaces the legacy minimal drawing subset with the rich common model.
|
|
22
|
+
* @param {object[]} adapted Historical adapter output.
|
|
23
|
+
* @param {Record<string, any>} native Native renderer model.
|
|
24
|
+
* @returns {object[]} Canonical CircuitJSON rows.
|
|
25
|
+
*/
|
|
26
|
+
static project(adapted, native) {
|
|
27
|
+
const nativeSchematic = native?.schematic
|
|
28
|
+
if (!nativeSchematic) return [...adapted]
|
|
29
|
+
const schematic =
|
|
30
|
+
AltiumCircuitJsonProjection.#schematicWithSourceTypes(
|
|
31
|
+
nativeSchematic
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
const sourceFormat = Primitives.sourceFormat(native)
|
|
35
|
+
const idScope = Primitives.idScope(native, sourceFormat)
|
|
36
|
+
const componentIds = AltiumCircuitJsonProjection.#componentIds(
|
|
37
|
+
schematic,
|
|
38
|
+
idScope
|
|
39
|
+
)
|
|
40
|
+
const hiddenComponentIds = new Set(
|
|
41
|
+
Primitives.array(schematic.components)
|
|
42
|
+
.filter(
|
|
43
|
+
(component) =>
|
|
44
|
+
component?.schematicDesignatorVisible === false
|
|
45
|
+
)
|
|
46
|
+
.map((component) => componentIds.get(component))
|
|
47
|
+
.filter(Boolean)
|
|
48
|
+
)
|
|
49
|
+
const nativeComponentsById = new Map(
|
|
50
|
+
Primitives.array(schematic.components).map((component) => [
|
|
51
|
+
componentIds.get(component),
|
|
52
|
+
component
|
|
53
|
+
])
|
|
54
|
+
)
|
|
55
|
+
const legacySchematicSourceTraceIds = new Set(
|
|
56
|
+
adapted
|
|
57
|
+
.filter((element) => element?.type === 'schematic_trace')
|
|
58
|
+
.map((element) => String(element.source_trace_id || ''))
|
|
59
|
+
.filter(Boolean)
|
|
60
|
+
)
|
|
61
|
+
const protectedPcbSourceTraceIds = new Set(
|
|
62
|
+
adapted
|
|
63
|
+
.filter((element) => element?.type === 'pcb_trace')
|
|
64
|
+
.map((element) => String(element.source_trace_id || ''))
|
|
65
|
+
.filter(Boolean)
|
|
66
|
+
)
|
|
67
|
+
const model = adapted
|
|
68
|
+
.filter((element) =>
|
|
69
|
+
AltiumCircuitJsonProjection.#preservesAdaptedElement(
|
|
70
|
+
element,
|
|
71
|
+
legacySchematicSourceTraceIds,
|
|
72
|
+
protectedPcbSourceTraceIds
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
.map((element) => {
|
|
76
|
+
if (element?.type !== 'schematic_component') return element
|
|
77
|
+
const component = nativeComponentsById.get(
|
|
78
|
+
element.schematic_component_id
|
|
79
|
+
)
|
|
80
|
+
return {
|
|
81
|
+
...element,
|
|
82
|
+
rotation: -(
|
|
83
|
+
Primitives.number(
|
|
84
|
+
component?.rotation,
|
|
85
|
+
element.rotation
|
|
86
|
+
) || 0
|
|
87
|
+
),
|
|
88
|
+
...(hiddenComponentIds.has(element.schematic_component_id)
|
|
89
|
+
? { show_label: false }
|
|
90
|
+
: {})
|
|
91
|
+
}
|
|
92
|
+
})
|
|
93
|
+
const netIds = AltiumCircuitJsonProjection.#netIds(model)
|
|
94
|
+
|
|
95
|
+
model.push(
|
|
96
|
+
AltiumCircuitJsonProjection.#rootSheet(schematic, native, idScope)
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
CircuitJsonSchematicGraphicBuilder.append(
|
|
100
|
+
model,
|
|
101
|
+
schematic,
|
|
102
|
+
idScope,
|
|
103
|
+
componentIds,
|
|
104
|
+
netIds
|
|
105
|
+
)
|
|
106
|
+
return AltiumSchematicCoordinateProjection.project(
|
|
107
|
+
model,
|
|
108
|
+
schematic?.sheet?.height
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Classifies native Altium record-27 wire segments at the convergence
|
|
114
|
+
* boundary while preserving explicit source-neutral classifications.
|
|
115
|
+
* @param {Record<string, any>} schematic Historical native schematic.
|
|
116
|
+
* @returns {Record<string, any>} Projection-owned schematic view.
|
|
117
|
+
*/
|
|
118
|
+
static #schematicWithSourceTypes(schematic) {
|
|
119
|
+
return {
|
|
120
|
+
...schematic,
|
|
121
|
+
lines: Primitives.array(schematic.lines).map((line) =>
|
|
122
|
+
Object.hasOwn(line || {}, 'sourceType')
|
|
123
|
+
? line
|
|
124
|
+
: {
|
|
125
|
+
...line,
|
|
126
|
+
sourceType:
|
|
127
|
+
String(line?.recordType || '') === '27'
|
|
128
|
+
? 'wire'
|
|
129
|
+
: 'graphic'
|
|
130
|
+
}
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Keeps source traces unless they exclusively back the legacy schematic
|
|
137
|
+
* projection. PCB and unrelated source relations remain byte-for-byte.
|
|
138
|
+
* @param {Record<string, any>} element Adapted CircuitJSON row.
|
|
139
|
+
* @param {Set<string>} legacySchematicSourceTraceIds Schematic trace ids.
|
|
140
|
+
* @param {Set<string>} protectedPcbSourceTraceIds PCB trace ids.
|
|
141
|
+
* @returns {boolean} Whether the adapted row belongs in the rich model.
|
|
142
|
+
*/
|
|
143
|
+
static #preservesAdaptedElement(
|
|
144
|
+
element,
|
|
145
|
+
legacySchematicSourceTraceIds,
|
|
146
|
+
protectedPcbSourceTraceIds
|
|
147
|
+
) {
|
|
148
|
+
const type = String(element?.type || '')
|
|
149
|
+
if (LEGACY_SCHEMATIC_DRAWING_TYPES.has(type)) return false
|
|
150
|
+
if (type !== 'source_trace') return true
|
|
151
|
+
|
|
152
|
+
const id = String(element.source_trace_id || '')
|
|
153
|
+
return (
|
|
154
|
+
!legacySchematicSourceTraceIds.has(id) ||
|
|
155
|
+
protectedPcbSourceTraceIds.has(id)
|
|
156
|
+
)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Projects the source page as the root sheet, not a child-sheet symbol.
|
|
161
|
+
* @param {Record<string, any>} schematic Native schematic.
|
|
162
|
+
* @param {Record<string, any>} native Native document.
|
|
163
|
+
* @param {string} idScope Document id scope.
|
|
164
|
+
* @returns {object} Canonical root-sheet row.
|
|
165
|
+
*/
|
|
166
|
+
static #rootSheet(schematic, native, idScope) {
|
|
167
|
+
return {
|
|
168
|
+
type: 'schematic_sheet',
|
|
169
|
+
schematic_sheet_id: Primitives.id(idScope, [
|
|
170
|
+
'schematic_sheet',
|
|
171
|
+
'root'
|
|
172
|
+
]),
|
|
173
|
+
name: Primitives.string(
|
|
174
|
+
native?.summary?.title || native?.fileName,
|
|
175
|
+
'Main'
|
|
176
|
+
),
|
|
177
|
+
sheet_index: 0,
|
|
178
|
+
width: Math.max(
|
|
179
|
+
Primitives.number(schematic?.sheet?.width, 0) || 0,
|
|
180
|
+
0
|
|
181
|
+
),
|
|
182
|
+
height: Math.max(
|
|
183
|
+
Primitives.number(schematic?.sheet?.height, 0) || 0,
|
|
184
|
+
0
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Reconstructs historical deterministic component ids without mutation.
|
|
191
|
+
* @param {Record<string, any>} schematic Native schematic.
|
|
192
|
+
* @param {string} idScope Document id scope.
|
|
193
|
+
* @returns {Map<object, string>} Native component id lookup.
|
|
194
|
+
*/
|
|
195
|
+
static #componentIds(schematic, idScope) {
|
|
196
|
+
const ids = new Map()
|
|
197
|
+
for (const [index, component] of Primitives.array(
|
|
198
|
+
schematic?.components
|
|
199
|
+
).entries()) {
|
|
200
|
+
ids.set(
|
|
201
|
+
component,
|
|
202
|
+
Primitives.id(idScope, [
|
|
203
|
+
'schematic_component',
|
|
204
|
+
component?.designator || component?.name || index
|
|
205
|
+
])
|
|
206
|
+
)
|
|
207
|
+
}
|
|
208
|
+
return ids
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Indexes canonical source nets by their native names.
|
|
213
|
+
* @param {object[]} model Canonical rows.
|
|
214
|
+
* @returns {Map<string, string>} Source-net id lookup.
|
|
215
|
+
*/
|
|
216
|
+
static #netIds(model) {
|
|
217
|
+
return new Map(
|
|
218
|
+
model
|
|
219
|
+
.filter((element) => element?.type === 'source_net')
|
|
220
|
+
.map((element) => [
|
|
221
|
+
String(element.name || ''),
|
|
222
|
+
String(element.source_net_id || '')
|
|
223
|
+
])
|
|
224
|
+
.filter(([name, id]) => name && id)
|
|
225
|
+
)
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
Object.freeze(AltiumCircuitJsonProjection.prototype)
|
|
230
|
+
Object.freeze(AltiumCircuitJsonProjection)
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 André Fiedler
|
|
2
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
import { DocumentResult, ToolkitAsset } from 'circuitjson-toolkit/parser'
|
|
5
|
+
|
|
6
|
+
import { AltiumParser } from '../core/altium/AltiumParser.mjs'
|
|
7
|
+
import { CircuitJsonModelAdapter } from '../core/circuit-json/CircuitJsonModelAdapter.mjs'
|
|
8
|
+
import { CircuitJsonSchematicImageProjection } from '../core/circuit-json/CircuitJsonSchematicImageProjection.mjs'
|
|
9
|
+
import { AltiumCircuitJsonProjection } from './AltiumCircuitJsonProjection.mjs'
|
|
10
|
+
import { ParserInput } from './ParserInput.mjs'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Converts one native parse into a canonical CircuitJSON document envelope.
|
|
14
|
+
*/
|
|
15
|
+
export class AltiumDocumentBuilder {
|
|
16
|
+
/**
|
|
17
|
+
* Runs the native parser and CircuitJSON adapter exactly once.
|
|
18
|
+
* @param {{ input: { fileName: string, data: string | ArrayBuffer | Uint8Array } }} normalized Normalized request.
|
|
19
|
+
* @returns {{ native: Record<string, any>, model: object[], nativeSidecarCount: number }} Decoded source data.
|
|
20
|
+
*/
|
|
21
|
+
static decode(normalized) {
|
|
22
|
+
const buffer = ParserInput.arrayBuffer(normalized.input.data)
|
|
23
|
+
const native = AltiumParser.parseArrayBufferToRendererModel(
|
|
24
|
+
normalized.input.fileName,
|
|
25
|
+
buffer
|
|
26
|
+
)
|
|
27
|
+
const adapted = CircuitJsonModelAdapter.fromRendererModel(native)
|
|
28
|
+
const projected = AltiumCircuitJsonProjection.project(adapted, native)
|
|
29
|
+
const model = projected.filter(
|
|
30
|
+
(element) =>
|
|
31
|
+
!String(element?.type || '').startsWith('altium_toolkit_')
|
|
32
|
+
)
|
|
33
|
+
return {
|
|
34
|
+
native,
|
|
35
|
+
model,
|
|
36
|
+
nativeSidecarCount: projected.length - model.length
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Parses and validates one normalized request exactly once.
|
|
42
|
+
* @param {{ input: { fileName: string, data: string | ArrayBuffer | Uint8Array, assets: object[] }, sourceReference: object, options: Record<string, any> }} normalized Normalized request.
|
|
43
|
+
* @param {{ native: Record<string, any>, model: object[], nativeSidecarCount: number } | null} [decoded] Previously decoded source data.
|
|
44
|
+
* @returns {Record<string, any>} Canonical immutable document.
|
|
45
|
+
*/
|
|
46
|
+
static build(normalized, decoded = null) {
|
|
47
|
+
const prepared = decoded || AltiumDocumentBuilder.decode(normalized)
|
|
48
|
+
const { model, native } = prepared
|
|
49
|
+
const extension = AltiumDocumentBuilder.#extension(
|
|
50
|
+
native,
|
|
51
|
+
normalized.options
|
|
52
|
+
)
|
|
53
|
+
const runtime =
|
|
54
|
+
normalized.options.retainSource === 'reference'
|
|
55
|
+
? { sourceReference: normalized.sourceReference }
|
|
56
|
+
: {}
|
|
57
|
+
return DocumentResult.createValidated(
|
|
58
|
+
{
|
|
59
|
+
model,
|
|
60
|
+
source: {
|
|
61
|
+
format: 'altium',
|
|
62
|
+
fileName: normalized.input.fileName,
|
|
63
|
+
fileType: ParserInput.suffix(normalized.input.fileName)
|
|
64
|
+
},
|
|
65
|
+
extensions: extension ? { altium: extension } : {},
|
|
66
|
+
assets: AltiumDocumentBuilder.#assets(
|
|
67
|
+
normalized.input.assets,
|
|
68
|
+
normalized.options.decodeAssets,
|
|
69
|
+
native
|
|
70
|
+
),
|
|
71
|
+
diagnostics: [
|
|
72
|
+
...(native.diagnostics || []),
|
|
73
|
+
...CircuitJsonSchematicImageProjection.diagnostics(native)
|
|
74
|
+
],
|
|
75
|
+
statistics: {
|
|
76
|
+
elementCount: model.length,
|
|
77
|
+
nativeSidecarCount: prepared.nativeSidecarCount,
|
|
78
|
+
nativeKind: String(native.kind || '')
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
runtime
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Selects source-native extension facts according to common options.
|
|
87
|
+
* @param {Record<string, any>} native Native renderer model.
|
|
88
|
+
* @param {Record<string, any>} options Common options.
|
|
89
|
+
* @returns {Record<string, any> | null} Extension payload or null.
|
|
90
|
+
*/
|
|
91
|
+
static #extension(native, options) {
|
|
92
|
+
if (
|
|
93
|
+
options.extensions === 'none' ||
|
|
94
|
+
(Array.isArray(options.extensions) && !options.extensions.length)
|
|
95
|
+
) {
|
|
96
|
+
return null
|
|
97
|
+
}
|
|
98
|
+
const includeNative =
|
|
99
|
+
options.extensions === 'full' ||
|
|
100
|
+
options.preserveRaw ||
|
|
101
|
+
(Array.isArray(options.extensions) &&
|
|
102
|
+
options.extensions.includes('altium.native-model'))
|
|
103
|
+
const completeness =
|
|
104
|
+
options.extensions === 'full'
|
|
105
|
+
? 'full'
|
|
106
|
+
: options.extensions === 'metadata'
|
|
107
|
+
? 'metadata'
|
|
108
|
+
: 'canonical'
|
|
109
|
+
const projectContext = AltiumDocumentBuilder.#projectContext(native)
|
|
110
|
+
const metadata = {
|
|
111
|
+
$meta: {
|
|
112
|
+
schema: 'ecad-toolkit.extension.v1',
|
|
113
|
+
completeness,
|
|
114
|
+
included: [
|
|
115
|
+
'altium.summary',
|
|
116
|
+
...(projectContext ? ['altium.project-context'] : []),
|
|
117
|
+
...(includeNative ? ['altium.native-model'] : [])
|
|
118
|
+
],
|
|
119
|
+
omitted: []
|
|
120
|
+
},
|
|
121
|
+
kind: String(native.kind || ''),
|
|
122
|
+
fileType: String(native.fileType || ''),
|
|
123
|
+
summary: native.summary || {},
|
|
124
|
+
...(projectContext ? { projectContext } : {})
|
|
125
|
+
}
|
|
126
|
+
return includeNative ? { ...metadata, native } : metadata
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Selects compact project facts required to resolve canonical schematics.
|
|
131
|
+
* @param {Record<string, any>} native Native renderer model.
|
|
132
|
+
* @returns {{ parameters: Record<string, string>, documents: string[] } | null} Project facts.
|
|
133
|
+
*/
|
|
134
|
+
static #projectContext(native) {
|
|
135
|
+
if (native?.kind !== 'project' || !native.project) return null
|
|
136
|
+
const parameters = Object.fromEntries(
|
|
137
|
+
(native.project.parameters?.list || []).map((parameter) => [
|
|
138
|
+
String(parameter?.name || ''),
|
|
139
|
+
String(parameter?.value || '')
|
|
140
|
+
])
|
|
141
|
+
)
|
|
142
|
+
const documents = (native.project.documents || []).map((document) =>
|
|
143
|
+
String(document?.normalizedPath || document?.path || '')
|
|
144
|
+
)
|
|
145
|
+
return { parameters, documents }
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Applies the common asset decode policy without sharing caller buffers.
|
|
150
|
+
* @param {object[]} assets Caller-supplied assets.
|
|
151
|
+
* @param {string} mode Decode mode.
|
|
152
|
+
* @param {Record<string, unknown>} native Native renderer model.
|
|
153
|
+
* @returns {object[]} Canonical asset records.
|
|
154
|
+
*/
|
|
155
|
+
static #assets(assets, mode, native) {
|
|
156
|
+
return [
|
|
157
|
+
...ToolkitAsset.prepareAll(assets, { mode }),
|
|
158
|
+
...ToolkitAsset.prepareAll(
|
|
159
|
+
CircuitJsonSchematicImageProjection.assets(native),
|
|
160
|
+
{ mode }
|
|
161
|
+
)
|
|
162
|
+
]
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
Object.freeze(AltiumDocumentBuilder.prototype)
|
|
167
|
+
Object.freeze(AltiumDocumentBuilder)
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 André Fiedler
|
|
2
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
const DOCUMENT_SCHEMA = 'ecad-toolkit.document.v1'
|
|
5
|
+
|
|
6
|
+
/** Resolves explicit Altium source extensions without changing document shape. */
|
|
7
|
+
export class AltiumExtensionResolver {
|
|
8
|
+
/**
|
|
9
|
+
* Returns the retained native renderer model when explicitly requested.
|
|
10
|
+
* Historical native renderer models pass through unchanged so callers can
|
|
11
|
+
* use one boundary during migration.
|
|
12
|
+
* @param {unknown} document Canonical document or native renderer model.
|
|
13
|
+
* @returns {Record<string, any> | null} Retained native model.
|
|
14
|
+
*/
|
|
15
|
+
static nativeModel(document) {
|
|
16
|
+
if (!AltiumExtensionResolver.#record(document)) return null
|
|
17
|
+
const schema = String(
|
|
18
|
+
AltiumExtensionResolver.#data(document, 'schema') || ''
|
|
19
|
+
)
|
|
20
|
+
if (schema !== DOCUMENT_SCHEMA) {
|
|
21
|
+
return AltiumExtensionResolver.#isLegacyModel(document, schema)
|
|
22
|
+
? document
|
|
23
|
+
: null
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const source = AltiumExtensionResolver.#data(document, 'source')
|
|
27
|
+
if (
|
|
28
|
+
String(AltiumExtensionResolver.#data(source, 'format') || '') !==
|
|
29
|
+
'altium'
|
|
30
|
+
) {
|
|
31
|
+
return null
|
|
32
|
+
}
|
|
33
|
+
const extensions = AltiumExtensionResolver.#data(document, 'extensions')
|
|
34
|
+
const altium = AltiumExtensionResolver.#data(extensions, 'altium')
|
|
35
|
+
const native = AltiumExtensionResolver.#data(altium, 'native')
|
|
36
|
+
return AltiumExtensionResolver.#record(native) ? native : null
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Returns whether an explicit native renderer model is available.
|
|
41
|
+
* @param {unknown} document Canonical document or native renderer model.
|
|
42
|
+
* @returns {boolean} Whether native Altium data can be resolved.
|
|
43
|
+
*/
|
|
44
|
+
static hasNativeModel(document) {
|
|
45
|
+
return AltiumExtensionResolver.nativeModel(document) !== null
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Identifies a historical Altium renderer model by its owned schema.
|
|
50
|
+
* @param {Record<string, any>} value Model candidate.
|
|
51
|
+
* @param {string} schema Owned schema value.
|
|
52
|
+
* @returns {boolean} Whether the value is a native Altium model.
|
|
53
|
+
*/
|
|
54
|
+
static #isLegacyModel(value, schema) {
|
|
55
|
+
if (
|
|
56
|
+
schema.startsWith('urn:altium-toolkit:') ||
|
|
57
|
+
schema.startsWith('altium-toolkit.')
|
|
58
|
+
) {
|
|
59
|
+
return true
|
|
60
|
+
}
|
|
61
|
+
const sourceFormat = String(
|
|
62
|
+
AltiumExtensionResolver.#data(value, 'sourceFormat') || ''
|
|
63
|
+
)
|
|
64
|
+
return sourceFormat === 'altium'
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Reads one own data property without invoking accessors.
|
|
69
|
+
* @param {unknown} owner Field owner.
|
|
70
|
+
* @param {string} key Field name.
|
|
71
|
+
* @returns {unknown} Own data value or undefined.
|
|
72
|
+
*/
|
|
73
|
+
static #data(owner, key) {
|
|
74
|
+
if (!AltiumExtensionResolver.#record(owner)) return undefined
|
|
75
|
+
try {
|
|
76
|
+
const descriptor = Object.getOwnPropertyDescriptor(owner, key)
|
|
77
|
+
return descriptor && Object.hasOwn(descriptor, 'value')
|
|
78
|
+
? descriptor.value
|
|
79
|
+
: undefined
|
|
80
|
+
} catch {
|
|
81
|
+
return undefined
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Returns true for non-array object records.
|
|
87
|
+
* @param {unknown} value Candidate value.
|
|
88
|
+
* @returns {boolean} Whether the value is a record.
|
|
89
|
+
*/
|
|
90
|
+
static #record(value) {
|
|
91
|
+
return Boolean(
|
|
92
|
+
value && typeof value === 'object' && !Array.isArray(value)
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
Object.freeze(AltiumExtensionResolver.prototype)
|
|
98
|
+
Object.freeze(AltiumExtensionResolver)
|