diff --git a/Sources/FoundationEssentials/JSON/JSONScanner.swift b/Sources/FoundationEssentials/JSON/JSONScanner.swift index 9f368cb97..f78c3637b 100644 --- a/Sources/FoundationEssentials/JSON/JSONScanner.swift +++ b/Sources/FoundationEssentials/JSON/JSONScanner.swift @@ -265,7 +265,6 @@ internal struct JSONScanner { var reader: DocumentReader var depth: Int = 0 var partialMap = JSONPartialMapData() - private static let maximumRecursionDepth = 512 internal struct Options { var assumesTopLevelDictionary = false @@ -413,7 +412,7 @@ internal struct JSONScanner { mutating func scanArray() throws { let firstChar = reader.read() precondition(firstChar == ._openbracket) - guard self.depth < Self.maximumRecursionDepth else { + guard self.depth < 512 else { throw JSONError.tooManyNestedArraysOrDictionaries(location: reader.sourceLocation(atOffset: 1)) } self.depth &+= 1 @@ -471,7 +470,7 @@ internal struct JSONScanner { mutating func scanObject() throws { let firstChar = self.reader.read() precondition(firstChar == ._openbrace) - guard self.depth < Self.maximumRecursionDepth else { + guard self.depth < 512 else { throw JSONError.tooManyNestedArraysOrDictionaries(location: reader.sourceLocation(atOffset: -1)) } try scanObject(withoutBraces: false) diff --git a/Sources/FoundationEssentials/JSON/JSONWriter.swift b/Sources/FoundationEssentials/JSON/JSONWriter.swift index b8ff000a7..2ecf8b7b5 100644 --- a/Sources/FoundationEssentials/JSON/JSONWriter.swift +++ b/Sources/FoundationEssentials/JSON/JSONWriter.swift @@ -29,9 +29,6 @@ internal struct JSONWriter { } mutating func serializeJSON(_ value: JSONEncoderValue, depth: Int = 0) throws { - guard depth < Self.maximumRecursionDepth else { - throw JSONError.tooManyNestedArraysOrDictionaries() - } switch value { case .string(let str): serializeString(str) @@ -175,6 +172,10 @@ internal struct JSONWriter { } mutating func serializeArray(_ array: [JSONEncoderValue], depth: Int) throws { + guard depth < Self.maximumRecursionDepth else { + throw JSONError.tooManyNestedArraysOrDictionaries() + } + writer(ascii: ._openbracket) if pretty { writer(ascii: ._newline) @@ -203,6 +204,10 @@ internal struct JSONWriter { } mutating func serializePreformattedByteArray(_ bytes: [UInt8], _ lengths: [Int], depth: Int) throws { + guard depth < Self.maximumRecursionDepth else { + throw JSONError.tooManyNestedArraysOrDictionaries() + } + writer(ascii: ._openbracket) if pretty { writer(ascii: ._newline) @@ -237,6 +242,10 @@ internal struct JSONWriter { } mutating func serializeObject(_ dict: [String:JSONEncoderValue], depth: Int) throws { + guard depth < Self.maximumRecursionDepth else { + throw JSONError.tooManyNestedArraysOrDictionaries() + } + writer(ascii: ._openbrace) if pretty { writer(ascii: ._newline) diff --git a/Tests/FoundationEssentialsTests/JSONEncoderTests.swift b/Tests/FoundationEssentialsTests/JSONEncoderTests.swift index 3b18e0baa..6697df493 100644 --- a/Tests/FoundationEssentialsTests/JSONEncoderTests.swift +++ b/Tests/FoundationEssentialsTests/JSONEncoderTests.swift @@ -2492,19 +2492,13 @@ extension JSONEncoderTests { prettyPrintEncoder.outputFormatting = .prettyPrinted for encoder in [JSONEncoder(), prettyPrintEncoder] { - do { - let reencodedData = try encoder.encode(decoded) - let redecodedObjects = try decoder.decode(T.self, from: reencodedData) - XCTAssertEqual(decoded, redecodedObjects) - - if let plistData { - let decodedPlistObjects = try PropertyListDecoder().decode(T.self, from: plistData) - XCTAssertEqual(decoded, decodedPlistObjects) - - } - } - catch { - XCTFail("Pass test \"\(name) failed with error: \(error)") + let reencodedData = try! encoder.encode(decoded) + let redecodedObjects = try! decoder.decode(T.self, from: reencodedData) + XCTAssertEqual(decoded, redecodedObjects) + + if let plistData { + let decodedPlistObjects = try! PropertyListDecoder().decode(T.self, from: plistData) + XCTAssertEqual(decoded, decodedPlistObjects) } } } @@ -2529,10 +2523,6 @@ extension JSONEncoderTests { _run_passTest(name: "pass13", type: JSONPass.Test13.self) _run_passTest(name: "pass14", type: JSONPass.Test14.self) _run_passTest(name: "pass15", type: JSONPass.Test15.self) - // FIXME: Fix platform-specific crash on Windows, skipping test case for now -#if !os(Windows) - _run_passTest(name: "pass16", type: JSONPass.Test16.self) -#endif } func test_json5PassJSONFiles() { @@ -2597,7 +2587,6 @@ extension JSONEncoderTests { _run_failTest(name: "fail39", type: JSONFail.Test39.self) _run_failTest(name: "fail40", type: JSONFail.Test40.self) _run_failTest(name: "fail41", type: JSONFail.Test41.self) - _run_failTest(name: "fail42", type: JSONFail.Test42.self) } @@ -4379,12 +4368,6 @@ extension JSONPass { } } -extension JSONPass { - struct Test16: Codable, Equatable { - var nestedArray: [Test16]? - } -} - enum JSONFail { typealias Test1 = String typealias Test2 = [String] @@ -4426,7 +4409,6 @@ enum JSONFail { typealias Test39 = [String:String] typealias Test40 = [String:String] typealias Test41 = [String:String] - typealias Test42 = JSONPass.Test16 } enum JSON5Pass { } diff --git a/Tests/FoundationEssentialsTests/Resources/JSON/fail/fail42.json b/Tests/FoundationEssentialsTests/Resources/JSON/fail/fail42.json deleted file mode 100644 index 4263f00ee..000000000 --- a/Tests/FoundationEssentialsTests/Resources/JSON/fail/fail42.json +++ /dev/null @@ -1,1027 +0,0 @@ -{"nestedArray": [{ - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - -]} diff --git a/Tests/FoundationEssentialsTests/Resources/JSON/pass/pass16.json b/Tests/FoundationEssentialsTests/Resources/JSON/pass/pass16.json deleted file mode 100644 index 1d0f0c9b5..000000000 --- a/Tests/FoundationEssentialsTests/Resources/JSON/pass/pass16.json +++ /dev/null @@ -1,1025 +0,0 @@ -{ - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - { - "nestedArray":[ - - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] -}