From 951ecec688e388788cc988f6bb94a4221313a443 Mon Sep 17 00:00:00 2001 From: Joshua Pirihi Date: Tue, 21 Dec 2021 20:15:07 +1300 Subject: [PATCH 1/6] Node map kinda working --- Meshtastic Client.xcodeproj/project.pbxproj | 4 +-- .../UserInterfaceState.xcuserstate | Bin 0 -> 28207 bytes .../xcschemes/xcschememanagement.plist | 14 ++++++++ MeshtasticClient/Views/Nodes/NodeMap.swift | 33 +++++++++++++----- 4 files changed, 40 insertions(+), 11 deletions(-) create mode 100644 Meshtastic Client.xcodeproj/project.xcworkspace/xcuserdata/joshuapirihi.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 Meshtastic Client.xcodeproj/xcuserdata/joshuapirihi.xcuserdatad/xcschemes/xcschememanagement.plist diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index af7c9c5e..ae67097f 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -683,7 +683,7 @@ CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\""; - DEVELOPMENT_TEAM = GCH7VS5Y9R; + DEVELOPMENT_TEAM = 37C534H572; ENABLE_PREVIEWS = YES; INFOPLIST_FILE = MeshtasticClient/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -710,7 +710,7 @@ CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\""; - DEVELOPMENT_TEAM = GCH7VS5Y9R; + DEVELOPMENT_TEAM = 37C534H572; ENABLE_PREVIEWS = YES; INFOPLIST_FILE = MeshtasticClient/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; diff --git a/Meshtastic Client.xcodeproj/project.xcworkspace/xcuserdata/joshuapirihi.xcuserdatad/UserInterfaceState.xcuserstate b/Meshtastic Client.xcodeproj/project.xcworkspace/xcuserdata/joshuapirihi.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..0cf935596330218c3fcaee2a3d3ba117033cec78 GIT binary patch literal 28207 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 + + + + SchemeUserState + + MeshtasticClient.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/MeshtasticClient/Views/Nodes/NodeMap.swift b/MeshtasticClient/Views/Nodes/NodeMap.swift index c3aee386..9a76385d 100644 --- a/MeshtasticClient/Views/Nodes/NodeMap.swift +++ b/MeshtasticClient/Views/Nodes/NodeMap.swift @@ -36,23 +36,38 @@ struct NodeMap: View { set: { _ in } ) + /*ForEach ( locationNodes ) { node in + let mostRecent = node.positions?.lastObject as! PositionEntity + if mostRecent.coordinate != nil { + + annotations.append(MapLocation(name: node.user?.shortName! ?? "???", coordinate: mostRecent.coordinate!)) + + } + }*/ + NavigationView { ZStack { + + Map(coordinateRegion: regionBinding, interactionModes: [.all], showsUserLocation: true, - userTrackingMode: .constant(.follow)//, - //ForEach ( locationNodes ) { node in - // let mostRecent = node.positions?.lastObject as! PositionEntity - // if mostRecent.coordinate != nil { + userTrackingMode: .constant(.follow), + annotationItems: self.locationNodes.filter({ nodeinfo in + return nodeinfo.positions != nil && nodeinfo.positions!.count > 0 + }) + ) { locationNode in - // annotations.append(MapLocation(name: node.user?.shortName! ?? "???", coordinate: mostRecent.coordinate!)) - - // } - // } - ) + return MapAnnotation( + coordinate: (locationNode.positions!.lastObject as! PositionEntity).coordinate ?? CLLocationCoordinate2D(latitude: 0, longitude: 0), + content: { + CircleText(text: locationNode.user!.shortName ?? "???", color: .accentColor) + } + ) + + } //} .frame(maxHeight: .infinity) .ignoresSafeArea(.all, edges: [.leading, .trailing]) From 96589b8a1a10d7b8b5173d4396cf151f53ee857d Mon Sep 17 00:00:00 2001 From: Joshua Pirihi Date: Fri, 24 Dec 2021 20:06:21 +1300 Subject: [PATCH 2/6] Add custom node annotations with basic callout views --- Meshtastic Client.xcodeproj/project.pbxproj | 24 +++++ .../UserInterfaceState.xcuserstate | Bin 28207 -> 40835 bytes .../Map/Custom/PositionAnnotationView.swift | 63 ++++++++++++ MeshtasticClient/Views/Map/MapView.swift | 96 ++++++++++++++++++ MeshtasticClient/Views/Nodes/NodeMap.swift | 9 +- 5 files changed, 189 insertions(+), 3 deletions(-) create mode 100644 MeshtasticClient/Views/Map/Custom/PositionAnnotationView.swift create mode 100644 MeshtasticClient/Views/Map/MapView.swift diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index ae67097f..39370ae8 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + C9483F6D2773017500998F6B /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9483F6C2773017500998F6B /* MapView.swift */; }; + C9A7BC1027759A9600760B50 /* PositionAnnotationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A7BC0F27759A9600760B50 /* PositionAnnotationView.swift */; }; DD23A50F26FD1B4400D9B90C /* PeripheralModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD23A50E26FD1B4400D9B90C /* PeripheralModel.swift */; }; DD2E65262767A01F00E45FC5 /* NodeDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD2E65252767A01F00E45FC5 /* NodeDetail.swift */; }; DD47E3CE26F103C600029299 /* NodeList.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD47E3CD26F103C600029299 /* NodeList.swift */; }; @@ -67,6 +69,8 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + C9483F6C2773017500998F6B /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + C9A7BC0F27759A9600760B50 /* PositionAnnotationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionAnnotationView.swift; sourceTree = ""; }; DD23A50E26FD1B4400D9B90C /* PeripheralModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeripheralModel.swift; sourceTree = ""; }; DD2E65252767A01F00E45FC5 /* NodeDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeDetail.swift; sourceTree = ""; }; DD47E3CD26F103C600029299 /* NodeList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeList.swift; sourceTree = ""; }; @@ -141,6 +145,23 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + C9483F6B2773016700998F6B /* Map */ = { + isa = PBXGroup; + children = ( + C9A7BC0E27759A6800760B50 /* Custom */, + C9483F6C2773017500998F6B /* MapView.swift */, + ); + path = Map; + sourceTree = ""; + }; + C9A7BC0E27759A6800760B50 /* Custom */ = { + isa = PBXGroup; + children = ( + C9A7BC0F27759A9600760B50 /* PositionAnnotationView.swift */, + ); + path = Custom; + sourceTree = ""; + }; DD47E3CA26F0E50300029299 /* Nodes */ = { isa = PBXGroup; children = ( @@ -261,6 +282,7 @@ DDC2E18726CE24E40042C5E4 /* Views */ = { isa = PBXGroup; children = ( + C9483F6B2773016700998F6B /* Map */, DDC2E18D26CE25CB0042C5E4 /* Helpers */, DD47E3D726F2F21A00029299 /* Bluetooth */, DD47E3CA26F0E50300029299 /* Nodes */, @@ -506,11 +528,13 @@ DDAF8C5D26ED09490058C060 /* portnums.pb.swift in Sources */, DD9D8F2F2764403B00080993 /* Meshtastic.xcdatamodeld in Sources */, DD23A50F26FD1B4400D9B90C /* PeripheralModel.swift in Sources */, + C9A7BC1027759A9600760B50 /* PositionAnnotationView.swift in Sources */, DD47E3CE26F103C600029299 /* NodeList.swift in Sources */, DD47E3D626F17ED900029299 /* CircleText.swift in Sources */, DDC2E18F26CE25FE0042C5E4 /* ContentView.swift in Sources */, DDAF8C6326ED0A230058C060 /* admin.pb.swift in Sources */, DD539500276C452400AD86B1 /* Preferences.swift in Sources */, + C9483F6D2773017500998F6B /* MapView.swift in Sources */, DDAF8C5826ED07FD0058C060 /* mesh.pb.swift in Sources */, DD8169FB271F1F3A00F4AB02 /* MeshLog.swift in Sources */, DD2E65262767A01F00E45FC5 /* NodeDetail.swift in Sources */, diff --git a/Meshtastic Client.xcodeproj/project.xcworkspace/xcuserdata/joshuapirihi.xcuserdatad/UserInterfaceState.xcuserstate b/Meshtastic Client.xcodeproj/project.xcworkspace/xcuserdata/joshuapirihi.xcuserdatad/UserInterfaceState.xcuserstate index 0cf935596330218c3fcaee2a3d3ba117033cec78..5d4768a39ba9b50dbd71b8cd1573204eba8a6ae0 100644 GIT binary patch literal 40835 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 Od+I(3PyK)968{6xLDfe9 delta 14843 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 diff --git a/MeshtasticClient/Views/Map/Custom/PositionAnnotationView.swift b/MeshtasticClient/Views/Map/Custom/PositionAnnotationView.swift new file mode 100644 index 00000000..8b76d074 --- /dev/null +++ b/MeshtasticClient/Views/Map/Custom/PositionAnnotationView.swift @@ -0,0 +1,63 @@ +// +// PositionAnnotationView.swift +// MeshtasticClient +// +// Created by Joshua Pirihi on 24/12/21. +// + +import UIKit +import MapKit + +class PositionAnnotation: NSObject, MKAnnotation { + + // This property must be key-value observable, which the `@objc dynamic` attributes provide. + @objc dynamic var coordinate = CLLocationCoordinate2D(latitude: 0, longitude: 0) + + // Required if you set the annotation view's `canShowCallout` property to `true` + var title: String? = "Title" + + var shortName: String? + + // This property defined by `MKAnnotation` is not required. + //var subtitle: String? = NSLocalizedString("SAN_FRANCISCO_SUBTITLE", comment: "SF annotation") +} + +class PositionAnnotationView: MKAnnotationView { + + private let annotationFrame = CGRect(x: 0, y: 0, width: 32, height: 32) + private let label: UILabel + + override init(annotation: MKAnnotation?, reuseIdentifier: String?) { + self.label = UILabel(frame: annotationFrame.offsetBy(dx: 0, dy: 0)) + super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) + self.frame = annotationFrame + self.label.font = UIFont.preferredFont(forTextStyle: .caption2) + self.label.textColor = .white + self.label.textAlignment = .center + self.backgroundColor = .clear + self.addSubview(label) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) not implemented!") + } + + public var name: String = "" { + didSet { + self.label.text = name + } + } + + override func draw(_ rect: CGRect) { + guard let context = UIGraphicsGetCurrentContext() else { return } + + let circleRect = CGRect(x: 1, y: 1, width: 30, height: 30) + + context.setFillColor(CGColor(red: 0, green: 0.5, blue: 1.0, alpha: 1.0)) + + context.fillEllipse(in: circleRect) + + } + + +} diff --git a/MeshtasticClient/Views/Map/MapView.swift b/MeshtasticClient/Views/Map/MapView.swift new file mode 100644 index 00000000..34fed2e6 --- /dev/null +++ b/MeshtasticClient/Views/Map/MapView.swift @@ -0,0 +1,96 @@ +// +// MapView.swift +// MeshtasticClient +// +// Created by Joshua Pirihi on 22/12/21. +// + +import Foundation +import UIKit +import MapKit +import SwiftUI +import CoreData + +struct MapView: UIViewRepresentable { + //@Binding var route: MKPolyline? + var nodes: FetchedResults + + let mapViewDelegate = MapViewDelegate() + + func makeUIView(context: Context) -> MKMapView { + let map = MKMapView(frame: .zero) + map.userTrackingMode = .follow + map.mapType = .satellite + map.register(PositionAnnotationView.self, forAnnotationViewWithReuseIdentifier: NSStringFromClass(PositionAnnotationView.self)) + return map + } + + func updateUIView(_ view: MKMapView, context: Context) { + view.delegate = mapViewDelegate // (1) This should be set in makeUIView, but it is getting reset to `nil` + view.translatesAutoresizingMaskIntoConstraints = false // (2) In the absence of this, we get constraints error on rotation; and again, it seems one should do this in makeUIView, but has to be here + //addRoute(to: view) + showNodePositions(to: view) + } +} + +private extension MapView { + //func addRoute(to view: MKMapView) { + // if !view.overlays.isEmpty { + // view.removeOverlays(view.overlays) + // } + + //guard let route = route else { return } + //let mapRect = route.boundingMapRect + //view.setVisibleMapRect(mapRect, edgePadding: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10), animated: true) + //view.addOverlay(route) + //} + func showNodePositions(to view: MKMapView) { + if !view.annotations.isEmpty { + view.removeAnnotations(view.annotations) + } + + for node in self.nodes { + //try and get the last position + if (node.positions?.count ?? 0) > 0 { + let annotation = PositionAnnotation() + annotation.coordinate = (node.positions!.lastObject as! PositionEntity).coordinate ?? CLLocationCoordinate2D(latitude: 0, longitude: 0) + annotation.title = node.user?.longName ?? "Unknown" + annotation.shortName = node.user?.shortName?.uppercased() ?? "???" + + view.addAnnotation(annotation) + } + } + } +} + +class MapViewDelegate: NSObject, MKMapViewDelegate { + + func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { + + guard !annotation.isKind(of: MKUserLocation.self) else { + // Make a fast exit if the annotation is the `MKUserLocation`, as it's not an annotation view we wish to customize. + return nil + } + + var annotationView: MKAnnotationView? + + if let annotation = annotation as? PositionAnnotation { + annotationView = self.setupPositionAnnotationView(for: annotation, on: mapView) + } + + return annotationView + } + + private func setupPositionAnnotationView(for annotation: PositionAnnotation, on mapView: MKMapView) -> PositionAnnotationView { + let identifier = NSStringFromClass(PositionAnnotationView.self) + + let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? PositionAnnotationView ?? PositionAnnotationView() + + annotationView.name = annotation.shortName ?? "???" + + annotationView.canShowCallout = true + + + return annotationView + } +} diff --git a/MeshtasticClient/Views/Nodes/NodeMap.swift b/MeshtasticClient/Views/Nodes/NodeMap.swift index 9a76385d..0074f354 100644 --- a/MeshtasticClient/Views/Nodes/NodeMap.swift +++ b/MeshtasticClient/Views/Nodes/NodeMap.swift @@ -51,12 +51,12 @@ struct NodeMap: View { - Map(coordinateRegion: regionBinding, + /*Map(coordinateRegion: regionBinding, interactionModes: [.all], showsUserLocation: true, userTrackingMode: .constant(.follow), annotationItems: self.locationNodes.filter({ nodeinfo in - return nodeinfo.positions != nil && nodeinfo.positions!.count > 0 + return nodeinfo.positions != nil && nodeinfo.positions!.count > 0// && (nodeinfo.positions?.lastObject as? AnyObject)?.coordinate != nil }) ) { locationNode in @@ -67,7 +67,10 @@ struct NodeMap: View { } ) - } + }*/ + + MapView(nodes: self.locationNodes) + //} .frame(maxHeight: .infinity) .ignoresSafeArea(.all, edges: [.leading, .trailing]) From 9bb5ee933534e21b80066840ef8bd9bd6cfbaf8c Mon Sep 17 00:00:00 2001 From: Joshua Pirihi Date: Sat, 25 Dec 2021 14:48:01 +1300 Subject: [PATCH 3/6] Add map type selector to the settings tab --- .../UserInterfaceState.xcuserstate | Bin 40835 -> 48402 bytes .../Map/Custom/PositionAnnotationView.swift | 7 ++- MeshtasticClient/Views/Map/MapView.swift | 56 +++++++++++++----- MeshtasticClient/Views/Nodes/NodeMap.swift | 7 ++- .../Views/Settings/AppSettings.swift | 40 +++++++++++++ 5 files changed, 89 insertions(+), 21 deletions(-) diff --git a/Meshtastic Client.xcodeproj/project.xcworkspace/xcuserdata/joshuapirihi.xcuserdatad/UserInterfaceState.xcuserstate b/Meshtastic Client.xcodeproj/project.xcworkspace/xcuserdata/joshuapirihi.xcuserdatad/UserInterfaceState.xcuserstate index 5d4768a39ba9b50dbd71b8cd1573204eba8a6ae0..c864b6bced4699ee3447fb57884461b74e50ef5e 100644 GIT binary patch literal 48402 zcmeEv30zcF+xR`_?sM^DFZwVi1csBq0T*x*iE;@|f zL+_&x&?o2@^eg%e{f_=Xe_{qBtY8&uH~@#>!PtetZw5Jaz~>lpV?Dv!(1Q>=iPG+aDr?PX| zCbpIJu?yKH>@rqo&t=bJFJdoduVAlZJJ}8FMs^E(D|;JzCwnjZ0Q(@jgMEa3f_!Q_(%Dj z{PX+^yn}y{-^0JgAK(x2hxm8-&-l;zFZeI{ulTR|Z}=bh-vmbB1WB+9fkJ;FN{AL5 zLW~eABnv4*s*o;Z3Hd^SP$(1$#X^a2icltu7b=8GVVW>qm?4}hR10&2(}YFBV&M#7 ziLgvKN4P+^P`FfBDO@J360R1m5v~=k6RsE53U>;333m(k2-}2*ghz$PgeQfkgr|iU zgcpU~!d~Hk@TPD`_(=Fz_(b?r_)_>r_*VE?_+9uz3=u=cFma$5E=Guv;vg|fj20bY zoR}h}iY_rt^oZHwaPed@Un~#{#WCVou~l3kE);z-Xd-iZxe49pBA4HpB0}IpBG;cUlezXFNrUUd&IrstKuQ?J@I|< zbMXuDOYtl57x7o|H}Q9gmjuZn#YnM|Q;L(~rNL5ylqe-h$x@1xF6BtMQl2zK8Y+#H z@}*Mg6lsh!R+=nLk)}%1q-tr7bcVDXbH1TcjtXozgDpN$Dx+Y3Uj1S?M|HdFch|W$88Pko1=Hq4bgTvGj@bjr6Uo z$pLad*)9jl{pBDzSRNpU$f0tW94R~HBsp2ml(S@ye6l=39x3O`rSd8A9JxlWmA!JE zJXfA4*UP8L^W_G)MP4W`mCusTmoJc4%9qKv$eZNN@)r44`8N4>d8>Sfe5ZVue4qTV zyhGk8?~-4TUzB&tFUhaT2jp+%@8s|0ALJk9pX8tAU*uoq-{jwI$R^nWZ2fGZwlG_) z&1s9X#oJuAG+T*nlx?)F)OLz(jBTuKoUP0@-d1j_w9T;1w9T>A*yh_BY>l>d+XCCA zww1QaY^!XS+pe%(X_NwhQ+X34_+v~PB zY;W2Q+1|3fZF|S|zU?#HH@0tWzuJCN1VvONMOFfp{z|fvqNFM=B~3|J+)9R$sbnc0 zB~KZl6e}f4nKE7}SEee{l+%?~#iz6>?aBgWp|VI>tel}NQI;v^E0-uMl-0^r%GJs> z${M9Zc|dtk*{(dKJgn?c9#I}u9#bAyo=~1rUR3reuPARShm^OJ50#Hptg%ItR|?5YNnc{dem%nxO%cWS)HOzRi~-b)fwtcb(T6?tx``_ zYt{Mc>1wNbhPp&OQ$1HbPrXsSNxfNJqjspB>RNT3x?bI&ZdA9Zcd6Ud2h_*Z$JHm) z=hWxbJ?bawr|M_w=js>gm+DvQ*XlRwx9WH5PwJl0T+6&r?+HUP7?PYC`wpZJyy`t^c zUeyk3?`iLAA7~$HA88+JpJ-oczi7W|ziGc~e*{PYa)25T889dyDj+(*5fBp)ACMT3 z6yOTT3dju@Iw`KHy`f<*qcH(YKgP}kF(FgRD$?eA7yG8ezkc~;a$HSAwa?ed1Ty_~ zth1d=Ff%~s2)b5}tFp%xB|%q1olw0}Pnk`-uWzbtURcsv-RP~dpWJi2%IZ0V%}s5s z%?%CS)~ej>oXp(ptbA8qR#CCbljX^CvH|yLyDy1=X!n zs(q8|ef4u1yi@Ai=2g@;&28{PNtHdZ=Sb!ps>&)RdVOupt<_N7knoDC+p4SV(NHzN zrVT{IuC3@jHT%HsQJb3^=2W+qTBBCk!@A3i8TBX%S+c~P>ToYjbu7uq$%Bs>?#%3^ zORfF&Fefv~o0x1ShskB~m?6wiW*Bo4Gh7eQ`{{N)Q17n?>B0H{J!BK??now|DPRhj zBBmI=je-ph)0^~Wy;b+=?eJ}po>FDE!(=MvH7_iyUQj=`8kTB4>iU}B>V*XdLaj+{ z^$qoH^_35W=^j6E-doSX`ee6PRt%O&fD1Bx_DG; zb<4c&r`8<0MwkV|71!4L`<1QbS2EL?E{naWJl2kPN^gdV96TF=a2W-_yw z*-VulrKjqX^vU{6x;)3!n&w(>8uT}&zAde5ZfRZTR%MU;iz>$aVCfa!23VrEwyQCy z0Ha!)+gr>6P#Anw_CbHqNvY4*?)6yj-NHVc3OR#x6xQBKqrv8w)~nJug~YL z1+4YX_SI0jQQqtWAZ~7&ux#L3h4h>{#o z*;3s$ZyL}f@1oK5O>OIJimJgujPv^DwZRzmHIBlDdYBuG+5OCXG>JmLZ^~$ILkp;u zcC^PH*gxoKbMr20scxdWr!o7i{3o_gdjE${4%iu(!GNIkA&MFrcC;}o##OgWE^G%9 z)wm}-BJ%kAK6DcF92L+RtsJe}Ju$J)sAKR^yGl$-KK`yc5}>P8_c~Xa zntrt2jI_#w5?(Td2$@H>nJe)n{k-6c!a9f3H8!f?h|RvTk&mT6(lzrxi4`d)u0u+veHvp0VS~ zj=$&6FM^)SgVs#|*g9Izdnzg?9e;1HzYV=j$zMBFIVx`KnLcCY@ptyb9*O}|)@=Fl zqt2@8&QniyGXDQM=hQeyo^F0|j=bb)<5Pzh#;yxmKNo-o_|nlZGcdme$h8S4X}*Q^ zb!}j@2?RkUjTsK+m^lok%nN`Bu4FpFymAL~7jr-JEOUT)7tAOhGhc$yLR699qldwu@d}tS-a_AE0r$g!V5~^Oc{txNPs|3BgcmQu z7k~j`HNFntj_<+u;q72tcoTmBhJ~+KjtyY#>;Nz!sQ(5R8_W(Dx92=Q#84zNyLm!77l>uxDbu5Z*7&A|#S`0`nqXB04b3(4eN^Q2OQaJ)&;VJYN6k{`0mh~T&fl9ITWh~sa8P4?RrU<1H@bR(x3meEXmvxwVymCR@=2yV zM<+V3zM;0&Yx1%xdz968Z$S!9%|EykDipT2LW{Ps)$L6+^D4~Ep6IQEwKvsJ$!CwD z**wbZT+2MhJkC6!57ST5hwCRFg(1KykL1IS_;?5CE>TB&?#UeD8IqHmIV9VJtY?^K zLE!Pj70`^e%rne$%(6*k74XHJ#tY2u4(3IDq&{Ik^D?uC*$ZOJKIRo>Kl3X59$*eK zufx17-qY4IG-*t)C5BRCZ`oI^47Fdv8T9cL49j;6II&GQOp$`Vh*ok-eTTn-eKO= z3-wX@Df(EwY%lXZ^8u{wL*^sqAVKvl_>d`wLVzEsm}w zF$ox-A!B~dd;uaioOn02sc37ZC{9;cUR~eX$$Uv^&N1s)Gy9tPhWS_@t(WR0Q!D3D z&~;?kd8_m>K<$qKQpV^db~q$+F~1oP$I*wN^qy2pbrXlrgg8fCb8DYPoNP=SA%sDv z&Tnn4UfhWgvn*)YpXPsNF^>dOh3vKQ-HYrk!geB&u92#o$5r1PLq@jQU7%^qWG#~E zTxRCh&<4{NKZ7MlJ&S74m~k;|f_4W1ndmU(#@OP3n- z2aRTSuhA!%pU0rFYxD+_T0Do!Iw|$FBj?DLk%lN^9pyw+$s~863caNRP0~-NFc|}! zsuW!|MlK68X=#%NuFq}AgrR7HE7t+#bBiNG_V#|UGw zlx6!5lgdf{)3BP=qPa|RC-R~?eSy9Z1PKr&Doqh$Kv(mz-s<_@T9e^}{b=gMt`a|6 zFKKOV?BWMj*G=dQCV2~LMlI-c5H@|N4Yi{MXdzmJ7VC@kGxR0;nfg-wEPa`->qI|W zKW7VC!mL3{(OGC2(m^^s8=ZsBMQ7>f0=>IYze&GYUqjGY1T81%N`h9y6If*soM4f+ zuDZRU%|JHOn3G)K1#;-6fKlCA?`v){!Ok zo)Hi`|BA}#rLK?4VZB=cKsqdhw0iee8y)yrQQN%Pk`T7O=h3n9@=sHjjZqP5%R{|xtUQd}i)?3$RPRGE1x^VinYnP{+>!*7- zZDRf0c}A%<%vy8{9cCRU7aPz<{bGH&eu=(f9RS!Gv;`ov63+BeKb%g6Bcg-=tc>1; z25e2NUT8?Gu+H$_rGCRlMNKnBX-BU@qj_^HzyX*`>RZ492kk?8RWW*}DR(Q*XeQH2Lf$B>ecp5^cG#^A^nC9W(}MIT_xbLuerf% zQdoMR)5o`Xn@XF&FzmB4Kqmd5PC=rw**I)-A3g+W5`Cn1bnn5Z=o?U4&}Zm#^ac77 zeTBZ(JN32tI(@yqLEpFmeT%+B-^1S@fzsTfZz4bhZy{(Yr8&LuF3^N)m;uSnAbP!Tl8DkViDxVoAld2Ow6KN)SqrezRy3jU--9MI0%IX-hp+s zXffCy>uanh#x~)8%;ELe4oY=@9E5}Q+x1Tf3M43sAeUbD8VGXFLf85)D|!iBWyU2#OdW72YTBn@o#r#-(caVoX62(E9^Hy2Fo!0? zX6~1}-TE&5NqwvSvHp?%g#KYKH3KK$M4ZGN zz$pNG59@d8kAn1nhd!ptp57%!^;)AT=y#jEyQDL7W7Fxzx^V{1#97#*-=*K9-={yI zZ|{=-aTLfqAH$p)^^#fCiUmeT(}?1isqslvLD27|`haQXvI_EX0TkS?Z-WAgmp(gZ z6^$}FeUNr~6eZ58HP(>U9|9bMT74}$d+`J~@rk$sS2Fv1?(Z}zo4|=Rw&*+bM|8ly z8T5>Yrl+S<4(3Zgt=TuPy}G5owSHcGI=v%EKT>(=`@mR1x?#sN{&wwyA*|r3cpC6h zpg@+EW@&z%csiB#k5&X0Z#)yv!n3EhfKF&?Li*$SV^#Lz|IS4Hrs%XqbVV(#&8L|& ztHyI?z`Up&MpevCT*EBu`Cu>h!aVAj{dgX(pf`tes(s!W@NcWP0TjChUeGXi>O0KN z=HmuXh5?2<@qA-hE$wp}>T67haQT|sTWh=)RcOXbK!Cw5_;lQgeYg#`;{|vjSiu(K zGxVqQr}by_XZ7dw=k*u#7xmrxOZv-O@R?MCV&bum2|gR21E0*{=7kbn)e%Kht#C^SF6u&Z<}YZ^}d@!p{As{p%(NCkQ(|-c_CcejfI{~ zF&baV9PYrY^}TwTNl2~%BLcn_Oq=kl@6%r~e#`7-_IL{%I`CS!3&NfHs~vcq{u;dt z3NP|Dv{jo+GdX0}wpp!i!CRP+PP_?k)(_|hJJA+=8^}Gc>v1#aG7YBT_06`(=~!>m z+_rgvs_q;)*kIbA`5Uqc*jqt1S&Q!lv+Mo(A^k1=?X~y;0I%)(I{;4a8Z647p#IJG zrA=>cZnQMZu7{KrQc6(J+}>0RM;p<*O?iD&legAi+d1MZa}MS9k=8VJ;-~0xcHt-W z_w^5YEN4<3Z2gf7sj|Des5;fO&7HC+Oj@~jZndx7*L_r#bDC?xS_ap7_$BA`n9@g9n~^e(?oSzlJV4_N7b{3@{01Nb10*S`Sf^ppOn{xLyz{l_D@)0_BE7kBzz z|IFe}CWyR8dCmJ^@BR>fgg@3l*T2-i*1yre?dCQ647Tuv!E5N{7Ho8HUh}oV5x$}v zf!=;ujG_mpu^#o{FxI0#jK<&n4Lf03%1-njOvW+oL@^GSZF=t|b(39|HAw6aejs60 zHk3);%xZ8Y&<`#J0@?m-5E~4a10nj)`Y-yg`fvL0`XBnA1Th4Go`*NHVJ6*VBiTW0 z6cf)nm_&kDgJ^<>g-DP}kl}0*@SjIG`;y@QX==!(0X1aP3F7?Zkj(^g$Y!w~`b!W` zkYN7R%k05+mvzv?*x^7D*^>y8I@ps5l8=ulvIT50P!YBegZOXL4|K96XbV9K5XQJ8 zNuhS3b7ZnfhU_+L+%k58L50|I{e6P^0U2UT^h;?EN4B5hhuJ=aft`w@nf>ex9LvsP zXXAK+1^{IMccCE=_Fg&;7<^5giz@bgiNtYH1NKZx4G0?ecjSOjazIeT38n{r%TJHl_n-%a z(gPTC7Sw8jYax>e_C15;#u;2ni8H&3o;$DAc?MUqtGmx2nIK2+Gq@fo zG8f`%P=NH4H2b|2CZ0+!}ph_a74yn%g%-Os+tzQ!J44-(`iD3c(d zGuZ^?5R}_}QajDP%P{vY((-@FZ)$3$mo{*xc_fQv-!+?L(I$TH66?Hra9``u@g3o} zW}kU~cZ5HgM>y0x!sZiogp~K1elqFD+<_kF`IC8`L;Vz!L!1gMnZq2*aU9PHoCtUC zGTgo^1Pvz$X!i($MiP`yPys=O1QiifOi;;YPGby>h708Sb3sfzH-K{HQ5I)Dg`n{S zl~Xs!3IA|r!|N~22Qv1F(o;AmaApoD&}ctr<`RIvS#y zxH1P=HKv0D#2R~iT$#&(=%0{IE*EbiXdG~5ZYbr-Wk=)6!t>6Nv3{-`VvSqCQLc`6 zaYd9XPXw;a4W(SUtPfWbSYwJc6bY zG>xF?1kE65W;bo>$wiLJG5$+5hJ&jQ%4}x+9gXS9Caj%5m%9us72J8;`P>EEh1^Bl z#oTi45^e=|DYufKQwgdjXbwR&1l1DcC8&;|xdg$|>Iph+3%AOT;;Xrl>}$Q-p&`w0&B zGkAuEZ)S(skiqk*iEF@+H@FeXm4yPYj2!GUGMvQo2Xq6Tm*VN46K<~-C7Oa z?X455o924Kb_TY1@JcfT!{R2e2O6e8yV;i7{<^xeM(O$R$nKhfT&CFV_6Ts3v`^8Q zAivAZpN4^okL8`zV{UR~rFRjyBbl)zmeG7IAIHa2Ao;5bM>nYZ0hdqUli-Su2O4}y z2M=n_iep?w@@a4t$*1$c?g24ZbzQ{qS$yu1cZ7T%lgJMxXr&IC>1A+B*agDQkr%Ep zkk^{R2)?jS>mq1fLeS;3^%azY^n>=+?KQo3caCiA-OCt$ERzgA`YC()@q9Vc4~>W8 z1|}a^R?&4&ZQ4BH=z2UeE`JHS%G~M-z7p*DT@5<9_25Nv3}D0sW{4eDHvf(6E8vuRbU;+5xWSaq)u_W|dX+i2H$A zRMxjOfDJnkVsOlYiEy6-{s^rQ(L`@FsTTrNEA_!OzC@n35u!K_IIB+*JcA})d zl|~NuTAIPLtQ8hpNTZ+33qN~Tucpn}2gMa_;I}ZY+BYBW3cHG-JzW2f@;1S309BR% z=&bp4d25swnNu3o+G5Os-dol#0#7Y--X_NANN06Hl65SDUcu>Npx)1pbzTp(GyNHE z%J*CCVM)m;sjjqi_ptne!qRbN<0nsRL0r3k=b2hucBpf{d^r_}uf`B$)Hi zyk>hmgqC|59|W1SL0CBrC9j9jatFi#HNYn?M4GfQ4o5IN$!A*Nrvjd}8MT_g3)%-B z(LQD&)U0FRLW27Cbgk1L6J?LfE6mNz$Z%)5irs}Cm&cP;;3~+=b-RXSdx{G3b4qeE zh7_8_-9l<=>M*0W_GW;Se(q2TX7i68o|c^h!D4D>-Vlgs3erRNo-{n`}*#-eqOdK!(CL6S5!EpxL`;&4C)W@%62c^S3V(YVuiDE5?nZ0 zfMc$+=aBxGxTxMW`oieI-W7TvmQG{D?BHX(WC_Iid9rAP84OS3&HOu%ow;;rSGngX z#qlc<4Ct7qP12U&i0oD(C?g@-r+`bM$dLH z%B`!etFE0>TRX(YN6|xu9qB=AWvKL$k84GShcVh+*z$f8K$RAJx zc>~(vn(_>MCSC^jkmum@Ab-F{{19XZcoZ@Ne2jm3pAi8G*O%aY2)B5K`0N2sAM#K8H#o%ZG4ocKb#4j$zk-0$kNXikkl<{>K1JBq3Hue@ zy@X?3aI8~&!I5ff)lyUITFSbh4h2g{n9=-q$CV(^1&?7l1fuihZ%Ff^F1>^#DN+6ZAYmFA(%1eXyItoSRO_fGQeg;6I42XTX^2>gTqb!i{xG zab3mc6AN>wrI@OBem|{*BdX=s))ut4wSga;KbpgTH4pNX)q{0PmXHrf>+0&|X!9%a zw$;ot`mrXLea!kM42}iwHagjEu>+i=j@ix_$M4)`jnqA}-rF!5!jP&V`49L6_u7w) zV~$V^?$T|G>5Qo3oY|uV29NQN`(=F7Re|5dKMiU(|0MquK@SqNy_0{2e}3$z3z;NA~-0X#Pi1=HL=K^EYm zqf@X63PAumFLw%>5J1o#f&(Z)@pOT?xjDT-x~i+RpcMiKysZ{C9dEOu`s%rm`k@zs z2th&^xIzoT!T=#e00Ct$LHh`Lg`oZGgn>f15Ftbo^eRE06Z8i`f6{3V`HP8kJ^(}pyr*zfp)!dYPy2tU8(UC{5 z-Mx_pZK5tk26{sRh9l_XtCo-K}zDdv_g5Dws5d59>!Z6_^VYqOzFoK|W2|7&B`viSR z&?j_t{c8-v7Q}c|`9PWgqX6)hu-*@g>RUnH08$4l=hdp~>9(FA4gJps%g1Zxwt( zo6s(R`5DZq-xBm4K|c`m%Zc22b0f|?a*y@yJvM8cOCOv^(D(n9{k@3Uy;itbST0;b z(2oTDM9|N)dB2I3j-JRo8@~5YOs2zEaPa<++S#uJ{YKF5#sTDY z9Y97-_s3lS$F5jGYrk(0Ztim^ppP9SnCU*0b;4$PDC>m{!bamzFd`U~QPw(?EyAtB zZNlxsR)RT#d4dIkC4!X`e<=4Jc_4)4%K1X1^r7+?&De6ZV5{ zAiP4by+e4F;QqaI1K|xrH^6~a_No)98<;6U(hL!!!O%`EMN@c7I1INu!rQ_-!n*_q z5gbhLfVF6g@V@W?+!f&vg2U*c(opKE^0B2Al~u(>rIq6+R#g;_EiSAq9bZ;8rWm}> z`&KBPTAmN2*Q(&?)5GM_iqe9y#S@_$+J}i^pD{Z-gwF{M)gk&7a!Ltb86k5Zg7mQH zWaZ^RY^fW9_^h4&PWXXt?DqtRcL+Zc9NBwge=|2WqAHL*X_0FY^)_~as?=`y<-^qx z^=}H45QD00=e&~0e;rI*9?9PE4ds^T-<|Nl(Szklunoe-P)MraRFR5cwP0)KB(Xx3>jP+;3}@Z$v3>FxiQTs zOsj26>w2DMoW0-5W}(}kq76KfL`Fm+7Fm%Kc~KBWQ4)cg4k9>;;Any!1ji5@OR$sR zID+E|9=uspOm_vbpJ<1R$9ORaoE30_-&p~t5}XMak(C5z{pUF<{O`L8i!q?Hif|&} zPiatBF&?}R#KB?${3a0$|0f%NQ^5Z~wyX95{sR}&Me3F$x(Rl5h?xYZ9iI<^m?KiR zB)mz?10MvO-YE_hhY<|jWb|=DFefyEISfIaf&5|TBmMveYYIi;D8nH@EYaU5*mJC| ztR~|`h^yXe4`gSHA*rx2InJ!M-p71KS6L2_(~F7LhxvUPa$|L^eUbzR*Q4Q8nIUNign^#ah_N&o+i#0 z8^lJjNo*Ed2reUd9>M1md;`IE68tQ|ZxZ}1VQqwsCTtdAPa*7V!ukk%0by?@?A^Wi zme_9ct=ua6?0;P#pgNPUM-W+&x2?Lq!5`z$ZJ`v;Fb5rS0tdBx7!0-nHq*X?E;9!m zc0$7C{AtgC(^!dIe0@he*Bo(pmHpHcwYS!|h4rm9klPV_3;GUwkvZ&$6C&f8M+#P8 zA23c}_WlojN4?Y>HNVO}|3oboM2^39Z0$RPE6f?d_3R0VhwQd{o5BZ(Uwucs#vHM@ z%0B&HU$b?zbYuWv$SK)(z#Gj0M^)Kp{_6uCiLKPK+;_-Mb4bY0b^M;&uQceX3~?kKo=t2yAf6GD=#qqMF9%Ik_loz4_lw)a2gC;n9#3#N!4n9cNN@$jXb?P!;K>9}A$Tgm)3%5Y`K6pk#mB_Q z*({KAc2PNJx+Uk#B)FPj@ap8LtW)=&C+qy5a>^7Ts-Z&!rF@1Z7QF^y5u3#Y(O)BW zs@(kBW$G8-65pW$(c1*i>JUM7o_(AG(Ffwkra<%&6^N>+6!WPe5S`jbAPN+`&XH;6 z)x0Iqd@X(t`nvdy_^tRI!8HWe66{@zw?i=L0}x1B2?3>`tsg5e^lzg|`x^p(SI{Yq zM72i$LqdiKCNWe5n|rLu`kv>Q8Vz!KV>CpWp_9 z8wqYAxS3!On@%UVm0;f%DcD3LDNGtDh11|dX%I!EHVcu?Ab1(Ux*1=H&;19HYT!Dd zJ0879q&JONhO_TBXPEaKCp6$eN(DrcTm-lK5lM0bB1suirj#Xl2wp(&LV_0&ycqP0 z1iNTYwM!PD43lU$qI43$OFE>J2|n}q5K1bLjKGCWQV~U{rQjzljiQ#Tv-;vw#Ba`# zk-hLq8YfKve3Htf@e)vULh#w(a`QihPttU0mWfX@DL$QdjJaF8R3kNk;w{xmUa3x+ zE6tPYrPHMOQiBB8a{<8@5_}QC7Zbdk;7bTzK``vZN`f!jEH(Qv$tSf*?SMxMDITq| z@aPJHuOawa%8jo3&qJdBea%}sk75SsftOpDaS>n!SU`*)FnO3i)=jc>nRGeDhE)V# z*&)H(tQNqNbpSr-%Ritf;$NABzP^s>j+*? z@P^IOHa|>0Bt1-xLDHiXCO29zxryN0O=Hm3e?aoYN2f_IQjpwD@GTZd?l~q%9*|zA zAPF}`n>(a82;Op>Ao;d**aXRUDM;Q*AqpT1K=QV}Ac>2+5-wZN^{MoQ36P&tfV|^a z&8;Ti$qbb_zL$QGew2QaewKcbewBWcewY4`{v`M=g6}5y9)j;B7$Ee1g0~U;0Kp*F zZzuSnEiy8pQs$+HWs${C=@>qtXg(cG2@A&0P)*?K$NrPAs}7I zIdZO?NANC!pCtIHe|rp-HF|+;hIGm_q!T}Lj44|!#>kU_lFMV|adMeFUM`m>$P?uX zxl#u87Op&>C-?<|UnCfa#!CdhOz<9p_Y%BsvpmI*Gc(K-AaWJOm{%-}0sk1)FQUKx zpNB91`_hHnNRgn4;Qba7oDN8E^b{c0Suc{$pop-T;MY3jB?KQhPDEHHpKT%np@?u0 z=rIdcare>kcUVJRC@(iixO_1M#5azo$tw8<3W=A?SIAe&tL3ZYtL1CtYvt?Y>j^$Y z@LL3f=KT)Apm`rA_&tK5;|~b_aI<`)9}+vn$KyRHO`19k0 z#3$uvOh|m1LgE*czCA}t@|S%{@}OVs4_d>$EblX+aW93&Z;sK-YH?8h0OSezb@>hX zP5F@gmi)GOpZu^dxC!;819UIBKT*+82AgpzY_c#!M|^jKlDT7r`%QY z=QKiF{))onAAXo*85*I@a%O}!EBynO{|2!9gMuXpe}DSH(uM&nj}~_AKXV%d4FXWw z;GPb3*i^#e;{!^Y-3G5fg9}eve*j9B1zN{FW{}6eQPdPB?3CI^6^YK-3IQGn{94ehAq>UW%JmwZ8^4FTb^wQVHLu{ZfS%K zAZ$Ov+6fy-*#3kKB5d$x+b|OqY$HsC&sGSCzz(nwAht-+dXr<=goLV+>r7>%qJ3vFjpSX^XVY&*lY#CE1_sqHM=GMjEA zgmn-$hOn`ObrLp?uBhvw>Nv!?vEVt`6Hq!XBspiEWGR zb^s{bt#}h*(;+R6Z7W2`v7ov2g+i{%f~k9L+e|3DpF&|Kg~F{AblrU#SuJ+ho&^cP z_K59K+hexJZBN*Ciuc)`v^`~e+V%`#J%oj5yd1*j5;l*pL#Twn4khd`0@?T2;ahCa z`9X0vCbpMp;#u213XCUPz&KKWgRn(3_bg#Y{{xQy25@|rg5zPrjaYmM}~f~authwV>= zA#5=LWs4p4KP4O}HbpZqK~X6tl>YsEl^`Vw=&=&43{XOpP$f(msDvvKN~AJ~uww{2 zmayXpTSnONge@oR1i}J8svvCTW+mE00>x?4V>>kX_+N0%d|yX@X$|1;beYh6<>WZfMx2mDOar;-zpnLz$_}Qf4bv%Bf1VGDoRV zY6)9KSP*2Y2|I_dHH3vHUc%N9b}nJ(ZC2|1aCn+BUuj_Cl_m;@^%fk?Cu}oeTPP(y z{U1R5Hvr<96cCpZ_B0C+bpXVp<;=5A`U2%53W^sJwxL70n6Qn<35u60s|;GKTt;be z6IFbMQlL6Y$~)&s^O}sY541+TR=L3h$?GXdwjQgs)udCoje_J_Wu3BK*`RDxZc#QV zo0Toft%PkOY&&5W5OyJ97ZG+bVb37!62hKI*rl75+x;MUm+3UE+($w3EDI!c%W0ZD z?;nW#H$dc03X!`AyUc>fr;kY*cPlSbczlVlq(j+5*t3rl9``E;On7{a!s9t0btT-3SNP#k4LlY+s$pt4z@s{lu&X=N2*O@#;;5{Z5G^kA!3mOS~ zTZak~-0jDS1wM6wi3RNx3${{-T4Z3s9euGt>~8_pQdKvk19cgN!@G{v%4%}Hx{AW# z1?q+BMe4=sa`h5*g?g#FQU$tu4`J^m?0tm2pRn5q`v74dB;QX;qWT) zF~}zwuhRUl><$YK;aa5{@=Joey6Yb}{5QbiEffwxn|Z{7!&{FDhj**@QaFSYeXK); z6Mg(R;qXEAVSp%gJ5`*X0L4k&K^3Q+0E&I#kdLx}YNu+x@kNCx{eiIiED-(qSRkq~8hCj_T9!EH$Y8&FV4@#7G(nRM!lp?Spbmh%sll5+2z#&( zJO!$juB6$u{s2-MTm-$*p}|GapKPY(hNRT_Ef`Z{^<29jp*CIt$vJ5Rc7|K-o00uBUaSI`zGOKyaw1n za*|%EE&vZLjj$i+W&5-YGgFh6sby&%Eqj{JdZig*KPK!)g#D1P zU!3rha?5sHiv@yMMKWJqdyf%2f zHeM^&CTJ5iFnWGX*l!8@Jz;+&?9c19N!ny>iZ)f7M%Z5o`#WL(Anc!nqj@=S*IV+m z*(SDpQ)SPzG8r^9&xO|u=6dq--5FU~uFUL$43}p}L6)naBpbfwWoPGlGD}K|vpqdK zsxdqIu1`lph7=CTFD%S=JjnQ(S>Vde%`C~y%quA=ap&~xsMYM~mp&a87Zw!fyFGcX;*z3Vm#5g1 z?HZB^nPf9^3bP7}GxOcKIUWlH+qH$1YAqn_Zyjh0+!z5_`0I3XR;x3$vyNzGm7J}e z`xhk_Y8U@S$)y^+8=ym5NjTJ@ts)#g_9RSvUQO}&D#EdP*(>xNmD;sI)NQC``a9mg3XFigLtU_i&XKk&v z4$`PXHjf^;53NwTwc2`Z1I3)bC_gsJ+@fs;*+|<&II%<9LO2QDxeMda#K~5^-9AWd z?d~1gb|z%AcBgiicDHtqcCU7ycE7ewdq8`Ta5lmzgi{Hp5iWpm{Rn3#Tp;246E0}8 z_K@~4lgPwt4{MKUk84k8J3%<%f(bVOWRXhvhj1Z;3ng3_;ReE^xM^lK1<23=IYrIS zkSL?R#%pEvm|pKIZm6GIKZjuo4T~X1O3%TJv~e^TsLv!It`pK3w|QswOcgQJ`a%Ddq_>)BqPPd zWHYnLH1nUl)Gm~IO?#6v;se@2?RD)9!bK1+l5m3v7qw11q`jrRt-V9IXu>%N7elyM z3hWe+dgovDr{|_Gr0-oYnZ9qECd%$xG`_{3e9PUZl|S_>G^}WEq%Q_HL9N0&*LctH zBqL|Zc zOzkgAa%C&z3Dwb7`#?nv3XU9Fl(M_L>^6x7J&`cR)x$=)j1hr2p;+)47gtNQfQ;X^l%DW6vv5 z(TbX9eBD(7Z-K+teY=d?g*H#9K{Cgq3okM-|9pZdRF8I*BF>=qlP15-{|nj$x2OJeZDsa(+bT zh>?&4-QHPHXyomNQ6r$K)pG+-q2|`^ccFva*;Q(!Y3+KSw4JdFdrlcMcHGg@n)lAP zJ+`bXsX4SLp8#3D{fVb(TII!S%O{q>;TfMHdz!frx~Ilcpv9!gX7YX5g6@s&oKkj_ zr%-#^bpK&@PAh}2GiL#v?EyZuCSY~WhUQ0k-X|6KSY`s`vu|eFnKPO5m`j*znd_Mw znVXHo;My3oVAY7K- z2tNSrvBxGz6kz_g66BnMN(smAiB>Y+rSP{kE8!j8Mos5P$z1lHfLNwqfHNSD5(xSV zZ%|3LPf1@SG!QP+&>R8=2P6Q@&_Ox_22&x&UfEn*z1UIR=ExlC$#9g9Gq^)QGRR*{ zAkZJndnq6-zzt#?ebx~GJCmcQm^D3+y3VLM!Tg?Q7ewX^riHRjATKEH)6>BN_iFd-d_b? z_t(ic$T!Ki$zRw)Z3VVkaIL%Eb`Q8Y?X&H-y=FUTd&73f_O|U^+k3VTY(Lw6wfzpR zDo9}!UJ(^pQ4~#aC|PjvKV4~3mME*>_VX^~Zsk$sIpqZf?#h(C$}7s-%Dc*Y$_L6v za4+?l+D}abTYRP3rV_A(UIJFo%hb!&>(v|8o7E0=t-4-)NPS8DSmU%nt-lte4FI)1 z2{hIbT9GzRo2RvFi?lPerP?x$Xg7dF`na}Jd$Rw}K{zNSC^KkA(4#@m1icmXLD09s zOfU}Sf`woy*cPk?4-Ae79uyoM924vejt@=v!Cwb|8~lCnkHJ3&|2iOOz_0<$11=kI-+)I3JUQU$0nZM2e!zqq$heTYki{VvhO7y>J7jmr%OQJ1UI}?MPYO>7cZH{i zXM|^kj}0#iFAtv>UKu_)d}{dg@R{MW!%q#L6J8r$7v3JeBD^Dfd-(qFuOqaG)QDjb z<0EP#7DcR#xF+J-i0dQPMXZn57;#6$y%G0EJR0#r#7hx-B3_AjHR3?T?~y{J7%4~g zkBp9tjf{&-h)jx1i7btr962L$R%BIVZDd{KyvWlc&yHLdd1vI)kEY`V9&klrX4rP~D)@2VFVn z)Gq)Rd@cQFEedqw1pOMV%Ja5Y-;FBI=r`&Zw3{d)8l(LXvEhvo=&ggC++;f@%G z(-H4Ta3ndh949$S9b+A3jtPzm$0SF+qs_6vvD|T`<7&sXj_Vz_IPP`a?|8tm-SM#F z5yxYW7acD-_BdW~yy`gUc*AkX@v-Cgn4p-L7+1`=nDH?)V`^f&F>_<;V_ITbW7=XC z#4L(g5wj-du9)pHPsThQ^K8ruF)zjJjd>;JhuHqHIkBT->tfG{JwJ9`?1tD|VmHU$ z8hd-}9kF-C-V^&m?C#i?WB10s68mcG0jJ^&c1Am6oK9!FGr^hUOmXHphdNJkp6nd! zoaUV2oaL-?dY!G#Hs=E8BIj97-MPZK(z(icg>!@RZs)zu`<)LsUvM6De&GDd`Hk~C z=MQm}akJulaf{+Ejk`LoGj3hnhPW@{evD`1rTF0ZnE0gl?D*XHA@RfFi{ej-A0O|H zZ;ihwetGb5uBua_4 zL^UxeaX?~d;=sg+M0eu&#Ky!0i3<}KC!U|UJaI+h%ET)ZuS&co@w&t{iCYujN_;Qz z^CT`wPI4sWClw|YCyh!fO&XI_mQ8MV^VX{=}Eq%_N0YLdeZWw6-g_TRwZ4L zv^wePq;*Lfl5R=boU|=zSJG2S&m=vUv^(jIq(ez>C%v2WWzyG4-zI&ZjFY)!Az4a} zOa>`4*_E80ygd1uYN%PSS`gQ7e zslTWG=~7*Rt{_*4E5bF%<#5HiGF(Gk(_OP%Rjz7Rt*g#e?`m*0xh`;B>{{Vk>00Hw z!nN9UlWU`Ev+Fk39j?1w_qrZ;?Q%WkddBsp>l4>!t}k3)xqf&3nTFEXG<#Z5+JLms zw3M{Gv|(w((?+CSpLR>y=CoVWwx&Itb|~$gw8Lrdr+t+6N!sUWU!{GMuA~Q~2c`$5 z4@eJ9ADAAS?n-y3XQk()4@o~M{p9p9>1FBV=@ZlI(tYU*(if*MNk2FJ{PZi*SEpZ{ zer@`O^jp$5r{9|XK>9=JJJKIb-7MPbcAxD&&wYXWV)qL7 zO84dN)$Xg^cew9%-{;=ue$f4pdx!fe_dfTl?t|_(-EX@OyFYM$p+nHiZUXI5lR&YYGxGqWmlPNp|=UgrGFrp(hb&(FLlb9v^9%$1p!XRgk? zCiA+?8#8at?8w}a`DPZ%a%PRnYRp=dbw}3jtk1H(&-y9r*R0KW*X z@C@=KgFVpg$@1iY9bl4Yj%TjtG*5%)bWfXSfoGBD0?);sD?F<`ot}-JO`cmlcY5yj z+~?WmdCK#WXRl|!=QYnep5HuwX5(yU_TcQq?3C=ZY?zsPvS(z^ z%C5?um+i}5ki9tj%e~PuH-_vaY^89{2eE@_PLZuh;X3 zXOb()ljKdRPijuunY1TqZ&GX0$)vWVGf7vHt|fIR-AsCv^f>A7q-RN=L1RGUK;fVX zplHxa5C{YT!9i<5DWEhE3WNpWK_t+65Dz2(2|=ZxGLQ^Z4pM`3pbC%)R0* zSTGwb0hfbSU@h1PHiNBT8#n;o0^SZj2yO+R0-phQfG>hCgRg?GgKvPJK}JIsLKZ<* zLckCxWHscw3<{DCK|{!pA_yO1f>c4aK@LH#K(0e>LT*FuLheHzK%PL}K|Vk}LB2q~ zK}SGGLB~MDpwpl;q0!Je(0FJ9bQyF7bS*RkN`R7}Sx_pJ0cAniPzh89RX~+c3$zMq zhdQ8}pbgL!PfoU%J*Z_1IBb19cn zZlpX+=}#F*`Iz!KijNNE5Oa*^JzY+=JYQ+>bnjJc?{Zo{(<}x`2_h4`2zV8`6_*0Ix4+1-I3mw{sFZFMMl|CepCRp3AF{a8}%#d z0O~NR6?F=A26Yy73-uiJ7WE!Ai28&ML(f1*qhrwX(Xr^w=w|djbO-tZx(j^+eH(ob z-GhFHeuaLEevckRf5i;PjKqXu#$v)TlQ7YkSj;NSY77#y0YkxXFr^q5CV)AP>Bc<6 zyvGb+K43m#M`1@}L$PDAQP^qN>DZar#n`3TMC=M|G8T$mja`eCV)tTOu^re8*e>j4 z>^1B?>;vo{*gvsPuun7QXV5ZgGHzr%%y^RVETb>ubw+>2K*k_$F>V8{0LQ}#a57v4 zt`b*^YsBrw?Zvg=4&sjBj^obZI&l|qS8&&HH*vRdefUxM7> zN%r@BpND7S*?1nFk9Xk%_(uFTd^3Ir{t*5o{yhF7{tEs&{sz7m{~SMnAHx4j7)BUH z7(*CG2q(-W#1fVe;t2_a<%Cs)wS*Kx8UaPX67U2ffl1I20)!^QcET>g9>O8QQ9>)> zB;h>aH^L>t6~bG>5OFwhBr%j2MjTI^L;R5lCaxo*h*%+(!JB*h)M_JVWdtULbZ6ZxQbjdx*WnN5sd(zllSnsiZ^_m;@uOA^k)` zlQKvI5{X11<&&r+I>}6`A$dqXQh>CXw4c;Q>LgtzT_fEf-6B0C^^pciA4#7`pEJi~ zj?0Y5oR~Q!Gb(dIW^Cr-%pWrCnf}aRW>e<&%w3r+nFlftXCBLJ&3usgB`YRtNmhJT zLe{b@NES2;p0z%UmQ|EhoW;%hE>+4>Wofc>S%&P6?CaToXFt#WU-ql)x7qKr2eXH= z|IHbe6OuDMXI9SaoS2+>ISX?Z=fvg2=OpAT%UO{_$Pwh!<{Zkom-Cf8pS+GtC9BD1 zvXyKnJIFqAklaMxPTocSg}jg4LOwt~L~bXaBX^Q7lCO}jkzbNOk-q}NfDm8|Fb;?S zB7qoS2@nUw0|`JffB?_{7Qh2pKsEpXxd0cC0h@tFU>nd3>;(1zdw~|wr;Mb8Qo<@&9R&c4{O2M^)8-}f@VCNCg;xu^3vU(PE$k`mEqqk?xbSJ=3+gax2z3-Slsc9=o;ra# zi8_@!jXIMWO`Su9Q7KdnHAp>2?W0YlL1<)}jOL+jp#^D8v}W2q+EH37?G)_{t%G)+ zc7t}Cc8~Ue_6O||?O%EreFA+VeF}XBJ(?avpGRLtUrC44(R3m`i=Isf=u|qLUPNcn z*>p3#nchn8q+h0ArFYZs(C^cKr~g6!hd#uZ$e6;I#+b>N&6vwrz*xkHV=QGPGFC9q zj0^^zL1bhyHZaJHTt)$d%J}}2GKv{SMiZlx@uDcaXk}4BQAN?#qBBLkMNf-f6um5Z zRW!&P#tdPOW{zc!XGSn1nUk1Pm{H6H%tg#N=2B)Nb2$^w%w;%~VIE`NVGgjuSkqY1tU0WCtVOIPta#RsEI13zD)=tm zD`FM1xGX+P$P%-pECox&a@n<#?3wIn_8j(H_I&n2_Hy+1&SP`f0=AGXX3N=1 zwuY@^*RX5Zo7h{}yV<|8_p=YNkF!s*PqW+E*V(=7e)a(SBl|P^D`z-oBqx*;#tG*{ za$-44I6rWfauPVpIjcAz4wwVutmdrc8F`1zs2LGVdC% zn|G6Uhj)+H!yDWfwGp~8Z=-JG_Kn>e2l!L?EBQn|z|Z3s@@af7U(A>AWqbu+$yf8M z_|<$T-_7^(>-mTIXZfA{F8*bHH~%L84*wqi8NZJ|$p0!BE*L2Y6+{Rk1(O6*1W|%` z0Y<r_ks_C zkAlyFuO-7vLP|!Lj425#SzLlF;g;A-T1xJe3<+ll!NLu~0wGOUBxDIogmR%$s1fRg zMxj~g7J7w#;bvi@aI3IQcu9C&ctdzw*dy!}J`(;Vd@KAa3K5MGjS+>5B1Mx$Q$-6! z%SA{LT9hFoh%!YRL}XE}s6a#$6^Rrgl}IDfi7G@Ukws(^Rg0XWT9HSzUvypczBH;7 zT1qW7mNu21Eqz$}y!3yiuS(yPeiDxmj}nK9!^Gpo5#mVkZ1G(20`VeooH$;L5^oSw z#ChMXFhydPm?P$i%f)K3R%{o$#BQ-yyh*%8929R8?-#d;Z;S7VABg`D|0#YVekSe{ z|08}QekcA=7G4%vHmPh%Syb7KvgopyviW5T%NCc#mBp8#%8JWuWqZrI%LXO0Bv1(; zkxI0Z3W-TlDRD~tlFgC^$yP~|q*-!6a#(UqazfH3IV0(n^hsVz-b&s}K1sevzDb8m zBc-#Y3#E&tKS+O+u9AYJU@24zmr|q(sYAL+8kBC6HcNL)_exu&2c+%NtJ25Pr_vYF zm(thLe(8Ypqx7@%t8BO|N;X3_OEy~;BbzUal`WRV$(G6zWXohY*+!XDc0hJV_C-Ed zzE)l!SIUj@N_mysF0Yd}$hXRWmhX`7mj5E(CqE%?lef#y$vfp;@~855@{jT%`M-)0 zijj&?#aP93#Vo}V#gB?a#R^5T0-}H`)+lfailRhOs*ot;3Z+7$&?}6JN=22TTCq*h ztk|L0rP!m`r`WGJs5q=Rrf5~1RNPm5ERQZbtGsk~1as*F@lRz@kOE9WVH zP%c#_D3>W$C|4=hDG|zaB}R!;5|kU23Z+J=R~nQSrA=9_tWh>7w<`B34=N8Uk108eE43e_qVNCj5GRI61#sZvx3 zRk{kT!m8M+O4T0K71dkyG&M|3Q7hD5b)$Nlx>>zL-J(9OKA}FPKCNz7cc`zcZ>sO8 z@2h`T|Dpb@8KVi;OwdfyOw-KNL~G_~e$+rU>of>Wx(1^mX|gmMG&veTBhz>_do;&1 zr!=QEXEmLgi<--ttD0U-pXQr(gm#p6jCPzhLOW4AMLSJ9Q#)I`LYt&b)A~=^EPv{d8c`gd7pW|`H=ajxz&8ie8${i?lJe8ADaI(KQ=!#zc9ZvzcRlu zzcUY*2P>ykuB^S+80jTc28=Tl=gpt*@>9 z*7w#A)=$>Y)_<#JRza%rtF%>3Rb5s8*v8x9Z73Vbw%(Rw18j5~&&Icv*hDt5O=7FC znQRuD&E~K)z%I0x+RN-Rd%0a@*Vy%TgWY7`W^cFuT^(8-Urnl( zRC}rqR$s5aU;TUa!|Fe)`>Nkn4^$6Uf2#gm{jVd;5$=d|Om;*$raO`xDUNgp#*yJ5 zIo3OJ9DsxE;5p~9Mz5*M}uRJW1pkNanNzZam;bv(c|cKJaRmCJaxQq zymY*F^g9L|A8W#EB5NkqOsR>gnNbs66H_y#TPMoSU5u&Y*LzbD#59=YD6a^Q5!OdDVH{dDD5%+2ibWK6Jiv zzIA?e4R?)ng}TCA<6Sdcvs|-Xb6p~r##QO6a#g#WF1Ks5tI@U1)$H2o+U@G89a{^o zrPr!zYil>vHq>sdZK^#~+g96Nd#<*#_M&^1d!c)|8{~$#;qG;Aggf1hb`#w>ZoXUR zwz_w@Tin;(Pu=g_@7)9LLC;9f1kWVTRL^wJEYBQIoM)*g(X+yn+yJep39#5o(G;@&!f7jb@S^M)-9@wt1GDE)$!{}>PqW&)E%ljTGv{4s_t}M zdtGl`U)?`-Z|dIF4b%;KM|wlOVcu}>1n)%e9Pd2uLhoX4oHyPJ_QJetyz9IOFVai* z^1K4C$Sd|*yqmnu-ksjv-aX!Z-u>P-Z@c%R_p!In7vh`YTjY!LE%hb(R`^!=QhXbH zbf3&u?o<18K7-Hfv-<458egri&bQmQ*Vp1Z;5+0y>TC6#@}2Q@_|E$}ecit2zIXNG z>tpIc_1Jo9y}aI4-%!7!{&D?_`Zx7M{!o9Uf3iQyKf@pGkM%F{$NLlf%l#|;8UA8_ zh5xYsg#WDnod1gdmjAB5$KUIJ=zr;d=l|gUHfGgk*1Oqz) zy90XzErFwfE>?5y6qc&|p|_ zd~j-TdT?eiIv5*V6kHNq9z+JwL2M8oBn7jA*+C$f7c30Y|3j-IM*PHqcrXRzr1 E0693kA^-pY delta 19889 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 let mapViewDelegate = MapViewDelegate() - + + //observe changes to the key in UserDefaults + @AppStorage("meshMapType") var type: String = "hybrid" + func makeUIView(context: Context) -> MKMapView { + let map = MKMapView(frame: .zero) + map.userTrackingMode = .follow - map.mapType = .satellite + + let region = MKCoordinateRegion( center: map.centerCoordinate, latitudinalMeters: CLLocationDistance(exactly: 500)!, longitudinalMeters: CLLocationDistance(exactly: 500)!) + map.setRegion(map.regionThatFits(region), animated: false) + + //self.updateMapType(map) + map.register(PositionAnnotationView.self, forAnnotationViewWithReuseIdentifier: NSStringFromClass(PositionAnnotationView.self)) + return map } func updateUIView(_ view: MKMapView, context: Context) { view.delegate = mapViewDelegate // (1) This should be set in makeUIView, but it is getting reset to `nil` view.translatesAutoresizingMaskIntoConstraints = false // (2) In the absence of this, we get constraints error on rotation; and again, it seems one should do this in makeUIView, but has to be here - //addRoute(to: view) - showNodePositions(to: view) + + self.updateMapType(view) + + self.showNodePositions(to: view) + } + + func updateMapType(_ map: MKMapView) { + + switch self.type { + case "satellite": + map.mapType = .satellite + break + case "standard": + map.mapType = .standard + break + case "hybrid": + map.mapType = .hybrid + break + default: + map.mapType = .hybrid + } } } private extension MapView { - //func addRoute(to view: MKMapView) { - // if !view.overlays.isEmpty { - // view.removeOverlays(view.overlays) - // } - //guard let route = route else { return } - //let mapRect = route.boundingMapRect - //view.setVisibleMapRect(mapRect, edgePadding: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10), animated: true) - //view.addOverlay(route) - //} func showNodePositions(to view: MKMapView) { + + //clear any existing annotations if !view.annotations.isEmpty { view.removeAnnotations(view.annotations) } for node in self.nodes { //try and get the last position - if (node.positions?.count ?? 0) > 0 { + if (node.positions?.count ?? 0) > 0 && (node.positions!.lastObject as! PositionEntity).coordinate != nil { let annotation = PositionAnnotation() - annotation.coordinate = (node.positions!.lastObject as! PositionEntity).coordinate ?? CLLocationCoordinate2D(latitude: 0, longitude: 0) + annotation.coordinate = (node.positions!.lastObject as! PositionEntity).coordinate! annotation.title = node.user?.longName ?? "Unknown" annotation.shortName = node.user?.shortName?.uppercased() ?? "???" diff --git a/MeshtasticClient/Views/Nodes/NodeMap.swift b/MeshtasticClient/Views/Nodes/NodeMap.swift index 88211a53..c2cca6e3 100644 --- a/MeshtasticClient/Views/Nodes/NodeMap.swift +++ b/MeshtasticClient/Views/Nodes/NodeMap.swift @@ -16,11 +16,15 @@ struct NodeMap: View { @Environment(\.managedObjectContext) var context @EnvironmentObject var bleManager: BLEManager + //@AppStorage("meshMapType") var meshMapType: String = "hybrid" + @State private var showLabels: Bool = false @State private var annotationItems: [MapLocation] = [] @FetchRequest( sortDescriptors: [NSSortDescriptor(keyPath: \NodeInfoEntity.lastHeard, ascending: false)], animation: .default) + + private var locationNodes: FetchedResults var annotations: [MapLocation] = [MapLocation]() @@ -72,8 +76,7 @@ struct NodeMap: View { }*/ - MapView(nodes: self.locationNodes) - + MapView(nodes: self.locationNodes)//.environmentObject(userSettings) //} .frame(maxHeight: .infinity) .ignoresSafeArea(.all, edges: [.leading, .trailing]) diff --git a/MeshtasticClient/Views/Settings/AppSettings.swift b/MeshtasticClient/Views/Settings/AppSettings.swift index d541e3d8..3710d2eb 100644 --- a/MeshtasticClient/Views/Settings/AppSettings.swift +++ b/MeshtasticClient/Views/Settings/AppSettings.swift @@ -2,6 +2,7 @@ import Foundation import Combine import SwiftUI import SwiftProtobuf +import MapKit enum KeyboardType: Int, CaseIterable, Identifiable { @@ -30,6 +31,28 @@ enum KeyboardType: Int, CaseIterable, Identifiable { } } +enum MeshMapType: String, CaseIterable, Identifiable { + + case satellite = "satellite" + case hybrid = "hybrid" + case standard = "standard" + + var id: String { self.rawValue } + + var description: String { + get { + switch self { + case .satellite: + return "Satellite" + case .standard: + return "Standard" + case .hybrid: + return "Hybrid" + } + } + } +} + class UserSettings: ObservableObject { // @Published var meshtasticUsername: String { // didSet { @@ -61,6 +84,14 @@ class UserSettings: ObservableObject { UserDefaults.standard.set(meshActivityLog, forKey: "meshActivityLog") } } + + @Published var meshMapType: String { + didSet { + UserDefaults.standard.set(meshMapType, forKey: "meshMapType") + } + } + + init() { @@ -70,6 +101,7 @@ class UserSettings: ObservableObject { //self.provideLocation = UserDefaults.standard.object(forKey: "provideLocation") as? Bool ?? false self.keyboardType = UserDefaults.standard.object(forKey: "keyboardType") as? Int ?? 0 self.meshActivityLog = UserDefaults.standard.object(forKey: "meshActivityLog") as? Bool ?? false + self.meshMapType = UserDefaults.standard.string(forKey: "meshMapType") ?? "hybrid" } } @@ -140,6 +172,14 @@ struct AppSettings: View { .listRowSeparator(.visible) } } + Section(header: Text("MAP OPTIONS")) { + Picker("Map Type", selection: $userSettings.meshMapType) { + ForEach(MeshMapType.allCases) { map in + Text(map.description) + } + } + .pickerStyle(DefaultPickerStyle()) + } } } .navigationTitle("App Settings") From 275d9d13eea2eaa061af6c55fe1e5bee27b5f7c0 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Fri, 24 Dec 2021 23:57:50 -0800 Subject: [PATCH 4/6] Update .gitignore --- .gitignore | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/.gitignore b/.gitignore index e43b0f98..db82741f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,69 @@ .DS_Store +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xccheckout +*.xcscmblueprint + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +# Package.pins +# Package.resolved +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/#source-control + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots/**/*.png +fastlane/test_output From 56024202463570e1e41184997ecdccc5dd7f0d38 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sat, 25 Dec 2021 00:05:56 -0800 Subject: [PATCH 5/6] Update .gitignore --- .gitignore | 72 +++--------------------------------------------------- 1 file changed, 4 insertions(+), 68 deletions(-) diff --git a/.gitignore b/.gitignore index db82741f..6bec327e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,69 +1,5 @@ .DS_Store -# Xcode -# -# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore - -## Build generated -build/ -DerivedData/ - -## Various settings -*.pbxuser -!default.pbxuser -*.mode1v3 -!default.mode1v3 -*.mode2v3 -!default.mode2v3 -*.perspectivev3 -!default.perspectivev3 -xcuserdata/ - -## Other -*.moved-aside -*.xccheckout -*.xcscmblueprint - -## Obj-C/Swift specific -*.hmap -*.ipa -*.dSYM.zip -*.dSYM - -## Playgrounds -timeline.xctimeline -playground.xcworkspace - -# Swift Package Manager -# -# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. -# Packages/ -# Package.pins -# Package.resolved -.build/ - -# CocoaPods -# -# We recommend against adding the Pods directory to your .gitignore. However -# you should judge for yourself, the pros and cons are mentioned at: -# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control -# -# Pods/ - -# Carthage -# -# Add this line if you want to avoid checking in source code from Carthage dependencies. -# Carthage/Checkouts - -Carthage/Build - -# fastlane -# -# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the -# screenshots whenever they are needed. -# For more information about the recommended setup visit: -# https://docs.fastlane.tools/best-practices/source-control/#source-control - -fastlane/report.xml -fastlane/Preview.html -fastlane/screenshots/**/*.png -fastlane/test_output +Build +*xcuserdata* +*xcscmblueprint* +nRF Toolbox.xcworkspace/xcshareddata From 90104cba5358444160b64d355cfa63d19cf962c7 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sat, 25 Dec 2021 00:07:37 -0800 Subject: [PATCH 6/6] Delete xcschememanagement.plist User file added to the gitignore --- .../xcschemes/xcschememanagement.plist | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 Meshtastic Client.xcodeproj/xcuserdata/joshuapirihi.xcuserdatad/xcschemes/xcschememanagement.plist diff --git a/Meshtastic Client.xcodeproj/xcuserdata/joshuapirihi.xcuserdatad/xcschemes/xcschememanagement.plist b/Meshtastic Client.xcodeproj/xcuserdata/joshuapirihi.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index f0e83da9..00000000 --- a/Meshtastic Client.xcodeproj/xcuserdata/joshuapirihi.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,14 +0,0 @@ - - - - - SchemeUserState - - MeshtasticClient.xcscheme_^#shared#^_ - - orderHint - 0 - - - -