- }
-
- return result
-}
-
-func parseOpportunities(_ text: String, vertices: [String: CGPoint]) -> [Opportunity] {
-
- var result: [Opportunity] = []
- let regex = try! NSRegularExpression(pattern: opportunityPattern, options: .caseInsensitive)
-
- let lines = text.split(whereSeparator: \.isNewline)
-
- for (index, line) in lines.enumerated() {
- let range = NSRange(location: 0, length: line.utf16.count)
- let matches = regex.matches(in: String(line), options: [], range: range)
-
- if matches.count > 0 && matches[0].numberOfRanges == 4 {
-
- let match = matches[0]
- let multiplier = CGFloat(
- String(line[Range(match.range(at: 2), in: line)!]) == "-" ? -1.0 : 1.0)
- let vertex = String(line[Range(match.range(at: 1), in: line)!])
- let opportunityString = String(line[Range(match.range(at: 3), in: line)!])
- let opportunity = CGFloat(
- truncating: NumberFormatter().number(from: opportunityString) ?? 0.0)
-
- if let origin = vertices[vertex] {
- let destination = CGPoint(x: origin.x + opportunity * multiplier, y: origin.y)
- result.append(Opportunity(id: index, origin: origin, destination: destination))
- }
- }
- }
-
- return result
-}
-
-func parseBlockers(_ text: String, vertices: [String: CGPoint]) -> [Blocker] {
-
- var result: [Blocker] = []
- let regex = try! NSRegularExpression(pattern: blockerPattern, options: .caseInsensitive)
-
- let lines = text.split(whereSeparator: \.isNewline)
-
- for (index, line) in lines.enumerated() {
- let range = NSRange(location: 0, length: line.utf16.count)
- let matches = regex.matches(in: String(line), options: [], range: range)
-
- if matches.count > 0 && matches[0].numberOfRanges == 2 {
-
- let match = matches[0]
- let vertexA = String(line[Range(match.range(at: 1), in: line)!])
-
- if let position = vertices[vertexA] {
- result.append(Blocker(id: index, position: position))
- }
- }
- }
-
- return result
-}
-
-func parseStages(_ text: String) -> [CGFloat] {
-
- var result = defaultDimensions
- let regex = try! NSRegularExpression(pattern: stagePattern, options: .caseInsensitive)
-
- let lines = text.split(whereSeparator: \.isNewline)
-
- for line in lines {
- let range = NSRange(location: 0, length: line.utf16.count)
- let matches = regex.matches(in: String(line), options: [], range: range)
-
- if matches.count > 0 && matches[0].numberOfRanges == 3 {
-
- let match = matches[0]
- let stage = String(line[Range(match.range(at: 1), in: line)!])
- let dimensionsString = String(line[Range(match.range(at: 2), in: line)!])
- let dimensions = CGFloat(truncating: NumberFormatter().number(from: dimensionsString) ?? 0.0)
-
- result[stage.count - 1] = dimensions
- }
- }
-
- return result
-}
-
-// Converts vetex dictionary to array
-
-func mapVertices(_ vertices: [String: CGPoint]) -> [Vertex] {
- var i = 0
- return vertices.map { label, position in
- i += 1
- return Vertex(id: i, label: label, position: position)
- }
-}
-
-extension Map {
- func parse() -> ParsedMap {
-
- let text = self.content ?? ""
- let vertices = parseVertices(text)
- let mappedVertices = mapVertices(vertices)
- let edges = parseEdges(text, vertices: vertices)
- let blockers = parseBlockers(text, vertices: vertices)
- let opportunities = parseOpportunities(text, vertices: vertices)
- let stages = parseStages(text)