]> git.r.bdr.sh - rbdr/map/blobdiff - Map.xcodeproj/project.pbxproj
Update to support notes + new style
[rbdr/map] / Map.xcodeproj / project.pbxproj
index b212de6ee8128558dc1ed803e815508ac46b9ade..9cd5d87f48829e9bc33f0d6064131bcb2e1c9c58 100644 (file)
@@ -3,37 +3,35 @@
        archiveVersion = 1;
        classes = {
        };
-       objectVersion = 50;
+       objectVersion = 53;
        objects = {
 
 /* Begin PBXBuildFile section */
                B523C73D25C98D9800C44061 /* NSImage+writePNG.swift in Sources */ = {isa = PBXBuildFile; fileRef = B523C73C25C98D9800C44061 /* NSImage+writePNG.swift */; };
                B523C74625C9BD3500C44061 /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B523C74525C9BD3500C44061 /* CloudKit.framework */; };
-               B523C74B25C9C1BA00C44061 /* DefaultMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B523C74A25C9C1BA00C44061 /* DefaultMapView.swift */; };
+               B523C74B25C9C1BA00C44061 /* EmptyMapDetailScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = B523C74A25C9C1BA00C44061 /* EmptyMapDetailScreen.swift */; };
                B523C75A25C9FD4900C44061 /* MapAxes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B523C75925C9FD4900C44061 /* MapAxes.swift */; };
                B523C76225CA05A300C44061 /* MapStages.swift in Sources */ = {isa = PBXBuildFile; fileRef = B523C76125CA05A300C44061 /* MapStages.swift */; };
                B523C76725CA071B00C44061 /* MapVertices.swift in Sources */ = {isa = PBXBuildFile; fileRef = B523C76625CA071B00C44061 /* MapVertices.swift */; };
                B523C76C25CA0DFA00C44061 /* MapEdges.swift in Sources */ = {isa = PBXBuildFile; fileRef = B523C76B25CA0DFA00C44061 /* MapEdges.swift */; };
                B523C77125CA121300C44061 /* MapBlockers.swift in Sources */ = {isa = PBXBuildFile; fileRef = B523C77025CA121300C44061 /* MapBlockers.swift */; };
-               B523C77625CA181100C44061 /* MapColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B523C77525CA181100C44061 /* MapColor.swift */; };
                B523C77E25CA294C00C44061 /* MapOpportunities.swift in Sources */ = {isa = PBXBuildFile; fileRef = B523C77D25CA294C00C44061 /* MapOpportunities.swift */; };
                B526257225C874F9003E73B7 /* MapApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526257125C874F9003E73B7 /* MapApp.swift */; };
-               B526257425C874F9003E73B7 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526257325C874F9003E73B7 /* ContentView.swift */; };
+               B526257425C874F9003E73B7 /* MapEditorWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526257325C874F9003E73B7 /* MapEditorWindow.swift */; };
                B526257625C874FA003E73B7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B526257525C874FA003E73B7 /* Assets.xcassets */; };
                B526257925C874FA003E73B7 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B526257825C874FA003E73B7 /* Preview Assets.xcassets */; };
                B526257B25C874FA003E73B7 /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526257A25C874FA003E73B7 /* Persistence.swift */; };
                B526257E25C874FA003E73B7 /* Map.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B526257C25C874FA003E73B7 /* Map.xcdatamodeld */; };
                B526258A25C874FA003E73B7 /* MapTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526258925C874FA003E73B7 /* MapTests.swift */; };
                B526259525C874FA003E73B7 /* MapUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526259425C874FA003E73B7 /* MapUITests.swift */; };
-               B52625A625C876C3003E73B7 /* MapDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52625A525C876C3003E73B7 /* MapDetail.swift */; };
+               B52625A625C876C3003E73B7 /* MapDetailScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52625A525C876C3003E73B7 /* MapDetailScreen.swift */; };
                B52625AB25C87909003E73B7 /* Date+format.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52625AA25C87909003E73B7 /* Date+format.swift */; };
-               B52625B025C87C14003E73B7 /* MapRender.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52625AF25C87C14003E73B7 /* MapRender.swift */; };
+               B52625B025C87C14003E73B7 /* MapRenderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52625AF25C87C14003E73B7 /* MapRenderView.swift */; };
                B52625BB25C884C2003E73B7 /* Map+parse.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52625BA25C884C2003E73B7 /* Map+parse.swift */; };
                B52625C625C8BD2A003E73B7 /* Stage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52625C525C8BD2A003E73B7 /* Stage.swift */; };
                B539516C25CB0C9300959F72 /* Store.swift in Sources */ = {isa = PBXBuildFile; fileRef = B539516B25CB0C9200959F72 /* Store.swift */; };
                B539517425CB0CA400959F72 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = B539517325CB0CA400959F72 /* AppState.swift */; };
                B539518125CB2D7A00959F72 /* MapTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B539518025CB2D7A00959F72 /* MapTextEditor.swift */; };
-               B587BB6025CDCECB00F328ED /* SlowMapRender.swift in Sources */ = {isa = PBXBuildFile; fileRef = B587BB5F25CDCECB00F328ED /* SlowMapRender.swift */; };
                B5CF75C925CC19FC003BFF3D /* EvolutionPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CF75C825CC19FC003BFF3D /* EvolutionPicker.swift */; };
                B5CF75CF25CC7965003BFF3D /* MapParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CF75CE25CC7965003BFF3D /* MapParser.swift */; };
                B5CF75D825CC79BC003BFF3D /* VertexParserStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CF75D725CC79BC003BFF3D /* VertexParserStrategy.swift */; };
                B5CF75EA25CC7A13003BFF3D /* OpportunityParserStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CF75E925CC7A13003BFF3D /* OpportunityParserStrategy.swift */; };
                B5CF75EF25CC7A4A003BFF3D /* StageParserStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CF75EE25CC7A4A003BFF3D /* StageParserStrategy.swift */; };
                B5CF75F725CC97CA003BFF3D /* Debouncer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CF75F625CC97CA003BFF3D /* Debouncer.swift */; };
+               B5F8D3082A06DD8C000EEA24 /* Font+Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F8D3072A06DD8C000EEA24 /* Font+Theme.swift */; };
+               B5F8D30B2A06E3E6000EEA24 /* Color+Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F8D30A2A06E3E6000EEA24 /* Color+Theme.swift */; };
+               B5F8D30E2A06E5C2000EEA24 /* Patterns in Frameworks */ = {isa = PBXBuildFile; productRef = B5F8D30D2A06E5C2000EEA24 /* Patterns */; };
+               B5F8D3102A07B33D000EEA24 /* NSColor+Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F8D30F2A07B33D000EEA24 /* NSColor+Theme.swift */; };
+               B5F8D3122A07B690000EEA24 /* NoteParserStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F8D3112A07B690000EEA24 /* NoteParserStrategy.swift */; };
+               B5F8D3142A07C05F000EEA24 /* MapNotes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F8D3132A07C05F000EEA24 /* MapNotes.swift */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
 /* Begin PBXFileReference section */
                B523C73C25C98D9800C44061 /* NSImage+writePNG.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSImage+writePNG.swift"; sourceTree = "<group>"; };
                B523C74525C9BD3500C44061 /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = System/Library/Frameworks/CloudKit.framework; sourceTree = SDKROOT; };
-               B523C74A25C9C1BA00C44061 /* DefaultMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultMapView.swift; sourceTree = "<group>"; };
+               B523C74A25C9C1BA00C44061 /* EmptyMapDetailScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyMapDetailScreen.swift; sourceTree = "<group>"; };
                B523C75925C9FD4900C44061 /* MapAxes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapAxes.swift; sourceTree = "<group>"; };
                B523C76125CA05A300C44061 /* MapStages.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapStages.swift; sourceTree = "<group>"; };
                B523C76625CA071B00C44061 /* MapVertices.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapVertices.swift; sourceTree = "<group>"; };
                B523C76B25CA0DFA00C44061 /* MapEdges.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapEdges.swift; sourceTree = "<group>"; };
                B523C77025CA121300C44061 /* MapBlockers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapBlockers.swift; sourceTree = "<group>"; };
-               B523C77525CA181100C44061 /* MapColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapColor.swift; sourceTree = "<group>"; };
                B523C77D25CA294C00C44061 /* MapOpportunities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapOpportunities.swift; sourceTree = "<group>"; };
                B526256E25C874F9003E73B7 /* Map.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Map.app; sourceTree = BUILT_PRODUCTS_DIR; };
                B526257125C874F9003E73B7 /* MapApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapApp.swift; sourceTree = "<group>"; };
-               B526257325C874F9003E73B7 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
+               B526257325C874F9003E73B7 /* MapEditorWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapEditorWindow.swift; sourceTree = "<group>"; };
                B526257525C874FA003E73B7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
                B526257825C874FA003E73B7 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
                B526257A25C874FA003E73B7 /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = "<group>"; };
                B526259025C874FA003E73B7 /* MapUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MapUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
                B526259425C874FA003E73B7 /* MapUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapUITests.swift; sourceTree = "<group>"; };
                B526259625C874FA003E73B7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
-               B52625A525C876C3003E73B7 /* MapDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapDetail.swift; sourceTree = "<group>"; };
+               B52625A525C876C3003E73B7 /* MapDetailScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapDetailScreen.swift; sourceTree = "<group>"; };
                B52625AA25C87909003E73B7 /* Date+format.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+format.swift"; sourceTree = "<group>"; };
-               B52625AF25C87C14003E73B7 /* MapRender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapRender.swift; sourceTree = "<group>"; };
+               B52625AF25C87C14003E73B7 /* MapRenderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapRenderView.swift; sourceTree = "<group>"; };
                B52625BA25C884C2003E73B7 /* Map+parse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Map+parse.swift"; sourceTree = "<group>"; };
                B52625C525C8BD2A003E73B7 /* Stage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Stage.swift; sourceTree = "<group>"; };
                B539516B25CB0C9200959F72 /* Store.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Store.swift; sourceTree = "<group>"; };
                B539517325CB0CA400959F72 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = "<group>"; };
                B539518025CB2D7A00959F72 /* MapTextEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTextEditor.swift; sourceTree = "<group>"; };
-               B587BB5F25CDCECB00F328ED /* SlowMapRender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SlowMapRender.swift; sourceTree = "<group>"; };
                B5CF75C825CC19FC003BFF3D /* EvolutionPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EvolutionPicker.swift; sourceTree = "<group>"; };
                B5CF75CE25CC7965003BFF3D /* MapParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapParser.swift; sourceTree = "<group>"; };
                B5CF75D725CC79BC003BFF3D /* VertexParserStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VertexParserStrategy.swift; sourceTree = "<group>"; };
                B5CF75E925CC7A13003BFF3D /* OpportunityParserStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpportunityParserStrategy.swift; sourceTree = "<group>"; };
                B5CF75EE25CC7A4A003BFF3D /* StageParserStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StageParserStrategy.swift; sourceTree = "<group>"; };
                B5CF75F625CC97CA003BFF3D /* Debouncer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Debouncer.swift; sourceTree = "<group>"; };
+               B5F8D3072A06DD8C000EEA24 /* Font+Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Font+Theme.swift"; sourceTree = "<group>"; };
+               B5F8D30A2A06E3E6000EEA24 /* Color+Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Theme.swift"; sourceTree = "<group>"; };
+               B5F8D30F2A07B33D000EEA24 /* NSColor+Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSColor+Theme.swift"; sourceTree = "<group>"; };
+               B5F8D3112A07B690000EEA24 /* NoteParserStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteParserStrategy.swift; sourceTree = "<group>"; };
+               B5F8D3132A07C05F000EEA24 /* MapNotes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapNotes.swift; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
                        buildActionMask = 2147483647;
                        files = (
                                B523C74625C9BD3500C44061 /* CloudKit.framework in Frameworks */,
+                               B5F8D30E2A06E5C2000EEA24 /* Patterns in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        name = Frameworks;
                        sourceTree = "<group>";
                };
-               B523C75825C9FD3A00C44061 /* MapRenderComponents */ = {
+               B523C75825C9FD3A00C44061 /* MapRender */ = {
                        isa = PBXGroup;
                        children = (
                                B523C75925C9FD4900C44061 /* MapAxes.swift */,
                                B523C76125CA05A300C44061 /* MapStages.swift */,
                                B523C76625CA071B00C44061 /* MapVertices.swift */,
+                               B5F8D3132A07C05F000EEA24 /* MapNotes.swift */,
                                B523C76B25CA0DFA00C44061 /* MapEdges.swift */,
                                B523C77025CA121300C44061 /* MapBlockers.swift */,
                                B523C77D25CA294C00C44061 /* MapOpportunities.swift */,
                        );
-                       path = MapRenderComponents;
+                       path = MapRender;
                        sourceTree = "<group>";
                };
                B526256525C874F9003E73B7 = {
                B526257025C874F9003E73B7 /* Map */ = {
                        isa = PBXGroup;
                        children = (
-                               B523C77525CA181100C44061 /* MapColor.swift */,
-                               B5CF75CD25CC7953003BFF3D /* MapParser */,
-                               B539516A25CB0C7800959F72 /* State */,
-                               B52625B425C87D54003E73B7 /* Extensions */,
-                               B539517925CB0D6100959F72 /* Views */,
-                               B523C75825C9FD3A00C44061 /* MapRenderComponents */,
+                               B526257125C874F9003E73B7 /* MapApp.swift */,
+                               B5F8D2FE2A06DB3A000EEA24 /* Data */,
+                               B5F8D3092A06DE1A000EEA24 /* Logic */,
+                               B5F8D2FF2A06DB40000EEA24 /* Presentation */,
+                               B52625B425C87D54003E73B7 /* Core Extensions */,
                                B526257525C874FA003E73B7 /* Assets.xcassets */,
                                B526257F25C874FA003E73B7 /* Info.plist */,
                                B526258025C874FA003E73B7 /* Map.entitlements */,
                                B526257C25C874FA003E73B7 /* Map.xcdatamodeld */,
                                B526257725C874FA003E73B7 /* Preview Content */,
-                               B5CF75F625CC97CA003BFF3D /* Debouncer.swift */,
                        );
                        path = Map;
                        sourceTree = "<group>";
                        path = MapUITests;
                        sourceTree = "<group>";
                };
-               B52625B425C87D54003E73B7 /* Extensions */ = {
+               B52625B425C87D54003E73B7 /* Core Extensions */ = {
                        isa = PBXGroup;
                        children = (
-                               B52625BA25C884C2003E73B7 /* Map+parse.swift */,
                                B52625AA25C87909003E73B7 /* Date+format.swift */,
                                B523C73C25C98D9800C44061 /* NSImage+writePNG.swift */,
+                               B5F8D3072A06DD8C000EEA24 /* Font+Theme.swift */,
+                               B5F8D30F2A07B33D000EEA24 /* NSColor+Theme.swift */,
+                               B5F8D30A2A06E3E6000EEA24 /* Color+Theme.swift */,
                        );
-                       path = Extensions;
+                       path = "Core Extensions";
                        sourceTree = "<group>";
                };
-               B539516A25CB0C7800959F72 /* State */ = {
+               B5CF75CD25CC7953003BFF3D /* MapParser */ = {
                        isa = PBXGroup;
                        children = (
+                               B5CF75D625CC79A4003BFF3D /* Strategies */,
+                               B5CF75CE25CC7965003BFF3D /* MapParser.swift */,
+                       );
+                       path = MapParser;
+                       sourceTree = "<group>";
+               };
+               B5CF75D625CC79A4003BFF3D /* Strategies */ = {
+                       isa = PBXGroup;
+                       children = (
+                               B5CF75D725CC79BC003BFF3D /* VertexParserStrategy.swift */,
+                               B5F8D3112A07B690000EEA24 /* NoteParserStrategy.swift */,
+                               B5CF75DC25CC79D7003BFF3D /* EdgeParserStrategy.swift */,
+                               B5CF75E125CC79ED003BFF3D /* BlockerParserStrategy.swift */,
+                               B5CF75E925CC7A13003BFF3D /* OpportunityParserStrategy.swift */,
+                               B5CF75EE25CC7A4A003BFF3D /* StageParserStrategy.swift */,
+                       );
+                       path = Strategies;
+                       sourceTree = "<group>";
+               };
+               B5F8D2FE2A06DB3A000EEA24 /* Data */ = {
+                       isa = PBXGroup;
+                       children = (
+                               B5F8D3012A06DB75000EEA24 /* Models */,
                                B52625C525C8BD2A003E73B7 /* Stage.swift */,
                                B526257A25C874FA003E73B7 /* Persistence.swift */,
                                B539516B25CB0C9200959F72 /* Store.swift */,
                                B539517325CB0CA400959F72 /* AppState.swift */,
                        );
-                       path = State;
+                       path = Data;
                        sourceTree = "<group>";
                };
-               B539517925CB0D6100959F72 /* Views */ = {
+               B5F8D2FF2A06DB40000EEA24 /* Presentation */ = {
+                       isa = PBXGroup;
+                       children = (
+                               B5F8D3022A06DBC3000EEA24 /* Windows */,
+                               B5F8D3032A06DC2D000EEA24 /* Screens */,
+                               B5F8D3052A06DCF3000EEA24 /* Complex Components */,
+                               B5F8D3042A06DCC4000EEA24 /* Base Components */,
+                       );
+                       path = Presentation;
+                       sourceTree = "<group>";
+               };
+               B5F8D3012A06DB75000EEA24 /* Models */ = {
+                       isa = PBXGroup;
+                       children = (
+                               B52625BA25C884C2003E73B7 /* Map+parse.swift */,
+                       );
+                       path = Models;
+                       sourceTree = "<group>";
+               };
+               B5F8D3022A06DBC3000EEA24 /* Windows */ = {
+                       isa = PBXGroup;
+                       children = (
+                               B526257325C874F9003E73B7 /* MapEditorWindow.swift */,
+                       );
+                       path = Windows;
+                       sourceTree = "<group>";
+               };
+               B5F8D3032A06DC2D000EEA24 /* Screens */ = {
+                       isa = PBXGroup;
+                       children = (
+                               B523C74A25C9C1BA00C44061 /* EmptyMapDetailScreen.swift */,
+                               B52625A525C876C3003E73B7 /* MapDetailScreen.swift */,
+                       );
+                       path = Screens;
+                       sourceTree = "<group>";
+               };
+               B5F8D3042A06DCC4000EEA24 /* Base Components */ = {
                        isa = PBXGroup;
                        children = (
-                               B526257125C874F9003E73B7 /* MapApp.swift */,
-                               B526257325C874F9003E73B7 /* ContentView.swift */,
-                               B52625A525C876C3003E73B7 /* MapDetail.swift */,
-                               B523C74A25C9C1BA00C44061 /* DefaultMapView.swift */,
-                               B539518025CB2D7A00959F72 /* MapTextEditor.swift */,
-                               B587BB5F25CDCECB00F328ED /* SlowMapRender.swift */,
-                               B52625AF25C87C14003E73B7 /* MapRender.swift */,
                                B5CF75C825CC19FC003BFF3D /* EvolutionPicker.swift */,
+                               B539518025CB2D7A00959F72 /* MapTextEditor.swift */,
+                               B523C75825C9FD3A00C44061 /* MapRender */,
                        );
-                       path = Views;
+                       path = "Base Components";
                        sourceTree = "<group>";
                };
-               B5CF75CD25CC7953003BFF3D /* MapParser */ = {
+               B5F8D3052A06DCF3000EEA24 /* Complex Components */ = {
                        isa = PBXGroup;
                        children = (
-                               B5CF75D625CC79A4003BFF3D /* Strategies */,
-                               B5CF75CE25CC7965003BFF3D /* MapParser.swift */,
+                               B5F8D3062A06DD2A000EEA24 /* MapRender */,
                        );
-                       path = MapParser;
+                       path = "Complex Components";
                        sourceTree = "<group>";
                };
-               B5CF75D625CC79A4003BFF3D /* Strategies */ = {
+               B5F8D3062A06DD2A000EEA24 /* MapRender */ = {
                        isa = PBXGroup;
                        children = (
-                               B5CF75D725CC79BC003BFF3D /* VertexParserStrategy.swift */,
-                               B5CF75DC25CC79D7003BFF3D /* EdgeParserStrategy.swift */,
-                               B5CF75E125CC79ED003BFF3D /* BlockerParserStrategy.swift */,
-                               B5CF75E925CC7A13003BFF3D /* OpportunityParserStrategy.swift */,
-                               B5CF75EE25CC7A4A003BFF3D /* StageParserStrategy.swift */,
+                               B52625AF25C87C14003E73B7 /* MapRenderView.swift */,
                        );
-                       path = Strategies;
+                       path = MapRender;
+                       sourceTree = "<group>";
+               };
+               B5F8D3092A06DE1A000EEA24 /* Logic */ = {
+                       isa = PBXGroup;
+                       children = (
+                               B5CF75CD25CC7953003BFF3D /* MapParser */,
+                               B5CF75F625CC97CA003BFF3D /* Debouncer.swift */,
+                       );
+                       path = Logic;
                        sourceTree = "<group>";
                };
 /* End PBXGroup section */
                        dependencies = (
                        );
                        name = Map;
+                       packageProductDependencies = (
+                               B5F8D30D2A06E5C2000EEA24 /* Patterns */,
+                       );
                        productName = Map;
                        productReference = B526256E25C874F9003E73B7 /* Map.app */;
                        productType = "com.apple.product-type.application";
                B526256625C874F9003E73B7 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
+                               BuildIndependentTargetsInParallel = YES;
                                LastSwiftUpdateCheck = 1240;
-                               LastUpgradeCheck = 1240;
+                               LastUpgradeCheck = 1430;
                                TargetAttributes = {
                                        B526256D25C874F9003E73B7 = {
                                                CreatedOnToolsVersion = 12.4;
                                Base,
                        );
                        mainGroup = B526256525C874F9003E73B7;
+                       packageReferences = (
+                               B5F8D30C2A06E5C2000EEA24 /* XCRemoteSwiftPackageReference "patterns" */,
+                       );
                        productRefGroup = B526256F25C874F9003E73B7 /* Products */;
                        projectDirPath = "";
                        projectRoot = "";
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
-                               B52625B025C87C14003E73B7 /* MapRender.swift in Sources */,
+                               B52625B025C87C14003E73B7 /* MapRenderView.swift in Sources */,
                                B523C77E25CA294C00C44061 /* MapOpportunities.swift in Sources */,
                                B52625AB25C87909003E73B7 /* Date+format.swift in Sources */,
                                B5CF75D825CC79BC003BFF3D /* VertexParserStrategy.swift in Sources */,
                                B5CF75EA25CC7A13003BFF3D /* OpportunityParserStrategy.swift in Sources */,
+                               B5F8D3142A07C05F000EEA24 /* MapNotes.swift in Sources */,
                                B523C77125CA121300C44061 /* MapBlockers.swift in Sources */,
                                B523C76725CA071B00C44061 /* MapVertices.swift in Sources */,
                                B5CF75CF25CC7965003BFF3D /* MapParser.swift in Sources */,
                                B5CF75E225CC79ED003BFF3D /* BlockerParserStrategy.swift in Sources */,
+                               B5F8D3102A07B33D000EEA24 /* NSColor+Theme.swift in Sources */,
+                               B5F8D30B2A06E3E6000EEA24 /* Color+Theme.swift in Sources */,
                                B539517425CB0CA400959F72 /* AppState.swift in Sources */,
                                B523C75A25C9FD4900C44061 /* MapAxes.swift in Sources */,
                                B539518125CB2D7A00959F72 /* MapTextEditor.swift in Sources */,
                                B52625BB25C884C2003E73B7 /* Map+parse.swift in Sources */,
                                B52625C625C8BD2A003E73B7 /* Stage.swift in Sources */,
                                B523C73D25C98D9800C44061 /* NSImage+writePNG.swift in Sources */,
+                               B5F8D3122A07B690000EEA24 /* NoteParserStrategy.swift in Sources */,
                                B526257B25C874FA003E73B7 /* Persistence.swift in Sources */,
+                               B5F8D3082A06DD8C000EEA24 /* Font+Theme.swift in Sources */,
                                B5CF75EF25CC7A4A003BFF3D /* StageParserStrategy.swift in Sources */,
-                               B523C77625CA181100C44061 /* MapColor.swift in Sources */,
                                B5CF75DD25CC79D7003BFF3D /* EdgeParserStrategy.swift in Sources */,
-                               B526257425C874F9003E73B7 /* ContentView.swift in Sources */,
+                               B526257425C874F9003E73B7 /* MapEditorWindow.swift in Sources */,
                                B526257E25C874FA003E73B7 /* Map.xcdatamodeld in Sources */,
                                B5CF75C925CC19FC003BFF3D /* EvolutionPicker.swift in Sources */,
-                               B523C74B25C9C1BA00C44061 /* DefaultMapView.swift in Sources */,
+                               B523C74B25C9C1BA00C44061 /* EmptyMapDetailScreen.swift in Sources */,
                                B539516C25CB0C9300959F72 /* Store.swift in Sources */,
                                B526257225C874F9003E73B7 /* MapApp.swift in Sources */,
-                               B52625A625C876C3003E73B7 /* MapDetail.swift in Sources */,
+                               B52625A625C876C3003E73B7 /* MapDetailScreen.swift in Sources */,
                                B523C76225CA05A300C44061 /* MapStages.swift in Sources */,
-                               B587BB6025CDCECB00F328ED /* SlowMapRender.swift in Sources */,
                                B5CF75F725CC97CA003BFF3D /* Debouncer.swift in Sources */,
                                B523C76C25CA0DFA00C44061 /* MapEdges.swift in Sources */,
                        );
                                CLANG_WARN_UNREACHABLE_CODE = YES;
                                CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
                                COPY_PHASE_STRIP = NO;
+                               DEAD_CODE_STRIPPING = YES;
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                ENABLE_STRICT_OBJC_MSGSEND = YES;
                                ENABLE_TESTABILITY = YES;
                                CLANG_WARN_UNREACHABLE_CODE = YES;
                                CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
                                COPY_PHASE_STRIP = NO;
+                               DEAD_CODE_STRIPPING = YES;
                                DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
                                ENABLE_NS_ASSERTIONS = NO;
                                ENABLE_STRICT_OBJC_MSGSEND = YES;
                                CODE_SIGN_ENTITLEMENTS = Map/Map.entitlements;
                                CODE_SIGN_STYLE = Automatic;
                                COMBINE_HIDPI_IMAGES = YES;
-                               CURRENT_PROJECT_VERSION = 3;
+                               CURRENT_PROJECT_VERSION = 4;
+                               DEAD_CODE_STRIPPING = YES;
                                DEVELOPMENT_ASSET_PATHS = "\"Map/Preview Content\"";
                                DEVELOPMENT_TEAM = S68NHQVJXW;
                                ENABLE_HARDENED_RUNTIME = YES;
                                        "$(inherited)",
                                        "@executable_path/../Frameworks",
                                );
-                               MACOSX_DEPLOYMENT_TARGET = 11;
-                               MARKETING_VERSION = 1.2.0;
+                               MACOSX_DEPLOYMENT_TARGET = 12.0;
+                               MARKETING_VERSION = 2.0.0;
                                PRODUCT_BUNDLE_IDENTIFIER = pizza.unlimited.Map;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                                SWIFT_VERSION = 5.0;
                                CODE_SIGN_ENTITLEMENTS = Map/Map.entitlements;
                                CODE_SIGN_STYLE = Automatic;
                                COMBINE_HIDPI_IMAGES = YES;
-                               CURRENT_PROJECT_VERSION = 3;
+                               CURRENT_PROJECT_VERSION = 4;
+                               DEAD_CODE_STRIPPING = YES;
                                DEVELOPMENT_ASSET_PATHS = "\"Map/Preview Content\"";
                                DEVELOPMENT_TEAM = S68NHQVJXW;
                                ENABLE_HARDENED_RUNTIME = YES;
                                        "$(inherited)",
                                        "@executable_path/../Frameworks",
                                );
-                               MACOSX_DEPLOYMENT_TARGET = 11;
-                               MARKETING_VERSION = 1.2.0;
+                               MACOSX_DEPLOYMENT_TARGET = 12.0;
+                               MARKETING_VERSION = 2.0.0;
                                PRODUCT_BUNDLE_IDENTIFIER = pizza.unlimited.Map;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                                SWIFT_VERSION = 5.0;
                                BUNDLE_LOADER = "$(TEST_HOST)";
                                CODE_SIGN_STYLE = Automatic;
                                COMBINE_HIDPI_IMAGES = YES;
+                               DEAD_CODE_STRIPPING = YES;
                                DEVELOPMENT_TEAM = S68NHQVJXW;
                                INFOPLIST_FILE = MapTests/Info.plist;
                                LD_RUNPATH_SEARCH_PATHS = (
                                BUNDLE_LOADER = "$(TEST_HOST)";
                                CODE_SIGN_STYLE = Automatic;
                                COMBINE_HIDPI_IMAGES = YES;
+                               DEAD_CODE_STRIPPING = YES;
                                DEVELOPMENT_TEAM = S68NHQVJXW;
                                INFOPLIST_FILE = MapTests/Info.plist;
                                LD_RUNPATH_SEARCH_PATHS = (
                                ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
                                CODE_SIGN_STYLE = Automatic;
                                COMBINE_HIDPI_IMAGES = YES;
+                               DEAD_CODE_STRIPPING = YES;
                                DEVELOPMENT_TEAM = S68NHQVJXW;
                                INFOPLIST_FILE = MapUITests/Info.plist;
                                LD_RUNPATH_SEARCH_PATHS = (
                                ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
                                CODE_SIGN_STYLE = Automatic;
                                COMBINE_HIDPI_IMAGES = YES;
+                               DEAD_CODE_STRIPPING = YES;
                                DEVELOPMENT_TEAM = S68NHQVJXW;
                                INFOPLIST_FILE = MapUITests/Info.plist;
                                LD_RUNPATH_SEARCH_PATHS = (
                };
 /* End XCConfigurationList section */
 
+/* Begin XCRemoteSwiftPackageReference section */
+               B5F8D30C2A06E5C2000EEA24 /* XCRemoteSwiftPackageReference "patterns" */ = {
+                       isa = XCRemoteSwiftPackageReference;
+                       repositoryURL = "https://git.sr.ht/~rbdr/patterns";
+                       requirement = {
+                               kind = upToNextMajorVersion;
+                               minimumVersion = 2.0.0;
+                       };
+               };
+/* End XCRemoteSwiftPackageReference section */
+
+/* Begin XCSwiftPackageProductDependency section */
+               B5F8D30D2A06E5C2000EEA24 /* Patterns */ = {
+                       isa = XCSwiftPackageProductDependency;
+                       package = B5F8D30C2A06E5C2000EEA24 /* XCRemoteSwiftPackageReference "patterns" */;
+                       productName = Patterns;
+               };
+/* End XCSwiftPackageProductDependency section */
+
 /* Begin XCVersionGroup section */
                B526257C25C874FA003E73B7 /* Map.xcdatamodeld */ = {
                        isa = XCVersionGroup;