use clang-format
diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..cb9f91c --- /dev/null +++ b/.clang-format
@@ -0,0 +1,19 @@ +Standard: Cpp11 +IndentWidth: 4 +AccessModifierOffset: -4 +UseTab: Never +BinPackParameters: false +BinPackArguments: false +AllowShortIfStatementsOnASingleLine: true +AllowShortLoopsOnASingleLine: false +AllowShortBlocksOnASingleLine: true +AllowShortFunctionsOnASingleLine: false +AllowAllParametersOfDeclarationOnNextLine: true +ConstructorInitializerAllOnOneLineOrOnePerLine: true +AlwaysBreakTemplateDeclarations: true +NamespaceIndentation: None +PointerBindsToType: true +SpacesInParentheses: false +BreakBeforeBraces: Attach +ColumnLimit: 0 +Cpp11BracedListStyle: false
diff --git a/Makefile b/Makefile index b6ca0a1..5abaceb 100644 --- a/Makefile +++ b/Makefile
@@ -38,6 +38,6 @@ rm -f local.env format: - @echo "not implmented" + ./scripts/format.sh .PHONY: test bench \ No newline at end of file
diff --git a/bench/run.cpp b/bench/run.cpp index c88034c..0ee728d 100644 --- a/bench/run.cpp +++ b/bench/run.cpp
@@ -1,20 +1,18 @@ -#include <benchmark/benchmark.h> -#include <string> -#include <delaunator.hpp> #include "../examples/utils.hpp" +#include <benchmark/benchmark.h> +#include <delaunator.hpp> +#include <string> namespace { - void BM_45K_geojson_nodes(benchmark::State& state) - { - std::string points_str = utils::read_file("./test/test-files/osm-nodes-45331-epsg-3857.geojson"); - std::vector<double> coords = utils::get_geo_json_points(points_str); +void BM_45K_geojson_nodes(benchmark::State& state) { + std::string points_str = utils::read_file("./test/test-files/osm-nodes-45331-epsg-3857.geojson"); + std::vector<double> coords = utils::get_geo_json_points(points_str); - while (state.KeepRunning()) - { - delaunator::Delaunator delaunator(coords); - } + while (state.KeepRunning()) { + delaunator::Delaunator delaunator(coords); } } +} // namespace BENCHMARK(BM_45K_geojson_nodes)->Unit(benchmark::kMillisecond);
diff --git a/examples/utils.hpp b/examples/utils.hpp index 78e5735..fd8c622 100644 --- a/examples/utils.hpp +++ b/examples/utils.hpp
@@ -1,5 +1,9 @@ +#pragma once + #include <fstream> #include <stdexcept> +#include <string> +#include <vector> #include "rapidjson/document.h" namespace utils {
diff --git a/include/delaunator.hpp b/include/delaunator.hpp index f4078c3..0a38442 100644 --- a/include/delaunator.hpp +++ b/include/delaunator.hpp
@@ -1,13 +1,13 @@ #pragma once -#include <vector> -#include <exception> -#include <memory> -#include <limits> -#include <utility> -#include <cmath> -#include <iostream> #include <algorithm> +#include <cmath> +#include <exception> +#include <iostream> +#include <limits> +#include <memory> +#include <utility> +#include <vector> namespace delaunator { @@ -15,8 +15,7 @@ const double ax, const double ay, const double bx, - const double by -) { + const double by) { const double dx = ax - bx; const double dy = ay - by; return dx * dx + dy * dy; @@ -28,8 +27,7 @@ const double bx, const double by, const double cx, - const double cy -) { + const double cy) { const double dx = bx - ax; const double dy = by - ay; const double ex = cx - ax; @@ -55,8 +53,7 @@ const double qx, const double qy, const double rx, - const double ry -) { + const double ry) { return (qy - py) * (rx - qx) - (qx - px) * (ry - qy); } @@ -66,8 +63,7 @@ const double bx, const double by, const double cx, - const double cy -) { + const double cy) { const double dx = bx - ax; const double dy = by - ay; const double ex = cx - ax; @@ -88,8 +84,7 @@ std::size_t i, std::size_t j, double cx, - double cy -) { + double cy) { const double d1 = dist(coords[2 * i], coords[2 * i + 1], cx, cy); const double d2 = dist(coords[2 * j], coords[2 * j + 1], cx, cy); const double diff1 = d1 - d2; @@ -111,7 +106,7 @@ double cx; double cy; - bool operator() (std::size_t i, std::size_t j) { + bool operator()(std::size_t i, std::size_t j) { return compare(coords, i, j, cx, cy) < 0; } }; @@ -124,8 +119,7 @@ double cx, double cy, double px, - double py -) { + double py) { const double dx = ax - px; const double dy = ay - py; const double ex = bx - px; @@ -138,8 +132,8 @@ const double cp = fx * fx + fy * fy; return (dx * (ey * cp - bp * fy) - - dy * (ex * cp - bp * fx) + - ap * (ex * fy - ey * fx)) < 0.0; + dy * (ex * cp - bp * fx) + + ap * (ex * fy - ey * fx)) < 0.0; } inline bool check_pts_equal(double x1, double y1, double x2, double y2) { @@ -161,47 +155,45 @@ class Delaunator { - public: - std::vector<double> const& coords; - std::vector<std::size_t> triangles; - std::vector<std::size_t> halfedges; +public: + std::vector<double> const& coords; + std::vector<std::size_t> triangles; + std::vector<std::size_t> halfedges; - Delaunator (std::vector<double> const& in_coords); + Delaunator(std::vector<double> const& in_coords); - private: - std::vector<std::size_t> m_hash; - std::vector<DelaunatorPoint> m_hull; - double m_center_x; - double m_center_y; - std::size_t m_hash_size; +private: + std::vector<std::size_t> m_hash; + std::vector<DelaunatorPoint> m_hull; + double m_center_x; + double m_center_y; + std::size_t m_hash_size; - std::size_t remove_node(std::size_t node); - std::size_t legalize(std::size_t a); - std::size_t insert_node(std::size_t i); - std::size_t insert_node(std::size_t i, std::size_t prev); - std::size_t hash_key(double x, double y); - void hash_edge(std::size_t e); - std::size_t add_triangle( - std::size_t i0, - std::size_t i1, - std::size_t i2, - std::size_t a, - std::size_t b, - std::size_t c - ); - void link(std::size_t a, std::size_t b); + std::size_t remove_node(std::size_t node); + std::size_t legalize(std::size_t a); + std::size_t insert_node(std::size_t i); + std::size_t insert_node(std::size_t i, std::size_t prev); + std::size_t hash_key(double x, double y); + void hash_edge(std::size_t e); + std::size_t add_triangle( + std::size_t i0, + std::size_t i1, + std::size_t i2, + std::size_t a, + std::size_t b, + std::size_t c); + void link(std::size_t a, std::size_t b); }; -Delaunator::Delaunator (std::vector<double> const& in_coords) : - coords(in_coords), - triangles(), - halfedges(), - m_hash(), - m_hull(), - m_center_x(), - m_center_y(), - m_hash_size() -{ +Delaunator::Delaunator(std::vector<double> const& in_coords) + : coords(in_coords), + triangles(), + halfedges(), + m_hash(), + m_hull(), + m_center_x(), + m_center_y(), + m_hash_size() { std::size_t n = coords.size() >> 1; double max_x = std::numeric_limits<double>::min(); @@ -245,8 +237,7 @@ for (std::size_t i = 0; i < n; i++) { if (i == i0) continue; const double d = dist(coords[2 * i0], coords[2 * i0 + 1], coords[2 * i], coords[2 * i + 1]); - if (d < min_dist && d > 0.0) - { + if (d < min_dist && d > 0.0) { i1 = i; min_dist = d; } @@ -255,33 +246,27 @@ double min_radius = std::numeric_limits<double>::max(); // find the third point which forms the smallest circumcircle with the first two - for (std::size_t i = 0; i < n; i++) - { + for (std::size_t i = 0; i < n; i++) { if (i == i0 || i == i1) continue; const double r = circumradius( - coords[2 * i0], coords[2 * i0 + 1], - coords[2 * i1], coords[2 * i1 + 1], - coords[2 * i], coords[2 * i + 1]); + coords[2 * i0], coords[2 * i0 + 1], coords[2 * i1], coords[2 * i1 + 1], coords[2 * i], coords[2 * i + 1]); - if (r < min_radius) - { + if (r < min_radius) { i2 = i; min_radius = r; } } if (!(min_radius < std::numeric_limits<double>::max())) { - throw std::runtime_error("not triangulation");; + throw std::runtime_error("not triangulation"); + ; } bool coord_area = area( - coords[2 * i0], coords[2 * i0 + 1], - coords[2 * i1], coords[2 * i1 + 1], - coords[2 * i2], coords[2 * i2 + 1] - ) < 0.0; + coords[2 * i0], coords[2 * i0 + 1], coords[2 * i1], coords[2 * i1 + 1], coords[2 * i2], coords[2 * i2 + 1]) < 0.0; if (coord_area) { - std::swap(i1,i2); + std::swap(i1, i2); } const double i0x = coords[2 * i0]; @@ -295,7 +280,7 @@ // sort the points by distance from the seed triangle circumcenter // cerr << ids << endl; - std::sort(ids.begin(), ids.end(), sort_to_center {coords, m_center_x, m_center_y}); + std::sort(ids.begin(), ids.end(), sort_to_center{ coords, m_center_x, m_center_y }); // quicksort(ids, coords, 0, n - 1, m_center_x, m_center_y); // cerr << ids << endl; @@ -333,10 +318,9 @@ xp = x; yp = y; if ( - check_pts_equal(x, y, i0x, i0y) || - check_pts_equal(x, y, i1x, i1y) || - check_pts_equal(x, y, i2x, i2y) - ) continue; + check_pts_equal(x, y, i0x, i0y) || + check_pts_equal(x, y, i1x, i1y) || + check_pts_equal(x, y, i2x, i2y)) continue; const std::size_t start_key = hash_key(x, y); std::size_t key = start_key; @@ -344,20 +328,15 @@ do { start = m_hash[key]; key = (key + 1) % m_hash_size; - } while( + } while ( (start == INVALID_INDEX || m_hull[start].removed) && - (key != start_key) - ); + (key != start_key)); e = start; - while( + while ( area( - x, y, - m_hull[e].x, m_hull[e].y, - m_hull[m_hull[e].next].x, m_hull[m_hull[e].next].y - ) >= 0.0 - ) { + x, y, m_hull[e].x, m_hull[e].y, m_hull[m_hull[e].next].x, m_hull[m_hull[e].next].y) >= 0.0) { e = m_hull[e].next; if (e == start) { @@ -372,8 +351,9 @@ m_hull[e].i, i, m_hull[m_hull[e].next].i, - INVALID_INDEX, INVALID_INDEX, m_hull[e].t - ); + INVALID_INDEX, + INVALID_INDEX, + m_hull[e].t); m_hull[e].t = t; // keep track of boundary triangles on the hull e = insert_node(i, e); @@ -385,18 +365,11 @@ } // walk forward through the hull, adding more triangles and flipping recursively std::size_t q = m_hull[e].next; - while( + while ( area( - x, y, - m_hull[q].x, m_hull[q].y, - m_hull[m_hull[q].next].x, m_hull[m_hull[q].next].y - ) < 0.0 - ) { + x, y, m_hull[q].x, m_hull[q].y, m_hull[m_hull[q].next].x, m_hull[m_hull[q].next].y) < 0.0) { t = add_triangle( - m_hull[q].i, i, - m_hull[m_hull[q].next].i, m_hull[m_hull[q].prev].t, - INVALID_INDEX, m_hull[q].t - ); + m_hull[q].i, i, m_hull[m_hull[q].next].i, m_hull[m_hull[q].prev].t, INVALID_INDEX, m_hull[q].t); m_hull[m_hull[q].prev].t = legalize(t + 2); remove_node(q); q = m_hull[q].next; @@ -404,18 +377,11 @@ if (walk_back) { // walk backward from the other side, adding more triangles and flipping q = m_hull[e].prev; - while( + while ( area( - x, y, - m_hull[m_hull[q].prev].x, m_hull[m_hull[q].prev].y, - m_hull[q].x, m_hull[q].y - ) < 0.0 - ) { + x, y, m_hull[m_hull[q].prev].x, m_hull[m_hull[q].prev].y, m_hull[q].x, m_hull[q].y) < 0.0) { t = add_triangle( - m_hull[m_hull[q].prev].i, i, - m_hull[q].i, INVALID_INDEX, - m_hull[q].t, m_hull[m_hull[q].prev].t - ); + m_hull[m_hull[q].prev].i, i, m_hull[q].i, INVALID_INDEX, m_hull[q].t, m_hull[m_hull[q].prev].t); legalize(t + 2); m_hull[m_hull[q].prev].t = t; remove_node(q); @@ -450,11 +416,7 @@ std::size_t p1 = triangles[bl]; const bool illegal = in_circle( - coords[2 * p0], coords[2 * p0 + 1], - coords[2 * pr], coords[2 * pr + 1], - coords[2 * pl], coords[2 * pl + 1], - coords[2 * p1], coords[2 * p1 + 1] - ); + coords[2 * p0], coords[2 * p0 + 1], coords[2 * pr], coords[2 * pr + 1], coords[2 * pl], coords[2 * pl + 1], coords[2 * p1], coords[2 * p1 + 1]); if (illegal) { triangles[a] = p1; @@ -503,7 +465,7 @@ const double p = 1.0 - dx / (std::abs(dx) + std::abs(dy)); return static_cast<std::size_t>(std::llround(std::floor( (2.0 + (dy < 0.0 ? -p : p)) / 4.0 * static_cast<double>(m_hash_size) //TODO:is this conversion save? - ))); + ))); } void Delaunator::hash_edge(std::size_t e) { @@ -516,8 +478,7 @@ std::size_t i2, std::size_t a, std::size_t b, - std::size_t c -) { + std::size_t c) { std::size_t t = triangles.size(); triangles.push_back(i0); triangles.push_back(i1); @@ -529,7 +490,7 @@ } void Delaunator::link(std::size_t a, std::size_t b) { - std::size_t s = halfedges.size(); + std::size_t s = halfedges.size(); if (a == s) { halfedges.push_back(b); } else if (a < s) { @@ -543,11 +504,10 @@ halfedges.push_back(a); } else if (b < s2) { halfedges[b] = a; - } else { + } else { throw std::runtime_error("Cannot link edge"); } } } - } //namespace delaunator
diff --git a/scripts/format.sh b/scripts/format.sh new file mode 100755 index 0000000..e2e5165 --- /dev/null +++ b/scripts/format.sh
@@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +set -eu +set -o pipefail + +: ' + +Runs clang-format on the code in include/ + +Return `1` if there are files to be formatted, and automatically formats them. + +Returns `0` if everything looks properly formatted. + +' + # Set up the environment by installing mason and clang++ +./scripts/setup.sh --config local.env +source local.env + +# Add clang-format as a dep +mason install clang-format ${MASON_LLVM_RELEASE} +mason link clang-format ${MASON_LLVM_RELEASE} + +# Run clang-format on all cpp and hpp files in the /src directory +find include/ bench/ test/ -type f -name '*.hpp' -or -name '*.cpp' \ + | xargs -I{} clang-format -i -style=file {} + +# Print list of modified files +dirty=$(git ls-files --modified include/ bench/ test/) + +if [[ $dirty ]]; then + echo "The following files have been modified:" + echo $dirty + exit 1 +else + exit 0 +fi \ No newline at end of file
diff --git a/test/delaunator.test.cpp b/test/delaunator.test.cpp index aac3093..4138bbd 100644 --- a/test/delaunator.test.cpp +++ b/test/delaunator.test.cpp
@@ -1,22 +1,20 @@ -#include <delaunator.hpp> -#include <catch.hpp> #include "../examples/utils.hpp" +#include <catch.hpp> +#include <delaunator.hpp> namespace { - void validate(const std::vector<double> &coords) { - delaunator::Delaunator d(coords); +void validate(const std::vector<double>& coords) { + delaunator::Delaunator d(coords); - SECTION("validate halfedges") { - for(std::size_t i = 0; i < d.halfedges.size(); i++) { - const auto i2 = d.halfedges[i]; - REQUIRE(static_cast<bool>( - (i2 == delaunator::INVALID_INDEX) || (d.halfedges[i2] == i)) - ); - } + SECTION("validate halfedges") { + for (std::size_t i = 0; i < d.halfedges.size(); i++) { + const auto i2 = d.halfedges[i]; + REQUIRE(static_cast<bool>( + (i2 == delaunator::INVALID_INDEX) || (d.halfedges[i2] == i))); } - } } +} // namespace TEST_CASE("triangles match JS version ouput", "[Delaunator]") { std::string points_str = utils::read_file("./test/test-files/playgrounds-1356-epsg-3857.geojson"); @@ -30,14 +28,15 @@ } SECTION("values are the same") { - for(std::size_t i = 0; i < triangles.size(); i++) - { + for (std::size_t i = 0; i < triangles.size(); i++) { REQUIRE(delaunator.triangles[i] == Approx(triangles[i])); } } } TEST_CASE("produces correct triangulation", "[Delaunator]") { + // clang-format off std::vector<double> coords = {168, 180, 168, 178, 168, 179, 168, 181, 168, 183, 167, 183, 167, 184, 165, 184, 162, 186, 164, 188, 161, 188, 160, 191, 158, 193, 156, 193, 152, 195, 152, 198, 150, 198, 147, 198, 148, 205, 150, 210, 148, 210, 148, 208, 145, 206, 142, 206, 140, 206, 138, 206, 135, 206, 135, 209, 131, 209, 131, 211, 127, 211, 124, 210, 120, 207, 120, 204, 120, 202, 124, 201, 123, 201, 125, 198, 125, 194, 127, 194, 127, 191, 130, 191, 132, 189, 134, 189, 134, 186, 136, 184, 134, 182, 134, 179, 134, 176, 136, 174, 139, 174, 141, 177, 142, 176, 144, 176, 147, 178, 148, 176, 151, 178, 154, 178, 153, 175, 152, 174, 152, 170, 152, 168, 150, 166, 148, 166, 147, 165, 145, 162, 146, 160, 146, 157, 146, 155, 144, 155, 142, 152, 140, 150, 138, 150, 138, 148, 140, 145, 140, 142, 140, 138, 139, 138, 137, 138, 135, 138, 133, 135, 132, 132, 129, 132, 128, 132, 124, 132, 124, 130, 123, 130, 118, 126, 116, 124, 112, 122, 109, 122, 105, 122, 102, 124, 100, 124, 97, 124, 95, 126, 92, 127, 89, 127, 88, 130, 85, 132, 80, 134, 72, 134, 69, 134, 65, 138, 64, 138, 58, 137, 56, 133, 52, 133, 51, 133, 48, 133, 44, 133, 41, 131, 38, 130, 35, 130, 32, 127, 30, 127, 27, 127, 24, 127, 24, 126, 23, 124, 20, 122, 17, 122, 16, 118, 15, 116, 15, 110, 18, 108, 20, 102, 24, 97, 28, 102, 28, 98, 26, 97, 28, 94, 27, 85, 29, 79, 32, 76, 39, 70, 44, 66, 48, 65, 53, 61, 53, 58, 51, 54, 54, 54, 52, 48, 51, 43, 48, 42, 49, 38, 48, 34, 51, 30, 53, 33, 58, 30, 61, 30, 60, 27, 64, 26, 68, 24, 74, 24, 80, 24, 85, 26, 92, 26, 96, 29, 103, 32, 109, 33, 112, 37, 116, 37, 120, 37, 124, 35, 126, 35, 128, 38, 132, 38, 134, 41, 138, 38, 140, 36, 142, 40, 144, 43, 145, 41, 149, 41, 155, 41, 159, 41, 161, 46, 165, 46, 164, 42, 164, 39, 164, 34, 167, 30, 173, 24, 178, 24, 184, 24, 189, 26, 195, 21, 195, 20, 199, 20, 203, 20, 207, 17, 211, 17, 216, 17, 218, 16, 222, 22, 225, 27, 228, 31, 226, 34, 224, 34, 226, 39, 228, 43, 230, 46, 236, 46, 242, 46, 243, 50, 245, 50, 247, 54, 247, 56, 248, 60, 248, 65, 253, 66, 255, 64, 260, 64, 264, 67, 268, 71, 272, 66, 275, 66, 281, 61, 285, 66, 286, 70, 292, 74, 294, 74, 296, 74, 296, 71, 301, 74, 307, 74, 311, 78, 315, 74, 315, 77, 319, 77, 322, 82, 328, 82, 331, 81, 331, 84, 333, 86, 333, 90, 330, 95, 326, 98, 328, 99, 332, 98, 333, 101, 331, 104, 329, 104, 327, 106, 329, 111, 332, 116, 333, 119, 333, 122, 332, 126, 332, 130, 327, 130, 321, 130, 317, 130, 315, 134, 312, 134, 308, 138, 306, 138, 306, 144, 306, 149, 306, 152, 301, 152, 297, 154, 295, 154, 292, 154, 292, 158, 288, 158, 283, 162, 281, 164, 279, 163, 276, 163, 273, 166, 272, 169, 268, 168, 265, 170, 260, 172, 256, 176, 252, 176, 248, 181, 246, 182, 246, 189, 246, 194, 248, 197, 250, 198, 252, 200, 252, 203, 254, 205, 260, 205, 264, 202, 267, 202, 269, 202, 272, 199, 280, 199, 278, 202, 278, 207, 278, 211, 276, 211, 272, 213, 268, 213, 265, 213, 264, 211, 262, 210, 260, 210, 257, 212, 257, 214, 255, 217, 253, 217, 253, 221, 249, 220, 247, 220, 243, 222, 240, 223, 239, 226, 234, 231, 229, 231, 224, 231, 219, 227, 220, 227, 222, 224, 222, 222, 222, 219, 224, 217, 222, 214, 220, 212, 217, 210, 215, 210, 211, 209, 208, 206, 202, 209, 202, 205, 206, 202, 211, 198, 216, 195, 220, 192, 224, 192, 221, 186, 218, 186, 214, 185, 208, 185, 204, 186, 200, 186, 193, 183, 190, 182, 188, 182, 190, 178, 186, 178, 184, 174, 182, 171, 178, 171, 173, 174, 169, 174, 169, 175, 169, 179, 167, 182, 164, 186, 160, 192, 155, 195, 152, 198, 150, 198, 148, 198, 148, 202, 151, 208, 148, 210, 146, 208, 144, 205, 140, 205, 137, 208, 132, 208, 132, 210, 127, 210, 124, 210, 120, 206, 120, 202, 123, 202, 124, 201, 124, 198, 128, 195, 131, 191, 133, 187, 135, 183, 130, 203, 129, 208, 123, 203, 129, 203, 129, 198, 133, 198, 136, 200, 142, 200, 143, 199, 143, 197, 137, 196, 136, 194, 133, 194, 136, 186, 136, 182, 141, 186, 144, 186, 150, 186, 150, 190, 155, 190, 159, 188, 156, 182, 151, 182, 144, 182, 164, 176, 161, 177, 157, 177, 166, 176, 168, 165, 175, 167, 180, 167, 188, 159, 195, 164, 195, 162, 187, 162, 178, 163, 173, 166, 168, 170, 156, 170, 157, 165, 164, 165, 164, 161, 170, 159, 167, 158, 159, 154, 149, 151, 145, 145, 145, 138, 152, 138, 152, 146, 159, 146, 165, 153, 176, 153, 180, 153, 187, 153, 194, 153, 202, 153, 202, 158, 197, 158, 193, 158, 193, 142, 180, 142, 171, 142, 163, 135, 176, 135, 186, 139, 201, 139, 206, 139, 205, 147, 205, 160, 198, 160, 206, 174, 205, 178, 196, 178, 196, 182, 202, 182, 206, 181, 209, 181, 215, 181, 222, 181, 230, 177, 238, 175, 241, 175, 237, 175, 237, 168, 237, 161, 232, 156, 231, 162, 225, 166, 217, 169, 210, 173, 224, 173, 227, 173, 235, 175, 237, 178, 228, 192, 222, 199, 216, 199, 211, 204, 205, 206, 219, 207, 222, 211, 229, 214, 236, 214, 244, 211, 247, 211, 268, 206, 277, 201, 279, 201, 281, 202, 278, 202, 242, 178, 236, 170, 236, 162, 255, 162, 251, 156, 240, 156, 253, 152, 261, 152, 277, 157, 268, 151, 255, 143, 260, 142, 267, 145, 271, 149, 273, 154, 258, 146, 257, 131, 256, 134, 248, 137, 260, 137, 260, 134, 271, 137, 276, 138, 276, 144, 289, 144, 285, 150, 294, 150, 298, 149, 301, 145, 292, 145, 282, 134, 276, 134, 283, 127, 282, 116, 277, 113, 283, 113, 288, 106, 296, 106, 297, 113, 297, 118, 298, 118, 310, 122, 310, 128, 300, 130, 300, 140, 292, 129, 292, 114, 283, 122, 289, 122, 299, 122, 299, 134, 294, 134, 288, 124, 314, 121, 311, 113, 308, 110, 304, 96, 299, 90, 299, 82, 305, 87, 309, 94, 311, 101, 312, 102, 314, 107, 320, 112, 320, 115, 326, 116, 323, 109, 321, 102, 321, 94, 321, 90, 328, 90, 328, 88, 316, 88, 316, 84, 307, 84, 290, 77, 289, 88, 289, 97, 278, 97, 268, 106, 268, 110, 261, 105, 255, 103, 244, 103, 252, 100, 252, 91, 252, 82, 242, 78, 252, 78, 259, 78, 264, 87, 267, 92, 272, 91, 272, 83, 264, 83, 260, 79, 276, 79, 283, 84, 283, 94, 289, 94, 284, 86, 272, 77, 253, 110, 248, 110, 239, 110, 234, 114, 222, 125, 219, 127, 219, 131, 219, 138, 219, 141, 224, 139, 224, 135, 225, 130, 232, 136, 240, 138, 237, 131, 237, 118, 248, 120, 256, 122, 262, 127, 255, 118, 245, 110, 207, 129, 199, 134, 195, 134, 188, 130, 180, 130, 165, 129, 156, 129, 165, 128, 173, 125, 185, 126, 193, 126, 201, 124, 204, 123, 208, 116, 214, 114, 207, 114, 196, 114, 183, 121, 183, 111, 189, 117, 196, 112, 172, 126, 164, 126, 159, 114, 174, 106, 186, 106, 192, 105, 184, 105, 184, 96, 173, 96, 163, 111, 159, 110, 152, 110, 168, 110, 171, 106, 183, 98, 193, 101, 219, 96, 225, 97, 225, 104, 232, 92, 240, 92, 237, 86, 229, 86, 216, 88, 214, 79, 203, 79, 203, 75, 212, 75, 221, 75, 229, 80, 230, 89, 217, 88, 217, 77, 228, 77, 228, 69, 235, 71, 240, 71, 244, 66, 236, 54, 236, 62, 232, 68, 229, 61, 216, 61, 212, 58, 212, 47, 212, 39, 214, 28, 215, 48, 225, 55, 236, 55, 202, 65, 202, 54, 202, 44, 202, 24, 198, 32, 199, 38, 192, 38, 185, 38, 174, 42, 174, 48, 178, 51, 184, 51, 194, 55, 191, 68, 182, 68, 174, 69, 167, 67, 153, 59, 153, 49, 147, 49, 152, 58, 152, 74, 154, 83, 161, 83, 165, 88, 153, 97, 153, 89, 152, 82, 168, 88, 168, 101, 156, 102, 156, 119, 173, 110, 184, 110, 177, 106, 160, 106, 145, 125, 137, 122, 131, 120, 124, 120, 122, 118, 113, 118, 114, 111, 129, 111, 140, 110, 143, 106, 137, 102, 127, 102, 119, 98, 126, 93, 139, 93, 139, 99, 141, 95, 128, 89, 118, 74, 128, 76, 135, 76, 141, 83, 141, 71, 137, 61, 137, 50, 129, 50, 118, 50, 109, 52, 112, 61, 123, 60, 134, 60, 129, 76, 121, 67, 124, 76, 123, 76, 111, 74, 128, 73, 109, 83, 109, 94, 105, 103, 102, 118, 92, 113, 98, 105, 99, 93, 94, 93, 94, 81, 99, 81, 100, 73, 100, 89, 100, 60, 100, 55, 105, 37, 101, 34, 93, 37, 90, 37, 90, 49, 99, 49, 88, 68, 80, 68, 78, 64, 88, 62, 86, 77, 76, 89, 71, 91, 71, 106, 78, 106, 82, 118, 84, 110, 71, 104, 76, 103, 76, 91, 78, 83, 85, 89, 83, 103, 83, 119, 76, 130, 62, 130, 68, 127, 74, 126, 83, 123, 62, 123, 56, 123, 59, 129, 59, 120, 49, 110, 46, 106, 56, 100, 62, 94, 62, 109, 72, 112, 67, 112, 57, 112, 61, 122, 60, 102, 52, 125, 44, 121, 36, 114, 32, 110, 20, 110, 22, 118, 35, 118, 44, 124, 32, 119, 22, 111, 44, 96, 36, 106, 36, 94, 32, 94, 35, 83, 44, 91, 52, 91, 52, 80, 59, 80, 62, 76, 62, 70, 47, 78, 55, 75, 64, 71, 64, 60, 58, 53, 58, 43, 65, 43, 65, 60, 76, 52, 73, 38, 76, 36, 93, 48, 89, 39, 99, 40, 98, 50, 94, 63, 117, 63, 131, 67, 131, 74, 142, 78, 140, 61, 124, 58, 124, 48, 136, 55, 236, 200, 228, 200, 226, 192, 232, 198, 238, 210, 248, 210, 236, 220, 230, 223, 230, 213, 175, 32, 172, 32, 171, 38, 184, 30}; + // clang-format on validate(coords); }