diff --git a/src/libslic3r/EdgeGrid.hpp b/src/libslic3r/EdgeGrid.hpp index 1a51f3439..81517a5c4 100644 --- a/src/libslic3r/EdgeGrid.hpp +++ b/src/libslic3r/EdgeGrid.hpp @@ -209,6 +209,25 @@ public: } } + template void visit_cells_intersecting_box(BoundingBox bbox, VISITOR &visitor) const + { + // End points of the line segment. + bbox.min -= m_bbox.min; + bbox.max -= m_bbox.min + Point(1, 1); + // Get the cells of the end points. + bbox.min /= m_resolution; + bbox.max /= m_resolution; + // Trim with the cells. + bbox.min.x() = std::max(bbox.min.x(), 0); + bbox.min.y() = std::max(bbox.min.y(), 0); + bbox.max.x() = std::min(bbox.max.x(), (coord_t)m_cols - 1); + bbox.max.y() = std::min(bbox.max.y(), (coord_t)m_rows - 1); + for (coord_t iy = bbox.min.y(); iy <= bbox.max.y(); ++ iy) + for (coord_t ix = bbox.min.x(); ix <= bbox.max.x(); ++ ix) + if (! visitor(iy, ix)) + return; + } + std::pair>::const_iterator, std::vector>::const_iterator> cell_data_range(coord_t row, coord_t col) const { const EdgeGrid::Grid::Cell &cell = m_cells[row * m_cols + col]; diff --git a/src/libslic3r/ElephantFootCompensation.cpp b/src/libslic3r/ElephantFootCompensation.cpp index 828064c32..69a20b5ec 100644 --- a/src/libslic3r/ElephantFootCompensation.cpp +++ b/src/libslic3r/ElephantFootCompensation.cpp @@ -8,6 +8,7 @@ #include "Flow.hpp" #include "Geometry.hpp" #include "SVG.hpp" +#include "Utils.hpp" #include #include @@ -26,6 +27,10 @@ struct ResampledPoint { double curve_parameter; }; +// Distance calculated using SDF (Shape Diameter Function). +// The distance is calculated by casting a fan of rays and measuring the intersection distance. +// Thus the calculation is relatively slow. For the Elephant foot compensation purpose, this distance metric does not avoid +// pinching off small pieces of a contour, thus this function has been superseded by contour_distance2(). std::vector contour_distance(const EdgeGrid::Grid &grid, const size_t idx_contour, const Slic3r::Points &contour, const std::vector &resampled_point_parameters, double search_radius) { assert(! contour.empty()); @@ -167,7 +172,7 @@ std::vector contour_distance(const EdgeGrid::Grid &grid, const size_t idx SVG svg(debug_out_path("contour_distance_raycasted-%d-%d.svg", iRun, &pt_next - contour.data()).c_str(), bbox); svg.draw(expoly_grid); svg.draw_outline(Polygon(contour), "blue", scale_(0.01)); - svg.draw(*pt_this, "red", scale_(0.1)); + svg.draw(*pt_this, "red", coord_t(scale_(0.1))); #endif /* CONTOUR_DISTANCE_DEBUG_SVG */ for (int i = - num_rays + 1; i < num_rays; ++ i) { @@ -182,7 +187,7 @@ std::vector contour_distance(const EdgeGrid::Grid &grid, const size_t idx svg.draw(Line(visitor.pt_start, visitor.pt_end), "yellow", scale_(0.01)); if (visitor.t_min < 1.) { Vec2d pt = visitor.pt + visitor.dir * visitor.t_min; - svg.draw(Point(pt), "red", scale_(0.1)); + svg.draw(Point(pt), "red", coord_t(scale_(0.1))); } #endif /* CONTOUR_DISTANCE_DEBUG_SVG */ } @@ -209,7 +214,7 @@ std::vector contour_distance(const EdgeGrid::Grid &grid, const size_t idx out.emplace_back(float(distances.front() * search_radius)); #endif #ifdef CONTOUR_DISTANCE_DEBUG_SVG - printf("contour_distance_raycasted-%d-%d.svg - distance %lf\n", iRun, &pt_next - contour.data(), unscale(out.back())); + printf("contour_distance_raycasted-%d-%d.svg - distance %lf\n", iRun, int(&pt_next - contour.data()), unscale(out.back())); #endif /* CONTOUR_DISTANCE_DEBUG_SVG */ pt_this = &pt_next; idx_pt_this = &pt_next - contour.data(); @@ -223,6 +228,188 @@ std::vector contour_distance(const EdgeGrid::Grid &grid, const size_t idx return out; } +// Contour distance by measuring the closest point of an ExPolygon stored inside the EdgeGrid, while filtering out points of the same contour +// at concave regions, or convex regions with low curvature (curvature is estimated as a ratio between contour length and chordal distance crossing the contour ends). +std::vector contour_distance2(const EdgeGrid::Grid &grid, const size_t idx_contour, const Slic3r::Points &contour, const std::vector &resampled_point_parameters, double compensation, double search_radius) +{ + assert(! contour.empty()); + assert(contour.size() >= 2); + + std::vector out; + + if (contour.size() > 2) + { +#ifdef CONTOUR_DISTANCE_DEBUG_SVG + static int iRun = 0; + ++ iRun; + BoundingBox bbox = get_extents(contour); + bbox.merge(grid.bbox()); + ExPolygon expoly_grid; + expoly_grid.contour = Polygon(*grid.contours().front()); + for (size_t i = 1; i < grid.contours().size(); ++ i) + expoly_grid.holes.emplace_back(Polygon(*grid.contours()[i])); +#endif + struct Visitor { + Visitor(const EdgeGrid::Grid &grid, const size_t idx_contour, const std::vector &resampled_point_parameters, double dist_same_contour_accept, double dist_same_contour_reject) : + grid(grid), idx_contour(idx_contour), contour(*grid.contours()[idx_contour]), resampled_point_parameters(resampled_point_parameters), dist_same_contour_accept(dist_same_contour_accept), dist_same_contour_reject(dist_same_contour_reject) {} + + void init(const Points &contour, const Point &apoint) { + this->idx_point = &apoint - contour.data(); + this->point = apoint; + this->found = false; + this->dir_inside = this->dir_inside_at_point(contour, this->idx_point); + } + + bool operator()(coord_t iy, coord_t ix) { + // Called with a row and colum of the grid cell, which is intersected by a line. + auto cell_data_range = this->grid.cell_data_range(iy, ix); + for (auto it_contour_and_segment = cell_data_range.first; it_contour_and_segment != cell_data_range.second; ++ it_contour_and_segment) { + // End points of the line segment and their vector. + std::pair segment = this->grid.segment(*it_contour_and_segment); + const Vec2d v = (segment.second - segment.first).cast(); + const Vec2d va = (this->point - segment.first).cast(); + const double l2 = v.squaredNorm(); // avoid a sqrt + const double t = (l2 == 0.0) ? 0. : clamp(0., 1., va.dot(v) / l2); + // Closest point from this->point to the segment. + const Vec2d foot = segment.first.cast() + t * v; + const Vec2d bisector = foot - this->point.cast(); + const double dist = bisector.norm(); + if ((! this->found || dist < this->distance) && this->dir_inside.dot(bisector) > 0) { + bool accept = true; + if (it_contour_and_segment->first == idx_contour) { + // Complex case: The closest segment originates from the same contour as the starting point. + // Reject the closest point if its distance along the contour is reasonable compared to the current contour bisector (this->pt, foot). + double param_lo = resampled_point_parameters[this->idx_point].curve_parameter; + double param_hi; + double param_end = resampled_point_parameters.back().curve_parameter; + const Slic3r::Points &ipts = *grid.contours()[it_contour_and_segment->first]; + const size_t ipt = it_contour_and_segment->second; + { + ResampledPoint key(ipt, false, 0.); + auto lower = [](const ResampledPoint& l, const ResampledPoint r) { return l.idx_src < r.idx_src || (l.idx_src == r.idx_src && int(l.interpolated) > int(r.interpolated)); }; + auto it = std::lower_bound(resampled_point_parameters.begin(), resampled_point_parameters.end(), key, lower); + assert(it != resampled_point_parameters.end() && it->idx_src == ipt && ! it->interpolated); + param_hi = t * sqrt(l2); + if (ipt + 1 < ipts.size()) + param_hi += it->curve_parameter; + } + if (param_lo > param_hi) + std::swap(param_lo, param_hi); + assert(param_lo > - SCALED_EPSILON && param_lo <= param_end + SCALED_EPSILON); + assert(param_hi > - SCALED_EPSILON && param_hi <= param_end + SCALED_EPSILON); + double dist_along_contour = std::min(param_hi - param_lo, param_lo + param_end - param_hi); + if (dist_along_contour < dist_same_contour_accept) + accept = false; + else if (dist < dist_same_contour_reject + SCALED_EPSILON) { + // this->point is close to foot. This point will only be accepted if the path along the contour is significantly + // longer than the bisector. That is, the path shall not bulge away from the bisector too much. + // Bulge is estimated by 0.6 of the circle circumference drawn around the bisector. + // Test whether the contour is convex or concave. + bool inside = + (t == 0.) ? this->inside_corner(ipts, ipt, this->point) : + (t == 1.) ? this->inside_corner(ipts, ipt + 1 == ipts.size() ? 0 : ipt + 1, this->point) : + this->left_of_segment(ipts, ipt, this->point); + accept = inside && dist_along_contour > 0.6 * M_PI * dist; + } + } + if (accept && (! this->found || dist < this->distance)) { + // Simple case: Just measure the shortest distance. + this->distance = dist; +#ifdef CONTOUR_DISTANCE_DEBUG_SVG + this->closest_point = foot.cast(); +#endif /* CONTOUR_DISTANCE_DEBUG_SVG */ + this->found = true; + } + } + } + // Continue traversing the grid. + return true; + } + + const EdgeGrid::Grid &grid; + const size_t idx_contour; + const Points &contour; + const std::vector &resampled_point_parameters; + const double dist_same_contour_accept; + const double dist_same_contour_reject; + + size_t idx_point; + Point point; + // Direction inside the contour from idx_point, not normalized. + Vec2d dir_inside; + bool found; + double distance; +#ifdef CONTOUR_DISTANCE_DEBUG_SVG + Point closest_point; +#endif /* CONTOUR_DISTANCE_DEBUG_SVG */ + + private: + static Vec2d dir_inside_at_point(const Points &contour, size_t i) { + size_t iprev = prev_idx_modulo(i, contour); + size_t inext = next_idx_modulo(i, contour); + Vec2d v1 = (contour[i] - contour[iprev]).cast(); + Vec2d v2 = (contour[inext] - contour[i]).cast(); + return Vec2d(- v1.y() - v2.y(), v1.x() + v2.x()); + } + static Vec2d dir_inside_at_segment(const Points& contour, size_t i) { + size_t inext = next_idx_modulo(i, contour); + Vec2d v = (contour[inext] - contour[i]).cast(); + return Vec2d(- v.y(), v.x()); + } + + static bool inside_corner(const Slic3r::Points &contour, size_t i, const Point &pt_oposite) { + const Vec2d pt = pt_oposite.cast(); + size_t iprev = prev_idx_modulo(i, contour); + size_t inext = next_idx_modulo(i, contour); + Vec2d v1 = (contour[i] - contour[iprev]).cast(); + Vec2d v2 = (contour[inext] - contour[i]).cast(); + bool left_of_v1 = cross2(v1, pt - contour[iprev].cast()) > 0.; + bool left_of_v2 = cross2(v2, pt - contour[i ].cast()) > 0.; + return cross2(v1, v2) > 0 ? + left_of_v1 && left_of_v2 : // convex corner + left_of_v1 || left_of_v2; // concave corner + } + static bool left_of_segment(const Slic3r::Points &contour, size_t i, const Point &pt_oposite) { + const Vec2d pt = pt_oposite.cast(); + size_t inext = next_idx_modulo(i, contour); + Vec2d v = (contour[inext] - contour[i]).cast(); + return cross2(v, pt - contour[i].cast()) > 0.; + } + } visitor(grid, idx_contour, resampled_point_parameters, 0.5 * compensation * M_PI, search_radius); + + out.reserve(contour.size()); + Point radius_vector(search_radius, search_radius); + for (const Point &pt : contour) { + visitor.init(contour, pt); + grid.visit_cells_intersecting_box(BoundingBox(pt - radius_vector, pt + radius_vector), visitor); + out.emplace_back(float(visitor.found ? std::min(visitor.distance, search_radius) : search_radius)); + +#if 0 +//#ifdef CONTOUR_DISTANCE_DEBUG_SVG + if (out.back() < search_radius) { + SVG svg(debug_out_path("contour_distance_filtered-%d-%d.svg", iRun, int(&pt - contour.data())).c_str(), bbox); + svg.draw(expoly_grid); + svg.draw_outline(Polygon(contour), "blue", scale_(0.01)); + svg.draw(pt, "green", coord_t(scale_(0.1))); + svg.draw(visitor.closest_point, "red", coord_t(scale_(0.1))); + printf("contour_distance_filtered-%d-%d.svg - distance %lf\n", iRun, int(&pt - contour.data()), unscale(out.back())); + } +#endif /* CONTOUR_DISTANCE_DEBUG_SVG */ + } +#ifdef CONTOUR_DISTANCE_DEBUG_SVG + if (out.back() < search_radius) { + SVG svg(debug_out_path("contour_distance_filtered-final-%d.svg", iRun).c_str(), bbox); + svg.draw(expoly_grid); + svg.draw_outline(Polygon(contour), "blue", scale_(0.01)); + for (size_t i = 0; i < contour.size(); ++ i) + svg.draw(contour[i], out[i] < float(search_radius - SCALED_EPSILON) ? "red" : "green", coord_t(scale_(0.1))); + } +#endif /* CONTOUR_DISTANCE_DEBUG_SVG */ + } + + return out; +} + Points resample_polygon(const Points &contour, double dist, std::vector &resampled_point_parameters) { Points out; @@ -258,8 +445,8 @@ static inline void smooth_compensation(std::vector &compensation, float s std::vector out(compensation); for (size_t iter = 0; iter < num_iterations; ++ iter) { for (size_t i = 0; i < compensation.size(); ++ i) { - float prev = (i == 0) ? compensation.back() : compensation[i - 1]; - float next = (i + 1 == compensation.size()) ? compensation.front() : compensation[i + 1]; + float prev = prev_value_modulo(i, compensation); + float next = next_value_modulo(i, compensation); float laplacian = compensation[i] * (1.f - strength) + 0.5f * strength * (prev + next); // Compensations are negative. Only apply the laplacian if it leads to lower compensation. out[i] = std::max(laplacian, compensation[i]); @@ -268,30 +455,6 @@ static inline void smooth_compensation(std::vector &compensation, float s } } -template -static inline INDEX_TYPE prev_idx_cyclic(INDEX_TYPE idx, const CONTAINER &container) -{ - if (idx == 0) - idx = INDEX_TYPE(container.size()); - return -- idx; -} - -template -static inline INDEX_TYPE next_idx_cyclic(INDEX_TYPE idx, const CONTAINER &container) -{ - if (++ idx == INDEX_TYPE(container.size())) - idx = 0; - return idx; -} - -template -static inline T exchange(T& obj, U&& new_value) -{ - T old_value = std::move(obj); - obj = std::forward(new_value); - return old_value; -} - static inline void smooth_compensation_banded(const Points &contour, float band, std::vector &compensation, float strength, size_t num_iterations) { assert(contour.size() == compensation.size()); @@ -303,13 +466,13 @@ static inline void smooth_compensation_banded(const Points &contour, float band, for (int i = 0; i < int(compensation.size()); ++ i) { const Vec2f pthis = contour[i].cast(); - int j = prev_idx_cyclic(i, contour); + int j = prev_idx_modulo(i, contour); Vec2f pprev = contour[j].cast(); float prev = compensation[j]; float l2 = (pthis - pprev).squaredNorm(); if (l2 < dist_min2) { float l = sqrt(l2); - int jprev = exchange(j, prev_idx_cyclic(j, contour)); + int jprev = exchange(j, prev_idx_modulo(j, contour)); while (j != i) { const Vec2f pp = contour[j].cast(); const float lthis = (pp - pprev).norm(); @@ -324,17 +487,17 @@ static inline void smooth_compensation_banded(const Points &contour, float band, prev = use_min ? std::min(prev, compensation[j]) : compensation[j]; pprev = pp; l = lnext; - jprev = exchange(j, prev_idx_cyclic(j, contour)); + jprev = exchange(j, prev_idx_modulo(j, contour)); } } - j = next_idx_cyclic(i, contour); + j = next_idx_modulo(i, contour); pprev = contour[j].cast(); float next = compensation[j]; l2 = (pprev - pthis).squaredNorm(); if (l2 < dist_min2) { float l = sqrt(l2); - int jprev = exchange(j, next_idx_cyclic(j, contour)); + int jprev = exchange(j, next_idx_modulo(j, contour)); while (j != i) { const Vec2f pp = contour[j].cast(); const float lthis = (pp - pprev).norm(); @@ -349,7 +512,7 @@ static inline void smooth_compensation_banded(const Points &contour, float band, next = use_min ? std::min(next, compensation[j]) : compensation[j]; pprev = pp; l = lnext; - jprev = exchange(j, next_idx_cyclic(j, contour)); + jprev = exchange(j, next_idx_modulo(j, contour)); } } @@ -396,7 +559,7 @@ ExPolygon elephant_foot_compensation(const ExPolygon &input_expoly, const Flow & Polygon &poly = (idx_contour == 0) ? resampled.contour : resampled.holes[idx_contour - 1]; std::vector resampled_point_parameters; poly.points = resample_polygon(poly.points, resample_interval, resampled_point_parameters); - std::vector dists = contour_distance(grid, idx_contour, poly.points, resampled_point_parameters, search_radius); + std::vector dists = contour_distance2(grid, idx_contour, poly.points, resampled_point_parameters, scaled_compensation, search_radius); for (float &d : dists) { // printf("Point %d, Distance: %lf\n", int(&d - dists.data()), unscale(d)); // Convert contour width to available compensation distance. @@ -414,12 +577,21 @@ ExPolygon elephant_foot_compensation(const ExPolygon &input_expoly, const Flow & } ExPolygons out_vec = variable_offset_inner_ex(resampled, deltas, 2.); - assert(out_vec.size() == 1); if (out_vec.size() == 1) out = std::move(out_vec.front()); - else + else { // Something went wrong, don't compensate. out = input_expoly; +#ifdef TESTS_EXPORT_SVGS + if (out_vec.size() > 1) { + static int iRun = 0; + SVG::export_expolygons(debug_out_path("elephant_foot_compensation-many_contours-%d.svg", iRun ++).c_str(), + { { { input_expoly }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } }, + { { out_vec }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); + } +#endif /* TESTS_EXPORT_SVGS */ + assert(out_vec.size() == 1); + } } return out; diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp index 9af2adcc6..71e896745 100644 --- a/src/libslic3r/Utils.hpp +++ b/src/libslic3r/Utils.hpp @@ -165,6 +165,65 @@ template size_t next_highest_power_of_2(T v, return next_highest_power_of_2(uint32_t(v)); } +template +inline INDEX_TYPE prev_idx_modulo(INDEX_TYPE idx, const INDEX_TYPE count) +{ + if (idx == 0) + idx = count; + return -- idx; +} + +template +inline INDEX_TYPE next_idx_modulo(INDEX_TYPE idx, const INDEX_TYPE count) +{ + if (++ idx == count) + idx = 0; + return idx; +} + +template +inline typename CONTAINER_TYPE::size_type prev_idx_modulo(typename CONTAINER_TYPE::size_type idx, const CONTAINER_TYPE &container) +{ + return prev_idx_modulo(idx, container.size()); +} + +template +inline typename CONTAINER_TYPE::size_type next_idx_modulo(typename CONTAINER_TYPE::size_type idx, const CONTAINER_TYPE &container) +{ + return next_idx_modulo(idx, container.size()); +} + +template +inline typename const CONTAINER_TYPE::value_type& prev_value_modulo(typename CONTAINER_TYPE::size_type idx, const CONTAINER_TYPE &container) +{ + return container[prev_idx_modulo(idx, container.size())]; +} + +template +inline typename CONTAINER_TYPE::value_type& prev_value_modulo(typename CONTAINER_TYPE::size_type idx, CONTAINER_TYPE &container) +{ + return container[prev_idx_modulo(idx, container.size())]; +} + +template +inline typename const CONTAINER_TYPE::value_type& next_value_modulo(typename CONTAINER_TYPE::size_type idx, const CONTAINER_TYPE &container) +{ + return container[next_idx_modulo(idx, container.size())]; +} + +template +inline typename CONTAINER_TYPE::value_type& next_value_modulo(typename CONTAINER_TYPE::size_type idx, CONTAINER_TYPE &container) +{ + return container[next_idx_modulo(idx, container.size())]; +} + +template +inline T exchange(T& obj, U&& new_value) +{ + T old_value = std::move(obj); + obj = std::forward(new_value); + return old_value; +} extern std::string xml_escape(std::string text); diff --git a/tests/libslic3r/test_elephant_foot_compensation.cpp b/tests/libslic3r/test_elephant_foot_compensation.cpp index e5ea97e68..98ec5df52 100644 --- a/tests/libslic3r/test_elephant_foot_compensation.cpp +++ b/tests/libslic3r/test_elephant_foot_compensation.cpp @@ -220,8 +220,217 @@ static ExPolygon vase_with_fins() return out; } +static ExPolygon contour_with_hole() +{ + ExPolygon out; + out.contour.points = { + { 23302819, 108248}, { 23410179, 157624}, { 23451825, 176777}, { 24106418, 478750}, { 24704172, 811512}, { 24883849, 911534}, { 25980045, 1530217}, { 26591038, 1897423}, { 26829981, 2041022}, { 27158523, 2249848}, { 27618921, 2584465}, + { 27896903, 2786507}, { 28144524, 2978990}, { 28815685, 3551061}, { 28909975, 3628821}, { 29371498, 4009409}, { 29402087, 4037084}, { 29493584, 4119861}, { 29765627, 4382947}, { 30607836, 5197449}, { 30934687, 5508413}, { 31019374, 5593546}, + { 31075807, 5655861}, { 31235879, 5823254}, { 31667505, 6274618}, { 31976596, 6656087}, { 32328364, 7055603}, { 32440973, 7183484}, { 32491346, 7249288}, { 33179667, 8148478}, { 33575401, 8717521}, { 33835875, 9075811}, { 34010014, 9315332}, + { 34304500, 9781688}, { 34369165, 9898535}, { 34397842, 9950359}, { 34494651, 10316439}, { 34501993, 10344190}, { 34385828, 10617514}, { 34331252, 10651174}, { 34084812, 10803186}, { 33894353, 10899665}, { 33398927, 11326583}, + { 33183121, 11494200}, { 32195826, 12261037}, { 31686925, 12719913}, { 31571718, 12807396}, { 31250995, 13050935}, { 31207108, 13086856}, { 31130381, 13149671}, { 31070741, 13206732}, { 30967095, 13305896}, { 30228082, 14071658}, + { 30116771, 14212337}, { 30044101, 14304176}, { 29567520, 14906137}, { 29043350, 15664879}, { 28911161, 15871189}, { 28855871, 15957479}, { 28714334, 16227582}, { 28650159, 16350050}, { 28364584, 16899765}, { 28240857, 17235607}, + { 28151371, 17509658}, { 28114198, 17623503}, { 28309361, 17730441}, { 28370394, 17763884}, { 28488974, 17847025}, { 28525745, 17872806}, { 29082248, 18281292}, { 29152930, 18376480}, { 29168058, 18396855}, { 29173722, 18656366}, + { 29176206, 18770149}, { 29167406, 18857292}, { 29104337, 19029141}, { 29049428, 19178752}, { 28907061, 19434701}, { 28857790, 19523283}, { 28715480, 19775043}, { 28630622, 20043684}, { 28609342, 20111052}, { 28573760, 20267045}, + { 28403454, 21103762}, { 28370165, 21230085}, { 28332310, 21373746}, { 28315057, 21418891}, { 28294569, 21472487}, { 28334157, 21579715}, { 28561468, 21814880}, { 28854906, 22118451}, { 29225599, 22499341}, { 29285205, 22617454}, + { 29324833, 22695983}, { 29313473, 22800767}, { 29312583, 22808982}, { 29272380, 22876835}, { 28829469, 23460472}, { 28817999, 23488286}, { 28796393, 23540675}, { 28775618, 23627381}, { 28732328, 23808034}, { 28661140, 24177335}, + { 28645731, 24834289}, { 28625222, 25202417}, { 28579034, 26031478}, { 28586310, 26420529}, { 28633240, 26560504}, { 28664456, 26653603}, { 28740916, 26788014}, { 28797005, 26886614}, { 28812464, 26950783}, { 28858428, 27009579}, + { 28975940, 26859631}, { 29022419, 26805440}, { 29115451, 26696972}, { 29135739, 26685915}, { 29155135, 26675346}, { 29408332, 26616458}, { 29592642, 26573591}, { 29614928, 26568091}, { 29711634, 26559197}, { 30723503, 26466299}, + { 31183646, 26470661}, { 31550568, 26550771}, { 31777556, 26600329}, { 32014697, 26671604}, { 32334931, 26854665}, { 32449353, 26920987}, { 32657873, 27041843}, { 32701539, 27084927}, { 32750872, 27133602}, { 33434549, 27790306}, + { 33487600, 27817659}, { 33548673, 27849142}, { 33793150, 28109624}, { 33877574, 28164293}, { 33965395, 28221161}, { 33999067, 28249986}, { 34024398, 28271673}, { 34059690, 28329572}, { 34087359, 28374972}, { 34181544, 28710471}, + { 34170186, 28732578}, { 34134947, 28801161}, { 34092867, 29064916}, { 33950784, 29233310}, { 33878646, 29318804}, { 33721956, 29672399}, { 33660358, 29727949}, { 33620108, 29764243}, { 33393624, 30270577}, { 33094597, 30771032}, + { 33063116, 30812704}, { 32973928, 30930779}, { 32608081, 31341847}, { 32393317, 31544017}, { 32206520, 31719862}, { 31997581, 31894374}, { 31972538, 31942583}, { 32059002, 32025240}, { 32171917, 32133182}, { 32501317, 32311025}, + { 32715593, 32426714}, { 32802065, 32479231}, { 32956210, 32574312}, { 33249042, 32770899}, { 33946833, 33239350}, { 34445301, 33680139}, { 34778020, 33974357}, { 35230994, 34391224}, { 35341113, 34460366}, { 35450459, 34529022}, + { 35625170, 34673345}, { 35764733, 34757179}, { 35775747, 34633947}, { 35846476, 34564107}, { 35965365, 34446723}, { 36038088, 34379954}, { 36151170, 34276133}, { 36426218, 34106680}, { 36531666, 34187969}, { 36695885, 34314565}, + { 37011093, 34586835}, { 37067557, 34150814}, { 37052506, 33989541}, { 37037043, 33823855}, { 37069574, 33661923}, { 37083653, 33591851}, { 37186706, 33497192}, { 37521634, 33288703}, { 37617140, 33275082}, { 37684699, 33219614}, + { 37821418, 33228393}, { 37938489, 33235910}, { 38091617, 33138918}, { 38155158, 33060873}, { 38213556, 32989142}, { 38727086, 32659362}, { 38746459, 32654507}, { 38809135, 32638806}, { 38820634, 32624462}, { 38855007, 32581573}, + { 39134002, 32235481}, { 39392850, 32163442}, { 39569189, 32115608}, { 39686862, 32083692}, { 39744314, 32146839}, { 39840707, 31963655}, { 39973169, 31711932}, { 40025735, 31592644}, { 40157184, 31465080}, { 40313010, 31313863}, + { 40390192, 31223588}, { 40418596, 31230809}, { 40594404, 31186692}, { 40732045, 31068306}, { 40746151, 30846139}, { 40761255, 30608300}, { 40853394, 30223426}, { 40876768, 30095588}, { 40895496, 29993166}, { 40968240, 29949606}, + { 41197066, 29989787}, { 41412367, 30027591}, { 41472384, 29977101}, { 41695297, 29659954}, { 41890516, 29382211}, { 42157410, 28987811}, { 42408947, 28616097}, { 42669462, 28292349}, { 42683144, 28275345}, { 42919982, 27924149}, + { 43162781, 27628506}, { 43527344, 27260325}, { 43847191, 27036250}, { 44057061, 26922424}, { 44231096, 26828037}, { 44301999, 26795490}, { 44327421, 26804561}, { 44319287, 26913761}, { 44143507, 27648484}, { 44107324, 27729499}, + { 44074236, 27803580}, { 44025541, 27932083}, { 43944121, 28146941}, { 43877811, 28710269}, { 43895199, 28764671}, { 43933238, 28883702}, { 43919165, 29004140}, { 43888109, 29269841}, { 43825852, 29576752}, { 43811824, 29609468}, + { 43748820, 29756420}, { 43763658, 29837769}, { 43832567, 30215488}, { 44075125, 29807258}, { 44209233, 29804204}, { 44310228, 29813855}, { 44365586, 29958259}, { 43873534, 30271247}, { 44003187, 30330249}, { 44617279, 30687869}, + { 44694113, 31070182}, { 44941015, 31257544}, { 45130334, 31171398}, { 45147836, 31132029}, { 45242053, 31070592}, { 45345637, 31033061}, { 45565937, 30953238}, { 45609517, 30857448}, { 45651888, 30764320}, { 45660681, 30754094}, + { 45822750, 30772646}, { 45944979, 30753042}, { 45964326, 30749938}, { 46054945, 30795588}, { 46577640, 31130668}, { 46870296, 31313313}, { 46976414, 31379541}, { 46998128, 31406087}, { 47008874, 31439291}, { 47031018, 31569281}, + { 47031214, 31576854}, { 47036334, 31774677}, { 47193705, 31889293}, { 47353245, 32029772}, { 47484683, 32145510}, { 47534251, 32233847}, { 47538509, 32241438}, { 47602626, 32453825}, { 47622648, 32465115}, { 47701707, 32575250}, + { 47776955, 33122018}, { 47677092, 33345574}, { 47630772, 33380015}, { 47572757, 33423150}, { 47328653, 33537512}, { 47343826, 33612940}, { 47462219, 33617810}, { 47578431, 33622591}, { 47808035, 33604884}, { 47842258, 33885890}, + { 47847000, 34154765}, { 47852298, 34455418}, { 47806556, 34798342}, { 47804979, 34803470}, { 47795265, 34835122}, { 47811501, 34879922}, { 47843100, 35247684}, { 47839663, 35481904}, { 47833503, 35902474}, { 47803910, 36044010}, + { 47819598, 36077879}, { 47841934, 36100587}, { 47854870, 36165755}, { 47911856, 36452861}, { 47927332, 36616382}, { 47936929, 36717785}, { 47770423, 36987292}, { 47699764, 37101659}, { 47671115, 37157488}, { 47423375, 37424772}, + { 47616349, 37518717}, { 47680621, 37550006}, { 47836151, 37632587}, { 47811936, 37777743}, { 47716954, 38113916}, { 47654340, 38250491}, { 47533407, 38514290}, { 47431515, 38674036}, { 47367427, 38987733}, { 47348164, 39043625}, + { 47298533, 39187606}, { 47279676, 39231940}, { 47252411, 39296047}, { 47246894, 39304927}, { 47238746, 39318037}, { 47232029, 39335258}, { 47220194, 39365593}, { 47196053, 39429922}, { 47159408, 39527585}, { 47041654, 39691835}, + { 47002148, 39908798}, { 46964248, 39997937}, { 46895728, 40159083}, { 46826610, 40301043}, { 46763479, 40430710}, { 46514929, 40884923}, { 46474179, 40918994}, { 46440818, 40946888}, { 46433233, 40992821}, { 46426528, 41033401}, + { 46108271, 41626808}, { 46056215, 41723876}, { 45997871, 41855066}, { 45755987, 42227269}, { 45653183, 42385466}, { 45444848, 42652871}, { 45380966, 42654262}, { 45336326, 42655238}, { 45326382, 42763461}, { 45318953, 42844333}, + { 45175146, 43086382}, { 45086585, 43235443}, { 45055897, 43281060}, { 44968051, 43418247}, { 44470500, 44195272}, { 44413430, 44364401}, { 44390221, 44433179}, { 44309502, 44528273}, { 44199667, 44604532}, { 43887229, 44833256}, + { 43815081, 44886070}, { 43726552, 44932547}, { 43689058, 44928887}, { 43686137, 44927822}, { 43280111, 44871367}, { 43249704, 44937548}, { 43324977, 45004000}, { 43046101, 45224515}, { 42898716, 45341059}, { 42838343, 45382240}, + { 42721108, 45493632}, { 42470119, 45669357}, { 42359756, 45746630}, { 42073412, 45910212}, { 42022050, 45926905}, { 41907133, 46027394}, { 41144940, 46559849}, { 40902566, 46683907}, { 40884989, 46688481}, { 40811763, 46707548}, + { 40768612, 46786655}, { 40675645, 46871372}, { 40548269, 46985681}, { 40382460, 47085920}, { 40082094, 47267510}, { 39768380, 47413990}, { 39734614, 47420931}, { 39586801, 47437916}, { 39408498, 47458403}, { 39355630, 47574767}, + { 39281498, 47737937}, { 39251009, 47783502}, { 39152882, 47890727}, { 39013408, 48043132}, { 38921577, 48100514}, { 38896008, 48108330}, { 38727116, 48102492}, { 38692428, 48101294}, { 38425261, 48075982}, { 38342344, 48047392}, + { 38336010, 48154957}, { 38151978, 48395628}, { 37811687, 48488990}, { 37804084, 48490379}, { 37674998, 48513979}, { 37674196, 48513196}, { 37658712, 48498074}, { 37592273, 48482371}, { 37336907, 48659173}, { 37140701, 48741338}, + { 37129466, 48764064}, { 37075599, 48873013}, { 36739574, 48838715}, { 36721697, 48864552}, { 36456161, 49171298}, { 36442740, 49184060}, { 36436660, 49212679}, { 36300951, 49585030}, { 36223897, 49727927}, { 36150156, 49864671}, + { 35924446, 50245885}, { 35769083, 50508275}, { 35750118, 50514284}, { 35323137, 50653609}, { 34050908, 50703703}, { 33864494, 50706292}, { 33666152, 50709051}, { 33813201, 50839130}, { 33884905, 50893350}, { 33912037, 50913867}, + { 34282238, 51132740}, { 35016181, 51605972}, { 35027459, 51615787}, { 35030754, 51618656}, { 35108803, 51693454}, { 35137469, 51720927}, { 34948522, 51872654}, { 34658613, 52064227}, { 34464997, 52192175}, { 34289189, 52285353}, + { 34219119, 52312637}, { 33847969, 52428212}, { 33681538, 52480036}, { 33407178, 52510887}, { 33421683, 52685666}, { 33428342, 52765908}, { 33392094, 53146294}, { 33371466, 53362761}, { 33253040, 54291767}, { 33196142, 54612534}, + { 33128154, 54815569}, { 33095559, 54912904}, { 32570427, 55111061}, { 32525706, 55125923}, { 32458612, 55148214}, { 32385063, 55163161}, { 32282016, 55184108}, { 32241393, 55188603}, { 32190544, 55194226}, { 32027959, 55217259}, + { 32011561, 56072729}, { 32003567, 57064095}, { 31997637, 57799631}, { 32015577, 60287161}, { 32014290, 61201940}, { 32012996, 62120667}, { 32007630, 62197246}, { 32002828, 62265761}, { 32003310, 62373952}, { 32003630, 62444825}, + { 31951202, 63100419}, { 31935103, 63301732}, { 31937490, 63354807}, { 31968533, 64124669}, { 32071989, 64767136}, { 32091323, 64947492}, { 32101518, 65042609}, { 32140486, 65216353}, { 32159835, 65302616}, { 32422071, 66001036}, + { 32441049, 66056128}, { 32463003, 66119864}, { 32483582, 66164217}, { 32504016, 66208251}, { 32702117, 66557895}, { 32734168, 66611648}, { 32759723, 66654509}, { 32985249, 66546464}, { 33208649, 66439436}, { 33424955, 66330151}, + { 33554797, 66263457}, { 33891385, 66090564}, { 34622897, 65616004}, { 34819546, 65471063}, { 34988926, 65346218}, { 35739513, 64794843}, { 36421629, 64150515}, { 36944662, 63656452}, { 36959929, 63643292}, { 36964174, 63639854}, + { 36973615, 63630686}, { 37023366, 63597643}, { 37652255, 63172287}, { 37804320, 63100590}, { 37939211, 63174238}, { 37949998, 63178562}, { 38147664, 63257792}, { 38147652, 63269386}, { 38147521, 63403665}, { 38150429, 63418056}, + { 38177182, 63550576}, { 38159827, 64298859}, { 38153585, 64520174}, { 38146482, 64771937}, { 38142126, 64820836}, { 38138239, 64839298}, { 38115242, 65010431}, { 38113231, 65025393}, { 37912271, 66372984}, { 37841830, 66687479}, + { 37674277, 67228175}, { 37551047, 67593509}, { 37497098, 67727333}, { 37392268, 67951311}, { 36986640, 68817980}, { 36604483, 69575518}, { 36479686, 69769345}, { 36265058, 70102690}, { 36332308, 70163400}, { 36398395, 70223058}, + { 36718105, 70645723}, { 36714573, 70708131}, { 36707947, 70825274}, { 36665865, 71083146}, { 36295751, 71910509}, { 36243731, 72020144}, { 36010145, 72512434}, { 35364761, 74115820}, { 35327445, 74206370}, { 35287332, 74303707}, + { 35262905, 74370595}, { 35235816, 74444782}, { 35006275, 75142899}, { 34758612, 75896141}, { 34609479, 76324076}, { 34534936, 76598593}, { 34419529, 77019735}, { 34125782, 78091675}, { 34270135, 78023153}, { 34366481, 77977415}, + { 34669421, 77827427}, { 35532698, 77282412}, { 35875762, 77065829}, { 35924952, 77041288}, { 35981906, 77004141}, { 36227708, 76899428}, { 36700108, 76693284}, { 36835857, 76657801}, { 36942059, 76731654}, { 36959107, 76741135}, + { 37155031, 76850094}, { 37152161, 76868751}, { 37133420, 76990662}, { 37135224, 77014721}, { 37144331, 77136260}, { 37029215, 77783623}, { 36994547, 77984972}, { 36957442, 78200506}, { 36949745, 78231593}, { 36945059, 78243379}, + { 36909925, 78358183}, { 36908693, 78362210}, { 36517584, 79569608}, { 36400200, 79852238}, { 36160758, 80317591}, { 36001388, 80606724}, { 35929263, 80720331}, { 35803937, 80894237}, { 35313741, 81574455}, { 34810829, 82211118}, + { 34636165, 82398130}, { 34424143, 82625140}, { 34177218, 82875584}, { 34001320, 83053991}, { 33330876, 83686990}, { 33313615, 83940131}, { 33257889, 84757318}, { 33154596, 86125618}, { 33050414, 87930914}, { 33037323, 88157771}, + { 32996151, 88791902}, { 33122354, 88720953}, { 34042644, 88195810}, { 34854618, 87571171}, { 35217422, 87292077}, { 35240201, 87279017}, { 35256654, 87268145}, { 35304044, 87230648}, { 35465557, 87154377}, { 35979874, 86886707}, + { 36162994, 86833255}, { 36213131, 86859811}, { 36328089, 86920714}, { 36446386, 87103899}, { 36444792, 87129675}, { 36435583, 87278561}, { 36439166, 87306042}, { 36455346, 87430153}, { 36439626, 87577638}, { 36363937, 88287781}, + { 36334385, 88516418}, { 36324472, 88550288}, { 36266923, 88831775}, { 36258817, 88871412}, { 36009099, 90001153}, { 35925390, 90278389}, { 35742522, 90743063}, { 35584494, 91114154}, { 35511233, 91260521}, { 35378328, 91493626}, + { 34896978, 92337857}, { 34592698, 92829175}, { 34534101, 92906355}, { 34379904, 93109443}, { 34292029, 93224277}, { 34181322, 93368951}, { 33996695, 93594059}, { 33791238, 93844563}, { 33350304, 94350448}, { 32679061, 95059135}, + { 32663276, 95383974}, { 32630835, 96051559}, { 32623715, 96162432}, { 32625261, 96184173}, { 32631760, 96253789}, { 32637940, 96319986}, { 32671334, 96831435}, { 32555999, 97073603}, { 32552956, 97110111}, { 32549772, 97148299}, + { 32339278, 100576678}, { 32333722, 100685777}, { 32330348, 100752035}, { 32315766, 101012907}, { 32604225, 100816839}, { 32833219, 100661190}, { 33690734, 100037568}, { 33947721, 99810841}, { 34263306, 99532414}, { 34709871, 99161136}, + { 35458100, 98470566}, { 35535202, 98409290}, { 35673889, 98299068}, { 35825183, 98230993}, { 36031300, 98138241}, { 36364183, 98058757}, { 36389853, 98099020}, { 36443213, 98182736}, { 36495776, 98421334}, { 36464592, 98534766}, + { 36403262, 98757832}, { 36433188, 98786253}, { 36468201, 98819516}, { 36427877, 99135414}, { 36380139, 99509425}, { 36367327, 99566653}, { 36130997, 100458902}, { 36092849, 100736616}, { 35993189, 101207413}, { 35961980, 101354843}, + { 35901824, 101565944}, { 35599001, 102436249}, { 35598486, 102437494}, { 35525627, 102612717}, { 35498238, 102672427}, { 35179093, 103368204}, { 34902420, 103873765}, { 34074371, 105280790}, { 33796945, 105666257}, { 33430747, 106175067}, + { 32757675, 107021332}, { 32288404, 107611357}, { 32147333, 107782229}, { 32045181, 107903768}, { 32013865, 108446053}, { 32004365, 108597331}, { 31933356, 109727991}, { 31929556, 109801743}, { 31921205, 109963885}, { 31919950, 109998202}, + { 31917378, 110068478}, { 31935487, 110174763}, { 31962352, 110332410}, { 31868759, 110776536}, { 31779274, 112901692}, { 31772558, 113008639}, { 31763520, 113152580}, { 31760914, 113226796}, { 31757613, 113320828}, { 31878079, 113245898}, + { 32056600, 113134847}, { 32205325, 113028281}, { 32417383, 112876331}, { 32791706, 112611586}, { 33374891, 112199137}, { 34043729, 111739447}, { 34299836, 111533282}, { 34686259, 111194925}, { 35041202, 110899316}, { 36153161, 109973245}, + { 36489565, 109732139}, { 36935134, 109547251}, { 36998142, 109523782}, { 37285208, 109416845}, { 37303575, 109443686}, { 37380657, 109556352}, { 37429339, 109768662}, { 37389406, 109896075}, { 37312708, 110140778}, { 37330397, 110173101}, + { 37358669, 110224762}, { 37347970, 110508588}, { 37343682, 110622428}, { 37233824, 111039422}, { 36974286, 111866215}, { 36941457, 112104350}, { 36810462, 112600390}, { 36763361, 112778757}, { 36685333, 113003686}, { 36304140, 113929965}, + { 36303227, 113931942}, { 36219925, 114112998}, { 36185254, 114177524}, { 35766113, 114957538}, { 35699185, 115058398}, { 35271549, 115739102}, { 34529522, 116832154}, { 34230604, 117226448}, { 34152175, 117323267}, { 33753453, 117815498}, + { 33688745, 117896887}, { 33515149, 118115220}, { 33167360, 118505862}, { 32252839, 119533076}, { 31951224, 119865885}, { 31856676, 119967574}, { 31811772, 120013039}, { 31820788, 120150853}, { 31837447, 120637820}, { 31884548, 122014628}, + { 31884879, 122025348}, { 31884889, 122025915}, { 31884859, 122030715}, { 31853727, 124752378}, { 31852710, 125798379}, { 32040109, 125687330}, { 32336721, 125511560}, { 33050838, 125039566}, { 33741293, 124531865}, { 34004877, 124347492}, + { 34706008, 123857040}, { 34900746, 123695124}, { 35248769, 123405773}, { 35958009, 122839178}, { 36752647, 122139217}, { 36794698, 122103853}, { 36926183, 121993279}, { 37041929, 121900209}, { 37364281, 121641009}, { 37506782, 121535931}, + { 37599623, 121475276}, { 37805210, 121390600}, { 38274450, 121197339}, { 38429386, 121137935}, { 38611951, 121409191}, { 38647554, 121490884}, { 38558179, 121763354}, { 38544345, 121816126}, { 38504735, 121967178}, { 38540287, 122025777}, + { 38533522, 122225637}, { 38527834, 122393821}, { 38490015, 122574939}, { 38335371, 123023448}, { 38226910, 123422167}, { 38128017, 123785706}, { 38110062, 123913558}, { 38039445, 124196782}, { 37811751, 125109983}, { 37795287, 125159401}, + { 37789856, 125175267}, { 37747302, 125281671}, { 37678378, 125454008}, { 37326009, 126304036}, { 37280379, 126403545}, { 36723741, 127438116}, { 36607591, 127622339}, { 35307172, 129556108}, { 34960577, 130042788}, { 34625146, 130457962}, + { 34244496, 130929114}, { 33616736, 131638592}, { 33126427, 132192717}, { 32289044, 133098400}, { 32128210, 133254928}, { 32114672, 133265860}, { 32051379, 133303244}, { 31973610, 133349175}, { 32021296, 134019482}, { 32078232, 134927829}, + { 32192915, 136757391}, { 32250210, 137342897}, { 32301584, 137908848}, { 32406571, 139065434}, { 32456488, 139422175}, { 32511513, 139855909}, { 32587723, 140456611}, { 33065481, 140191593}, { 33323332, 140063408}, { 33766028, 139843340}, + { 33978698, 139717429}, { 34224999, 139571601}, { 35090288, 139002456}, { 36098536, 138270161}, { 36204726, 138196467}, { 36870073, 137734734}, { 36937868, 137678015}, { 37269439, 137400662}, { 38224552, 136636721}, { 39248462, 135736109}, + { 39262231, 135724978}, { 39431206, 135588270}, { 39558286, 135491389}, { 40066663, 135103831}, { 40597978, 134876486}, { 40913397, 134752602}, { 41009750, 134730971}, { 41033440, 134769160}, { 41137853, 134937472}, { 41236776, 135135656}, + { 41185372, 135392011}, { 41170368, 135466840}, { 41117848, 135629223}, { 41128977, 135726643}, { 41112112, 135925316}, { 41028443, 136275112}, { 40892177, 136737346}, { 40715316, 137337282}, { 40625973, 137862286}, { 40571054, 138077826}, + { 40413004, 138698127}, { 40307787, 139028628}, { 40280705, 139108396}, { 40108570, 139542037}, { 39781168, 140366808}, { 39776747, 140377453}, { 39771298, 140388940}, { 39694209, 140532631}, { 39126953, 141589960}, { 39112976, 141613526}, + { 38864787, 141998169}, { 38780359, 142124163}, { 37534211, 143983846}, { 36837998, 144898691}, { 36749607, 145008489}, { 36437049, 145396720}, { 36308895, 145540735}, { 35926199, 145970826}, { 35104551, 146848709}, { 34756762, 147234955}, + { 34428436, 147599589}, { 34120556, 147908106}, { 34059694, 147944671}, { 33992021, 147971830}, { 33888925, 148013197}, { 33994002, 148234139}, { 34102871, 148463060}, { 34260406, 148815390}, { 34505558, 149252538}, { 34649150, 149539737}, + { 34875213, 149991894}, { 34913367, 150060689}, { 34939834, 150108425}, { 35009188, 150222655}, { 35057146, 150301638}, { 35531716, 151039155}, { 35961908, 151607166}, { 36198106, 151919026}, { 37112008, 151466356}, { 37122527, 151461129}, + { 37143274, 151448455}, { 37793852, 151104327}, { 38753278, 150462096}, { 39057095, 150265965}, { 39387132, 150052914}, { 39992757, 149578233}, { 40209373, 149410006}, { 40448656, 149224173}, { 41648972, 148150708}, { 41827582, 147994189}, + { 42089284, 147764870}, { 42281920, 147557241}, { 42535672, 147283737}, { 43211137, 146606344}, { 43969650, 145734949}, { 44008274, 145690567}, { 44434382, 145256367}, { 44673165, 145036231}, { 44753304, 144976343}, { 44941707, 144886575}, + { 45449136, 144644796}, { 45533221, 144617860}, { 45594657, 144672684}, { 45686988, 144755077}, { 45821054, 144894151}, { 45845698, 144928928}, { 45802394, 145256827}, { 45801968, 145263145}, { 45793099, 145396327}, { 45826083, 145436911}, + { 45827387, 145448733}, { 45852550, 145676686}, { 45846396, 146183080}, { 45801072, 146729105}, { 45751200, 147329993}, { 45765306, 147565974}, { 45765766, 147690105}, { 45758629, 147823920}, { 45717918, 148587045}, { 45669293, 148998256}, + { 45657164, 149090109}, { 45565455, 149517107}, { 45390903, 150329829}, { 45380310, 150370709}, { 45303883, 150599765}, { 45049477, 151362234}, { 45041081, 151384892}, { 44988127, 151512567}, { 44899898, 151709940}, { 44188361, 153301702}, + { 43960091, 153807492}, { 43687530, 154326968}, { 43680264, 154339888}, { 43428400, 154787836}, { 43418419, 154804941}, { 43222756, 155140257}, { 43211901, 155157187}, { 43019606, 155457042}, { 42439201, 156284412}, { 42742998, 156320854}, + { 42946786, 156345296}, { 43218356, 156408139}, { 43490220, 156548626}, { 43600789, 156605776}, { 43616758, 156616967}, { 43638494, 156675797}, { 43689725, 156874320}, { 43697411, 156939181}, { 43667792, 157194800}, { 43663112, 157219786}, + { 43589483, 157612846}, { 43578259, 157650201}, { 43503908, 157897703}, { 43271842, 158586008}, { 43026656, 159112379}, { 42680049, 159768278}, { 42229097, 160621619}, { 41614538, 161818913}, { 41602009, 161838594}, { 41549009, 161921905}, + { 41366702, 162195210}, { 41089703, 162610457}, { 41051349, 162661598}, { 40028827, 163938879}, { 39981539, 163995316}, { 39859709, 164140726}, { 39557928, 164489623}, { 38840108, 165319487}, { 38817977, 165343409}, { 36508721, 167822791}, + { 35803734, 168527171}, { 35265129, 169065323}, { 35217638, 169111343}, { 35182142, 169143335}, { 34143283, 170051242}, { 34091092, 170092305}, { 33992346, 170169987}, { 32820222, 171015261}, { 32596277, 171172367}, { 32366414, 171333625}, + { 30949741, 172256683}, { 30776429, 172369214}, { 30685231, 172428426}, { 29784929, 172978028}, { 29711510, 173022900}, { 29649347, 173060901}, { 29626880, 173084470}, { 29607989, 173104288}, { 29476620, 173372906}, { 29166644, 173374167}, + { 29105869, 173396269}, { 29066168, 173410694}, { 28480959, 173773359}, { 28318456, 173874074}, { 28236958, 173920336}, { 28053468, 174015451}, { 27663961, 174212865}, { 26444009, 174781179}, { 25128636, 175292014}, { 24833691, 175404475}, + { 24567873, 175499255}, { 23673660, 175815148}, { 23263816, 175959931}, { 22989484, 175996217}, { 22919277, 176005507}, { 22821755, 176011321}, { 22593369, 175931875}, { 22197778, 175796707}, { 20895444, 175329856}, { 20562493, 175210506}, + { 20357518, 175131409}, { 19431901, 174778687}, { 19227774, 174700914}, { 17432818, 173805114}, { 17355249, 173765680}, { 17340552, 173757060}, { 17293649, 173727963}, { 15176003, 172414266}, { 14987901, 172296594}, { 14897452, 172240019}, + { 14730104, 172123866}, { 14649567, 172067971}, { 12604451, 170685425}, { 12582065, 170669040}, { 12501564, 170610143}, { 12483411, 170595498}, { 12418519, 170543227}, { 11146256, 169546467}, { 11131285, 169533173}, { 10973608, 169393198}, + { 10963368, 169383375}, { 10855356, 169279681}, { 9350332, 167783891}, { 9237755, 167663880}, { 9038028, 167450975}, { 7554140, 165846157}, { 6510331, 164717307}, { 6450301, 164645790}, { 4792198, 162599032}, { 4711896, 162499401}, + { 4702892, 162486484}, { 4689884, 162466018}, { 4689721, 162465748}, { 4111625, 161512044}, { 3262811, 159825639}, { 3085907, 159501392}, { 2964224, 159278374}, { 2880198, 159123098}, { 2827825, 159026309}, { 2730830, 158798250}, + { 2662597, 158637824}, { 2461794, 158144454}, { 2258655, 157377436}, { 2232776, 156966420}, { 2227381, 156880727}, { 2229842, 156800001}, { 2404803, 156571898}, { 2502593, 156512353}, { 2571069, 156470646}, { 3012355, 156329121}, + { 3172690, 156317433}, { 3263007, 156310852}, { 3448807, 156270050}, { 2933268, 155537448}, { 2932334, 155536119}, { 2690506, 155171633}, { 2473838, 154800417}, { 2214521, 154335871}, { 1956160, 153843466}, { 1643404, 153150964}, + { 936422, 151585583}, { 886715, 151471650}, { 881872, 151459055}, { 835673, 151315362}, { 420381, 150023686}, { 415543, 150006511}, { 411493, 149986474}, { 371105, 149740432}, { 184472, 148603483}, { 176976, 148544106}, { 143829, 148268525}, + { 141423, 148213179}, { 118798, 147692447}, { 141994, 147109270}, { 96664, 146619882}, { 46940, 146083025}, { 34028, 145778412}, { 32148, 145734124}, { 50580, 145571914}, { 79797, 145477573}, { 59893, 144996644}, { 53607, 144916874}, + { 75632, 144881102}, { 170230, 144783356}, { 367047, 144609349}, { 495089, 144649841}, { 696206, 144748339}, { 861062, 144829070}, { 1202743, 145013350}, { 1665932, 145467720}, { 1738044, 145542186}, { 1871110, 145679584}, { 2233705, 146073631}, + { 2875888, 146771504}, { 2976802, 146887761}, { 3008358, 146918708}, { 3105019, 147016992}, { 3562844, 147482514}, { 3900940, 147829488}, { 3926192, 147851556}, { 5456634, 149216502}, { 5473415, 149229592}, { 5678115, 149389248}, + { 6416516, 149979537}, { 6693887, 150160404}, { 7011978, 150367823}, { 8034093, 151060650}, { 8245822, 151174920}, { 8663509, 151400371}, { 8734568, 151444233}, { 9700825, 151913516}, { 10314440, 151101573}, { 10876143, 150241580}, + { 10937084, 150142918}, { 10989872, 150057455}, { 11012110, 150016058}, { 11029139, 149984364}, { 11202330, 149640866}, { 11331097, 149385460}, { 11601540, 148893595}, { 11801542, 148453984}, { 11867898, 148312015}, { 12006182, 148016156}, + { 11936334, 147987685}, { 11846756, 147951181}, { 11775937, 147908929}, { 11448318, 147578728}, { 10005162, 146006655}, { 9941330, 145934468}, { 9420742, 145345782}, { 9364739, 145276533}, { 9005053, 144831776}, { 8354706, 143947082}, + { 7741954, 143034251}, { 7046776, 141998616}, { 6866979, 141726486}, { 6759755, 141551328}, { 6581042, 141228382}, { 6214827, 140566592}, { 6160332, 140464737}, { 6154984, 140452943}, { 6118667, 140365627}, { 5608006, 139066930}, + { 5576877, 138974353}, { 5449821, 138579522}, { 5423448, 138473840}, { 5269717, 137857830}, { 5183256, 137323221}, { 5051763, 136885377}, { 4900390, 136381329}, { 4788716, 135926420}, { 4778542, 135832434}, { 4751278, 135580592}, + { 4759133, 135551850}, { 4772567, 135502722}, { 4750760, 135428400}, { 4689711, 135220325}, { 4720284, 134950229}, { 4772938, 134876983}, { 4872059, 134739100}, { 4907041, 134734799}, { 4988166, 134747911}, { 5187996, 134827143}, + { 5324282, 134881173}, { 5823633, 135095262}, { 6457261, 135576778}, { 6468046, 135585394}, { 6645027, 135726930}, { 7665807, 136625984}, { 8014871, 136908364}, { 8760642, 137511681}, { 9070115, 137764153}, { 9505207, 138067027}, + { 9692018, 138199840}, { 10866067, 139034528}, { 10974854, 139102654}, { 11199174, 139243162}, { 11980766, 139757269}, { 12820102, 140204762}, { 13013724, 140301821}, { 13307713, 140449197}, { 13339465, 140204984}, { 13387908, 139832384}, + { 13476326, 139229254}, { 13545245, 138464294}, { 13637934, 137435521}, { 13704650, 136750183}, { 13756310, 135946981}, { 13854009, 134427968}, { 13931781, 133352665}, { 13880515, 133326641}, { 13806176, 133288914}, { 13608773, 133095964}, + { 13229938, 132676064}, { 12917088, 132329299}, { 12475540, 131854762}, { 12234438, 131582242}, { 11645945, 130917061}, { 11435343, 130656410}, { 11256705, 130435328}, { 11087956, 130227341}, { 10943531, 130049329}, { 10660547, 129658000}, + { 9884836, 128504691}, { 9363495, 127729593}, { 9183437, 127445707}, { 8613352, 126392173}, { 8569664, 126295529}, { 8233135, 125484892}, { 8100143, 125150567}, { 8091324, 125125230}, { 8068370, 125055541}, { 8047369, 124966573}, + { 7827878, 124036734}, { 7815999, 123941440}, { 7743138, 123689990}, { 7467916, 122740178}, { 7381012, 122383130}, { 7365871, 122250909}, { 7330956, 121946008}, { 7347071, 121910652}, { 7366239, 121868607}, { 7337555, 121775565}, + { 7275180, 121573218}, { 7357784, 121255913}, { 7363162, 121248563}, { 7433561, 121152362}, { 7492882, 121172887}, { 8152120, 121400901}, { 8296078, 121458859}, { 8337642, 121483827}, { 8428744, 121552386}, { 8461373, 121578560}, + { 9113408, 122101612}, { 9968838, 122858025}, { 10418874, 123221408}, { 11203964, 123855334}, { 11236475, 123882487}, { 11264272, 123901717}, { 12869603, 125041315}, { 13619004, 125547677}, { 13833945, 125671552}, { 14049136, 125795572}, + { 14042979, 124631730}, { 14031124, 123791039}, { 14029618, 123425913}, { 14024871, 122275773}, { 14024680, 122240909}, { 14024300, 122172017}, { 14024368, 122132419}, { 14024494, 122058437}, { 14025750, 122003675}, { 14028093, 121901540}, + { 14053706, 121051621}, { 14084937, 120015176}, { 13976495, 119893307}, { 12808105, 118596333}, { 12632795, 118395530}, { 12332420, 118051483}, { 12010936, 117651678}, { 11662489, 117218341}, { 11286185, 116695820}, { 10542401, 115590915}, + { 10484664, 115505145}, { 10085127, 114875400}, { 9677465, 114107097}, { 9676038, 114103997}, { 9587011, 113910478}, { 9572058, 113874387}, { 9221672, 113028545}, { 9132465, 112762183}, { 8929936, 112011523}, { 8896027, 111773355}, + { 8763540, 111338847}, { 8591711, 110775312}, { 8585822, 110750616}, { 8583286, 110726469}, { 8532504, 110242770}, { 8561517, 110201837}, { 8589689, 110162093}, { 8539283, 109999835}, { 8459773, 109743891}, { 8476274, 109635698}, + { 8539247, 109532026}, { 8559299, 109499015}, { 8639538, 109407427}, { 8837219, 109481673}, { 9374636, 109713713}, { 9614985, 109884378}, { 9895885, 110108176}, { 10150796, 110311272}, { 10647433, 110745796}, { 11163900, 111149653}, + { 11435641, 111378216}, { 11952173, 111812662}, { 12063358, 111892355}, { 12195941, 111987389}, { 13754894, 113077948}, { 13965930, 113207021}, { 14143358, 113315534}, { 14095680, 112195851}, { 14075275, 111736247}, { 14031684, 110754424}, + { 13949266, 109698295}, { 13931155, 109374956}, { 13907232, 108947887}, { 13903305, 108820557}, { 13899752, 108705317}, { 13898286, 108692370}, { 13896892, 108680054}, { 13882077, 108455610}, { 13866991, 108227067}, { 13852378, 107897586}, + { 13627196, 107630194}, { 13249326, 107173733}, { 13128837, 107021896}, { 12504668, 106235327}, { 12449045, 106156712}, { 12301165, 105947708}, { 12240927, 105864439}, { 12071292, 105629917}, { 11741182, 105140360}, { 11102902, 104050785}, + { 11009874, 103891983}, { 10724262, 103375048}, { 10370561, 102607103}, { 10302463, 102446702}, { 9995869, 101563023}, { 9933827, 101340326}, { 9788639, 100674614}, { 9761576, 100425516}, { 9620310, 99895785}, { 9572074, 99714909}, + { 9473316, 99261511}, { 9457110, 98860065}, { 9475422, 98813097}, { 9491516, 98771818}, { 9454445, 98628574}, { 9395112, 98399301}, { 9430018, 98201406}, { 9448015, 98172416}, { 9519385, 98057456}, { 9858391, 98155219}, { 10045563, 98209192}, + { 10217386, 98274096}, { 10328458, 98365757}, { 11168922, 99136589}, { 11517095, 99428522}, { 11782963, 99664460}, { 12152171, 99992110}, { 12543518, 100270019}, { 12914813, 100533689}, { 13199749, 100744460}, { 13324020, 100835567}, + { 13585579, 101027330}, { 13575682, 100826649}, { 13569447, 100700201}, { 13562345, 100567361}, { 13559065, 100506021}, { 13429751, 98521010}, { 13371150, 97621467}, { 13343156, 97180710}, { 13333987, 97039073}, { 13207473, 95084673}, + { 13138184, 95005008}, { 13017680, 94866468}, { 12083312, 93848129}, { 12022705, 93771797}, { 11862461, 93569995}, { 11784430, 93470508}, { 11589381, 93221813}, { 11309567, 92840780}, { 10844778, 92098029}, { 10775191, 91976786}, + { 10496881, 91491862}, { 10185086, 90849349}, { 10144137, 90764963}, { 10074833, 90600171}, { 9828579, 89857830}, { 9703614, 89075796}, { 9674971, 88969502}, { 9495272, 88102892}, { 9475468, 87916753}, { 9440640, 87589408}, { 9465676, 87528619}, + { 9487914, 87474617}, { 9465041, 87357340}, { 9428525, 87170118}, { 9490390, 86904119}, { 9512256, 86883153}, { 9574632, 86823334}, { 9727402, 86841642}, { 10166330, 86894255}, { 10190151, 86899193}, { 10198409, 86903284}, { 10249971, 86942095}, + { 10299758, 86980568}, { 11788945, 88131376}, { 11901024, 88196968}, { 12050012, 88284161}, { 12770268, 88697024}, { 12893258, 88767518}, { 12865978, 88340499}, { 12755514, 86383203}, { 12590001, 84209400}, { 12584956, 84143148}, + { 12549052, 83666692}, { 11929877, 83107725}, { 11390770, 82556851}, { 11083660, 82243035}, { 10537284, 81546957}, { 10424674, 81403496}, { 10079867, 80926984}, { 9689286, 80270083}, { 9687616, 80267071}, { 9615613, 80136762}, + { 9601056, 80104215}, { 9309849, 79453353}, { 9259598, 79312241}, { 9118888, 78788995}, { 9088297, 78585733}, { 8994447, 78301695}, { 8881493, 77959840}, { 8828452, 77771748}, { 8812025, 77688113}, { 8733303, 77287329}, { 8744431, 77274990}, + { 8786674, 77228142}, { 8770800, 77179143}, { 8746495, 77100409}, { 8709758, 76981397}, { 8765710, 76725562}, { 8780763, 76703647}, { 8821796, 76643902}, { 9050198, 76667553}, { 9430163, 76706910}, { 9505621, 76721216}, { 9535183, 76740071}, + { 9561982, 76753134}, { 11021709, 77681521}, { 11271938, 77809531}, { 11740477, 78049225}, { 11713323, 77940287}, { 11500961, 77088300}, { 11491445, 77055518}, { 11468672, 76977103}, { 11007894, 75454998}, { 10625858, 74342820}, + { 10581531, 74223613}, { 10547931, 74133250}, { 9872558, 72487409}, { 9785055, 72279833}, { 9735127, 72161397}, { 9661531, 72007947}, { 9614591, 71910070}, { 9234200, 71112437}, { 9147114, 70727104}, { 9142261, 70702843}, { 9138267, 70682891}, + { 9286224, 70443224}, { 9461343, 70247284}, { 9556416, 70162672}, { 9625168, 70101485}, { 9435737, 69811425}, { 9287394, 69584273}, { 8757085, 68530695}, { 8673850, 68365333}, { 8445942, 67877601}, { 8187617, 67187177}, { 8139627, 67039434}, + { 7937861, 66234567}, { 7892565, 65909655}, { 7845288, 65439718}, { 7844011, 65310767}, { 7823103, 65136343}, { 7778117, 64761067}, { 7716333, 64313964}, { 7705694, 64124356}, { 7687717, 63803945}, { 7701643, 63790152}, { 7718011, 63773943}, + { 7758186, 63752036}, { 7729172, 63586572}, { 7697769, 63407488}, { 7779619, 63146399}, { 7790119, 63132497}, { 7857734, 63042993}, { 7899799, 63053366}, { 8115923, 63106666}, { 8464711, 63240292}, { 8677072, 63398904}, { 8767176, 63477143}, + { 8977927, 63660143}, { 9421383, 64100703}, { 9785048, 64413088}, { 9975436, 64589567}, { 10286420, 64877827}, { 11014721, 65410888}, { 11115862, 65482249}, { 11327524, 65631599}, { 11395991, 65675856}, { 11535890, 65766274}, { 12026448, 66109919}, + { 12502690, 66343355}, { 12786634, 66472769}, { 13164960, 66645193}, { 13207596, 66564001}, { 13256756, 66470394}, { 13640736, 65570500}, { 13683003, 65454507}, { 13718537, 65356988}, { 13735231, 65270567}, { 13747424, 65207437}, + { 13863686, 64629409}, { 13875328, 64496043}, { 13887975, 64351165}, { 13957488, 63607260}, { 13950883, 63386188}, { 13943973, 63154947}, { 13895952, 62476120}, { 13876483, 62262044}, { 13859838, 62079009}, { 13859584, 62074662}, + { 13859582, 62065658}, { 13859483, 61971042}, { 13862761, 55222623}, { 13815791, 55212684}, { 13617475, 55174296}, { 13379849, 55128299}, { 13200660, 55067043}, { 13117648, 55038667}, { 12798922, 54907256}, { 12743350, 54730557}, + { 12719703, 54655364}, { 12656225, 54324243}, { 12632418, 53676660}, { 12625539, 53489551}, { 12652785, 53052852}, { 12782795, 52820186}, { 12846930, 52705411}, { 13041220, 52491209}, { 13143647, 52409064}, { 13187810, 52373646}, + { 13354789, 52319639}, { 13381838, 52313108}, { 13407786, 52306845}, { 13609096, 52308186}, { 13798532, 52309451}, { 14794521, 52294618}, { 15549961, 52336594}, { 16050147, 52311338}, { 16209513, 52303295}, { 16312325, 52297439}, + { 16369590, 51869307}, { 16340473, 51576398}, { 16331091, 51482008}, { 16316170, 51377054}, { 16241360, 51186578}, { 16186688, 51047373}, { 16076915, 50725256}, { 16093629, 50461603}, { 16098435, 50385771}, { 16109774, 50333994}, + { 16208639, 50141731}, { 16271132, 50020206}, { 16284775, 49997056}, { 16295310, 49985147}, { 16360397, 49947770}, { 16432796, 49916484}, { 16999910, 49671395}, { 17079341, 49631019}, { 17221011, 49559013}, { 17356128, 49546264}, + { 17369996, 49528116}, { 17426993, 49502498}, { 17530282, 49456075}, { 17342293, 49148088}, { 17284381, 49008875}, { 17254026, 48935905}, { 17357436, 48625105}, { 17422365, 48429965}, { 17423796, 48426977}, { 17601162, 48056939}, + { 17599241, 47980228}, { 17595410, 47827198}, { 17579402, 47751708}, { 17538195, 47557388}, { 17400788, 46598168}, { 17023471, 46464319}, { 16973301, 46446494}, { 16812540, 46389386}, { 16673736, 46329440}, { 16319654, 46176525}, + { 15950663, 46003440}, { 15838028, 45939836}, { 15697899, 45836427}, { 15289766, 45502367}, { 15260072, 45476441}, { 14999104, 45248614}, { 14962927, 45210840}, { 14722491, 44959778}, { 14678301, 44921783}, { 14404868, 44686698}, + { 14020130, 44298671}, { 13905758, 44155324}, { 13566066, 43648328}, { 13163266, 43047144}, { 13102631, 42937239}, { 13070977, 42862998}, { 12945977, 42560557}, { 12902489, 42448510}, { 12696099, 41916758}, { 12684650, 41857975}, + { 12656516, 41713516}, { 12557005, 40938961}, { 12554067, 40837978}, { 12550435, 40713161}, { 12562692, 40535359}, { 12575839, 40344643}, { 12609216, 40034504}, { 12660395, 39915667}, { 12708691, 39803526}, { 12798899, 39599814}, + { 12938906, 39372986}, { 12995589, 39281154}, { 13232289, 39007147}, { 13498241, 38725717}, { 13591444, 38550048}, { 13628611, 38480001}, { 13631794, 38446522}, { 13586786, 38388985}, { 13507530, 38236091}, { 13096257, 38028857}, + { 12821362, 37838492}, { 12551686, 37651741}, { 12445887, 37503612}, { 12369283, 37396362}, { 12264258, 37242462}, { 12195026, 37044172}, { 12148552, 36863589}, { 12101329, 36680088}, { 12142095, 35348959}, { 12144651, 35291418}, + { 12162788, 34883134}, { 12163706, 34850506}, { 12168637, 34675334}, { 12163420, 34644423}, { 12134883, 34475307}, { 12106311, 33932082}, { 12095021, 33476333}, { 12094122, 33057779}, { 12092211, 32168031}, { 12100800, 31962352}, + { 12107580, 31800023}, { 12116077, 31640101}, { 12122543, 31518406}, { 12193613, 31111725}, { 12255946, 30755035}, { 12655685, 28642673}, { 12654000, 28322388}, { 12689137, 28120452}, { 12708722, 28007885}, { 12692342, 27740702}, + { 12770201, 27316837}, { 12810004, 27100162}, { 12822406, 26990057}, { 12840969, 26876333}, { 12930142, 26507364}, { 13006294, 26192274}, { 13140275, 25812749}, { 13171909, 25737294}, { 13213594, 25637871}, { 13513395, 24982223}, + { 13564918, 24904642}, { 13614340, 24830229}, { 13673478, 24765245}, { 13723561, 24710211}, { 13790283, 24595233}, { 13857122, 24480057}, { 14153860, 24116007}, { 14231993, 24020147}, { 14248273, 23981550}, { 14451243, 23786195}, + { 14602942, 23651634}, { 14684407, 23579375}, { 15221344, 23339532}, { 15255414, 23324310}, { 15480802, 23178412}, { 15646843, 23091400}, { 16018697, 22744059}, { 16456749, 22567685}, { 16708674, 22466255}, { 16837697, 22410158}, + { 17154392, 22190832}, { 17069931, 22106918}, { 17007737, 21985244}, { 16978925, 21928875}, { 17036320, 21826992}, { 17212750, 21670157}, { 17298093, 21594293}, { 17451145, 21457485}, { 17530883, 21256458}, { 17541075, 21230767}, + { 17549886, 21207629}, { 17244063, 20372250}, { 17209346, 20248411}, { 17092010, 20089995}, { 17023648, 19955801}, { 16984483, 19912896}, { 16834254, 19784836}, { 16625524, 19606905}, { 16620983, 19603024}, { 16616582, 19597241}, + { 16614255, 19589014}, { 16578856, 19463898}, { 16588025, 19439937}, { 16595650, 19420015}, { 16602627, 19365704}, { 16608518, 19319848}, { 16694764, 19210381}, { 16784442, 19096556}, { 16461235, 17851161}, { 16421291, 17669728}, + { 16359955, 17616552}, { 16304854, 17528237}, { 16266671, 17467038}, { 16001330, 17343372}, { 15927109, 17308781}, { 15828509, 17248124}, { 15766385, 17190011}, { 15678175, 17097940}, { 15629868, 17047518}, { 15678592, 16534350}, + { 15695434, 16356965}, { 15704034, 16303332}, { 15705308, 16269732}, { 15725443, 15743784}, { 15808595, 15332260}, { 15821377, 15312568}, { 15838901, 15285580}, { 15993537, 15201723}, { 16119571, 15175593}, { 16189683, 15163592}, + { 16237347, 15155438}, { 16508759, 15159065}, { 16375757, 14977910}, { 16282021, 14850635}, { 15510709, 13877187}, { 15342882, 13710959}, { 15237532, 13606608}, { 14831965, 13239743}, { 14581428, 13013122}, { 14293147, 12740902}, + { 14190984, 12660109}, { 13669460, 12247703}, { 12564414, 11331695}, { 12487187, 11271158}, { 12046686, 10925925}, { 11871179, 10835479}, { 11582487, 10686699}, { 11523291, 10654160}, { 11396348, 10324251}, { 11575096, 9791088}, + { 11656410, 9657529}, { 11694903, 9594301}, { 12154341, 8957487}, { 12327404, 8717611}, { 12920992, 7861977}, { 13163209, 7541046}, { 13299428, 7360558}, { 13534727, 7094968}, { 13607608, 7012705}, { 14344532, 6120949}, { 15087045, 5393680}, + { 15307430, 5177820}, { 15930737, 4553097}, { 16730116, 3841678}, { 17107544, 3505773}, { 17287251, 3346015}, { 17407773, 3251557}, { 17762201, 2970942}, { 18238970, 2593464}, { 18584923, 2367852}, { 18697829, 2294226}, { 18997703, 2084694}, + { 19253265, 1922140}, { 19413044, 1820512}, { 20082389, 1425058}, { 21018405, 914454}, { 21306702, 757182}, { 21909855, 426548}, { 22232009, 276063}, { 22432844, 180461}, { 22572399, 114027}, { 22900298, 67093} + }; + out.holes.emplace_back(Slic3r::Points( { + { 28812659, 51882256}, { 28813904, 51895244}, { 28807002, 51890550}, { 28850702, 52059657}, { 28856299, 52123368}, { 29045593, 52135332}, { 29004080, 52024610}, { 28932623, 51976002}, { 29332407, 51880142}, { 29334099, 51804647}, + { 29252306, 51781113}, { 29155613, 51753292}, { 28890648, 51728889}, { 28797131, 51720277} + } )); + return out; +} + SCENARIO("Elephant foot compensation", "[ElephantFoot]") { + GIVEN("Contour with hole") { + ExPolygon expoly = contour_with_hole(); + WHEN("Compensated") { + // Elephant foot compensation shall not pinch off bits from this contour. + ExPolygon expoly_compensated = elephant_foot_compensation(expoly, Flow(0.419999987f, 0.2f, 0.4f, false), 0.2f); +#ifdef TESTS_EXPORT_SVGS + SVG::export_expolygons(debug_out_path("elephant_foot_compensation_with_hole.svg").c_str(), + { { { expoly }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } }, + { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); +#endif /* TESTS_EXPORT_SVGS */ + THEN("area of the compensated polygon is smaller") { + REQUIRE(expoly_compensated.area() < expoly.area()); + } + } + } + GIVEN("Tiny contour") { ExPolygon expoly({ { 133382606, 94912473 }, { 134232493, 95001115 }, { 133783926, 95159440 }, { 133441897, 95180666 }, { 133408242, 95191984 }, { 133339012, 95166830 }, { 132991642, 95011087 }, { 133206549, 94908304 } }); WHEN("Compensated") {